DPM: Sync API return value with other bt-service modules.
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-adapter.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <stdio.h>
19 #include <gio/gio.h>
20 #include <glib.h>
21 #include <dlog.h>
22 #include <string.h>
23 #include <vconf.h>
24 #include <syspopup_caller.h>
25 #include <aul.h>
26 #include <dbus/dbus-glib.h>
27 #include <dbus/dbus.h>
28 #include <bundle.h>
29 #include <eventsystem.h>
30 #include <bundle_internal.h>
31
32 #include "alarm.h"
33 #include "bluetooth-api.h"
34 #include "bt-internal-types.h"
35 #include "bt-service-common.h"
36 #include "bt-service-event.h"
37 #include "bt-service-adapter.h"
38 #include "bt-service-util.h"
39 #include "bt-service-network.h"
40 #include "bt-service-obex-server.h"
41 #include "bt-service-opp-client.h"
42 #include "bt-service-agent.h"
43 #include "bt-service-main.h"
44 #include "bt-service-avrcp.h"
45 #include "bt-service-device.h"
46 #ifdef TIZEN_FEATURE_BT_DPM
47 #include "bt-service-dpm.h"
48 #endif
49
50 typedef struct {
51         guint event_id;
52         int timeout;
53         time_t start_time;
54         int alarm_id;
55 } bt_adapter_timer_t;
56
57 bt_adapter_timer_t visible_timer = {0, };
58
59 typedef struct {
60         alarm_id_t alarm_id;
61         bt_set_alarm_cb callback;
62         void *user_data;
63 } bt_service_alarm_t;
64
65 typedef struct {
66         gboolean is_alarm_initialized;
67         GList *g_alarm_list;
68 } bt_service_alarm_mgr_t;
69
70 static bt_service_alarm_mgr_t alarm_mgr = {0, };
71
72 static gboolean is_discovering;
73 static gboolean cancel_by_user;
74 static bt_status_t adapter_status = BT_DEACTIVATED;
75 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
76 static gboolean is_le_intended = FALSE;
77 static void *adapter_agent = NULL;
78 static GDBusProxy *core_proxy = NULL;
79 static guint timer_id = 0;
80 static guint le_timer_id = 0;
81 static gboolean is_recovery_mode;
82
83 static uint status_reg_id;
84
85 #define BT_CORE_NAME "org.projectx.bt_core"
86 #define BT_CORE_PATH "/org/projectx/bt_core"
87 #define BT_CORE_INTERFACE "org.projectx.btcore"
88
89 #define BT_DISABLE_TIME 500 /* 500 ms */
90
91 static int alarm_cb(alarm_id_t alarm_id, void* user_param);
92 static void alarm_data_free(void *data);
93
94 GDBusProxy *_bt_init_core_proxy(void)
95 {
96         GDBusProxy *proxy;
97         GDBusConnection *conn;
98
99         conn = _bt_gdbus_get_system_gconn();
100         if (!conn)
101                 return NULL;
102
103         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
104                                         NULL,
105                                         BT_CORE_NAME,
106                                         BT_CORE_PATH,
107                                         BT_CORE_INTERFACE,
108                                         NULL, NULL);
109
110         if (!proxy)
111                 return NULL;
112
113         core_proxy = proxy;
114
115         return proxy;
116 }
117
118 static GDBusProxy *__bt_get_core_proxy(void)
119 {
120         return (core_proxy) ? core_proxy : _bt_init_core_proxy();
121 }
122
123 static gboolean __bt_is_factory_test_mode(void)
124 {
125         int mode = 0;
126
127         if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
128                 BT_ERR("Get the DUT Mode fail");
129                 return TRUE;
130         }
131
132         if (mode != FALSE) {
133                 BT_INFO("DUT Test Mode !!");
134                 return TRUE;
135         }
136
137         return FALSE;
138 }
139
140 static gboolean __bt_timeout_handler(gpointer user_data)
141 {
142         int result = BLUETOOTH_ERROR_NONE;
143         time_t current_time;
144         int time_diff;
145
146         /* Take current time */
147         time(&current_time);
148         time_diff = difftime(current_time, visible_timer.start_time);
149
150         /* Send event to application */
151         _bt_send_event(BT_ADAPTER_EVENT,
152                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
153                         g_variant_new("(in)", result, time_diff));
154
155         if (visible_timer.timeout <= time_diff) {
156                 g_source_remove(visible_timer.event_id);
157                 visible_timer.event_id = 0;
158                 visible_timer.timeout = 0;
159
160 #ifndef TIZEN_PROFILE_WEARABLE
161                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
162                         BT_ERR("Set vconf failed\n");
163 #endif
164                 return FALSE;
165         }
166
167         return TRUE;
168 }
169
170 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
171 {
172
173         int result = BLUETOOTH_ERROR_NONE;
174         int timeout = 0;
175
176         if (alarm_id != visible_timer.alarm_id)
177                 return 0;
178
179         if (visible_timer.event_id) {
180                 _bt_send_event(BT_ADAPTER_EVENT,
181                                 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
182                                 g_variant_new("(in)", result, timeout));
183                 g_source_remove(visible_timer.event_id);
184                 visible_timer.event_id = 0;
185                 visible_timer.timeout = 0;
186
187 #ifndef TIZEN_PROFILE_WEARABLE
188                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
189                         BT_ERR("Set vconf failed\n");
190 #endif
191         }
192         /* Switch Off visibility in Bluez */
193         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
194         visible_timer.alarm_id = 0;
195         return 0;
196 }
197
198 static void __bt_visibility_alarm_remove()
199 {
200         if (visible_timer.event_id > 0) {
201                 g_source_remove(visible_timer.event_id);
202                 visible_timer.event_id = 0;
203         }
204
205         if (visible_timer.alarm_id > 0) {
206                 _bt_service_remove_alarm(visible_timer.alarm_id);
207                 visible_timer.alarm_id = 0;
208         }
209 }
210
211 int __bt_set_visible_time(int timeout)
212 {
213         int result;
214         alarm_id_t alarm_id;
215 #ifndef TIZEN_PROFILE_WEARABLE
216 #ifdef TIZEN_FEATURE_BT_DPM
217         int discoverable_state = DPM_BT_ERROR;
218 #endif
219 #endif
220
221         __bt_visibility_alarm_remove();
222
223         visible_timer.timeout = timeout;
224
225 #ifndef TIZEN_PROFILE_WEARABLE
226 #ifdef TIZEN_FEATURE_BT_DPM
227         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
228         if(discoverable_state != DPM_RESTRICTED) {
229 #endif
230         if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
231                 BT_ERR("Set vconf failed");
232 #ifdef TIZEN_FEATURE_BT_DPM
233         }
234 #endif
235 #endif
236
237
238         if (timeout <= 0)
239                 return BLUETOOTH_ERROR_NONE;
240
241         result = _bt_service_set_alarm(visible_timer.timeout,
242                                                 __bt_visibility_alarm_cb, NULL, &alarm_id);
243         if (result != BLUETOOTH_ERROR_NONE)
244                 return BLUETOOTH_ERROR_INTERNAL;
245         visible_timer.alarm_id = alarm_id;
246         /* Take start time */
247         time(&(visible_timer.start_time));
248         visible_timer.event_id = g_timeout_add_seconds(1,
249                                 __bt_timeout_handler, NULL);
250
251         return BLUETOOTH_ERROR_NONE;
252 }
253
254 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
255 {
256         int i = 0;
257         char **parts;
258         GVariantIter *iter;
259         gchar *uuid = NULL;
260
261         ret_if(value == NULL);
262         ret_if(dev == NULL);
263
264         dev->service_index = 0;
265
266         g_variant_get(value, "as", &iter);
267         while (g_variant_iter_loop(iter, "s", &uuid)) {
268                 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
269                 parts = g_strsplit(uuid, "-", -1);
270
271                 if (parts == NULL || parts[0] == NULL) {
272                         g_free(uuid);
273                         break;
274                 }
275
276                 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
277                 g_strfreev(parts);
278
279                 dev->service_index++;
280                 i++;
281         }
282         g_variant_iter_free(iter);
283 }
284
285 static int __bt_get_bonded_device_info(gchar *device_path,
286                 bluetooth_device_info_t *dev_info)
287 {
288         GError *error = NULL;
289         GDBusProxy *device_proxy;
290         gchar *address = NULL;
291         gchar *name = NULL;
292         unsigned int cod = 0;
293         gint rssi = 0;
294         gboolean trust = FALSE;
295         gboolean paired = FALSE;
296         guchar connected = 0;
297         GByteArray *manufacturer_data = NULL;
298         int ret;
299         GDBusConnection *conn;
300         GVariant *result;
301         GVariantIter *property_iter;
302         const gchar *key;
303         GVariant *value;
304         guint8 char_value;
305         GVariantIter *char_value_iter;
306
307         BT_CHECK_PARAMETER(device_path, return);
308         BT_CHECK_PARAMETER(dev_info, return);
309
310         conn = _bt_gdbus_get_system_gconn();
311         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
312
313         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
314                                         NULL,
315                                         BT_BLUEZ_NAME,
316                                         device_path,
317                                         BT_PROPERTIES_INTERFACE,
318                                         NULL, NULL);
319
320         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
321
322         result = g_dbus_proxy_call_sync(device_proxy,
323                                 "GetAll",
324                                 g_variant_new("(s)", BT_DEVICE_INTERFACE),
325                                 G_DBUS_CALL_FLAGS_NONE,
326                                 -1,
327                                 NULL,
328                                 &error);
329
330         if (!result) {
331                 BT_ERR("Error occured in Proxy call");
332                 if (error != NULL) {
333                         BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
334                         g_clear_error(&error);
335                 }
336                 g_object_unref(device_proxy);
337                 return BLUETOOTH_ERROR_INTERNAL;
338         }
339
340         g_object_unref(device_proxy);
341
342         g_variant_get(result, "(a{sv})", &property_iter);
343
344         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
345                 if (!g_strcmp0(key, "Paired")) {
346                         paired = g_variant_get_boolean(value);
347                 } else if (!g_strcmp0(key, "Address")) {
348                         g_variant_get(value, "s", &address);
349                 } else if (!g_strcmp0(key, "Alias")) {
350                         g_variant_get(value, "s", &name);
351                 } else if (!g_strcmp0(key, "Name")) {
352                         if (!name)
353                                 g_variant_get(value, "s", &name);
354                 } else if (!g_strcmp0(key, "Class")) {
355                         cod = g_variant_get_uint32(value);
356                 } else if (!g_strcmp0(key, "Connected")) {
357                         connected = g_variant_get_byte(value);
358                 } else if (!g_strcmp0(key, "Trusted")) {
359                         trust = g_variant_get_boolean(value);
360                 } else if (!g_strcmp0(key, "RSSI")) {
361                         rssi = g_variant_get_int16(value);
362                 } else if (!g_strcmp0(key, "UUIDs")) {
363                         __bt_get_service_list(value, dev_info);
364                 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
365                         dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
366                 } else if (!g_strcmp0(key, "ManufacturerData")) {
367                         manufacturer_data = g_byte_array_new();
368                         g_variant_get(value, "ay", &char_value_iter);
369                         while (g_variant_iter_loop(char_value_iter, "y",  &char_value))
370                                 g_byte_array_append(manufacturer_data, &char_value, 1);
371
372                         g_variant_iter_free(char_value_iter);
373
374                         if (manufacturer_data) {
375                                 if (manufacturer_data->len > 0) {
376                                         memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
377                                                 manufacturer_data->len);
378                                 }
379                         }
380                         g_byte_array_free(manufacturer_data, TRUE);
381                 }
382         }
383         g_variant_iter_free(property_iter);
384
385         BT_DBG("trust: %d, paired: %d", trust, paired);
386
387         g_variant_unref(result);
388
389         if ((paired == FALSE) && (trust == FALSE)) {
390                 g_free(address);
391                 g_free(name);
392                 return BLUETOOTH_ERROR_NOT_PAIRED;
393         }
394
395         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
396                                         address);
397
398         _bt_divide_device_class(&dev_info->device_class, cod);
399
400         g_strlcpy(dev_info->device_name.name, name,
401                         BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
402
403         dev_info->rssi = rssi;
404         dev_info->trust = trust;
405         dev_info->paired = paired;
406         dev_info->connected = connected;
407         ret = BLUETOOTH_ERROR_NONE;
408         g_free(address);
409         g_free(name);
410
411         return ret;
412 }
413
414 void _bt_set_discovery_status(gboolean mode)
415 {
416         is_discovering = mode;
417 }
418
419 void _bt_set_cancel_by_user(gboolean value)
420 {
421         cancel_by_user = value;
422 }
423
424 gboolean _bt_get_cancel_by_user(void)
425 {
426         return cancel_by_user;
427 }
428
429 void _bt_adapter_set_status(bt_status_t status)
430 {
431         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
432         adapter_status = status;
433 }
434
435 bt_status_t _bt_adapter_get_status(void)
436 {
437         return adapter_status;
438 }
439
440 void _bt_adapter_set_le_status(bt_le_status_t status)
441 {
442         BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
443         adapter_le_status = status;
444 }
445
446 bt_le_status_t _bt_adapter_get_le_status(void)
447 {
448         return adapter_le_status;
449 }
450
451
452 void _bt_set_le_intended_status(gboolean value)
453 {
454         is_le_intended = value;
455 }
456
457 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
458 {
459         char *phone_name = NULL;
460         char *ptr = NULL;
461
462         if (node == NULL)
463                 return;
464
465         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
466                 phone_name = vconf_keynode_get_str(node);
467
468                 if (phone_name && strlen(phone_name) != 0) {
469                         if (!g_utf8_validate(phone_name, -1,
470                                                         (const char **)&ptr))
471                                         *ptr = '\0';
472
473                         _bt_set_local_name(phone_name);
474                 }
475         }
476 }
477
478 static void __bt_set_local_name(void)
479 {
480         bluetooth_device_name_t local_name;
481         char *phone_name = NULL;
482         char *ptr = NULL;
483         char *temp = NULL;
484
485         if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
486                 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
487                 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
488
489                 if (!phone_name)
490                         return;
491
492                 if (strlen(phone_name) != 0) {
493                         if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
494                                 *ptr = '\0';
495
496                         _bt_set_local_name(phone_name);
497                 }
498                 free(phone_name);
499         }
500 }
501
502 static int __bt_set_enabled(void)
503 {
504         int adapter_status = BT_ADAPTER_DISABLED;
505         int result = BLUETOOTH_ERROR_NONE;
506
507         if (timer_id > 0) {
508                 BT_DBG("g_source is removed");
509                 g_source_remove(timer_id);
510                 timer_id = 0;
511         }
512
513         _bt_check_adapter(&adapter_status);
514
515         if (adapter_status == BT_ADAPTER_DISABLED) {
516                 BT_ERR("Bluetoothd is not running");
517                 return BLUETOOTH_ERROR_INTERNAL;
518         }
519
520 #if defined(TIZEN_PROFILE_MOBILE) || defined(TIZEN_PROFILE_IVI)
521         /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
522         if (_bt_set_discoverable_mode(
523                 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
524                         BT_ERR("Set connectable mode failed");
525 #else
526 #ifdef TIZEN_PROFILE_TV
527         if (_bt_set_discoverable_mode(
528                 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
529                         BT_ERR("Fail to set discoverable mode");
530 #endif
531 #endif
532
533         /* Update Bluetooth Status to notify other modules */
534         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
535                 BT_ERR("Set vconf failed\n");
536
537         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
538                 BT_ERR("Set vconf failed\n");
539
540         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
541                                                 EVT_VAL_BT_ON) != ES_R_OK)
542                 BT_ERR("Fail to set value");
543
544         /* Send enabled event to API */
545         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
546                                 g_variant_new("(i)", result));
547
548 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
549         _bt_audio_start_auto_connect(FALSE);
550 #endif
551
552         __bt_set_local_name();
553         _bt_set_discovery_status(FALSE);
554
555         return BLUETOOTH_ERROR_NONE;
556 }
557
558 void _bt_set_disabled(int result)
559 {
560         int power_off_status = 0;
561         int ret;
562         int ret_pm_ignore;
563         int pm_ignore_mode = 0;
564
565         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
566         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
567
568         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
569
570         /* Update the vconf BT status in normal Deactivation case only */
571         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
572                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
573
574                 BT_DBG("Update vconf for BT normal Deactivation");
575
576                 if (result == BLUETOOTH_ERROR_TIMEOUT)
577                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
578                                 BT_ERR("Set vconf failed");
579
580                 /* Update Bluetooth Status to notify other modules */
581                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
582                         BT_ERR("Set vconf failed");
583
584                 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
585                                                         EVT_VAL_BT_OFF) != ES_R_OK)
586                         BT_ERR("Fail to set value");
587         }
588
589         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
590                 BT_ERR("Set vconf failed\n");
591
592         _bt_cancel_queued_transfers();
593         _bt_adapter_set_status(BT_DEACTIVATED);
594         _bt_set_discovery_status(FALSE);
595
596 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
597         if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
598 #endif
599                 /* Send disabled event */
600                 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
601                                 g_variant_new("(i)", result));
602 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
603         }
604 #endif
605
606         BT_INFO("Adapter disabled");
607 }
608
609 static int __bt_set_le_enabled(void)
610 {
611         BT_DBG("+");
612         int result = BLUETOOTH_ERROR_NONE;
613         bt_status_t status;
614
615         /* Update Bluetooth Status to notify other modules */
616         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
617                 BT_ERR("Set vconf failed\n");
618
619         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
620                                                 EVT_VAL_BT_LE_ON) != ES_R_OK)
621                 BT_ERR("Fail to set value");
622
623         /* Send enabled event to API */
624         /*
625         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
626                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
627         */
628         status = _bt_adapter_get_status();
629         if (status == BT_DEACTIVATED) {
630                 BT_INFO("BREDR is off, turn off PSCAN");
631                 _bt_set_connectable(FALSE);
632         }
633         if (le_timer_id > 0) {
634                 g_source_remove(le_timer_id);
635                 le_timer_id = 0;
636         }
637
638         /* Send enabled event to API */
639         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
640                                 g_variant_new("(i)", result));
641
642         __bt_set_local_name();
643
644         BT_DBG("-");
645         return BLUETOOTH_ERROR_NONE;
646 }
647
648 void _bt_set_le_disabled(int result)
649 {
650         int power_off_status;
651         int ret;
652
653         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
654         BT_DBG("ret : %d", ret);
655         BT_DBG("power_off_status : %d", power_off_status);
656
657         /* Update Bluetooth Status to notify other modules */
658         BT_DBG("Update vconf for BT LE normal Deactivation");
659         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
660                 BT_ERR("Set vconf failed\n");
661         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
662
663         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
664                                                 EVT_VAL_BT_LE_OFF) != ES_R_OK)
665                 BT_ERR("Fail to set value");
666
667         /* Send disabled event */
668         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
669                         g_variant_new("(i)", result));
670 }
671
672 void *_bt_get_adapter_agent(void)
673 {
674         return adapter_agent;
675 }
676
677 int _bt_enable_core(void)
678 {
679         GDBusProxy *proxy;
680         GVariant *result;
681         GError *error = NULL;
682
683         proxy = __bt_get_core_proxy();
684         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
685
686         /* Clean up the process */
687         result = g_dbus_proxy_call_sync(proxy,
688                                 "EnableCore",
689                                 NULL,
690                                 G_DBUS_CALL_FLAGS_NONE,
691                                 -1,
692                                 NULL,
693                                 &error);
694
695         if (!result) {
696                 if (error != NULL) {
697                         BT_ERR("Bt core call failed(Error: %s)", error->message);
698                         g_clear_error(&error);
699                 } else
700                         BT_ERR("Bt core call failed");
701                 return BLUETOOTH_ERROR_INTERNAL;
702         }
703
704         g_variant_unref(result);
705         return BLUETOOTH_ERROR_NONE;
706 }
707
708 #if defined(TIZEN_FEATURE_FLIGHTMODE_ENABLED) || (!defined(TIZEN_PROFILE_WEARABLE))
709 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
710 {
711         gboolean flight_mode = FALSE;
712         int power_saving_mode = 0;
713         int type;
714
715         DBG_SECURE("key=%s", vconf_keynode_get_name(node));
716         type = vconf_keynode_get_type(node);
717         if (type == VCONF_TYPE_BOOL) {
718                 flight_mode = vconf_keynode_get_bool(node);
719                 if (flight_mode != TRUE) {
720                         BT_ERR("Ignore the event");
721                         return;
722                 }
723         } else if (type == VCONF_TYPE_INT) {
724                 power_saving_mode = vconf_keynode_get_int(node);
725                 if (power_saving_mode != 2) {
726                         BT_ERR("Ignore the event");
727                         return;
728                 }
729         } else {
730                 BT_ERR("Invaild vconf key type : %d", type);
731                 return;
732         }
733
734         _bt_enable_core();
735 }
736 #endif
737
738 void _bt_service_register_vconf_handler(void)
739 {
740         BT_DBG("+");
741
742 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
743         if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
744                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
745                 BT_ERR("Unable to register key handler");
746 #else
747         BT_DBG("Telephony is disabled");
748 #endif
749
750 #ifndef TIZEN_PROFILE_WEARABLE
751         if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
752                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
753                 BT_ERR("Unable to register key handler");
754 #endif
755 }
756
757 void _bt_service_unregister_vconf_handler(void)
758 {
759         BT_DBG("+");
760
761 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
762         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
763                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
764 #endif
765
766 #ifndef TIZEN_PROFILE_WEARABLE
767         vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
768                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
769 #endif
770 }
771
772 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
773 {
774         const char *bt_status = NULL;
775         const char *bt_le_status = NULL;
776         BT_DBG("bt state set event(%s) received", event_name);
777
778         bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
779         BT_DBG("bt_state: (%s)", bt_status);
780
781         bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
782         BT_DBG("bt_state: (%s)", bt_le_status);
783 }
784
785 void _bt_handle_adapter_added(void)
786 {
787         BT_DBG("+");
788         bt_status_t status;
789         bt_le_status_t le_status;
790         int ret;
791 /*
792         if (timer_id > 0) {
793                 BT_DBG("g_source is removed");
794                 g_source_remove(timer_id);
795                 timer_id = 0;
796         }
797 */
798
799         status = _bt_adapter_get_status();
800         le_status = _bt_adapter_get_le_status();
801         BT_DBG("status : %d", status);
802         BT_DBG("le_status : %d", le_status);
803
804 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
805         adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
806         if (!adapter_agent) {
807                 BT_ERR("Fail to register agent");
808                 return;
809         }
810 #else
811         if (adapter_agent == NULL) {
812                 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
813                 if (!adapter_agent) {
814                         BT_ERR("Fail to register agent");
815                         return;
816                 }
817         }
818 #endif
819
820         if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
821                 BT_ERR("Fail to register media player");
822
823         if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
824                 BT_ERR("Fail to init obex server");
825
826 #ifdef TIZEN_BT_PAN_NAP_ENABLED
827         if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
828                 BT_ERR("Fail to activate network");
829 #endif
830
831         /* add the vconf noti handler */
832         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
833                                         __bt_phone_name_changed_cb, NULL);
834         if (ret < 0)
835                 BT_ERR("Unable to register key handler");
836
837         if (le_status == BT_LE_ACTIVATING ||
838                  status == BT_ACTIVATING) {
839                 __bt_set_le_enabled();
840                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
841         }
842
843         if (status == BT_ACTIVATING) {
844                 __bt_set_enabled();
845                 _bt_adapter_set_status(BT_ACTIVATED);
846         }
847
848         /* eventsystem */
849         if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
850                         (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
851                 BT_ERR("Fail to register system event");
852         }
853 }
854
855 void _bt_handle_adapter_removed(void)
856 {
857         int ret;
858
859         _bt_adapter_set_status(BT_DEACTIVATED);
860
861         __bt_visibility_alarm_remove();
862
863         if (alarm_mgr.is_alarm_initialized == TRUE) {
864                 alarmmgr_fini();
865                 alarm_mgr.is_alarm_initialized = FALSE;
866                 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
867                 alarm_mgr.g_alarm_list = NULL;
868         }
869
870 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
871         _bt_audio_stop_auto_connect();
872 #endif
873
874         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
875                                 (vconf_callback_fn)__bt_phone_name_changed_cb);
876         if (0 != ret)
877                 ERR("vconf_ignore_key_changed failed\n");
878
879 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
880         _bt_destroy_agent(adapter_agent);
881         adapter_agent = NULL;
882
883         if (is_recovery_mode == TRUE) {
884                 /* Send disabled event */
885                 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
886
887                 /* Will recover BT by bt-core, so set the mode as activating */
888                 _bt_adapter_set_status(BT_ACTIVATING);
889                 is_recovery_mode = FALSE;
890         } else {
891                 _bt_reliable_terminate_service(NULL);
892         }
893 #else
894         _bt_set_disabled(BLUETOOTH_ERROR_NONE);
895 #endif
896
897         if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
898                 BT_ERR("Fail to unregister system event");
899 }
900
901 static gboolean __bt_enable_timeout_cb(gpointer user_data)
902 {
903         GDBusProxy *proxy;
904         GVariant *result;
905         GError *error = NULL;
906
907         timer_id = 0;
908
909         retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
910
911         BT_ERR("EnableAdapter is failed");
912
913         proxy = __bt_get_core_proxy();
914         if (!proxy)
915                 return FALSE;
916
917         /* Clean up the process */
918         result = g_dbus_proxy_call_sync(proxy,
919                                 "DisableAdapter",
920                                 NULL,
921                                 G_DBUS_CALL_FLAGS_NONE,
922                                 -1,
923                                 NULL,
924                                 &error);
925
926         if (!result) {
927                 if (error != NULL) {
928                         BT_ERR("Bt core call failed(Error: %s)", error->message);
929                         g_clear_error(&error);
930                 } else {
931                         BT_ERR("Bt core call failed");
932                 }
933                 return FALSE;
934         }
935
936         g_variant_unref(result);
937         _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
938
939 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
940         _bt_terminate_service(NULL);
941 #endif
942
943         return FALSE;
944 }
945
946 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
947 {
948         GDBusProxy *proxy;
949         GVariant *result;
950         GError *error = NULL;
951
952         le_timer_id = 0;
953
954         retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
955
956         BT_ERR("EnableAdapterLE is failed");
957
958         proxy = __bt_get_core_proxy();
959         if (!proxy)
960                 return FALSE;
961
962         /* Clean up the process */
963         result = g_dbus_proxy_call_sync(proxy,
964                                 "DisableAdapterLe",
965                                 NULL,
966                                 G_DBUS_CALL_FLAGS_NONE,
967                                 -1,
968                                 NULL,
969                                 &error);
970
971         if (!result) {
972                 if (error != NULL) {
973                         BT_ERR("Bt core call failed(Error: %s)", error->message);
974                         g_clear_error(&error);
975                 } else
976                         BT_ERR("Bt core call failed");
977                 return FALSE;
978         }
979
980         g_variant_unref(result);
981         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
982
983         _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
984
985         if (_bt_adapter_get_status() == BT_DEACTIVATED)
986                 _bt_terminate_service(NULL);
987
988         return FALSE;
989 }
990
991 void _bt_adapter_start_le_enable_timer(void)
992 {
993         if (le_timer_id > 0) {
994                 g_source_remove(le_timer_id);
995                 le_timer_id = 0;
996         }
997
998         le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
999                         __bt_enable_le_timeout_cb, NULL);
1000
1001         return;
1002 }
1003
1004 void _bt_adapter_start_enable_timer(void)
1005 {
1006         if (timer_id > 0) {
1007                 g_source_remove(timer_id);
1008                 timer_id = 0;
1009         }
1010
1011         timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1012                         __bt_enable_timeout_cb, NULL);
1013
1014         return;
1015 }
1016
1017 #ifdef TIZEN_PROFILE_TV
1018 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1019 {
1020         BT_DBG("+");
1021
1022         __bt_set_enabled();
1023         _bt_adapter_set_status(BT_ACTIVATED);
1024
1025         return FALSE;
1026 }
1027 #endif
1028
1029 int _bt_enable_adapter_check_status(void)
1030 {
1031         bt_status_t status = _bt_adapter_get_status();
1032         bt_le_status_t le_status = _bt_adapter_get_le_status();
1033
1034         BT_DBG("");
1035
1036         if (status == BT_ACTIVATING) {
1037                 BT_ERR("Enabling in progress");
1038                 return BLUETOOTH_ERROR_IN_PROGRESS;
1039         }
1040
1041         if (status == BT_ACTIVATED) {
1042                 BT_ERR("Already enabled");
1043                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1044         }
1045
1046         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1047                 BT_ERR("Disabling in progress");
1048                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1049         }
1050
1051         return BLUETOOTH_ERROR_NONE;
1052 }
1053
1054 int _bt_enable_adapter(void)
1055 {
1056         GDBusProxy *proxy;
1057         GError *error = NULL;
1058         int ret;
1059         GVariant *result = NULL;
1060         bt_status_t status = _bt_adapter_get_status();
1061         bt_le_status_t le_status = _bt_adapter_get_le_status();
1062
1063         BT_DBG("");
1064
1065         if (status == BT_ACTIVATING) {
1066                 BT_ERR("Enabling in progress");
1067                 return BLUETOOTH_ERROR_IN_PROGRESS;
1068         }
1069
1070         if (status == BT_ACTIVATED) {
1071                 BT_ERR("Already enabled");
1072                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1073         }
1074
1075         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1076                 BT_ERR("Disabling in progress");
1077                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1078         }
1079
1080         _bt_adapter_set_status(BT_ACTIVATING);
1081
1082 #ifdef TIZEN_PROFILE_TV
1083 {
1084         int adapter_status = BT_ADAPTER_DISABLED;
1085
1086         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1087                 BT_ERR("Set vconf failed");
1088
1089         _bt_check_adapter(&adapter_status);
1090         if (adapter_status == BT_ADAPTER_ENABLED) {
1091                 g_idle_add(__bt_adapter_enabled_cb, NULL);
1092                 _bt_adapter_start_enable_timer();
1093                 return BLUETOOTH_ERROR_NONE;
1094         }
1095 }
1096 #endif
1097
1098         proxy = __bt_get_core_proxy();
1099         if (!proxy)
1100                 return BLUETOOTH_ERROR_INTERNAL;
1101
1102         if (le_status == BT_LE_ACTIVATED) {
1103                 BT_INFO("LE Already enabled. Just turn on PSCAN");
1104                 ret = _bt_set_connectable(TRUE);
1105                 if (ret == BLUETOOTH_ERROR_NONE)
1106                         _bt_adapter_set_status(BT_ACTIVATED);
1107                 else
1108                         return BLUETOOTH_ERROR_INTERNAL;
1109         }
1110
1111         result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1112                                          NULL,
1113                                          G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1114                                          NULL, &error);
1115          if (error) {
1116                 BT_ERR("EnableAdapterLe failed: %s", error->message);
1117                 _bt_adapter_set_status(BT_DEACTIVATED);
1118                 g_clear_error(&error);
1119                 error = NULL;
1120                 result = g_dbus_proxy_call_sync(proxy,
1121                                 "DisableAdapter",
1122                                 NULL,
1123                                 G_DBUS_CALL_FLAGS_NONE,
1124                                 -1,
1125                                 NULL,
1126                                 &error);
1127
1128                 if (error != NULL) {
1129                                 BT_ERR("Bt core call failed(Error: %s)", error->message);
1130                                 g_clear_error(&error);
1131                 }
1132                 g_variant_unref(result);
1133 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
1134                 /* Terminate myself */
1135                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1136 #endif
1137                 return BLUETOOTH_ERROR_INTERNAL;
1138         }
1139         g_variant_unref(result);
1140         if (le_status == BT_LE_ACTIVATED)
1141                 __bt_set_enabled();
1142         else
1143                 _bt_adapter_start_enable_timer();
1144
1145         return BLUETOOTH_ERROR_NONE;
1146 }
1147
1148 static gboolean __bt_disconnect_all(void)
1149 {
1150         int i;
1151         GDBusConnection *conn;
1152         GDBusProxy *dev_proxy;
1153         gboolean ret = FALSE;
1154         GVariant *result;
1155         GError *error = NULL;
1156         GArray *device_list;
1157         bluetooth_device_info_t info;
1158         guint size;
1159         char *device_path = NULL;
1160         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1161
1162
1163         BT_DBG("");
1164
1165         conn = _bt_gdbus_get_system_gconn();
1166
1167         device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1168
1169         if (_bt_get_bonded_devices(&device_list)
1170                                         != BLUETOOTH_ERROR_NONE) {
1171                 g_array_free(device_list, TRUE);
1172                 return FALSE;
1173         }
1174
1175         size = (device_list->len) / sizeof(bluetooth_device_info_t);
1176
1177         for (i = 0; i < size; i++) {
1178
1179                 info = g_array_index(device_list,
1180                                 bluetooth_device_info_t, i);
1181
1182                 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1183                         BT_DBG("Found Connected device");
1184                         _bt_convert_addr_type_to_string(address, info.device_address.addr);
1185                         device_path = _bt_get_device_object_path(address);
1186                         if (device_path == NULL)
1187                                 continue;
1188
1189                         BT_DBG("Disconnecting : %s", device_path);
1190
1191                         dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1192                                                         NULL,
1193                                                         BT_BLUEZ_NAME,
1194                                                         device_path,
1195                                                         BT_DEVICE_INTERFACE,
1196                                                         NULL, NULL);
1197
1198                         if (dev_proxy == NULL)
1199                                 continue;
1200
1201                         result = g_dbus_proxy_call_sync(dev_proxy,
1202                                                 "Disconnect",
1203                                                 NULL,
1204                                                 G_DBUS_CALL_FLAGS_NONE,
1205                                                 -1,
1206                                                 NULL,
1207                                                 &error);
1208
1209                         if (!result) {
1210                                 if (error != NULL) {
1211                                         BT_ERR("Disconnect call failed(Error: %s)", error->message);
1212                                         g_clear_error(&error);
1213                                 } else
1214                                         BT_ERR("Disconnect call failed");
1215                                 g_object_unref(dev_proxy);
1216                                 return FALSE;
1217                         }
1218
1219                         g_variant_unref(result);
1220                         g_object_unref(dev_proxy);
1221                 }
1222         }
1223         ret = TRUE;
1224         g_array_free(device_list, TRUE);
1225
1226         return ret;
1227 }
1228
1229 #if 0
1230 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1231 {
1232         BT_DBG("");
1233         _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1234
1235         return FALSE;
1236 }
1237 #endif
1238
1239 int _bt_disable_cb(void)
1240 {
1241         FN_START;
1242         GDBusProxy *proxy;
1243 #if 0
1244         int ret;
1245 #endif
1246         GVariant *result;
1247         GError *error = NULL;
1248
1249         _bt_adapter_set_status(BT_DEACTIVATING);
1250 #if 0
1251         bt_le_status_t le_status;
1252         le_status = _bt_adapter_get_le_status();
1253         BT_DBG("le_status : %d", le_status);
1254         if (le_status == BT_LE_ACTIVATED) {
1255                 BT_INFO("LE is enabled. Just turn off PSCAN");
1256
1257                 if (_bt_is_discovering())
1258                         _bt_cancel_discovery();
1259
1260                 if (_bt_is_connectable() == FALSE) {
1261                         g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1262                 } else {
1263                         ret = _bt_set_connectable(FALSE);
1264                         if (ret != BLUETOOTH_ERROR_NONE) {
1265                                 BT_ERR("_bt_set_connectable fail!");
1266                                 _bt_adapter_set_status(BT_ACTIVATED);
1267                                 return BLUETOOTH_ERROR_INTERNAL;
1268                         }
1269                 }
1270         }
1271 #endif
1272         proxy = __bt_get_core_proxy();
1273         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1274
1275         result = g_dbus_proxy_call_sync(proxy,
1276                                 "DisableAdapter",
1277                                 NULL,
1278                                 G_DBUS_CALL_FLAGS_NONE,
1279                                 -1,
1280                                 NULL,
1281                                 &error);
1282
1283         if (!result) {
1284                 if (error != NULL) {
1285                         BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1286                         g_clear_error(&error);
1287                 } else
1288                         BT_ERR("Failed to DisableAdapter");
1289                 _bt_adapter_set_status(BT_ACTIVATED);
1290                 return BLUETOOTH_ERROR_INTERNAL;
1291         }
1292
1293         g_variant_unref(result);
1294         return BLUETOOTH_ERROR_NONE;
1295 }
1296
1297 int _bt_disable_adapter_check_status(void)
1298 {
1299         bt_status_t status = _bt_adapter_get_status();
1300
1301         BT_DBG("");
1302
1303         if (status == BT_DEACTIVATING) {
1304                 BT_DBG("Disabling in progress");
1305                 return BLUETOOTH_ERROR_IN_PROGRESS;
1306         }
1307
1308         if (status == BT_DEACTIVATED) {
1309                 BT_DBG("Already disabled");
1310                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1311         }
1312
1313         return BLUETOOTH_ERROR_NONE;
1314 }
1315
1316 int _bt_disable_adapter(void)
1317 {
1318         BT_DBG("+");
1319         int ret;
1320
1321         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1322                 BT_DBG("Disabling in progress");
1323                 return BLUETOOTH_ERROR_IN_PROGRESS;
1324         }
1325
1326         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1327                 BT_DBG("Already disabled");
1328                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1329         }
1330
1331         if (timer_id > 0) {
1332                 g_source_remove(timer_id);
1333                 timer_id = 0;
1334         }
1335
1336         __bt_disconnect_all();
1337         ret = _bt_disable_cb();
1338
1339         BT_DBG("-");
1340         return ret;
1341 }
1342
1343 int _bt_recover_adapter(void)
1344 {
1345         BT_DBG("+");
1346         GDBusProxy *proxy;
1347         GVariant *result;
1348         GError *error = NULL;
1349
1350         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1351                 BT_DBG("Disabling in progress");
1352                 return BLUETOOTH_ERROR_IN_PROGRESS;
1353         }
1354
1355         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1356                 BT_DBG("Already disabled");
1357                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1358         }
1359
1360         _bt_adapter_set_status(BT_DEACTIVATING);
1361
1362         proxy = __bt_get_core_proxy();
1363         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1364
1365         result = g_dbus_proxy_call_sync(proxy,
1366                                 "RecoverAdapter",
1367                                 NULL,
1368                                 G_DBUS_CALL_FLAGS_NONE,
1369                                 -1,
1370                                 NULL,
1371                                 &error);
1372
1373         if (!result) {
1374                 if (error != NULL) {
1375                         BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1376                         g_clear_error(&error);
1377                 } else
1378                         BT_ERR("Failed to RecoverAdapter");
1379                 return BLUETOOTH_ERROR_INTERNAL;
1380         }
1381
1382         is_recovery_mode = TRUE;
1383
1384         g_variant_unref(result);
1385         __bt_disconnect_all();
1386
1387         BT_DBG("-");
1388         return BLUETOOTH_ERROR_NONE;
1389 }
1390
1391 int _bt_reset_adapter(void)
1392 {
1393         GDBusProxy *proxy;
1394         GVariant *result;
1395         GError *error = NULL;
1396
1397         BT_DBG("");
1398
1399         proxy = __bt_get_core_proxy();
1400         if (!proxy)
1401                 return BLUETOOTH_ERROR_INTERNAL;
1402
1403         result = g_dbus_proxy_call_sync(proxy,
1404                                 "ResetAdapter",
1405                                 NULL,
1406                                 G_DBUS_CALL_FLAGS_NONE,
1407                                 -1,
1408                                 NULL,
1409                                 &error);
1410
1411         if (!result) {
1412                 if (error != NULL) {
1413                         BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1414                         g_clear_error(&error);
1415                 } else
1416                         BT_ERR("Failed to ResetAdapter");
1417                 return BLUETOOTH_ERROR_INTERNAL;
1418         }
1419
1420         g_variant_unref(result);
1421         /* Terminate myself */
1422         if (_bt_adapter_get_status() == BT_DEACTIVATED)
1423                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1424
1425         return BLUETOOTH_ERROR_NONE;
1426 }
1427
1428 #ifndef TIZEN_PROFILE_TV
1429 int _bt_check_adapter(int *status)
1430 {
1431
1432         char *adapter_path = NULL;
1433
1434         BT_CHECK_PARAMETER(status, return);
1435
1436         *status = BT_ADAPTER_DISABLED;
1437
1438         adapter_path = _bt_get_adapter_path();
1439
1440
1441         if (adapter_path != NULL)
1442                 *status = BT_ADAPTER_ENABLED;
1443
1444         g_free(adapter_path);
1445         return BLUETOOTH_ERROR_NONE;
1446 }
1447 #else
1448 int _bt_check_adapter(int *status)
1449 {
1450         GDBusProxy *proxy;
1451         GError *error = NULL;
1452         GVariant *result;
1453         GVariant *temp;
1454         gboolean powered = FALSE;
1455
1456         BT_CHECK_PARAMETER(status, return);
1457
1458         *status = BT_ADAPTER_DISABLED;
1459
1460         proxy = _bt_get_adapter_properties_proxy();
1461         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1462
1463         result = g_dbus_proxy_call_sync(proxy,
1464                                 "Get",
1465                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1466                                         "Powered"),
1467                                 G_DBUS_CALL_FLAGS_NONE,
1468                                 -1,
1469                                 NULL,
1470                                 &error);
1471
1472         if (!result) {
1473                 BT_ERR("Failed to get local address");
1474                 if (error != NULL) {
1475                         BT_ERR("Failed to get local address (Error: %s)", error->message);
1476                         g_clear_error(&error);
1477                 }
1478                 return BLUETOOTH_ERROR_INTERNAL;
1479         }
1480
1481         g_variant_get(result, "(v)", &temp);
1482         powered = g_variant_get_boolean(temp);
1483         BT_DBG("powered: %d", powered);
1484
1485         if (powered)
1486                 *status = BT_ADAPTER_ENABLED;
1487
1488         g_variant_unref(result);
1489         g_variant_unref(temp);
1490         return BLUETOOTH_ERROR_NONE;
1491 }
1492 #endif
1493
1494 int _bt_enable_adapter_le(void)
1495 {
1496         BT_DBG("+");
1497         GDBusProxy *proxy;
1498         GError *error = NULL;
1499         bt_status_t status = _bt_adapter_get_status();
1500         bt_le_status_t le_status = _bt_adapter_get_le_status();
1501         GVariant *result;
1502
1503         if (le_status == BT_LE_ACTIVATING) {
1504                 BT_ERR("Enabling in progress");
1505                 return BLUETOOTH_ERROR_IN_PROGRESS;
1506         }
1507
1508         if (le_status == BT_LE_ACTIVATED) {
1509                 BT_ERR("Already enabled");
1510                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1511         }
1512
1513         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1514                 BT_ERR("Disabling in progress");
1515                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1516         }
1517
1518         _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1519
1520         proxy = __bt_get_core_proxy();
1521         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1522
1523         result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1524                                         NULL,
1525                                         G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1526                                         NULL, &error);
1527         if (error) {
1528                 BT_ERR("EnableAdapterLe failed: %s", error->message);
1529                 _bt_adapter_set_le_status(BT_DEACTIVATED);
1530                 g_clear_error(&error);
1531
1532                 /* Clean up the process */
1533                 result = g_dbus_proxy_call_sync(proxy,
1534                                         "DisableAdapterLe",
1535                                         NULL,
1536                                         G_DBUS_CALL_FLAGS_NONE,
1537                                         -1,
1538                                         NULL,
1539                                         &error);
1540
1541                 if (!result) {
1542                                 BT_ERR("Bt core call failed");
1543                                 if (error) {
1544                                         BT_ERR("EnableAdapterLE Failed %s", error->message);
1545                                         g_clear_error(&error);
1546                                 }
1547                 }
1548                 g_variant_unref(result);
1549                 /* Terminate myself */
1550                 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1551                         g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1552                 return BLUETOOTH_ERROR_INTERNAL;
1553         }
1554
1555         if (result)
1556                 g_variant_unref(result);
1557
1558         _bt_adapter_start_le_enable_timer();
1559
1560         if (status == BT_ACTIVATED) {
1561                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1562                 __bt_set_le_enabled();
1563         }
1564         BT_DBG("le status : %d", _bt_adapter_get_le_status());
1565         BT_DBG("-");
1566         return BLUETOOTH_ERROR_NONE;
1567 }
1568
1569 int _bt_disable_adapter_le(void)
1570 {
1571         BT_DBG("+");
1572         GDBusProxy *proxy;
1573         bt_le_status_t bt_le_state;
1574         GVariant *result;
1575         GError *error = NULL;
1576
1577         bt_le_state = _bt_adapter_get_le_status();
1578         if (bt_le_state == BT_LE_DEACTIVATING) {
1579                 BT_DBG("Disabling in progress");
1580                 return BLUETOOTH_ERROR_IN_PROGRESS;
1581         }
1582
1583         if (bt_le_state == BT_LE_DEACTIVATED) {
1584                 BT_DBG("Already disabled");
1585                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1586         }
1587
1588         _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1589
1590         proxy = __bt_get_core_proxy();
1591         if (!proxy)
1592                 return BLUETOOTH_ERROR_INTERNAL;
1593
1594         result = g_dbus_proxy_call_sync(proxy,
1595                                 "DisableAdapterLe",
1596                                 NULL,
1597                                 G_DBUS_CALL_FLAGS_NONE,
1598                                 -1,
1599                                 NULL,
1600                                 &error);
1601
1602         if (!result) {
1603                 if (error != NULL) {
1604                         BT_ERR("Bt core call failed (Error: %s)", error->message);
1605                         g_clear_error(&error);
1606                 } else
1607                         BT_ERR("Bt core call failed");
1608                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1609                 return BLUETOOTH_ERROR_INTERNAL;
1610         }
1611
1612         g_variant_unref(result);
1613         _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1614         BT_DBG("le status : %d", _bt_adapter_get_le_status());
1615         BT_DBG("-");
1616         return BLUETOOTH_ERROR_NONE;
1617 }
1618
1619 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1620 {
1621
1622         GDBusProxy *proxy;
1623         GError *error = NULL;
1624         const char *address;
1625         GVariant *result;
1626         GVariant *temp;
1627
1628         BT_CHECK_PARAMETER(local_address, return);
1629
1630         proxy = _bt_get_adapter_properties_proxy();
1631         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1632
1633         result = g_dbus_proxy_call_sync(proxy,
1634                                 "Get",
1635                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1636                                         "Address"),
1637                                 G_DBUS_CALL_FLAGS_NONE,
1638                                 -1,
1639                                 NULL,
1640                                 &error);
1641
1642         if (!result) {
1643                 BT_ERR("Failed to get local address");
1644                 if (error != NULL) {
1645                         BT_ERR("Failed to get local address (Error: %s)", error->message);
1646                         g_clear_error(&error);
1647                 }
1648                 return BLUETOOTH_ERROR_INTERNAL;
1649         }
1650
1651         g_variant_get(result, "(v)", &temp);
1652         address = g_variant_get_string(temp, NULL);
1653         BT_DBG("Address:%s", address);
1654
1655         if (address)
1656                 _bt_convert_addr_string_to_type(local_address->addr, address);
1657         else
1658                 return BLUETOOTH_ERROR_INTERNAL;
1659
1660         g_variant_unref(result);
1661         g_variant_unref(temp);
1662         return BLUETOOTH_ERROR_NONE;
1663 }
1664
1665 int _bt_get_local_version(bluetooth_version_t *local_version)
1666 {
1667         GDBusProxy *proxy;
1668         const char *ver = NULL;
1669         char *ptr = NULL;
1670         int ret = BLUETOOTH_ERROR_NONE;
1671         GVariant *result;
1672         GVariant *temp;
1673
1674         BT_CHECK_PARAMETER(local_version, return);
1675
1676         GError *error = NULL;
1677
1678         proxy = _bt_get_adapter_properties_proxy();
1679         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1680
1681         result = g_dbus_proxy_call_sync(proxy,
1682                                 "Get",
1683                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1684                                         "Version"),
1685                                 G_DBUS_CALL_FLAGS_NONE,
1686                                 -1,
1687                                 NULL,
1688                                 &error);
1689
1690         if (!result) {
1691                 if (error != NULL) {
1692                         BT_ERR("Failed to get local version (Error: %s)", error->message);
1693                         g_clear_error(&error);
1694                 } else
1695                         BT_ERR("Failed to get local version");
1696                 return BLUETOOTH_ERROR_INTERNAL;
1697         }
1698
1699         g_variant_get(result, "(v)", &temp);
1700         ver = g_variant_get_string(temp, NULL);
1701         BT_DBG("VERSION: %s", ver);
1702
1703         if (ver && (strlen(ver) > 0)) {
1704                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1705                 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1706                         *ptr = '\0';
1707
1708                 g_strlcpy(local_version->version, ver,
1709                                 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1710
1711         } else {
1712                 ret = BLUETOOTH_ERROR_INTERNAL;
1713         }
1714
1715         g_variant_unref(result);
1716         g_variant_unref(temp);
1717         return ret;
1718 }
1719
1720 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1721 {
1722         GDBusProxy *proxy;
1723         const char *name = NULL;
1724         char *ptr = NULL;
1725         int ret = BLUETOOTH_ERROR_NONE;
1726         GVariant *result;
1727         GVariant *temp;
1728         GError *error = NULL;
1729
1730         BT_CHECK_PARAMETER(local_name, return);
1731
1732         proxy = _bt_get_adapter_properties_proxy();
1733         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1734
1735         result = g_dbus_proxy_call_sync(proxy,
1736                                 "Get",
1737                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1738                                         "Alias"),
1739                                 G_DBUS_CALL_FLAGS_NONE,
1740                                 -1,
1741                                 NULL,
1742                                 &error);
1743
1744         if (!result) {
1745                 if (error != NULL) {
1746                         BT_ERR("Failed to get local name (Error: %s)", error->message);
1747                         g_clear_error(&error);
1748                 } else
1749                         BT_ERR("Failed to get local name");
1750                 return BLUETOOTH_ERROR_INTERNAL;
1751         }
1752
1753         g_variant_get(result, "(v)", &temp);
1754         name = g_variant_get_string(temp, NULL);
1755         BT_DBG("LOCAL NAME:%s", name);
1756
1757         if (name && (strlen(name) > 0)) {
1758                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1759                 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1760                         *ptr = '\0';
1761
1762                 g_strlcpy(local_name->name, name,
1763                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1764         } else {
1765                 ret = BLUETOOTH_ERROR_INTERNAL;
1766         }
1767         g_variant_unref(result);
1768         g_variant_unref(temp);
1769         return ret;
1770 }
1771
1772 int _bt_set_local_name(char *local_name)
1773 {
1774         GDBusProxy *proxy;
1775         GError *error = NULL;
1776         char *ptr = NULL;
1777         GVariant *result;
1778
1779         BT_CHECK_PARAMETER(local_name, return);
1780
1781         proxy = _bt_get_adapter_properties_proxy();
1782
1783         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1784
1785         if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1786                 *ptr = '\0';
1787
1788         result = g_dbus_proxy_call_sync(proxy,
1789                                 "Set",
1790                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1791                                         "Alias", g_variant_new("s", local_name)),
1792                                 G_DBUS_CALL_FLAGS_NONE,
1793                                 -1,
1794                                 NULL,
1795                                 &error);
1796
1797         if (!result) {
1798                 if (error != NULL) {
1799                         BT_ERR("Failed to set Alias (Error: %s)", error->message);
1800                         g_clear_error(&error);
1801                 } else
1802                         BT_ERR("Failed to set Alias");
1803                 return BLUETOOTH_ERROR_INTERNAL;
1804         }
1805
1806         g_variant_unref(result);
1807         return BLUETOOTH_ERROR_NONE;
1808 }
1809
1810 int _bt_is_service_used(char *service_uuid, gboolean *used)
1811 {
1812         GDBusProxy *proxy;
1813         GError *error = NULL;
1814         int ret = BLUETOOTH_ERROR_NONE;
1815         GVariant *result;
1816         GVariant *temp = NULL;
1817         GVariantIter *iter = NULL;
1818         gchar *uuid = NULL;
1819
1820         BT_DBG("+");
1821         BT_CHECK_PARAMETER(service_uuid, return);
1822         BT_CHECK_PARAMETER(used, return);
1823
1824         proxy = _bt_get_adapter_properties_proxy();
1825         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1826
1827         result = g_dbus_proxy_call_sync(proxy,
1828                                 "Get",
1829                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1830                                         "UUIDs"),
1831                                 G_DBUS_CALL_FLAGS_NONE,
1832                                 -1,
1833                                 NULL,
1834                                 &error);
1835
1836         if (!result) {
1837                 if (error != NULL) {
1838                         BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1839                         g_clear_error(&error);
1840                 } else
1841                         BT_ERR("Failed to get UUIDs");
1842                 return BLUETOOTH_ERROR_INTERNAL;
1843         }
1844
1845         g_variant_get(result, "(v)", &temp);
1846         g_variant_get(temp, "as", &iter);
1847
1848         *used = FALSE;
1849         while (g_variant_iter_loop(iter, "&s", &uuid)) {
1850                 if (strcasecmp(uuid, service_uuid) == 0) {
1851                         *used = TRUE;
1852                         break;
1853                 }
1854         }
1855         g_variant_iter_free(iter);
1856         g_variant_unref(result);
1857
1858         BT_DBG("Service Used? %d", *used);
1859
1860         return ret;
1861 }
1862
1863 static gboolean __bt_get_discoverable_property(void)
1864 {
1865         GDBusProxy *proxy;
1866         gboolean discoverable_v;
1867         GError *error = NULL;
1868         GVariant *result;
1869         GVariant *temp;
1870
1871         proxy = _bt_get_adapter_properties_proxy();
1872         retv_if(proxy == NULL, FALSE);
1873
1874         result = g_dbus_proxy_call_sync(proxy,
1875                                 "Get",
1876                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1877                                         "Discoverable"),
1878                                 G_DBUS_CALL_FLAGS_NONE,
1879                                 -1,
1880                                 NULL,
1881                                 &error);
1882
1883         if (!result) {
1884                 if (error != NULL) {
1885                         BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1886                         g_clear_error(&error);
1887                 } else
1888                         BT_ERR("Failed to get Discoverable property");
1889                 return BLUETOOTH_ERROR_INTERNAL;
1890         }
1891
1892         g_variant_get(result, "(v)", &temp);
1893         discoverable_v = g_variant_get_boolean(temp);
1894         BT_DBG("discoverable_v:%d", discoverable_v);
1895
1896         g_variant_unref(result);
1897         g_variant_unref(temp);
1898
1899         return discoverable_v;
1900 }
1901
1902 int _bt_get_discoverable_mode(int *mode)
1903 {
1904         gboolean discoverable;
1905         unsigned int timeout;
1906
1907         BT_CHECK_PARAMETER(mode, return);
1908
1909         discoverable = __bt_get_discoverable_property();
1910         timeout = _bt_get_discoverable_timeout_property();
1911
1912         if (discoverable == TRUE) {
1913                 if (timeout == 0)
1914                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1915                 else
1916                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1917         } else {
1918                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1919         }
1920         return BLUETOOTH_ERROR_NONE;
1921 }
1922
1923
1924 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1925 {
1926         int ret = BLUETOOTH_ERROR_NONE;
1927         gboolean inq_scan;
1928         gboolean pg_scan;
1929         GError *error = NULL;
1930         GDBusProxy *proxy;
1931         GVariant *result;
1932 #ifdef TIZEN_FEATURE_BT_DPM
1933         int discoverable_state = DPM_BT_ERROR;
1934 #endif
1935
1936         proxy = _bt_get_adapter_properties_proxy();
1937
1938         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1939
1940 #ifdef TIZEN_FEATURE_BT_DPM
1941         _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1942         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
1943                  discoverable_state == DPM_RESTRICTED) {
1944                 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT_HANDSFREE");
1945                 return BLUETOOTH_ERROR_ACCESS_DENIED;
1946         }
1947         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
1948                 discoverable_state == DPM_RESTRICTED) {
1949                 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT");
1950                 return BLUETOOTH_ERROR_ACCESS_DENIED;
1951         }
1952 #endif
1953
1954         switch (discoverable_mode) {
1955         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1956                 pg_scan = TRUE;
1957                 inq_scan = FALSE;
1958                 timeout = 0;
1959                 break;
1960         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1961                 pg_scan = TRUE;
1962                 inq_scan = TRUE;
1963                 timeout = 0;
1964                 break;
1965         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1966                 inq_scan = TRUE;
1967                 pg_scan = TRUE;
1968                 break;
1969         default:
1970                 return BLUETOOTH_ERROR_INVALID_PARAM;
1971         }
1972
1973         BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1974                         discoverable_mode, timeout);
1975
1976         result = g_dbus_proxy_call_sync(proxy,
1977                                 "Set",
1978                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1979                                         "Connectable", g_variant_new("b", pg_scan)),
1980                                 G_DBUS_CALL_FLAGS_NONE,
1981                                 -1,
1982                                 NULL,
1983                                 &error);
1984
1985         if (!result) {
1986                 if (error != NULL) {
1987                         BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1988                         g_clear_error(&error);
1989                 } else
1990                         BT_ERR("Failed to set connectable property");
1991                 return BLUETOOTH_ERROR_INTERNAL;
1992         }
1993         g_variant_unref(result);
1994         result = g_dbus_proxy_call_sync(proxy,
1995                                 "Set",
1996                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
1997                                                 g_variant_new("b", inq_scan)),
1998                                 G_DBUS_CALL_FLAGS_NONE,
1999                                 -1,
2000                                 NULL,
2001                                 &error);
2002
2003         if (!result) {
2004                 if (error != NULL) {
2005                         BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2006                         g_clear_error(&error);
2007                 } else
2008                         BT_ERR("Failed to set Discoverable property");
2009                 return BLUETOOTH_ERROR_INTERNAL;
2010         }
2011         g_variant_unref(result);
2012         result = g_dbus_proxy_call_sync(proxy,
2013                                 "Set",
2014                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2015                                         "DiscoverableTimeout", g_variant_new("u", timeout)),
2016                                 G_DBUS_CALL_FLAGS_NONE,
2017                                 -1,
2018                                 NULL,
2019                                 &error);
2020
2021         if (!result) {
2022                 if (error != NULL) {
2023                         BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2024                         g_clear_error(&error);
2025                 } else
2026                         BT_ERR("Failed to set DiscoverableTimeout property");
2027                 return BLUETOOTH_ERROR_INTERNAL;
2028         }
2029
2030         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2031                 timeout = -1;
2032
2033         ret = __bt_set_visible_time(timeout);
2034
2035         g_variant_unref(result);
2036
2037         return ret;
2038 }
2039
2040 int _bt_start_discovery(void)
2041 {
2042         GDBusProxy *proxy;
2043         GError *error = NULL;
2044         GVariant *result;
2045
2046         if (_bt_is_discovering() == TRUE) {
2047                 BT_ERR("BT is already in discovering");
2048                 return BLUETOOTH_ERROR_IN_PROGRESS;
2049         } else if (_bt_is_device_creating() == TRUE) {
2050                 BT_ERR("Bonding device is going on");
2051                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2052         }
2053
2054         proxy = _bt_get_adapter_proxy();
2055         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2056
2057         result = g_dbus_proxy_call_sync(proxy,
2058                                 "StartDiscovery",
2059                                 NULL,
2060                                 G_DBUS_CALL_FLAGS_NONE,
2061                                 -1,
2062                                 NULL,
2063                                 &error);
2064
2065         if (!result) {
2066                 if (error != NULL) {
2067                         BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2068                         g_clear_error(&error);
2069                 } else
2070                         BT_ERR("StartDiscovery failed");
2071                 return BLUETOOTH_ERROR_INTERNAL;
2072         }
2073
2074         is_discovering = TRUE;
2075         cancel_by_user = FALSE;
2076         /* discovery status will be change in event */
2077         g_variant_unref(result);
2078         return BLUETOOTH_ERROR_NONE;
2079 }
2080
2081 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2082 {
2083         GDBusProxy *proxy;
2084         GVariant *result;
2085         GError *error = NULL;
2086         const gchar *disc_type;
2087
2088         if (_bt_is_discovering() == TRUE) {
2089                 BT_ERR("BT is already in discovering");
2090                 return BLUETOOTH_ERROR_IN_PROGRESS;
2091         }
2092
2093         proxy = _bt_get_adapter_proxy();
2094         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2095
2096         if (role == DISCOVERY_ROLE_BREDR)
2097                 disc_type = "BREDR";
2098         else if (role == DISCOVERY_ROLE_LE)
2099                 disc_type = "LE";
2100         else if (role == DISCOVERY_ROLE_LE_BREDR)
2101                 disc_type = "LE_BREDR";
2102         else
2103                 return BLUETOOTH_ERROR_INVALID_PARAM;
2104
2105         result = g_dbus_proxy_call_sync(proxy,
2106                                 "StartCustomDiscovery",
2107                                 g_variant_new("s", disc_type),
2108                                 G_DBUS_CALL_FLAGS_NONE,
2109                                 -1,
2110                                 NULL,
2111                                 &error);
2112
2113         if (!result) {
2114                 if (error != NULL) {
2115                         BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2116                         g_clear_error(&error);
2117                 } else
2118                         BT_ERR("StartCustomDiscovery failed");
2119                 return BLUETOOTH_ERROR_INTERNAL;
2120         }
2121
2122         is_discovering = TRUE;
2123         cancel_by_user = FALSE;
2124         /* discovery status will be change in event */
2125         g_variant_unref(result);
2126         return BLUETOOTH_ERROR_NONE;
2127 }
2128
2129 int _bt_cancel_discovery(void)
2130 {
2131         GDBusProxy *proxy;
2132         GError *error = NULL;
2133         GVariant *result;
2134
2135         if (_bt_is_discovering() == FALSE) {
2136                 BT_ERR("BT is not in discovering");
2137                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2138         }
2139
2140         proxy = _bt_get_adapter_proxy();
2141         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2142
2143         result = g_dbus_proxy_call_sync(proxy,
2144                                 "StopDiscovery",
2145                                 NULL,
2146                                 G_DBUS_CALL_FLAGS_NONE,
2147                                 -1,
2148                                 NULL,
2149                                 &error);
2150
2151         if (!result) {
2152                 int ret = BLUETOOTH_ERROR_INTERNAL;
2153                 if (error != NULL) {
2154                         BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2155
2156                         if (g_strrstr(error->message, "No discovery started"))
2157                                 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2158
2159                         g_clear_error(&error);
2160                 } else {
2161                         BT_ERR("StopDiscovery failed");
2162                 }
2163
2164                 return ret;
2165         }
2166
2167         cancel_by_user = TRUE;
2168         /* discovery status will be change in event */
2169         g_variant_unref(result);
2170         return BLUETOOTH_ERROR_NONE;
2171 }
2172
2173 gboolean _bt_is_discovering(void)
2174 {
2175         return is_discovering;
2176 }
2177
2178 gboolean _bt_is_connectable(void)
2179 {
2180         GDBusProxy *proxy;
2181         GError *error = NULL;
2182         gboolean is_connectable = FALSE;
2183         GVariant *result;
2184         GVariant *temp;
2185
2186         proxy = _bt_get_adapter_properties_proxy();
2187         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2188
2189         result = g_dbus_proxy_call_sync(proxy,
2190                                 "Get",
2191                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2192                                         "Connectable"),
2193                                 G_DBUS_CALL_FLAGS_NONE,
2194                                 -1,
2195                                 NULL,
2196                                 &error);
2197
2198         if (!result) {
2199                 if (error != NULL) {
2200                         BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2201                         g_clear_error(&error);
2202                 } else
2203                         BT_ERR("Failed to get connectable property");
2204                 return BLUETOOTH_ERROR_INTERNAL;
2205         }
2206
2207         g_variant_get(result, "(v)", &temp);
2208         is_connectable = g_variant_get_boolean(temp);
2209         BT_DBG("discoverable_v:%d", is_connectable);
2210
2211         g_variant_unref(result);
2212         g_variant_unref(temp);
2213
2214         BT_INFO("Get connectable [%d]", is_connectable);
2215         return is_connectable;
2216 }
2217
2218 int _bt_set_connectable(gboolean is_connectable)
2219 {
2220         GDBusProxy *proxy;
2221         GError *error = NULL;
2222         GVariant *result;
2223
2224         if (__bt_is_factory_test_mode()) {
2225                 BT_ERR("Unable to set connectable in factory binary !!");
2226                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2227         }
2228
2229         proxy = _bt_get_adapter_properties_proxy();
2230
2231         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2232
2233         result = g_dbus_proxy_call_sync(proxy,
2234                                 "Set",
2235                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2236                                                 g_variant_new("b", is_connectable)),
2237                                 G_DBUS_CALL_FLAGS_NONE,
2238                                 -1,
2239                                 NULL,
2240                                 &error);
2241
2242         if (!result) {
2243                 if (error != NULL) {
2244                         BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2245                         g_clear_error(&error);
2246                 } else
2247                         BT_ERR("Failed to set connectable property");
2248                 return BLUETOOTH_ERROR_INTERNAL;
2249         }
2250
2251         BT_INFO_C("### Set connectable [%d]", is_connectable);
2252         g_variant_unref(result);
2253         return BLUETOOTH_ERROR_NONE;
2254 }
2255
2256 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2257 {
2258         GDBusProxy *proxy;
2259         gboolean discovering_v;
2260         GError *error = NULL;
2261         char *discovering_type =  NULL;
2262         GVariant *result;
2263         GVariant *temp;
2264
2265         proxy = _bt_get_adapter_properties_proxy();
2266         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2267
2268         if (discovery_type == DISCOVERY_ROLE_BREDR)
2269                 discovering_type = "Discovering";
2270         else if (discovery_type == DISCOVERY_ROLE_LE)
2271                 discovering_type = "LEDiscovering";
2272
2273         result = g_dbus_proxy_call_sync(proxy,
2274                                 "Get",
2275                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2276                                         discovering_type),
2277                                 G_DBUS_CALL_FLAGS_NONE,
2278                                 -1,
2279                                 NULL,
2280                                 &error);
2281
2282         if (!result) {
2283                 if (error != NULL) {
2284                         BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2285                         g_clear_error(&error);
2286                 } else
2287                         BT_ERR("Failed to get discovering property");
2288                 return BLUETOOTH_ERROR_INTERNAL;
2289         }
2290
2291         g_variant_get(result, "(v)", &temp);
2292         discovering_v = g_variant_get_boolean(temp);
2293         BT_DBG("discoverable_v:%d", discovering_v);
2294
2295         g_variant_unref(result);
2296         g_variant_unref(temp);
2297
2298         return discovering_v;
2299 }
2300
2301 unsigned int _bt_get_discoverable_timeout_property(void)
2302 {
2303         GDBusProxy *proxy;
2304         unsigned int timeout_v;
2305         GError *error = NULL;
2306         GVariant *result;
2307         GVariant *temp;
2308
2309         proxy = _bt_get_adapter_properties_proxy();
2310         retv_if(proxy == NULL, 0);
2311
2312         result = g_dbus_proxy_call_sync(proxy,
2313                                 "Get",
2314                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2315                                         "DiscoverableTimeout"),
2316                                 G_DBUS_CALL_FLAGS_NONE,
2317                                 -1,
2318                                 NULL,
2319                                 &error);
2320
2321         if (!result) {
2322                 BT_ERR("Fail to get discoverable timeout");
2323                 if (error != NULL) {
2324                         BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2325                         g_clear_error(&error);
2326                 }
2327                 return 0;
2328         }
2329
2330         g_variant_get(result, "(v)", &temp);
2331         timeout_v = g_variant_get_uint32(temp);
2332         BT_DBG("discoverable_v:%d", timeout_v);
2333
2334         g_variant_unref(result);
2335         g_variant_unref(temp);
2336
2337         return timeout_v;
2338 }
2339
2340 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2341 {
2342         bluetooth_device_info_t *dev_info;
2343         GVariant *value;
2344         const gchar *key;
2345         GByteArray *manufacturer_data = NULL;
2346         guint8 char_value;
2347         GVariantIter *char_value_iter;
2348
2349         dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2350
2351         while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2352
2353                 if (key == NULL)
2354                         continue;
2355
2356                 if (!g_strcmp0(key, "Address")) {
2357                         const char *address = NULL;
2358                         address = g_variant_get_string(value, NULL);
2359                         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2360                                                         address);
2361                 } else if (!g_strcmp0(key, "Class")) {
2362                         unsigned int cod;
2363                         cod = g_variant_get_uint32(value);
2364                         _bt_divide_device_class(&dev_info->device_class, cod);
2365                 } else if (!g_strcmp0(key, "Name")) {
2366                         const char *name = NULL;
2367                         name = g_variant_get_string(value, NULL);
2368                         /* If there is no Alias */
2369                         if (strlen(dev_info->device_name.name) == 0) {
2370                                 g_strlcpy(dev_info->device_name.name, name,
2371                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2372                         }
2373                 } else if (!g_strcmp0(key, "Alias")) {
2374                         const char *alias = NULL;
2375                         alias = g_variant_get_string(value, NULL);
2376                         /* Overwrite the name */
2377                         if (alias) {
2378                                 memset(dev_info->device_name.name, 0x00,
2379                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2380                                 g_strlcpy(dev_info->device_name.name, alias,
2381                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2382                         }
2383                 } else if (!g_strcmp0(key, "IsAliasSet")) {
2384                         dev_info->is_alias_set = g_variant_get_boolean(value);
2385                 } else if (!g_strcmp0(key, "Connected")) {
2386                         dev_info->connected = g_variant_get_byte(value);
2387                 } else if (!g_strcmp0(key, "Paired")) {
2388                         dev_info->paired = g_variant_get_boolean(value);
2389                 } else if (!g_strcmp0(key, "Trusted")) {
2390                         dev_info->trust = g_variant_get_boolean(value);
2391                 } else if (!g_strcmp0(key, "RSSI")) {
2392                         dev_info->rssi = g_variant_get_int16(value);
2393                 } else if (!g_strcmp0(key, "UUIDs")) {
2394                         GVariantIter *iter;
2395                         gchar *uuid = NULL;
2396                         char **parts;
2397                         int i = 0;
2398
2399                         dev_info->service_index = 0;
2400                         g_variant_get(value, "as", &iter);
2401                         while (g_variant_iter_loop(iter, "s", &uuid)) {
2402                                 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2403                                 parts = g_strsplit(uuid, "-", -1);
2404
2405                                 if (parts == NULL || parts[0] == NULL) {
2406                                         g_free(uuid);
2407                                         break;
2408                                 }
2409
2410                                 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2411                                 g_strfreev(parts);
2412
2413                                 i++;
2414                         }
2415                         dev_info->service_index = i;
2416                         g_variant_iter_free(iter);
2417                 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2418                         dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2419                 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2420                         manufacturer_data = g_byte_array_new();
2421                         g_variant_get(value, "ay", &char_value_iter);
2422                         while (g_variant_iter_loop(char_value_iter, "y",  &char_value))
2423                                 g_byte_array_append(manufacturer_data, &char_value, 1);
2424
2425                         if (manufacturer_data) {
2426                                 if (manufacturer_data->len > 0)
2427                                         memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2428                         }
2429                         g_variant_iter_free(char_value_iter);
2430                         g_byte_array_free(manufacturer_data, TRUE);
2431                 }
2432         }
2433
2434         return dev_info;
2435 }
2436
2437 static void __bt_extract_device_info(GVariantIter *iter,
2438                                                         GArray **dev_list)
2439 {
2440         bluetooth_device_info_t *dev_info = NULL;
2441         char *object_path = NULL;
2442         GVariantIter *interface_iter;
2443         GVariantIter *svc_iter;
2444         char *interface_str = NULL;
2445
2446         /* Parse the signature:  oa{sa{sv}}} */
2447         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2448                 &interface_iter)) {
2449
2450                 if (object_path == NULL)
2451                         continue;
2452
2453                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2454                                 &interface_str, &svc_iter)) {
2455                         if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2456                                 BT_DBG("Found a device: %s", object_path);
2457                                 dev_info = __bt_parse_device_info(svc_iter);
2458                                 if (dev_info) {
2459                                         if (dev_info->paired == TRUE) {
2460                                                 g_array_append_vals(*dev_list, dev_info,
2461                                                                 sizeof(bluetooth_device_info_t));
2462                                         }
2463                                         g_free(dev_info);
2464                                 }
2465                                 g_free(interface_str);
2466                                 g_variant_iter_free(svc_iter);
2467                                 break;
2468                         }
2469                 }
2470         }
2471         BT_DBG("-");
2472 }
2473
2474 int _bt_get_bonded_devices(GArray **dev_list)
2475 {
2476         BT_DBG("+");
2477         GDBusConnection *conn;
2478         GDBusProxy *manager_proxy;
2479         GVariant *result = NULL;
2480         GVariantIter *iter = NULL;
2481         GError *error = NULL;
2482
2483         conn = _bt_gdbus_get_system_gconn();
2484         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2485
2486         manager_proxy = _bt_get_manager_proxy();
2487         retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2488
2489         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2490                                 NULL,
2491                                 G_DBUS_CALL_FLAGS_NONE,
2492                                 -1,
2493                                 NULL,
2494                                 NULL);
2495
2496         if (!result) {
2497                 if (error != NULL) {
2498                         BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2499                         g_clear_error(&error);
2500                 } else
2501                         BT_ERR("Failed to Failed to GetManagedObjects");
2502                 return BLUETOOTH_ERROR_INTERNAL;
2503         }
2504
2505         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
2506         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2507
2508         __bt_extract_device_info(iter, dev_list);
2509         g_variant_iter_free(iter);
2510         g_variant_unref(result);
2511
2512         BT_DBG("-");
2513         return BLUETOOTH_ERROR_NONE;
2514 }
2515
2516 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2517 {
2518         BT_DBG("+");
2519         GDBusConnection *conn;
2520         GDBusProxy *manager_proxy;
2521         GVariant *result = NULL;
2522         GVariant *result1 = NULL;
2523         GVariantIter *iter = NULL;
2524         GError *error = NULL;
2525         char *object_path = NULL;
2526         GVariantIter *interface_iter;
2527         char *interface_str = NULL;
2528         GDBusProxy *device_proxy = NULL;
2529         gboolean is_connected = FALSE;
2530
2531         conn = _bt_gdbus_get_system_gconn();
2532         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2533
2534         manager_proxy = _bt_get_manager_proxy();
2535         retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2536
2537         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2538                                 NULL,
2539                                 G_DBUS_CALL_FLAGS_NONE,
2540                                 -1,
2541                                 NULL,
2542                                 NULL);
2543
2544         if (!result) {
2545                 if (error != NULL) {
2546                         BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2547                         g_clear_error(&error);
2548                         error = NULL;
2549                 } else
2550                         BT_ERR("Failed to Failed to GetManagedObjects");
2551                 return BLUETOOTH_ERROR_INTERNAL;
2552         }
2553
2554         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
2555         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2556
2557         /* Parse the signature:  oa{sa{sv}}} */
2558         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2559                 if (object_path == NULL)
2560                         continue;
2561
2562                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2563                                 &interface_str, NULL)) {
2564                         if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2565                                 BT_DBG("Found a device: %s", object_path);
2566                                 g_free(interface_str);
2567
2568                                 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2569                                                                                         NULL, BT_BLUEZ_NAME,
2570                                                                                         object_path, BT_DEVICE_INTERFACE,  NULL, NULL);
2571
2572                                 if (device_proxy == NULL) {
2573                                         BT_DBG("Device don't have this service");
2574                                         break;
2575                                 }
2576
2577                                 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2578                                                         g_variant_new("(s)", profile_uuid),
2579                                                         G_DBUS_CALL_FLAGS_NONE,
2580                                                         -1,
2581                                                         NULL,
2582                                                         &error);
2583
2584                                 if (result1 == NULL) {
2585                                         BT_ERR("Error occured in Proxy call");
2586                                         if (error) {
2587                                                 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2588                                                 g_error_free(error);
2589                                                 error = NULL;
2590                                         }
2591                                         g_object_unref(device_proxy);
2592                                         break;
2593                                 }
2594                                 g_variant_get(result1, "(b)", &is_connected);
2595
2596                                 if (is_connected == TRUE) {
2597                                         char address[BT_ADDRESS_STRING_SIZE];
2598                                         bluetooth_device_address_t *addr = NULL;
2599
2600                                         _bt_convert_device_path_to_address(object_path, address);
2601
2602                                         addr = g_malloc0(sizeof(bluetooth_device_address_t));
2603                                         _bt_convert_addr_string_to_type(addr->addr, address);
2604
2605                                         g_array_append_vals(*addr_list, addr,
2606                                                         sizeof(bluetooth_device_address_t));
2607                                 }
2608
2609                                 g_variant_unref(result1);
2610                                 g_object_unref(device_proxy);
2611
2612                                 break;
2613                         }
2614                 }
2615         }
2616
2617         g_variant_unref(result);
2618         g_variant_iter_free(iter);
2619
2620         BT_DBG("-");
2621         return BLUETOOTH_ERROR_NONE;
2622 }
2623
2624 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2625                                 bluetooth_device_info_t *dev_info)
2626 {
2627         char *object_path = NULL;
2628         GDBusProxy *adapter_proxy;
2629         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2630         int ret = BLUETOOTH_ERROR_NONE;
2631
2632         BT_CHECK_PARAMETER(device_address, return);
2633         BT_CHECK_PARAMETER(dev_info, return);
2634
2635         adapter_proxy = _bt_get_adapter_proxy();
2636         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2637
2638         _bt_convert_addr_type_to_string(address, device_address->addr);
2639
2640         object_path = _bt_get_device_object_path(address);
2641
2642         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2643
2644         ret = __bt_get_bonded_device_info(object_path, dev_info);
2645         g_free(object_path);
2646
2647         return ret;
2648 }
2649
2650 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2651 {
2652         char *object_path = NULL;
2653         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2654         gboolean alias_set = FALSE;
2655
2656         GDBusConnection *conn;
2657         GDBusProxy *device_proxy;
2658         GError *error = NULL;
2659         GVariant *result = NULL;
2660         GVariant *temp = NULL;
2661
2662
2663         BT_CHECK_PARAMETER(device_address, return);
2664         BT_CHECK_PARAMETER(is_alias_set, return);
2665
2666         _bt_convert_addr_type_to_string(address, device_address->addr);
2667
2668         object_path = _bt_get_device_object_path(address);
2669         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2670
2671         conn = _bt_gdbus_get_system_gconn();
2672         if (conn == NULL) {
2673                 g_free(object_path);
2674                 return BLUETOOTH_ERROR_INTERNAL;
2675         }
2676
2677         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2678                         NULL,
2679                         BT_BLUEZ_NAME,
2680                         object_path,
2681                         BT_PROPERTIES_INTERFACE,
2682                         NULL, NULL);
2683         if (device_proxy == NULL) {
2684                 g_free(object_path);
2685                 return BLUETOOTH_ERROR_INTERNAL;
2686         }
2687
2688         result = g_dbus_proxy_call_sync(device_proxy, "Get",
2689                         g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2690                         G_DBUS_CALL_FLAGS_NONE,
2691                         -1,
2692                         NULL,
2693                         &error);
2694
2695         if (!result) {
2696                 BT_ERR("Error occured in Proxy call");
2697                 if (error != NULL) {
2698                         BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2699                         g_error_free(error);
2700                 }
2701                 g_object_unref(device_proxy);
2702                 g_free(object_path);
2703                 return BLUETOOTH_ERROR_INTERNAL;
2704         }
2705
2706         g_variant_get(result, "(v)", &temp);
2707         alias_set = g_variant_get_boolean(temp);
2708         *is_alias_set = alias_set;
2709         BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2710         g_variant_unref(temp);
2711         g_variant_unref(result);
2712         g_object_unref(device_proxy);
2713
2714         g_free(object_path);
2715
2716         return BLUETOOTH_ERROR_NONE;
2717 }
2718
2719 int _bt_get_timeout_value(int *timeout)
2720 {
2721         time_t current_time;
2722         int time_diff;
2723
2724         /* Take current time */
2725         time(&current_time);
2726         time_diff = difftime(current_time, visible_timer.start_time);
2727
2728         BT_DBG("Time diff = %d\n", time_diff);
2729
2730         *timeout = visible_timer.timeout - time_diff;
2731
2732         return BLUETOOTH_ERROR_NONE;
2733 }
2734
2735 int _bt_set_le_privacy(gboolean set_privacy)
2736 {
2737         GDBusProxy *proxy;
2738         GError *error = NULL;
2739         GVariant *result = NULL;
2740
2741         if (__bt_is_factory_test_mode()) {
2742                 BT_ERR("Unable to set le privacy in factory binary !!");
2743                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2744         }
2745
2746         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2747                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2748                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2749         }
2750
2751         proxy = _bt_get_adapter_proxy();
2752         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2753
2754         result = g_dbus_proxy_call_sync(proxy,
2755                                 "SetLePrivacy",
2756                                 g_variant_new("(b)", set_privacy),
2757                                 G_DBUS_CALL_FLAGS_NONE,
2758                                 -1,
2759                                 NULL,
2760                                 &error);
2761
2762         if (!result) {
2763                 if (error != NULL) {
2764                         BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2765                         g_clear_error(&error);
2766                 } else
2767                         BT_ERR("Failed to SetLePrivacy");
2768                 return BLUETOOTH_ERROR_INTERNAL;
2769         }
2770
2771         g_variant_unref(result);
2772         BT_INFO("SetLePrivacy as %d", set_privacy);
2773         return BLUETOOTH_ERROR_NONE;
2774 }
2775
2776 int _bt_set_le_static_random_address(gboolean is_enable)
2777 {
2778         GDBusProxy *proxy;
2779         GError *error = NULL;
2780         GVariant *result = NULL;
2781
2782         if (__bt_is_factory_test_mode()) {
2783                 BT_ERR("Unable to set le random address in factory binary !!");
2784                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2785         }
2786
2787         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2788                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2789                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2790         }
2791
2792         proxy = _bt_get_adapter_proxy();
2793         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2794
2795         result = g_dbus_proxy_call_sync(proxy,
2796                                 "SetLeStaticRandomAddress",
2797                                 g_variant_new("(b)", is_enable),
2798                                 G_DBUS_CALL_FLAGS_NONE,
2799                                 -1,
2800                                 NULL,
2801                                 &error);
2802
2803         if (!result) {
2804                 if (error != NULL) {
2805                         BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2806                         g_clear_error(&error);
2807                 } else
2808                         BT_ERR("Failed to SetLeStaticRandomAddress");
2809                 return BLUETOOTH_ERROR_INTERNAL;
2810         }
2811
2812         g_variant_unref(result);
2813         BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2814         return BLUETOOTH_ERROR_NONE;
2815 }
2816
2817 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2818 {
2819         GDBusProxy *proxy;
2820         GError *error = NULL;
2821         int i;
2822         GVariant *val;
2823         GVariant *result;
2824         GVariantBuilder *builder;
2825
2826         BT_CHECK_PARAMETER(m_data, return);
2827
2828         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2829                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2830                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2831         }
2832
2833         proxy = _bt_get_adapter_proxy();
2834         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2835
2836         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2837
2838         for (i = 0; i < (m_data->data_len) + 2; i++)
2839                 g_variant_builder_add(builder, "y", m_data->data[i]);
2840
2841         val = g_variant_new("(ay)", builder);
2842
2843         result = g_dbus_proxy_call_sync(proxy,
2844                                 "SetManufacturerData",
2845                                 val,
2846                                 G_DBUS_CALL_FLAGS_NONE,
2847                                 -1,
2848                                 NULL,
2849                                 &error);
2850         g_variant_builder_unref(builder);
2851         if (!result) {
2852                 if (error != NULL) {
2853                         BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2854                         g_clear_error(&error);
2855                 } else {
2856                         BT_ERR("Failed to SetManufacturerData");
2857                 }
2858                 return BLUETOOTH_ERROR_INTERNAL;
2859         }
2860         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2861
2862         for (i = 0; i < (m_data->data_len) + 2; i++)
2863                 g_variant_builder_add(builder, "y", m_data->data[i]);
2864
2865         val = g_variant_new("(ay)", builder);
2866
2867         _bt_send_event(BT_ADAPTER_EVENT,
2868                         BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2869                         val);
2870
2871         BT_INFO("Set manufacturer data");
2872
2873         g_variant_builder_unref(builder);
2874         g_variant_unref(result);
2875
2876         return BLUETOOTH_ERROR_NONE;
2877 }
2878
2879
2880 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2881 {
2882         int result = BLUETOOTH_ERROR_NONE;
2883         bt_service_alarm_t *alarm = NULL;
2884
2885         if (!call_back || !alarm_id)
2886                 return BLUETOOTH_ERROR_INVALID_PARAM;
2887
2888         if (!alarm_mgr.is_alarm_initialized) {
2889                 result = alarmmgr_init("bt-service");
2890                 if (result != 0) {
2891                         BT_ERR("Failed to initialize alarm = %d", result);
2892                         result = BLUETOOTH_ERROR_INTERNAL;
2893                         goto finish;
2894                 }
2895                 result = alarmmgr_set_cb(alarm_cb, NULL);
2896                 if (result != 0) {
2897                         BT_ERR("Failed to set the callback = %d", result);
2898                         result = BLUETOOTH_ERROR_INTERNAL;
2899                         goto finish;
2900                 }
2901                 alarm_mgr.is_alarm_initialized = TRUE;
2902         }
2903
2904         alarm = g_malloc0(sizeof(bt_service_alarm_t));
2905         if (!alarm)
2906                 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2907
2908         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
2909                                                 0, NULL, alarm_id);
2910         if (result != 0) {
2911                 BT_ERR("Failed to create alarm error = %d", result);
2912                 result = BLUETOOTH_ERROR_INTERNAL;
2913                 g_free(alarm);
2914                 goto finish;
2915         }
2916         alarm->alarm_id = *alarm_id;
2917         alarm->callback = call_back;
2918         alarm->user_data = user_data;
2919
2920         alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
2921         result = BLUETOOTH_ERROR_NONE;
2922 finish:
2923         return result;
2924 }
2925
2926 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
2927 {
2928         GList *node = NULL;
2929         bt_service_alarm_t *p_data;
2930         bt_set_alarm_cb callback = NULL;
2931         void *user_data = NULL;
2932
2933         node = g_list_find_custom(alarm_mgr.g_alarm_list,
2934                         GINT_TO_POINTER(alarm_id), compare_alarm);
2935         if (!node)
2936                 return 0;
2937
2938         p_data = (bt_service_alarm_t *)node->data;
2939         alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
2940                         node);
2941
2942         if (!p_data)
2943                 return 0;
2944
2945         callback = p_data->callback;
2946         user_data = p_data->user_data;
2947         g_free(p_data);
2948
2949         if (callback)
2950                 callback(alarm_id, user_data);
2951
2952         return 0;
2953 }
2954
2955 int _bt_service_remove_alarm(alarm_id_t alarm_id)
2956 {
2957         GList *list = NULL;
2958         bt_service_alarm_t *p_data;
2959         list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
2960
2961         if (list != NULL) {
2962                 alarmmgr_remove_alarm(alarm_id);
2963                 p_data = (bt_service_alarm_t *)list->data;
2964                 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
2965                 g_free(p_data);
2966         }
2967
2968         return 0;
2969 }
2970
2971 gint compare_alarm(gconstpointer list_data, gconstpointer data)
2972 {
2973 #ifdef ARCH64
2974         alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
2975 #else
2976         alarm_id_t alarm_id = (alarm_id_t)data;
2977 #endif
2978         bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
2979
2980         if (p_data->alarm_id == alarm_id)
2981                 return 0;
2982
2983         return 1;
2984 }
2985
2986 static void alarm_data_free(void *data)
2987 {
2988         bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
2989         g_free(p_data);
2990         return;
2991 }
2992
2993 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
2994 {
2995         int result;
2996 #ifdef ARCH64
2997         int function = (int)(uintptr_t)user_data;
2998 #else
2999         int function = (int)user_data;
3000 #endif
3001
3002         switch (function) {
3003         case BT_ENABLE_ADAPTER:
3004                 result = _bt_enable_adapter();
3005                 if (result != BLUETOOTH_ERROR_NONE) {
3006                         BT_ERR("_bt_enable_adapter is failed");
3007                         /* Send enabled event to API */
3008                         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3009                                         g_variant_new("(i)", result));
3010                 }
3011                 break;
3012         case BT_DISABLE_ADAPTER:
3013                 result = _bt_disable_adapter();
3014                 if (result != BLUETOOTH_ERROR_NONE) {
3015                         BT_ERR("_bt_disable_adapter is failed");
3016                         /* Send disabled event to API */
3017                         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3018                                         g_variant_new("(i)", result));
3019                 }
3020                 break;
3021         default:
3022                 BT_ERR("function is NOT matched");
3023                 break;
3024         }
3025
3026         return FALSE;
3027 }
3028
3029 int _bt_adapter_request_delayed(int function)
3030 {
3031         int ret;
3032
3033         switch (function) {
3034         case BT_ENABLE_ADAPTER:
3035                 ret = _bt_enable_adapter_check_status();
3036                 if (ret == BLUETOOTH_ERROR_NONE)
3037                         _bt_adapter_set_status(BT_ACTIVATING);
3038                 else
3039                         return ret;
3040
3041                 break;
3042         case BT_DISABLE_ADAPTER:
3043                 ret = _bt_disable_adapter_check_status();
3044                 if (ret == BLUETOOTH_ERROR_NONE)
3045                         _bt_adapter_set_status(BT_DEACTIVATING);
3046                 else
3047                         return ret;
3048
3049                 break;
3050         default:
3051                 BT_ERR("function is NOT matched");
3052                 return BLUETOOTH_ERROR_INTERNAL;
3053         }
3054
3055 #ifdef ARCH64
3056         g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3057 #else
3058         g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3059 #endif
3060
3061         return BLUETOOTH_ERROR_NONE;
3062 }
3063
3064 #ifdef TIZEN_PROFILE_TV
3065 int _bt_get_enable_timer_id(void)
3066 {
3067         return timer_id;
3068 }
3069 #endif