Change interval table to support fused location
[platform/core/location/lbs-dbus.git] / server / src / lbs_dbus_server.c
1 /*
2  * lbs-dbus
3  *
4  * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <stdio.h>
20
21 #include "generated-code.h"
22 #include "lbs_dbus_server.h"
23 #include "lbs_dbus_server_priv.h"
24
25 typedef struct _lbs_server_dbus_s {
26         /* LBS server dbus info */
27         gchar *service_name;
28         gchar *prev_owner;
29         gchar *service_path;
30         gchar *name;
31         gchar *description;
32         GHashTable *connections;
33         gint status;
34         GDBusObjectManagerServer *manager;
35         LbsObjectSkeleton *obj_skeleton;
36
37         LbsDbusSetOptionsCB set_options_cb;
38         LbsDbusShutdownCB shutdown_cb;
39         LbsDbusUpdateIntervalCB update_interval_cb;
40         LbsDbusRequestChangeIntervalCB request_change_interval_cb;
41         LbsDbusGetNmeaCB get_nmea_cb;
42         gpointer userdata;      /* used for save GpsManager */
43
44         guint owner_changed_id;
45         guint owner_id;
46         guint get_providerinfo_h;
47         guint get_status_h;
48         guint set_option_h;
49         guint add_reference_h;
50         guint remove_reference_h;
51         guint get_nmea_h;
52
53         /* for geofence */
54         guint add_fence_h;
55         guint remove_fence_h;
56         guint pause_fence_h;
57         guint resume_fence_h;
58         guint start_geofence_h;
59         guint stop_geofence_h;
60         gint geofence_status;
61
62         /* for H/W gps-geofence */
63         guint add_hw_fence_h;
64         guint delete_hw_fence_h;
65         guint pause_hw_fence_h;
66         guint resume_hw_fence_h;
67         gint hw_geofence_status;
68         GpsGeofenceAddFenceCB add_hw_fence_cb;
69         GpsGeofenceDeleteFenceCB delete_hw_fence_cb;
70         GpsGeofencePauseFenceCB pause_hw_fence_cb;
71         GpsGeofenceResumeFenceCB resume_hw_fence_cb;
72
73         /* Tizen 3.0 */
74         guint set_mock_location_h;
75         LbsDbusSetMockLocationCB set_mock_location_cb;
76
77 #ifdef TIZEN_3_0_OPT
78         lbs_server_dbus_cb_t callback;
79 #endif
80 } lbs_server_dbus_s;
81
82 static gboolean lbs_dbus_setup_position_interface(LbsObjectSkeleton *object, lbs_server_dbus_s *handle)
83 {
84         LBS_SERVER_LOGD("lbs_dbus_setup_position_interface");
85         if (!object || !handle)
86                 return FALSE;
87
88         LbsPosition *position = NULL;
89         position = lbs_position_skeleton_new();
90         lbs_object_skeleton_set_position(object, position);
91         g_object_unref(position);
92
93         return TRUE;
94 }
95
96 static gboolean lbs_dbus_setup_batch_interface(LbsObjectSkeleton *object, lbs_server_dbus_s *handle)
97 {
98         LBS_SERVER_LOGD("lbs_dbus_setup_batch_interface");
99         if (!object || !handle)
100                 return FALSE;
101
102         LbsBatch *batch = NULL;
103         batch = lbs_batch_skeleton_new();
104         lbs_object_skeleton_set_batch(object, batch);
105         g_object_unref(batch);
106
107         return TRUE;
108 }
109
110 static gboolean lbs_dbus_setup_satellite_interface(LbsObjectSkeleton *object, lbs_server_dbus_s *handle)
111 {
112         LBS_SERVER_LOGD("lbs_dbus_setup_satellite_interface");
113         if (!object || !handle)
114                 return FALSE;
115
116         LbsSatellite *sat = NULL;
117         sat = lbs_satellite_skeleton_new();
118         lbs_object_skeleton_set_satellite(object, sat);
119         g_object_unref(sat);
120
121         return TRUE;
122 }
123
124 static gboolean lbs_dbus_setup_nmea_interface(LbsObjectSkeleton *object, lbs_server_dbus_s *handle)
125 {
126         LBS_SERVER_LOGD("lbs_dbus_setup_nmea_interface");
127         if (!object || !handle)
128                 return FALSE;
129
130         LbsNmea *nmea = NULL;
131         nmea = lbs_nmea_skeleton_new();
132         lbs_object_skeleton_set_nmea(object, nmea);
133         g_object_unref(nmea);
134
135         return TRUE;
136 }
137
138 static gboolean lbs_dbus_setup_gps_geofence_interface(LbsObjectSkeleton *object, lbs_server_dbus_s *handle)
139 {
140         LBS_SERVER_LOGD("lbs_dbus_setup_gps_geofence_interface");
141         if (!object || !handle)
142                 return FALSE;
143
144         LbsGpsGeofence *gps_geofence = NULL;
145         gps_geofence = lbs_gps_geofence_skeleton_new();
146         lbs_object_skeleton_set_gps_geofence(object, gps_geofence);
147         g_object_unref(gps_geofence);
148
149         return TRUE;
150 }
151
152
153 static gboolean
154 on_manager_getproviderinfo(LbsManager *mgr, GDBusMethodInvocation *invocation, gpointer user_data)
155 {
156         LBS_SERVER_LOGD("on_manager_getproviderinfo");
157         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
158         if (!handle)
159                 return FALSE;
160
161         if (handle->name && handle->description)
162                 lbs_manager_complete_get_provider_info(mgr, invocation, handle->name, handle->description);
163         else
164                 lbs_manager_complete_get_provider_info(mgr, invocation, NULL, NULL);
165
166         return TRUE;
167 }
168
169 static gboolean
170 on_manager_getstatus(LbsManager *mgr, GDBusMethodInvocation *invocation, gpointer user_data)
171 {
172         LBS_SERVER_LOGD("on_manager_getstatus");
173         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
174         if (!handle)
175                 return FALSE;
176
177         lbs_manager_complete_get_status(mgr, invocation, handle->status);
178
179         return TRUE;
180 }
181
182 static gboolean
183 on_nmea_getnmea(LbsNmea *nmea, GDBusMethodInvocation *invocation, gpointer user_data)
184 {
185         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
186         if (!handle)
187                 return FALSE;
188
189         gint timestamp = 0;
190         gchar *nmea_data = NULL;
191
192         if (handle->get_nmea_cb) {
193                 handle->get_nmea_cb(&timestamp, &nmea_data, handle->userdata);
194                 LBS_SERVER_LOGD("timestmap: %d, nmea_data: %s", timestamp, nmea_data);
195         }
196         lbs_nmea_complete_get_nmea(nmea, invocation, timestamp, nmea_data);
197         g_free(nmea_data);
198
199         return TRUE;
200 }
201
202 static gboolean
203 on_manager_setoptions(LbsManager *mgr, GDBusMethodInvocation *invocation, GVariant *options, gpointer user_data)
204 {
205         LBS_SERVER_LOGD("ENTER >>>");
206         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
207         if (!handle)
208                 return FALSE;
209
210         if (handle->set_options_cb) {
211                 const gchar *sender = NULL;
212                 sender = g_dbus_method_invocation_get_sender(invocation);
213                 handle->set_options_cb(options, sender, handle->userdata);
214                 LBS_SERVER_LOGD("set_options_cb was called");
215         }
216
217         lbs_manager_complete_set_options(mgr, invocation);
218
219         return TRUE;
220 }
221
222 static gboolean
223 on_manager_addreference(LbsManager *mgr, GDBusMethodInvocation *invocation, int method, gpointer user_data)
224 {
225         LBS_SERVER_LOGD("method: %d", method);
226         if (method < 0 || method >= LBS_SERVER_METHOD_SIZE) return FALSE;
227
228         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
229         if (!handle)
230                 return FALSE;
231
232         const gchar *sender = NULL;
233         gchar *client = NULL;
234         int count = 0;
235
236         /* Update the hash of open connections */
237         sender = g_dbus_method_invocation_get_sender(invocation);
238         client = g_strdup(sender);
239
240         int *count_arr = (int *) g_hash_table_lookup(handle->connections, client);
241         if (!count_arr) {
242                 LBS_SERVER_LOGD("first add for sender %s ", client);
243                 count_arr = (int *)g_malloc0(LBS_SERVER_METHOD_SIZE * sizeof(int));
244                 g_return_val_if_fail(count_arr, FALSE);
245
246                 g_hash_table_insert(handle->connections, (gpointer)client, (gpointer)count_arr);
247         }
248
249         count = count_arr[method];
250         count++;
251
252         if (count <= 0) {
253                 count = 1;
254                 LBS_SERVER_LOGE("Client reference count set to 1 for client [%s] of method [%d]", client, method);
255         }
256
257         LBS_SERVER_LOGD("client [%s], method[%d], count [%d] is inserted in hash table", client, method, count);
258
259         count_arr[method] = count;
260
261         lbs_manager_complete_add_reference(mgr, invocation);
262
263         return TRUE;
264 }
265
266 static gboolean lbs_find_method(gpointer key, gpointer value, gpointer user_data)
267 {
268         int *ip = (int *) user_data;
269         int *arr = (int *) value;
270         int method = *ip;
271
272         if (arr[method] > 0)
273                 LBS_SERVER_LOGD("[%s] lbs_find_method method: %d, count: %d", (char *)key, method, arr[method]);
274
275         return (arr[method] > 0) ? TRUE : FALSE;
276 }
277
278 static gboolean
279 lbs_server_remove_client(lbs_server_dbus_s *handle, const char *client, int method)
280 {
281         if (!handle || !client)
282                 return FALSE;
283
284         int count = 0;
285         int *count_arr = (int *) g_hash_table_lookup(handle->connections, client);
286
287         if (!count_arr) {
288                 LBS_SERVER_LOGD("Client[%s] Method[%d] is already removed", client, method);
289                 return FALSE;
290         }
291
292         count = count_arr[method];
293         LBS_SERVER_LOGD("lbs_server_remove_client method:%d count:%d", method, count);
294
295         if (count == 0) {
296                 LBS_SERVER_LOGD("Client[%s] Method[%d] is already removed", client, method);
297                 return FALSE;
298         }
299
300         count--;
301         count_arr[method] = count;
302
303         if (count > 0) {
304                 LBS_SERVER_LOGD("Client[%s] of method[%d] has reference count[%d]", client, method, count);
305         } else if (count == 0) {
306                 LBS_SERVER_LOGD("Remove [%s : %d] in hash table, ref count is 0", client, method);
307
308                 int i = 0, count_each = 0;
309                 for (i = 0; i < LBS_SERVER_METHOD_SIZE; i++) {
310                         count_each = count_arr[i];
311                         if (count_each != 0) {
312                                 LBS_SERVER_LOGD("[%s] method[%d]'s count is not zero - count: %d", client, i, count_each);
313                                 return FALSE;
314                         }
315                 }
316
317                 if (!g_hash_table_remove(handle->connections, client))
318                         LBS_SERVER_LOGE("g_hash_table_remove is Fail");
319         }
320
321         int index = 0;
322         gboolean *shutdown_arr = (gboolean *) g_malloc0_n(LBS_SERVER_METHOD_SIZE, sizeof(gboolean));
323         g_return_val_if_fail(shutdown_arr, FALSE);
324
325         if (g_hash_table_size(handle->connections) == 0) {
326                 LBS_SERVER_SECLOG("Hash table size is zero, Now shutdown provider[%s]", handle->name);
327
328                 for (; index < LBS_SERVER_METHOD_SIZE; index++) shutdown_arr[index] = TRUE;
329         } else {
330                 LBS_SERVER_SECLOG("Hash table size is not zero");
331
332                 for (; index < LBS_SERVER_METHOD_SIZE ; index++) {
333                         if (g_hash_table_find(handle->connections, (GHRFunc)lbs_find_method, &index) == NULL) {
334                                 shutdown_arr[index] = TRUE;
335                                 continue;
336                         }
337                 }
338         }
339
340         if (handle->shutdown_cb) {
341                 handle->shutdown_cb(handle->userdata, shutdown_arr);
342                 LBS_SERVER_LOGD("shutdown_cb called.. gps:%d, nps:%d",
343                                                 shutdown_arr[LBS_SERVER_METHOD_GPS], shutdown_arr[LBS_SERVER_METHOD_NPS]);
344         }
345
346         g_free(shutdown_arr);
347         return TRUE;
348 }
349
350 static gboolean on_manager_removereference(LbsManager *mgr, GDBusMethodInvocation *invocation, int method, gpointer user_data)
351 {
352         LBS_SERVER_LOGD("method: %d", method);
353         if (method < 0 || method >= LBS_SERVER_METHOD_SIZE) return FALSE;
354
355         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
356         if (!handle)
357                 return FALSE;
358
359         const gchar *sender = NULL;
360         sender = g_dbus_method_invocation_get_sender(invocation);
361         if (!lbs_server_remove_client(handle, sender, method))
362                 LBS_SERVER_LOGD("Unreffed by client that has not been referenced");
363
364         lbs_manager_complete_remove_reference(mgr, invocation);
365
366         return TRUE;
367 }
368
369 /*
370  * For H/W gps-geofence methods
371  */
372 static gboolean
373 on_gps_geofence_addfence(LbsGpsGeofence *gps_geofence, GDBusMethodInvocation *invocation,
374                  gint fence_id, gdouble latitude, gdouble longitude, gint radius, gint last_state,
375                  gint monitor_states, gint notification_responsiveness, gint unknown_timer, gpointer user_data)
376 {
377         LBS_SERVER_LOGD("on_gps_geofence_addfence");
378
379         /* call gps-manager's callback, add_hw_fence_cb */
380         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
381         if (!handle)
382                 return FALSE;
383
384         if (handle->add_hw_fence_cb) {
385                 handle->add_hw_fence_cb(fence_id, latitude, longitude, radius, last_state, monitor_states,
386                                                          notification_responsiveness, unknown_timer, handle->userdata);
387                 LBS_SERVER_LOGD("add_hw_fence_cb called");
388         }
389         lbs_gps_geofence_complete_add_fence(gps_geofence, invocation);
390         return TRUE;
391 }
392
393 static gboolean
394 on_gps_geofence_deletefence(LbsGpsGeofence *gps_geofence, GDBusMethodInvocation *invocation, gint fence_id, gpointer user_data)
395 {
396         LBS_SERVER_LOGD("on_gps_geofence_deletefence");
397
398         /* call gps-manager's callback, delete_hw_fence_cb */
399         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
400         if (!handle)
401                 return FALSE;
402
403         if (handle->delete_hw_fence_cb) {
404                 handle->delete_hw_fence_cb(fence_id, handle->userdata);
405                 LBS_SERVER_LOGD("delete_hw_fence_cb called");
406         }
407         lbs_gps_geofence_complete_delete_fence(gps_geofence, invocation);
408         return TRUE;
409 }
410
411 static gboolean
412 on_gps_geofence_pausefence(LbsGpsGeofence *gps_geofence, GDBusMethodInvocation *invocation, gint fence_id, gpointer user_data)
413 {
414         LBS_SERVER_LOGD("on_gps_geofence_pausefence");
415
416         /* call gps-manager's callback, pause_hw_fence_cb */
417         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
418         if (!handle)
419                 return FALSE;
420
421         if (handle->pause_hw_fence_cb) {
422                 handle->pause_hw_fence_cb(fence_id, handle->userdata);
423                 LBS_SERVER_LOGD("pause_hw_fence_cb called");
424         }
425
426         lbs_gps_geofence_complete_pause_fence(gps_geofence, invocation);
427         return TRUE;
428 }
429
430 static gboolean
431 on_gps_geofence_resumefence(LbsGpsGeofence *gps_geofence, GDBusMethodInvocation *invocation, gint fence_id, gint monitor_states, gpointer user_data)
432 {
433         LBS_SERVER_LOGD("on_gps_geofence_resumefence");
434
435         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
436         if (!handle)
437                 return FALSE;
438
439         /* call gps-manager's callback, resume_hw_fence_cb */
440         if (handle->resume_hw_fence_cb) {
441                 handle->resume_hw_fence_cb(fence_id, monitor_states, handle->userdata);
442                 LBS_SERVER_LOGD("resume_hw_fence_cb called");
443         }
444
445         lbs_gps_geofence_complete_resume_fence(gps_geofence, invocation);
446         return TRUE;
447 }
448
449
450 /* Tizen 3.0 */
451
452 static gboolean
453 on_manager_setmocklocation(LbsManager *mgr, GDBusMethodInvocation *invocation, gint method,
454                                                         gdouble latitude, gdouble longitude, gdouble altitude,
455                                                         gdouble speed, gdouble direction, gdouble accuracy, gpointer user_data)
456 {
457         LBS_SERVER_LOGD("on_manager_setmocklocation [method: %d]", method);
458         if (method < 0 || method >= LBS_SERVER_METHOD_SIZE) return FALSE;
459
460         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
461         if (!handle)
462                 return FALSE;
463
464         if (handle->set_mock_location_cb) {
465                 handle->set_mock_location_cb(method, latitude, longitude, altitude, speed, direction, accuracy, handle->userdata);
466
467                 LBS_SERVER_LOGD("set_mock_location_cb was called");
468         }
469
470         lbs_manager_complete_set_mock_location(mgr, invocation);
471
472         return TRUE;
473 }
474
475 static gboolean
476 lbs_remove_client_by_force(const char *client, void *data)
477 {
478         LBS_SERVER_LOGD("remove client by force for client [%s]", client);
479         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)data;
480
481         int *count_arr = (int *) g_hash_table_lookup(handle->connections, client);
482
483         if (!count_arr) {
484                 LBS_SERVER_LOGD("Client[%s] is already removed", client);
485                 return FALSE;
486         } else {
487                 LBS_SERVER_LOGD("[Client: %s]. Remove all clients in hash table", client);
488                 if (!g_hash_table_remove(handle->connections, client))
489                         LBS_SERVER_LOGE("g_hash_table_remove is Fail");
490         }
491
492         int index = 0;
493         gboolean *shutdown_arr = (gboolean *) g_malloc0_n(LBS_SERVER_METHOD_SIZE, sizeof(gboolean));
494         g_return_val_if_fail(shutdown_arr, FALSE);
495
496         if (g_hash_table_size(handle->connections) == 0) {
497                 LBS_SERVER_SECLOG("Hash table size is zero, Now shutdown provider[%s]", handle->name);
498
499                 for (; index < LBS_SERVER_METHOD_SIZE; index++) shutdown_arr[index] = TRUE;
500         } else {
501                 LBS_SERVER_SECLOG("Hash table size is not zero");
502
503                 for (; index < LBS_SERVER_METHOD_SIZE ; index++) {
504                         if (g_hash_table_find(handle->connections, (GHRFunc)lbs_find_method, &index) == NULL) {
505                                 shutdown_arr[index] = TRUE;
506                                 continue;
507                         }
508                 }
509         }
510
511         if (handle->shutdown_cb) {
512                 handle->shutdown_cb(handle->userdata, shutdown_arr);
513                 LBS_SERVER_LOGD("shutdown_cb called.. gps: %d, nps: %d",
514                                                 shutdown_arr[LBS_SERVER_METHOD_GPS], shutdown_arr[LBS_SERVER_METHOD_NPS]);
515         }
516
517         if (handle->update_interval_cb) {
518                 gboolean is_needed_change_interval = FALSE;
519                 for (index = 0; index < LBS_SERVER_METHOD_SIZE ; index++) {
520                         is_needed_change_interval = handle->update_interval_cb(LBS_SERVER_INTERVAL_REMOVE, client, index, 0, 0, handle->userdata);
521                         if (is_needed_change_interval) {
522                                 is_needed_change_interval = FALSE;
523                                 if (handle->request_change_interval_cb)
524                                         handle->request_change_interval_cb(index, handle->userdata);
525                         }
526                 }
527         }
528
529         LBS_SERVER_LOGD("###### A client[%s] is abnormally shut down ########", client);
530
531         g_free(shutdown_arr);
532         return TRUE;
533 }
534
535 static void
536 lbs_scan_sender(char *key, char *value, gpointer user_data)
537 {
538         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
539         g_return_if_fail(handle);
540         gchar *prev_owner = handle->prev_owner;
541         g_return_if_fail(prev_owner);
542
543         if (g_strcmp0(prev_owner, key) == 0) {
544                 LBS_SERVER_LOGD("disconnected sender name matched, remove client by force!");
545                 lbs_remove_client_by_force(prev_owner, handle);
546         }
547 }
548
549 static void
550 on_name_owner_changed(GDBusConnection *connection, const gchar *sender_name,
551                                         const gchar *object_path, const gchar *interface_name, const gchar *signal_name,
552                                         GVariant *parameters,   /* 1. service name 2. prev_owner 3. new_owner */
553                                         gpointer user_data)
554 {
555         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
556         g_return_if_fail(handle);
557
558         gchar *service_name = NULL, *prev_owner = NULL, *new_owner = NULL;
559         g_variant_get(parameters, "(&s&s&s)", &service_name, &prev_owner, &new_owner);
560
561         if (g_strcmp0(object_path, "/org/freedesktop/DBus") != 0 ||
562                 g_strcmp0(interface_name, "org.freedesktop.DBus") != 0 ||
563                 g_strcmp0(sender_name, "org.freedesktop.DBus") != 0) {
564                 goto out;
565         }
566
567         /* if the prev_owner matches the sender name, then remote sender(client) is crashed */
568         if (g_strcmp0(new_owner, "") == 0 && (prev_owner != NULL && strlen(prev_owner) > 0)
569                 && handle->connections != NULL) {
570                 if (handle->prev_owner) {
571                         g_free(handle->prev_owner);
572                         handle->prev_owner = NULL;
573                 }
574                 handle->prev_owner = g_strdup(prev_owner);
575                 g_hash_table_foreach(handle->connections, (GHFunc)lbs_scan_sender, handle);
576         }
577
578 out:
579         ;
580 }
581
582 static void on_bus_acquired(GDBusConnection *conn, const gchar *name, gpointer user_data)
583 {
584         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)user_data;
585         if (!handle)
586                 return;
587
588         LbsManager *mgr = NULL;
589         LbsObjectSkeleton *object = NULL;
590         gchar *path = NULL;
591
592         LBS_SERVER_LOGD("dbus registered");
593
594         /* create object for each interfaces*/
595         path = g_strdup_printf("%s/%s", handle->service_path, "SAMSUNG");
596         if (path == NULL) {
597                 LBS_SERVER_LOGE("path is NULL");
598                 path = NULL;
599         }
600
601         object = lbs_object_skeleton_new(path);
602         if (object == NULL) {
603                 LBS_SERVER_LOGE("Can't create object. path: %s", path);
604                 g_free(path);
605                 return;
606         }
607         g_free(path);
608
609         handle->obj_skeleton = object;
610         lbs_dbus_setup_position_interface(object, handle);
611         lbs_dbus_setup_batch_interface(object, handle);
612         lbs_dbus_setup_satellite_interface(object, handle);
613         lbs_dbus_setup_nmea_interface(object, handle);
614
615         /* add H/W gps-geofence interface */
616         lbs_dbus_setup_gps_geofence_interface(object, handle);
617         g_dbus_object_manager_server_export(handle->manager, G_DBUS_OBJECT_SKELETON(object));
618
619         /* Add interface to default object path */
620         mgr = lbs_manager_skeleton_new();
621
622         handle->get_providerinfo_h = g_signal_connect(mgr, "handle-get-provider-info", G_CALLBACK(on_manager_getproviderinfo), handle);
623         handle->get_status_h = g_signal_connect(mgr, "handle-get-status", G_CALLBACK(on_manager_getstatus), handle);
624         if (handle->set_options_cb != NULL)
625                 handle->set_option_h = g_signal_connect(mgr, "handle-set-options", G_CALLBACK(on_manager_setoptions), handle);
626
627         handle->add_reference_h = g_signal_connect(mgr, "handle-add-reference", G_CALLBACK(on_manager_addreference), handle);
628         if (handle->shutdown_cb)
629                 handle->remove_reference_h = g_signal_connect(mgr, "handle-remove-reference", G_CALLBACK(on_manager_removereference), handle);
630
631         /* Tizen 3.0 */
632         if (handle->set_mock_location_cb)
633                 handle->set_mock_location_h = g_signal_connect(mgr, "handle-set-mock-location", G_CALLBACK(on_manager_setmocklocation), handle);
634
635         /* Add interface for nmea method*/
636         LbsNmea *nmea = NULL;
637         nmea = lbs_nmea_skeleton_new();
638         handle->get_nmea_h = g_signal_connect(nmea, "handle-get-nmea", G_CALLBACK(on_nmea_getnmea), handle);
639
640         /* register callback for each methods for H/W gps-geofence */
641         LbsGpsGeofence *gps_geofence = NULL;
642         if (handle->obj_skeleton) {
643                 gps_geofence = lbs_object_get_gps_geofence(LBS_OBJECT(handle->obj_skeleton));
644                 if (gps_geofence) {
645                         if (handle->add_hw_fence_cb)
646                                 handle->add_hw_fence_h = g_signal_connect(gps_geofence, "handle-add-fence", G_CALLBACK(on_gps_geofence_addfence), handle);
647
648                         if (handle->delete_hw_fence_cb)
649                                 handle->delete_hw_fence_h = g_signal_connect(gps_geofence, "handle-delete-fence", G_CALLBACK(on_gps_geofence_deletefence), handle);
650
651                         if (handle->pause_hw_fence_cb)
652                                 handle->pause_hw_fence_h = g_signal_connect(gps_geofence, "handle-pause-fence", G_CALLBACK(on_gps_geofence_pausefence), handle);
653
654                         if (handle->resume_hw_fence_cb)
655                                 handle->resume_hw_fence_h = g_signal_connect(gps_geofence, "handle-resume-fence", G_CALLBACK(on_gps_geofence_resumefence), handle);
656
657                         g_object_unref(gps_geofence);
658                 }
659         }
660
661         handle->owner_changed_id = g_dbus_connection_signal_subscribe(conn,
662                                                    "org.freedesktop.DBus", "org.freedesktop.DBus", "NameOwnerChanged", "/org/freedesktop/DBus", NULL,
663                                                    G_DBUS_SIGNAL_FLAGS_NONE, on_name_owner_changed, handle, NULL);
664
665         g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(mgr), conn, handle->service_path, NULL);
666         g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(nmea), conn, handle->service_path, NULL);
667
668         g_dbus_object_manager_server_set_connection(handle->manager, conn);
669
670         LBS_SERVER_LOGD("done to acquire the dbus");
671 }
672
673 static void on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
674 {
675         LBS_SERVER_SECLOG("LBS Server: Acquired the name <%s> on the system bus", name);
676 }
677
678 static void on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
679 {
680         LBS_SERVER_SECLOG("LBS Server: Lost the name <%s> on the system bus", name);
681 }
682
683 EXPORT_API int
684 lbs_server_emit_position_changed(lbs_server_dbus_h lbs_dbus_server,
685                                                                 gint arg_method, gint arg_fields, gint arg_timestamp, gdouble arg_latitude, gdouble arg_longitude, gdouble arg_altitude,
686                                                                 gdouble arg_speed, gdouble arg_direction, gdouble arg_climb, GVariant *arg_accuracy)
687 {
688         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
689         g_return_val_if_fail(arg_accuracy, LBS_SERVER_ERROR_PARAMETER);
690
691         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)lbs_dbus_server;
692         g_return_val_if_fail(handle->obj_skeleton, LBS_SERVER_ERROR_PARAMETER);
693
694         LbsPosition *lbs_pos = NULL;
695         lbs_pos = lbs_object_get_position(LBS_OBJECT(handle->obj_skeleton));
696         g_return_val_if_fail(lbs_pos, LBS_SERVER_ERROR_PARAMETER);
697
698         lbs_position_emit_position_changed(lbs_pos,
699            arg_method, arg_fields, arg_timestamp, arg_latitude, arg_longitude, arg_altitude, arg_speed, arg_direction, arg_climb, arg_accuracy);
700
701         g_object_unref(lbs_pos);
702
703         return LBS_SERVER_ERROR_NONE;
704 }
705
706 EXPORT_API int
707 lbs_server_emit_batch_changed(lbs_server_dbus_h lbs_dbus_server, gint arg_num_of_location)
708 {
709         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
710
711         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)lbs_dbus_server;
712         g_return_val_if_fail(handle->obj_skeleton, LBS_SERVER_ERROR_PARAMETER);
713
714         LbsBatch *lbs_batch = NULL;
715         lbs_batch = lbs_object_get_batch(LBS_OBJECT(handle->obj_skeleton));
716         g_return_val_if_fail(lbs_batch, LBS_SERVER_ERROR_PARAMETER);
717
718         lbs_batch_emit_batch_changed(lbs_batch, arg_num_of_location);
719
720         g_object_unref(lbs_batch);
721
722         return LBS_SERVER_ERROR_NONE;
723 }
724
725 EXPORT_API int
726 lbs_server_emit_satellite_changed(lbs_server_dbus_h lbs_dbus_server, gint arg_timestamp, gint arg_satellite_used, gint arg_satellite_visible, GVariant *arg_used_prn, GVariant *arg_sat_info)
727 {
728         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
729         g_return_val_if_fail(arg_used_prn, LBS_SERVER_ERROR_PARAMETER);
730         g_return_val_if_fail(arg_sat_info, LBS_SERVER_ERROR_PARAMETER);
731
732         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)lbs_dbus_server;
733         g_return_val_if_fail(handle->obj_skeleton, LBS_SERVER_ERROR_PARAMETER);
734
735         LbsSatellite *sat = NULL;
736         sat = lbs_object_get_satellite(LBS_OBJECT(handle->obj_skeleton));
737         g_return_val_if_fail(sat, LBS_SERVER_ERROR_PARAMETER);
738
739         lbs_satellite_emit_satellite_changed(sat, arg_timestamp, arg_satellite_used, arg_satellite_visible, arg_used_prn, arg_sat_info);
740         g_object_unref(sat);
741
742         return LBS_SERVER_ERROR_NONE;
743 }
744
745 EXPORT_API int
746 lbs_server_emit_nmea_changed(lbs_server_dbus_h lbs_dbus_server, gint arg_timestamp, const gchar *arg_nmea_data)
747 {
748         LBS_SERVER_LOGW("timestamp: %d, nmea_data: %s", arg_timestamp, arg_nmea_data);
749
750         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
751         g_return_val_if_fail(arg_nmea_data, LBS_SERVER_ERROR_PARAMETER);
752
753         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)lbs_dbus_server;
754         g_return_val_if_fail(handle->obj_skeleton, LBS_SERVER_ERROR_PARAMETER);
755
756         LbsNmea *nmea = NULL;
757         nmea = lbs_object_get_nmea(LBS_OBJECT(handle->obj_skeleton));
758         g_return_val_if_fail(nmea, LBS_SERVER_ERROR_PARAMETER);
759
760         lbs_nmea_emit_nmea_changed(nmea, arg_timestamp, arg_nmea_data);
761         g_object_unref(nmea);
762
763         return LBS_SERVER_ERROR_NONE;
764 }
765
766 EXPORT_API int
767 lbs_server_emit_status_changed(lbs_server_dbus_h lbs_dbus_server, int method, gint status)
768 {
769         LBS_SERVER_LOGD("method: %d, status: %d", method, status);
770         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
771
772         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)lbs_dbus_server;
773         g_return_val_if_fail(handle->obj_skeleton, LBS_SERVER_ERROR_PARAMETER);
774
775         LbsManager *lbs_mgr = NULL;
776         lbs_mgr = lbs_object_get_manager(LBS_OBJECT(handle->obj_skeleton));
777         g_return_val_if_fail(lbs_mgr, LBS_SERVER_ERROR_PARAMETER);
778
779         handle->status = status;
780         lbs_manager_emit_status_changed(lbs_mgr, method, status);
781         g_object_unref(lbs_mgr);
782
783         return LBS_SERVER_ERROR_NONE;
784 }
785
786 /* gps-manager -> geofence-manager : enable/disable */
787 EXPORT_API int
788 lbs_server_emit_gps_geofence_status_changed(lbs_server_dbus_h lbs_dbus_server, gint status)
789 {
790         LBS_SERVER_LOGD("ENTER >>>");
791         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
792
793         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)lbs_dbus_server;
794         g_return_val_if_fail(handle->obj_skeleton, LBS_SERVER_ERROR_PARAMETER);
795
796         LbsGpsGeofence *gps_geofence = NULL;
797         gps_geofence = lbs_object_get_gps_geofence(LBS_OBJECT(handle->obj_skeleton));
798         g_return_val_if_fail(gps_geofence, LBS_SERVER_ERROR_PARAMETER);
799
800         handle->hw_geofence_status = status;
801         lbs_gps_geofence_emit_status_changed(gps_geofence, status);
802         g_object_unref(gps_geofence);
803
804         return LBS_SERVER_ERROR_NONE;
805 }
806
807 /* gps-manager -> geofence-manger: fence in/out */
808 EXPORT_API int
809 lbs_server_emit_gps_geofence_changed(lbs_server_dbus_h lbs_dbus_server, gint fence_id, gint transition, gdouble latitude, gdouble longitude, gdouble altitude, gdouble speed, gdouble bearing, gdouble hor_accuracy)
810 {
811         LBS_SERVER_LOGD("ENTER >>>");
812         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
813
814         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)lbs_dbus_server;
815         g_return_val_if_fail(handle->obj_skeleton, LBS_SERVER_ERROR_PARAMETER);
816
817         LbsGpsGeofence *gps_geofence = NULL;
818         gps_geofence = lbs_object_get_gps_geofence(LBS_OBJECT(handle->obj_skeleton));
819         g_return_val_if_fail(gps_geofence, LBS_SERVER_ERROR_PARAMETER);
820
821         lbs_gps_geofence_emit_geofence_changed(gps_geofence, fence_id, transition, latitude, longitude, altitude, speed, bearing, hor_accuracy);
822         g_object_unref(gps_geofence);
823
824         return LBS_SERVER_ERROR_NONE;
825 }
826
827 static void _glib_log(const gchar *log_domain, GLogLevelFlags log_level, const gchar *msg, gpointer user_data)
828 {
829         LBS_SERVER_LOGD("GLIB[%d]: %s", log_level, msg);
830 }
831
832 EXPORT_API int
833 lbs_server_create(char *service_name, char *service_path, char *name, char *description, lbs_server_dbus_h *lbs_dbus_server, lbs_server_dbus_cb_t *lbs_server_cb, gpointer userdata)
834 {
835         LBS_SERVER_LOGD("ENTER >>>");
836         g_return_val_if_fail(service_name, LBS_SERVER_ERROR_PARAMETER);
837         g_return_val_if_fail(service_path, LBS_SERVER_ERROR_PARAMETER);
838         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
839
840         int ret = LBS_SERVER_ERROR_NONE;
841
842         lbs_server_dbus_s *handle = g_new0(lbs_server_dbus_s, 1);
843         g_return_val_if_fail(handle, LBS_SERVER_ERROR_MEMORY);
844
845         g_log_set_default_handler(_glib_log, NULL);
846
847         handle->service_name = g_strdup(service_name);
848         handle->service_path = g_strdup(service_path);
849         handle->manager = g_dbus_object_manager_server_new(handle->service_path);
850
851         if (name)
852                 handle->name = g_strdup(name);
853
854         if (description)
855                 handle->description = g_strdup(description);
856
857         handle->connections = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
858         handle->userdata = userdata;
859
860 #if TIZEN_3_0_OPT
861         handle->callback = lbs_server_cb;
862 #endif
863
864         handle->set_options_cb = lbs_server_cb->set_options_cb;
865         handle->shutdown_cb = lbs_server_cb->shutdown_cb;
866         handle->update_interval_cb = lbs_server_cb->update_interval_cb;
867         handle->request_change_interval_cb = lbs_server_cb->request_change_interval_cb;
868         handle->get_nmea_cb = lbs_server_cb->get_nmea_cb;
869
870         /* Tizen 3.0 */
871         handle->set_mock_location_cb = lbs_server_cb->set_mock_location_cb;
872
873         /* add H/W gps-gefence callbacks */
874         handle->add_hw_fence_cb = lbs_server_cb->add_hw_fence_cb;
875         handle->delete_hw_fence_cb = lbs_server_cb->delete_hw_fence_cb;
876         handle->pause_hw_fence_cb = lbs_server_cb->pause_hw_fence_cb;
877         handle->resume_hw_fence_cb = lbs_server_cb->resume_hw_fence_cb;
878         handle->owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
879                                                   service_name, G_BUS_NAME_OWNER_FLAGS_REPLACE, on_bus_acquired, on_name_acquired, on_name_lost, handle, NULL);
880
881         LBS_SERVER_LOGD("g_bus_own_name id=[%d]", handle->owner_id);
882
883         *lbs_dbus_server = (lbs_server_dbus_h *)handle;
884
885         return ret;
886 }
887
888
889 EXPORT_API int
890 lbs_server_destroy(lbs_server_dbus_h lbs_dbus_server)
891 {
892         LBS_SERVER_LOGD("ENTER >>>");
893         g_return_val_if_fail(lbs_dbus_server, LBS_SERVER_ERROR_PARAMETER);
894
895         lbs_server_dbus_s *handle = (lbs_server_dbus_s *)lbs_dbus_server;
896
897         int ret = LBS_SERVER_ERROR_NONE;
898
899         g_bus_unown_name(handle->owner_id);
900
901         if (handle->prev_owner) {
902                 g_free(handle->prev_owner);
903                 handle->prev_owner = NULL;
904         }
905
906         LbsManager *lbs_mgr = NULL;
907         lbs_mgr = lbs_object_get_manager(LBS_OBJECT(handle->obj_skeleton));
908         g_return_val_if_fail(lbs_mgr, LBS_SERVER_ERROR_PARAMETER);
909
910         if (handle->get_providerinfo_h) {
911                 g_signal_handler_disconnect(lbs_mgr, handle->get_providerinfo_h);
912                 handle->get_providerinfo_h = 0;
913         }
914
915         if (handle->get_status_h) {
916                 g_signal_handler_disconnect(lbs_mgr, handle->get_status_h);
917                 handle->get_status_h = 0;
918         }
919
920         if (handle->set_option_h) {
921                 g_signal_handler_disconnect(lbs_mgr, handle->set_option_h);
922                 handle->set_option_h = 0;
923         }
924
925         if (handle->add_reference_h) {
926                 g_signal_handler_disconnect(lbs_mgr, handle->add_reference_h);
927                 handle->add_reference_h = 0;
928         }
929
930         if (handle->remove_reference_h) {
931                 g_signal_handler_disconnect(lbs_mgr, handle->remove_reference_h);
932                 handle->remove_reference_h = 0;
933         }
934
935         if (handle->set_mock_location_h) {
936                 g_signal_handler_disconnect(lbs_mgr, handle->set_mock_location_h);
937                 handle->set_mock_location_h = 0;
938         }
939         g_object_unref(lbs_mgr);
940
941         LbsNmea *nmea = NULL;
942         nmea = lbs_object_get_nmea(LBS_OBJECT(handle->obj_skeleton));
943         g_return_val_if_fail(nmea, LBS_SERVER_ERROR_PARAMETER);
944
945         if (handle->get_nmea_h) {
946                 g_signal_handler_disconnect(nmea, handle->get_nmea_h);
947                 handle->get_nmea_h = 0;
948         }
949         g_object_unref(nmea);
950
951         /* disconnect H/W gps-geofence callbacks */
952         LbsGpsGeofence *gps_geofence = NULL;
953         gps_geofence = lbs_object_get_gps_geofence(LBS_OBJECT(handle->obj_skeleton));
954         g_return_val_if_fail(gps_geofence, LBS_SERVER_ERROR_PARAMETER);
955
956         if (handle->add_hw_fence_h) {
957                 g_signal_handler_disconnect(gps_geofence, handle->add_hw_fence_h);
958                 handle->add_hw_fence_h = 0;
959         }
960
961         if (handle->delete_hw_fence_h) {
962                 g_signal_handler_disconnect(gps_geofence, handle->delete_hw_fence_h);
963                 handle->delete_hw_fence_h = 0;
964         }
965
966         if (handle->pause_hw_fence_h) {
967                 g_signal_handler_disconnect(gps_geofence, handle->pause_hw_fence_h);
968                 handle->pause_hw_fence_h = 0;
969         }
970
971         if (handle->resume_hw_fence_h) {
972                 g_signal_handler_disconnect(gps_geofence, handle->resume_hw_fence_h);
973                 handle->resume_hw_fence_h = 0;
974         }
975
976         g_object_unref(gps_geofence);
977
978         if (handle->manager) {
979                 if (handle->owner_changed_id) {
980                         g_dbus_connection_signal_unsubscribe(g_dbus_object_manager_server_get_connection(handle->manager), handle->owner_changed_id);
981                         handle->owner_changed_id = 0;
982                 }
983                 g_object_unref(handle->manager);
984                 handle->manager = NULL;
985         }
986
987         g_hash_table_destroy(handle->connections);
988
989         g_free(handle);
990
991         return ret;
992 }
993