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