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