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