Rollback changes to submit TIZEN:COMMON project
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-adapter.c
1 /*
2  * bluetooth-frwk
3  *
4  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
20 #include <stdio.h>
21 #include <dbus/dbus-glib.h>
22 #include <dbus/dbus.h>
23 #include <glib.h>
24 #include <dlog.h>
25 #include <string.h>
26 #include <vconf.h>
27 #include <status.h>
28 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
29 #include <syspopup_caller.h>
30 #endif
31 #ifdef __TIZEN_MOBILE__
32 #include <aul.h>
33 #endif
34 #include "alarm.h"
35
36 #include "bluetooth-api.h"
37 #include "bt-internal-types.h"
38
39 #include "bt-service-common.h"
40 #include "bt-service-event.h"
41 #include "bt-service-adapter.h"
42 #include "bt-service-util.h"
43 #include "bt-service-network.h"
44 #include "bt-service-obex-server.h"
45 #include "bt-service-agent.h"
46 #include "bt-service-main.h"
47 #include "bt-service-avrcp.h"
48
49 typedef struct {
50         guint event_id;
51         int timeout;
52         time_t start_time;
53         int alarm_id;
54 } bt_adapter_timer_t;
55
56 bt_adapter_timer_t visible_timer;
57 static gboolean is_discovering;
58 static gboolean cancel_by_user;
59 static bt_status_t adapter_status = BT_DEACTIVATED;
60 static void *adapter_agent = NULL;
61 static DBusGProxy *core_proxy = NULL;
62
63 #define BT_CORE_NAME "org.projectx.bt_core"
64 #define BT_CORE_PATH "/org/projectx/bt_core"
65 #define BT_CORE_INTERFACE "org.projectx.btcore"
66
67 static gboolean __bt_timeout_handler(gpointer user_data)
68 {
69         int result = BLUETOOTH_ERROR_NONE;
70         time_t current_time;
71         int time_diff;
72
73         /* Take current time */
74         time(&current_time);
75         time_diff = difftime(current_time, visible_timer.start_time);
76
77         /* Send event to application */
78         _bt_send_event(BT_ADAPTER_EVENT,
79                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
80                         DBUS_TYPE_INT32, &result,
81                         DBUS_TYPE_INT16, &time_diff,
82                         DBUS_TYPE_INVALID);
83
84         if (visible_timer.timeout <= time_diff) {
85                 g_source_remove(visible_timer.event_id);
86                 visible_timer.event_id = 0;
87                 visible_timer.timeout = 0;
88
89                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
90                         BT_DBG("Set vconf failed\n");
91                 return FALSE;
92         }
93
94         return TRUE;
95 }
96
97 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
98 {
99         BT_DBG("__bt_visibility_alarm_cb \n");
100
101         /* Switch Off visibility in Bluez */
102         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
103         visible_timer.alarm_id = 0;
104         alarmmgr_fini();
105         return 0;
106 }
107
108 static void __bt_visibility_alarm_create()
109 {
110         alarm_id_t alarm_id;
111         int result;
112
113         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
114                                                 0, NULL, &alarm_id);
115         if(result < 0) {
116                 BT_DBG("Failed to create alarm error = %d\n", result);
117                 alarmmgr_fini();
118         } else {
119                 BT_DBG("Alarm created = %d\n", alarm_id);
120                 visible_timer.alarm_id = alarm_id;
121         }
122 }
123
124 int __bt_set_visible_time(int timeout)
125 {
126         int result;
127
128         if (visible_timer.event_id > 0) {
129                 g_source_remove(visible_timer.event_id);
130                 visible_timer.event_id = 0;
131         }
132
133         if (visible_timer.alarm_id > 0) {
134                 alarmmgr_remove_alarm(visible_timer.alarm_id);
135                 visible_timer.alarm_id = 0;
136         }
137
138         visible_timer.timeout = timeout;
139
140         if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
141                 BT_ERR("Set vconf failed\n");
142
143         if (timeout <= 0)
144                 return BLUETOOTH_ERROR_NONE;
145
146         /* Take start time */
147         time(&(visible_timer.start_time));
148         visible_timer.event_id = g_timeout_add_seconds(1,
149                                 __bt_timeout_handler, NULL);
150
151         /* Set Alarm timer to switch off BT */
152         result = alarmmgr_init("bt-service");
153         if (result != 0)
154                 return BLUETOOTH_ERROR_INTERNAL;
155
156         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
157         if (result != 0)
158                 return BLUETOOTH_ERROR_INTERNAL;
159
160         __bt_visibility_alarm_create();
161
162         return BLUETOOTH_ERROR_NONE;
163 }
164
165 static void __bt_get_service_list(GValue *value, bluetooth_device_info_t *dev)
166 {
167         int i;
168         char **uuids;
169         char **parts;
170
171         ret_if(value == NULL);
172         ret_if(dev == NULL);
173
174         uuids = g_value_get_boxed(value);
175         ret_if(uuids == NULL);
176
177         dev->service_index = 0;
178
179         for (i = 0; uuids[i] != NULL; i++) {
180                 g_strlcpy(dev->uuids[i], uuids[i], BLUETOOTH_UUID_STRING_MAX);
181
182                 parts = g_strsplit(uuids[i], "-", -1);
183
184                 if (parts == NULL || parts[0] == NULL)
185                         break;
186
187                 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
188                 g_strfreev(parts);
189
190                 dev->service_index++;
191         }
192 }
193
194 static bt_remote_dev_info_t *__bt_parse_remote_device_info(
195                                         DBusMessageIter *item_iter)
196 {
197         DBusMessageIter value_iter;
198         bt_remote_dev_info_t *dev_info;
199
200         dbus_message_iter_recurse(item_iter, &value_iter);
201
202         if (dbus_message_iter_get_arg_type(&value_iter) !=
203                                         DBUS_TYPE_DICT_ENTRY) {
204                 BT_DBG("No entry");
205                 return NULL;
206         }
207
208         dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
209
210         while (dbus_message_iter_get_arg_type(&value_iter) ==
211                                                 DBUS_TYPE_DICT_ENTRY) {
212                 char *value = NULL;
213                 char *key;
214                 DBusMessageIter dict_entry;
215                 DBusMessageIter iter_dict_val;
216
217                 dbus_message_iter_recurse(&value_iter, &dict_entry);
218
219                 dbus_message_iter_get_basic(&dict_entry, &key);
220
221                 if (key == NULL) {
222                         dbus_message_iter_next(&value_iter);
223                         continue;
224                 }
225
226                 if (!dbus_message_iter_next(&dict_entry)) {
227                         dbus_message_iter_next(&value_iter);
228                         continue;
229                 }
230                 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
231
232                 if (strcasecmp(key, "Address") == 0) {
233                         const char *address = NULL;
234                         dbus_message_iter_get_basic(&iter_dict_val,
235                                                         &address);
236                         dev_info->address = g_strdup(address);
237                 } else if (strcasecmp(key, "Class") == 0) {
238                         dbus_message_iter_get_basic(&iter_dict_val,
239                                                 &dev_info->class);
240                 } else if (strcasecmp(key, "Name") == 0) {
241                         dbus_message_iter_get_basic(&iter_dict_val,
242                                                         &value);
243                         if (dev_info->name == NULL)
244                                 dev_info->name = g_strdup(value);
245                 } else if (strcasecmp(key, "Connected") == 0) {
246                         dbus_message_iter_get_basic(&iter_dict_val,
247                                                 &dev_info->connected);
248                 } else if (strcasecmp(key, "Paired") == 0) {
249                         dbus_message_iter_get_basic(&iter_dict_val,
250                                                 &dev_info->paired);
251                 } else if (strcasecmp(key, "Trusted") == 0) {
252                         dbus_message_iter_get_basic(&iter_dict_val,
253                                                 &dev_info->trust);
254                 } else if (strcasecmp(key, "RSSI") == 0) {
255                         dbus_message_iter_get_basic(&iter_dict_val,
256                                                 &dev_info->rssi);
257                 } else if (strcasecmp(key, "UUIDs") == 0) {
258                         DBusMessageIter uuid_iter;
259                         DBusMessageIter tmp_iter;
260                         int i = 0;
261
262                         dbus_message_iter_recurse(&iter_dict_val,
263                                                         &uuid_iter);
264                         tmp_iter = uuid_iter;
265
266                         /* Store the uuid count */
267                         while (dbus_message_iter_get_arg_type(&tmp_iter) !=
268                                                         DBUS_TYPE_INVALID) {
269
270                                 dbus_message_iter_get_basic(&tmp_iter,
271                                                                 &value);
272
273                                 dev_info->uuid_count++;
274                                 if (!dbus_message_iter_next(&tmp_iter))
275                                         break;
276                         }
277
278                         /* Store the uuids */
279                         if (dev_info->uuid_count > 0) {
280                                 dev_info->uuids = g_new0(char *,
281                                                 dev_info->uuid_count + 1);
282                         } else {
283                                 dbus_message_iter_next(&value_iter);
284                                 continue;
285                         }
286
287                         while (dbus_message_iter_get_arg_type(&uuid_iter) !=
288                                                         DBUS_TYPE_INVALID) {
289                                 dbus_message_iter_get_basic(&uuid_iter,
290                                                                 &value);
291                                 dev_info->uuids[i] = g_strdup(value);
292                                 i++;
293                                 if (!dbus_message_iter_next(&uuid_iter)) {
294                                         break;
295                                 }
296                         }
297                 }
298
299                 dbus_message_iter_next(&value_iter);
300         }
301
302         return dev_info;
303 }
304
305 static void __bt_extract_remote_devinfo(DBusMessageIter *msg_iter,
306                                                 GArray **dev_list)
307 {
308         bt_remote_dev_info_t *dev_info = NULL;
309         char *object_path = NULL;
310         DBusMessageIter value_iter;
311
312         /* Parse the signature:  oa{sa{sv}}} */
313         ret_if(dbus_message_iter_get_arg_type(msg_iter) !=
314                                         DBUS_TYPE_OBJECT_PATH);
315
316         dbus_message_iter_get_basic(msg_iter, &object_path);
317         ret_if(object_path == NULL);
318
319         /* object array (oa) */
320         ret_if(dbus_message_iter_next(msg_iter) == FALSE);
321         ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY);
322
323         dbus_message_iter_recurse(msg_iter, &value_iter);
324
325         /* string array (sa) */
326         while (dbus_message_iter_get_arg_type(&value_iter) ==
327                                         DBUS_TYPE_DICT_ENTRY) {
328                 char *interface_name = NULL;
329                 DBusMessageIter interface_iter;
330
331                 dbus_message_iter_recurse(&value_iter, &interface_iter);
332
333                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
334                                                         DBUS_TYPE_STRING);
335
336                 dbus_message_iter_get_basic(&interface_iter, &interface_name);
337
338                 ret_if(dbus_message_iter_next(&interface_iter) == FALSE);
339
340                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
341                                                         DBUS_TYPE_ARRAY);
342
343                 if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) {
344                         BT_DBG("Found a device: %s", object_path);
345                         dev_info = __bt_parse_remote_device_info(
346                                                         &interface_iter);
347
348                         if (dev_info) {
349                                 g_array_append_vals(*dev_list, dev_info,
350                                         sizeof(bt_remote_dev_info_t));
351                         }
352                 }
353
354                 dbus_message_iter_next(&value_iter);
355         }
356 }
357
358 int _bt_get_remote_found_devices(GArray **dev_list)
359 {
360         DBusMessage *msg;
361         DBusMessage *reply;
362         DBusMessageIter reply_iter;
363         DBusMessageIter value_iter;
364         DBusError err;
365         DBusConnection *conn;
366
367         conn = _bt_get_system_conn();
368         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
369
370         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
371                                                 BT_MANAGER_INTERFACE,
372                                                 "GetManagedObjects");
373
374         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
375
376         /* Synchronous call */
377         dbus_error_init(&err);
378         reply = dbus_connection_send_with_reply_and_block(
379                                         conn, msg,
380                                         -1, &err);
381         dbus_message_unref(msg);
382
383         if (!reply) {
384                 BT_ERR("Can't get managed objects");
385
386                 if (dbus_error_is_set(&err)) {
387                         BT_ERR("%s", err.message);
388                         dbus_error_free(&err);
389                 }
390                 return BLUETOOTH_ERROR_INTERNAL;
391         }
392
393         if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
394                 BT_ERR("Fail to iterate the reply");
395                 return BLUETOOTH_ERROR_INTERNAL;
396         }
397
398         dbus_message_iter_recurse(&reply_iter, &value_iter);
399
400         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
401         while (dbus_message_iter_get_arg_type(&value_iter) ==
402                                                 DBUS_TYPE_DICT_ENTRY) {
403                 DBusMessageIter msg_iter;
404
405                 dbus_message_iter_recurse(&value_iter, &msg_iter);
406
407                 __bt_extract_remote_devinfo(&msg_iter, dev_list);
408
409                 dbus_message_iter_next(&value_iter);
410         }
411
412         return BLUETOOTH_ERROR_NONE;
413 }
414
415 static int __bt_get_bonded_device_info(gchar *device_path,
416                 bluetooth_device_info_t *dev_info)
417 {
418         GValue *value = { 0 };
419         GError *err = NULL;
420         DBusGProxy *device_proxy;
421         const gchar *address;
422         const gchar *name;
423         unsigned int cod;
424         gint rssi;
425         gboolean trust;
426         gboolean paired;
427         gboolean connected;
428         GHashTable *hash = NULL;
429         int ret;
430         DBusGConnection *conn;
431
432         BT_CHECK_PARAMETER(device_path, return);
433         BT_CHECK_PARAMETER(dev_info, return);
434
435         conn = _bt_get_system_gconn();
436         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
437
438         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
439                                 device_path, BT_PROPERTIES_INTERFACE);
440
441         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
442
443         dbus_g_proxy_call(device_proxy, "GetAll", &err,
444                                 G_TYPE_STRING, BT_DEVICE_INTERFACE,
445                                 G_TYPE_INVALID,
446                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
447                                 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
448
449         g_object_unref(device_proxy);
450
451         if (err != NULL) {
452                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
453                 g_error_free(err);
454                 return BLUETOOTH_ERROR_INTERNAL;
455         }
456
457         if (hash != NULL) {
458                 value = g_hash_table_lookup(hash, "Paired");
459                 paired = g_value_get_boolean(value);
460
461                 value = g_hash_table_lookup(hash, "Address");
462                 address = value ? g_value_get_string(value) : NULL;
463
464                 value = g_hash_table_lookup(hash, "Alias");
465                 name = value ? g_value_get_string(value) : NULL;
466
467                 if (name != NULL)
468                         BT_DBG("Alias Name [%s]", name);
469                 else {
470                         value = g_hash_table_lookup(hash, "Name");
471                         name = value ? g_value_get_string(value) : NULL;
472                 }
473
474                 value = g_hash_table_lookup(hash, "Class");
475                 cod = value ? g_value_get_uint(value) : 0;
476
477                 value = g_hash_table_lookup(hash, "Connected");
478                 connected = value ? g_value_get_boolean(value) : FALSE;
479
480                 value = g_hash_table_lookup(hash, "Trusted");
481                 trust = value ? g_value_get_boolean(value) : FALSE;
482
483                 if ((paired == FALSE) && (trust == FALSE)) {
484                         return BLUETOOTH_ERROR_NOT_PAIRED;
485                 }
486
487                 value = g_hash_table_lookup(hash, "RSSI");
488                 rssi = value ? g_value_get_int(value) : 0;
489
490                 value = g_hash_table_lookup(hash, "UUIDs");
491                 __bt_get_service_list(value, dev_info);
492
493                 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
494                                                 address);
495
496                 _bt_divide_device_class(&dev_info->device_class, cod);
497
498                 g_strlcpy(dev_info->device_name.name, name,
499                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
500
501                 dev_info->rssi = rssi;
502                 dev_info->trust = trust;
503                 dev_info->paired = paired;
504                 dev_info->connected = connected;
505                 g_hash_table_destroy(hash);
506                 ret = BLUETOOTH_ERROR_NONE;
507         } else {
508                 BT_ERR("Hash is NULL\n");
509                 ret = BLUETOOTH_ERROR_INTERNAL;
510         }
511
512         return ret;
513 }
514
515 void _bt_set_discovery_status(gboolean mode)
516 {
517         is_discovering = mode;
518 }
519
520 void _bt_set_cancel_by_user(gboolean value)
521 {
522         cancel_by_user = value;
523 }
524
525 gboolean _bt_get_cancel_by_user(void)
526 {
527         return cancel_by_user;
528 }
529
530 static void __bt_flight_mode_cb(keynode_t *node, void *data)
531 {
532         gboolean flight_mode = FALSE;
533         int bt_status;
534
535         BT_DBG("key=%s\n", vconf_keynode_get_name(node));
536
537         bt_status = _bt_adapter_get_status();
538
539         if (vconf_keynode_get_type(node) == VCONF_TYPE_BOOL) {
540                 flight_mode = vconf_keynode_get_bool(node);
541
542                 BT_DBG("value=%d\n", flight_mode);
543
544                 if (flight_mode == TRUE) {
545                         BT_DBG("Deactivate Bluetooth Service\n");
546                         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 1) != 0)
547                                 BT_DBG("Set vconf failed+\n");
548
549                         if (bt_status == BT_ACTIVATED)
550                                 _bt_disable_adapter();
551                 } else {
552
553                         int value = 0;
554
555                         if (vconf_get_int(BT_OFF_DUE_TO_FLIGHT_MODE, &value))
556                                 BT_ERR("Fail get flight mode value");
557
558                         if (value == 0)
559                                 return;
560
561                         BT_DBG("Activate Bluetooth Service\n");
562                         if (vconf_set_int(BT_OFF_DUE_TO_FLIGHT_MODE, 0))
563                                 BT_DBG("Set vconf failed\n");
564
565                         if (bt_status == BT_DEACTIVATED)
566                                 _bt_enable_adapter();
567                 }
568         }
569 }
570
571 #ifdef __TIZEN_MOBILE__
572 static void __launch_bt_service(int status, int run_type)
573 {
574         bundle *kb;
575         char status_val[5] = { 0, };
576         char run_type_val[5] = { 0, };
577
578         snprintf(status_val, sizeof(status_val), "%d", status);
579         snprintf(run_type_val, sizeof(run_type_val), "%d", run_type);
580
581         BT_DBG("status: %s, run_type: %s", status_val, run_type_val);
582
583         kb = bundle_create();
584
585         bundle_add(kb, "launch-type", "setstate");
586         bundle_add(kb, "status", status_val);
587         bundle_add(kb, "run-type", run_type_val);
588
589         aul_launch_app("com.samsung.bluetooth", kb);
590
591         bundle_free(kb);
592 }
593 #endif
594
595 void _bt_adapter_set_status(bt_status_t status)
596 {
597         adapter_status = status;
598 }
599
600 bt_status_t _bt_adapter_get_status(void)
601 {
602         return adapter_status;
603 }
604
605 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
606 {
607         char *phone_name = NULL;
608         char *ptr = NULL;
609
610         if (node == NULL)
611                 return;
612
613         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
614                 phone_name = vconf_keynode_get_str(node);
615                 if (phone_name && strlen(phone_name) != 0) {
616                         if (!g_utf8_validate(phone_name, -1,
617                                                         (const char **)&ptr))
618                                 *ptr = '\0';
619
620                         _bt_set_local_name(phone_name);
621                 }
622         }
623 }
624
625 static void __bt_set_visible_mode(void)
626 {
627         int timeout;
628
629         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
630                 BT_ERR("Fail to get the timeout value");
631
632         /* -1: Always on */
633         if (timeout == -1) {
634                 if (_bt_set_discoverable_mode(
635                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
636                         timeout) != BLUETOOTH_ERROR_NONE) {
637                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
638                                 BT_ERR("Set vconf failed");
639                 }
640         }
641 }
642
643 static void __bt_set_local_name(void)
644 {
645         char *phone_name = NULL;
646         char *ptr = NULL;
647
648         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
649
650         if (!phone_name)
651                 return;
652
653         if (strlen(phone_name) != 0) {
654                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
655                         *ptr = '\0';
656                 _bt_set_local_name(phone_name);
657         }
658         free(phone_name);
659 }
660
661 void _bt_set_enabled(void)
662 {
663         int result = BLUETOOTH_ERROR_NONE;
664
665         _bt_adapter_set_status(BT_ACTIVATED);
666
667         // register agent if it was not previously done.
668         if (!adapter_agent) {
669                 BT_DBG("");
670                 _bt_handle_adapter_added();
671         }
672
673         __bt_set_visible_mode();
674
675         __bt_set_local_name();
676
677         /* Update Bluetooth Status to notify other modules */
678         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
679                 BT_ERR("Set vconf failed\n");
680
681         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
682                 BT_ERR("Set vconf failed\n");
683
684         /* Send enabled event to API */
685         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
686                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
687 }
688
689 void _bt_set_disabled(void)
690 {
691         int result = BLUETOOTH_ERROR_NONE;
692
693         _bt_adapter_set_status(BT_DEACTIVATED);
694
695         /* Update Bluetooth Status to notify other modules */
696         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
697                 BT_ERR("Set vconf failed\n");
698
699         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
700                 BT_ERR("Set vconf failed\n");
701
702         /* Send disabled event */
703         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
704                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
705 }
706
707 void *_bt_get_adapter_agent(void)
708 {
709         return adapter_agent;
710 }
711
712 void _bt_handle_flight_mode_noti(void)
713 {
714         BT_DBG("+");
715         vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
716                         __bt_flight_mode_cb, NULL);
717         BT_DBG("-");
718 }
719
720 void _bt_handle_adapter_added(void)
721 {
722         BT_DBG("");
723
724         adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
725         if (!adapter_agent) {
726                 BT_ERR("Fail to register agent");
727                 return;
728         }
729
730 #ifdef __TIZEN_MOBILE__
731         if (!aul_app_is_running("com.samsung.bluetooth"))
732                         __launch_bt_service(0, 0);
733
734         if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
735                 BT_ERR("Fail to register media player");
736 #endif
737
738         if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
739                 BT_ERR("Fail to init obex server");
740 /*
741         if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
742                 BT_ERR("Fail to activate network");
743 */
744
745         /* add the vconf noti handler */
746         vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
747                                         __bt_phone_name_changed_cb, NULL);
748
749         vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
750                         __bt_flight_mode_cb, NULL);
751 }
752
753 void _bt_handle_adapter_removed(void)
754 {
755         BT_DBG("");
756
757         vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
758                                 (vconf_callback_fn)__bt_phone_name_changed_cb);
759
760         _bt_destroy_agent(adapter_agent);
761         adapter_agent = NULL;
762
763         _bt_terminate_service(NULL);
764 }
765
766 DBusGProxy *_bt_init_core_proxy(void)
767 {
768         DBusGProxy *proxy;
769         DBusGConnection *conn;
770
771         conn = _bt_get_system_gconn();
772         if (!conn)
773                 return NULL;
774
775         proxy = dbus_g_proxy_new_for_name(conn, BT_CORE_NAME,
776                        BT_CORE_PATH, BT_CORE_INTERFACE);
777         if (!proxy)
778                 return NULL;
779
780         core_proxy = proxy;
781
782         return proxy;
783 }
784
785 static DBusGProxy *__bt_get_core_proxy(void)
786 {
787         return (core_proxy) ? core_proxy : _bt_init_core_proxy();
788 }
789
790 int _bt_enable_adapter(void)
791 {
792         DBusGProxy *proxy;
793         GError *err = NULL;
794
795         BT_DBG("");
796
797         if (_bt_adapter_get_status() == BT_ACTIVATING) {
798                         BT_DBG("Enabling in progress");
799                         return BLUETOOTH_ERROR_IN_PROGRESS;
800         }
801
802         if (_bt_adapter_get_status() == BT_ACTIVATED) {
803                         BT_DBG("Already enabled");
804                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
805         }
806
807         _bt_adapter_set_status(BT_ACTIVATING);
808
809         proxy = __bt_get_core_proxy();
810         if (!proxy)
811                 return BLUETOOTH_ERROR_INTERNAL;
812
813          if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapter",
814                                         BT_ENABLE_TIMEOUT, &err,
815                                         G_TYPE_INVALID,
816                                         G_TYPE_INVALID) == FALSE) {
817
818                 _bt_adapter_set_status(BT_DEACTIVATED);
819
820                 if (err != NULL) {
821                         BT_ERR("Bt core call failed: [%s]", err->message);
822                         g_error_free(err);
823                 }
824
825                 /* Clean up the process */
826                 if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
827                                 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
828                                 BT_ERR("Bt core call failed");
829                 }
830
831                 /* Display notification */
832                 notification_status_message_post(BT_STR_NOT_SUPPORT);
833
834                 /* Terminate myself */
835                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
836                 return BLUETOOTH_ERROR_INTERNAL;
837         }
838
839         return BLUETOOTH_ERROR_NONE;
840 }
841
842 int _bt_disable_adapter(void)
843 {
844         DBusGProxy *proxy;
845
846         BT_DBG("");
847
848         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
849                         BT_DBG("Disabling in progress");
850                         return BLUETOOTH_ERROR_IN_PROGRESS;
851         }
852
853         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
854                         BT_DBG("Already disabled");
855                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
856         }
857
858         _bt_adapter_set_status(BT_DEACTIVATING);
859
860         proxy = __bt_get_core_proxy();
861         if (!proxy)
862                 return BLUETOOTH_ERROR_INTERNAL;
863
864         if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
865                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
866                 BT_ERR("Bt core call failed");
867                 _bt_adapter_set_status(BT_ACTIVATED);
868                 return BLUETOOTH_ERROR_INTERNAL;
869         }
870
871         return BLUETOOTH_ERROR_NONE;
872 }
873
874 int _bt_reset_adapter(void)
875 {
876         DBusGProxy *proxy;
877
878         BT_DBG("");
879
880         proxy = __bt_get_core_proxy();
881         if (!proxy)
882                 return BLUETOOTH_ERROR_INTERNAL;
883
884         if (dbus_g_proxy_call(proxy, "ResetAdapter", NULL,
885                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
886                 BT_ERR("Bt core call failed");
887                 return BLUETOOTH_ERROR_INTERNAL;
888         }
889
890         /* Terminate myself */
891         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
892                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
893         }
894
895         return BLUETOOTH_ERROR_NONE;
896 }
897
898 int _bt_check_adapter(int *status)
899 {
900         BT_CHECK_PARAMETER(status, return);
901
902         *status = 0; /* 0: disabled */
903
904         if (_bt_get_adapter_power())
905                 *status = 1; /* 1: enabled */
906
907         return BLUETOOTH_ERROR_NONE;
908 }
909
910 int _bt_get_local_address(bluetooth_device_address_t *local_address)
911 {
912         DBusGProxy *proxy;
913         GError *err = NULL;
914         char *address;
915         GValue address_v = { 0 };
916
917         BT_CHECK_PARAMETER(local_address, return);
918
919         proxy = _bt_get_adapter_properties_proxy();
920         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
921
922         if (!dbus_g_proxy_call(proxy, "Get", &err,
923                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
924                         G_TYPE_STRING, "Address",
925                         G_TYPE_INVALID,
926                         G_TYPE_VALUE, &address_v,
927                         G_TYPE_INVALID)) {
928                 if (err != NULL) {
929                         BT_ERR("Getting property failed: [%s]\n", err->message);
930                         g_error_free(err);
931                 }
932                 return BLUETOOTH_ERROR_INTERNAL;
933         }
934
935         address = (char *)g_value_get_string(&address_v);
936
937         if (address) {
938                 _bt_convert_addr_string_to_type(local_address->addr, address);
939         } else {
940                 return BLUETOOTH_ERROR_INTERNAL;
941         }
942
943         return BLUETOOTH_ERROR_NONE;
944 }
945
946 int _bt_get_local_name(bluetooth_device_name_t *local_name)
947 {
948         DBusGProxy *proxy;
949         GError *err = NULL;
950         GValue name_v = { 0 };
951         char *name = NULL;
952         char *ptr = NULL;
953         int ret = BLUETOOTH_ERROR_NONE;
954
955         BT_CHECK_PARAMETER(local_name, return);
956
957         proxy = _bt_get_adapter_properties_proxy();
958         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
959
960         if (!dbus_g_proxy_call(proxy, "Get", &err,
961                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
962                         G_TYPE_STRING, "Alias",
963                         G_TYPE_INVALID,
964                         G_TYPE_VALUE, &name_v,
965                         G_TYPE_INVALID)) {
966                 if (err != NULL) {
967                         BT_ERR("Getting property failed: [%s]\n", err->message);
968                         g_error_free(err);
969                 }
970                 return BLUETOOTH_ERROR_INTERNAL;
971         }
972
973         name = (char *)g_value_get_string(&name_v);
974
975         if (name && (strlen(name) > 0)) {
976                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
977                 if (!g_utf8_validate(name, -1, (const char **)&ptr))
978                         *ptr = '\0';
979
980                 g_strlcpy(local_name->name, name,
981                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
982         } else {
983                 ret = BLUETOOTH_ERROR_INTERNAL;
984         }
985
986         return ret;
987 }
988
989 int _bt_set_local_name(char *local_name)
990 {
991         GValue name = { 0 };
992         DBusGProxy *proxy;
993         GError *error = NULL;
994         char *ptr = NULL;
995
996         BT_CHECK_PARAMETER(local_name, return);
997
998         proxy = _bt_get_adapter_properties_proxy();
999         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1000
1001         if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1002                 *ptr = '\0';
1003
1004         g_value_init(&name, G_TYPE_STRING);
1005         g_value_set_string(&name, local_name);
1006
1007         dbus_g_proxy_call(proxy, "Set", &error,
1008                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1009                         G_TYPE_STRING, "Alias",
1010                         G_TYPE_VALUE, &name,
1011                         G_TYPE_INVALID, G_TYPE_INVALID);
1012
1013         g_value_unset(&name);
1014
1015         if (error) {
1016                 BT_ERR("SetProperty Fail: %s", error->message);
1017                 g_error_free(error);
1018                 return BLUETOOTH_ERROR_INTERNAL;
1019         }
1020
1021         return BLUETOOTH_ERROR_NONE;
1022 }
1023
1024 int _bt_is_service_used(char *service_uuid, gboolean *used)
1025 {
1026         char **uuids;
1027         int i;
1028         DBusGProxy *proxy;
1029         GHashTable *hash = NULL;
1030         GValue *value;
1031         int ret = BLUETOOTH_ERROR_NONE;
1032
1033         BT_CHECK_PARAMETER(service_uuid, return);
1034         BT_CHECK_PARAMETER(used, return);
1035
1036         proxy = _bt_get_adapter_proxy();
1037         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1038
1039         dbus_g_proxy_call(proxy, "GetProperties", NULL,
1040                           G_TYPE_INVALID,
1041                           dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
1042                           G_TYPE_VALUE), &hash, G_TYPE_INVALID);
1043
1044         retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
1045
1046         value = g_hash_table_lookup(hash, "UUIDs");
1047         uuids = g_value_get_boxed(value);
1048
1049         if (uuids == NULL) {
1050                 /* Normal case */
1051                 *used = FALSE;
1052                 goto done;
1053         }
1054
1055         for (i = 0; uuids[i] != NULL; i++) {
1056                 if (strcasecmp(uuids[i], service_uuid) == 0) {
1057                         *used = TRUE;
1058                         goto done;
1059                 }
1060         }
1061
1062         *used = FALSE;
1063 done:
1064         g_hash_table_destroy(hash);
1065         return ret;
1066 }
1067
1068 static gboolean __bt_get_discoverable_property(void)
1069 {
1070         DBusGProxy *proxy;
1071         GValue discoverable_v = { 0 };
1072         GError *err = NULL;
1073
1074         proxy = _bt_get_adapter_properties_proxy();
1075         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1076
1077         if (!dbus_g_proxy_call(proxy, "Get", &err,
1078                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1079                         G_TYPE_STRING, "Discoverable",
1080                         G_TYPE_INVALID,
1081                         G_TYPE_VALUE, &discoverable_v,
1082                         G_TYPE_INVALID)) {
1083                 if (err != NULL) {
1084                         BT_ERR("Getting property failed: [%s]\n", err->message);
1085                         g_error_free(err);
1086                 }
1087                 return BLUETOOTH_ERROR_INTERNAL;
1088         }
1089
1090         return g_value_get_boolean(&discoverable_v);
1091 }
1092
1093 int _bt_get_discoverable_mode(int *mode)
1094 {
1095         gboolean discoverable;
1096         unsigned int timeout;
1097
1098         BT_CHECK_PARAMETER(mode, return);
1099
1100         discoverable = __bt_get_discoverable_property();
1101         timeout = _bt_get_discoverable_timeout_property();
1102
1103         if (discoverable == TRUE) {
1104                 if (timeout == 0)
1105                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1106                 else
1107                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1108         } else {
1109                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1110         }
1111         return BLUETOOTH_ERROR_NONE;
1112 }
1113
1114 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1115 {
1116         int ret = BLUETOOTH_ERROR_NONE;
1117         gboolean inq_scan;
1118         gboolean pg_scan;
1119         GError *error = NULL;
1120         GValue connectable = { 0 };
1121         GValue discoverable = { 0 };
1122         GValue val_timeout = { 0 };
1123         DBusGProxy *proxy;
1124
1125         proxy = _bt_get_adapter_properties_proxy();
1126         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1127
1128         g_value_init(&connectable, G_TYPE_BOOLEAN);
1129         g_value_init(&discoverable, G_TYPE_BOOLEAN);
1130         g_value_init(&val_timeout, G_TYPE_UINT);
1131
1132         switch (discoverable_mode) {
1133         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1134                 pg_scan = TRUE;
1135                 inq_scan = FALSE;
1136                 timeout = 0;
1137                 break;
1138         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1139                 pg_scan = TRUE;
1140                 inq_scan = TRUE;
1141                 timeout = 0;
1142                 break;
1143         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1144                 inq_scan = TRUE;
1145                 pg_scan = TRUE;
1146                 break;
1147         default:
1148                 return BLUETOOTH_ERROR_INVALID_PARAM;
1149         }
1150
1151         g_value_set_boolean(&connectable, pg_scan);
1152         g_value_set_boolean(&discoverable, inq_scan);
1153         g_value_set_uint(&val_timeout, timeout);
1154
1155         dbus_g_proxy_call(proxy, "Set", &error,
1156                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1157                                 G_TYPE_STRING, "Powered",
1158                                 G_TYPE_VALUE, &connectable,
1159                                 G_TYPE_INVALID, G_TYPE_INVALID);
1160
1161         if (error != NULL) {
1162                 BT_ERR("Powered set err:[%s]", error->message);
1163                 g_error_free(error);
1164                 ret = BLUETOOTH_ERROR_INTERNAL;
1165                 goto done;
1166         }
1167
1168         dbus_g_proxy_call(proxy, "Set", &error,
1169                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1170                                 G_TYPE_STRING, "Discoverable",
1171                                 G_TYPE_VALUE, &discoverable,
1172                                 G_TYPE_INVALID, G_TYPE_INVALID);
1173
1174         if (error != NULL) {
1175                 BT_ERR("Discoverable set err:[%s]", error->message);
1176                 g_error_free(error);
1177                 ret = BLUETOOTH_ERROR_INTERNAL;
1178                 goto done;
1179         }
1180
1181         dbus_g_proxy_call(proxy, "Set", &error,
1182                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1183                                 G_TYPE_STRING, "DiscoverableTimeout",
1184                                 G_TYPE_VALUE, &val_timeout,
1185                                 G_TYPE_INVALID, G_TYPE_INVALID);
1186
1187         if (error != NULL) {
1188                 BT_ERR("Timeout set err:[%s]", error->message);
1189                 g_error_free(error);
1190                 ret = BLUETOOTH_ERROR_INTERNAL;
1191                 goto done;
1192         }
1193
1194         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1195                 timeout = -1;
1196
1197         __bt_set_visible_time(timeout);
1198
1199 done:
1200         g_value_unset(&val_timeout);
1201         g_value_unset(&connectable);
1202         g_value_unset(&discoverable);
1203
1204         return ret;
1205 }
1206
1207 int _bt_start_discovery(void)
1208 {
1209         DBusGProxy *proxy;
1210
1211         if (_bt_is_discovering() == TRUE) {
1212                 BT_ERR("BT is already in discovering");
1213                 return BLUETOOTH_ERROR_IN_PROGRESS;
1214         }
1215
1216         proxy = _bt_get_adapter_proxy();
1217         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1218
1219         if (!dbus_g_proxy_call(proxy, "StartDiscovery", NULL,
1220                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1221                 BT_ERR("Discover start failed");
1222                 return BLUETOOTH_ERROR_INTERNAL;
1223         }
1224
1225         _bt_stop_discovery_timeout();
1226
1227         is_discovering = TRUE;
1228         cancel_by_user = FALSE;
1229         /* discovery status will be change in event */
1230
1231         return BLUETOOTH_ERROR_NONE;
1232 }
1233
1234 int _bt_cancel_discovery(void)
1235 {
1236         DBusGProxy *proxy;
1237
1238         if (_bt_is_discovering() == FALSE) {
1239                 BT_ERR("BT is not in discovering");
1240                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1241         }
1242
1243         proxy = _bt_get_adapter_proxy();
1244         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1245
1246         if (!dbus_g_proxy_call(proxy, "StopDiscovery", NULL,
1247                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1248                 BT_ERR("Discover stop failed");
1249                 return BLUETOOTH_ERROR_INTERNAL;
1250         }
1251
1252         cancel_by_user = TRUE;
1253         /* discovery status will be change in event */
1254
1255         return BLUETOOTH_ERROR_NONE;
1256 }
1257
1258 gboolean _bt_is_discovering(void)
1259 {
1260         return is_discovering;
1261 }
1262
1263 gboolean _bt_get_discovering_property(void)
1264 {
1265         DBusGProxy *proxy;
1266         GValue discovering_v = { 0 };
1267         GError *err = NULL;
1268
1269         proxy = _bt_get_adapter_properties_proxy();
1270         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1271
1272         if (!dbus_g_proxy_call(proxy, "Get", &err,
1273                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1274                         G_TYPE_STRING, "Discovering",
1275                         G_TYPE_INVALID,
1276                         G_TYPE_VALUE, &discovering_v,
1277                         G_TYPE_INVALID)) {
1278                 if (err != NULL) {
1279                         BT_ERR("Getting property failed: [%s]\n", err->message);
1280                         g_error_free(err);
1281                 }
1282                 return BLUETOOTH_ERROR_INTERNAL;
1283         }
1284
1285         return g_value_get_boolean(&discovering_v);
1286 }
1287
1288 unsigned int _bt_get_discoverable_timeout_property(void)
1289 {
1290         DBusGProxy *proxy;
1291         GValue timeout_v = { 0 };
1292         GError *err = NULL;
1293
1294         proxy = _bt_get_adapter_properties_proxy();
1295         retv_if(proxy == NULL, 0);
1296
1297         if (!dbus_g_proxy_call(proxy, "Get", &err,
1298                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1299                         G_TYPE_STRING, "DiscoverableTimeout",
1300                         G_TYPE_INVALID,
1301                         G_TYPE_VALUE, &timeout_v,
1302                         G_TYPE_INVALID)) {
1303                 if (err != NULL) {
1304                         BT_ERR("Getting property failed: [%s]\n", err->message);
1305                         g_error_free(err);
1306                 }
1307                 return 0;
1308         }
1309
1310         return g_value_get_uint(&timeout_v);
1311 }
1312
1313 static bluetooth_device_info_t *__bt_parse_device_info(DBusMessageIter *item_iter)
1314 {
1315         DBusMessageIter value_iter;
1316         bluetooth_device_info_t *dev_info;
1317
1318         dbus_message_iter_recurse(item_iter, &value_iter);
1319
1320         if (dbus_message_iter_get_arg_type(&value_iter) != DBUS_TYPE_DICT_ENTRY) {
1321                 BT_DBG("No entry");
1322                 return NULL;
1323         }
1324
1325         dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
1326
1327         while (dbus_message_iter_get_arg_type(&value_iter) ==
1328                                                 DBUS_TYPE_DICT_ENTRY) {
1329                 char *value = NULL;
1330                 char *key;
1331                 DBusMessageIter dict_entry;
1332                 DBusMessageIter iter_dict_val;
1333
1334                 dbus_message_iter_recurse(&value_iter, &dict_entry);
1335
1336                 dbus_message_iter_get_basic(&dict_entry, &key);
1337
1338                 if (key == NULL) {
1339                         dbus_message_iter_next(&value_iter);
1340                         continue;
1341                 }
1342
1343                 if (!dbus_message_iter_next(&dict_entry)) {
1344                         dbus_message_iter_next(&value_iter);
1345                         continue;
1346                 }
1347                 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
1348
1349                 if (strcasecmp(key, "Address") == 0) {
1350                         const char *address = NULL;
1351                         dbus_message_iter_get_basic(&iter_dict_val, &address);
1352                         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
1353                                                         address);
1354
1355                 } else if (strcasecmp(key, "Class") == 0) {
1356                         unsigned int cod;
1357                         dbus_message_iter_get_basic(&iter_dict_val, &cod);
1358                         _bt_divide_device_class(&dev_info->device_class, cod);
1359                 } else if (strcasecmp(key, "Name") == 0) {
1360                         dbus_message_iter_get_basic(&iter_dict_val, &value);
1361
1362                         /* If there is no Alias */
1363                         if (strlen(dev_info->device_name.name) == 0) {
1364                                 g_strlcpy(dev_info->device_name.name, value,
1365                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1366                         }
1367                 } else if (strcasecmp(key, "Alias") == 0) {
1368                         dbus_message_iter_get_basic(&iter_dict_val, &value);
1369
1370                         /* Overwrite the name */
1371                         if (value) {
1372                                 memset(dev_info->device_name.name, 0x00,
1373                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1374                                 g_strlcpy(dev_info->device_name.name, value,
1375                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1376                         }
1377                 } else if (strcasecmp(key, "Connected") == 0) {
1378                         dbus_message_iter_get_basic(&iter_dict_val,
1379                                                 &dev_info->connected);
1380                 } else if (strcasecmp(key, "Paired") == 0) {
1381                         dbus_message_iter_get_basic(&iter_dict_val,
1382                                                 &dev_info->paired);
1383                 } else if (strcasecmp(key, "Trusted") == 0) {
1384                         dbus_message_iter_get_basic(&iter_dict_val,
1385                                                 &dev_info->trust);
1386                 } else if (strcasecmp(key, "RSSI") == 0) {
1387                         dbus_message_iter_get_basic(&iter_dict_val,
1388                                                 &dev_info->rssi);
1389                 } else if (strcasecmp(key, "UUIDs") == 0) {
1390                         DBusMessageIter uuid_iter;
1391                         char **parts;
1392                         int i = 0;
1393
1394                         dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
1395
1396                         while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
1397                                 dbus_message_iter_get_basic(&uuid_iter,
1398                                                         &value);
1399
1400                                 g_strlcpy(dev_info->uuids[i], value,
1401                                                 BLUETOOTH_UUID_STRING_MAX);
1402
1403                                 parts = g_strsplit(value, "-", -1);
1404
1405                                 if (parts == NULL || parts[0] == NULL)
1406                                         break;
1407
1408                                 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
1409                                 g_strfreev(parts);
1410
1411                                 i++;
1412                                 if (!dbus_message_iter_next(&uuid_iter)) {
1413                                         break;
1414                                 }
1415                         }
1416
1417                         dev_info->service_index = i;
1418                 }
1419
1420                 dbus_message_iter_next(&value_iter);
1421         }
1422
1423         return dev_info;
1424 }
1425
1426 static void __bt_extract_device_info(DBusMessageIter *msg_iter,
1427                                                         GArray **dev_list)
1428 {
1429         bluetooth_device_info_t *dev_info = NULL;
1430         char *object_path = NULL;
1431         DBusMessageIter value_iter;
1432
1433         /* Parse the signature:  oa{sa{sv}}} */
1434         ret_if(dbus_message_iter_get_arg_type(msg_iter) !=
1435                                 DBUS_TYPE_OBJECT_PATH);
1436
1437         dbus_message_iter_get_basic(msg_iter, &object_path);
1438         ret_if(object_path == NULL);
1439
1440         /* object array (oa) */
1441         ret_if(dbus_message_iter_next(msg_iter) == FALSE);
1442         ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY);
1443
1444         dbus_message_iter_recurse(msg_iter, &value_iter);
1445
1446         /* string array (sa) */
1447         while (dbus_message_iter_get_arg_type(&value_iter) ==
1448                                         DBUS_TYPE_DICT_ENTRY) {
1449                 char *interface_name = NULL;
1450                 DBusMessageIter interface_iter;
1451
1452                 dbus_message_iter_recurse(&value_iter, &interface_iter);
1453
1454                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
1455                                                         DBUS_TYPE_STRING);
1456
1457                 dbus_message_iter_get_basic(&interface_iter, &interface_name);
1458
1459                 ret_if(dbus_message_iter_next(&interface_iter) == FALSE);
1460
1461                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
1462                                                         DBUS_TYPE_ARRAY);
1463
1464                 if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) {
1465                         BT_DBG("Found a device: %s", object_path);
1466                         dev_info = __bt_parse_device_info(&interface_iter);
1467
1468                         if (dev_info) {
1469                                 if (dev_info->paired == TRUE) {
1470                                         g_array_append_vals(*dev_list, dev_info,
1471                                                         sizeof(bluetooth_device_info_t));
1472                                 } else {
1473                                         g_free(dev_info);
1474                                 }
1475                         }
1476
1477                         return;
1478                 }
1479
1480                 dbus_message_iter_next(&value_iter);
1481         }
1482
1483         BT_DBG("There is no device interface");
1484 }
1485
1486 int _bt_get_bonded_devices(GArray **dev_list)
1487 {
1488         DBusMessage *msg;
1489         DBusMessage *reply;
1490         DBusMessageIter reply_iter;
1491         DBusMessageIter value_iter;
1492         DBusError err;
1493         DBusConnection *conn;
1494
1495         conn = _bt_get_system_conn();
1496         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1497
1498         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
1499                                                 BT_MANAGER_INTERFACE,
1500                                                 "GetManagedObjects");
1501
1502         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
1503
1504         /* Synchronous call */
1505         dbus_error_init(&err);
1506         reply = dbus_connection_send_with_reply_and_block(
1507                                         conn, msg,
1508                                         -1, &err);
1509         dbus_message_unref(msg);
1510
1511         if (!reply) {
1512                 BT_ERR("Can't get managed objects");
1513
1514                 if (dbus_error_is_set(&err)) {
1515                         BT_ERR("%s", err.message);
1516                         dbus_error_free(&err);
1517                 }
1518                 return BLUETOOTH_ERROR_INTERNAL;
1519         }
1520
1521         if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
1522             BT_ERR("Fail to iterate the reply");
1523             return BLUETOOTH_ERROR_INTERNAL;
1524         }
1525
1526         dbus_message_iter_recurse(&reply_iter, &value_iter);
1527
1528         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
1529         while (dbus_message_iter_get_arg_type(&value_iter) ==
1530                                                 DBUS_TYPE_DICT_ENTRY) {
1531                 DBusMessageIter msg_iter;
1532
1533                 dbus_message_iter_recurse(&value_iter, &msg_iter);
1534
1535                 __bt_extract_device_info(&msg_iter, dev_list);
1536
1537                 dbus_message_iter_next(&value_iter);
1538         }
1539
1540         return BLUETOOTH_ERROR_NONE;
1541 }
1542
1543 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
1544                                 bluetooth_device_info_t *dev_info)
1545 {
1546         char *object_path = NULL;
1547         DBusGProxy *adapter_proxy;
1548         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1549
1550         BT_CHECK_PARAMETER(device_address, return);
1551         BT_CHECK_PARAMETER(dev_info, return);
1552
1553         adapter_proxy = _bt_get_adapter_proxy();
1554         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1555
1556         _bt_convert_addr_type_to_string(address, device_address->addr);
1557
1558         object_path = _bt_get_device_object_path(address);
1559
1560         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_FOUND);
1561
1562         if (__bt_get_bonded_device_info(object_path,
1563                                 dev_info) != BLUETOOTH_ERROR_NONE) {
1564                 BT_ERR("Can't get the paired device path \n");
1565                 g_free(object_path);
1566                 return BLUETOOTH_ERROR_INTERNAL;
1567         }
1568         g_free(object_path);
1569         return BLUETOOTH_ERROR_NONE;
1570 }
1571
1572 int _bt_get_timeout_value(int *timeout)
1573 {
1574         time_t current_time;
1575         int time_diff;
1576
1577         /* Take current time */
1578         time(&current_time);
1579         time_diff = difftime(current_time, visible_timer.start_time);
1580
1581         BT_DBG("Time diff = %d\n", time_diff);
1582
1583         *timeout = visible_timer.timeout - time_diff;
1584
1585         return BLUETOOTH_ERROR_NONE;
1586 }
1587