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