svace : lbs_client_set_position_update_interval
[platform/core/location/lbs-dbus.git] / client / src / lbs_dbus_client.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 #include <app_manager.h>
21 #include <package_manager.h>
22 #include "lbs_dbus_client.h"
23 #include "lbs_dbus_client_priv.h"
24 #include "generated-code.h"
25
26 #define LOCATION_PRIVACY_ID     "http://tizen.org/privacy/location"
27 #define PRIVACY_INTERFACE       "org.tizen.privacy_manager.signal"
28 #define PRIVACY_MEMBER          "privacy_setting_changed"
29 #define PRIVACY_PATH            "/privacy_manager/dbus_notification"
30
31 typedef struct _lbs_client_dbus_s {
32         int is_started;
33         GDBusConnection *conn;
34         lbs_client_method_e method;
35         int loc_evt_id;
36         int loc_status_evt_id;
37         int sat_evt_id;
38         int batch_evt_id;
39         int nmea_evt_id;
40         int privacy_evt_id;
41         int fused_mode;
42         unsigned int interval;
43         lbs_client_cb user_cb;
44         lbs_client_cb batch_cb;
45         void *user_data;
46 } lbs_client_dbus_s;
47
48 static int __lbs_get_appid(char **app_id)
49 {
50         pid_t pid = getpid();
51         int ret = 0;
52         char *aid = NULL;
53
54         ret = app_manager_get_app_id(pid, &aid);
55         if (ret != APP_MANAGER_ERROR_NONE || aid == NULL) {
56                 LBS_CLIENT_LOGE("Fail to app_manager_get_package. Error[%d]", ret);
57                 return FALSE;
58         }
59         *app_id = (char *)g_malloc0(sizeof(char) * 64);
60         g_strlcpy(*app_id, aid, 64);
61         LBS_CLIENT_LOGD("get_appid [%s]", *app_id);
62         g_free(aid);
63
64         return TRUE;
65 }
66
67 static int __lbs_get_app_type(char *app_id, char **type)
68 {
69         int ret;
70         app_info_h app_info;
71         char *app_type = NULL;
72
73         ret = app_info_create(app_id, &app_info);
74         if (ret != APP_MANAGER_ERROR_NONE) {
75                 LBS_CLIENT_LOGE("Fail to get app_info. Err[%d]", ret);
76                 return FALSE;
77         }
78
79         ret = app_info_get_type(app_info, &app_type);
80         if (ret != APP_MANAGER_ERROR_NONE) {
81                 LBS_CLIENT_LOGE("Fail to get type. Err[%d]", ret);
82                 app_info_destroy(app_info);
83                 return FALSE;
84         }
85
86         *type = (char *)g_malloc0(sizeof(char) * 16);
87         g_strlcpy(*type, app_type, 16);
88         g_free(app_type);
89         app_info_destroy(app_info);
90
91         return TRUE;
92 }
93
94 static int __lbs_check_package_id(char *pkg_id)
95 {
96         int ret;
97         gchar *app_id = NULL;
98         gchar *type = NULL;
99         char *package_id = NULL;
100
101         if (!__lbs_get_appid(&app_id))
102                 return FALSE;
103
104         if (!__lbs_get_app_type(app_id, &type))
105                 return FALSE;
106
107         if ((g_strcmp0(type, "c++app") == 0) || (g_strcmp0(type, "webapp") == 0)) {
108                 LBS_CLIENT_LOGE("Do not check for App[%s] Type[%s]", app_id, type);
109                 g_free(app_id);
110                 g_free(type);
111                 return FALSE;
112         }
113         g_free(type);
114
115         ret = package_manager_get_package_id_by_app_id(app_id, &package_id);
116         if (ret != PACKAGE_MANAGER_ERROR_NONE) {
117                 LBS_CLIENT_LOGE("Fail to get package_id for [%s]. Err[%d]", app_id, ret);
118                 g_free(app_id);
119                 return FALSE;
120         }
121         LBS_CLIENT_LOGD("Current package[%s] / Privacy package[%s]", package_id, pkg_id);
122
123         if (g_strcmp0(pkg_id, package_id) == 0)
124                 ret = TRUE;
125         else
126                 ret = FALSE;
127
128         g_free(package_id);
129         g_free(app_id);
130
131         return ret;
132 }
133
134
135 static void __signal_batch_callback(GDBusConnection *conn, const gchar *name, const gchar *path, const gchar *interface, const gchar *sig, GVariant *param, gpointer user_data)
136 {
137         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)user_data;
138         if (handle == NULL) {
139                 LBS_CLIENT_LOGD("Invalid handle");
140                 return;
141         }
142
143         if (handle->is_started == FALSE) {
144                 LBS_CLIENT_LOGD("Handle[%p] is not started", handle);
145                 return;
146         }
147
148         if (handle->batch_cb)
149                 handle->batch_cb(sig, param, handle->user_data);
150 }
151
152 static void __signal_callback(GDBusConnection *conn, const gchar *name, const gchar *path, const gchar *interface, const gchar *sig, GVariant *param, gpointer user_data)
153 {
154         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)user_data;
155         if (handle == NULL) {
156                 LBS_CLIENT_LOGD("Invalid handle");
157                 return;
158         }
159
160         if (handle->is_started == FALSE) {
161                 LBS_CLIENT_LOGD("Handle[%p] is not started", handle);
162                 return;
163         }
164
165         if (handle->user_cb)
166                 handle->user_cb(sig, param, handle->user_data);
167 }
168
169 static void __privacy_setting_changed(GDBusConnection *conn, const gchar *name, const gchar *path, const gchar *interface, const gchar *sig, GVariant *param, gpointer user_data)
170 {
171         LBS_CLIENT_LOGD("ENTER >>>");
172
173         gchar *pkg_id = NULL;
174         gchar *privacy_id = NULL;
175
176         g_variant_get(param, "(ss)", &pkg_id, &privacy_id);
177         if (!pkg_id)
178                 return;
179
180         if (!privacy_id) {
181                 g_free(pkg_id);
182                 return;
183         }
184
185         if (g_strcmp0(privacy_id, LOCATION_PRIVACY_ID) != 0) {
186                 LBS_CLIENT_LOGD("[%s]'s [%s] privacy is changed", pkg_id, privacy_id);
187                 g_free(pkg_id);
188                 g_free(privacy_id);
189                 return;
190         }
191
192         LBS_CLIENT_LOGD("[%s]'s [%s] location privacy is changed", pkg_id, privacy_id);
193         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)user_data;
194
195         if (handle == NULL || handle->is_started == FALSE) {
196                 LBS_CLIENT_LOGE("Invalid handle or is_started [FALSE]");
197                 g_free(pkg_id);
198                 g_free(privacy_id);
199                 return;
200         }
201
202         if (!__lbs_check_package_id(pkg_id)) {
203                 LBS_CLIENT_LOGE("pkg_id[%s] is not current pakcage id", pkg_id);
204                 g_free(pkg_id);
205                 g_free(privacy_id);
206                 return;
207         }
208         g_free(pkg_id);
209         g_free(privacy_id);
210
211         if (lbs_client_stop(handle, handle->interval, handle->fused_mode) != LBS_CLIENT_ERROR_NONE)
212                 LBS_CLIENT_LOGE("lbs_client_stop is fail");
213
214         if (handle->user_cb)
215                 handle->user_cb("StatusChanged", g_variant_new("(i)", FALSE), handle->user_data);
216
217         lbs_client_destroy(handle);
218         handle = NULL;
219
220         LBS_CLIENT_LOGD("EXIT <<<");
221 }
222
223 static void
224 lbs_client_signal_unsubcribe(lbs_client_dbus_h lbs_client)
225 {
226         LBS_CLIENT_LOGD("lbs_client_unsubcribe");
227
228         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
229         if (handle == NULL) {
230                 LBS_CLIENT_LOGD("Invalid handle");
231                 return;
232         }
233         if (handle->conn == NULL) {
234                 LBS_CLIENT_LOGD("Invalid dbus_connection");
235                 return;
236         }
237
238         if (handle->loc_evt_id) {
239                 g_dbus_connection_signal_unsubscribe(handle->conn, handle->loc_evt_id);
240                 handle->loc_evt_id = 0;
241         }
242
243         if (handle->batch_evt_id) {
244                 g_dbus_connection_signal_unsubscribe(handle->conn, handle->batch_evt_id);
245                 handle->batch_evt_id = 0;
246         }
247
248         if (handle->sat_evt_id) {
249                 g_dbus_connection_signal_unsubscribe(handle->conn, handle->sat_evt_id);
250                 handle->sat_evt_id = 0;
251         }
252
253         if (handle->loc_status_evt_id) {
254                 g_dbus_connection_signal_unsubscribe(handle->conn, handle->loc_status_evt_id);
255                 handle->loc_status_evt_id = 0;
256         }
257
258         if (handle->nmea_evt_id) {
259                 g_dbus_connection_signal_unsubscribe(handle->conn, handle->nmea_evt_id);
260                 handle->nmea_evt_id = 0;
261         }
262 }
263
264 static void
265 lbs_client_privacy_signal_subcribe(lbs_client_dbus_h lbs_client)
266 {
267         LBS_CLIENT_LOGD("lbs_client_privacy_signal_subcribe");
268
269         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
270         handle->privacy_evt_id = g_dbus_connection_signal_subscribe(handle->conn,
271                                                                 NULL, PRIVACY_INTERFACE, PRIVACY_MEMBER, PRIVACY_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, __privacy_setting_changed, handle, NULL);
272
273         if (handle->privacy_evt_id)
274                 LBS_CLIENT_LOGD("Listening Privacy info");
275         else
276                 LBS_CLIENT_LOGD("Fail to listen Privacy info");
277 }
278
279 static void
280 lbs_client_privacy_signal_unsubcribe(lbs_client_dbus_h lbs_client)
281 {
282         LBS_CLIENT_LOGD("lbs_client_privacy_signal_unsubcribe");
283
284         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
285         if (handle->privacy_evt_id) {
286                 g_dbus_connection_signal_unsubscribe(handle->conn, handle->privacy_evt_id);
287                 handle->privacy_evt_id = 0;
288         }
289 }
290
291 EXPORT_API int
292 lbs_client_batch_start(lbs_client_dbus_h lbs_client, lbs_client_callback_e callback_type, lbs_client_cb callback, unsigned int batch_interval, unsigned int batch_period, void *user_data)
293 {
294         LBS_CLIENT_LOGD("lbs_client_batch_start");
295
296         g_return_val_if_fail(lbs_client, LBS_CLIENT_ERROR_PARAMETER);
297         g_return_val_if_fail(callback_type >= LBS_CLIENT_LOCATION_CB && callback_type <= LBS_CLIENT_BATCH_CB, LBS_CLIENT_ERROR_PARAMETER);
298
299         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
300         g_return_val_if_fail(handle->is_started == FALSE, LBS_CLIENT_ERROR_STATUS);
301
302         GVariant *reg = NULL;
303         GVariant *param = NULL, *method = NULL;
304         GError *error = NULL;
305         GVariantBuilder *builder = NULL;
306         GDBusProxy *proxy = NULL;
307         gchar *signal_path = NULL;
308         int ret = LBS_CLIENT_ERROR_NONE;
309
310         signal_path = g_strdup_printf("%s/%s", SERVICE_PATH, "SAMSUNG");
311         LBS_CLIENT_SECLOG("LBS signal subscribe Object Path [%s]", signal_path);
312
313         if (callback) {
314                 handle->batch_cb = callback;
315                 handle->user_data = user_data;
316
317                 if (callback_type & LBS_CLIENT_BATCH_CB) {
318                         handle->batch_evt_id = g_dbus_connection_signal_subscribe(handle->conn,
319                                                                           SERVICE_NAME, "org.tizen.lbs.Batch", "BatchChanged",
320                                                                           signal_path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, __signal_batch_callback, handle, NULL);
321
322                         if (handle->batch_evt_id)
323                                 LBS_CLIENT_LOGD("Listening batch info");
324                         else
325                                 LBS_CLIENT_LOGD("Fail to listen batch info");
326                 }
327         }
328         g_free(signal_path);
329
330         /* Start Batch */
331         LBS_CLIENT_LOGD("START: CMD-START_BATCH");
332         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
333         g_variant_builder_add(builder, "{sv}", "CMD", g_variant_new_string("START_BATCH"));
334         g_variant_builder_add(builder, "{sv}", "BATCH_INTERVAL", g_variant_new_int32((gint32) batch_interval));
335         g_variant_builder_add(builder, "{sv}", "BATCH_PERIOD", g_variant_new_int32((gint32) batch_period));
336         param = g_variant_ref_sink(g_variant_new("(@a{sv})", g_variant_builder_end(builder)));
337         method = g_variant_ref_sink(g_variant_new("(i)", handle->method));
338
339         proxy = g_dbus_proxy_new_sync(handle->conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
340                                                                   SERVICE_NAME, SERVICE_PATH, "org.tizen.lbs.Manager", NULL, &error);
341
342         if (error && error->message) {
343                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
344                         LBS_CLIENT_LOGE("Access denied. Msg[%s]", error->message);
345                         ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
346                 } else {
347                         LBS_CLIENT_LOGE("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
348                         ret = LBS_CLIENT_ERROR_DBUS_CALL;
349                 }
350                 g_error_free(error);
351                 g_variant_unref(param);
352                 g_variant_unref(method);
353                 lbs_client_signal_unsubcribe(handle);
354                 return ret;
355         }
356
357         if (proxy) {
358                 reg = g_dbus_proxy_call_sync(proxy, "AddReference", method, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
359                                                                          &error);
360
361                 if (error && error->message) {
362                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
363                                 LBS_CLIENT_LOGE("Access denied. Msg[%s]", error->message);
364                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
365                         } else {
366                                 LBS_CLIENT_LOGE("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
367                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
368                         }
369                         g_error_free(error);
370                         g_variant_unref(param);
371                         g_variant_unref(method);
372                         lbs_client_signal_unsubcribe(handle);
373                         return ret;
374                 }
375                 if (reg) {
376                         g_variant_unref(reg);
377                         reg = NULL;
378                 }
379
380                 reg = g_dbus_proxy_call_sync(proxy, "SetOptions", param, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error);
381
382                 if (error && error->message) {
383                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
384                                 LBS_CLIENT_LOGE("Access denied. Msg[%s]", error->message);
385                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
386                         } else {
387                                 LBS_CLIENT_LOGE("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
388                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
389                         }
390                         g_error_free(error);
391                         g_variant_unref(param);
392                         g_variant_unref(method);
393
394                         lbs_client_signal_unsubcribe(handle);
395                         return ret;
396                 }
397                 if (reg) {
398                         g_variant_unref(reg);
399                         reg = NULL;
400                 }
401
402                 g_object_unref(proxy);
403         }
404
405         /* g_variant_builder_unref(builder); */
406         g_variant_unref(method);
407         g_variant_unref(param);
408
409         lbs_client_privacy_signal_subcribe(handle);
410         handle->is_started = TRUE;
411
412         return LBS_CLIENT_ERROR_NONE;
413 }
414
415 EXPORT_API int
416 lbs_client_set_position_update_interval(lbs_client_dbus_h lbs_client, unsigned int interval, unsigned int prev_interval)
417 {
418         LBS_CLIENT_LOGD("lbs_client_set_position_update_interval");
419         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
420
421         g_return_val_if_fail(handle, LBS_CLIENT_ERROR_PARAMETER);
422         g_return_val_if_fail(handle->is_started == TRUE, LBS_CLIENT_ERROR_STATUS);
423
424         GVariant *reg = NULL;
425         GVariant *param = NULL;
426         GVariant *method = NULL;
427         GError *error = NULL;
428         GVariantBuilder *builder = NULL;
429         GDBusProxy *proxy = NULL;
430         gchar *signal_path = NULL;
431         int ret = LBS_CLIENT_ERROR_NONE;
432
433         signal_path = g_strdup_printf("%s/%s", SERVICE_PATH, "SAMSUNG");
434         LBS_CLIENT_LOGD("LBS signal subscribe Object Path [%s]", signal_path);
435         g_free(signal_path);
436
437         LBS_CLIENT_LOGD("SET option INTERVAL_UPDATE:[%u -> %u], method:[%d]", prev_interval, interval, method);
438         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
439         g_variant_builder_add(builder, "{sv}", "CMD", g_variant_new_string("SET:OPT"));
440         g_variant_builder_add(builder, "{sv}", "INTERVAL_UPDATE", g_variant_new_uint32(interval));
441         g_variant_builder_add(builder, "{sv}", "PREV_INTERVAL", g_variant_new_uint32(prev_interval));
442         g_variant_builder_add(builder, "{sv}", "METHOD", g_variant_new_int32(handle->method));
443         g_variant_builder_add(builder, "{sv}", "FUSED_MODE", g_variant_new_int32(handle->fused_mode));
444         param = g_variant_ref_sink(g_variant_new("(@a{sv})", g_variant_builder_end(builder)));
445         method = g_variant_ref_sink(g_variant_new("(i)", handle->method));
446
447         proxy = g_dbus_proxy_new_sync(handle->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, SERVICE_NAME, SERVICE_PATH, "org.tizen.lbs.Manager", NULL, &error);
448
449         if (error && error->message) {
450                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
451                         LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
452                         ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
453                 } else {
454                         LBS_CLIENT_LOGI("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
455                         ret = LBS_CLIENT_ERROR_DBUS_CALL;
456                 }
457                 g_error_free(error);
458                 g_variant_unref(param);
459                 g_variant_unref(method);
460
461                 g_object_unref(proxy);
462                 return ret;
463         }
464
465         error = NULL;
466         if (proxy) {
467                 reg = g_dbus_proxy_call_sync(proxy, "SetOptions", param, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error);
468                 if (error && error->message) {
469                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
470                                 LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
471                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
472                         } else {
473                                 LBS_CLIENT_LOGI("Fail to proxy call. ErrCode[%d], Msg[%s]", error->code, error->message);
474                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
475                         }
476                         g_error_free(error);
477                         g_variant_unref(param);
478                         g_variant_unref(method);
479
480                         g_object_unref(proxy);
481                         return ret;
482                 }
483
484                 if (reg) {
485                         g_variant_unref(reg);
486                         reg = NULL;
487                 }
488
489                 reg = g_dbus_proxy_call_sync(proxy, "RemoveReference", method, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error);
490
491                 if (error && error->message) {
492                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
493                                 LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
494                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
495                         } else {
496                                 LBS_CLIENT_LOGI("Fail to proxy call. ErrCode[%d], Msg[%s]", error->code, error->message);
497                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
498                         }
499                         g_error_free(error);
500                         g_variant_unref(param);
501                         g_variant_unref(method);
502
503                         g_object_unref(proxy);
504                         return ret;
505                 }
506                 if (reg) {
507                         g_variant_unref(reg);
508                         reg = NULL;
509                 }
510
511                 g_object_unref(proxy);
512         }
513         /* g_variant_builder_unref(builder); */
514         g_variant_unref(param);
515         g_variant_unref(method);
516
517         return LBS_CLIENT_ERROR_NONE;
518 }
519
520 EXPORT_API int
521 lbs_client_batch_stop(lbs_client_dbus_h lbs_client)
522 {
523         LBS_CLIENT_LOGD("lbs_client_batch_stop");
524
525         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
526         g_return_val_if_fail(handle, LBS_CLIENT_ERROR_PARAMETER);
527         g_return_val_if_fail(handle->is_started == TRUE, LBS_CLIENT_ERROR_STATUS);
528
529         int ret = LBS_CLIENT_ERROR_NONE;
530         GVariant *param = NULL, *method = NULL, *reg = NULL;
531         GError *error = NULL;
532         GVariantBuilder *builder = NULL;
533
534         lbs_client_privacy_signal_unsubcribe(handle);
535         lbs_client_signal_unsubcribe(handle);
536
537         /* Stop */
538         LBS_CLIENT_LOGD("STOP: CMD-STOP_BATCH");
539         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
540         g_variant_builder_add(builder, "{sv}", "CMD", g_variant_new_string("STOP_BATCH"));
541
542         LBS_CLIENT_LOGD("METHOD: %d", handle->method);
543         g_variant_builder_add(builder, "{sv}", "METHOD", g_variant_new_int32(handle->method));
544         param = g_variant_ref_sink(g_variant_new("(@a{sv})", g_variant_builder_end(builder)));
545         method = g_variant_ref_sink(g_variant_new("(i)", handle->method));
546
547         GDBusProxy *proxy = NULL;
548         proxy = g_dbus_proxy_new_sync(handle->conn, G_DBUS_PROXY_FLAGS_NONE, NULL, SERVICE_NAME, SERVICE_PATH, "org.tizen.lbs.Manager", NULL, &error);
549
550         if (error && error->message) {
551                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
552                         LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
553                         ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
554                 } else {
555                         LBS_CLIENT_LOGI("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
556                         ret = LBS_CLIENT_ERROR_DBUS_CALL;
557                 }
558                 g_error_free(error);
559                 g_variant_unref(param);
560                 g_variant_unref(method);
561
562                 g_object_unref(proxy);
563                 return ret;
564         }
565
566         error = NULL;
567         if (proxy) {
568                 reg = g_dbus_proxy_call_sync(proxy, "SetOptions", param, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error);
569                 if (error && error->message) {
570                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
571                                 LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
572                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
573                         } else {
574                                 LBS_CLIENT_LOGI("Fail to proxy call. ErrCode[%d], Msg[%s]", error->code, error->message);
575                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
576                         }
577                         g_error_free(error);
578                         g_variant_unref(param);
579                         g_variant_unref(method);
580
581                         g_object_unref(proxy);
582                         return ret;
583                 }
584
585                 if (reg) {
586                         g_variant_unref(reg);
587                         reg = NULL;
588                 }
589
590                 g_object_unref(proxy);
591         }
592         /* g_variant_builder_unref (builder); */
593         g_variant_unref(param);
594         g_variant_unref(method);
595
596         handle->is_started = FALSE;
597
598         return ret;
599 }
600
601 EXPORT_API int
602 lbs_client_start(lbs_client_dbus_h lbs_client, unsigned int interval, lbs_client_callback_e callback_type, lbs_client_cb callback, int fused_mode, void *user_data)
603 {
604         LBS_CLIENT_LOGD("lbs_client_start");
605         g_return_val_if_fail(lbs_client, LBS_CLIENT_ERROR_PARAMETER);
606         g_return_val_if_fail(callback_type >= LBS_CLIENT_LOCATION_CB && callback_type <= LBS_CLIENT_BATCH_CB, LBS_CLIENT_ERROR_PARAMETER);
607
608         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
609         g_return_val_if_fail(handle->is_started == FALSE, LBS_CLIENT_ERROR_STATUS);
610
611         GVariant *reg = NULL;
612         GVariant *param = NULL, *method = NULL;
613         GError *error = NULL;
614         GVariantBuilder *builder = NULL;
615         GDBusProxy *proxy = NULL;
616         gchar *signal_path = NULL;
617         gchar *app_id = NULL;
618         int ret = LBS_CLIENT_ERROR_NONE;
619
620         signal_path = g_strdup_printf("%s/%s", SERVICE_PATH, "SAMSUNG");
621         LBS_CLIENT_SECLOG("LBS signal subscribe Object Path [%s]", signal_path);
622
623         if (callback) {
624                 handle->user_cb = callback;
625                 handle->user_data = user_data;
626
627                 if (callback_type & LBS_CLIENT_LOCATION_CB) {
628                         handle->loc_evt_id = g_dbus_connection_signal_subscribe(handle->conn,
629                                                                 SERVICE_NAME, "org.tizen.lbs.Position", "PositionChanged", signal_path,
630                                                                 NULL, G_DBUS_SIGNAL_FLAGS_NONE, __signal_callback, handle, NULL);
631
632                         if (handle->loc_evt_id)
633                                 LBS_CLIENT_LOGD("Listening Position info");
634                         else
635                                 LBS_CLIENT_LOGD("Fail to listen Position info");
636                 }
637
638                 if (callback_type & LBS_CLIENT_LOCATION_STATUS_CB) {
639                         handle->loc_status_evt_id = g_dbus_connection_signal_subscribe(handle->conn,
640                                                                                 SERVICE_NAME, "org.tizen.lbs.Manager", "StatusChanged", SERVICE_PATH,
641                                                                                 NULL, G_DBUS_SIGNAL_FLAGS_NONE, __signal_callback, handle, NULL);
642
643                         if (handle->loc_status_evt_id)
644                                 LBS_CLIENT_LOGD("Listening location Status");
645                         else
646                                 LBS_CLIENT_LOGD("Fail to listen location Status");
647                 }
648
649                 if (callback_type & LBS_CLIENT_SATELLITE_CB) {
650                         handle->sat_evt_id = g_dbus_connection_signal_subscribe(handle->conn,
651                                                                         SERVICE_NAME, "org.tizen.lbs.Satellite", "SatelliteChanged", signal_path,
652                                                                         NULL, G_DBUS_SIGNAL_FLAGS_NONE, __signal_callback, handle, NULL);
653
654                         if (handle->sat_evt_id)
655                                 LBS_CLIENT_LOGD("Listening satellite info");
656                         else
657                                 LBS_CLIENT_LOGD("Fail to listen satellite info");
658                 }
659
660                 if (callback_type & LBS_CLIENT_NMEA_CB) {
661                         handle->nmea_evt_id = g_dbus_connection_signal_subscribe(handle->conn,
662                                                                  SERVICE_NAME, "org.tizen.lbs.Nmea", "NmeaChanged", signal_path,
663                                                                  NULL, G_DBUS_SIGNAL_FLAGS_NONE, __signal_callback, handle, NULL);
664
665                         if (handle->nmea_evt_id)
666                                 LBS_CLIENT_LOGD("Listening nmea info");
667                         else
668                                 LBS_CLIENT_LOGD("Fail to listen nmea info");
669                 }
670         }
671         g_free(signal_path);
672
673         /* Start */
674         LBS_CLIENT_LOGD("START: CMD-START");
675         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
676         g_variant_builder_add(builder, "{sv}", "CMD", g_variant_new_string("START"));
677         g_variant_builder_add(builder, "{sv}", "METHOD", g_variant_new_int32(handle->method));
678         g_variant_builder_add(builder, "{sv}", "INTERVAL", g_variant_new_uint32(interval));
679         g_variant_builder_add(builder, "{sv}", "FUSED_MODE", g_variant_new_int32(fused_mode));
680
681         if (__lbs_get_appid(&app_id)) {
682                 LBS_CLIENT_LOGD("[%s] Request START", app_id);
683                 g_variant_builder_add(builder, "{sv}", "APP_ID", g_variant_new_string(app_id));
684
685                 if (app_id)
686                         g_free(app_id);
687         }
688
689         param = g_variant_ref_sink(g_variant_new("(@a{sv})", g_variant_builder_end(builder)));
690         method = g_variant_ref_sink(g_variant_new("(i)", handle->method));
691         proxy = g_dbus_proxy_new_sync(handle->conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
692                                                                         SERVICE_NAME, SERVICE_PATH, "org.tizen.lbs.Manager", NULL, &error);
693
694         if (error && error->message) {
695                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
696                         LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
697                         ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
698                 } else {
699                         LBS_CLIENT_LOGI("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
700                         ret = LBS_CLIENT_ERROR_DBUS_CALL;
701                 }
702                 g_error_free(error);
703                 g_variant_unref(param);
704                 g_variant_unref(method);
705                 lbs_client_signal_unsubcribe(handle);
706                 return ret;
707         }
708
709         if (proxy) {
710                 reg = g_dbus_proxy_call_sync(proxy, "AddReference", method, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
711
712                 if (error && error->message) {
713                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
714                                 LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
715                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
716                         } else {
717                                 LBS_CLIENT_LOGI("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
718                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
719                         }
720                         g_error_free(error);
721                         g_variant_unref(param);
722                         g_variant_unref(method);
723                         lbs_client_signal_unsubcribe(handle);
724                         return ret;
725                 }
726                 if (reg) {
727                         g_variant_unref(reg);
728                         reg = NULL;
729                 }
730
731                 reg = g_dbus_proxy_call_sync(proxy, "SetOptions", param, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error);
732                 if (error && error->message) {
733                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
734                                 LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
735                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
736                         } else {
737                                 LBS_CLIENT_LOGI("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
738                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
739                         }
740                         g_error_free(error);
741                         g_variant_unref(param);
742                         g_variant_unref(method);
743
744                         lbs_client_signal_unsubcribe(handle);
745                         return ret;
746                 }
747                 if (reg) {
748                         g_variant_unref(reg);
749                         reg = NULL;
750                 }
751
752                 g_object_unref(proxy);
753         }
754
755         /* g_variant_builder_unref (builder); */
756         g_variant_unref(param);
757         g_variant_unref(method);
758
759         lbs_client_privacy_signal_subcribe(handle);
760         handle->is_started = TRUE;
761         handle->interval = interval;
762         handle->fused_mode = fused_mode;
763
764         return LBS_CLIENT_ERROR_NONE;
765 }
766
767 EXPORT_API int
768 lbs_client_stop(lbs_client_dbus_h lbs_client, unsigned int interval, int fused_mode)
769 {
770         LBS_CLIENT_LOGD("lbs_client_stop [interval: %d]", interval);
771
772         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
773         g_return_val_if_fail(handle, LBS_CLIENT_ERROR_PARAMETER);
774         g_return_val_if_fail(handle->is_started == TRUE, LBS_CLIENT_ERROR_STATUS);
775
776         int ret = LBS_CLIENT_ERROR_NONE;
777         GVariant *param = NULL, *method = NULL, *reg = NULL;
778         GError *error = NULL;
779         GVariantBuilder *builder = NULL;
780         gchar *app_id = NULL;
781
782         lbs_client_privacy_signal_unsubcribe(handle);
783         lbs_client_signal_unsubcribe(handle);
784
785         /* Stop */
786         LBS_CLIENT_LOGD("STOP: CMD-STOP");
787         builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
788         g_variant_builder_add(builder, "{sv}", "CMD", g_variant_new_string("STOP"));
789
790         LBS_CLIENT_LOGD("METHOD: %d", handle->method);
791         g_variant_builder_add(builder, "{sv}", "METHOD", g_variant_new_int32(handle->method));
792         g_variant_builder_add(builder, "{sv}", "INTERVAL", g_variant_new_uint32(interval));
793         g_variant_builder_add(builder, "{sv}", "FUSED_MODE", g_variant_new_int32(fused_mode));
794
795         if (__lbs_get_appid(&app_id)) {
796                 LBS_CLIENT_LOGD("[%s] Request STOP", app_id);
797                 g_variant_builder_add(builder, "{sv}", "APP_ID", g_variant_new_string(app_id));
798
799                 if (app_id)
800                         g_free(app_id);
801         }
802
803         param = g_variant_ref_sink(g_variant_new("(@a{sv})", g_variant_builder_end(builder)));
804         method = g_variant_ref_sink(g_variant_new("(i)", handle->method));
805
806         GDBusProxy *proxy = NULL;
807         proxy = g_dbus_proxy_new_sync(handle->conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
808                                                                 SERVICE_NAME, SERVICE_PATH, "org.tizen.lbs.Manager", NULL, &error);
809
810         if (error && error->message) {
811                 if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
812                         LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
813                         ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
814                 } else {
815                         LBS_CLIENT_LOGI("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
816                         ret = LBS_CLIENT_ERROR_DBUS_CALL;
817                 }
818                 g_error_free(error);
819                 g_variant_unref(param);
820                 g_variant_unref(method);
821
822                 g_object_unref(proxy);
823                 return ret;
824         }
825
826         error = NULL;
827         if (proxy) {
828                 reg = g_dbus_proxy_call_sync(proxy, "SetOptions", param, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error);
829                 if (error && error->message) {
830                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
831                                 LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
832                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
833                         } else {
834                                 LBS_CLIENT_LOGI("Fail to proxy call. ErrCode[%d], Msg[%s]", error->code, error->message);
835                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
836                         }
837                         g_error_free(error);
838                         g_variant_unref(param);
839                         g_variant_unref(method);
840
841                         g_object_unref(proxy);
842                         return ret;
843                 }
844
845                 if (reg) {
846                         g_variant_unref(reg);
847                         reg = NULL;
848                 }
849
850                 reg = g_dbus_proxy_call_sync(proxy, "RemoveReference", method, G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error);
851
852                 if (error && error->message) {
853                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
854                                 LBS_CLIENT_LOGI("Access denied. Msg[%s]", error->message);
855                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
856                         } else {
857                                 LBS_CLIENT_LOGI("Fail to proxy call. ErrCode[%d], Msg[%s]", error->code, error->message);
858                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
859                         }
860                         g_error_free(error);
861                         g_variant_unref(param);
862                         g_variant_unref(method);
863
864                         g_object_unref(proxy);
865                         return ret;
866                 }
867                 if (reg) {
868                         g_variant_unref(reg);
869                         reg = NULL;
870                 }
871
872                 g_object_unref(proxy);
873         }
874         /* g_variant_builder_unref (builder); */
875         g_variant_unref(param);
876         g_variant_unref(method);
877
878         handle->is_started = FALSE;
879
880         return ret;
881 }
882
883 EXPORT_API int
884 lbs_client_get_nmea(lbs_client_dbus_h lbs_client, int *timestamp, char **nmea)
885 {
886         g_return_val_if_fail(lbs_client, LBS_CLIENT_ERROR_PARAMETER);
887         g_return_val_if_fail(timestamp, LBS_CLIENT_ERROR_PARAMETER);
888         g_return_val_if_fail(nmea, LBS_CLIENT_ERROR_PARAMETER);
889
890         GError *error = NULL;
891         int ret = LBS_CLIENT_ERROR_NONE;
892
893         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
894         *timestamp = 0;
895         *nmea = NULL;
896
897         LbsNmea *proxy = NULL;
898         proxy = lbs_nmea_proxy_new_sync(handle->conn, G_DBUS_PROXY_FLAGS_NONE, SERVICE_NAME, SERVICE_PATH, NULL, &error);
899
900         gint cur_timestamp = 0;
901         gchar *cur_nmea_data = NULL;
902
903         if (proxy) {
904                 ret = lbs_nmea_call_get_nmea_sync(proxy, &cur_timestamp, &cur_nmea_data, NULL, &error);
905                 if (error && error->message) {
906                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
907                                 LBS_CLIENT_LOGE("Access denied. Msg[%s]", error->message);
908                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
909                         } else {
910                                 LBS_CLIENT_LOGE("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
911                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
912                         }
913                         g_error_free(error);
914                         return ret;
915                 }
916
917                 LBS_CLIENT_LOGD("Get NMEA: Timestamp[%d], NMEA[%s]", cur_timestamp, cur_nmea_data);
918                 *timestamp = cur_timestamp;
919                 *nmea = cur_nmea_data;
920
921                 g_object_unref(proxy);
922         }
923
924         return LBS_CLIENT_ERROR_NONE;
925 }
926
927 static int
928 _client_create_connection(lbs_client_dbus_s *client)
929 {
930         LBS_CLIENT_LOGD("create connection");
931         g_return_val_if_fail(client, LBS_CLIENT_ERROR_PARAMETER);
932         GError *error = NULL;
933
934         client->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
935         if (!client->conn) {
936                 if (error && error->message) {
937                         LBS_CLIENT_LOGI("Fail to get GBus. ErrCode[%d], Msg[%s]", error->code, error->message);
938                         g_error_free(error);
939                         error = NULL;
940                 }
941                 LBS_CLIENT_LOGI("Fail to get addr of bus.");
942                 return LBS_CLIENT_ERROR_CONNECTION;
943         }
944
945         LBS_CLIENT_LOGD("client->conn: %p", client->conn);
946
947         return LBS_CLIENT_ERROR_NONE;
948 }
949
950 static void _glib_log(const gchar *log_domain, GLogLevelFlags log_level,
951                                           const gchar *msg, gpointer user_data)
952 {
953         LBS_CLIENT_LOGD("GLIB[%d] : %s", log_level, msg);
954 }
955
956 /* The reason why we seperate this from start is to support IPC for db operation between a server and a client. */
957 EXPORT_API int
958 lbs_client_create(lbs_client_method_e method, lbs_client_dbus_h *lbs_client)
959 {
960         LBS_CLIENT_LOGD("lbs_client_create");
961         g_return_val_if_fail(lbs_client, LBS_CLIENT_ERROR_PARAMETER);
962
963         int ret = LBS_CLIENT_ERROR_NONE;
964
965         lbs_client_dbus_s *client = g_new0(lbs_client_dbus_s, 1);
966         g_return_val_if_fail(client, LBS_CLIENT_ERROR_MEMORY);
967
968         g_log_set_default_handler(_glib_log, NULL);
969
970         ret = _client_create_connection(client);
971         if (ret != LBS_CLIENT_ERROR_NONE) {
972                 g_free(client);
973                 return ret;
974         }
975
976         client->method = method;
977
978         *lbs_client = (lbs_client_dbus_s *)client;
979
980         return LBS_CLIENT_ERROR_NONE;
981 }
982
983 EXPORT_API int
984 lbs_client_destroy(lbs_client_dbus_h lbs_client)
985 {
986         LBS_CLIENT_LOGD("lbs_client_destroy");
987         g_return_val_if_fail(lbs_client, LBS_CLIENT_ERROR_PARAMETER);
988
989         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
990         g_return_val_if_fail(handle->is_started == FALSE, LBS_CLIENT_ERROR_STATUS);
991
992         handle->user_cb = NULL;
993         handle->batch_cb = NULL;
994         handle->user_data = NULL;
995
996         if (handle->conn) {
997                 g_object_unref(handle->conn);
998                 handle->conn = NULL;
999         }
1000
1001         g_free(handle);
1002
1003         return LBS_CLIENT_ERROR_NONE;
1004 }
1005
1006 /* Tizen 3.0 */
1007
1008 static void __dbus_set_location_callback(GObject *source_object, GAsyncResult *res, gpointer user_data)
1009 {
1010         LBS_CLIENT_LOGD(">>> __dbus_set_location_callback");
1011
1012         g_return_if_fail(source_object);
1013         g_return_if_fail(res);
1014
1015         GError *error = NULL;
1016         gboolean success = FALSE;
1017         LbsManager *proxy = (LbsManager *)source_object;
1018
1019         /* TODO: lbs-server will send method and status via DBUS. Have to change lbs.xml */
1020         success = lbs_manager_call_set_mock_location_finish(proxy, res, &error);
1021         if (success != TRUE) {
1022                 LBS_CLIENT_LOGW("SetLocation failed!!!");
1023
1024                 if (error && error->message) {
1025                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
1026                                 LBS_CLIENT_LOGE("Access denied. Msg[%s]", error->message);
1027                         else
1028                                 LBS_CLIENT_LOGE("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
1029
1030                         g_error_free(error);
1031                 }
1032         }
1033 }
1034
1035 EXPORT_API int
1036 lbs_client_set_mock_location_async(lbs_client_dbus_h lbs_client, gint method,
1037         gdouble latitude, gdouble longitude, gdouble altitude, gdouble speed, gdouble direction,
1038         gdouble accuracy, lbs_client_cb callback, void *user_data)
1039 {
1040         LBS_CLIENT_LOGD("ENTER >>> lbs_client_set_mock_location_async");
1041         g_return_val_if_fail(lbs_client, LBS_CLIENT_ERROR_PARAMETER);
1042
1043         lbs_client_dbus_s *handle = (lbs_client_dbus_s *)lbs_client;
1044         int ret = LBS_CLIENT_ERROR_NONE;
1045
1046         handle->user_data = user_data;
1047
1048         LbsManager *proxy = NULL;
1049         GError *error = NULL;
1050
1051         proxy = lbs_manager_proxy_new_sync(handle->conn, G_DBUS_PROXY_FLAGS_NONE, SERVICE_NAME, SERVICE_PATH, NULL, &error);
1052
1053         if (proxy) {
1054                 lbs_manager_call_set_mock_location(proxy, method, latitude, longitude, altitude, speed, direction,
1055                                                                                         accuracy, NULL, __dbus_set_location_callback, handle);
1056
1057                 g_object_unref(proxy);
1058                 proxy = NULL;
1059         } else {
1060                 if (error && error->message) {
1061                         if (error->code == G_DBUS_ERROR_ACCESS_DENIED) {
1062                                 LBS_CLIENT_LOGE("Access denied. Msg[%s]", error->message);
1063                                 ret = LBS_CLIENT_ERROR_ACCESS_DENIED;
1064                         } else {
1065                                 LBS_CLIENT_LOGE("Fail to new proxy ErrCode[%d], Msg[%s]", error->code, error->message);
1066                                 ret = LBS_CLIENT_ERROR_DBUS_CALL;
1067                         }
1068                         g_error_free(error);
1069                 }
1070         }
1071
1072         return ret;
1073 }
1074