fix svace warnings
[platform/core/location/geofence-server.git] / geofence-server / src / geofence_server_wifi.c
1 /* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <stdlib.h>
17 #include <vconf.h>
18 #include <vconf-keys.h>
19 #include <glib.h>
20
21 #include "geofence_server.h"
22 #include "server.h"
23 #include "debug_util.h"
24 #include "geofence_server_private.h"
25 #include "geofence_server_db.h"
26 #include "geofence_server_log.h"
27 #include "geofence_server_internal.h"
28
29 static void emit_wifi_geofence_inout_changed(GeofenceServer *geofence_server, int fence_id, int fence_status)
30 {
31         LOGD_GEOFENCE("emit_wifi_geofence_inout_changed");
32         char *app_id = NULL;
33         int ret = FENCE_ERR_NONE;
34
35         ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id);
36         if (ret != FENCE_ERR_NONE) {
37                 LOGE("Error getting the app_id for fence id[%d]", fence_id);
38                 return;
39         }
40         GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server);
41         if (item_data == NULL) {
42                 LOGD_GEOFENCE("getting item data failed. fence_id [%d]", fence_id);
43                 g_free(app_id);
44                 return;
45         }
46         if (fence_status == GEOFENCE_FENCE_STATE_IN) {
47                 if (item_data->common_info.status != GEOFENCE_FENCE_STATE_IN) {
48                         geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, app_id, fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_IN);
49                         item_data->common_info.status = GEOFENCE_FENCE_STATE_IN;
50                 }
51         } else if (fence_status == GEOFENCE_FENCE_STATE_OUT) {
52                 if (item_data->common_info.status != GEOFENCE_FENCE_STATE_OUT) {
53                         geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, app_id, fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_OUT);
54                         item_data->common_info.status = GEOFENCE_FENCE_STATE_OUT;
55                 }
56         }
57         if (app_id)
58                 free(app_id);
59 }
60
61 static bool __check_for_match(char *str1, char *str2)
62 {
63         if (g_strrstr(str1, str2) == NULL)
64                 return false;
65         return true;
66 }
67
68 static void bt_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data)
69 {
70         int ret = BT_ERROR_NONE;
71         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
72         LOGI_GEOFENCE("Current addresses: %s", geofence_server->ble_info);
73
74         if (info == NULL) {
75                 LOGI_GEOFENCE("Stopping scan as there is no BLE address found");
76                 ret = bt_adapter_le_stop_scan();
77                 if (ret != BT_ERROR_NONE)
78                         LOGE_GEOFENCE("Unable to stop the BLE scan, error: %d", ret);
79                 return;
80         }
81         LOGI_GEOFENCE("Received address: %s", info->remote_address);
82
83         if (!g_ascii_strcasecmp(geofence_server->ble_info, "")) {
84                 g_stpcpy(geofence_server->ble_info, info->remote_address);
85         } else if (!__check_for_match(geofence_server->ble_info, info->remote_address)) { /* If duplicate does not exist */
86                 char *p = g_strjoin(";", geofence_server->ble_info, info->remote_address, NULL);
87                 g_stpcpy(geofence_server->ble_info, p);
88                 g_free(p);
89         } else {
90                 LOGI_GEOFENCE("Stopping scan. Address: %s already exist in the string %s", info->remote_address, geofence_server->ble_info);
91                 ret = bt_adapter_le_stop_scan();
92                 if (ret != BT_ERROR_NONE)
93                         LOGE_GEOFENCE("Unable to stop the BLE scan, error: %d", ret);
94                 /* Add the string to the database. */
95                 geofence_manager_set_ble_info_to_geofence(geofence_server->connectedTrackingWifiFenceId, geofence_server->ble_info);
96         }
97 }
98
99 static void emit_wifi_geofence_proximity_changed(GeofenceServer *geofence_server, int fence_id, int fence_proximity_status)
100 {
101         FUNC_ENTRANCE_SERVER
102         LOGD_GEOFENCE("emit_wifi_geofence_proximity_changed");
103         char *app_id = NULL;
104         int ret = FENCE_ERR_NONE;
105
106         ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id);
107         if (ret != FENCE_ERR_NONE) {
108                 LOGE("Error getting the app_id for fence id[%d]", fence_id);
109                 return;
110         }
111         GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server);
112         if (item_data == NULL) {
113                 LOGD_GEOFENCE("getting item data failed. fence_id [%d]", fence_id);
114                 g_free(app_id);
115                 return;
116         }
117
118         if (fence_proximity_status != item_data->common_info.proximity_status) {
119                 geofence_dbus_server_send_geofence_proximity_changed(geofence_server->geofence_dbus_server, app_id, fence_id, item_data->common_info.access_type, fence_proximity_status, GEOFENCE_PROXIMITY_PROVIDER_WIFI);
120                 if (geofence_server->connectedTrackingWifiFenceId == fence_id) {
121                         if (fence_proximity_status == GEOFENCE_PROXIMITY_IMMEDIATE) {
122                                 LOGD_GEOFENCE("WIFI Fence. Scanning for BLE and storing in DB");
123                                 g_stpcpy(geofence_server->ble_info, "");
124                                 ret = bt_adapter_le_start_scan(bt_le_scan_result_cb, geofence_server);
125                                 if (ret != BT_ERROR_NONE) {
126                                         LOGE_GEOFENCE("Fail to start ble scan. %d", ret);
127                                 }
128                         } else if (item_data->common_info.proximity_status == GEOFENCE_PROXIMITY_IMMEDIATE) { /* Stopping the scan if state changes from imm to somethingelse */
129                                 ret = bt_adapter_le_stop_scan();
130                                 if (ret != BT_ERROR_NONE)
131                                         LOGE_GEOFENCE("Unable to stop the BLE scan/ Stopped already, error: %d", ret);
132                         }
133                 }
134                 item_data->common_info.proximity_status = fence_proximity_status;
135         }
136         if (app_id)
137                 free(app_id);
138 }
139
140 void wifi_rssi_level_changed(wifi_rssi_level_e rssi_level, void *user_data)
141 {
142         FUNC_ENTRANCE_SERVER
143         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
144         g_return_if_fail(geofence_server);
145         wifi_ap_h ap_h;
146         char *bssid = NULL;
147         geofence_proximity_state_e state = GEOFENCE_PROXIMITY_UNCERTAIN;
148         wifi_error_e rv = WIFI_ERROR_NONE;
149         LOGI_GEOFENCE("running cnt: %d, connected id: %d", geofence_server->running_wifi_cnt, geofence_server->connectedTrackingWifiFenceId);
150         if (geofence_server->running_wifi_cnt > 0 && geofence_server->connectedTrackingWifiFenceId != -1) {
151                 rv = wifi_get_connected_ap(&ap_h);
152                 if (rv != WIFI_ERROR_NONE) {
153                         LOGE_GEOFENCE("Fail to get the connected AP: Error - %d", rv);
154                         return;
155                 }
156                 rv = wifi_ap_get_bssid(ap_h, &bssid);
157                 if (rv != WIFI_ERROR_NONE) {
158                         LOGI_GEOFENCE("Fail to get the bssid: [%d]", rv);
159                 } else {
160                         /*Emit the proximity alert here using mConnectedFenceId*/
161                         if (rssi_level == WIFI_RSSI_LEVEL_4)
162                                 state = GEOFENCE_PROXIMITY_IMMEDIATE;
163                         else if (rssi_level ==  WIFI_RSSI_LEVEL_3)
164                                 state = GEOFENCE_PROXIMITY_NEAR;
165                         else
166                                 state = GEOFENCE_PROXIMITY_FAR;
167                         emit_wifi_geofence_proximity_changed(geofence_server, geofence_server->connectedTrackingWifiFenceId, state);
168                 }
169         }
170 }
171
172 void wifi_device_state_changed(wifi_device_state_e state, void *user_data)
173 {
174         FUNC_ENTRANCE_SERVER
175         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
176         g_return_if_fail(geofence_server);
177
178         int fence_id = 0;
179         geofence_type_e fence_type;
180         GeofenceItemData *item_data = NULL;
181
182         GList *fence_list = g_list_first(geofence_server->tracking_list);
183
184         for (; fence_list != NULL; fence_list = g_list_next(fence_list)) {
185                 fence_id = GPOINTER_TO_INT(fence_list->data);
186                 item_data = NULL;
187                 item_data = __get_item_by_fence_id(fence_id, geofence_server);
188
189                 if (item_data == NULL)
190                         continue;
191
192                 fence_type = item_data->common_info.type;
193
194                 if (fence_type != GEOFENCE_TYPE_WIFI)
195                         continue;
196
197                 if (state == WIFI_DEVICE_STATE_DEACTIVATED) {
198                         LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id);
199                         emit_wifi_geofence_inout_changed(geofence_server, fence_id, GEOFENCE_FENCE_STATE_OUT);
200                         emit_wifi_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_UNCERTAIN);
201                 }
202         }
203
204         LOGD_GEOFENCE("exit");
205 }
206
207 void __geofence_check_wifi_matched_bssid(wifi_connection_state_e state, char *bssid, void *user_data)
208 {
209         LOGD_GEOFENCE("Comparing the matching bssids");
210         GeofenceServer *geofence_server = (GeofenceServer *)user_data;
211         GList *tracking_fences = g_list_first(geofence_server->tracking_list);
212         int tracking_fence_id = 0;
213         bssid_info_s *bssid_info = NULL;
214         geofence_type_e type = -1;
215
216         /*Wifi tracking list has to be traversed here*/
217         while (tracking_fences) {
218                 tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data);
219                 tracking_fences = g_list_next(tracking_fences);
220                 if (FENCE_ERR_NONE != geofence_manager_get_geofence_type(tracking_fence_id, &type)) {
221                         LOGD_GEOFENCE("Error fetching the fence type/ fence does not exist");
222                         return;
223                 }
224                 if (type == GEOFENCE_TYPE_WIFI) {
225                         if (FENCE_ERR_NONE != geofence_manager_get_bssid_info(tracking_fence_id, &bssid_info)) {
226                                 LOGD_GEOFENCE("Error fetching the fence bssid info/ fence does not exist");
227                                 return;
228                         }
229                         if (!g_ascii_strcasecmp(bssid_info->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(bssid_info->bssid, "-", ':'), bssid)) {
230                                 LOGI_GEOFENCE("Matched wifi fence: fence_id = %d, bssid = %s", tracking_fence_id, bssid_info->bssid);
231                                 if (state == WIFI_CONNECTION_STATE_CONNECTED) {
232                                         emit_wifi_geofence_inout_changed(geofence_server, tracking_fence_id, GEOFENCE_FENCE_STATE_IN);
233                                         geofence_server->connectedTrackingWifiFenceId = tracking_fence_id;
234                                 } else if (state == WIFI_CONNECTION_STATE_DISCONNECTED) {
235                                         emit_wifi_geofence_inout_changed(geofence_server, tracking_fence_id, GEOFENCE_FENCE_STATE_OUT);
236                                         emit_wifi_geofence_proximity_changed(geofence_server, tracking_fence_id, GEOFENCE_PROXIMITY_UNCERTAIN);
237                                         geofence_server->connectedTrackingWifiFenceId = -1;
238                                 }
239                                 break;  /*Because there cannot be two APs connected at the same time*/
240                         }
241                 }
242         }
243
244 }
245
246 void wifi_conn_state_changed(wifi_connection_state_e state, wifi_ap_h ap, void *user_data)
247 {
248         LOGD_GEOFENCE("wifi_conn_state_changed");
249         GeofenceServer *geofence_server = (GeofenceServer *)user_data;
250         char *ap_bssid = NULL;
251         int rv = 0;
252         g_return_if_fail(geofence_server);
253         rv = wifi_ap_get_bssid(ap, &ap_bssid);
254
255         if (rv != WIFI_ERROR_NONE) {
256                 LOGD_GEOFENCE("Failed to get the bssid");
257                 return;
258         }
259
260         if (state == WIFI_CONNECTION_STATE_CONNECTED) {
261                 LOGD_GEOFENCE("Wifi connected to [%s].", ap_bssid);
262                 __geofence_check_wifi_matched_bssid(state, ap_bssid, user_data);
263         } else if (state == WIFI_CONNECTION_STATE_DISCONNECTED) {
264                 LOGD_GEOFENCE("Wifi disconnected with [%s].", ap_bssid);
265                 __geofence_check_wifi_matched_bssid(state, ap_bssid, user_data);
266         }
267 }