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