check bt adapter state from bt-service daemon
[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         BT_CHECK_PARAMETER(status, return);
897
898         *status = 0; /* 0: disabled */
899
900         if (_bt_get_adapter_power())
901                 *status = 1; /* 1: enabled */
902
903         return BLUETOOTH_ERROR_NONE;
904 }
905
906 int _bt_get_local_address(bluetooth_device_address_t *local_address)
907 {
908         DBusGProxy *proxy;
909         GError *err = NULL;
910         char *address;
911         GValue address_v = { 0 };
912
913         BT_CHECK_PARAMETER(local_address, return);
914
915         proxy = _bt_get_adapter_properties_proxy();
916         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
917
918         if (!dbus_g_proxy_call(proxy, "Get", &err,
919                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
920                         G_TYPE_STRING, "Address",
921                         G_TYPE_INVALID,
922                         G_TYPE_VALUE, &address_v,
923                         G_TYPE_INVALID)) {
924                 if (err != NULL) {
925                         BT_ERR("Getting property failed: [%s]\n", err->message);
926                         g_error_free(err);
927                 }
928                 return BLUETOOTH_ERROR_INTERNAL;
929         }
930
931         address = (char *)g_value_get_string(&address_v);
932
933         if (address) {
934                 _bt_convert_addr_string_to_type(local_address->addr, address);
935         } else {
936                 return BLUETOOTH_ERROR_INTERNAL;
937         }
938
939         return BLUETOOTH_ERROR_NONE;
940 }
941
942 int _bt_get_local_name(bluetooth_device_name_t *local_name)
943 {
944         DBusGProxy *proxy;
945         GError *err = NULL;
946         GValue name_v = { 0 };
947         char *name = NULL;
948         char *ptr = NULL;
949         int ret = BLUETOOTH_ERROR_NONE;
950
951         BT_CHECK_PARAMETER(local_name, return);
952
953         proxy = _bt_get_adapter_properties_proxy();
954         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
955
956         if (!dbus_g_proxy_call(proxy, "Get", &err,
957                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
958                         G_TYPE_STRING, "Alias",
959                         G_TYPE_INVALID,
960                         G_TYPE_VALUE, &name_v,
961                         G_TYPE_INVALID)) {
962                 if (err != NULL) {
963                         BT_ERR("Getting property failed: [%s]\n", err->message);
964                         g_error_free(err);
965                 }
966                 return BLUETOOTH_ERROR_INTERNAL;
967         }
968
969         name = (char *)g_value_get_string(&name_v);
970
971         if (name && (strlen(name) > 0)) {
972                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
973                 if (!g_utf8_validate(name, -1, (const char **)&ptr))
974                         *ptr = '\0';
975
976                 g_strlcpy(local_name->name, name,
977                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
978         } else {
979                 ret = BLUETOOTH_ERROR_INTERNAL;
980         }
981
982         return ret;
983 }
984
985 int _bt_set_local_name(char *local_name)
986 {
987         GValue name = { 0 };
988         DBusGProxy *proxy;
989         GError *error = NULL;
990         char *ptr = NULL;
991
992         BT_CHECK_PARAMETER(local_name, return);
993
994         proxy = _bt_get_adapter_properties_proxy();
995         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
996
997         if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
998                 *ptr = '\0';
999
1000         g_value_init(&name, G_TYPE_STRING);
1001         g_value_set_string(&name, local_name);
1002
1003         dbus_g_proxy_call(proxy, "Set", &error,
1004                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1005                         G_TYPE_STRING, "Alias",
1006                         G_TYPE_VALUE, &name,
1007                         G_TYPE_INVALID, G_TYPE_INVALID);
1008
1009         g_value_unset(&name);
1010
1011         if (error) {
1012                 BT_ERR("SetProperty Fail: %s", error->message);
1013                 g_error_free(error);
1014                 return BLUETOOTH_ERROR_INTERNAL;
1015         }
1016
1017         return BLUETOOTH_ERROR_NONE;
1018 }
1019
1020 int _bt_is_service_used(char *service_uuid, gboolean *used)
1021 {
1022         char **uuids;
1023         int i;
1024         DBusGProxy *proxy;
1025         GHashTable *hash = NULL;
1026         GValue *value;
1027         int ret = BLUETOOTH_ERROR_NONE;
1028
1029         BT_CHECK_PARAMETER(service_uuid, return);
1030         BT_CHECK_PARAMETER(used, return);
1031
1032         proxy = _bt_get_adapter_proxy();
1033         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1034
1035         dbus_g_proxy_call(proxy, "GetProperties", NULL,
1036                           G_TYPE_INVALID,
1037                           dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
1038                           G_TYPE_VALUE), &hash, G_TYPE_INVALID);
1039
1040         retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
1041
1042         value = g_hash_table_lookup(hash, "UUIDs");
1043         uuids = g_value_get_boxed(value);
1044
1045         if (uuids == NULL) {
1046                 /* Normal case */
1047                 *used = FALSE;
1048                 goto done;
1049         }
1050
1051         for (i = 0; uuids[i] != NULL; i++) {
1052                 if (strcasecmp(uuids[i], service_uuid) == 0) {
1053                         *used = TRUE;
1054                         goto done;
1055                 }
1056         }
1057
1058         *used = FALSE;
1059 done:
1060         g_hash_table_destroy(hash);
1061         return ret;
1062 }
1063
1064 static gboolean __bt_get_discoverable_property(void)
1065 {
1066         DBusGProxy *proxy;
1067         GValue discoverable_v = { 0 };
1068         GError *err = NULL;
1069
1070         proxy = _bt_get_adapter_properties_proxy();
1071         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1072
1073         if (!dbus_g_proxy_call(proxy, "Get", &err,
1074                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1075                         G_TYPE_STRING, "Discoverable",
1076                         G_TYPE_INVALID,
1077                         G_TYPE_VALUE, &discoverable_v,
1078                         G_TYPE_INVALID)) {
1079                 if (err != NULL) {
1080                         BT_ERR("Getting property failed: [%s]\n", err->message);
1081                         g_error_free(err);
1082                 }
1083                 return BLUETOOTH_ERROR_INTERNAL;
1084         }
1085
1086         return g_value_get_boolean(&discoverable_v);
1087 }
1088
1089 int _bt_get_discoverable_mode(int *mode)
1090 {
1091         gboolean discoverable;
1092         unsigned int timeout;
1093
1094         BT_CHECK_PARAMETER(mode, return);
1095
1096         discoverable = __bt_get_discoverable_property();
1097         timeout = _bt_get_discoverable_timeout_property();
1098
1099         if (discoverable == TRUE) {
1100                 if (timeout == 0)
1101                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1102                 else
1103                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1104         } else {
1105                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1106         }
1107         return BLUETOOTH_ERROR_NONE;
1108 }
1109
1110 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1111 {
1112         int ret = BLUETOOTH_ERROR_NONE;
1113         gboolean inq_scan;
1114         gboolean pg_scan;
1115         GError *error = NULL;
1116         GValue connectable = { 0 };
1117         GValue discoverable = { 0 };
1118         GValue val_timeout = { 0 };
1119         DBusGProxy *proxy;
1120
1121         proxy = _bt_get_adapter_properties_proxy();
1122         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1123
1124         g_value_init(&connectable, G_TYPE_BOOLEAN);
1125         g_value_init(&discoverable, G_TYPE_BOOLEAN);
1126         g_value_init(&val_timeout, G_TYPE_UINT);
1127
1128         switch (discoverable_mode) {
1129         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1130                 pg_scan = TRUE;
1131                 inq_scan = FALSE;
1132                 timeout = 0;
1133                 break;
1134         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1135                 pg_scan = TRUE;
1136                 inq_scan = TRUE;
1137                 timeout = 0;
1138                 break;
1139         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1140                 inq_scan = TRUE;
1141                 pg_scan = TRUE;
1142                 break;
1143         default:
1144                 return BLUETOOTH_ERROR_INVALID_PARAM;
1145         }
1146
1147         g_value_set_boolean(&connectable, pg_scan);
1148         g_value_set_boolean(&discoverable, inq_scan);
1149         g_value_set_uint(&val_timeout, timeout);
1150
1151         dbus_g_proxy_call(proxy, "Set", &error,
1152                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1153                                 G_TYPE_STRING, "Powered",
1154                                 G_TYPE_VALUE, &connectable,
1155                                 G_TYPE_INVALID, G_TYPE_INVALID);
1156
1157         if (error != NULL) {
1158                 BT_ERR("Powered set err:[%s]", error->message);
1159                 g_error_free(error);
1160                 ret = BLUETOOTH_ERROR_INTERNAL;
1161                 goto done;
1162         }
1163
1164         dbus_g_proxy_call(proxy, "Set", &error,
1165                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1166                                 G_TYPE_STRING, "Discoverable",
1167                                 G_TYPE_VALUE, &discoverable,
1168                                 G_TYPE_INVALID, G_TYPE_INVALID);
1169
1170         if (error != NULL) {
1171                 BT_ERR("Discoverable set err:[%s]", error->message);
1172                 g_error_free(error);
1173                 ret = BLUETOOTH_ERROR_INTERNAL;
1174                 goto done;
1175         }
1176
1177         dbus_g_proxy_call(proxy, "Set", &error,
1178                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1179                                 G_TYPE_STRING, "DiscoverableTimeout",
1180                                 G_TYPE_VALUE, &val_timeout,
1181                                 G_TYPE_INVALID, G_TYPE_INVALID);
1182
1183         if (error != NULL) {
1184                 BT_ERR("Timeout set err:[%s]", error->message);
1185                 g_error_free(error);
1186                 ret = BLUETOOTH_ERROR_INTERNAL;
1187                 goto done;
1188         }
1189
1190         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1191                 timeout = -1;
1192
1193         __bt_set_visible_time(timeout);
1194
1195 done:
1196         g_value_unset(&val_timeout);
1197         g_value_unset(&connectable);
1198         g_value_unset(&discoverable);
1199
1200         return ret;
1201 }
1202
1203 int _bt_start_discovery(void)
1204 {
1205         DBusGProxy *proxy;
1206
1207         if (_bt_is_discovering() == TRUE) {
1208                 BT_ERR("BT is already in discovering");
1209                 return BLUETOOTH_ERROR_IN_PROGRESS;
1210         }
1211
1212         proxy = _bt_get_adapter_proxy();
1213         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1214
1215         if (!dbus_g_proxy_call(proxy, "StartDiscovery", NULL,
1216                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1217                 BT_ERR("Discover start failed");
1218                 return BLUETOOTH_ERROR_INTERNAL;
1219         }
1220
1221         _bt_stop_discovery_timeout();
1222
1223         is_discovering = TRUE;
1224         cancel_by_user = FALSE;
1225         /* discovery status will be change in event */
1226
1227         return BLUETOOTH_ERROR_NONE;
1228 }
1229
1230 int _bt_cancel_discovery(void)
1231 {
1232         DBusGProxy *proxy;
1233
1234         if (_bt_is_discovering() == FALSE) {
1235                 BT_ERR("BT is not in discovering");
1236                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1237         }
1238
1239         proxy = _bt_get_adapter_proxy();
1240         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1241
1242         if (!dbus_g_proxy_call(proxy, "StopDiscovery", NULL,
1243                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1244                 BT_ERR("Discover stop failed");
1245                 return BLUETOOTH_ERROR_INTERNAL;
1246         }
1247
1248         cancel_by_user = TRUE;
1249         /* discovery status will be change in event */
1250
1251         return BLUETOOTH_ERROR_NONE;
1252 }
1253
1254 gboolean _bt_is_discovering(void)
1255 {
1256         return is_discovering;
1257 }
1258
1259 gboolean _bt_get_discovering_property(void)
1260 {
1261         DBusGProxy *proxy;
1262         GValue discovering_v = { 0 };
1263         GError *err = NULL;
1264
1265         proxy = _bt_get_adapter_properties_proxy();
1266         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1267
1268         if (!dbus_g_proxy_call(proxy, "Get", &err,
1269                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1270                         G_TYPE_STRING, "Discovering",
1271                         G_TYPE_INVALID,
1272                         G_TYPE_VALUE, &discovering_v,
1273                         G_TYPE_INVALID)) {
1274                 if (err != NULL) {
1275                         BT_ERR("Getting property failed: [%s]\n", err->message);
1276                         g_error_free(err);
1277                 }
1278                 return BLUETOOTH_ERROR_INTERNAL;
1279         }
1280
1281         return g_value_get_boolean(&discovering_v);
1282 }
1283
1284 unsigned int _bt_get_discoverable_timeout_property(void)
1285 {
1286         DBusGProxy *proxy;
1287         GValue timeout_v = { 0 };
1288         GError *err = NULL;
1289
1290         proxy = _bt_get_adapter_properties_proxy();
1291         retv_if(proxy == NULL, 0);
1292
1293         if (!dbus_g_proxy_call(proxy, "Get", &err,
1294                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1295                         G_TYPE_STRING, "DiscoverableTimeout",
1296                         G_TYPE_INVALID,
1297                         G_TYPE_VALUE, &timeout_v,
1298                         G_TYPE_INVALID)) {
1299                 if (err != NULL) {
1300                         BT_ERR("Getting property failed: [%s]\n", err->message);
1301                         g_error_free(err);
1302                 }
1303                 return 0;
1304         }
1305
1306         return g_value_get_uint(&timeout_v);
1307 }
1308
1309 static bluetooth_device_info_t *__bt_parse_device_info(DBusMessageIter *item_iter)
1310 {
1311         DBusMessageIter value_iter;
1312         bluetooth_device_info_t *dev_info;
1313
1314         dbus_message_iter_recurse(item_iter, &value_iter);
1315
1316         if (dbus_message_iter_get_arg_type(&value_iter) != DBUS_TYPE_DICT_ENTRY) {
1317                 BT_DBG("No entry");
1318                 return NULL;
1319         }
1320
1321         dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
1322
1323         while (dbus_message_iter_get_arg_type(&value_iter) ==
1324                                                 DBUS_TYPE_DICT_ENTRY) {
1325                 char *value = NULL;
1326                 char *key;
1327                 DBusMessageIter dict_entry;
1328                 DBusMessageIter iter_dict_val;
1329
1330                 dbus_message_iter_recurse(&value_iter, &dict_entry);
1331
1332                 dbus_message_iter_get_basic(&dict_entry, &key);
1333
1334                 if (key == NULL) {
1335                         dbus_message_iter_next(&value_iter);
1336                         continue;
1337                 }
1338
1339                 if (!dbus_message_iter_next(&dict_entry)) {
1340                         dbus_message_iter_next(&value_iter);
1341                         continue;
1342                 }
1343                 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
1344
1345                 if (strcasecmp(key, "Address") == 0) {
1346                         const char *address = NULL;
1347                         dbus_message_iter_get_basic(&iter_dict_val, &address);
1348                         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
1349                                                         address);
1350
1351                 } else if (strcasecmp(key, "Class") == 0) {
1352                         unsigned int cod;
1353                         dbus_message_iter_get_basic(&iter_dict_val, &cod);
1354                         _bt_divide_device_class(&dev_info->device_class, cod);
1355                 } else if (strcasecmp(key, "Name") == 0) {
1356                         dbus_message_iter_get_basic(&iter_dict_val, &value);
1357
1358                         /* If there is no Alias */
1359                         if (strlen(dev_info->device_name.name) == 0) {
1360                                 g_strlcpy(dev_info->device_name.name, value,
1361                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1362                         }
1363                 } else if (strcasecmp(key, "Alias") == 0) {
1364                         dbus_message_iter_get_basic(&iter_dict_val, &value);
1365
1366                         /* Overwrite the name */
1367                         if (value) {
1368                                 memset(dev_info->device_name.name, 0x00,
1369                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1370                                 g_strlcpy(dev_info->device_name.name, value,
1371                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1372                         }
1373                 } else if (strcasecmp(key, "Connected") == 0) {
1374                         dbus_message_iter_get_basic(&iter_dict_val,
1375                                                 &dev_info->connected);
1376                 } else if (strcasecmp(key, "Paired") == 0) {
1377                         dbus_message_iter_get_basic(&iter_dict_val,
1378                                                 &dev_info->paired);
1379                 } else if (strcasecmp(key, "Trusted") == 0) {
1380                         dbus_message_iter_get_basic(&iter_dict_val,
1381                                                 &dev_info->trust);
1382                 } else if (strcasecmp(key, "RSSI") == 0) {
1383                         dbus_message_iter_get_basic(&iter_dict_val,
1384                                                 &dev_info->rssi);
1385                 } else if (strcasecmp(key, "UUIDs") == 0) {
1386                         DBusMessageIter uuid_iter;
1387                         char **parts;
1388                         int i = 0;
1389
1390                         dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
1391
1392                         while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
1393                                 dbus_message_iter_get_basic(&uuid_iter,
1394                                                         &value);
1395
1396                                 g_strlcpy(dev_info->uuids[i], value,
1397                                                 BLUETOOTH_UUID_STRING_MAX);
1398
1399                                 parts = g_strsplit(value, "-", -1);
1400
1401                                 if (parts == NULL || parts[0] == NULL)
1402                                         break;
1403
1404                                 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
1405                                 g_strfreev(parts);
1406
1407                                 i++;
1408                                 if (!dbus_message_iter_next(&uuid_iter)) {
1409                                         break;
1410                                 }
1411                         }
1412
1413                         dev_info->service_index = i;
1414                 }
1415
1416                 dbus_message_iter_next(&value_iter);
1417         }
1418
1419         return dev_info;
1420 }
1421
1422 static void __bt_extract_device_info(DBusMessageIter *msg_iter,
1423                                                         GArray **dev_list)
1424 {
1425         bluetooth_device_info_t *dev_info = NULL;
1426         char *object_path = NULL;
1427         DBusMessageIter value_iter;
1428
1429         /* Parse the signature:  oa{sa{sv}}} */
1430         ret_if(dbus_message_iter_get_arg_type(msg_iter) !=
1431                                 DBUS_TYPE_OBJECT_PATH);
1432
1433         dbus_message_iter_get_basic(msg_iter, &object_path);
1434         ret_if(object_path == NULL);
1435
1436         /* object array (oa) */
1437         ret_if(dbus_message_iter_next(msg_iter) == FALSE);
1438         ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY);
1439
1440         dbus_message_iter_recurse(msg_iter, &value_iter);
1441
1442         /* string array (sa) */
1443         while (dbus_message_iter_get_arg_type(&value_iter) ==
1444                                         DBUS_TYPE_DICT_ENTRY) {
1445                 char *interface_name = NULL;
1446                 DBusMessageIter interface_iter;
1447
1448                 dbus_message_iter_recurse(&value_iter, &interface_iter);
1449
1450                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
1451                                                         DBUS_TYPE_STRING);
1452
1453                 dbus_message_iter_get_basic(&interface_iter, &interface_name);
1454
1455                 ret_if(dbus_message_iter_next(&interface_iter) == FALSE);
1456
1457                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
1458                                                         DBUS_TYPE_ARRAY);
1459
1460                 if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) {
1461                         BT_DBG("Found a device: %s", object_path);
1462                         dev_info = __bt_parse_device_info(&interface_iter);
1463
1464                         if (dev_info) {
1465                                 if (dev_info->paired == TRUE) {
1466                                         g_array_append_vals(*dev_list, dev_info,
1467                                                         sizeof(bluetooth_device_info_t));
1468                                 } else {
1469                                         g_free(dev_info);
1470                                 }
1471                         }
1472
1473                         return;
1474                 }
1475
1476                 dbus_message_iter_next(&value_iter);
1477         }
1478
1479         BT_DBG("There is no device interface");
1480 }
1481
1482 int _bt_get_bonded_devices(GArray **dev_list)
1483 {
1484         DBusMessage *msg;
1485         DBusMessage *reply;
1486         DBusMessageIter reply_iter;
1487         DBusMessageIter value_iter;
1488         DBusError err;
1489         DBusConnection *conn;
1490
1491         conn = _bt_get_system_conn();
1492         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1493
1494         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
1495                                                 BT_MANAGER_INTERFACE,
1496                                                 "GetManagedObjects");
1497
1498         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
1499
1500         /* Synchronous call */
1501         dbus_error_init(&err);
1502         reply = dbus_connection_send_with_reply_and_block(
1503                                         conn, msg,
1504                                         -1, &err);
1505         dbus_message_unref(msg);
1506
1507         if (!reply) {
1508                 BT_ERR("Can't get managed objects");
1509
1510                 if (dbus_error_is_set(&err)) {
1511                         BT_ERR("%s", err.message);
1512                         dbus_error_free(&err);
1513                 }
1514                 return BLUETOOTH_ERROR_INTERNAL;
1515         }
1516
1517         if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
1518             BT_ERR("Fail to iterate the reply");
1519             return BLUETOOTH_ERROR_INTERNAL;
1520         }
1521
1522         dbus_message_iter_recurse(&reply_iter, &value_iter);
1523
1524         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
1525         while (dbus_message_iter_get_arg_type(&value_iter) ==
1526                                                 DBUS_TYPE_DICT_ENTRY) {
1527                 DBusMessageIter msg_iter;
1528
1529                 dbus_message_iter_recurse(&value_iter, &msg_iter);
1530
1531                 __bt_extract_device_info(&msg_iter, dev_list);
1532
1533                 dbus_message_iter_next(&value_iter);
1534         }
1535
1536         return BLUETOOTH_ERROR_NONE;
1537 }
1538
1539 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
1540                                 bluetooth_device_info_t *dev_info)
1541 {
1542         char *object_path = NULL;
1543         DBusGProxy *adapter_proxy;
1544         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1545
1546         BT_CHECK_PARAMETER(device_address, return);
1547         BT_CHECK_PARAMETER(dev_info, return);
1548
1549         adapter_proxy = _bt_get_adapter_proxy();
1550         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1551
1552         _bt_convert_addr_type_to_string(address, device_address->addr);
1553
1554         object_path = _bt_get_device_object_path(address);
1555
1556         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_FOUND);
1557
1558         if (__bt_get_bonded_device_info(object_path,
1559                                 dev_info) != BLUETOOTH_ERROR_NONE) {
1560                 BT_ERR("Can't get the paired device path \n");
1561                 g_free(object_path);
1562                 return BLUETOOTH_ERROR_INTERNAL;
1563         }
1564         g_free(object_path);
1565         return BLUETOOTH_ERROR_NONE;
1566 }
1567
1568 int _bt_get_timeout_value(int *timeout)
1569 {
1570         time_t current_time;
1571         int time_diff;
1572
1573         /* Take current time */
1574         time(&current_time);
1575         time_diff = difftime(current_time, visible_timer.start_time);
1576
1577         BT_DBG("Time diff = %d\n", time_diff);
1578
1579         *timeout = visible_timer.timeout - time_diff;
1580
1581         return BLUETOOTH_ERROR_NONE;
1582 }
1583