Fix Coverity Issues
[platform/core/location/geofence-server.git] / geofence-server / src / geofence_server_bluetooth.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 <glib.h>
18
19 #include "geofence_server.h"
20 #include "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"
26
27 static int connectedFence = -1;
28 static gboolean __geofence_check_fence_status(int fence_status, GeofenceItemData *item_data)
29 {
30         FUNC_ENTRANCE_SERVER
31         gboolean ret = FALSE;
32
33         if (fence_status != item_data->common_info.status) {
34                 LOGD_GEOFENCE("Fence status changed. %d -> %d", item_data->common_info.status, fence_status);
35                 ret = TRUE;
36                 item_data->common_info.status = fence_status;   /*update status*/
37         }
38         return ret;
39 }
40
41 static bool __check_for_match(char *str1, char *str2)
42 {
43         if (g_strrstr(str1, str2) == NULL)
44                 return false;
45         return true;
46 }
47
48 static void bt_le_scan_result_cb(int result, bt_adapter_le_device_scan_result_info_s *info, void *user_data)
49 {
50         int ret = BT_ERROR_NONE;
51         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
52         LOGI_GEOFENCE("Current addresses: %s", geofence_server->ble_info);
53
54         if (info == NULL) {
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);
59                 return;
60         }
61         LOGI_GEOFENCE("Received address: %s", info->remote_address);
62
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);
68                 g_free(p);
69         } else {
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);
77         }
78 }
79
80 static void emit_bt_geofence_proximity_changed(GeofenceServer *geofence_server, int fence_id, int fence_proximity_status)
81 {
82         FUNC_ENTRANCE_SERVER
83         LOGD_GEOFENCE("emit_bt_geofence_proximity_changed");
84         char *app_id = NULL;
85         int ret = FENCE_ERR_NONE;
86
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);
90                 return;
91         }
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);
95                 g_free(app_id);
96                 return;
97         }
98
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);
107                 }
108                 item_data->common_info.proximity_status = fence_proximity_status;
109         }
110         g_free(app_id);
111 }
112
113
114 static void emit_bt_geofence_inout_changed(GeofenceServer *geofence_server, GeofenceItemData *item_data, int fence_status)
115 {
116         FUNC_ENTRANCE_SERVER
117         char *app_id = (char *)g_malloc0(sizeof(char) *APP_ID_LEN);
118         g_strlcpy(app_id, item_data->common_info.appid, APP_ID_LEN);
119         if (app_id == NULL) {
120                 LOGD_GEOFENCE("get app_id failed. fence_id [%d]", item_data->common_info.fence_id);
121                 return;
122         }
123
124         if (fence_status == GEOFENCE_FENCE_STATE_IN)
125                 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);
126         else if (fence_status == GEOFENCE_FENCE_STATE_OUT)
127                 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);
128
129         if (item_data->client_status == GEOFENCE_CLIENT_STATUS_START)
130                 item_data->client_status = GEOFENCE_CLIENT_STATUS_RUNNING;
131
132         if (app_id)
133                 g_free(app_id);
134 }
135
136 static void __geofence_check_bt_fence_type(gboolean connected, const char *bssid, void *data)
137 {
138         FUNC_ENTRANCE_SERVER
139         GeofenceServer *geofence_server = (GeofenceServer *)data;
140         g_return_if_fail(geofence_server);
141         g_return_if_fail(bssid);
142
143         int fence_id = 0;
144         geofence_type_e fence_type;
145         GeofenceItemData *item_data = NULL;
146         bssid_info_s *bt_info_from_db = NULL;
147         bssid_info_s *bt_info_from_list = NULL;
148
149         GList *fence_list = g_list_first(geofence_server->tracking_list);
150
151         for (; fence_list != NULL; fence_list = g_list_next(fence_list)) {
152                 int ret = FENCE_ERR_NONE;
153                 item_data = NULL;
154                 fence_id = GPOINTER_TO_INT(fence_list->data);
155                 item_data = __get_item_by_fence_id(fence_id, geofence_server);
156
157                 if (item_data == NULL)
158                         continue;
159
160                 fence_type = item_data->common_info.type;
161
162                 if (fence_type != GEOFENCE_TYPE_BT)
163                         continue;
164
165                 bt_info_from_list = (bssid_info_s *) item_data->priv;
166
167                 if (bt_info_from_list == NULL || bt_info_from_list->enabled == FALSE)
168                         continue;
169
170                 ret = geofence_manager_get_bssid_info(fence_id, &bt_info_from_db);
171
172                 if (bt_info_from_db == NULL) {
173                         LOGD_GEOFENCE("Failed to get bt_info. Fence Id[%d], Error[%d]", fence_id, ret);
174                         continue;
175                 }
176                 LOGD_GEOFENCE("bt_info->bssid [%s]", bt_info_from_db->bssid);
177
178                 if (!g_ascii_strcasecmp(bt_info_from_db->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(bt_info_from_db->bssid, "-", ':'), bssid)) {
179                         if (connected) {        /* connected => FENCE_IN*/
180                                 if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_IN, item_data) == TRUE) {
181                                         LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_IN", fence_id);
182                                         connectedFence = fence_id;
183                                         emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_IN);
184                                         emit_bt_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_NEAR);
185                                 }
186                         } else {        /* disconnected => FENCE_OUT*/
187                                 if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_OUT, item_data) == TRUE) {
188                                         LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id);
189                                         connectedFence = -1;
190                                         emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_OUT);
191                                         emit_bt_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_UNCERTAIN);
192                                 }
193                         }
194                 }
195                 g_slice_free(bssid_info_s, bt_info_from_db);
196                 bt_info_from_db = NULL;
197                 bt_info_from_list = NULL;
198         }
199         LOGD_GEOFENCE("exit");
200 }
201
202 void bt_conn_state_changed(gboolean connected, bt_device_connection_info_s *conn_info, void *user_data)
203 {
204         FUNC_ENTRANCE_SERVER
205         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
206         g_return_if_fail(geofence_server);
207         g_return_if_fail(conn_info);
208
209         if (connected == true) {
210                 if (conn_info->remote_address == NULL) {
211                         LOGD_GEOFENCE("Bluetooth device connected, but remote_address not exist.");
212                 } else {
213                         LOGD_GEOFENCE("Bluetooth device connected [%s].", conn_info->remote_address);
214                         __geofence_check_bt_fence_type(connected, conn_info->remote_address, user_data);
215                 }
216         } else {
217                 LOGD_GEOFENCE("Bluetooth device disconnected [%s]. reason [%d]", conn_info->remote_address, conn_info->disconn_reason);
218                 __geofence_check_bt_fence_type(connected, conn_info->remote_address, user_data);
219         }
220         LOGD_GEOFENCE("exit");
221 }
222
223 void bt_adp_disable(gboolean connected, void *user_data)
224 {
225         FUNC_ENTRANCE_SERVER
226         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
227         g_return_if_fail(geofence_server);
228
229         int fence_id = 0;
230
231         geofence_type_e fence_type;
232         GeofenceItemData *item_data = NULL;
233
234         GList *fence_list = g_list_first(geofence_server->tracking_list);
235
236         for (; fence_list != NULL; fence_list = g_list_next(fence_list)) {
237                 fence_id = GPOINTER_TO_INT(fence_list->data);
238                 item_data = NULL;
239                 item_data = __get_item_by_fence_id(fence_id, geofence_server);
240
241                 if (item_data == NULL)
242                         continue;
243
244                 fence_type = item_data->common_info.type;
245
246                 if (fence_type != GEOFENCE_TYPE_BT)     /* check only bluetooth type*/
247                         continue;
248
249                 if (connected == FALSE) {
250                         if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_OUT, item_data) == TRUE) {
251                                 LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id);
252                                 emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_OUT);
253                                 emit_bt_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_UNCERTAIN);
254                         }
255                 }
256         }
257
258         LOGD_GEOFENCE("exit");
259 }