848ef5bdc7b2bd59cce86ced9b4a77837414b15e
[platform/core/location/geofence-server.git] / geofence-server / src / geofence_server.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 <stdio.h>
17 #include <string.h>
18 #include <time.h>
19 #include <stdlib.h>
20 #include <glib.h>
21 #include <glib-object.h>
22 #include <geofence_client.h>
23 #include <dd-display.h>
24 #include <vconf.h>
25 #include <vconf-internal-wifi-keys.h>
26 #include "geofence_server_data_types.h"
27 #include "geofence_server.h"
28 #include "server.h"
29 #include "debug_util.h"
30 #include "geofence_server_db.h"
31 #include "geofence_server_private.h"
32 #include "geofence_server_wifi.h"
33 #include "geofence_server_alarm.h"
34 #include "geofence_server_internal.h"
35 #include "geofence_server_bluetooth.h"
36 #include <wifi.h>
37
38 #define TIZEN_ENGINEER_MODE
39 #ifdef TIZEN_ENGINEER_MODE
40 #include "geofence_server_log.h"
41 #endif
42
43 #define GEOFENCE_SERVER_SERVICE_NAME    "org.tizen.lbs.Providers.GeofenceServer"
44 #define GEOFENCE_SERVER_SERVICE_PATH    "/org/tizen/lbs/Providers/GeofenceServer"
45 #define TIME_INTERVAL   5
46
47 #define SMART_ASSIST_HOME       1
48
49 #define SMART_ASSIST_TIMEOUT                    60      /* Refer to LPP */
50 #define GEOFENCE_DEFAULT_RADIUS                 200     /* Default 200 m */
51
52 #define NPS_TIMEOUT                             180
53
54 #define MYPLACES_APPID  "org.tizen.myplace"
55 #define DEFAULT_PLACE_HOME 1
56 #define DEFAULT_PLACE_OFFICE 2
57 #define DEFAULT_PLACE_CAR 3
58
59 static int __nps_alarm_cb(alarm_id_t alarm_id, void *user_data);
60 static int __nps_timeout_cb(alarm_id_t alarm_id, void *user_data);
61 static void __add_left_fences(gpointer user_data);
62 static void __stop_geofence_service(gint fence_id, const gchar *app_id, gpointer userdata);
63 static void __start_activity_service(GeofenceServer *geofence_server);
64 static void __stop_activity_service(GeofenceServer *geofence_server);
65 static void __activity_cb(activity_type_e type, const activity_data_h data, double timestamp, activity_error_e error, void *user_data);
66
67 static const char *__convert_wifi_error_to_string(wifi_error_e err_type)
68 {
69         switch (err_type) {
70         case WIFI_ERROR_NONE:
71                 return "NONE";
72         case WIFI_ERROR_INVALID_PARAMETER:
73                 return "INVALID_PARAMETER";
74         case WIFI_ERROR_OUT_OF_MEMORY:
75                 return "OUT_OF_MEMORY";
76         case WIFI_ERROR_INVALID_OPERATION:
77                 return "INVALID_OPERATION";
78         case WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
79                 return "ADDRESS_FAMILY_NOT_SUPPORTED";
80         case WIFI_ERROR_OPERATION_FAILED:
81                 return "OPERATION_FAILED";
82         case WIFI_ERROR_NO_CONNECTION:
83                 return "NO_CONNECTION";
84         case WIFI_ERROR_NOW_IN_PROGRESS:
85                 return "NOW_IN_PROGRESS";
86         case WIFI_ERROR_ALREADY_EXISTS:
87                 return "ALREADY_EXISTS";
88         case WIFI_ERROR_OPERATION_ABORTED:
89                 return "OPERATION_ABORTED";
90         case WIFI_ERROR_DHCP_FAILED:
91                 return "DHCP_FAILED";
92         case WIFI_ERROR_INVALID_KEY:
93                 return "INVALID_KEY";
94         case WIFI_ERROR_NO_REPLY:
95                 return "NO_REPLY";
96         case WIFI_ERROR_SECURITY_RESTRICTED:
97                 return "SECURITY_RESTRICTED";
98         case WIFI_ERROR_PERMISSION_DENIED:
99                 return "PERMISSION_DENIED";
100         default:
101                 return "NOT Defined";
102         }
103 }
104
105 #if 0 /* Not used */
106 static const char *__bt_get_error_message(bt_error_e err)
107 {
108         switch (err) {
109         case BT_ERROR_NONE:
110                 return "BT_ERROR_NONE";
111         case BT_ERROR_CANCELLED:
112                 return "BT_ERROR_CANCELLED";
113         case BT_ERROR_INVALID_PARAMETER:
114                 return "BT_ERROR_INVALID_PARAMETER";
115         case BT_ERROR_OUT_OF_MEMORY:
116                 return "BT_ERROR_OUT_OF_MEMORY";
117         case BT_ERROR_RESOURCE_BUSY:
118                 return "BT_ERROR_RESOURCE_BUSY";
119         case BT_ERROR_TIMED_OUT:
120                 return "BT_ERROR_TIMED_OUT";
121         case BT_ERROR_NOW_IN_PROGRESS:
122                 return "BT_ERROR_NOW_IN_PROGRESS";
123         case BT_ERROR_NOT_INITIALIZED:
124                 return "BT_ERROR_NOT_INITIALIZED";
125         case BT_ERROR_NOT_ENABLED:
126                 return "BT_ERROR_NOT_ENABLED";
127         case BT_ERROR_ALREADY_DONE:
128                 return "BT_ERROR_ALREADY_DONE";
129         case BT_ERROR_OPERATION_FAILED:
130                 return "BT_ERROR_OPERATION_FAILED";
131         case BT_ERROR_NOT_IN_PROGRESS:
132                 return "BT_ERROR_NOT_IN_PROGRESS";
133         case BT_ERROR_REMOTE_DEVICE_NOT_BONDED:
134                 return "BT_ERROR_REMOTE_DEVICE_NOT_BONDED";
135         case BT_ERROR_AUTH_REJECTED:
136                 return "BT_ERROR_AUTH_REJECTED";
137         case BT_ERROR_AUTH_FAILED:
138                 return "BT_ERROR_AUTH_FAILED";
139         case BT_ERROR_REMOTE_DEVICE_NOT_FOUND:
140                 return "BT_ERROR_REMOTE_DEVICE_NOT_FOUND";
141         case BT_ERROR_SERVICE_SEARCH_FAILED:
142                 return "BT_ERROR_SERVICE_SEARCH_FAILED";
143         case BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED:
144                 return "BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED";
145 #ifndef TIZEN_TV
146         case BT_ERROR_PERMISSION_DENIED:
147                 return "BT_ERROR_PERMISSION_DENIED";
148         case BT_ERROR_SERVICE_NOT_FOUND:
149                 return "BT_ERROR_SERVICE_NOT_FOUND";
150 #endif
151         default:
152                 return "NOT Defined";
153         }
154 }
155 #endif
156
157 static int __emit_fence_event(GeofenceServer *geofence_server, int place_id, int fence_id, access_type_e access_type, const gchar *app_id, geofence_server_error_e error, geofence_manage_e state)
158 {
159         FUNC_ENTRANCE_SERVER;
160         g_return_val_if_fail(geofence_server, -1);
161
162         geofence_dbus_server_send_geofence_event_changed(geofence_server->geofence_dbus_server, place_id, fence_id, access_type, app_id, error, state);
163         return 0;
164 }
165
166 static int __emit_fence_inout(GeofenceServer *geofence_server, int fence_id, geofence_fence_state_e state)
167 {
168         FUNC_ENTRANCE_SERVER;
169         g_return_val_if_fail(geofence_server, -1);
170         int ret = 0;
171
172         LOGD_GEOFENCE("FenceId[%d], state[%d]", fence_id, state);
173         GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server);
174         if (item_data == NULL) {
175                 LOGD_GEOFENCE("Invalid item_data");
176                 return -1;
177         }
178
179         if (state == GEOFENCE_FENCE_STATE_IN) {
180                 LOGD_GEOFENCE("FENCE_IN to be set, current state: %d",
181                         item_data->common_info.status);
182                 if (item_data->common_info.status != GEOFENCE_FENCE_STATE_IN) {
183                         geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, item_data->common_info.appid, fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_IN);
184                         if (item_data->client_status == GEOFENCE_CLIENT_STATUS_START) {
185                                 item_data->client_status = GEOFENCE_CLIENT_STATUS_RUNNING;
186                         }
187 #ifdef TIZEN_ENGINEER_MODE
188                         GEOFENCE_PRINT_LOG("FENCE_IN")
189 #endif
190                 }
191
192                 item_data->common_info.status = GEOFENCE_FENCE_STATE_IN;
193
194         } else if (state == GEOFENCE_FENCE_STATE_OUT) {
195                 LOGD_GEOFENCE("FENCE_OUT to be set, current state: %d",
196                         item_data->common_info.status);
197                 if (item_data->common_info.status != GEOFENCE_FENCE_STATE_OUT) {
198                         geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, item_data->common_info.appid, fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_OUT);
199                         if (item_data->client_status == GEOFENCE_CLIENT_STATUS_START) {
200                                 item_data->client_status = GEOFENCE_CLIENT_STATUS_RUNNING;
201                         }
202 #ifdef TIZEN_ENGINEER_MODE
203                         GEOFENCE_PRINT_LOG("FENCE_OUT")
204 #endif
205                 } else {
206                         LOGD_GEOFENCE("Fence status [%d]", item_data->common_info.status);
207                 }
208                 item_data->common_info.status = GEOFENCE_FENCE_STATE_OUT;
209         } else {
210                 LOGD_GEOFENCE("Not emit, Prev[%d], Curr[%d]", item_data->common_info.status, state);
211         }
212
213         return ret;
214 }
215
216 static void __check_inout_by_gps(double latitude, double longitude, int fence_id, void *user_data)
217 {
218         FUNC_ENTRANCE_SERVER;
219         double distance = 0.0;
220         LOGD_GEOFENCE("fence_id [%d]", fence_id);
221         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
222         GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server);
223         if (!item_data || item_data->client_status == GEOFENCE_CLIENT_STATUS_NONE)
224                 return;
225
226         location_accuracy_level_e level = 0;
227         double horizontal = 0.0;
228         double vertical = 0.0;
229         geofence_fence_state_e status = GEOFENCE_FENCE_STATE_OUT;
230
231         geocoordinate_info_s *geocoordinate_info = (geocoordinate_info_s *)item_data->priv;
232
233         /* get_current_position/ check_fence_in/out  for geoPoint */
234         location_manager_get_accuracy(geofence_server->loc_manager, &level, &horizontal, &vertical);
235         location_manager_get_distance(latitude, longitude, geocoordinate_info->latitude, geocoordinate_info->longitude, &distance);
236
237         if (distance >= geocoordinate_info->radius) {
238                 LOGD_GEOFENCE("FENCE_OUT : based on distance. Distance[%f]", distance);
239                 status = GEOFENCE_FENCE_STATE_OUT;
240         } else {
241                 LOGD_GEOFENCE("FENCE_IN : based on distance. Distance[%f]", distance);
242                 status = GEOFENCE_FENCE_STATE_IN;
243         }
244
245         if (__emit_fence_inout(geofence_server, item_data->common_info.fence_id, status) == 0 && status == GEOFENCE_FENCE_STATE_IN) {
246                 LOGD_GEOFENCE("Disable timer");
247         }
248 }
249
250 static void __check_current_location_cb(double latitude, double longitude, double altitude, time_t timestamp, void *user_data)
251 {
252         FUNC_ENTRANCE_SERVER;
253         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
254         location_accuracy_level_e level;
255         double hor_acc = 0.0; 
256         double ver_acc = 0.0;
257         int ret = 0;
258         int fence_id = 0;
259         GList *tracking_list = NULL;
260         GeofenceItemData *item_data = NULL;
261
262         ret = location_manager_get_accuracy(geofence_server->loc_manager, &level, &hor_acc, &ver_acc);
263         if (ret == LOCATIONS_ERROR_NONE) {
264                 LOGD_GEOFENCE("hor_acc:%f, ver_acc:%f", hor_acc, ver_acc);
265         }
266         if (hor_acc > 500) {
267                 return;
268         }
269
270         LOGD_GEOFENCE("Traversing the tracking list");
271         tracking_list = g_list_first(geofence_server->tracking_list);
272         LOGD_GEOFENCE("Got the first element in tracking list");
273
274         while (tracking_list) {
275                 fence_id = GPOINTER_TO_INT(tracking_list->data);
276                 item_data = __get_item_by_fence_id(fence_id, geofence_server);
277
278                 if (item_data != NULL) {
279                         if (item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) {
280                                 LOGD_GEOFENCE("TRACKING FENCE ID :: %d", fence_id);
281                                 __check_inout_by_gps(latitude, longitude, fence_id, geofence_server);
282                         }
283                 }
284                 tracking_list = g_list_next(tracking_list);
285         }
286         LOGD_GEOFENCE("Unsetting the position_updated_cb");
287         location_manager_unset_position_updated_cb(geofence_server->loc_manager);
288         location_manager_stop(geofence_server->loc_manager);
289         geofence_server->loc_started = FALSE;
290 }
291
292 static void __geofence_position_changed_cb(double latitude, double longitude, double altitude, time_t timestamp, void *user_data)
293 {
294         FUNC_ENTRANCE_SERVER;
295         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
296         double distance = 0;
297         int interval = 0;
298         /*Remove the timeout callback that might be running when requesting for fix.*/
299         if (geofence_server->nps_timeout_alarm_id != -1) {
300                 LOGI_GEOFENCE("Removing the timeout alarm from restart gps");
301                 geofence_server->nps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->nps_timeout_alarm_id);
302         }
303         geofence_server->last_loc_time = timestamp;
304         __check_current_location_cb(latitude, longitude, altitude, timestamp, user_data);
305
306         /* Distance based alarm */
307         distance = _get_min_distance(latitude, longitude, geofence_server);
308
309         if (distance < 200) {
310                 LOGD_GEOFENCE("interval: 1 secs");
311                 interval = 1;
312         } else if (distance < 500) {
313                 LOGD_GEOFENCE("interval: 3 secs");
314                 interval = 3;
315         } else if (distance < 1000) {
316                 LOGD_GEOFENCE("interval: 6 secs");
317                 interval = 6;
318         } else if (distance < 2000) {
319                 LOGD_GEOFENCE("interval: 20 secs");
320                 interval = 20;
321         } else if (distance < 3000) {
322                 LOGD_GEOFENCE("interval : 1 min");
323                 interval = 1 * 60;
324         } else if (distance < 5000) {
325                 LOGD_GEOFENCE("interval: 2 mins");
326                 interval = 2 * 60;
327         } else if (distance < 10000) {
328                 LOGD_GEOFENCE("interval: 5 mins");
329                 interval = 5 * 60;
330         } else if (distance < 20000) {
331                 LOGD_GEOFENCE("interval : 10 mins");
332                 interval = 10 * 60;
333         } else if (distance < 100000) {
334                 LOGD_GEOFENCE("interval : 20 mins");
335                 interval = 20 * 60;
336         } else {
337                 LOGD_GEOFENCE("interval : 60 mins");
338                 interval = 60 * 60;
339         }
340
341         /* remove the activity value when 10 hours later */
342         if (geofence_server->last_loc_time - geofence_server->activity_timestamp > 10 * 60 * 60)
343                 geofence_server->activity_type = ACTIVITY_IN_VEHICLE;
344
345         if (geofence_server->activity_type == ACTIVITY_STATIONARY)
346                 interval = interval * 10;
347         else if (geofence_server->activity_type == ACTIVITY_WALK)
348                 interval = interval * 5;
349         else if (geofence_server->activity_type == ACTIVITY_RUN)
350                 interval = interval * 3;
351
352         LOGI_GEOFENCE("Setting the interval of alrm %d s", interval);
353
354         if (geofence_server->nps_alarm_id == -1) {
355                 LOGI_GEOFENCE("Setting the nps alarm from the callback");
356                 geofence_server->nps_alarm_id = _geofence_add_alarm(interval, __nps_alarm_cb, geofence_server);
357         }
358         return;
359 }
360
361 static void __check_tracking_list(const char *bssid, void *user_data,
362         geofence_type_e type)
363 {
364         FUNC_ENTRANCE_SERVER;
365         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
366         g_return_if_fail(geofence_server);
367         int tracking_fence_id = 0;
368         GeofenceItemData *item_data = NULL;
369         GList *tracking_fences = g_list_first(geofence_server->tracking_list);
370
371         while (tracking_fences) {
372                 tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data);
373                 tracking_fences = g_list_next(tracking_fences);
374                 item_data = __get_item_by_fence_id(tracking_fence_id, geofence_server);
375                 if (item_data != NULL) {
376                         if (item_data->common_info.type == type) {
377                                 if (type == GEOFENCE_TYPE_WIFI) {
378                                         bssid_info_s *wifi_info = (bssid_info_s *)item_data->priv;
379
380                                         if ((!g_ascii_strcasecmp(wifi_info->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(wifi_info->bssid, "-", ':'), bssid)) && item_data->is_wifi_status_in == false) {
381                                                 LOGI_GEOFENCE("Matched wifi fence: fence_id = %d, bssid = %s", item_data->common_info.fence_id, wifi_info->bssid);
382                                                 item_data->is_wifi_status_in =  true;
383                                         }
384                                 } else if (type == GEOFENCE_TYPE_BT) {
385                                         bssid_info_s *bt_info = (bssid_info_s *)item_data->priv;
386
387                                         if ((!g_ascii_strcasecmp(bt_info->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(bt_info->bssid, "-", ':'), bssid)) && item_data->is_bt_status_in == false) {
388                                                 LOGI_GEOFENCE("Matched bt fence: fence_id = %d, bssid received = %s, bssid = %s", item_data->common_info.fence_id, bt_info->bssid, bssid);
389                                                 item_data->is_bt_status_in = true;
390                                         }
391                                 }
392                         }
393                 } else {
394                         LOGI_GEOFENCE("No data present for the fence: %d", tracking_fence_id);
395                 }
396         }
397 }
398
399 void bt_adapter_device_discovery_state_cb(int result, bt_adapter_device_discovery_state_e discovery_state, bt_adapter_device_discovery_info_s *discovery_info, void *user_data)
400 {
401         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
402         GeofenceItemData *item_data = NULL;
403         int i;
404         int tracking_fence_id = 0;
405         GList *tracking_fences = g_list_first(geofence_server->tracking_list);
406
407         if (discovery_state != BT_ADAPTER_DEVICE_DISCOVERY_FOUND) {
408                 LOGI_GEOFENCE("BREDR discovery %s", discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished");
409                 /* Check only if some BT fence is running */
410                 if (discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_FINISHED && geofence_server->running_bt_cnt > 0) {
411                         LOGI_GEOFENCE("Comparison for BT is done. Now emit the status...");
412                         while (tracking_fences) {
413                                 tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data);
414                                 tracking_fences = g_list_next(tracking_fences);
415                                 item_data = __get_item_by_fence_id(tracking_fence_id, geofence_server);
416                                 if (item_data && item_data->common_info.type == GEOFENCE_TYPE_BT) {
417                                         if (item_data->is_bt_status_in == true) {
418                                                 __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_IN);
419                                         } else {
420                                                 __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_OUT);
421                                         }
422                                         item_data->is_bt_status_in = false;
423                                 }
424                         }
425                 }
426         } else {
427                 LOGI_GEOFENCE("%s %s", discovery_info->remote_address, discovery_info->remote_name);
428                 LOGI_GEOFENCE("rssi: %d is_bonded: %d", discovery_info->rssi, discovery_info->is_bonded);
429
430                 if (geofence_server->running_bt_cnt > 0) {
431                         for (i = 0; i < discovery_info->service_count; i++) {
432                                 LOGI_GEOFENCE("uuid: %s", discovery_info->service_uuid[i]);
433                         }
434                         LOGI_GEOFENCE("Tracking list is being checked for the BT geofence");
435                         __check_tracking_list(discovery_info->remote_address, geofence_server, GEOFENCE_TYPE_BT);
436                 }
437         }
438 }
439
440 static void geofence_network_evt_cb(net_event_info_t *event_cb, void *user_data)
441 {
442         FUNC_ENTRANCE_SERVER;
443         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
444         g_return_if_fail(geofence_server);
445         GList *tracking_fences = g_list_first(geofence_server->tracking_list);
446         GeofenceItemData *item_data = NULL;
447         int tracking_fence_id = 0;
448
449         switch (event_cb->Event) {
450         case NET_EVENT_WIFI_SCAN_IND:
451
452                 LOGD_GEOFENCE("Got WIFI scan Ind : %d\n", event_cb->Error);
453
454                 net_profile_info_t *profiles = NULL;
455                 int num_of_profile = 0;
456
457                 if (geofence_server->running_wifi_cnt > 0) {    /*Check only if some wifi fence is running*/
458                         if (NET_ERR_NONE != net_get_profile_list(NET_DEVICE_WIFI, &profiles, &num_of_profile)) {
459                                 LOGD_GEOFENCE("Failed to get the scanned list");
460                         } else {
461                                 LOGD_GEOFENCE("Scan results retrieved successfully. No.of profiles: %d", num_of_profile);
462                                 if (num_of_profile > 0 && profiles != NULL) {
463                                         int cnt;
464                                         for (cnt = 0; cnt < num_of_profile; cnt++) {
465                                                 net_wifi_profile_info_t *ap_info = &profiles[cnt].ProfileInfo.Wlan;
466                                                 LOGD_GEOFENCE("BSSID %s", ap_info->bssid);
467                                                 __check_tracking_list(ap_info->bssid, geofence_server, GEOFENCE_TYPE_WIFI);
468                                         }
469                                         LOGD_GEOFENCE("Comparing fences with scan results is done.Now emit the status to the application");
470                                         while (tracking_fences) {
471                                                 tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data);
472                                                 tracking_fences = g_list_next(tracking_fences);
473                                                 item_data = __get_item_by_fence_id(tracking_fence_id, geofence_server);
474                                                 if (item_data && item_data->common_info.type == GEOFENCE_TYPE_WIFI) {
475                                                         if (item_data->is_wifi_status_in == true) {
476                                                                 __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_IN);
477                                                         } else {
478                                                                 __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_OUT);
479                                                         }
480                                                         item_data->is_wifi_status_in = false;
481                                                 }
482                                         }
483                                 }
484                         }
485                 }
486
487                 break;
488         default:
489                 break;
490         }
491 }
492
493 static int __start_gps_positioning(GeofenceServer *geofence_server, location_position_updated_cb callback)
494 {
495         FUNC_ENTRANCE_SERVER;
496         g_return_val_if_fail(geofence_server, -1);
497         int ret = FENCE_ERR_NONE;
498
499         if (geofence_server->loc_manager == NULL) {
500                 ret = location_manager_create(LOCATIONS_METHOD_GPS, &geofence_server->loc_manager);
501                 if (ret != LOCATIONS_ERROR_NONE) {
502                         LOGD_GEOFENCE("Fail to create location_manager_h: %d", ret);
503                         return FENCE_ERR_UNKNOWN;
504                 }
505         }
506
507         if (geofence_server->loc_started == FALSE) {
508                 ret = location_manager_set_position_updated_cb(geofence_server->loc_manager, callback, 1, (void *) geofence_server);
509                 if (ret != LOCATIONS_ERROR_NONE) {
510                         LOGD_GEOFENCE("Fail to set callback. %d", ret);
511                         return FENCE_ERR_UNKNOWN;
512                 }
513
514                 ret = location_manager_start(geofence_server->loc_manager);
515                 if (ret != LOCATIONS_ERROR_NONE) {
516                         LOGD_GEOFENCE("Fail to start. %d", ret);
517                         return FENCE_ERR_UNKNOWN;
518                 }
519                 if (geofence_server->nps_timeout_alarm_id == -1)
520                         geofence_server->nps_timeout_alarm_id = _geofence_add_alarm(NPS_TIMEOUT, __nps_timeout_cb, geofence_server);
521
522                 geofence_server->loc_started = TRUE;
523         } else {
524                 LOGD_GEOFENCE("loc_started TRUE");
525         }
526
527         return ret;
528 }
529
530 static void __stop_gps_positioning(gpointer userdata)
531 {
532         FUNC_ENTRANCE_SERVER;
533         g_return_if_fail(userdata);
534         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
535         int ret = 0;
536         if (geofence_server->loc_started == TRUE) {
537                 ret = location_manager_stop(geofence_server->loc_manager);
538                 if (ret != LOCATIONS_ERROR_NONE) {
539                         return;
540                 }
541                 geofence_server->loc_started = FALSE;
542                 ret = location_manager_unset_position_updated_cb
543                         (geofence_server->loc_manager);
544                 if (ret != LOCATIONS_ERROR_NONE) {
545                         return;
546                 }
547         }
548
549         if (geofence_server->loc_manager != NULL) {
550                 ret = location_manager_destroy(geofence_server->loc_manager);
551                 if (ret != LOCATIONS_ERROR_NONE) {
552                         return;
553                 }
554                 geofence_server->loc_manager = NULL;
555         }
556 }
557
558 static int __nps_timeout_cb(alarm_id_t alarm_id, void *user_data)
559 {
560         LOGI_GEOFENCE("__nps_timeout_cb");
561         g_return_val_if_fail(user_data, -1);
562         LOGD_GEOFENCE("alarm_id : %d", alarm_id);
563         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
564         geofence_server->nps_timeout_alarm_id = -1;     /*resetting the alarm id*/
565         /*Stop the gps for sometime when there is no fix*/
566         __stop_gps_positioning(geofence_server);
567         geofence_server->nps_alarm_id = _geofence_add_alarm(1 * 60, __nps_alarm_cb, geofence_server);
568         display_unlock_state(LCD_OFF, PM_RESET_TIMER);
569         return 0;
570 }
571
572 static int __nps_alarm_cb(alarm_id_t alarm_id, void *user_data)
573 {
574         LOGI_GEOFENCE("__nps_alarm_cb");
575         g_return_val_if_fail(user_data, -1);
576         LOGD_GEOFENCE("alarm_id : %d", alarm_id);
577         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
578         __start_gps_positioning(geofence_server, __geofence_position_changed_cb);
579         geofence_server->nps_alarm_id = -1;
580         return 0;
581 }
582
583 static void gps_setting_changed_cb(location_method_e method, bool enable,
584         void *user_data)
585 {
586         FUNC_ENTRANCE_SERVER;
587         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
588         g_return_if_fail(geofence_server);
589         GList *tracking_fences = g_list_first(geofence_server->tracking_list);
590         GeofenceItemData *item_data = NULL;
591         int tracking_fence_id = 0;
592         int ret = FENCE_ERR_NONE;
593         if (enable == false && geofence_server->running_geopoint_cnt > 0) {
594                 LOGI_GEOFENCE("Stopping the GPS from settings callback");
595                 __stop_gps_positioning(geofence_server);
596
597                 /*Stop the interval alarm if it is running...*/
598                 if (geofence_server->nps_alarm_id != -1) {
599                         LOGI_GEOFENCE("Interval timer removed. ID[%d]", geofence_server->nps_alarm_id);
600                         geofence_server->nps_alarm_id = _geofence_remove_alarm(geofence_server->nps_alarm_id);
601                 }
602                 /*stop the timeout alarm if it is running...*/
603                 if (geofence_server->nps_timeout_alarm_id != -1) {
604                         LOGI_GEOFENCE("Timeout timer removed. ID[%d]",
605                                 geofence_server->nps_timeout_alarm_id);
606                         geofence_server->nps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->nps_timeout_alarm_id);
607                 }
608                 while (tracking_fences) {
609                         tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data);
610                         tracking_fences = g_list_next(tracking_fences);
611                         item_data = __get_item_by_fence_id(tracking_fence_id, geofence_server);
612                         if (item_data && item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) {
613                                 __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_OUT);
614                         }
615                 }
616         } else if (enable == true && geofence_server->running_geopoint_cnt > 0) {
617                 ret = __start_gps_positioning(geofence_server, __geofence_position_changed_cb);
618                 if (ret != FENCE_ERR_NONE) {
619                         LOGE_GEOFENCE("Fail to start gps positioning. Error[%d]", ret);
620                         return;
621                 }
622         }
623 }
624
625 #if 0 /* Not used */
626 static int __check_fence_interval(alarm_id_t alarm_id, void *data)
627 {
628         return TRUE;
629 }
630
631 static void __pause_geofence_service(void *userdata)
632 {
633         FUNC_ENTRANCE_SERVER;
634         g_return_if_fail(userdata);
635 }
636
637 static void __resume_geofence_service(void *userdata)
638 {
639         FUNC_ENTRANCE_SERVER;
640         g_return_if_fail(userdata);
641 }
642 #endif
643
644 /*********************************THIS HAS TO BE USED ONLY FOR TESTING*********************************************/
645 #ifdef __LOCAL_TEST__
646 static void __free_geofence_list(gpointer userdata)
647 {
648         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
649
650         GList *tmp_fence_list = g_list_first(geofence_server->geofence_list);
651         while (tmp_fence_list) {
652                 GeofenceItemData *tmp_data = (GeofenceItemData *)tmp_fence_list->data;
653                 if (tmp_data) {
654                         g_free(tmp_data);
655                 }
656                 tmp_fence_list = g_list_next(tmp_fence_list);
657         }
658         geofence_server->geofence_list = NULL;
659 }
660 #endif
661
662 static int __check_fence_permission(int fence_id, const char *app_id)
663 {
664         access_type_e access_type = ACCESS_TYPE_PUBLIC;
665         char *appid;
666         int ret = FENCE_ERR_NONE;
667         ret = geofence_manager_get_access_type(fence_id, -1, &access_type);
668         if (ret != FENCE_ERR_NONE) {
669                 LOGE("Error getting the access_type");
670                 return -1;
671         }
672         if (access_type == ACCESS_TYPE_PRIVATE) {
673                 ret = geofence_manager_get_appid_from_geofence(fence_id, &appid);
674                 if (ret != FENCE_ERR_NONE) {
675                         LOGE("Error getting the app_id for fence_id[%d]", fence_id);
676                         return -1;
677                 }
678                 if (g_strcmp0(appid, app_id)) {
679                         LOGE("Not authorized to access this private fence[%d]", fence_id);
680                         return 0;
681                 }
682         }
683         return 1;
684 }
685
686 static int __check_place_permission(int place_id, const char *app_id)
687 {
688         access_type_e access_type = ACCESS_TYPE_PUBLIC;
689         char *appid;
690         int ret = FENCE_ERR_NONE;
691         ret = geofence_manager_get_access_type(-1, place_id, &access_type);
692         if (ret != FENCE_ERR_NONE) {
693                 LOGE("Error getting the access_type");
694                 return -1;
695         }
696         if (access_type == ACCESS_TYPE_PRIVATE) {
697                 ret = geofence_manager_get_appid_from_places(place_id, &appid);
698                 if (ret != FENCE_ERR_NONE) {
699                         LOGE("Error getting the place_id for place_id[%d]", place_id);
700                         return -1;
701                 }
702                 if (g_strcmp0(appid, app_id)) {
703                         LOGE("Not authorized to access this private place[%d]", place_id);
704                         return 0;
705                 }
706         }
707         return 1;
708 }
709
710 static int __add_fence(const gchar *app_id,
711         gint place_id,
712         gint geofence_type,
713         gdouble latitude,
714         gdouble longitude,
715         gint radius,
716         const gchar *address,
717         const gchar *bssid, const gchar *ssid, gpointer userdata)
718 {
719         FUNC_ENTRANCE_SERVER;
720         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
721
722         /* create fence id*/
723         int fence_id = -1;
724         int ret = FENCE_ERR_NONE;
725         void *next_item_ptr = NULL;
726         time_t cur_time;
727         time(&cur_time);
728         access_type_e access_type;
729
730         ret = geofence_manager_get_access_type(-1, place_id, &access_type);
731         if (ret != FENCE_ERR_NONE) {
732                 LOGI_GEOFENCE("Error fetching the access type from the DB for place: %d or place-id does not exist.", place_id);
733                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_FENCE_ADDED);
734                 return -1;
735         }
736
737         ret = __check_place_permission(place_id, app_id);
738         if (ret != 1) {
739                 LOGE("Unable to add the fence. Permission denied or DB error occured while accessing the place[%d]", place_id);
740                 if (ret == 0) {
741                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_ADDED);
742                 } else {
743                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_ADDED);
744                 }
745                 return -1;
746         }
747         /* create GeofenceItemData item, and append it into geofence_list*/
748         GeofenceItemData *item_data = (GeofenceItemData *)g_malloc0(sizeof(GeofenceItemData));
749         if (item_data == NULL) {
750                 LOGI_GEOFENCE("Unable to add the fence because of malloc fail");
751                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_FENCE_ADDED);
752                 return -1;
753         }
754
755         item_data->distance = -1;
756         item_data->client_status = GEOFENCE_CLIENT_STATUS_NONE;
757         item_data->common_info.type = geofence_type;
758         /*fences added by myplaces application are public fences by default*/
759         if (!g_strcmp0(app_id, MYPLACES_APPID)) {
760                 item_data->common_info.access_type = ACCESS_TYPE_PUBLIC;
761         } else {
762                 item_data->common_info.access_type = ACCESS_TYPE_PRIVATE;
763         }
764         item_data->common_info.enable = 1;
765         item_data->common_info.status = GEOFENCE_FENCE_STATE_UNCERTAIN;
766         item_data->is_wifi_status_in = false;
767         item_data->is_bt_status_in = false;
768         g_strlcpy(item_data->common_info.appid, app_id, APP_ID_LEN);
769         item_data->common_info.running_status = 0;
770         item_data->common_info.place_id = place_id;
771
772         /*DB is called and fence-id is retrieved from there(by auto increment mechanism)*/
773         geofence_manager_set_common_info(&(item_data->common_info), &fence_id);
774         item_data->common_info.fence_id = fence_id;
775         LOGD_GEOFENCE("fence id : %d", item_data->common_info.fence_id);
776
777         if (geofence_type == GEOFENCE_TYPE_GEOPOINT) {
778                 LOGD_GEOFENCE("Add geofence with GeoPoint");
779                 geocoordinate_info_s *geocoordinate_info = (geocoordinate_info_s *)g_malloc0(sizeof(geocoordinate_info_s));
780                 if (geocoordinate_info == NULL) {
781                         LOGI_GEOFENCE("Fail to set geocoordinate_info for GPS because of malloc fail");
782                         __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_FENCE_ADDED);
783                         return -1;
784                 }
785                 geocoordinate_info->latitude = latitude;
786                 geocoordinate_info->longitude = longitude;
787                 if (radius < GEOFENCE_DEFAULT_RADIUS) {
788                         geocoordinate_info->radius = GEOFENCE_DEFAULT_RADIUS;
789                 } else {
790                         geocoordinate_info->radius = radius;
791                 }
792                 g_strlcpy(geocoordinate_info->address, address, ADDRESS_LEN);
793
794                 /*Geopoint information is saved in the DB*/
795                 ret = geofence_manager_set_geocoordinate_info(fence_id, geocoordinate_info);
796                 if (ret != FENCE_ERR_NONE) {
797                         LOGI_GEOFENCE("Fail to set geocoordinate_info");
798                         ret = geofence_manager_delete_fence_info(fence_id);
799                         if (ret != FENCE_ERR_NONE)
800                                 LOGI_GEOFENCE("Fail to delete fence_id[%d] from common table", fence_id);
801                         __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_ADDED);
802                         return -1;
803                 }
804                 item_data->priv = (void *) geocoordinate_info;
805
806         } else if (geofence_type == GEOFENCE_TYPE_WIFI) {       /* Specific AP */
807                 LOGD_GEOFENCE("Add geofence with specific AP");
808
809                 bssid_info_s *wifi_info = NULL;
810                 wifi_info = (bssid_info_s *) g_malloc0(sizeof(bssid_info_s));
811                 if (wifi_info == NULL) {
812                         LOGI_GEOFENCE("Fail to set bssid_info for wifi because of malloc fail");
813                         __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_FENCE_ADDED);
814                         return -1;
815                 }
816                 g_strlcpy(wifi_info->bssid, bssid, WLAN_BSSID_LEN);
817                 g_strlcpy(wifi_info->ssid, ssid, WLAN_BSSID_LEN);
818
819                 /*Wifi information is saved in the DB(both wifi and BT share the same bssid table here)*/
820                 ret = geofence_manager_set_bssid_info(fence_id, wifi_info);
821                 if (ret != FENCE_ERR_NONE) {
822                         LOGI_GEOFENCE("Fail to set bssid_info for wifi");
823                         ret = geofence_manager_delete_fence_info(fence_id);
824                         if (ret != FENCE_ERR_NONE)
825                                 LOGI_GEOFENCE("Fail to delete fence_id[%d] from common table", fence_id);
826                         __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_ADDED);
827                         return -1;
828                 }
829                 item_data->priv = (void *) wifi_info;
830         } else if (geofence_type == GEOFENCE_TYPE_BT) {
831                 LOGD_GEOFENCE("Add geofence with bluetooth bssid");
832
833                 bssid_info_s *bt_info = NULL;
834                 bt_info = (bssid_info_s *) g_malloc0(sizeof(bssid_info_s));
835                 if (bt_info == NULL) {
836                         LOGI_GEOFENCE("Fail to set bssid_info for BT because of malloc fail");
837                         __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_FENCE_ADDED);
838                         return -1;
839                 }
840                 bt_info->enabled = TRUE;
841                 g_strlcpy(bt_info->bssid, bssid, WLAN_BSSID_LEN);
842                 g_strlcpy(bt_info->ssid, ssid, WLAN_BSSID_LEN);
843
844                 /*BT info is saved in the DB(both wifi and BT share the same bssid table here)*/
845                 ret = geofence_manager_set_bssid_info(fence_id, bt_info);
846                 if (ret != FENCE_ERR_NONE) {
847                         LOGI_GEOFENCE("Fail to set bssid_info for BT");
848                         ret = geofence_manager_delete_fence_info(fence_id);
849                         if (ret != FENCE_ERR_NONE)
850                                 LOGI_GEOFENCE("Fail to delete fence_id[%d] from common table", fence_id);
851                         __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_ADDED);
852                         return -1;
853                 }
854                 item_data->priv = (void *) bt_info;
855         }
856         /*Adding the data to the geofence_list which contains the added geofences list information*/
857         if (geofence_server->geofence_list == NULL) {
858                 geofence_server->geofence_list = g_list_append(geofence_server->geofence_list, item_data);
859         } else {
860                 geofence_server->geofence_list = g_list_insert_before(geofence_server->geofence_list, next_item_ptr, item_data);
861         }
862         /*This code is just for testing purpose. It will be removed after the development phase - Karthik*/
863         int temp_cnt = 0;
864         GList *temp_list = g_list_first(geofence_server->geofence_list);
865         temp_list = g_list_first(geofence_server->geofence_list);
866         while (temp_list) {
867                 temp_cnt++;
868                 temp_list = g_list_next(temp_list);
869         }
870         LOGI_GEOFENCE("Fences in local list: %d", temp_cnt);
871         geofence_manager_get_count_of_fences(&temp_cnt);
872         LOGI_GEOFENCE("Fence count in DB: %d", temp_cnt);
873
874         /*Emit the error code*/
875         __emit_fence_event(geofence_server, place_id, fence_id, item_data->common_info.access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_ADDED);
876         return fence_id;
877 }
878
879 static int __add_place(const gchar *app_id,
880         const gchar *place_name, gpointer userdata)
881 {
882         FUNC_ENTRANCE_SERVER;
883         int place_id = -1;
884         int ret = FENCE_ERR_NONE;
885         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
886         place_info_s *place_info = (place_info_s *)g_malloc0(sizeof(place_info_s));
887
888         if (place_info == NULL) {
889                 LOGI_GEOFENCE("Unable to add the place due to malloc fail");
890                 __emit_fence_event(geofence_server, -1, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_PLACE_ADDED);
891                 return -1;
892         }
893         /*fences added by myplaces application are public fences by default*/
894         if (!g_strcmp0(app_id, MYPLACES_APPID))
895                 place_info->access_type = ACCESS_TYPE_PUBLIC;
896         else
897                 place_info->access_type = ACCESS_TYPE_PRIVATE;
898
899         g_strlcpy(place_info->place_name, place_name, PLACE_NAME_LEN);
900         g_strlcpy(place_info->appid, app_id, APP_ID_LEN);
901         /*Add the place details to db*/
902         ret = geofence_manager_set_place_info(place_info, &place_id);
903         if (ret != FENCE_ERR_NONE) {
904                 LOGI_GEOFENCE("Unable to add the place due to DB error");
905                 __emit_fence_event(geofence_server, -1, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_ADDED);
906                 return -1;
907         }
908         __emit_fence_event(geofence_server, place_id, -1, place_info->access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_PLACE_ADDED);
909
910         return place_id;
911 }
912
913 static void __enable_service(gint fence_id, const gchar *app_id, gboolean enable, gpointer userdata)
914 {
915         FUNC_ENTRANCE_SERVER;
916         g_return_if_fail(userdata);
917
918         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
919         int ret = FENCE_ERR_NONE;
920         access_type_e access_type = ACCESS_TYPE_UNKNOWN;
921         int place_id = -1;
922         int enable_status = 0;
923         geofence_manage_e manage_enum = GEOFENCE_MANAGE_SETTING_ENABLED;
924
925         if (enable == 0)
926                 manage_enum = GEOFENCE_MANAGE_SETTING_DISABLED;
927
928         ret = geofence_manager_get_access_type(fence_id, -1, &access_type);
929         if (ret != FENCE_ERR_NONE) {
930                 LOGI_GEOFENCE("Error fetching the access type from the DB for fence: %d or fence-id does not exist.", fence_id);
931                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, manage_enum);
932                 return;
933         }
934         ret = geofence_manager_get_place_id(fence_id, &place_id);
935         if (ret != FENCE_ERR_NONE) {
936                 LOGI_GEOFENCE("Error fetching the place_id from the DB for fence: %d", fence_id);
937                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, manage_enum);
938                 return;
939         }
940         if (access_type == ACCESS_TYPE_PUBLIC) {
941                 if (g_strcmp0(app_id, MYPLACES_APPID) != 0) {
942                         LOGI_GEOFENCE("Received: %s", app_id);
943                         LOGI_GEOFENCE("Not authorized to enable/disable this fence[%d] service.", fence_id);
944                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, manage_enum);
945                         return;
946                 }
947                 if (enable == true)
948                         enable_status = 1;
949                 ret = geofence_manager_set_enable_status(fence_id, enable_status);
950                 if (ret != FENCE_ERR_NONE) {
951                         LOGI_GEOFENCE("DB error in enabling/disabling the fence[%d].", fence_id);
952                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, manage_enum);
953                         return;
954                 }
955         } else {
956                 LOGI_GEOFENCE("Currently, only public fences can be enabled/disabled. It can be done by MyPlaces app only.");
957         }
958         /*Emit the error code*/
959         __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, manage_enum);
960 }
961
962 static void __update_place(gint place_id, const gchar *app_id, const gchar *place_name, gpointer userdata)
963 {
964         FUNC_ENTRANCE_SERVER;
965         int ret = FENCE_ERR_NONE;
966         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
967
968         if (place_id == DEFAULT_PLACE_HOME || place_id == DEFAULT_PLACE_OFFICE || place_id == DEFAULT_PLACE_CAR) {
969                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED, GEOFENCE_MANAGE_PLACE_UPDATED);
970                 return;
971         }
972
973         place_info_s *place_info = (place_info_s *) g_malloc0(sizeof(place_info_s));
974         if (place_info == NULL) {
975                 LOGI_GEOFENCE("malloc fail for place id[%d]", place_id);
976                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_PLACE_UPDATED);
977                 return;
978         }
979         ret = geofence_manager_get_place_info(place_id, &place_info);
980         if (ret != FENCE_ERR_NONE) {
981                 LOGI_GEOFENCE("Place_id does not exist or DB error in getting the place info for place_id[%d].", place_id);
982                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_PLACE_UPDATED);
983                 g_free(place_info);
984                 return;
985         }
986         if (g_strcmp0(app_id, place_info->appid) != 0) {
987                 LOGI_GEOFENCE("Not authorized to update the place");
988                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED, GEOFENCE_MANAGE_PLACE_UPDATED);
989                 g_free(place_info);
990                 return;
991         }
992
993         /*Update the place details to db*/
994         ret = geofence_manager_update_place_info(place_id, place_name);
995         if (ret != FENCE_ERR_NONE) {
996                 LOGI_GEOFENCE("Unable to update the place");
997                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_UPDATED);
998                 g_free(place_info);
999                 return;
1000         }
1001         __emit_fence_event(geofence_server, place_id, -1, place_info->access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_PLACE_UPDATED);
1002         g_free(place_info);
1003 }
1004
1005 static void __remove_fence(gint fence_id, const gchar *app_id, gpointer userdata)
1006 {
1007         FUNC_ENTRANCE_SERVER;
1008         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
1009         g_return_if_fail(geofence_server);
1010         int ret = FENCE_ERR_NONE;
1011         int place_id = -1;
1012         char *app_id_db;
1013         access_type_e access_type = ACCESS_TYPE_UNKNOWN;
1014
1015         /*//////////Required to be sent in the event callback////////////////--*/
1016         ret = geofence_manager_get_place_id(fence_id, &place_id);
1017         if (ret != FENCE_ERR_NONE) {
1018                 LOGI_GEOFENCE("Error fetching the place_id from the DB for fence: %d or fence-id does not exist", fence_id);
1019                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_FENCE_REMOVED);
1020                 return;
1021         }
1022         /*//////////////////////////////////////////////////////////////////--*/
1023         ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id_db);
1024         if (ret != FENCE_ERR_NONE) {
1025                 LOGI_GEOFENCE("Failed to get the appid, Error - %d", ret);
1026                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED);
1027                 return;
1028         }
1029         if (g_strcmp0(app_id_db, app_id) != 0) {
1030                 LOGI_GEOFENCE("Not authorized to remove the fence");
1031                 g_free(app_id_db);
1032                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_REMOVED);
1033                 return;
1034         }
1035         g_free(app_id_db);
1036         /*/////////required to be sent in the event callback///////////////--*/
1037         ret = geofence_manager_get_access_type(fence_id, -1, &access_type);
1038         if (ret != FENCE_ERR_NONE) {
1039                 LOGI_GEOFENCE("Error fetching the access type from the DB for fence: %d", fence_id);
1040                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED);
1041                 return;
1042         }
1043         /*///////////////////////////////////////////////////////////////////////--*/
1044         GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server);
1045         if (item_data == NULL) {
1046                 LOGI_GEOFENCE("Invalid fence_id[%d]", fence_id);
1047                 return;
1048         }
1049
1050         /*Stop the geofence service for the fence first if it is running*/
1051         int tracking_status = -1;
1052         ret = geofence_manager_get_running_status(fence_id, &tracking_status);
1053         if (ret != FENCE_ERR_NONE) {
1054                 LOGI_GEOFENCE("Error fetching the running status from the DB for fence: %d or fence-id does not exist", fence_id);
1055                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED);
1056                 return;
1057         }
1058         if (tracking_status == 1) {
1059                 __stop_geofence_service(fence_id, app_id, userdata);
1060         } else if (tracking_status > 1) {/*its a public fence*/
1061                 tracking_status = 1;    /*resetting the running status to 1 for forcefull stop from MYPlacesApp*/
1062                 ret = geofence_manager_set_running_status(fence_id, tracking_status);
1063                 if (ret != FENCE_ERR_NONE) {
1064                         LOGI_GEOFENCE("Error resetting the running status in the DB for fence: %d or fence-id does not exist", fence_id);
1065                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED);
1066                         return;
1067                 }
1068                 __stop_geofence_service(fence_id, app_id, userdata);
1069         }
1070         /*Removing the fence id from the DB*/
1071         ret = geofence_manager_delete_fence_info(fence_id);
1072         if (ret != FENCE_ERR_NONE) {
1073                 LOGI_GEOFENCE("Fail to delete fence_id[%d]", fence_id);
1074                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED);
1075                 return;
1076         }
1077
1078         /*Removing the fence id from the geofence_list which contains the added fence list details*/
1079         geofence_server->geofence_list = g_list_remove(geofence_server->geofence_list, item_data);
1080         LOGI_GEOFENCE("Removed fence_id[%d]", fence_id);
1081         g_free(item_data);      /*freeing the memory*/
1082
1083         /*Check if the length of the geofence_list is 0 then free and make it null*/
1084         if (g_list_length(geofence_server->geofence_list) == 0) {
1085                 g_list_free(geofence_server->geofence_list);
1086                 geofence_server->geofence_list = NULL;
1087         }
1088         /*Emit the error code*/
1089         __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_REMOVED);
1090 }
1091
1092 static void __get_place_name(gint place_id, const gchar *app_id, char **place_name, int *error_code, gpointer userdata)
1093 {
1094         FUNC_ENTRANCE_SERVER;
1095         access_type_e access_type = ACCESS_TYPE_UNKNOWN;
1096
1097         int ret = geofence_manager_get_access_type(-1, place_id, &access_type);
1098         if (ret != FENCE_ERR_NONE) {
1099                 LOGI_GEOFENCE("Error fetching the access type from the DB for place: %d or place-id does not exist.", place_id);
1100                 *error_code = GEOFENCE_SERVER_ERROR_ID_NOT_EXIST;
1101                 return;
1102         }
1103
1104         ret = __check_place_permission(place_id, app_id);
1105         if (ret != 1) {
1106                 LOGE("Unable to get the place name. Permission denied or DB error occured while accessing the place[%d]", place_id);
1107                 if (ret == 0) {
1108                         *error_code = GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED;
1109                 } else {
1110                         *error_code = GEOFENCE_SERVER_ERROR_DATABASE;
1111                 }
1112                 return;
1113         }
1114         ret = geofence_manager_get_place_name(place_id, place_name);
1115         if (ret != FENCE_ERR_NONE) {
1116                 *error_code = GEOFENCE_SERVER_ERROR_DATABASE;
1117                 return;
1118         }
1119         *error_code = GEOFENCE_SERVER_ERROR_NONE;
1120 }
1121
1122 static void __remove_place(gint place_id, const gchar *app_id,
1123         gpointer userdata)
1124 {
1125         FUNC_ENTRANCE_SERVER;
1126         g_return_if_fail(userdata);
1127         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
1128         GList *fence_list = NULL, *list = NULL;
1129         int fence_cnt = 0;
1130         int tracking_status = 0;
1131         int ret = FENCE_ERR_NONE;
1132         GeofenceItemData *item_data = NULL;
1133         access_type_e access_type = ACCESS_TYPE_UNKNOWN;
1134
1135         /* Default places */
1136         if (place_id == DEFAULT_PLACE_HOME || place_id == DEFAULT_PLACE_OFFICE || place_id == DEFAULT_PLACE_CAR) {
1137                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED, GEOFENCE_MANAGE_PLACE_REMOVED);
1138                 return;
1139         }
1140         ret = geofence_manager_get_access_type(-1, place_id, &access_type);
1141         if (ret != FENCE_ERR_NONE) {
1142                 LOGE("Unable to fetch the access type for place_id[%d]", place_id);
1143                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_PLACE_REMOVED);
1144                 return;
1145         }
1146
1147         place_info_s *place_info =
1148                 (place_info_s *) g_malloc0(sizeof(place_info_s));
1149         ret = geofence_manager_get_place_info(place_id, &place_info);
1150         if (ret != FENCE_ERR_NONE) {
1151                 LOGI_GEOFENCE("Place_id does not exist or DB error in getting the place info for place_id[%d].", place_id);
1152                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_PLACE_REMOVED);
1153                 g_free(place_info);
1154                 return;
1155         }
1156         if (g_strcmp0(app_id, place_info->appid) != 0) {
1157                 LOGI_GEOFENCE("Not authorized to remove the place");
1158                 g_free(place_info);
1159                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED, GEOFENCE_MANAGE_PLACE_REMOVED);
1160                 return;
1161         }
1162         g_free(place_info);
1163
1164         ret = geofence_manager_get_fenceid_list_from_db(&fence_cnt, &fence_list, place_id);
1165         if (ret != FENCE_ERR_NONE) {
1166                 LOGE("Unable to fetch the fence list from the DB");
1167                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_REMOVED);
1168                 return;
1169         }
1170         int fence_id = 0;
1171         list = g_list_first(fence_list);
1172         while (list) {
1173                 fence_id = GPOINTER_TO_INT(list->data);
1174                 item_data = __get_item_by_fence_id(fence_id, geofence_server);
1175                 ret = geofence_manager_get_running_status(fence_id, &tracking_status);
1176                 if (ret != FENCE_ERR_NONE) {
1177                         LOGE("Unable to fetch the running status before removing the fence while removing a place");
1178                         __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_REMOVED);
1179                         return;
1180                 }
1181                 if (tracking_status == 1) {
1182                         __stop_geofence_service(fence_id, app_id, userdata);
1183                 } else if (tracking_status > 1) {
1184                         tracking_status = 1;    /*resetting the running status as it is a forcefull stop from MYPlacesApp*/
1185                         ret = geofence_manager_set_running_status(fence_id, tracking_status);
1186                         if (ret != FENCE_ERR_NONE) {
1187                                 LOGI_GEOFENCE("Error setting the running status from the DB for fence: %d or fence-id does not exist", fence_id);
1188                                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_REMOVED);
1189                                 return;
1190                         }
1191                         __stop_geofence_service(fence_id, app_id, userdata);
1192                 }
1193
1194                 /*Removing the fence id from the geofence_list which contains the added fence list details*/
1195                 geofence_server->geofence_list = g_list_remove(geofence_server->geofence_list, item_data);
1196                 LOGI_GEOFENCE("Removed fence_id[%d]", fence_id);
1197                 g_free(item_data);
1198                 /*Check if the length of the geofence_list is 0 then free and make it null*/
1199                 if (g_list_length(geofence_server->geofence_list) == 0) {
1200                         g_list_free(geofence_server->geofence_list);
1201                         geofence_server->geofence_list = NULL;
1202                 }
1203                 list = g_list_next(list);
1204         }
1205         ret = geofence_manager_delete_place_info(place_id);
1206         if (ret != FENCE_ERR_NONE) {
1207                 LOGI_GEOFENCE("DB error occured while removing the place from DB");
1208                 __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_REMOVED);
1209                 return;
1210         }
1211         __emit_fence_event(geofence_server, place_id, -1, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_PLACE_REMOVED);
1212 }
1213
1214 static void __start_geofence_service(gint fence_id, const gchar *app_id, gpointer userdata)
1215 {
1216         FUNC_ENTRANCE_SERVER;
1217         g_return_if_fail(userdata);
1218
1219         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
1220         int tracking_fence_id = -1;
1221         void *next_item_ptr = NULL;
1222         GList *track_list = g_list_first(geofence_server->tracking_list);
1223         GeofenceItemData *item_data = NULL;
1224
1225         int ret = FENCE_ERR_NONE;
1226         int tracking_status = -1;
1227         int place_id = -1;
1228         access_type_e access_type = ACCESS_TYPE_UNKNOWN;
1229         char *app_id_db = NULL;
1230         geofence_fence_state_e status_to_be_emitted = GEOFENCE_FENCE_STATE_UNCERTAIN;
1231
1232         item_data = __get_item_by_fence_id(fence_id, geofence_server);  /*Fetch the fence details from add_list*/
1233         if (item_data == NULL) {
1234                 LOGI_GEOFENCE("Invalid fence id - no fence exists with this fence id");
1235                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_FENCE_STARTED);
1236                 return;         /*Invalid fence id - no fence exists with this fence id*/
1237         }
1238         if (!g_strcmp0(app_id, MYPLACES_APPID)) {
1239                 LOGI_GEOFENCE("My Places cannot start a fence");
1240                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_STARTED);
1241                 return;
1242         }
1243         ret = geofence_manager_get_place_id(fence_id, &place_id);
1244         if (ret != FENCE_ERR_NONE) {
1245                 LOGI_GEOFENCE("Error fetching the place_id from the DB for fence: %d", fence_id);
1246                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED);
1247                 return;
1248         }
1249
1250         ret = geofence_manager_get_running_status(fence_id, &tracking_status);
1251         if (ret != FENCE_ERR_NONE) {
1252                 LOGI_GEOFENCE("Error fetching the running status from the DB for fence: %d or fence-id does not exist.", fence_id);
1253                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED);
1254                 return;
1255         }
1256
1257         ret = geofence_manager_get_access_type(fence_id, -1, &access_type);
1258         if (ret != FENCE_ERR_NONE) {
1259                 LOGE("Error getting the access_type");
1260                 return;
1261         }
1262         if (access_type == ACCESS_TYPE_PRIVATE) {
1263                 ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id_db);
1264                 if (ret != FENCE_ERR_NONE) {
1265                         LOGE("Error getting the app_id for fence_id[%d]", fence_id);
1266                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED);
1267                         return;
1268                 }
1269                 if (g_strcmp0(app_id_db, app_id)) {
1270                         LOGE("Not authorized to access this private fence[%d]", fence_id);
1271                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_STARTED);
1272                         g_free(app_id_db);
1273                         return;
1274                 }
1275                 g_free(app_id_db);
1276                 if (tracking_status == 1) {
1277                         LOGI_GEOFENCE("Private fence ID: %d, already exists in the tracking list", fence_id);
1278                         __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_ALREADY_STARTED, GEOFENCE_MANAGE_FENCE_STARTED);
1279                         return;
1280                 } else {
1281                         ret = geofence_manager_set_running_status(fence_id, 1);
1282                         if (ret != FENCE_ERR_NONE) {
1283                                 LOGI_GEOFENCE("Error setting the fence status");
1284                                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED);
1285                                 return;
1286                         }
1287                         tracking_status = 1;
1288                 }
1289         } else if (access_type == ACCESS_TYPE_PUBLIC) {
1290                 int enable = -1;
1291                 ret = geofence_manager_get_enable_status(fence_id, &enable);
1292                 if (ret != FENCE_ERR_NONE) {
1293                         LOGI_GEOFENCE("Error fetching the enable status from the DB for fence: %d or fence-id does not exist.", fence_id);
1294                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED);
1295                         return;
1296                 }
1297                 if (enable == 0) {
1298                         LOGI_GEOFENCE("Error - Fence[%d] is not enabled",
1299                                 fence_id);
1300                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_STARTED);
1301                         return;
1302                 }
1303                 if (tracking_status > 0) {
1304                         LOGI_GEOFENCE("Public fence ID: %d, already exists in the tracking list, incrementing the counter for fence", fence_id);
1305                         ret = geofence_manager_set_running_status(fence_id, (tracking_status + 1));
1306                         if (ret != FENCE_ERR_NONE) {
1307                                 LOGI_GEOFENCE("Error setting the fence status");
1308                                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED);
1309                                 return;
1310                         }
1311                         __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STARTED);
1312                         return;
1313                 } else {
1314                         ret = geofence_manager_set_running_status(fence_id, (tracking_status + 1));
1315                         if (ret != FENCE_ERR_NONE) {
1316                                 LOGI_GEOFENCE("Error setting the fence status");
1317                                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED);
1318                                 return;
1319                         }
1320                         tracking_status++;
1321                 }
1322         }
1323
1324         item_data->client_status = GEOFENCE_CLIENT_STATUS_START;
1325
1326         if (item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) {
1327                 ret = __start_gps_positioning(geofence_server, __geofence_position_changed_cb);
1328                 if (ret != FENCE_ERR_NONE) {
1329                         LOGE_GEOFENCE("Fail to start gps positioning. Error[%d]", ret);
1330                         geofence_manager_set_running_status(fence_id, (tracking_status - 1));
1331                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_IPC, GEOFENCE_MANAGE_FENCE_STARTED);
1332                         return;
1333                 }
1334                 geofence_server->running_geopoint_cnt++;
1335                 
1336                 __start_activity_service(geofence_server);
1337         } else if (item_data->common_info.type == GEOFENCE_TYPE_BT) {
1338                 LOGI_GEOFENCE("fence_type [GEOFENCE_TYPE_BT]");
1339
1340                 bssid_info_s *bt_info = NULL;
1341                 if (item_data->priv != NULL) {
1342                         bt_info = (bssid_info_s *) item_data->priv;
1343                         if (!bt_info->enabled)
1344                                 bt_info->enabled = TRUE;
1345                 }
1346                 bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED;
1347                 bt_error_e error = BT_ERROR_NONE;
1348                 error = bt_adapter_get_state(&adapter_state);
1349                 if (error == BT_ERROR_NONE) {
1350                         geofence_server->running_bt_cnt++;
1351                         if (adapter_state == BT_ADAPTER_DISABLED) {
1352                                 LOGE_GEOFENCE("BT Adapter is DISABLED");
1353                                 status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT;
1354                         } else if (adapter_state == BT_ADAPTER_ENABLED) {
1355                                 bt_device_info_s *bt_device_info = NULL;
1356                                 if (bt_info != NULL) {
1357                                         ret = bt_adapter_get_bonded_device_info(bt_info->bssid, &bt_device_info);
1358                                         if (ret != BT_ERROR_NONE) {
1359                                                 LOGE_GEOFENCE("Fail to get the bonded device info/ Not bonded with any device. Error[%d]", ret);
1360                                                 /*NEED TO BE DECIDED WHETHER TO REQUEST FOR A SCAN HERE OR JUST EMIT OUT AS STATUS*/
1361                                                 if (ret == BT_ERROR_REMOTE_DEVICE_NOT_BONDED)
1362                                                         status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT;
1363                                         } else {
1364                                                 if (bt_device_info == NULL) {
1365                                                         LOGI_GEOFENCE("bt_adapter_get_bonded_device_info [%s] failed.", bt_info->bssid);
1366                                                         status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT;
1367                                                 } else {
1368                                                         if (bt_device_info->is_bonded == TRUE && bt_device_info->is_connected == TRUE) {
1369                                                                 LOGI_GEOFENCE("[%s] bonded TRUE, connected TRUE", bt_info->bssid);
1370                                                                 status_to_be_emitted = GEOFENCE_FENCE_STATE_IN;
1371                                                         } else {
1372                                                                 status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT;
1373                                                         }
1374                                                 }
1375                                         }
1376                                 }
1377                         }
1378                 } else {
1379                         if (error != BT_ERROR_NONE) {
1380                                 LOGI_GEOFENCE("Unable to get the BT adapter state. Not added to track list: %d", error);
1381                                 geofence_manager_set_running_status(fence_id, (tracking_status - 1));
1382                                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_IPC, GEOFENCE_MANAGE_FENCE_STARTED);
1383                                 return;
1384                         }
1385                 }
1386         } else if (item_data->common_info.type == GEOFENCE_TYPE_WIFI) {
1387                 LOGI_GEOFENCE("fence_type [GEOFENCE_TYPE_WIFI]");
1388                 wifi_error_e rv = WIFI_ERROR_NONE;
1389                 int nWifiState;
1390                 wifi_ap_h ap_h;
1391                 char *ap_bssid = NULL;
1392                 int bssidlen;
1393                 bssid_info_s *wifi_info = NULL;
1394                 vconf_get_int(VCONFKEY_WIFI_STATE, &nWifiState);
1395
1396                 if (nWifiState != 0) {
1397                         LOGI_GEOFENCE("Wifi is on...");
1398                         geofence_server->running_wifi_cnt++;    /*Incrementing the counter for wifi fence*/
1399
1400                         if (item_data->priv != NULL) {
1401                                 wifi_info = (bssid_info_s *) item_data->priv;
1402                         }
1403                         rv = wifi_get_connected_ap(&ap_h);
1404                         if (rv != WIFI_ERROR_NONE) {
1405                                 LOGI_GEOFENCE("Fail/not connected to get the connected AP: [%s] , geofence will be added to the fence list", __convert_wifi_error_to_string(rv));
1406                                 if (rv == WIFI_ERROR_NO_CONNECTION) {
1407                                         LOGI_GEOFENCE("Not connected to any AP");
1408                                         status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT;
1409                                 }
1410                         } else {
1411                                 rv = wifi_ap_get_bssid(ap_h, &ap_bssid);
1412                                 if (rv != WIFI_ERROR_NONE) {
1413                                         LOGI_GEOFENCE("Fail to get the bssid: [%d]\n", __convert_wifi_error_to_string(rv));
1414                                 } else {
1415                                         bssidlen = strlen(ap_bssid);
1416                                         LOGI_GEOFENCE("Connected AP: %s, %d\n", ap_bssid, bssidlen);
1417                                         if (g_strcmp0(wifi_info->bssid, ap_bssid) == 0) {
1418                                                 status_to_be_emitted = GEOFENCE_FENCE_STATE_IN;
1419                                         } else {
1420                                                 status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT;
1421                                         }
1422
1423                                 }
1424                         }
1425                 } else {
1426                         LOGI_GEOFENCE("Wifi is not switched on...");
1427                         geofence_server->running_wifi_cnt++;    /*Incrementing the counter for wifi fence*/
1428                         /*Emit the fence status as out as wifi is not switched on here*/
1429                         status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT;
1430                 }
1431         } else {
1432                 LOGI_GEOFENCE("Invalid fence_type[%d]",
1433                         item_data->common_info.type);
1434                 return;
1435         }
1436         /*Adding the fence to the tracking list*/
1437         LOGI_GEOFENCE("Add to tracklist: Fence id: %d", fence_id);
1438         if (geofence_server->tracking_list == NULL) {
1439                 geofence_server->tracking_list = g_list_append(geofence_server->tracking_list, GINT_TO_POINTER(fence_id));
1440         } else {
1441                 geofence_server->tracking_list = g_list_insert_before(geofence_server->tracking_list, next_item_ptr, GINT_TO_POINTER(fence_id));
1442         }
1443         LOGI_GEOFENCE("Added fence id: Fence id: %d", fence_id);
1444
1445         __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STARTED);
1446
1447         __emit_fence_inout(geofence_server, item_data->common_info.fence_id, status_to_be_emitted);
1448
1449         track_list = g_list_first(geofence_server->tracking_list);
1450         while (track_list) {
1451                 tracking_fence_id = GPOINTER_TO_INT(track_list->data);
1452                 LOGI_GEOFENCE("%d", tracking_fence_id);
1453                 track_list = g_list_next(track_list);
1454         }
1455 }
1456
1457 static void __stop_geofence_service(gint fence_id, const gchar *app_id, gpointer userdata)
1458 {
1459         FUNC_ENTRANCE_SERVER;
1460         g_return_if_fail(userdata);
1461
1462         GeofenceServer *geofence_server = (GeofenceServer *) userdata;
1463         GeofenceItemData *item_data = NULL;
1464         int tracking_status = -1;
1465         int ret = FENCE_ERR_NONE;
1466         int place_id = -1;
1467         access_type_e access_type = ACCESS_TYPE_UNKNOWN;
1468
1469         item_data = __get_item_by_fence_id(fence_id, geofence_server);  /*Fetch the fence details from add_list*/
1470         if (item_data == NULL) {
1471                 LOGI_GEOFENCE("Invalid fence id - no fence exists with this fence id");
1472                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_FENCE_STOPPED);
1473                 return;         /*Invalid fence id - no fence exists with this fence id*/
1474         }
1475         ret = geofence_manager_get_place_id(fence_id, &place_id);
1476         if (ret != FENCE_ERR_NONE) {
1477                 LOGI_GEOFENCE("Error fetching the place_id from the DB for fence: %d", fence_id);
1478                 __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED);
1479                 return;
1480         }
1481         ret = geofence_manager_get_access_type(fence_id, -1, &access_type);
1482         if (ret != FENCE_ERR_NONE) {
1483                 LOGI_GEOFENCE("Error fetching the access type from the DB for fence: %d", fence_id);
1484                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED);
1485                 return;
1486         }
1487         ret = __check_fence_permission(fence_id, app_id);
1488         if (ret != 1) {
1489                 LOGE("Permission denied or DB error occured while accessing the fence[%d]", fence_id);
1490                 if (ret == 0) {
1491                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_STOPPED);
1492                 } else {
1493                         __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED);
1494                 }
1495                 return;
1496         }
1497         ret = geofence_manager_get_running_status(fence_id, &tracking_status);
1498         if (ret != FENCE_ERR_NONE) {
1499                 LOGI_GEOFENCE("Error fetching the running status from the DB for fence: %d", fence_id);
1500                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED);
1501                 return;
1502         }
1503
1504         if (tracking_status == 0) {
1505                 /*This fence is not in the tracking mode currently - nothing to do, just return saying the error*/
1506                 LOGI_GEOFENCE("Fence ID: %d, is not in the tracking mode", fence_id);
1507                 __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STOPPED);
1508                 return;
1509         }
1510
1511         if (tracking_status > 0) {
1512                 LOGI_GEOFENCE("Remove from tracklist: Fence id: %d", fence_id);
1513                 item_data = __get_item_by_fence_id(fence_id, geofence_server);
1514
1515                 /*Item needs to be removed from the fence list*/
1516                 if (item_data != NULL) {
1517                         /*Main DB table should be updated here with the unsetting of running status flag*/
1518                         tracking_status = tracking_status - 1;
1519                         ret = geofence_manager_set_running_status(fence_id, tracking_status);
1520                         if (ret != FENCE_ERR_NONE) {
1521                                 LOGI_GEOFENCE("Error resetting the running status in DB for fence: %d", fence_id);
1522                                 __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED);
1523                                 return;
1524                         }
1525                         /*Update the geofence count according to the type of geofence*/
1526                         if (item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) {
1527                                 geofence_server->running_geopoint_cnt--;
1528                                 LOGI_GEOFENCE("Removed geopoint fence: %d from tracking list", fence_id);
1529
1530                                 if (geofence_server->running_geopoint_cnt <= 0) {
1531                                         /*Stopping GPS...*/
1532                                         __stop_gps_positioning(geofence_server);
1533
1534                                         /*Stop the interval alarm if it is running...*/
1535                                         if (geofence_server->nps_alarm_id != -1) {
1536                                                 LOGI_GEOFENCE("Interval timer removed. ID[%d]", geofence_server->nps_alarm_id);
1537                                                 geofence_server->nps_alarm_id = _geofence_remove_alarm(geofence_server->nps_alarm_id);
1538                                         }
1539                                         /*Stop the timeout alarm if it is running...*/
1540                                         if (geofence_server->nps_timeout_alarm_id != -1) {
1541                                                 LOGI_GEOFENCE("Timeout timer removed. ID[%d]", geofence_server->nps_timeout_alarm_id);
1542                                                 geofence_server->nps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->nps_timeout_alarm_id);
1543                                         }
1544                                         
1545                                         __stop_activity_service(geofence_server);
1546                                 }
1547                         } else if (item_data->common_info.type == GEOFENCE_TYPE_BT) {
1548                                 geofence_server->running_bt_cnt--;
1549                                 LOGI_GEOFENCE("Removed bt fence: %d from tracking list", fence_id);
1550
1551                                 if (geofence_server->running_bt_cnt <= 0) {
1552                                         /*May be unsetting the cb for bt discovery can be done here*/
1553                                 }
1554                         } else if (item_data->common_info.type == GEOFENCE_TYPE_WIFI) {
1555                                 /*NOTHING NEED TO BE DONE HERE EXCEPT DECREMENTING THE COUNT*/
1556                                 geofence_server->running_wifi_cnt--;
1557                         }
1558
1559                         if (tracking_status == 0) {
1560                                 /*Remove the fence from the tracklist*/
1561                                 LOGD_GEOFENCE("Setting the fence status as uncertain here...");
1562                                 item_data->common_info.status = GEOFENCE_FENCE_STATE_UNCERTAIN;
1563                                 geofence_server->tracking_list = g_list_remove(geofence_server->tracking_list, GINT_TO_POINTER(fence_id));
1564                                 if (g_list_length(geofence_server->tracking_list) == 0) {
1565                                         g_list_free(geofence_server->tracking_list);
1566                                         geofence_server->tracking_list = NULL;
1567                                 }
1568                         }
1569                 } else {
1570                         LOGI_GEOFENCE("Geofence service is not running for this fence");
1571                 }
1572
1573         }
1574         /* Emit the error code */
1575         __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STOPPED);
1576 }
1577
1578 static void __start_activity_service(GeofenceServer *geofence_server)
1579 {
1580         FUNC_ENTRANCE_SERVER;
1581         bool activity_supported = TRUE;
1582         int ret = ACTIVITY_ERROR_NONE;
1583
1584         if (geofence_server->activity_stationary_h == NULL) {
1585                 activity_is_supported(ACTIVITY_STATIONARY, &activity_supported);
1586                 if (activity_supported == TRUE) {
1587                         ret = activity_create(&(geofence_server->activity_stationary_h));
1588                         if (ret != ACTIVITY_ERROR_NONE) {
1589                                 LOGD_GEOFENCE("Fail to create stationary activity %d", ret);
1590                         } else {
1591                                 ret = activity_start_recognition(geofence_server->activity_stationary_h, ACTIVITY_STATIONARY, __activity_cb, geofence_server);
1592                                 if (ret != ACTIVITY_ERROR_NONE)
1593                                         LOGD_GEOFENCE("Fail to start stationary activity %d", ret);
1594                                 else
1595                                         LOGD_GEOFENCE("Success to start stationary activity");
1596                         }
1597                 } else
1598                         LOGD_GEOFENCE("Not support stationary activity");
1599         }
1600
1601         if (geofence_server->activity_walk_h == NULL) {
1602                 activity_is_supported(ACTIVITY_WALK, &activity_supported);
1603                 if (activity_supported == TRUE) {
1604                         ret = activity_create(&(geofence_server->activity_walk_h));
1605                         if (ret != ACTIVITY_ERROR_NONE) {
1606                                 LOGD_GEOFENCE("Fail to create walk activity %d", ret);
1607                         } else {
1608                                 ret = activity_start_recognition(geofence_server->activity_walk_h, ACTIVITY_WALK, __activity_cb, geofence_server);
1609                                 if (ret != ACTIVITY_ERROR_NONE)
1610                                         LOGD_GEOFENCE("Fail to start walk activity %d", ret);
1611                                 else
1612                                         LOGD_GEOFENCE("Success to start walk activity");
1613                         }
1614                 } else
1615                         LOGD_GEOFENCE("Not support walk activity");
1616         }
1617
1618         if (geofence_server->activity_run_h == NULL) {
1619                 activity_is_supported(ACTIVITY_RUN, &activity_supported);
1620                 if (activity_supported == TRUE) {
1621                         ret = activity_create(&(geofence_server->activity_run_h));
1622                         if (ret != ACTIVITY_ERROR_NONE) {
1623                                 LOGD_GEOFENCE("Fail to create run activity %d", ret);
1624                         } else {
1625                                 ret = activity_start_recognition(geofence_server->activity_run_h, ACTIVITY_RUN, __activity_cb, geofence_server);
1626                                 if (ret != ACTIVITY_ERROR_NONE)
1627                                         LOGD_GEOFENCE("Fail to start run activity %d", ret);
1628                                 else
1629                                         LOGD_GEOFENCE("Success to start run activity");
1630                         }
1631                 } else
1632                         LOGD_GEOFENCE("Not support run activity");
1633         }
1634
1635         if (geofence_server->activity_in_vehicle_h == NULL) {
1636                 activity_is_supported(ACTIVITY_IN_VEHICLE, &activity_supported);
1637                 if (activity_supported == TRUE) {
1638                         ret = activity_create(&(geofence_server->activity_in_vehicle_h));
1639                         if (ret != ACTIVITY_ERROR_NONE) {
1640                                 LOGD_GEOFENCE("Fail to create in_vehicle activity %d", ret);
1641                         } else {
1642                                 ret = activity_start_recognition(geofence_server->activity_in_vehicle_h, ACTIVITY_IN_VEHICLE, __activity_cb, geofence_server);
1643                                 if (ret != ACTIVITY_ERROR_NONE)
1644                                         LOGD_GEOFENCE("Fail to start in_vehicle activity %d", ret);
1645                                 else
1646                                         LOGD_GEOFENCE("Success to start in_vehicle activity");
1647                         }
1648                 } else
1649                         LOGD_GEOFENCE("Not support in_vehicle activity");
1650         }
1651 }
1652
1653 static void __stop_activity_service(GeofenceServer *geofence_server)
1654 {
1655         FUNC_ENTRANCE_SERVER;
1656         int ret = ACTIVITY_ERROR_NONE;
1657
1658         if (geofence_server->activity_stationary_h != NULL) {
1659                 ret = activity_stop_recognition(geofence_server->activity_stationary_h);
1660                 if (ret != ACTIVITY_ERROR_NONE)
1661                         LOGD_GEOFENCE("Fail to stop stationary activity %d", ret);
1662                 else
1663                         LOGD_GEOFENCE("Success to stop stationary activity");
1664
1665                 ret = activity_release(geofence_server->activity_stationary_h);
1666                 if (ret != ACTIVITY_ERROR_NONE)
1667                         LOGD_GEOFENCE("Fail to release stationary activity %d", ret);
1668                 else
1669                         geofence_server->activity_stationary_h = NULL;
1670         }
1671
1672         if (geofence_server->activity_walk_h != NULL) {
1673                 ret = activity_stop_recognition(geofence_server->activity_walk_h);
1674                 if (ret != ACTIVITY_ERROR_NONE)
1675                         LOGD_GEOFENCE("Fail to stop walk activity %d", ret);
1676                 else
1677                         LOGD_GEOFENCE("Success to stop walk activity");
1678
1679                 ret = activity_release(geofence_server->activity_walk_h);
1680                 if (ret != ACTIVITY_ERROR_NONE)
1681                         LOGD_GEOFENCE("Fail to release walk activity %d", ret);
1682                 else
1683                         geofence_server->activity_walk_h = NULL;
1684         }
1685
1686         if (geofence_server->activity_run_h != NULL) {
1687                 ret = activity_stop_recognition(geofence_server->activity_run_h);
1688                 if (ret != ACTIVITY_ERROR_NONE)
1689                         LOGD_GEOFENCE("Fail to stop run activity %d", ret);
1690                 else
1691                         LOGD_GEOFENCE("Success to stop run activity");
1692
1693                 ret = activity_release(geofence_server->activity_run_h);
1694                 if (ret != ACTIVITY_ERROR_NONE)
1695                         LOGD_GEOFENCE("Fail to release run activity %d", ret);
1696                 else
1697                         geofence_server->activity_run_h = NULL;
1698         }
1699
1700         if (geofence_server->activity_in_vehicle_h != NULL) {
1701                 ret = activity_stop_recognition(geofence_server->activity_in_vehicle_h);
1702                 if (ret != ACTIVITY_ERROR_NONE)
1703                         LOGD_GEOFENCE("Fail to stop in_vehicle activity %d", ret);
1704                 else
1705                         LOGD_GEOFENCE("Success to stop in_vehicle activity");
1706
1707                 ret = activity_release(geofence_server->activity_in_vehicle_h);
1708                 if (ret != ACTIVITY_ERROR_NONE)
1709                         LOGD_GEOFENCE("Fail to release in_vehicle activity %d", ret);
1710                 else
1711                         geofence_server->activity_in_vehicle_h = NULL;
1712         }
1713 }
1714
1715 static void __activity_cb(activity_type_e type, const activity_data_h data, double timestamp, activity_error_e error, void *user_data)
1716 {
1717         FUNC_ENTRANCE_SERVER
1718         GeofenceServer *geofence_server = (GeofenceServer *)user_data;
1719         activity_accuracy_e accuracy;
1720         int result = ACTIVITY_ERROR_NONE;
1721
1722         if (error != ACTIVITY_ERROR_NONE) {
1723                 LOGD_GEOFENCE("Error in activity callback %d", error);
1724                 return;
1725         }
1726
1727         result = activity_get_accuracy(data, &accuracy);
1728         if (result != ACTIVITY_ERROR_NONE) {
1729                 LOGD_GEOFENCE("Fail to get accuracy of activity %d", error);
1730                 return;
1731         }
1732
1733         if (accuracy >= ACTIVITY_ACCURACY_MID) {
1734                 geofence_server->activity_type = type;
1735                 geofence_server->activity_timestamp = timestamp;
1736
1737                 LOGD_GEOFENCE("Activity type = %d, timestamp = %lf", type, timestamp);
1738         }
1739 }
1740
1741 static GVariant *__get_list(int place_id, const gchar *app_id, int *fenceCnt, int *errorCode, gpointer userdata)
1742 {
1743         geofence_info_s *item;
1744         GVariantBuilder b;
1745         GList *fence_list = NULL, *list = NULL;
1746         place_info_s *place_info = NULL;
1747         int count = 0, fence_cnt = 0;
1748         int ret = 0;
1749
1750         LOGI_GEOFENCE(">>> Enter");
1751         /*As same API is used to get the fence list, whenever complete fence list is requested, place_id is passed as -1 from the module.*/
1752         /*Whenever fence_list in a particular place is requested place_id will not be -1. This is jusr maintained internally*/
1753         if (place_id == -1) {
1754                 ret = geofence_manager_get_fence_list_from_db(&count, &fence_list, -1);
1755         } else {
1756                 ret = geofence_manager_get_place_info(place_id, &place_info);
1757                 if (ret != FENCE_ERR_NONE) {
1758                         LOGE("Error getting the place info for place_id[%d]", place_id);
1759                         /* Send ZERO data gvariant*/
1760                         *errorCode = GEOFENCE_SERVER_ERROR_DATABASE;
1761                         *fenceCnt = fence_cnt;
1762                         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1763                         return g_variant_builder_end(&b);
1764                 }
1765                 if ((place_info != NULL) && (place_info->access_type == ACCESS_TYPE_PRIVATE)) {
1766                         if (g_strcmp0(app_id, place_info->appid) != 0) {
1767                                 LOGI_GEOFENCE("Not authorized to access this private place[%d]", place_id);
1768                                 if (place_info)
1769                                         g_free(place_info);
1770                                 /* Send ZERO data gvariant*/
1771                                 *errorCode = GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED;
1772                                 *fenceCnt = fence_cnt;
1773                                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1774                                 return g_variant_builder_end(&b);
1775                         }
1776                         if (place_info)
1777                                 g_free(place_info);
1778                 }
1779                 ret = geofence_manager_get_fence_list_from_db(&count, &fence_list, place_id);
1780         }
1781         LOGI_GEOFENCE("count = %d", count);
1782
1783         if (ret != FENCE_ERR_NONE) {
1784                 LOGI_GEOFENCE("get list failed");
1785                 /* Send ZERO data gvariant*/
1786                 *errorCode = GEOFENCE_SERVER_ERROR_DATABASE;
1787                 *fenceCnt = fence_cnt;
1788                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1789                 return g_variant_builder_end(&b);
1790         } else if (count == 0) {
1791                 LOGI_GEOFENCE("List is empty");
1792                 /* Send ZERO data gvariant*/
1793                 *errorCode = GEOFENCE_SERVER_ERROR_NONE;
1794                 *fenceCnt = fence_cnt;
1795                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1796                 return g_variant_builder_end(&b);
1797         }
1798
1799         /* Initialize for the container*/
1800         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1801
1802         list = g_list_first(fence_list);
1803         while (list) {
1804                 item = (geofence_info_s *) list->data;
1805
1806                 if (item && ((item->access_type == ACCESS_TYPE_PUBLIC) || !(g_strcmp0(app_id, item->app_id)))) {
1807                         /* Open container*/
1808                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
1809
1810                         /* Add parameters to dictionary*/
1811                         g_variant_builder_add(&b, "{sv}", "fence_id", g_variant_new_int32(item->fence_id));
1812
1813                         LOGI_GEOFENCE("fence_id: %d, place_id: %d, latitude: %f, longitude: %f, radius: %d", item->fence_id, item->param.place_id, item->param.latitude, item->param.longitude, item->param.radius);
1814
1815                         switch (item->param.type) {
1816                         case GEOFENCE_TYPE_GEOPOINT:{
1817                                         g_variant_builder_add(&b, "{sv}", "place_id", g_variant_new_int32(item->param.place_id));
1818                                         g_variant_builder_add(&b, "{sv}", "geofence_type", g_variant_new_int32(item->param.type));
1819                                         g_variant_builder_add(&b, "{sv}", "latitude", g_variant_new_double(item->param.latitude));
1820                                         g_variant_builder_add(&b, "{sv}", "longitude", g_variant_new_double(item->param.longitude));
1821                                         g_variant_builder_add(&b, "{sv}", "radius", g_variant_new_int32(item->param.radius));
1822                                         g_variant_builder_add(&b, "{sv}", "address", g_variant_new_string(item->param.address));
1823                                         g_variant_builder_add(&b, "{sv}", "bssid", g_variant_new_string("NA"));
1824                                         g_variant_builder_add(&b, "{sv}", "ssid", g_variant_new_string("NA"));
1825                                 }
1826                                 break;
1827                         case GEOFENCE_TYPE_WIFI:
1828                         case GEOFENCE_TYPE_BT:{
1829                                         g_variant_builder_add(&b, "{sv}", "place_id", g_variant_new_int32(item->param.place_id));
1830                                         g_variant_builder_add(&b, "{sv}", "geofence_type", g_variant_new_int32(item->param.type));
1831                                         g_variant_builder_add(&b, "{sv}", "latitude", g_variant_new_double(0.0));
1832                                         g_variant_builder_add(&b, "{sv}", "longitude", g_variant_new_double(0.0));
1833                                         g_variant_builder_add(&b, "{sv}", "radius", g_variant_new_int32(0.0));
1834                                         g_variant_builder_add(&b, "{sv}", "address", g_variant_new_string("NA"));
1835                                         g_variant_builder_add(&b, "{sv}", "bssid", g_variant_new_string(item->param.bssid));
1836                                         g_variant_builder_add(&b, "{sv}", "ssid", g_variant_new_string(item->param.ssid));
1837                                 }
1838                                 break;
1839                         default:
1840                                 LOGI_GEOFENCE("Unsupported type: [%d]", item->param.type);
1841                                 break;
1842                         }
1843
1844                         /* Close container*/
1845                         g_variant_builder_close(&b);
1846                         fence_cnt++;
1847                 } else {
1848                         if (item != NULL)
1849                                 LOGI_GEOFENCE("This fence id: %d is private. Not authorized to access by this app", item->fence_id);
1850                 }
1851
1852                 /* Move to next node*/
1853                 list = g_list_next(list);
1854         }
1855         *errorCode = GEOFENCE_SERVER_ERROR_NONE;
1856         *fenceCnt = fence_cnt;
1857         return g_variant_builder_end(&b);
1858 }
1859
1860 static GVariant *__get_place_list(const gchar *app_id, int *placeCnt, int *errorCode, gpointer userdata)
1861 {
1862         place_info_s *item;
1863         GVariantBuilder b;
1864         GList *place_list = NULL, *list = NULL;
1865         int count = 0, place_cnt = 0;
1866         int ret = 0;
1867
1868         LOGI_GEOFENCE(">>> Enter");
1869
1870         ret = geofence_manager_get_place_list_from_db(&count, &place_list);
1871
1872         LOGI_GEOFENCE("count = %d", count);
1873
1874         if (ret != FENCE_ERR_NONE) {
1875                 LOGI_GEOFENCE("get list failed");
1876                 /* Send ZERO data gvariant*/
1877                 *errorCode = GEOFENCE_SERVER_ERROR_DATABASE;
1878                 *placeCnt = place_cnt;
1879                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1880                 return g_variant_builder_end(&b);
1881         } else if (count == 0) {
1882                 LOGI_GEOFENCE("List is empty");
1883                 /* Send ZERO data gvariant*/
1884                 *errorCode = GEOFENCE_SERVER_ERROR_NONE;
1885                 *placeCnt = place_cnt;
1886                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1887                 return g_variant_builder_end(&b);
1888         }
1889
1890         /* Initialize for the container*/
1891         g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
1892
1893         list = g_list_first(place_list);
1894         while (list) {
1895                 item = (place_info_s *) list->data;
1896
1897                 if (item && ((item->access_type == ACCESS_TYPE_PUBLIC) || !(g_strcmp0(app_id, item->appid)))) {
1898                         /* Open container*/
1899                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
1900
1901                         LOGI_GEOFENCE("place_id: %d, access_type: %d, place_name: %s, app_id: %s", item->place_id, item->access_type, item->place_name, item->appid);
1902                         /* Add data to dictionary*/
1903                         g_variant_builder_add(&b, "{sv}", "place_id", g_variant_new_int32(item->place_id));
1904                         g_variant_builder_add(&b, "{sv}", "place_name", g_variant_new_string(item->place_name));
1905                         /* Close container*/
1906                         g_variant_builder_close(&b);
1907                         place_cnt++;
1908                 } else {
1909                         if (item != NULL)
1910                                 LOGI_GEOFENCE("This place id: %d is private. Not authorized to access by this app", item->place_id);
1911                 }
1912                 list = g_list_next(list);
1913         }
1914         *errorCode = GEOFENCE_SERVER_ERROR_NONE;
1915         *placeCnt = place_cnt;
1916         return g_variant_builder_end(&b);
1917 }
1918
1919 static void __add_default_place(char *place_name)
1920 {
1921         int place_id;
1922         place_info_s *place_info = (place_info_s *) g_malloc0(sizeof(place_info_s));
1923         g_return_if_fail(place_info);
1924
1925         place_info->access_type = ACCESS_TYPE_PUBLIC;
1926         g_strlcpy(place_info->place_name, place_name, PLACE_NAME_LEN);
1927         g_strlcpy(place_info->appid, "dummy_app_id", APP_ID_LEN);
1928         /*Add the place details to db*/
1929         int ret = geofence_manager_set_place_info(place_info, &place_id);
1930         if (ret != FENCE_ERR_NONE)
1931                 LOGI_GEOFENCE("Unable to add the default places due to DB error");
1932 }
1933
1934 static void __init_geofencemanager(GeofenceServer *geofence_server)
1935 {
1936         FUNC_ENTRANCE_SERVER;
1937
1938         geofence_server->loc_started = FALSE;
1939
1940         geofence_server->timer_id = -1;
1941         geofence_server->nps_alarm_id = -1;
1942         geofence_server->nps_timeout_alarm_id = -1;
1943         geofence_server->geofence_list = NULL;
1944         geofence_server->tracking_list = NULL;
1945         geofence_server->running_geopoint_cnt = 0;
1946         geofence_server->running_bt_cnt = 0;
1947         geofence_server->running_wifi_cnt = 0;
1948         geofence_server->activity_type = ACTIVITY_IN_VEHICLE;
1949         geofence_server->activity_timestamp = 0;
1950
1951         geofence_server->activity_stationary_h = NULL;
1952         geofence_server->activity_walk_h = NULL;
1953         geofence_server->activity_run_h = NULL;
1954         geofence_server->activity_in_vehicle_h = NULL;
1955
1956         /*Initializing the DB to store the fence informations*/
1957         if (geofence_manager_db_init() != FENCE_ERR_NONE) {
1958                 LOGI_GEOFENCE("Error initalizing the DB");
1959         }
1960         /*Adding default places in the DB*/
1961         int place_id = DEFAULT_PLACE_HOME;
1962         int count = -1;
1963
1964         while (place_id <= DEFAULT_PLACE_CAR) {
1965                 if (geofence_manager_get_place_count_by_placeid(place_id, &count) == FENCE_ERR_NONE) {
1966                         if (count == 0) {
1967                                 if (place_id == DEFAULT_PLACE_HOME) {
1968                                         __add_default_place("Home");
1969                                 } else if (place_id == DEFAULT_PLACE_OFFICE) {
1970                                         __add_default_place("Office");
1971                                 } else if (place_id == DEFAULT_PLACE_CAR) {
1972                                         __add_default_place("Car");
1973                                 }
1974                         }
1975                 } else {
1976                         LOGI_GEOFENCE("Error adding the default place: %d", place_id);
1977                 }
1978                 place_id++;
1979                 count = -1;
1980         }
1981
1982         /*delete all fences at rebooting for a test. TODO: will be replaced by updating previous fences*/
1983         /*geofence_manager_db_reset();*/
1984 }
1985
1986
1987 #if USE_HW_GEOFENCE
1988 static void __start_gps_geofence_client(void *handle, GeofenceModCB geofence_cb, void *userdata)
1989 {
1990         FUNC_ENTRANCE_SERVER;
1991         /*Previously code to start the HW geofence client was there. It has been removed now*/
1992         return;
1993 }
1994
1995 static void __stop_gps_geofence_client(void *handle)
1996 {
1997         FUNC_ENTRANCE_SERVER;
1998         /*Stop tracking the geofences*/
1999         return;
2000 }
2001 #endif
2002
2003 int __copy_geofence_to_item_data(int fence_id, GeofenceItemData *item_data)
2004 {
2005         FUNC_ENTRANCE_SERVER;
2006         g_return_val_if_fail(item_data, FENCE_ERR_INVALID_PARAMETER);
2007         char *app_id = NULL;
2008
2009         item_data->common_info.fence_id = fence_id;
2010         item_data->common_info.status = GEOFENCE_FENCE_STATE_UNCERTAIN;
2011         if (FENCE_ERR_NONE != geofence_manager_get_geofence_type(fence_id, &item_data->common_info.type))
2012                 return FENCE_ERR_SQLITE_FAIL;
2013
2014         if (FENCE_ERR_NONE != geofence_manager_get_access_type(fence_id, -1, &item_data->common_info.access_type))
2015                 return FENCE_ERR_SQLITE_FAIL;
2016         
2017         if (FENCE_ERR_NONE != geofence_manager_get_enable_status(fence_id, &item_data->common_info.enable))
2018                 return FENCE_ERR_SQLITE_FAIL;
2019         
2020         if (FENCE_ERR_NONE != geofence_manager_get_appid_from_geofence(fence_id, &app_id)) {
2021                 g_free(app_id);
2022                 return FENCE_ERR_SQLITE_FAIL;
2023         } else {
2024                 g_strlcpy(item_data->common_info.appid, app_id, APP_ID_LEN);
2025                 g_free(app_id);
2026         }
2027         if (FENCE_ERR_NONE != geofence_manager_get_placeid_from_geofence(fence_id, &item_data->common_info.place_id))
2028                 return FENCE_ERR_SQLITE_FAIL;
2029         
2030         if (FENCE_ERR_NONE != geofence_manager_get_running_status(fence_id, &item_data->common_info.running_status))
2031                 return FENCE_ERR_SQLITE_FAIL;
2032
2033         if (item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) {
2034                 geocoordinate_info_s *geocoordinate_info = NULL;
2035                 int ret = FENCE_ERR_NONE;
2036
2037                 ret = geofence_manager_get_geocoordinate_info(fence_id, &geocoordinate_info);
2038                 if (ret != FENCE_ERR_NONE || geocoordinate_info == NULL) {
2039                         LOGI_GEOFENCE("can not get geocoordinate_info");
2040                         return FENCE_ERR_SQLITE_FAIL;
2041                 }
2042                 item_data->priv = (void *) geocoordinate_info;
2043         } else {
2044                 bssid_info_s *bssid_info = NULL;
2045                 int ret = FENCE_ERR_NONE;
2046
2047                 ret = geofence_manager_get_bssid_info(fence_id, &bssid_info);
2048                 if (ret != FENCE_ERR_NONE || bssid_info == NULL) {
2049                         LOGI_GEOFENCE("can not get bssid_info");
2050                         return FENCE_ERR_SQLITE_FAIL;
2051                 }
2052                 item_data->priv = (void *) bssid_info;
2053         }
2054         return FENCE_ERR_NONE;
2055 }
2056
2057 static void __add_left_fences(gpointer user_data)
2058 {
2059         g_return_if_fail(user_data);
2060         GeofenceServer *geofence_server = (GeofenceServer *) user_data;
2061         if (geofence_server->geofence_list != NULL)
2062                 return;
2063         GList *fence_list = NULL;
2064         int fence_id = 0;
2065         int count = 0;
2066
2067         /*Get the number of fences count*/
2068         geofence_manager_get_count_of_fences(&count);
2069         if (count <= 0)
2070                 return;
2071         /*Fetch the fences from the DB and populate it in the list*/
2072         geofence_manager_get_fences(NULL, 0, &fence_list);
2073         fence_list = g_list_first(fence_list);
2074         while (fence_list) {
2075                 fence_id = GPOINTER_TO_INT(fence_list->data);
2076
2077                 /*if(geofence_server is not restarted by dbus auto activation method[It means phone is rebooted so app should start the fences again. If we start the service by ourself it is waste of power. So we should not do that])
2078                  * {
2079                  * geofence_manager_set_running_status(fence_id, 0); // resetting the running-status flag since it is a device reboot
2080                  * } */
2081
2082                 GeofenceItemData *item_data = (GeofenceItemData *)g_malloc0(sizeof(GeofenceItemData));
2083                 if (FENCE_ERR_NONE != __copy_geofence_to_item_data(fence_id, item_data)) {
2084                         g_free(item_data);
2085                         return;
2086                 }
2087                 LOGI_GEOFENCE("adding fence_id = %d to fence_list", item_data->common_info.fence_id);
2088
2089                 /*Here fences from DB will be added to the list but tracking list is not populated here*/
2090                 geofence_server->geofence_list = g_list_append(geofence_server->geofence_list, item_data);
2091
2092                 fence_list = g_list_next(fence_list);
2093         }
2094 }
2095
2096 static void _glib_log(const gchar *log_domain, GLogLevelFlags log_level, const gchar *msg, gpointer user_data)
2097 {
2098         LOGI_GEOFENCE("GLIB[%d] : %s", log_level, msg);
2099 }
2100
2101 int main(int argc, char **argv)
2102 {
2103         GeofenceServer *geofenceserver = NULL;
2104
2105         /*Callback registrations*/
2106         geofence_callbacks cb;
2107         cb.bt_conn_state_changed_cb = bt_conn_state_changed;
2108         cb.bt_apater_disable_cb = bt_adp_disable;
2109         cb.wifi_conn_state_changed_cb = wifi_conn_state_changed;
2110         cb.wifi_device_state_changed_cb = wifi_device_state_changed;
2111         cb.network_evt_cb = geofence_network_evt_cb;
2112         cb.bt_discovery_cb = bt_adapter_device_discovery_state_cb;
2113         cb.gps_setting_changed_cb = gps_setting_changed_cb;
2114
2115 #if !GLIB_CHECK_VERSION(2, 35, 0)
2116         g_type_init();
2117 #endif
2118
2119         geofenceserver = g_new0(GeofenceServer, 1);
2120         if (!geofenceserver) {
2121                 LOGI_GEOFENCE("GeofenceServer create fail");
2122                 return 1;
2123         }
2124
2125         if (alarmmgr_init(PACKAGE_NAME) != ALARMMGR_RESULT_SUCCESS) {
2126                 LOGI_GEOFENCE("alarmmgr_init fail");
2127                 return 1;
2128         }
2129
2130         g_log_set_default_handler(_glib_log, geofenceserver);
2131
2132         /*Initialize the geofence manager where DB related activities exists*/
2133         __init_geofencemanager(geofenceserver);
2134
2135         /*This will read the DB and populate the list*/
2136         __add_left_fences(geofenceserver);
2137
2138         /*This call goes and registers the cb with Server.c where all the wifi,bt event callbacks are triggered*/
2139         _geofence_register_update_callbacks(&cb, geofenceserver);
2140
2141         /*This call goes and make initializations of bt and wifi stacks and then register the callbacks with them*/
2142         _geofence_initialize_geofence_server(geofenceserver);
2143
2144 #ifdef TIZEN_ENGINEER_MODE
2145         _init_log();
2146 #endif
2147
2148         /* This call goes to Geofence_dbus_server.c and creates the actual server dbus connection who will interact with the client*/
2149         geofence_dbus_server_create(GEOFENCE_SERVER_SERVICE_NAME, GEOFENCE_SERVER_SERVICE_PATH, "geofence_manager", "geofence manager provider", &(geofenceserver->geofence_dbus_server), __add_fence, __add_place, __enable_service, __update_place, __remove_fence, __remove_place, __get_place_name, __get_list, __get_place_list, __start_geofence_service, __stop_geofence_service, (void *) geofenceserver);
2150
2151         LOGD_GEOFENCE("lbs_geofence_server_creation done");
2152
2153         geofenceserver->loop = g_main_loop_new(NULL, TRUE);
2154         g_main_loop_run(geofenceserver->loop);
2155
2156         LOGD_GEOFENCE("GEOFENCE_manager deamon Stop....");
2157
2158         /*This call goes to server.c and deregisters all the callbacks w.r.t bt and wifi*/
2159         _geofence_deinitialize_geofence_server();
2160
2161 #ifdef TIZEN_ENGINEER_MODE
2162         _deinit_log();
2163 #endif
2164         /*This call goes to Geofence_dbus_server.c and deletes the memory allocated to the server, hence destroys it*/
2165         geofence_dbus_server_destroy(geofenceserver->geofence_dbus_server);
2166         LOGD_GEOFENCE("lbs_server_destroy called");
2167
2168         g_main_loop_unref(geofenceserver->loop);
2169
2170         /*Closing the DB and the handle is aquired again when geofence server comes up.*/
2171         geofence_manager_close_db();
2172
2173         g_free(geofenceserver);
2174
2175         return 0;
2176 }