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