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.
19 #include "geofence_server.h"
21 #include "debug_util.h"
22 #include "geofence_server_log.h"
23 #include "geofence_server_private.h"
24 #include "geofence_server_internal.h"
25 #include "geofence_server_db.h"
27 static int connectedFence = -1;
28 static gboolean __geofence_check_fence_status(int fence_status, GeofenceItemData *item_data)
33 if (fence_status != item_data->common_info.status) {
34 LOGD_GEOFENCE("Fence status changed. %d -> %d", item_data->common_info.status, fence_status);
36 item_data->common_info.status = fence_status; /*update status*/
41 static bool __check_for_match(char *str1, char *str2)
43 if (g_strrstr(str1, str2) == NULL)
48 static void bt_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data)
50 int ret = BT_ERROR_NONE;
51 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
52 LOGI_GEOFENCE("Current addresses: %s", geofence_server->ble_info);
55 LOGI_GEOFENCE("Stopping scan as there is no BLE address found");
56 ret = bt_adapter_le_stop_scan();
57 if (ret != BT_ERROR_NONE)
58 LOGE_GEOFENCE("Unable to stop the BLE scan, error: %d", ret);
61 LOGI_GEOFENCE("Received address: %s", info->remote_address);
63 if (!g_ascii_strcasecmp(geofence_server->ble_info, "")) {
64 g_stpcpy(geofence_server->ble_info, info->remote_address);
65 } else if (!__check_for_match(geofence_server->ble_info, info->remote_address)) { /* If duplicate does not exist */
66 char *p = g_strjoin(";", geofence_server->ble_info, info->remote_address, NULL);
67 g_stpcpy(geofence_server->ble_info, p);
70 LOGI_GEOFENCE("Stopping scan. Address: %s already exist in the string %s", info->remote_address, geofence_server->ble_info);
71 ret = bt_adapter_le_stop_scan();
72 if (ret != BT_ERROR_NONE)
73 LOGE_GEOFENCE("Unable to stop the BLE scan, error: %d", ret);
74 /* Add the string to the database. */
75 if (connectedFence != -1)
76 geofence_manager_set_ble_info_to_geofence(connectedFence, geofence_server->ble_info);
80 static void emit_bt_geofence_proximity_changed(GeofenceServer *geofence_server, int fence_id, int fence_proximity_status)
83 LOGD_GEOFENCE("emit_bt_geofence_proximity_changed");
85 int ret = FENCE_ERR_NONE;
87 ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id);
88 if (ret != FENCE_ERR_NONE) {
89 LOGE("Error getting the app_id for fence id[%d]", fence_id);
92 GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server);
93 if (item_data == NULL) {
94 LOGD_GEOFENCE("getting item data failed. fence_id [%d]", fence_id);
99 if (fence_proximity_status != item_data->common_info.proximity_status) {
100 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_BLUETOOTH);
101 if (fence_proximity_status == GEOFENCE_PROXIMITY_NEAR) {
102 LOGD_GEOFENCE("BT Fence. Scanning for BLE and storing in DB");
103 g_stpcpy(geofence_server->ble_info, "");
104 ret = bt_adapter_le_start_scan(bt_le_scan_result_cb, geofence_server);
105 if (ret != BT_ERROR_NONE) {
106 LOGE_GEOFENCE("Fail to start ble scan. %d", ret);
109 item_data->common_info.proximity_status = fence_proximity_status;
117 static void emit_bt_geofence_inout_changed(GeofenceServer *geofence_server, GeofenceItemData *item_data, int fence_status)
120 char *app_id = (char *)g_malloc0(sizeof(char) * APP_ID_LEN);
121 g_strlcpy(app_id, item_data->common_info.appid, APP_ID_LEN);
122 if (app_id == NULL) {
123 LOGD_GEOFENCE("get app_id failed. fence_id [%d]", item_data->common_info.fence_id);
127 if (fence_status == GEOFENCE_FENCE_STATE_IN) {
128 geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, app_id, item_data->common_info.fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_IN);
129 } else if (fence_status == GEOFENCE_FENCE_STATE_OUT) {
130 geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, app_id, item_data->common_info.fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_OUT);
133 if (item_data->client_status == GEOFENCE_CLIENT_STATUS_START) {
134 item_data->client_status = GEOFENCE_CLIENT_STATUS_RUNNING;
140 static void __geofence_check_bt_fence_type(gboolean connected, const char *bssid, void *data)
143 GeofenceServer *geofence_server = (GeofenceServer *)data;
144 g_return_if_fail(geofence_server);
145 g_return_if_fail(bssid);
148 geofence_type_e fence_type;
149 GeofenceItemData *item_data = NULL;
150 bssid_info_s *bt_info_from_db = NULL;
151 bssid_info_s *bt_info_from_list = NULL;
153 GList *fence_list = g_list_first(geofence_server->tracking_list);
155 for (; fence_list != NULL; fence_list = g_list_next(fence_list)) {
156 int ret = FENCE_ERR_NONE;
158 fence_id = GPOINTER_TO_INT(fence_list->data);
159 item_data = __get_item_by_fence_id(fence_id, geofence_server);
161 if (item_data == NULL)
164 fence_type = item_data->common_info.type;
166 if (fence_type != GEOFENCE_TYPE_BT)
169 bt_info_from_list = (bssid_info_s *) item_data->priv;
171 if (bt_info_from_list == NULL || bt_info_from_list->enabled == FALSE)
174 ret = geofence_manager_get_bssid_info(fence_id, &bt_info_from_db);
176 if (bt_info_from_db == NULL) {
177 LOGD_GEOFENCE("Failed to get bt_info. Fence Id[%d], Error[%d]", fence_id, ret);
180 LOGD_GEOFENCE("bt_info->bssid [%s]", bt_info_from_db->bssid);
182 if (!g_ascii_strcasecmp(bt_info_from_db->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(bt_info_from_db->bssid, "-", ':'), bssid)) {
183 if (connected) { /* connected => FENCE_IN*/
184 if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_IN, item_data) == TRUE) {
185 LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_IN", fence_id);
186 connectedFence = fence_id;
187 emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_IN);
188 emit_bt_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_NEAR);
190 } else { /* disconnected => FENCE_OUT*/
191 if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_OUT, item_data) == TRUE) {
192 LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id);
194 emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_OUT);
195 emit_bt_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_UNCERTAIN);
199 g_slice_free(bssid_info_s, bt_info_from_db);
200 bt_info_from_db = NULL;
201 bt_info_from_list = NULL;
203 LOGD_GEOFENCE("exit");
206 void bt_conn_state_changed(gboolean connected, bt_device_connection_info_s *conn_info, void *user_data)
209 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
210 g_return_if_fail(geofence_server);
211 g_return_if_fail(conn_info);
213 if (connected == true) {
214 if (conn_info->remote_address == NULL) {
215 LOGD_GEOFENCE("Bluetooth device connected, but remote_address not exist.");
217 LOGD_GEOFENCE("Bluetooth device connected [%s].", conn_info->remote_address);
218 __geofence_check_bt_fence_type(connected, conn_info->remote_address, user_data);
221 LOGD_GEOFENCE("Bluetooth device disconnected [%s]. reason [%d]", conn_info->remote_address, conn_info->disconn_reason);
222 __geofence_check_bt_fence_type(connected, conn_info->remote_address, user_data);
224 LOGD_GEOFENCE("exit");
227 void bt_adp_disable(gboolean connected, void *user_data)
230 GeofenceServer *geofence_server = (GeofenceServer *) user_data;
231 g_return_if_fail(geofence_server);
235 geofence_type_e fence_type;
236 GeofenceItemData *item_data = NULL;
238 GList *fence_list = g_list_first(geofence_server->tracking_list);
240 for (; fence_list != NULL; fence_list = g_list_next(fence_list)) {
241 fence_id = GPOINTER_TO_INT(fence_list->data);
243 item_data = __get_item_by_fence_id(fence_id, geofence_server);
245 if (item_data == NULL)
248 fence_type = item_data->common_info.type;
250 if (fence_type != GEOFENCE_TYPE_BT) /* check only bluetooth type*/
253 if (connected == FALSE) {
254 if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_OUT, item_data) == TRUE) {
255 LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id);
256 emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_OUT);
257 emit_bt_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_UNCERTAIN);
262 LOGD_GEOFENCE("exit");