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