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