keep current bluetooth state when starting bt-service
[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 void _bt_set_enabled(void)
659 {
660         int result = BLUETOOTH_ERROR_NONE;
661
662         _bt_adapter_set_status(BT_ACTIVATED);
663
664         // register agent if it was not previously done.
665         if (!adapter_agent) {
666                 BT_DBG("");
667                 _bt_handle_adapter_added();
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
686 void _bt_set_disabled(void)
687 {
688         int result = BLUETOOTH_ERROR_NONE;
689
690         _bt_adapter_set_status(BT_DEACTIVATED);
691
692         /* Update Bluetooth Status to notify other modules */
693         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
694                 BT_ERR("Set vconf failed\n");
695
696         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
697                 BT_ERR("Set vconf failed\n");
698
699         /* Send disabled event */
700         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
701                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
702 }
703
704 void *_bt_get_adapter_agent(void)
705 {
706         return adapter_agent;
707 }
708
709 void _bt_handle_flight_mode_noti(void)
710 {
711         BT_DBG("+");
712         vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
713                         __bt_flight_mode_cb, NULL);
714         BT_DBG("-");
715 }
716
717 void _bt_handle_adapter_added(void)
718 {
719         BT_DBG("");
720
721         adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
722         if (!adapter_agent) {
723                 BT_ERR("Fail to register agent");
724                 return;
725         }
726
727 #ifdef __TIZEN_MOBILE__
728         if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
729                 BT_ERR("Fail to register media player");
730 #endif
731
732         if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
733                 BT_ERR("Fail to init obex server");
734 /*
735         if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
736                 BT_ERR("Fail to activate network");
737 */
738
739         /* add the vconf noti handler */
740         vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
741                                         __bt_phone_name_changed_cb, NULL);
742
743         vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
744                         __bt_flight_mode_cb, NULL);
745 }
746
747 void _bt_handle_adapter_removed(void)
748 {
749         BT_DBG("");
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_terminate_service(NULL);
758 }
759
760 DBusGProxy *_bt_init_core_proxy(void)
761 {
762         DBusGProxy *proxy;
763         DBusGConnection *conn;
764
765         conn = _bt_get_system_gconn();
766         if (!conn)
767                 return NULL;
768
769         proxy = dbus_g_proxy_new_for_name(conn, BT_CORE_NAME,
770                        BT_CORE_PATH, BT_CORE_INTERFACE);
771         if (!proxy)
772                 return NULL;
773
774         core_proxy = proxy;
775
776         return proxy;
777 }
778
779 static DBusGProxy *__bt_get_core_proxy(void)
780 {
781         return (core_proxy) ? core_proxy : _bt_init_core_proxy();
782 }
783
784 int _bt_enable_adapter(void)
785 {
786         DBusGProxy *proxy;
787         GError *err = NULL;
788
789         BT_DBG("");
790
791         if (_bt_adapter_get_status() == BT_ACTIVATING) {
792                         BT_DBG("Enabling in progress");
793                         return BLUETOOTH_ERROR_IN_PROGRESS;
794         }
795
796         if (_bt_adapter_get_status() == BT_ACTIVATED) {
797                         BT_DBG("Already enabled");
798                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
799         }
800
801         _bt_adapter_set_status(BT_ACTIVATING);
802
803         proxy = __bt_get_core_proxy();
804         if (!proxy)
805                 return BLUETOOTH_ERROR_INTERNAL;
806
807          if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapter",
808                                         BT_ENABLE_TIMEOUT, &err,
809                                         G_TYPE_INVALID,
810                                         G_TYPE_INVALID) == FALSE) {
811
812                 _bt_adapter_set_status(BT_DEACTIVATED);
813
814                 if (err != NULL) {
815                         BT_ERR("Bt core call failed: [%s]", err->message);
816                         g_error_free(err);
817                 }
818
819                 /* Clean up the process */
820                 if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
821                                 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
822                                 BT_ERR("Bt core call failed");
823                 }
824
825                 /* Display notification */
826                 notification_status_message_post(BT_STR_NOT_SUPPORT);
827
828                 /* Terminate myself */
829                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
830                 return BLUETOOTH_ERROR_INTERNAL;
831         }
832
833         return BLUETOOTH_ERROR_NONE;
834 }
835
836 int _bt_disable_adapter(void)
837 {
838         DBusGProxy *proxy;
839
840         BT_DBG("");
841
842         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
843                         BT_DBG("Disabling in progress");
844                         return BLUETOOTH_ERROR_IN_PROGRESS;
845         }
846
847         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
848                         BT_DBG("Already disabled");
849                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
850         }
851
852         _bt_adapter_set_status(BT_DEACTIVATING);
853
854         proxy = __bt_get_core_proxy();
855         if (!proxy)
856                 return BLUETOOTH_ERROR_INTERNAL;
857
858         if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
859                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
860                 BT_ERR("Bt core call failed");
861                 _bt_adapter_set_status(BT_ACTIVATED);
862                 return BLUETOOTH_ERROR_INTERNAL;
863         }
864
865         return BLUETOOTH_ERROR_NONE;
866 }
867
868 int _bt_reset_adapter(void)
869 {
870         DBusGProxy *proxy;
871
872         BT_DBG("");
873
874         proxy = __bt_get_core_proxy();
875         if (!proxy)
876                 return BLUETOOTH_ERROR_INTERNAL;
877
878         if (dbus_g_proxy_call(proxy, "ResetAdapter", NULL,
879                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
880                 BT_ERR("Bt core call failed");
881                 return BLUETOOTH_ERROR_INTERNAL;
882         }
883
884         /* Terminate myself */
885         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
886                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
887         }
888
889         return BLUETOOTH_ERROR_NONE;
890 }
891
892 int _bt_check_adapter(int *status)
893 {
894         BT_CHECK_PARAMETER(status, return);
895
896         *status = 0; /* 0: disabled */
897
898         if (_bt_get_adapter_power())
899                 *status = 1; /* 1: enabled */
900
901         return BLUETOOTH_ERROR_NONE;
902 }
903
904 int _bt_get_local_address(bluetooth_device_address_t *local_address)
905 {
906         DBusGProxy *proxy;
907         GError *err = NULL;
908         char *address;
909         GValue address_v = { 0 };
910
911         BT_CHECK_PARAMETER(local_address, return);
912
913         proxy = _bt_get_adapter_properties_proxy();
914         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
915
916         if (!dbus_g_proxy_call(proxy, "Get", &err,
917                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
918                         G_TYPE_STRING, "Address",
919                         G_TYPE_INVALID,
920                         G_TYPE_VALUE, &address_v,
921                         G_TYPE_INVALID)) {
922                 if (err != NULL) {
923                         BT_ERR("Getting property failed: [%s]\n", err->message);
924                         g_error_free(err);
925                 }
926                 return BLUETOOTH_ERROR_INTERNAL;
927         }
928
929         address = (char *)g_value_get_string(&address_v);
930
931         if (address) {
932                 _bt_convert_addr_string_to_type(local_address->addr, address);
933         } else {
934                 return BLUETOOTH_ERROR_INTERNAL;
935         }
936
937         return BLUETOOTH_ERROR_NONE;
938 }
939
940 int _bt_get_local_name(bluetooth_device_name_t *local_name)
941 {
942         DBusGProxy *proxy;
943         GError *err = NULL;
944         GValue name_v = { 0 };
945         char *name = NULL;
946         char *ptr = NULL;
947         int ret = BLUETOOTH_ERROR_NONE;
948
949         BT_CHECK_PARAMETER(local_name, return);
950
951         proxy = _bt_get_adapter_properties_proxy();
952         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
953
954         if (!dbus_g_proxy_call(proxy, "Get", &err,
955                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
956                         G_TYPE_STRING, "Alias",
957                         G_TYPE_INVALID,
958                         G_TYPE_VALUE, &name_v,
959                         G_TYPE_INVALID)) {
960                 if (err != NULL) {
961                         BT_ERR("Getting property failed: [%s]\n", err->message);
962                         g_error_free(err);
963                 }
964                 return BLUETOOTH_ERROR_INTERNAL;
965         }
966
967         name = (char *)g_value_get_string(&name_v);
968
969         if (name && (strlen(name) > 0)) {
970                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
971                 if (!g_utf8_validate(name, -1, (const char **)&ptr))
972                         *ptr = '\0';
973
974                 g_strlcpy(local_name->name, name,
975                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
976         } else {
977                 ret = BLUETOOTH_ERROR_INTERNAL;
978         }
979
980         return ret;
981 }
982
983 int _bt_set_local_name(char *local_name)
984 {
985         GValue name = { 0 };
986         DBusGProxy *proxy;
987         GError *error = NULL;
988         char *ptr = NULL;
989
990         BT_CHECK_PARAMETER(local_name, return);
991
992         proxy = _bt_get_adapter_properties_proxy();
993         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
994
995         if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
996                 *ptr = '\0';
997
998         g_value_init(&name, G_TYPE_STRING);
999         g_value_set_string(&name, local_name);
1000
1001         dbus_g_proxy_call(proxy, "Set", &error,
1002                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1003                         G_TYPE_STRING, "Alias",
1004                         G_TYPE_VALUE, &name,
1005                         G_TYPE_INVALID, G_TYPE_INVALID);
1006
1007         g_value_unset(&name);
1008
1009         if (error) {
1010                 BT_ERR("SetProperty Fail: %s", error->message);
1011                 g_error_free(error);
1012                 return BLUETOOTH_ERROR_INTERNAL;
1013         }
1014
1015         return BLUETOOTH_ERROR_NONE;
1016 }
1017
1018 int _bt_is_service_used(char *service_uuid, gboolean *used)
1019 {
1020         char **uuids;
1021         int i;
1022         DBusGProxy *proxy;
1023         GHashTable *hash = NULL;
1024         GValue *value;
1025         int ret = BLUETOOTH_ERROR_NONE;
1026
1027         BT_CHECK_PARAMETER(service_uuid, return);
1028         BT_CHECK_PARAMETER(used, return);
1029
1030         proxy = _bt_get_adapter_proxy();
1031         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1032
1033         dbus_g_proxy_call(proxy, "GetProperties", NULL,
1034                           G_TYPE_INVALID,
1035                           dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
1036                           G_TYPE_VALUE), &hash, G_TYPE_INVALID);
1037
1038         retv_if(hash == NULL, BLUETOOTH_ERROR_INTERNAL);
1039
1040         value = g_hash_table_lookup(hash, "UUIDs");
1041         uuids = g_value_get_boxed(value);
1042
1043         if (uuids == NULL) {
1044                 /* Normal case */
1045                 *used = FALSE;
1046                 goto done;
1047         }
1048
1049         for (i = 0; uuids[i] != NULL; i++) {
1050                 if (strcasecmp(uuids[i], service_uuid) == 0) {
1051                         *used = TRUE;
1052                         goto done;
1053                 }
1054         }
1055
1056         *used = FALSE;
1057 done:
1058         g_hash_table_destroy(hash);
1059         return ret;
1060 }
1061
1062 static gboolean __bt_get_discoverable_property(void)
1063 {
1064         DBusGProxy *proxy;
1065         GValue discoverable_v = { 0 };
1066         GError *err = NULL;
1067
1068         proxy = _bt_get_adapter_properties_proxy();
1069         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1070
1071         if (!dbus_g_proxy_call(proxy, "Get", &err,
1072                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1073                         G_TYPE_STRING, "Discoverable",
1074                         G_TYPE_INVALID,
1075                         G_TYPE_VALUE, &discoverable_v,
1076                         G_TYPE_INVALID)) {
1077                 if (err != NULL) {
1078                         BT_ERR("Getting property failed: [%s]\n", err->message);
1079                         g_error_free(err);
1080                 }
1081                 return BLUETOOTH_ERROR_INTERNAL;
1082         }
1083
1084         return g_value_get_boolean(&discoverable_v);
1085 }
1086
1087 int _bt_get_discoverable_mode(int *mode)
1088 {
1089         gboolean discoverable;
1090         unsigned int timeout;
1091
1092         BT_CHECK_PARAMETER(mode, return);
1093
1094         discoverable = __bt_get_discoverable_property();
1095         timeout = _bt_get_discoverable_timeout_property();
1096
1097         if (discoverable == TRUE) {
1098                 if (timeout == 0)
1099                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1100                 else
1101                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1102         } else {
1103                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1104         }
1105         return BLUETOOTH_ERROR_NONE;
1106 }
1107
1108 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1109 {
1110         int ret = BLUETOOTH_ERROR_NONE;
1111         gboolean inq_scan;
1112         gboolean pg_scan;
1113         GError *error = NULL;
1114         GValue connectable = { 0 };
1115         GValue discoverable = { 0 };
1116         GValue val_timeout = { 0 };
1117         DBusGProxy *proxy;
1118
1119         proxy = _bt_get_adapter_properties_proxy();
1120         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1121
1122         g_value_init(&connectable, G_TYPE_BOOLEAN);
1123         g_value_init(&discoverable, G_TYPE_BOOLEAN);
1124         g_value_init(&val_timeout, G_TYPE_UINT);
1125
1126         switch (discoverable_mode) {
1127         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1128                 pg_scan = TRUE;
1129                 inq_scan = FALSE;
1130                 timeout = 0;
1131                 break;
1132         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1133                 pg_scan = TRUE;
1134                 inq_scan = TRUE;
1135                 timeout = 0;
1136                 break;
1137         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1138                 inq_scan = TRUE;
1139                 pg_scan = TRUE;
1140                 break;
1141         default:
1142                 return BLUETOOTH_ERROR_INVALID_PARAM;
1143         }
1144
1145         g_value_set_boolean(&connectable, pg_scan);
1146         g_value_set_boolean(&discoverable, inq_scan);
1147         g_value_set_uint(&val_timeout, timeout);
1148
1149         dbus_g_proxy_call(proxy, "Set", &error,
1150                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1151                                 G_TYPE_STRING, "Powered",
1152                                 G_TYPE_VALUE, &connectable,
1153                                 G_TYPE_INVALID, G_TYPE_INVALID);
1154
1155         if (error != NULL) {
1156                 BT_ERR("Powered set err:[%s]", error->message);
1157                 g_error_free(error);
1158                 ret = BLUETOOTH_ERROR_INTERNAL;
1159                 goto done;
1160         }
1161
1162         dbus_g_proxy_call(proxy, "Set", &error,
1163                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1164                                 G_TYPE_STRING, "Discoverable",
1165                                 G_TYPE_VALUE, &discoverable,
1166                                 G_TYPE_INVALID, G_TYPE_INVALID);
1167
1168         if (error != NULL) {
1169                 BT_ERR("Discoverable set err:[%s]", error->message);
1170                 g_error_free(error);
1171                 ret = BLUETOOTH_ERROR_INTERNAL;
1172                 goto done;
1173         }
1174
1175         dbus_g_proxy_call(proxy, "Set", &error,
1176                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1177                                 G_TYPE_STRING, "DiscoverableTimeout",
1178                                 G_TYPE_VALUE, &val_timeout,
1179                                 G_TYPE_INVALID, G_TYPE_INVALID);
1180
1181         if (error != NULL) {
1182                 BT_ERR("Timeout set err:[%s]", error->message);
1183                 g_error_free(error);
1184                 ret = BLUETOOTH_ERROR_INTERNAL;
1185                 goto done;
1186         }
1187
1188         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1189                 timeout = -1;
1190
1191         __bt_set_visible_time(timeout);
1192
1193 done:
1194         g_value_unset(&val_timeout);
1195         g_value_unset(&connectable);
1196         g_value_unset(&discoverable);
1197
1198         return ret;
1199 }
1200
1201 int _bt_start_discovery(void)
1202 {
1203         DBusGProxy *proxy;
1204
1205         if (_bt_is_discovering() == TRUE) {
1206                 BT_ERR("BT is already in discovering");
1207                 return BLUETOOTH_ERROR_IN_PROGRESS;
1208         }
1209
1210         proxy = _bt_get_adapter_proxy();
1211         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1212
1213         if (!dbus_g_proxy_call(proxy, "StartDiscovery", NULL,
1214                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1215                 BT_ERR("Discover start failed");
1216                 return BLUETOOTH_ERROR_INTERNAL;
1217         }
1218
1219         _bt_stop_discovery_timeout();
1220
1221         is_discovering = TRUE;
1222         cancel_by_user = FALSE;
1223         /* discovery status will be change in event */
1224
1225         return BLUETOOTH_ERROR_NONE;
1226 }
1227
1228 int _bt_cancel_discovery(void)
1229 {
1230         DBusGProxy *proxy;
1231
1232         if (_bt_is_discovering() == FALSE) {
1233                 BT_ERR("BT is not in discovering");
1234                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1235         }
1236
1237         proxy = _bt_get_adapter_proxy();
1238         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1239
1240         if (!dbus_g_proxy_call(proxy, "StopDiscovery", NULL,
1241                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1242                 BT_ERR("Discover stop failed");
1243                 return BLUETOOTH_ERROR_INTERNAL;
1244         }
1245
1246         cancel_by_user = TRUE;
1247         /* discovery status will be change in event */
1248
1249         return BLUETOOTH_ERROR_NONE;
1250 }
1251
1252 gboolean _bt_is_discovering(void)
1253 {
1254         return is_discovering;
1255 }
1256
1257 gboolean _bt_get_discovering_property(void)
1258 {
1259         DBusGProxy *proxy;
1260         GValue discovering_v = { 0 };
1261         GError *err = NULL;
1262
1263         proxy = _bt_get_adapter_properties_proxy();
1264         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1265
1266         if (!dbus_g_proxy_call(proxy, "Get", &err,
1267                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1268                         G_TYPE_STRING, "Discovering",
1269                         G_TYPE_INVALID,
1270                         G_TYPE_VALUE, &discovering_v,
1271                         G_TYPE_INVALID)) {
1272                 if (err != NULL) {
1273                         BT_ERR("Getting property failed: [%s]\n", err->message);
1274                         g_error_free(err);
1275                 }
1276                 return BLUETOOTH_ERROR_INTERNAL;
1277         }
1278
1279         return g_value_get_boolean(&discovering_v);
1280 }
1281
1282 unsigned int _bt_get_discoverable_timeout_property(void)
1283 {
1284         DBusGProxy *proxy;
1285         GValue timeout_v = { 0 };
1286         GError *err = NULL;
1287
1288         proxy = _bt_get_adapter_properties_proxy();
1289         retv_if(proxy == NULL, 0);
1290
1291         if (!dbus_g_proxy_call(proxy, "Get", &err,
1292                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1293                         G_TYPE_STRING, "DiscoverableTimeout",
1294                         G_TYPE_INVALID,
1295                         G_TYPE_VALUE, &timeout_v,
1296                         G_TYPE_INVALID)) {
1297                 if (err != NULL) {
1298                         BT_ERR("Getting property failed: [%s]\n", err->message);
1299                         g_error_free(err);
1300                 }
1301                 return 0;
1302         }
1303
1304         return g_value_get_uint(&timeout_v);
1305 }
1306
1307 static bluetooth_device_info_t *__bt_parse_device_info(DBusMessageIter *item_iter)
1308 {
1309         DBusMessageIter value_iter;
1310         bluetooth_device_info_t *dev_info;
1311
1312         dbus_message_iter_recurse(item_iter, &value_iter);
1313
1314         if (dbus_message_iter_get_arg_type(&value_iter) != DBUS_TYPE_DICT_ENTRY) {
1315                 BT_DBG("No entry");
1316                 return NULL;
1317         }
1318
1319         dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
1320
1321         while (dbus_message_iter_get_arg_type(&value_iter) ==
1322                                                 DBUS_TYPE_DICT_ENTRY) {
1323                 char *value = NULL;
1324                 char *key;
1325                 DBusMessageIter dict_entry;
1326                 DBusMessageIter iter_dict_val;
1327
1328                 dbus_message_iter_recurse(&value_iter, &dict_entry);
1329
1330                 dbus_message_iter_get_basic(&dict_entry, &key);
1331
1332                 if (key == NULL) {
1333                         dbus_message_iter_next(&value_iter);
1334                         continue;
1335                 }
1336
1337                 if (!dbus_message_iter_next(&dict_entry)) {
1338                         dbus_message_iter_next(&value_iter);
1339                         continue;
1340                 }
1341                 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
1342
1343                 if (strcasecmp(key, "Address") == 0) {
1344                         const char *address = NULL;
1345                         dbus_message_iter_get_basic(&iter_dict_val, &address);
1346                         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
1347                                                         address);
1348
1349                 } else if (strcasecmp(key, "Class") == 0) {
1350                         unsigned int cod;
1351                         dbus_message_iter_get_basic(&iter_dict_val, &cod);
1352                         _bt_divide_device_class(&dev_info->device_class, cod);
1353                 } else if (strcasecmp(key, "Name") == 0) {
1354                         dbus_message_iter_get_basic(&iter_dict_val, &value);
1355
1356                         /* If there is no Alias */
1357                         if (strlen(dev_info->device_name.name) == 0) {
1358                                 g_strlcpy(dev_info->device_name.name, value,
1359                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1360                         }
1361                 } else if (strcasecmp(key, "Alias") == 0) {
1362                         dbus_message_iter_get_basic(&iter_dict_val, &value);
1363
1364                         /* Overwrite the name */
1365                         if (value) {
1366                                 memset(dev_info->device_name.name, 0x00,
1367                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1368                                 g_strlcpy(dev_info->device_name.name, value,
1369                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
1370                         }
1371                 } else if (strcasecmp(key, "Connected") == 0) {
1372                         dbus_message_iter_get_basic(&iter_dict_val,
1373                                                 &dev_info->connected);
1374                 } else if (strcasecmp(key, "Paired") == 0) {
1375                         dbus_message_iter_get_basic(&iter_dict_val,
1376                                                 &dev_info->paired);
1377                 } else if (strcasecmp(key, "Trusted") == 0) {
1378                         dbus_message_iter_get_basic(&iter_dict_val,
1379                                                 &dev_info->trust);
1380                 } else if (strcasecmp(key, "RSSI") == 0) {
1381                         dbus_message_iter_get_basic(&iter_dict_val,
1382                                                 &dev_info->rssi);
1383                 } else if (strcasecmp(key, "UUIDs") == 0) {
1384                         DBusMessageIter uuid_iter;
1385                         char **parts;
1386                         int i = 0;
1387
1388                         dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
1389
1390                         while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
1391                                 dbus_message_iter_get_basic(&uuid_iter,
1392                                                         &value);
1393
1394                                 g_strlcpy(dev_info->uuids[i], value,
1395                                                 BLUETOOTH_UUID_STRING_MAX);
1396
1397                                 parts = g_strsplit(value, "-", -1);
1398
1399                                 if (parts == NULL || parts[0] == NULL)
1400                                         break;
1401
1402                                 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
1403                                 g_strfreev(parts);
1404
1405                                 i++;
1406                                 if (!dbus_message_iter_next(&uuid_iter)) {
1407                                         break;
1408                                 }
1409                         }
1410
1411                         dev_info->service_index = i;
1412                 }
1413
1414                 dbus_message_iter_next(&value_iter);
1415         }
1416
1417         return dev_info;
1418 }
1419
1420 static void __bt_extract_device_info(DBusMessageIter *msg_iter,
1421                                                         GArray **dev_list)
1422 {
1423         bluetooth_device_info_t *dev_info = NULL;
1424         char *object_path = NULL;
1425         DBusMessageIter value_iter;
1426
1427         /* Parse the signature:  oa{sa{sv}}} */
1428         ret_if(dbus_message_iter_get_arg_type(msg_iter) !=
1429                                 DBUS_TYPE_OBJECT_PATH);
1430
1431         dbus_message_iter_get_basic(msg_iter, &object_path);
1432         ret_if(object_path == NULL);
1433
1434         /* object array (oa) */
1435         ret_if(dbus_message_iter_next(msg_iter) == FALSE);
1436         ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY);
1437
1438         dbus_message_iter_recurse(msg_iter, &value_iter);
1439
1440         /* string array (sa) */
1441         while (dbus_message_iter_get_arg_type(&value_iter) ==
1442                                         DBUS_TYPE_DICT_ENTRY) {
1443                 char *interface_name = NULL;
1444                 DBusMessageIter interface_iter;
1445
1446                 dbus_message_iter_recurse(&value_iter, &interface_iter);
1447
1448                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
1449                                                         DBUS_TYPE_STRING);
1450
1451                 dbus_message_iter_get_basic(&interface_iter, &interface_name);
1452
1453                 ret_if(dbus_message_iter_next(&interface_iter) == FALSE);
1454
1455                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
1456                                                         DBUS_TYPE_ARRAY);
1457
1458                 if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) {
1459                         BT_DBG("Found a device: %s", object_path);
1460                         dev_info = __bt_parse_device_info(&interface_iter);
1461
1462                         if (dev_info) {
1463                                 if (dev_info->paired == TRUE) {
1464                                         g_array_append_vals(*dev_list, dev_info,
1465                                                         sizeof(bluetooth_device_info_t));
1466                                 } else {
1467                                         g_free(dev_info);
1468                                 }
1469                         }
1470
1471                         return;
1472                 }
1473
1474                 dbus_message_iter_next(&value_iter);
1475         }
1476
1477         BT_DBG("There is no device interface");
1478 }
1479
1480 int _bt_get_bonded_devices(GArray **dev_list)
1481 {
1482         DBusMessage *msg;
1483         DBusMessage *reply;
1484         DBusMessageIter reply_iter;
1485         DBusMessageIter value_iter;
1486         DBusError err;
1487         DBusConnection *conn;
1488
1489         conn = _bt_get_system_conn();
1490         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1491
1492         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
1493                                                 BT_MANAGER_INTERFACE,
1494                                                 "GetManagedObjects");
1495
1496         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
1497
1498         /* Synchronous call */
1499         dbus_error_init(&err);
1500         reply = dbus_connection_send_with_reply_and_block(
1501                                         conn, msg,
1502                                         -1, &err);
1503         dbus_message_unref(msg);
1504
1505         if (!reply) {
1506                 BT_ERR("Can't get managed objects");
1507
1508                 if (dbus_error_is_set(&err)) {
1509                         BT_ERR("%s", err.message);
1510                         dbus_error_free(&err);
1511                 }
1512                 return BLUETOOTH_ERROR_INTERNAL;
1513         }
1514
1515         if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
1516             BT_ERR("Fail to iterate the reply");
1517             return BLUETOOTH_ERROR_INTERNAL;
1518         }
1519
1520         dbus_message_iter_recurse(&reply_iter, &value_iter);
1521
1522         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
1523         while (dbus_message_iter_get_arg_type(&value_iter) ==
1524                                                 DBUS_TYPE_DICT_ENTRY) {
1525                 DBusMessageIter msg_iter;
1526
1527                 dbus_message_iter_recurse(&value_iter, &msg_iter);
1528
1529                 __bt_extract_device_info(&msg_iter, dev_list);
1530
1531                 dbus_message_iter_next(&value_iter);
1532         }
1533
1534         return BLUETOOTH_ERROR_NONE;
1535 }
1536
1537 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
1538                                 bluetooth_device_info_t *dev_info)
1539 {
1540         char *object_path = NULL;
1541         DBusGProxy *adapter_proxy;
1542         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1543
1544         BT_CHECK_PARAMETER(device_address, return);
1545         BT_CHECK_PARAMETER(dev_info, return);
1546
1547         adapter_proxy = _bt_get_adapter_proxy();
1548         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1549
1550         _bt_convert_addr_type_to_string(address, device_address->addr);
1551
1552         object_path = _bt_get_device_object_path(address);
1553
1554         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_FOUND);
1555
1556         if (__bt_get_bonded_device_info(object_path,
1557                                 dev_info) != BLUETOOTH_ERROR_NONE) {
1558                 BT_ERR("Can't get the paired device path \n");
1559                 g_free(object_path);
1560                 return BLUETOOTH_ERROR_INTERNAL;
1561         }
1562         g_free(object_path);
1563         return BLUETOOTH_ERROR_NONE;
1564 }
1565
1566 int _bt_get_timeout_value(int *timeout)
1567 {
1568         time_t current_time;
1569         int time_diff;
1570
1571         /* Take current time */
1572         time(&current_time);
1573         time_diff = difftime(current_time, visible_timer.start_time);
1574
1575         BT_DBG("Time diff = %d\n", time_diff);
1576
1577         *timeout = visible_timer.timeout - time_diff;
1578
1579         return BLUETOOTH_ERROR_NONE;
1580 }
1581