Code Sync [Tizen3.0]: Merged the tizen_2.4 Spin code to tizen.org
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-adapter.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:  Hocheol Seo <hocheol.seo@samsung.com>
7  *               Girishashok Joshi <girish.joshi@samsung.com>
8  *               Chanyeol Park <chanyeol.park@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *              http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <stdio.h>
25 #include <dbus/dbus-glib.h>
26 #include <dbus/dbus.h>
27 #include <glib.h>
28 #include <dlog.h>
29 #include <string.h>
30 #include <vconf.h>
31 #include <syspopup_caller.h>
32 #include <aul.h>
33 #include <notification.h>
34 //#include <journal/device.h>
35
36 #include "alarm.h"
37
38 #include "bluetooth-api.h"
39 #include "bt-internal-types.h"
40
41 #include "bt-service-common.h"
42 #include "bt-service-event.h"
43 #include "bt-service-adapter.h"
44 #include "bt-service-util.h"
45 #include "bt-service-network.h"
46 #include "bt-service-obex-server.h"
47 #include "bt-service-agent.h"
48 #include "bt-service-main.h"
49 #include "bt-service-avrcp.h"
50
51 typedef struct {
52         guint event_id;
53         int timeout;
54         time_t start_time;
55         gboolean alarm_init;
56         int alarm_id;
57 } bt_adapter_timer_t;
58
59 bt_adapter_timer_t visible_timer = {0, };
60
61 static gboolean is_discovering;
62 static gboolean is_le_discovering;
63 static bt_le_discovery_type_t le_discovery_type = BT_LE_PASSIVE_SCAN;
64 static gboolean cancel_by_user;
65 static bt_status_t adapter_status = BT_DEACTIVATED;
66 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
67 static void *adapter_agent = NULL;
68 static DBusGProxy *core_proxy = NULL;
69 static guint timer_id = 0;
70 static guint le_timer_id = 0;
71
72 #define BT_CORE_NAME "org.projectx.bt_core"
73 #define BT_CORE_PATH "/org/projectx/bt_core"
74 #define BT_CORE_INTERFACE "org.projectx.btcore"
75
76 #define BT_DISABLE_TIME 500 /* 500 ms */
77
78 DBusGProxy *_bt_init_core_proxy(void)
79 {
80        DBusGProxy *proxy;
81         DBusGConnection *conn;
82
83         conn = _bt_get_system_gconn();
84         if (!conn)
85                 return NULL;
86
87        proxy = dbus_g_proxy_new_for_name(conn, BT_CORE_NAME,
88                        BT_CORE_PATH, BT_CORE_INTERFACE);
89         if (!proxy)
90                 return NULL;
91
92        core_proxy = proxy;
93
94        return proxy;
95 }
96
97 static DBusGProxy *__bt_get_core_proxy(void)
98 {
99        return (core_proxy) ? core_proxy : _bt_init_core_proxy();
100 }
101
102 static gboolean __bt_is_factory_test_mode(void)
103 {
104         int mode = 0;
105
106 #ifdef ENABLE_TIZEN_2_4
107         if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
108                 BT_ERR("Get the DUT Mode fail");
109                 return TRUE;
110         }
111 #endif
112
113         if (mode != FALSE) {
114                 BT_INFO("DUT Test Mode !!");
115                 return TRUE;
116         }
117
118         return FALSE;
119 }
120
121 static gboolean __bt_timeout_handler(gpointer user_data)
122 {
123         int result = BLUETOOTH_ERROR_NONE;
124         time_t current_time;
125         int time_diff;
126
127         /* Take current time */
128         time(&current_time);
129         time_diff = difftime(current_time, visible_timer.start_time);
130
131         /* Send event to application */
132         _bt_send_event(BT_ADAPTER_EVENT,
133                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
134                         DBUS_TYPE_INT32, &result,
135                         DBUS_TYPE_INT16, &time_diff,
136                         DBUS_TYPE_INVALID);
137
138         if (visible_timer.timeout <= time_diff) {
139                 g_source_remove(visible_timer.event_id);
140                 visible_timer.event_id = 0;
141                 visible_timer.timeout = 0;
142
143 #ifndef TIZEN_WEARABLE
144                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
145                         BT_ERR("Set vconf failed\n");
146 #endif
147                 return FALSE;
148         }
149
150         return TRUE;
151 }
152
153 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
154 {
155         BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
156
157         int result = BLUETOOTH_ERROR_NONE;
158         int timeout = 0;
159
160         if (alarm_id != visible_timer.alarm_id)
161                 return 0;
162
163         if (visible_timer.event_id) {
164                 _bt_send_event(BT_ADAPTER_EVENT,
165                                 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
166                                 DBUS_TYPE_INT32, &result,
167                                 DBUS_TYPE_INT16, &timeout,
168                                 DBUS_TYPE_INVALID);
169                 g_source_remove(visible_timer.event_id);
170                 visible_timer.event_id = 0;
171                 visible_timer.timeout = 0;
172
173 #ifndef TIZEN_WEARABLE
174                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
175                         BT_ERR("Set vconf failed\n");
176 #endif
177         }
178         /* Switch Off visibility in Bluez */
179         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
180         visible_timer.alarm_id = 0;
181         return 0;
182 }
183
184 static void __bt_visibility_alarm_create()
185 {
186         alarm_id_t alarm_id;
187         int result;
188
189         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
190                                                 0, NULL, &alarm_id);
191         if(result < 0) {
192                 BT_ERR("Failed to create alarm error = %d\n", result);
193         } else {
194                 BT_DBG("Alarm created = %d\n", alarm_id);
195                 visible_timer.alarm_id = alarm_id;
196         }
197 }
198
199 static void __bt_visibility_alarm_remove()
200 {
201         if (visible_timer.event_id > 0) {
202                 g_source_remove(visible_timer.event_id);
203                 visible_timer.event_id = 0;
204         }
205
206         if (visible_timer.alarm_id > 0) {
207                 alarmmgr_remove_alarm(visible_timer.alarm_id);
208                 visible_timer.alarm_id = 0;
209         }
210 }
211
212 int __bt_set_visible_time(int timeout)
213 {
214         int result;
215
216         __bt_visibility_alarm_remove();
217
218         visible_timer.timeout = timeout;
219
220 #ifndef TIZEN_WEARABLE
221         if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
222                 BT_ERR("Set vconf failed");
223 #endif
224         if (timeout <= 0)
225                 return BLUETOOTH_ERROR_NONE;
226
227         if (!visible_timer.alarm_init) {
228                 /* Set Alarm timer to switch off BT */
229                 result = alarmmgr_init("bt-service");
230                 if (result != 0)
231                         return BLUETOOTH_ERROR_INTERNAL;
232
233                 visible_timer.alarm_init = TRUE;
234         }
235
236         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
237         if (result != 0)
238                 return BLUETOOTH_ERROR_INTERNAL;
239
240         /* Take start time */
241         time(&(visible_timer.start_time));
242         visible_timer.event_id = g_timeout_add_seconds(1,
243                                 __bt_timeout_handler, NULL);
244
245         __bt_visibility_alarm_create();
246
247         return BLUETOOTH_ERROR_NONE;
248 }
249
250 static void __bt_get_service_list(GValue *value, bluetooth_device_info_t *dev)
251 {
252         int i;
253         char **uuids;
254         char **parts;
255
256         ret_if(value == NULL);
257         ret_if(dev == NULL);
258
259         uuids = g_value_get_boxed(value);
260         ret_if(uuids == NULL);
261
262         dev->service_index = 0;
263
264         for (i = 0; uuids[i] != NULL; i++) {
265                 g_strlcpy(dev->uuids[i], uuids[i], BLUETOOTH_UUID_STRING_MAX);
266
267                 parts = g_strsplit(uuids[i], "-", -1);
268
269                 if (parts == NULL || parts[0] == NULL)
270                         break;
271
272                 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
273                 g_strfreev(parts);
274
275                 dev->service_index++;
276         }
277 }
278
279 static int __bt_get_bonded_device_info(gchar *device_path,
280                 bluetooth_device_info_t *dev_info)
281 {
282         GValue *value = { 0 };
283         GError *err = NULL;
284         DBusGProxy *device_proxy;
285         const gchar *address;
286         const gchar *name;
287         unsigned int cod;
288         gint rssi;
289         gboolean trust;
290         gboolean paired;
291         gboolean connected;
292         GByteArray *manufacturer_data = NULL;
293         GHashTable *hash = NULL;
294         int ret;
295         DBusGConnection *conn;
296
297         BT_CHECK_PARAMETER(device_path, return);
298         BT_CHECK_PARAMETER(dev_info, return);
299
300         conn = _bt_get_system_gconn();
301         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
302
303         device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
304                                 device_path, BT_PROPERTIES_INTERFACE);
305
306         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
307
308         dbus_g_proxy_call(device_proxy, "GetAll", &err,
309                                 G_TYPE_STRING, BT_DEVICE_INTERFACE,
310                                 G_TYPE_INVALID,
311                                 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
312                                 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
313
314         g_object_unref(device_proxy);
315
316         if (err != NULL) {
317                 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
318                 g_error_free(err);
319                 return BLUETOOTH_ERROR_INTERNAL;
320         }
321
322         if (hash != NULL) {
323                 value = g_hash_table_lookup(hash, "Paired");
324                 paired = g_value_get_boolean(value);
325
326                 value = g_hash_table_lookup(hash, "Address");
327                 address = value ? g_value_get_string(value) : NULL;
328
329                 value = g_hash_table_lookup(hash, "Alias");
330                 name = value ? g_value_get_string(value) : NULL;
331
332                 if (name != NULL)
333                         BT_DBG("Alias Name [%s]", name);
334                 else {
335                         value = g_hash_table_lookup(hash, "Name");
336                         name = value ? g_value_get_string(value) : NULL;
337                 }
338
339                 value = g_hash_table_lookup(hash, "Class");
340                 cod = value ? g_value_get_uint(value) : 0;
341
342                 value = g_hash_table_lookup(hash, "Connected");
343                 connected = value ? g_value_get_boolean(value) : FALSE;
344
345                 value = g_hash_table_lookup(hash, "Trusted");
346                 trust = value ? g_value_get_boolean(value) : FALSE;
347
348                 BT_DBG("paired: %d", paired);
349                 BT_DBG("trust: %d", trust);
350
351                 if ((paired == FALSE) && (trust == FALSE)) {
352                         return BLUETOOTH_ERROR_NOT_PAIRED;
353                 }
354
355                 value = g_hash_table_lookup(hash, "RSSI");
356                 rssi = value ? g_value_get_int(value) : 0;
357
358                 value = g_hash_table_lookup(hash, "UUIDs");
359                 __bt_get_service_list(value, dev_info);
360
361                 value = g_hash_table_lookup(hash, "ManufacturerDataLen");
362                 dev_info->manufacturer_data.data_len = value ? g_value_get_uint(value) : 0;
363
364                 value = g_hash_table_lookup(hash, "ManufacturerData");
365                 manufacturer_data = value ? g_value_get_boxed(value) : NULL;
366                 if (manufacturer_data) {
367                         if (manufacturer_data->len > 0) {
368                                 BT_DBG("manufacturer_data->len  = %d", manufacturer_data->len);
369                                 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
370                         }
371                 }
372
373                 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
374                                                 address);
375
376                 _bt_divide_device_class(&dev_info->device_class, cod);
377
378                 g_strlcpy(dev_info->device_name.name, name,
379                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
380
381                 dev_info->rssi = rssi;
382                 dev_info->trust = trust;
383                 dev_info->paired = paired;
384                 dev_info->connected = connected;
385                 g_hash_table_destroy(hash);
386                 ret = BLUETOOTH_ERROR_NONE;
387         } else {
388                 BT_ERR("Hash is NULL\n");
389                 ret = BLUETOOTH_ERROR_INTERNAL;
390         }
391
392         return ret;
393 }
394
395 void _bt_set_discovery_status(gboolean mode)
396 {
397         is_discovering = mode;
398 }
399
400 void _bt_set_le_discovery_status(gboolean mode)
401 {
402         is_le_discovering = mode;
403 }
404
405 void _bt_set_le_discovery_type(bt_le_discovery_type_t type)
406 {
407         le_discovery_type = type;
408 }
409
410 bt_le_discovery_type_t _bt_get_le_discovery_type(void)
411 {
412         return le_discovery_type;
413 }
414
415 void _bt_set_cancel_by_user(gboolean value)
416 {
417         cancel_by_user = value;
418 }
419
420 gboolean _bt_get_cancel_by_user(void)
421 {
422         return cancel_by_user;
423 }
424
425 void _bt_adapter_set_status(bt_status_t status)
426 {
427         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
428         adapter_status = status;
429 }
430
431 bt_status_t _bt_adapter_get_status(void)
432 {
433         return adapter_status;
434 }
435
436 void _bt_adapter_set_le_status(bt_le_status_t status)
437 {
438         BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
439         adapter_le_status = status;
440 }
441
442 bt_le_status_t _bt_adapter_get_le_status(void)
443 {
444         return adapter_le_status;
445 }
446
447 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
448 {
449         char *phone_name = NULL;
450         char *ptr = NULL;
451
452         if (node == NULL)
453                 return;
454
455         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
456                 phone_name = vconf_keynode_get_str(node);
457
458                 if (phone_name && strlen(phone_name) != 0) {
459                         if (!g_utf8_validate(phone_name, -1,
460                                                         (const char **)&ptr))
461                                 *ptr = '\0';
462
463                         _bt_set_local_name(phone_name);
464                 }
465         }
466 }
467
468 #ifdef TIZEN_WEARABLE
469 static char * __bt_change_dev_name(const char *default_name)
470 {
471         FILE *fp = NULL;
472         char *buf = NULL;
473         char *name = NULL;
474         int result;
475
476         if ((fp = fopen("/csa/bluetooth/.bd_addr", "r")) == NULL) {
477                 BT_ERR("Unable to open bd_addr");
478                 return NULL;
479         }
480
481         result = fseek(fp, -4, SEEK_END);
482         if (result < 0) {
483                 BT_ERR("fseek is failed");
484                 fclose(fp);
485                 return NULL;
486         }
487
488         buf = (char *)malloc(sizeof(char) * 5);
489         if (buf == NULL) {
490                 BT_ERR("malloc is failed");
491                 fclose(fp);
492                 return NULL;
493         }
494         memset(buf, 0, 5);
495
496         result = fread(buf, 1, 4, fp);
497         if (result)
498                 BT_DBG("Size Read: [%d]", result);
499         else
500                 BT_ERR("Error reading file: code[%d]", result);
501
502         name = g_strdup_printf("%s (%s)", default_name, buf);
503
504         BT_INFO("%s", name);
505
506         free(buf);
507         fclose(fp);
508
509         return name ;
510 }
511 #else
512 static void __bt_set_visible_mode(void)
513 {
514         int timeout = 0;
515
516         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
517                 BT_ERR("Fail to get the timeout value");
518
519         /* -1: Always on */
520 }
521 #endif
522
523 static void __bt_set_local_name(void)
524 {
525         char *phone_name = NULL;
526         char *ptr = NULL;
527
528         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
529
530         if (!phone_name)
531                 return;
532
533         if (strlen(phone_name) != 0) {
534                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
535                         *ptr = '\0';
536
537 #ifdef TIZEN_WEARABLE
538                 if (strstr(phone_name, "(") == NULL) {
539                         char *tmp = __bt_change_dev_name(phone_name);
540                         if (tmp != NULL) {
541                                 free(phone_name);
542                                 phone_name = tmp;
543                         }
544                 }
545 #endif
546                 _bt_set_local_name(phone_name);
547         }
548         free(phone_name);
549 }
550
551 static int __bt_set_enabled(void)
552 {
553         int adapter_status = BT_ADAPTER_DISABLED;
554         int result = BLUETOOTH_ERROR_NONE;
555
556         _bt_check_adapter(&adapter_status);
557
558         if (adapter_status == BT_ADAPTER_DISABLED) {
559                 BT_ERR("Bluetoothd is not running");
560                 return BLUETOOTH_ERROR_INTERNAL;
561         }
562
563 #ifndef TIZEN_WEARABLE
564         __bt_set_visible_mode();
565 #endif
566
567         __bt_set_local_name();
568
569         /* Update Bluetooth Status to notify other modules */
570         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
571                 BT_ERR("Set vconf failed\n");
572
573         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
574                 BT_ERR("Set vconf failed\n");
575
576         /* Send enabled event to API */
577         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
578                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
579
580         return BLUETOOTH_ERROR_NONE;
581 }
582
583 void _bt_set_disabled(int result)
584 {
585         int power_off_status = 0;
586         int ret;
587         int ret_pm_ignore;
588         int pm_ignore_mode = 0;
589
590         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
591         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
592
593         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
594
595         /* Update the vconf BT status in normal Deactivation case only */
596         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
597                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
598
599                 BT_DBG("Update vconf for BT normal Deactivation");
600
601                 if (result == BLUETOOTH_ERROR_TIMEOUT)
602                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 )
603                                 BT_ERR("Set vconf failed");
604
605                 /* Update Bluetooth Status to notify other modules */
606                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
607                         BT_ERR("Set vconf failed");
608         }
609
610         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
611                 BT_ERR("Set vconf failed\n");
612
613         _bt_adapter_set_status(BT_DEACTIVATED);
614
615         if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
616                 /* Send disabled event */
617                 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
618                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
619         }
620
621         BT_INFO("Adapter disabled");
622 }
623
624 static int __bt_set_le_enabled(void)
625 {
626         BT_DBG("+");
627         int result = BLUETOOTH_ERROR_NONE;
628         bt_status_t status;
629
630         __bt_set_local_name();
631
632 #ifdef ENABLE_TIZEN_2_4
633         /* Update Bluetooth Status to notify other modules */
634         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
635                 BT_ERR("Set vconf failed\n");
636 #endif
637         /* Send enabled event to API */
638         /*
639         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
640                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
641         */
642         status = _bt_adapter_get_status();
643         if (status == BT_DEACTIVATED) {
644                 BT_INFO("BREDR is off, turn off PSCAN");
645                 _bt_set_connectable(FALSE);
646         }
647         if (le_timer_id > 0) {
648                 g_source_remove(le_timer_id);
649                 le_timer_id = 0;
650         }
651
652         /* Send enabled event to API */
653         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
654                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
655
656         BT_DBG("-");
657         return BLUETOOTH_ERROR_NONE;
658 }
659
660 void _bt_set_le_disabled(int result)
661 {
662         int power_off_status;
663         int ret;
664
665         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
666         BT_DBG("ret : %d", ret);
667         BT_DBG("power_off_status : %d", power_off_status);
668
669         /* Update Bluetooth Status to notify other modules */
670         BT_DBG("Update vconf for BT LE normal Deactivation");
671 #ifdef ENABLE_TIZEN_2_4
672         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
673                 BT_ERR("Set vconf failed\n");
674         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
675 #endif
676
677         if (_bt_adapter_get_status() != BT_DEACTIVATED) {
678                 /* Send disabled event */
679                 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
680                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
681         }
682 }
683
684 void *_bt_get_adapter_agent(void)
685 {
686         return adapter_agent;
687 }
688
689 int _bt_enable_core(void)
690 {
691         DBusGProxy *proxy;
692
693         proxy = __bt_get_core_proxy();
694         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
695
696         if (dbus_g_proxy_call(proxy, "EnableCore", NULL,
697                         G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
698                 BT_ERR("Bt core call failed");
699         }
700
701         return BLUETOOTH_ERROR_NONE;
702 }
703
704 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
705 {
706         gboolean flight_mode = FALSE;
707         int power_saving_mode = 0;
708         int type;
709
710         DBG_SECURE("key=%s", vconf_keynode_get_name(node));
711         type = vconf_keynode_get_type(node);
712         if (type == VCONF_TYPE_BOOL) {
713                 flight_mode = vconf_keynode_get_bool(node);
714                 if (flight_mode != TRUE) {
715                         BT_ERR("Ignore the event");
716                         return;
717                 }
718         } else if (type == VCONF_TYPE_INT) {
719                 power_saving_mode = vconf_keynode_get_int(node);
720                 if (power_saving_mode != 2) {
721                         BT_ERR("Ignore the event");
722                         return;
723                 }
724         } else {
725                 BT_ERR("Invaild vconf key type : %d", type);
726                 return;
727         }
728
729         _bt_enable_core();
730 }
731
732 void _bt_service_register_vconf_handler(void)
733 {
734         int ret;
735         BT_DBG("+");
736
737 #ifdef TIZEN_TELEPHONY_ENABLED
738         ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
739                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL);
740         if (ret < 0)
741                 BT_ERR("Unable to register key handler");
742 #else
743         BT_DBG("Telephony is disabled");
744 #endif
745
746 #ifndef TIZEN_WEARABLE
747 #ifdef ENABLE_TIZEN_2_4
748         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
749                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL);
750         if (ret < 0)
751                 BT_ERR("Unable to register key handler");
752 #endif
753 #endif
754 }
755
756 void _bt_service_unregister_vconf_handler(void)
757 {
758         BT_DBG("+");
759
760 #ifdef TIZEN_TELEPHONY_ENABLED
761         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
762                 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
763 #endif
764
765 #ifndef TIZEN_WEARABLE
766 #ifdef ENABLE_TIZEN_2_4
767         vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
768                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
769 #endif
770 #endif
771 }
772
773 void _bt_handle_adapter_added(void)
774 {
775         BT_DBG("+");
776         bt_status_t status;
777         bt_le_status_t le_status;
778         int ret;
779
780         if (timer_id > 0) {
781                 BT_DBG("g_source is removed");
782                 g_source_remove(timer_id);
783                 timer_id = 0;
784         }
785
786         status = _bt_adapter_get_status();
787         le_status = _bt_adapter_get_le_status();
788         BT_DBG("status : %d", status);
789         BT_DBG("le_status : %d", le_status);
790
791         adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
792         if (!adapter_agent) {
793                 BT_ERR("Fail to register agent");
794                 return;
795         }
796
797         if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
798                 BT_ERR("Fail to register media player");
799
800         if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
801                 BT_ERR("Fail to init obex server");
802
803 #ifndef TIZEN_WEARABLE
804         if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
805                 BT_ERR("Fail to activate network");
806 #endif
807
808         /* add the vconf noti handler */
809         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
810                                         __bt_phone_name_changed_cb, NULL);
811         if (ret < 0)
812                 BT_ERR("Unable to register key handler");
813
814         if (le_status == BT_LE_ACTIVATING) {
815                 __bt_set_le_enabled();
816                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
817         }
818         if (status == BT_ACTIVATING) {
819                 __bt_set_enabled();
820                 _bt_adapter_set_status(BT_ACTIVATED);
821         }
822 //      journal_bt_on();
823
824         _bt_service_register_vconf_handler();
825 }
826
827 void _bt_handle_adapter_removed(void)
828 {
829         int ret;
830
831         _bt_adapter_set_status(BT_DEACTIVATED);
832 //      journal_bt_off();
833
834         __bt_visibility_alarm_remove();
835
836         if (visible_timer.alarm_init) {
837                 alarmmgr_fini();
838                 visible_timer.alarm_init = FALSE;
839         }
840
841         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
842                                 (vconf_callback_fn)__bt_phone_name_changed_cb);
843         if (0 != ret) {
844                 ERR("vconf_ignore_key_changed failed\n");
845         }
846
847         _bt_destroy_agent(adapter_agent);
848         adapter_agent = NULL;
849
850         _bt_reliable_terminate_service(NULL);
851 }
852
853 static gboolean __bt_enable_timeout_cb(gpointer user_data)
854 {
855         DBusGProxy *proxy;
856
857         timer_id = 0;
858
859         retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
860
861         BT_ERR("EnableAdapter is failed");
862
863         proxy = __bt_get_core_proxy();
864         if (!proxy)
865                 return FALSE;
866
867         /* Clean up the process */
868         if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
869                                 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
870                 BT_ERR("Bt core call failed");
871         }
872
873         _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
874
875         /* Display notification */
876         notification_status_message_post(BT_STR_NOT_SUPPORT);
877
878         _bt_terminate_service(NULL);
879
880         return FALSE;
881 }
882
883 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
884 {
885         DBusGProxy *proxy;
886
887         le_timer_id = 0;
888
889         retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
890
891         BT_ERR("EnableAdapterLE is failed");
892
893         proxy = __bt_get_core_proxy();
894         if (!proxy)
895                 return FALSE;
896
897         /* Clean up the process */
898         if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
899                                 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
900                 BT_ERR("Bt core call failed");
901         }
902
903         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
904
905         _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
906
907         /* Display notification */
908         notification_status_message_post(BT_STR_NOT_SUPPORT);
909
910         if (_bt_adapter_get_status() == BT_DEACTIVATED)
911                 _bt_terminate_service(NULL);
912
913         return FALSE;
914 }
915
916 void _bt_adapter_start_le_enable_timer(void)
917 {
918         if (le_timer_id > 0) {
919                 g_source_remove(le_timer_id);
920                 le_timer_id = 0;
921         }
922
923         le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
924                         __bt_enable_le_timeout_cb, NULL);
925
926         return;
927 }
928
929 void _bt_adapter_start_enable_timer(void)
930 {
931         if (timer_id > 0) {
932                 g_source_remove(timer_id);
933                 timer_id = 0;
934         }
935
936         timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
937                         __bt_enable_timeout_cb, NULL);
938
939         return;
940 }
941
942 int _bt_enable_adapter(void)
943 {
944         DBusGProxy *proxy;
945         GError *err = NULL;
946         int ret;
947         bt_status_t status = _bt_adapter_get_status();
948         bt_le_status_t le_status = _bt_adapter_get_le_status();
949         BT_DBG("");
950
951         if (status == BT_ACTIVATING) {
952                 BT_ERR("Enabling in progress");
953                 return BLUETOOTH_ERROR_IN_PROGRESS;
954         }
955
956         if (status == BT_ACTIVATED) {
957                 BT_ERR("Already enabled");
958                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
959         }
960
961         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
962                 BT_ERR("Disabling in progress");
963                 return BLUETOOTH_ERROR_DEVICE_BUSY;
964         }
965
966         _bt_adapter_set_status(BT_ACTIVATING);
967
968         proxy = __bt_get_core_proxy();
969         if (!proxy)
970                 return BLUETOOTH_ERROR_INTERNAL;
971
972         if (le_status == BT_LE_ACTIVATED) {
973                 BT_INFO("LE Already enabled. Just turn on PSCAN");
974                 ret = _bt_set_connectable(TRUE);
975                 if (ret == BLUETOOTH_ERROR_NONE) {
976                         _bt_adapter_set_status(BT_ACTIVATED);
977                 } else {
978                         return BLUETOOTH_ERROR_INTERNAL;
979                 }
980         }
981
982          if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapter",
983                                         BT_ENABLE_TIMEOUT, &err,
984                                         G_TYPE_INVALID,
985                                         G_TYPE_INVALID) == FALSE) {
986
987                 _bt_adapter_set_status(BT_DEACTIVATED);
988
989                 if (err != NULL) {
990                         BT_ERR("Bt core call failed: [%s]", err->message);
991                         g_error_free(err);
992                 }
993
994                 /* Clean up the process */
995                 if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
996                                 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
997                                 BT_ERR("Bt core call failed");
998                 }
999
1000                 /* Display notification */
1001                 notification_status_message_post(BT_STR_NOT_SUPPORT);
1002
1003                 /* Terminate myself */
1004                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1005                 return BLUETOOTH_ERROR_INTERNAL;
1006         }
1007
1008         if (le_status == BT_LE_ACTIVATED) {
1009                 __bt_set_enabled();
1010         } else {
1011                 _bt_adapter_start_enable_timer();
1012         }
1013
1014         return BLUETOOTH_ERROR_NONE;
1015 }
1016
1017 static gboolean __bt_disconnect_all(void)
1018 {
1019         int i;
1020         DBusGConnection *conn;
1021         DBusGProxy *dev_proxy;
1022         gboolean ret = FALSE;
1023
1024         GArray *device_list;
1025         bluetooth_device_info_t info;
1026         guint size;
1027         char *device_path = NULL;
1028         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1029
1030
1031         BT_DBG("");
1032
1033         conn = _bt_get_system_gconn();
1034
1035         device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1036
1037         if (_bt_get_bonded_devices(&device_list)
1038                                         != BLUETOOTH_ERROR_NONE) {
1039                 g_array_free(device_list, TRUE);
1040                 return FALSE;
1041         }
1042
1043         size = (device_list->len) / sizeof(bluetooth_device_info_t);
1044
1045         for (i = 0; i < size; i++) {
1046
1047                 info = g_array_index(device_list,
1048                                 bluetooth_device_info_t, i);
1049
1050                 if (info.connected == TRUE) {
1051                         BT_DBG("Found Connected device");
1052                         _bt_convert_addr_type_to_string(address, info.device_address.addr);
1053                         device_path = _bt_get_device_object_path(address);
1054                         if (device_path == NULL)
1055                                 continue;
1056
1057                         BT_DBG("Disconnecting : %s", device_path);
1058
1059                         dev_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1060                                         device_path, BT_DEVICE_INTERFACE);
1061                         if (dev_proxy == NULL)
1062                                 continue;
1063
1064                         if(!dbus_g_proxy_call(dev_proxy, "Disconnect",
1065                                                 NULL, G_TYPE_INVALID, G_TYPE_INVALID)) {
1066                                 BT_ERR("Disconnect fail error.");
1067                                 g_object_unref(dev_proxy);
1068                                 return FALSE;
1069                         }
1070                 }
1071         }
1072         ret = TRUE;
1073         g_array_free(device_list, TRUE);
1074
1075         return ret;
1076 }
1077
1078 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1079 {
1080         BT_DBG("");
1081         _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1082
1083         return FALSE;
1084 }
1085
1086 int __bt_disable_cb(void)
1087 {
1088         FN_START;
1089         DBusGProxy *proxy;
1090         bt_le_status_t le_status;
1091         int ret;
1092
1093         _bt_adapter_set_status(BT_DEACTIVATING);
1094         le_status = _bt_adapter_get_le_status();
1095         BT_DBG("le_status : %d", le_status);
1096         if (le_status == BT_LE_ACTIVATED) {
1097                 BT_INFO("LE is enabled. Just turn off PSCAN");
1098
1099                 if (_bt_is_discovering())
1100                         _bt_cancel_discovery();
1101
1102                 if (_bt_is_connectable() == FALSE) {
1103                         g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1104                 } else {
1105                         ret = _bt_set_connectable(FALSE);
1106                         if (ret != BLUETOOTH_ERROR_NONE) {
1107                                 BT_ERR("_bt_set_connectable fail!");
1108                                 _bt_adapter_set_status(BT_ACTIVATED);
1109                                 return BLUETOOTH_ERROR_INTERNAL;
1110                         }
1111                 }
1112         }
1113
1114         proxy = __bt_get_core_proxy();
1115         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1116
1117         if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
1118                         G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1119                 BT_ERR("Bt core call failed");
1120                 _bt_adapter_set_status(BT_ACTIVATED);
1121                 return BLUETOOTH_ERROR_INTERNAL;
1122         }
1123
1124         return BLUETOOTH_ERROR_NONE;
1125 }
1126
1127 int _bt_disable_adapter(void)
1128 {
1129         BT_DBG("+");
1130         int ret;
1131
1132         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1133                 BT_DBG("Disabling in progress");
1134                 return BLUETOOTH_ERROR_IN_PROGRESS;
1135         }
1136
1137         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1138                 BT_DBG("Already disabled");
1139                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1140         }
1141
1142         if (timer_id > 0) {
1143                 g_source_remove(timer_id);
1144                 timer_id = 0;
1145         }
1146
1147         __bt_disconnect_all();
1148         ret = __bt_disable_cb();
1149
1150         BT_DBG("-");
1151         return ret;
1152 }
1153
1154 int _bt_recover_adapter(void)
1155 {
1156         BT_DBG("+");
1157         DBusGProxy *proxy;
1158
1159         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1160                 BT_DBG("Disabling in progress");
1161                 return BLUETOOTH_ERROR_IN_PROGRESS;
1162         }
1163
1164         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1165                 BT_DBG("Already disabled");
1166                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1167         }
1168
1169         _bt_adapter_set_status(BT_DEACTIVATING);
1170
1171         proxy = __bt_get_core_proxy();
1172         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1173
1174         if (dbus_g_proxy_call(proxy, "RecoverAdapter", NULL,
1175                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1176                 BT_ERR("Bt core call failed");
1177                 return BLUETOOTH_ERROR_INTERNAL;
1178         }
1179
1180         __bt_disconnect_all();
1181
1182         BT_ERR("-");
1183         return BLUETOOTH_ERROR_NONE;
1184 }
1185
1186 int _bt_reset_adapter(void)
1187 {
1188         DBusGProxy *proxy;
1189
1190         BT_DBG("");
1191
1192         proxy = __bt_get_core_proxy();
1193         if (!proxy)
1194                 return BLUETOOTH_ERROR_INTERNAL;
1195
1196         if (dbus_g_proxy_call(proxy, "ResetAdapter", NULL,
1197                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1198                 BT_ERR("Bt core call failed");
1199                 return BLUETOOTH_ERROR_INTERNAL;
1200         }
1201
1202         /* Terminate myself */
1203         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1204                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1205         }
1206
1207         return BLUETOOTH_ERROR_NONE;
1208 }
1209
1210 int _bt_check_adapter(int *status)
1211 {
1212
1213         char *adapter_path = NULL;
1214
1215         BT_CHECK_PARAMETER(status, return);
1216
1217         *status = BT_ADAPTER_DISABLED;
1218
1219         adapter_path = _bt_get_adapter_path();
1220
1221
1222         if (adapter_path != NULL)
1223                 *status = BT_ADAPTER_ENABLED;
1224
1225         g_free(adapter_path);
1226         return BLUETOOTH_ERROR_NONE;
1227 }
1228
1229 int _bt_enable_adapter_le(void)
1230 {
1231         BT_DBG("+");
1232         DBusGProxy *proxy;
1233         GError *err = NULL;
1234         bt_status_t status = _bt_adapter_get_status();
1235         bt_le_status_t le_status = _bt_adapter_get_le_status();
1236
1237         if (le_status == BT_LE_ACTIVATING) {
1238                 BT_ERR("Enabling in progress");
1239                 return BLUETOOTH_ERROR_IN_PROGRESS;
1240         }
1241
1242         if (le_status == BT_LE_ACTIVATED) {
1243                 BT_ERR("Already enabled");
1244                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1245         }
1246
1247         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1248                 BT_ERR("Disabling in progress");
1249                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1250         }
1251
1252         _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1253
1254         proxy = __bt_get_core_proxy();
1255         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1256
1257         if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapterLe",
1258                                 BT_ENABLE_TIMEOUT, &err,
1259                                 G_TYPE_INVALID,
1260                                 G_TYPE_INVALID) == FALSE) {
1261
1262                 _bt_adapter_set_le_status(BT_DEACTIVATED);
1263
1264                 if (err != NULL) {
1265                         BT_ERR("Bt core call failed: [%s]", err->message);
1266                         g_error_free(err);
1267                 }
1268
1269                 /* Clean up the process */
1270                 if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
1271                                         G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1272                         BT_ERR("Bt core call failed");
1273                 }
1274
1275                 /* Display notification */
1276                 notification_status_message_post(BT_STR_NOT_SUPPORT);
1277
1278                 /* Terminate myself */
1279                 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1280                         g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1281                 return BLUETOOTH_ERROR_INTERNAL;
1282         }
1283
1284         _bt_adapter_start_le_enable_timer();
1285
1286         if (status == BT_ACTIVATED) {
1287                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1288                 __bt_set_le_enabled();
1289         }
1290         BT_DBG("le status : %d", _bt_adapter_get_le_status());
1291         BT_DBG("-");
1292         return BLUETOOTH_ERROR_NONE;
1293 }
1294
1295 int _bt_disable_adapter_le(void)
1296 {
1297         BT_DBG("+");
1298         DBusGProxy *proxy;
1299         bt_le_status_t bt_le_state;
1300
1301         bt_le_state = _bt_adapter_get_le_status();
1302         if (bt_le_state == BT_LE_DEACTIVATING) {
1303                 BT_DBG("Disabling in progress");
1304                 return BLUETOOTH_ERROR_IN_PROGRESS;
1305         }
1306
1307         if (bt_le_state == BT_LE_DEACTIVATED) {
1308                 BT_DBG("Already disabled");
1309                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1310         }
1311
1312         _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1313
1314         proxy = __bt_get_core_proxy();
1315         if (!proxy)
1316                 return BLUETOOTH_ERROR_INTERNAL;
1317
1318         if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
1319                                        G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1320                 BT_ERR("Bt core call failed");
1321                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1322                 return BLUETOOTH_ERROR_INTERNAL;
1323        }
1324
1325         _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1326         BT_DBG("le status : %d", _bt_adapter_get_le_status());
1327         BT_DBG("-");
1328         return BLUETOOTH_ERROR_NONE;
1329 }
1330
1331 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1332 {
1333
1334         DBusGProxy *proxy;
1335         GError *err = NULL;
1336         char *address;
1337         GValue address_v = { 0 };
1338
1339         BT_CHECK_PARAMETER(local_address, return);
1340
1341         proxy = _bt_get_adapter_properties_proxy();
1342         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1343
1344         if (!dbus_g_proxy_call(proxy, "Get", &err,
1345                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1346                         G_TYPE_STRING, "Address",
1347                         G_TYPE_INVALID,
1348                         G_TYPE_VALUE, &address_v,
1349                         G_TYPE_INVALID)) {
1350                 if (err != NULL) {
1351                         BT_ERR("Getting property failed: [%s]\n", err->message);
1352                         g_error_free(err);
1353                 }
1354                 return BLUETOOTH_ERROR_INTERNAL;
1355         }
1356
1357         address = (char *)g_value_get_string(&address_v);
1358
1359         if (address) {
1360                 _bt_convert_addr_string_to_type(local_address->addr, address);
1361         } else {
1362                 return BLUETOOTH_ERROR_INTERNAL;
1363         }
1364
1365         return BLUETOOTH_ERROR_NONE;
1366 }
1367
1368 int _bt_get_local_version(bluetooth_version_t *local_version)
1369 {
1370         DBusGProxy *proxy;
1371         GHashTable *hash = NULL;
1372         char *ver = NULL;
1373         char *ptr = NULL;
1374         int ret = BLUETOOTH_ERROR_NONE;
1375
1376         BT_CHECK_PARAMETER(local_version, return);
1377
1378         GError *err = NULL;
1379         GValue version_v = { 0 };
1380
1381         proxy = _bt_get_adapter_properties_proxy();
1382         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1383
1384         if (!dbus_g_proxy_call(proxy, "Get", &err,
1385                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1386                         G_TYPE_STRING, "Version",
1387                         G_TYPE_INVALID,
1388                         G_TYPE_VALUE, &version_v,
1389                         G_TYPE_INVALID)) {
1390                 if (err != NULL) {
1391                         BT_ERR("Getting property failed: [%s]\n", err->message);
1392                         g_error_free(err);
1393                 }
1394                 return BLUETOOTH_ERROR_INTERNAL;
1395         }
1396
1397         ver = (char *)g_value_get_string(&version_v);
1398
1399
1400         if (ver && (strlen(ver) > 0)) {
1401                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1402                 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1403                         *ptr = '\0';
1404
1405                 g_strlcpy(local_version->version, ver,
1406                                 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1407
1408         } else {
1409                 ret = BLUETOOTH_ERROR_INTERNAL;
1410         }
1411
1412         g_hash_table_destroy(hash);
1413         return ret;
1414 }
1415
1416 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1417 {
1418         DBusGProxy *proxy;
1419         GHashTable *hash = NULL;
1420         char *name = NULL;
1421         char *ptr = NULL;
1422         int ret = BLUETOOTH_ERROR_NONE;
1423
1424         GError *err = NULL;
1425         GValue name_v = { 0 };
1426
1427         BT_CHECK_PARAMETER(local_name, return);
1428
1429         proxy = _bt_get_adapter_properties_proxy();
1430         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1431
1432         if (!dbus_g_proxy_call(proxy, "Get", &err,
1433                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1434                         G_TYPE_STRING, "Alias",
1435                         G_TYPE_INVALID,
1436                         G_TYPE_VALUE, &name_v,
1437                         G_TYPE_INVALID)) {
1438                 if (err != NULL) {
1439                         BT_ERR("Getting property failed: [%s]\n", err->message);
1440                         g_error_free(err);
1441                 }
1442                 return BLUETOOTH_ERROR_INTERNAL;
1443         }
1444
1445         name = (char *)g_value_get_string(&name_v);
1446
1447         if (name && (strlen(name) > 0)) {
1448                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1449                 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1450                         *ptr = '\0';
1451
1452                 g_strlcpy(local_name->name, name,
1453                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1454         } else {
1455                 ret = BLUETOOTH_ERROR_INTERNAL;
1456         }
1457
1458         g_hash_table_destroy(hash);
1459         return ret;
1460 }
1461
1462 int _bt_set_local_name(char *local_name)
1463 {
1464         GValue name = { 0 };
1465         DBusGProxy *proxy;
1466         GError *error = NULL;
1467         char *ptr = NULL;
1468
1469         BT_CHECK_PARAMETER(local_name, return);
1470
1471         proxy = _bt_get_adapter_properties_proxy();
1472
1473         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1474
1475         if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1476                 *ptr = '\0';
1477
1478         g_value_init(&name, G_TYPE_STRING);
1479         g_value_set_string(&name, local_name);
1480
1481         dbus_g_proxy_call(proxy, "Set", &error,
1482                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1483                         G_TYPE_STRING, "Alias",
1484                         G_TYPE_VALUE, &name,
1485                         G_TYPE_INVALID, G_TYPE_INVALID);
1486
1487         g_value_unset(&name);
1488
1489         if (error) {
1490                 BT_ERR("SetProperty Fail: %s", error->message);
1491                 g_error_free(error);
1492                 return BLUETOOTH_ERROR_INTERNAL;
1493         }
1494
1495         return BLUETOOTH_ERROR_NONE;
1496 }
1497
1498 int _bt_is_service_used(char *service_uuid, gboolean *used)
1499 {
1500         char **uuids;
1501         int i;
1502         DBusGProxy *proxy;
1503         GError *err = NULL;
1504         GValue uuids_v = { 0 };
1505         int ret = BLUETOOTH_ERROR_NONE;
1506
1507         BT_DBG("+");
1508         BT_CHECK_PARAMETER(service_uuid, return);
1509         BT_CHECK_PARAMETER(used, return);
1510
1511         proxy = _bt_get_adapter_properties_proxy();
1512         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1513
1514         if (!dbus_g_proxy_call(proxy, "Get", &err,
1515                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1516                         G_TYPE_STRING, "UUIDs",
1517                         G_TYPE_INVALID,
1518                         G_TYPE_VALUE, &uuids_v,
1519                         G_TYPE_INVALID)) {
1520                 if (err != NULL) {
1521                         BT_ERR("Getting property failed: [%s]\n", err->message);
1522                         g_error_free(err);
1523                 }
1524                 return BLUETOOTH_ERROR_INTERNAL;
1525         }
1526
1527         uuids = g_value_get_boxed(&uuids_v);
1528
1529         if (uuids == NULL) {
1530                 /* Normal case */
1531                 *used = FALSE;
1532                 goto done;
1533         }
1534
1535         for (i = 0; uuids[i] != NULL; i++) {
1536                 if (strcasecmp(uuids[i], service_uuid) == 0) {
1537                         *used = TRUE;
1538                         goto done;
1539                 }
1540         }
1541
1542         *used = FALSE;
1543 done:
1544         BT_DBG("Service Used? %d", *used);
1545         return ret;
1546 }
1547
1548
1549 static gboolean __bt_get_discoverable_property(void)
1550 {
1551         DBusGProxy *proxy;
1552         GValue discoverable_v = { 0 };
1553         GError *err = NULL;
1554
1555         proxy = _bt_get_adapter_properties_proxy();
1556         retv_if(proxy == NULL, FALSE);
1557
1558         if (!dbus_g_proxy_call(proxy, "Get", &err,
1559                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1560                         G_TYPE_STRING, "Discoverable",
1561                         G_TYPE_INVALID,
1562                         G_TYPE_VALUE, &discoverable_v,
1563                         G_TYPE_INVALID)) {
1564                 if (err != NULL) {
1565                         BT_ERR("Getting property failed: [%s]\n", err->message);
1566                         g_error_free(err);
1567                 }
1568                 return FALSE;
1569         }
1570
1571         return g_value_get_boolean(&discoverable_v);
1572 }
1573
1574 int _bt_get_discoverable_mode(int *mode)
1575 {
1576         gboolean discoverable;
1577         unsigned int timeout;
1578
1579         BT_CHECK_PARAMETER(mode, return);
1580
1581         discoverable = __bt_get_discoverable_property();
1582         timeout = _bt_get_discoverable_timeout_property();
1583
1584         if (discoverable == TRUE) {
1585                 if (timeout == 0)
1586                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1587                 else
1588                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1589         } else {
1590                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1591         }
1592         return BLUETOOTH_ERROR_NONE;
1593 }
1594
1595
1596 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1597 {
1598         int ret = BLUETOOTH_ERROR_NONE;
1599         gboolean inq_scan;
1600         gboolean pg_scan;
1601         GError *error = NULL;
1602         GValue connectable = { 0 };
1603         GValue discoverable = { 0 };
1604         GValue val_timeout = { 0 };
1605         DBusGProxy *proxy;
1606
1607         proxy = _bt_get_adapter_properties_proxy();
1608
1609         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1610
1611         g_value_init(&connectable, G_TYPE_BOOLEAN);
1612         g_value_init(&discoverable, G_TYPE_BOOLEAN);
1613         g_value_init(&val_timeout, G_TYPE_UINT);
1614
1615         switch (discoverable_mode) {
1616         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1617                 pg_scan = TRUE;
1618                 inq_scan = FALSE;
1619                 timeout = 0;
1620                 break;
1621         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1622                 pg_scan = TRUE;
1623                 inq_scan = TRUE;
1624                 timeout = 0;
1625                 break;
1626         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1627                 inq_scan = TRUE;
1628                 pg_scan = TRUE;
1629                 break;
1630         default:
1631                 return BLUETOOTH_ERROR_INVALID_PARAM;
1632         }
1633
1634         BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1635                         discoverable_mode, timeout);
1636
1637         g_value_set_boolean(&connectable, pg_scan);
1638         g_value_set_boolean(&discoverable, inq_scan);
1639         g_value_set_uint(&val_timeout, timeout);
1640
1641         dbus_g_proxy_call(proxy, "Set", &error,
1642                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1643                                 G_TYPE_STRING, "Connectable",
1644                                 G_TYPE_VALUE, &connectable,
1645                                 G_TYPE_INVALID, G_TYPE_INVALID);
1646
1647         if (error != NULL) {
1648                 BT_ERR("Connectable set err:[%s]", error->message);
1649                 g_error_free(error);
1650                 ret = BLUETOOTH_ERROR_INTERNAL;
1651                 goto done;
1652         }
1653
1654         dbus_g_proxy_call(proxy, "Set", &error,
1655                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1656                                 G_TYPE_STRING, "Discoverable",
1657                                 G_TYPE_VALUE, &discoverable,
1658                                 G_TYPE_INVALID, G_TYPE_INVALID);
1659
1660
1661         if (error != NULL) {
1662                 BT_ERR("Discoverable set err:[%s]", error->message);
1663                 g_error_free(error);
1664                 ret = BLUETOOTH_ERROR_INTERNAL;
1665                 goto done;
1666         }
1667
1668         dbus_g_proxy_call(proxy, "Set", &error,
1669                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1670                                 G_TYPE_STRING, "DiscoverableTimeout",
1671                                 G_TYPE_VALUE, &val_timeout,
1672                                 G_TYPE_INVALID, G_TYPE_INVALID);
1673
1674         if (error != NULL) {
1675                 BT_ERR("Timeout set err:[%s]", error->message);
1676                 g_error_free(error);
1677                 ret = BLUETOOTH_ERROR_INTERNAL;
1678                 goto done;
1679         }
1680
1681         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1682                 timeout = -1;
1683
1684         ret = __bt_set_visible_time(timeout);
1685
1686 done:
1687         g_value_unset(&val_timeout);
1688         g_value_unset(&connectable);
1689         g_value_unset(&discoverable);
1690
1691         return ret;
1692 }
1693
1694 int _bt_start_discovery(void)
1695 {
1696         DBusGProxy *proxy;
1697         GError *err = NULL;
1698
1699         if (_bt_is_discovering() == TRUE) {
1700                 BT_ERR("BT is already in discovering");
1701                 return BLUETOOTH_ERROR_IN_PROGRESS;
1702         } else if (_bt_is_device_creating() == TRUE) {
1703                 BT_ERR("Bonding device is going on");
1704                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1705         }
1706
1707         proxy = _bt_get_adapter_proxy();
1708         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1709
1710         if (!dbus_g_proxy_call(proxy, "StartDiscovery", &err,
1711                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1712                 if (err != NULL) {
1713                         BT_ERR("StartDiscovery failed: [%s]\n", err->message);
1714                         g_error_free(err);
1715                 }
1716                 BT_ERR("Discover start failed");
1717                 return BLUETOOTH_ERROR_INTERNAL;
1718         }
1719
1720         is_discovering = TRUE;
1721         cancel_by_user = FALSE;
1722         /* discovery status will be change in event */
1723
1724         return BLUETOOTH_ERROR_NONE;
1725 }
1726
1727 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
1728 {
1729         DBusGProxy *proxy;
1730
1731         const gchar *disc_type;
1732
1733         if (_bt_is_discovering() == TRUE) {
1734                 BT_ERR("BT is already in discovering");
1735                 return BLUETOOTH_ERROR_IN_PROGRESS;
1736         }
1737
1738         proxy = _bt_get_adapter_proxy();
1739         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1740
1741         if (role == DISCOVERY_ROLE_BREDR)
1742                 disc_type = "BREDR";
1743         else if (role == DISCOVERY_ROLE_LE)
1744                 disc_type = "LE";
1745         else if (role == DISCOVERY_ROLE_LE_BREDR)
1746                 disc_type = "LE_BREDR";
1747         else
1748                 return BLUETOOTH_ERROR_INVALID_PARAM;
1749
1750         if (!dbus_g_proxy_call(proxy, "StartCustomDiscovery", NULL,
1751                          G_TYPE_STRING, disc_type,
1752                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1753                 BT_ERR("StartCustomDiscovery failed");
1754                 return BLUETOOTH_ERROR_INTERNAL;
1755         }
1756
1757         is_discovering = TRUE;
1758         cancel_by_user = FALSE;
1759         /* discovery status will be change in event */
1760
1761         return BLUETOOTH_ERROR_NONE;
1762 }
1763
1764 int _bt_cancel_discovery(void)
1765 {
1766         DBusGProxy *proxy;
1767         GError *err = NULL;
1768
1769         if (_bt_is_discovering() == FALSE) {
1770                 BT_ERR("BT is not in discovering");
1771                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1772         }
1773
1774         proxy = _bt_get_adapter_proxy();
1775         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1776
1777         if (!dbus_g_proxy_call(proxy, "StopDiscovery", &err,
1778                                G_TYPE_INVALID, G_TYPE_INVALID)) {
1779                 if (err != NULL) {
1780                         BT_ERR("StopDiscovery failed: [%s]\n", err->message);
1781                         g_error_free(err);
1782                 }
1783                 return BLUETOOTH_ERROR_INTERNAL;
1784         }
1785
1786         cancel_by_user = TRUE;
1787         /* discovery status will be change in event */
1788
1789         return BLUETOOTH_ERROR_NONE;
1790 }
1791
1792 int _bt_start_le_discovery(void)
1793 {
1794    DBusGProxy *proxy;
1795
1796    if (_bt_is_le_discovering() == TRUE) {
1797        BT_ERR("BT is already in LE discovering");
1798        return BLUETOOTH_ERROR_IN_PROGRESS;
1799    }
1800
1801    proxy = _bt_get_adapter_proxy();
1802    retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1803
1804    if (!dbus_g_proxy_call(proxy, "StartLEDiscovery", NULL,
1805                   G_TYPE_INVALID, G_TYPE_INVALID)) {
1806        BT_ERR("LE Discover start failed");
1807        return BLUETOOTH_ERROR_INTERNAL;
1808    }
1809
1810    is_le_discovering = TRUE;
1811
1812    return BLUETOOTH_ERROR_NONE;
1813 }
1814
1815 int _bt_stop_le_discovery(void)
1816 {
1817    DBusGProxy *proxy;
1818
1819    if (_bt_is_le_discovering() == FALSE) {
1820        BT_ERR("BT is not in LE discovering");
1821        return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1822    }
1823
1824    proxy = _bt_get_adapter_proxy();
1825    retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1826
1827    if (!dbus_g_proxy_call(proxy, "StopLEDiscovery", NULL,
1828                   G_TYPE_INVALID, G_TYPE_INVALID)) {
1829        BT_ERR("LE Discover stop failed");
1830        return BLUETOOTH_ERROR_INTERNAL;
1831    }
1832
1833    return BLUETOOTH_ERROR_NONE;
1834 }
1835
1836 gboolean _bt_is_discovering(void)
1837 {
1838         return is_discovering;
1839 }
1840
1841 gboolean _bt_is_le_discovering(void)
1842 {
1843    return is_le_discovering;
1844 }
1845
1846 gboolean _bt_is_connectable(void)
1847 {
1848         DBusGProxy *proxy;
1849         GValue connectable_v = { 0 };
1850         GError *err = NULL;
1851         gboolean is_connectable = FALSE;
1852
1853         proxy = _bt_get_adapter_properties_proxy();
1854         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1855
1856         if (!dbus_g_proxy_call(proxy, "Get", &err,
1857                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1858                         G_TYPE_STRING, "Connectable",
1859                         G_TYPE_INVALID,
1860                         G_TYPE_VALUE, &connectable_v,
1861                         G_TYPE_INVALID)) {
1862                 if (err != NULL) {
1863                         BT_ERR("Getting property failed: [%s]\n", err->message);
1864                         g_error_free(err);
1865                 }
1866                 return BLUETOOTH_ERROR_INTERNAL;
1867         }
1868
1869         is_connectable = g_value_get_boolean(&connectable_v);
1870         BT_INFO("Get connectable [%d]", is_connectable);
1871
1872         return is_connectable;
1873 }
1874
1875 int _bt_set_connectable(gboolean is_connectable)
1876 {
1877         DBusGProxy *proxy;
1878         GValue connectable = { 0 };
1879         GError *error = NULL;
1880
1881         if (__bt_is_factory_test_mode()) {
1882                 BT_ERR("Unable to set connectable in factory binary !!");
1883                 return BLUETOOTH_ERROR_NOT_SUPPORT;
1884         }
1885
1886         proxy = _bt_get_adapter_properties_proxy();
1887
1888         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1889
1890         g_value_init(&connectable, G_TYPE_BOOLEAN);
1891         g_value_set_boolean(&connectable, is_connectable);
1892
1893         dbus_g_proxy_call(proxy, "Set", &error,
1894                                 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1895                                 G_TYPE_STRING, "Connectable",
1896                                 G_TYPE_VALUE, &connectable,
1897                                 G_TYPE_INVALID, G_TYPE_INVALID);
1898
1899         g_value_unset(&connectable);
1900         if (error != NULL) {
1901                 BT_ERR("Connectable set err:[%s]", error->message);
1902                 g_error_free(error);
1903                 return BLUETOOTH_ERROR_INTERNAL;
1904         }
1905
1906         BT_INFO("Set connectable [%d]", is_connectable);
1907         return BLUETOOTH_ERROR_NONE;
1908 }
1909
1910 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
1911 {
1912
1913         DBusGProxy *proxy;
1914         GValue discovering_v = { 0 };
1915         GError *err = NULL;
1916         char *discovering_type =  NULL;
1917
1918         proxy = _bt_get_adapter_properties_proxy();
1919         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1920
1921         if (discovery_type == DISCOVERY_ROLE_BREDR)
1922                 discovering_type = "Discovering";
1923         else if (discovery_type == DISCOVERY_ROLE_LE)
1924                 discovering_type = "LEDiscovering";
1925
1926         if (!dbus_g_proxy_call(proxy, "Get", &err,
1927                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1928                         G_TYPE_STRING, discovering_type,
1929                         G_TYPE_INVALID,
1930                         G_TYPE_VALUE, &discovering_v,
1931                         G_TYPE_INVALID)) {
1932                 if (err != NULL) {
1933                         BT_ERR("Getting property failed: [%s]\n", err->message);
1934                         g_error_free(err);
1935                 }
1936                 return BLUETOOTH_ERROR_INTERNAL;
1937         }
1938
1939         return g_value_get_boolean(&discovering_v);
1940
1941 }
1942
1943 unsigned int _bt_get_discoverable_timeout_property(void)
1944 {
1945         DBusGProxy *proxy;
1946         GValue timeout_v = { 0 };
1947         GError *err = NULL;
1948
1949         proxy = _bt_get_adapter_properties_proxy();
1950         retv_if(proxy == NULL, 0);
1951
1952         if (!dbus_g_proxy_call(proxy, "Get", &err,
1953                         G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1954                         G_TYPE_STRING, "DiscoverableTimeout",
1955                         G_TYPE_INVALID,
1956                         G_TYPE_VALUE, &timeout_v,
1957                         G_TYPE_INVALID)) {
1958                 if (err != NULL) {
1959                         BT_ERR("Getting property failed: [%s]\n", err->message);
1960                         g_error_free(err);
1961                 }
1962                 return 0;
1963         }
1964
1965         return g_value_get_uint(&timeout_v);
1966 }
1967
1968 static bluetooth_device_info_t *__bt_parse_device_info(DBusMessageIter *item_iter)
1969 {
1970         DBusMessageIter value_iter;
1971         bluetooth_device_info_t *dev_info;
1972
1973         dbus_message_iter_recurse(item_iter, &value_iter);
1974
1975         if (dbus_message_iter_get_arg_type(&value_iter) != DBUS_TYPE_DICT_ENTRY) {
1976                 BT_DBG("No entry");
1977                 return NULL;
1978         }
1979
1980         dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
1981
1982         while (dbus_message_iter_get_arg_type(&value_iter) ==
1983                                                 DBUS_TYPE_DICT_ENTRY) {
1984                 char *value = NULL;
1985                 char *key;
1986                 DBusMessageIter dict_entry;
1987                 DBusMessageIter iter_dict_val;
1988
1989                 dbus_message_iter_recurse(&value_iter, &dict_entry);
1990
1991                 dbus_message_iter_get_basic(&dict_entry, &key);
1992
1993                 if (key == NULL) {
1994                         dbus_message_iter_next(&value_iter);
1995                         continue;
1996                 }
1997
1998                 if (!dbus_message_iter_next(&dict_entry)) {
1999                         dbus_message_iter_next(&value_iter);
2000                         continue;
2001                 }
2002                 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
2003
2004                 if (strcasecmp(key, "Address") == 0) {
2005                         const char *address = NULL;
2006                         dbus_message_iter_get_basic(&iter_dict_val, &address);
2007                         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2008                                                         address);
2009
2010                 } else if (strcasecmp(key, "Class") == 0) {
2011                         unsigned int cod;
2012                         dbus_message_iter_get_basic(&iter_dict_val, &cod);
2013                         _bt_divide_device_class(&dev_info->device_class, cod);
2014                 } else if (strcasecmp(key, "Name") == 0) {
2015                         dbus_message_iter_get_basic(&iter_dict_val, &value);
2016
2017                         /* If there is no Alias */
2018                         if (strlen(dev_info->device_name.name) == 0) {
2019                                 g_strlcpy(dev_info->device_name.name, value,
2020                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2021                         }
2022                 } else if (strcasecmp(key, "Alias") == 0) {
2023                         dbus_message_iter_get_basic(&iter_dict_val, &value);
2024
2025                         /* Overwrite the name */
2026                         if (value) {
2027                                 memset(dev_info->device_name.name, 0x00,
2028                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2029                                 g_strlcpy(dev_info->device_name.name, value,
2030                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2031                         }
2032                 } else if (strcasecmp(key, "Connected") == 0) {
2033                         dbus_message_iter_get_basic(&iter_dict_val,
2034                                                 &dev_info->connected);
2035                 } else if (strcasecmp(key, "Paired") == 0) {
2036                         dbus_message_iter_get_basic(&iter_dict_val,
2037                                                 &dev_info->paired);
2038                 } else if (strcasecmp(key, "Trusted") == 0) {
2039                         dbus_message_iter_get_basic(&iter_dict_val,
2040                                                 &dev_info->trust);
2041                 } else if (strcasecmp(key, "RSSI") == 0) {
2042                         dbus_message_iter_get_basic(&iter_dict_val,
2043                                                 &dev_info->rssi);
2044                 } else if (strcasecmp(key, "UUIDs") == 0) {
2045                         DBusMessageIter uuid_iter;
2046                         char **parts;
2047                         int i = 0;
2048
2049                         dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
2050
2051                         while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
2052                                 dbus_message_iter_get_basic(&uuid_iter,
2053                                                         &value);
2054
2055                                 g_strlcpy(dev_info->uuids[i], value,
2056                                                 BLUETOOTH_UUID_STRING_MAX);
2057
2058                                 parts = g_strsplit(value, "-", -1);
2059
2060                                 if (parts == NULL || parts[0] == NULL)
2061                                         break;
2062
2063                                 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2064                                 g_strfreev(parts);
2065
2066                                 i++;
2067                                 if (!dbus_message_iter_next(&uuid_iter)) {
2068                                         break;
2069                                 }
2070                         }
2071
2072                         dev_info->service_index = i;
2073                 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2074                         dbus_message_iter_get_basic(&iter_dict_val,
2075                                                                 &dev_info->manufacturer_data.data_len);
2076                 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2077                         DBusMessageIter manufacturer_iter;
2078                         int i = 0;
2079                         char byte = 0;
2080
2081                         dbus_message_iter_recurse(&iter_dict_val, &manufacturer_iter);
2082
2083                         while (dbus_message_iter_get_arg_type(&manufacturer_iter) == DBUS_TYPE_BYTE) {
2084                                 dbus_message_iter_get_basic(&manufacturer_iter, &byte);
2085                                 dev_info->manufacturer_data.data[i] = byte;
2086                                 i++;
2087                                 dbus_message_iter_next(&manufacturer_iter);
2088                         }
2089                 }
2090
2091                 dbus_message_iter_next(&value_iter);
2092         }
2093
2094         return dev_info;
2095 }
2096
2097 static void __bt_extract_device_info(DBusMessageIter *msg_iter,
2098                                                         GArray **dev_list)
2099 {
2100         bluetooth_device_info_t *dev_info = NULL;
2101         char *object_path = NULL;
2102         DBusMessageIter value_iter;
2103
2104         /* Parse the signature:  oa{sa{sv}}} */
2105         ret_if(dbus_message_iter_get_arg_type(msg_iter) !=
2106                                 DBUS_TYPE_OBJECT_PATH);
2107
2108         dbus_message_iter_get_basic(msg_iter, &object_path);
2109         ret_if(object_path == NULL);
2110
2111         /* object array (oa) */
2112         ret_if(dbus_message_iter_next(msg_iter) == FALSE);
2113         ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY);
2114
2115         dbus_message_iter_recurse(msg_iter, &value_iter);
2116
2117         /* string array (sa) */
2118         while (dbus_message_iter_get_arg_type(&value_iter) ==
2119                                         DBUS_TYPE_DICT_ENTRY) {
2120                 char *interface_name = NULL;
2121                 DBusMessageIter interface_iter;
2122
2123                 dbus_message_iter_recurse(&value_iter, &interface_iter);
2124
2125                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
2126                                                         DBUS_TYPE_STRING);
2127
2128                 dbus_message_iter_get_basic(&interface_iter, &interface_name);
2129
2130                 ret_if(dbus_message_iter_next(&interface_iter) == FALSE);
2131
2132                 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
2133                                                         DBUS_TYPE_ARRAY);
2134
2135                 if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) {
2136                         BT_DBG("Found a device: %s", object_path);
2137                         dev_info = __bt_parse_device_info(&interface_iter);
2138
2139                         if (dev_info) {
2140                                 if (dev_info->paired == FALSE)
2141                                         goto not_paired;
2142
2143                                 g_array_append_vals(*dev_list, dev_info,
2144                                                 sizeof(bluetooth_device_info_t));
2145
2146                                 g_free(dev_info);
2147                         }
2148
2149                         return;
2150                 }
2151
2152                 dbus_message_iter_next(&value_iter);
2153         }
2154
2155         BT_DBG("There is no device interface");
2156
2157 not_paired:
2158         BT_DBG("Not paired");
2159         g_free(dev_info);
2160 }
2161
2162 int _bt_get_bonded_devices(GArray **dev_list)
2163 {
2164         BT_DBG("+");
2165         DBusMessage *msg;
2166         DBusMessage *reply;
2167         DBusMessageIter reply_iter;
2168         DBusMessageIter value_iter;
2169         DBusError err;
2170         DBusConnection *conn;
2171
2172         conn = _bt_get_system_conn();
2173         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2174
2175         msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
2176                                                 BT_MANAGER_INTERFACE,
2177                                                 "GetManagedObjects");
2178
2179         retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
2180
2181         /* Synchronous call */
2182         dbus_error_init(&err);
2183         reply = dbus_connection_send_with_reply_and_block(
2184                                         conn, msg,
2185                                         -1, &err);
2186         dbus_message_unref(msg);
2187
2188         if (!reply) {
2189                 BT_ERR("Can't get managed objects");
2190
2191                 if (dbus_error_is_set(&err)) {
2192                         BT_ERR("%s", err.message);
2193                         dbus_error_free(&err);
2194                 }
2195                 return BLUETOOTH_ERROR_INTERNAL;
2196         }
2197
2198         if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
2199                 BT_ERR("Fail to iterate the reply");
2200                 dbus_message_unref(reply);
2201                 return BLUETOOTH_ERROR_INTERNAL;
2202         }
2203
2204         dbus_message_iter_recurse(&reply_iter, &value_iter);
2205
2206         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
2207         while (dbus_message_iter_get_arg_type(&value_iter) ==
2208                                                 DBUS_TYPE_DICT_ENTRY) {
2209                 DBusMessageIter msg_iter;
2210
2211                 dbus_message_iter_recurse(&value_iter, &msg_iter);
2212
2213                 __bt_extract_device_info(&msg_iter, dev_list);
2214
2215                 dbus_message_iter_next(&value_iter);
2216         }
2217         dbus_message_unref(reply);
2218         BT_DBG("-");
2219         return BLUETOOTH_ERROR_NONE;
2220 }
2221
2222 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2223                                 bluetooth_device_info_t *dev_info)
2224 {
2225         char *object_path = NULL;
2226         DBusGProxy *adapter_proxy;
2227         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2228         int ret = BLUETOOTH_ERROR_NONE;
2229
2230         BT_CHECK_PARAMETER(device_address, return);
2231         BT_CHECK_PARAMETER(dev_info, return);
2232
2233         adapter_proxy = _bt_get_adapter_proxy();
2234         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2235
2236         _bt_convert_addr_type_to_string(address, device_address->addr);
2237
2238         object_path = _bt_get_device_object_path(address);
2239
2240         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2241
2242         ret = __bt_get_bonded_device_info(object_path, dev_info);
2243         g_free(object_path);
2244
2245         return ret;
2246 }
2247
2248 int _bt_get_timeout_value(int *timeout)
2249 {
2250         time_t current_time;
2251         int time_diff;
2252
2253         /* Take current time */
2254         time(&current_time);
2255         time_diff = difftime(current_time, visible_timer.start_time);
2256
2257         BT_DBG("Time diff = %d\n", time_diff);
2258
2259         *timeout = visible_timer.timeout - time_diff;
2260
2261         return BLUETOOTH_ERROR_NONE;
2262 }
2263
2264 int _bt_set_le_privacy(gboolean set_privacy)
2265 {
2266         DBusGProxy *proxy;
2267         GError *error = NULL;
2268         int ret = BLUETOOTH_ERROR_NONE;
2269
2270         if (__bt_is_factory_test_mode()) {
2271                 BT_ERR("Unable to set le privacy in factory binary !!");
2272                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2273         }
2274
2275         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2276                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2277                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2278         }
2279
2280         proxy = _bt_get_adapter_proxy();
2281         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2282
2283         dbus_g_proxy_call(proxy, "SetLePrivacy", &error,
2284                                    G_TYPE_BOOLEAN, set_privacy,
2285                                    G_TYPE_INVALID, G_TYPE_INVALID);
2286
2287         if (error) {
2288                 BT_ERR("SetLePrivacy Failed :[%s]", error->message);
2289                 if (g_strrstr(error->message, BT_SERVICE_ERR_MSG_NOT_SUPPORTED))
2290                         ret = BLUETOOTH_ERROR_NOT_SUPPORT;
2291                 else
2292                         ret = BLUETOOTH_ERROR_INTERNAL;
2293                 g_error_free(error);
2294                 return ret;
2295         }
2296
2297         BT_INFO("SetLePrivacy as %d", set_privacy);
2298
2299         return BLUETOOTH_ERROR_NONE;
2300 }
2301
2302 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2303 {
2304         DBusGProxy *proxy;
2305         GError *error = NULL;
2306         GArray *arr;
2307         int i;
2308
2309         BT_CHECK_PARAMETER(m_data, return);
2310
2311         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2312                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2313                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2314         }
2315
2316         proxy = _bt_get_adapter_proxy();
2317         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2318
2319         arr = g_array_new(TRUE, TRUE, sizeof(guint8));
2320
2321         for (i = 0; i < (m_data->data_len) + 2; i++)
2322                 g_array_append_vals(arr, &(m_data->data[i]), sizeof(guint8));
2323
2324         dbus_g_proxy_call(proxy, "SetManufacturerData", &error,
2325                         DBUS_TYPE_G_UCHAR_ARRAY, arr,
2326                         G_TYPE_INVALID, G_TYPE_INVALID);
2327
2328         g_array_free(arr, TRUE);
2329
2330         if (error) {
2331                 BT_ERR("SetManufacturerData Fail: %s", error->message);
2332                 g_error_free(error);
2333                 return BLUETOOTH_ERROR_INTERNAL;
2334         }
2335
2336         _bt_send_event(BT_ADAPTER_EVENT,
2337                         BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2338                         DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
2339                         &m_data, m_data->data_len,
2340                         DBUS_TYPE_INVALID);
2341
2342         BT_INFO("Set manufacturer data");
2343
2344         return BLUETOOTH_ERROR_NONE;
2345 }