fixed for deprecate WIFI API
[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         g_free(app_id);
58 }
59
60 static bool __check_for_match(char *str1, char *str2)
61 {
62         if (g_strrstr(str1, str2) == NULL)
63                 return false;
64         return true;
65 }
66
67 static void bt_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data)
68 {
69         int ret = BT_ERROR_NONE;
70         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
71         LOGI_GEOFENCE("Current addresses: %s", geofence_server->ble_info);
72
73         if (info == NULL) {
74                 LOGI_GEOFENCE("Stopping scan as there is no BLE address found");
75                 ret = bt_adapter_le_stop_scan();
76                 if (ret != BT_ERROR_NONE)
77                         LOGE_GEOFENCE("Unable to stop the BLE scan, error: %d", ret);
78                 return;
79         }
80         LOGI_GEOFENCE("Received address: %s", info->remote_address);
81
82         if (!g_ascii_strcasecmp(geofence_server->ble_info, "")) {
83                 g_stpcpy(geofence_server->ble_info, info->remote_address);
84         } else if (!__check_for_match(geofence_server->ble_info, info->remote_address)) { /* If duplicate does not exist */
85                 char *p = g_strjoin(";", geofence_server->ble_info, info->remote_address, NULL);
86                 g_stpcpy(geofence_server->ble_info, p);
87                 g_free(p);
88         } else {
89                 LOGI_GEOFENCE("Stopping scan. Address: %s already exist in the string %s", info->remote_address, geofence_server->ble_info);
90                 ret = bt_adapter_le_stop_scan();
91                 if (ret != BT_ERROR_NONE)
92                         LOGE_GEOFENCE("Unable to stop the BLE scan, error: %d", ret);
93                 /* Add the string to the database. */
94                 geofence_manager_set_ble_info_to_geofence(geofence_server->connectedTrackingWifiFenceId, geofence_server->ble_info);
95         }
96 }
97
98 static void emit_wifi_geofence_proximity_changed(GeofenceServer *geofence_server, int fence_id, int fence_proximity_status)
99 {
100         FUNC_ENTRANCE_SERVER
101         LOGD_GEOFENCE("emit_wifi_geofence_proximity_changed");
102         char *app_id = NULL;
103         int ret = FENCE_ERR_NONE;
104
105         ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id);
106         if (ret != FENCE_ERR_NONE) {
107                 LOGE("Error getting the app_id for fence id[%d]", fence_id);
108                 return;
109         }
110         GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server);
111         if (item_data == NULL) {
112                 LOGD_GEOFENCE("getting item data failed. fence_id [%d]", fence_id);
113                 g_free(app_id);
114                 return;
115         }
116
117         if (fence_proximity_status != item_data->common_info.proximity_status) {
118                 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);
119                 if (geofence_server->connectedTrackingWifiFenceId == fence_id) {
120                         if (fence_proximity_status == GEOFENCE_PROXIMITY_IMMEDIATE) {
121                                 LOGD_GEOFENCE("WIFI Fence. Scanning for BLE and storing in DB");
122                                 g_stpcpy(geofence_server->ble_info, "");
123                                 ret = bt_adapter_le_start_scan(bt_le_scan_result_cb, geofence_server);
124                                 if (ret != BT_ERROR_NONE)
125                                         LOGE_GEOFENCE("Fail to start ble scan. %d", ret);
126                         } else if (item_data->common_info.proximity_status == GEOFENCE_PROXIMITY_IMMEDIATE) { /* Stopping the scan if state changes from imm to somethingelse */
127                                 ret = bt_adapter_le_stop_scan();
128                                 if (ret != BT_ERROR_NONE)
129                                         LOGE_GEOFENCE("Unable to stop the BLE scan/ Stopped already, error: %d", ret);
130                         }
131                 }
132                 item_data->common_info.proximity_status = fence_proximity_status;
133         }
134         g_free(app_id);
135 }
136
137 void wifi_rssi_level_changed(wifi_manager_rssi_level_e rssi_level, void *user_data)
138 {
139         FUNC_ENTRANCE_SERVER
140         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
141         g_return_if_fail(geofence_server);
142         wifi_manager_ap_h ap_h;
143         char *bssid = NULL;
144         geofence_proximity_state_e state = GEOFENCE_PROXIMITY_UNCERTAIN;
145         wifi_manager_error_e rv = WIFI_MANAGER_ERROR_NONE;
146         LOGI_GEOFENCE("running cnt: %d, connected id: %d", geofence_server->running_wifi_cnt, geofence_server->connectedTrackingWifiFenceId);
147         if (geofence_server->running_wifi_cnt > 0 && geofence_server->connectedTrackingWifiFenceId != -1) {
148                 rv = wifi_manager_get_connected_ap(geofence_server->wifi_h, &ap_h);
149                 if (rv != WIFI_MANAGER_ERROR_NONE) {
150                         LOGE_GEOFENCE("Fail to get the connected AP: Error - %d", rv);
151                         return;
152                 }
153                 rv = wifi_manager_ap_get_bssid(ap_h, &bssid);
154                 if (rv != WIFI_MANAGER_ERROR_NONE) {
155                         LOGI_GEOFENCE("Fail to get the bssid: [%d]", rv);
156                 } else {
157                         /*Emit the proximity alert here using mConnectedFenceId*/
158                         if (rssi_level == WIFI_MANAGER_RSSI_LEVEL_4)
159                                 state = GEOFENCE_PROXIMITY_IMMEDIATE;
160                         else if (rssi_level ==  WIFI_MANAGER_RSSI_LEVEL_3)
161                                 state = GEOFENCE_PROXIMITY_NEAR;
162                         else
163                                 state = GEOFENCE_PROXIMITY_FAR;
164                         emit_wifi_geofence_proximity_changed(geofence_server, geofence_server->connectedTrackingWifiFenceId, state);
165                 }
166                 if (bssid != NULL)
167                         free(bssid);
168                 bssid = NULL;
169         }
170 }
171
172 void wifi_device_state_changed(wifi_manager_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_MANAGER_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_manager_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_MANAGER_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_MANAGER_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_manager_connection_state_e state, wifi_manager_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_manager_ap_get_bssid(ap, &ap_bssid);
254
255         if (rv != WIFI_MANAGER_ERROR_NONE) {
256                 LOGD_GEOFENCE("Failed to get the bssid");
257                 return;
258         }
259
260         if (state == WIFI_MANAGER_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_MANAGER_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         if (ap_bssid != NULL)
268                 free(ap_bssid);
269         ap_bssid = NULL;
270 }