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;
61 static bool __check_for_match(char *str1, char *str2)
63 if (g_strrstr(str1, str2) == NULL)
68 static void bt_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data)
70 int ret = BT_ERROR_NONE;
71 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
72 LOGI_GEOFENCE("Current addresses: %s", geofence_server->ble_info);
73 LOGI_GEOFENCE("Received address: %s", info->remote_address);
76 LOGI_GEOFENCE("Stopping scan as there is no BLE address found");
77 ret = bt_adapter_le_stop_scan();
78 if (ret != BT_ERROR_NONE)
79 LOGE_GEOFENCE("Unable to stop the BLE scan, error: %d", ret);
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);
127 } else if (item_data->common_info.proximity_status == GEOFENCE_PROXIMITY_IMMEDIATE) { /* Stopping the scan if state changes from imm to somethingelse */
128 ret = bt_adapter_le_stop_scan();
129 if (ret != BT_ERROR_NONE)
130 LOGE_GEOFENCE("Unable to stop the BLE scan/ Stopped already, error: %d", ret);
133 item_data->common_info.proximity_status = fence_proximity_status;
139 void wifi_rssi_level_changed(wifi_rssi_level_e rssi_level, void *user_data)
142 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
143 g_return_if_fail(geofence_server);
146 geofence_proximity_state_e state = GEOFENCE_PROXIMITY_UNCERTAIN;
147 wifi_error_e rv = WIFI_ERROR_NONE;
148 LOGI_GEOFENCE("running cnt: %d, connected id: %d", geofence_server->running_wifi_cnt, geofence_server->connectedTrackingWifiFenceId);
149 if (geofence_server->running_wifi_cnt > 0 && geofence_server->connectedTrackingWifiFenceId != -1) {
150 rv = wifi_get_connected_ap(&ap_h);
151 if (rv != WIFI_ERROR_NONE) {
152 LOGE_GEOFENCE("Fail to get the connected AP: Error - %d", rv);
155 rv = wifi_ap_get_bssid(ap_h, &bssid);
156 if (rv != WIFI_ERROR_NONE) {
157 LOGI_GEOFENCE("Fail to get the bssid: [%d]", rv);
159 /*Emit the proximity alert here using mConnectedFenceId*/
160 if (rssi_level == WIFI_RSSI_LEVEL_4)
161 state = GEOFENCE_PROXIMITY_IMMEDIATE;
162 else if (rssi_level == WIFI_RSSI_LEVEL_3)
163 state = GEOFENCE_PROXIMITY_NEAR;
165 state = GEOFENCE_PROXIMITY_FAR;
166 emit_wifi_geofence_proximity_changed(geofence_server, geofence_server->connectedTrackingWifiFenceId, state);
171 void wifi_device_state_changed(wifi_device_state_e state, void *user_data)
174 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
175 g_return_if_fail(geofence_server);
178 geofence_type_e fence_type;
179 GeofenceItemData *item_data = NULL;
181 GList *fence_list = g_list_first(geofence_server->tracking_list);
183 for (; fence_list != NULL; fence_list = g_list_next(fence_list)) {
184 fence_id = GPOINTER_TO_INT(fence_list->data);
186 item_data = __get_item_by_fence_id(fence_id, geofence_server);
188 if (item_data == NULL)
191 fence_type = item_data->common_info.type;
193 if (fence_type != GEOFENCE_TYPE_WIFI)
196 if (state == WIFI_DEVICE_STATE_DEACTIVATED) {
197 LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id);
198 emit_wifi_geofence_inout_changed(geofence_server, fence_id, GEOFENCE_FENCE_STATE_OUT);
199 emit_wifi_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_UNCERTAIN);
203 LOGD_GEOFENCE("exit");
206 void __geofence_check_wifi_matched_bssid(wifi_connection_state_e state, char *bssid, void *user_data)
208 LOGD_GEOFENCE("Comparing the matching bssids");
209 GeofenceServer *geofence_server = (GeofenceServer *)user_data;
210 GList *tracking_fences = g_list_first(geofence_server->tracking_list);
211 int tracking_fence_id = 0;
212 bssid_info_s *bssid_info = NULL;
213 geofence_type_e type = -1;
215 /*Wifi tracking list has to be traversed here*/
216 while (tracking_fences) {
217 tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data);
218 tracking_fences = g_list_next(tracking_fences);
219 if (FENCE_ERR_NONE != geofence_manager_get_geofence_type(tracking_fence_id, &type)) {
220 LOGD_GEOFENCE("Error fetching the fence type/ fence does not exist");
223 if (type == GEOFENCE_TYPE_WIFI) {
224 if (FENCE_ERR_NONE != geofence_manager_get_bssid_info(tracking_fence_id, &bssid_info)) {
225 LOGD_GEOFENCE("Error fetching the fence bssid info/ fence does not exist");
228 if (!g_ascii_strcasecmp(bssid_info->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(bssid_info->bssid, "-", ':'), bssid)) {
229 LOGI_GEOFENCE("Matched wifi fence: fence_id = %d, bssid = %s", tracking_fence_id, bssid_info->bssid);
230 if (state == WIFI_CONNECTION_STATE_CONNECTED) {
231 emit_wifi_geofence_inout_changed(geofence_server, tracking_fence_id, GEOFENCE_FENCE_STATE_IN);
232 geofence_server->connectedTrackingWifiFenceId = tracking_fence_id;
233 } else if (state == WIFI_CONNECTION_STATE_DISCONNECTED) {
234 emit_wifi_geofence_inout_changed(geofence_server, tracking_fence_id, GEOFENCE_FENCE_STATE_OUT);
235 emit_wifi_geofence_proximity_changed(geofence_server, tracking_fence_id, GEOFENCE_PROXIMITY_UNCERTAIN);
236 geofence_server->connectedTrackingWifiFenceId = -1;
238 break; /*Because there cannot be two APs connected at the same time*/
245 void wifi_conn_state_changed(wifi_connection_state_e state, wifi_ap_h ap, void *user_data)
247 LOGD_GEOFENCE("wifi_conn_state_changed");
248 GeofenceServer *geofence_server = (GeofenceServer *)user_data;
249 char *ap_bssid = NULL;
251 g_return_if_fail(geofence_server);
252 rv = wifi_ap_get_bssid(ap, &ap_bssid);
254 if (rv != WIFI_ERROR_NONE) {
255 LOGD_GEOFENCE("Failed to get the bssid");
259 if (state == WIFI_CONNECTION_STATE_CONNECTED) {
260 LOGD_GEOFENCE("Wifi connected to [%s].", ap_bssid);
261 __geofence_check_wifi_matched_bssid(state, ap_bssid, user_data);
262 } else if (state == WIFI_CONNECTION_STATE_DISCONNECTED) {
263 LOGD_GEOFENCE("Wifi disconnected with [%s].", ap_bssid);
264 __geofence_check_wifi_matched_bssid(state, ap_bssid, user_data);