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