1 /* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved
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
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <vconf-keys.h>
21 #include "geofence_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"
29 static void emit_wifi_geofence_inout_changed(GeofenceServer *geofence_server, int fence_id, int fence_status)
31 LOGD_GEOFENCE("emit_wifi_geofence_inout_changed");
33 int ret = FENCE_ERR_NONE;
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);
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);
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;
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;
60 static bool __check_for_match(char *str1, char *str2)
62 if (g_strrstr(str1, str2) == NULL)
67 static void bt_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data)
69 int ret = BT_ERROR_NONE;
70 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
71 LOGI_GEOFENCE("Current addresses: %s", geofence_server->ble_info);
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);
80 LOGI_GEOFENCE("Received address: %s", info->remote_address);
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);
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);
98 static void emit_wifi_geofence_proximity_changed(GeofenceServer *geofence_server, int fence_id, int fence_proximity_status)
101 LOGD_GEOFENCE("emit_wifi_geofence_proximity_changed");
103 int ret = FENCE_ERR_NONE;
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);
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);
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);
132 item_data->common_info.proximity_status = fence_proximity_status;
137 void wifi_rssi_level_changed(wifi_manager_rssi_level_e rssi_level, void *user_data)
140 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
141 g_return_if_fail(geofence_server);
142 wifi_manager_ap_h ap_h;
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);
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);
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;
163 state = GEOFENCE_PROXIMITY_FAR;
164 emit_wifi_geofence_proximity_changed(geofence_server, geofence_server->connectedTrackingWifiFenceId, state);
172 void wifi_device_state_changed(wifi_manager_device_state_e state, void *user_data)
175 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
176 g_return_if_fail(geofence_server);
179 geofence_type_e fence_type;
180 GeofenceItemData *item_data = NULL;
182 GList *fence_list = g_list_first(geofence_server->tracking_list);
184 for (; fence_list != NULL; fence_list = g_list_next(fence_list)) {
185 fence_id = GPOINTER_TO_INT(fence_list->data);
187 item_data = __get_item_by_fence_id(fence_id, geofence_server);
189 if (item_data == NULL)
192 fence_type = item_data->common_info.type;
194 if (fence_type != GEOFENCE_TYPE_WIFI)
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);
204 LOGD_GEOFENCE("exit");
207 void __geofence_check_wifi_matched_bssid(wifi_manager_connection_state_e state, char *bssid, void *user_data)
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;
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");
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");
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;
239 break; /*Because there cannot be two APs connected at the same time*/
246 void wifi_conn_state_changed(wifi_manager_connection_state_e state, wifi_manager_ap_h ap, void *user_data)
248 LOGD_GEOFENCE("wifi_conn_state_changed");
249 GeofenceServer *geofence_server = (GeofenceServer *)user_data;
250 char *ap_bssid = NULL;
252 g_return_if_fail(geofence_server);
253 rv = wifi_manager_ap_get_bssid(ap, &ap_bssid);
255 if (rv != WIFI_MANAGER_ERROR_NONE) {
256 LOGD_GEOFENCE("Failed to get the bssid");
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);
267 if (ap_bssid != NULL)