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