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