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