Fix bt-service crash issue
[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         g_variant_unref(temp);
1932
1933         BT_DBG("Service Used? %d", *used);
1934
1935         return ret;
1936 }
1937
1938 static gboolean __bt_get_discoverable_property(void)
1939 {
1940         GDBusProxy *proxy;
1941         gboolean discoverable_v;
1942         GError *error = NULL;
1943         GVariant *result;
1944         GVariant *temp;
1945
1946         proxy = _bt_get_adapter_properties_proxy();
1947         retv_if(proxy == NULL, FALSE);
1948
1949         result = g_dbus_proxy_call_sync(proxy,
1950                                 "Get",
1951                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1952                                         "Discoverable"),
1953                                 G_DBUS_CALL_FLAGS_NONE,
1954                                 -1,
1955                                 NULL,
1956                                 &error);
1957
1958         if (!result) {
1959                 if (error != NULL) {
1960                         BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1961                         g_clear_error(&error);
1962                 } else
1963                         BT_ERR("Failed to get Discoverable property");
1964                 return BLUETOOTH_ERROR_INTERNAL;
1965         }
1966
1967         g_variant_get(result, "(v)", &temp);
1968         discoverable_v = g_variant_get_boolean(temp);
1969         BT_DBG("discoverable_v:%d", discoverable_v);
1970
1971         g_variant_unref(result);
1972         g_variant_unref(temp);
1973
1974         return discoverable_v;
1975 }
1976
1977 int _bt_get_discoverable_mode(int *mode)
1978 {
1979         gboolean discoverable;
1980         unsigned int timeout;
1981
1982         BT_CHECK_PARAMETER(mode, return);
1983
1984         discoverable = __bt_get_discoverable_property();
1985         timeout = _bt_get_discoverable_timeout_property();
1986
1987         if (discoverable == TRUE) {
1988                 if (timeout == 0)
1989                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1990                 else
1991                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1992         } else {
1993                 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1994         }
1995         return BLUETOOTH_ERROR_NONE;
1996 }
1997
1998
1999 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
2000 {
2001         int ret = BLUETOOTH_ERROR_NONE;
2002         gboolean inq_scan;
2003         gboolean pg_scan;
2004         GError *error = NULL;
2005         GDBusProxy *proxy;
2006         GVariant *result;
2007
2008         proxy = _bt_get_adapter_properties_proxy();
2009
2010         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2011
2012 #ifdef TIZEN_DPM_ENABLE
2013         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
2014                 _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
2015                 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT_HANDSFREE");
2016                 return BLUETOOTH_ERROR_ACCESS_DENIED;
2017         }
2018         if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
2019                  _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
2020                 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT");
2021                 return BLUETOOTH_ERROR_ACCESS_DENIED;
2022         }
2023 #endif
2024
2025         switch (discoverable_mode) {
2026         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
2027                 pg_scan = TRUE;
2028                 inq_scan = FALSE;
2029                 timeout = 0;
2030                 break;
2031         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
2032                 pg_scan = TRUE;
2033                 inq_scan = TRUE;
2034                 timeout = 0;
2035                 break;
2036         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
2037                 inq_scan = TRUE;
2038                 pg_scan = TRUE;
2039                 break;
2040         default:
2041                 return BLUETOOTH_ERROR_INVALID_PARAM;
2042         }
2043
2044         BT_INFO("Req. discoverable_mode : %d, timeout : %d",
2045                         discoverable_mode, timeout);
2046
2047         result = g_dbus_proxy_call_sync(proxy,
2048                                 "Set",
2049                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2050                                         "Connectable", g_variant_new("b", pg_scan)),
2051                                 G_DBUS_CALL_FLAGS_NONE,
2052                                 -1,
2053                                 NULL,
2054                                 &error);
2055
2056         if (!result) {
2057                 if (error != NULL) {
2058                         BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2059                         g_clear_error(&error);
2060                 } else
2061                         BT_ERR("Failed to set connectable property");
2062                 return BLUETOOTH_ERROR_INTERNAL;
2063         }
2064         g_variant_unref(result);
2065         result = g_dbus_proxy_call_sync(proxy,
2066                                 "Set",
2067                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2068                                                 g_variant_new("b", inq_scan)),
2069                                 G_DBUS_CALL_FLAGS_NONE,
2070                                 -1,
2071                                 NULL,
2072                                 &error);
2073
2074         if (!result) {
2075                 if (error != NULL) {
2076                         BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2077                         g_clear_error(&error);
2078                 } else
2079                         BT_ERR("Failed to set Discoverable property");
2080                 return BLUETOOTH_ERROR_INTERNAL;
2081         }
2082         g_variant_unref(result);
2083         result = g_dbus_proxy_call_sync(proxy,
2084                                 "Set",
2085                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2086                                         "DiscoverableTimeout", g_variant_new("u", timeout)),
2087                                 G_DBUS_CALL_FLAGS_NONE,
2088                                 -1,
2089                                 NULL,
2090                                 &error);
2091
2092         if (!result) {
2093                 if (error != NULL) {
2094                         BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2095                         g_clear_error(&error);
2096                 } else
2097                         BT_ERR("Failed to set DiscoverableTimeout property");
2098                 return BLUETOOTH_ERROR_INTERNAL;
2099         }
2100
2101         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2102                 timeout = -1;
2103
2104         ret = __bt_set_visible_time(timeout);
2105
2106         g_variant_unref(result);
2107
2108         return ret;
2109 }
2110
2111 int _bt_start_discovery(void)
2112 {
2113         GDBusProxy *proxy;
2114         GError *error = NULL;
2115         GVariant *result;
2116
2117         if (_bt_is_discovering() == TRUE) {
2118                 BT_ERR("BT is already in discovering");
2119                 return BLUETOOTH_ERROR_IN_PROGRESS;
2120         } else if (_bt_is_device_creating() == TRUE) {
2121                 BT_ERR("Bonding device is going on");
2122                 return BLUETOOTH_ERROR_DEVICE_BUSY;
2123         }
2124
2125         proxy = _bt_get_adapter_proxy();
2126         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2127
2128         result = g_dbus_proxy_call_sync(proxy,
2129                                 "StartDiscovery",
2130                                 NULL,
2131                                 G_DBUS_CALL_FLAGS_NONE,
2132                                 -1,
2133                                 NULL,
2134                                 &error);
2135
2136         if (!result) {
2137                 if (error != NULL) {
2138                         BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2139                         g_clear_error(&error);
2140                 } else
2141                         BT_ERR("StartDiscovery failed");
2142                 return BLUETOOTH_ERROR_INTERNAL;
2143         }
2144
2145         is_discovering = TRUE;
2146         cancel_by_user = FALSE;
2147         /* discovery status will be change in event */
2148         g_variant_unref(result);
2149         return BLUETOOTH_ERROR_NONE;
2150 }
2151
2152 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2153 {
2154         GDBusProxy *proxy;
2155         GVariant *result;
2156         GError *error = NULL;
2157         const gchar *disc_type;
2158
2159         if (_bt_is_discovering() == TRUE) {
2160                 BT_ERR("BT is already in discovering");
2161                 return BLUETOOTH_ERROR_IN_PROGRESS;
2162         }
2163
2164         proxy = _bt_get_adapter_proxy();
2165         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2166
2167         if (role == DISCOVERY_ROLE_BREDR)
2168                 disc_type = "BREDR";
2169         else if (role == DISCOVERY_ROLE_LE)
2170                 disc_type = "LE";
2171         else if (role == DISCOVERY_ROLE_LE_BREDR)
2172                 disc_type = "LE_BREDR";
2173         else
2174                 return BLUETOOTH_ERROR_INVALID_PARAM;
2175
2176         result = g_dbus_proxy_call_sync(proxy,
2177                                 "StartCustomDiscovery",
2178                                 g_variant_new("s", disc_type),
2179                                 G_DBUS_CALL_FLAGS_NONE,
2180                                 -1,
2181                                 NULL,
2182                                 &error);
2183
2184         if (!result) {
2185                 if (error != NULL) {
2186                         BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2187                         g_clear_error(&error);
2188                 } else
2189                         BT_ERR("StartCustomDiscovery failed");
2190                 return BLUETOOTH_ERROR_INTERNAL;
2191         }
2192
2193         is_discovering = TRUE;
2194         cancel_by_user = FALSE;
2195         /* discovery status will be change in event */
2196         g_variant_unref(result);
2197         return BLUETOOTH_ERROR_NONE;
2198 }
2199
2200 int _bt_cancel_discovery(void)
2201 {
2202         GDBusProxy *proxy;
2203         GError *error = NULL;
2204         GVariant *result;
2205
2206         if (_bt_is_discovering() == FALSE) {
2207                 BT_ERR("BT is not in discovering");
2208                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2209         }
2210
2211         proxy = _bt_get_adapter_proxy();
2212         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2213
2214         result = g_dbus_proxy_call_sync(proxy,
2215                                 "StopDiscovery",
2216                                 NULL,
2217                                 G_DBUS_CALL_FLAGS_NONE,
2218                                 -1,
2219                                 NULL,
2220                                 &error);
2221
2222         if (!result) {
2223                 int ret = BLUETOOTH_ERROR_INTERNAL;
2224                 if (error != NULL) {
2225                         BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2226
2227                         if (g_strrstr(error->message, "No discovery started"))
2228                                 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2229
2230                         g_clear_error(&error);
2231                 } else {
2232                         BT_ERR("StopDiscovery failed");
2233                 }
2234
2235                 return ret;
2236         }
2237
2238         cancel_by_user = TRUE;
2239         /* discovery status will be change in event */
2240         g_variant_unref(result);
2241         return BLUETOOTH_ERROR_NONE;
2242 }
2243
2244 gboolean _bt_is_discovering(void)
2245 {
2246         return is_discovering;
2247 }
2248
2249 gboolean _bt_is_connectable(void)
2250 {
2251         GDBusProxy *proxy;
2252         GError *error = NULL;
2253         gboolean is_connectable = FALSE;
2254         GVariant *result;
2255         GVariant *temp;
2256
2257         proxy = _bt_get_adapter_properties_proxy();
2258         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2259
2260         result = g_dbus_proxy_call_sync(proxy,
2261                                 "Get",
2262                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2263                                         "Connectable"),
2264                                 G_DBUS_CALL_FLAGS_NONE,
2265                                 -1,
2266                                 NULL,
2267                                 &error);
2268
2269         if (!result) {
2270                 if (error != NULL) {
2271                         BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2272                         g_clear_error(&error);
2273                 } else
2274                         BT_ERR("Failed to get connectable property");
2275                 return BLUETOOTH_ERROR_INTERNAL;
2276         }
2277
2278         g_variant_get(result, "(v)", &temp);
2279         is_connectable = g_variant_get_boolean(temp);
2280         BT_DBG("discoverable_v:%d", is_connectable);
2281
2282         g_variant_unref(result);
2283         g_variant_unref(temp);
2284
2285         BT_INFO("Get connectable [%d]", is_connectable);
2286         return is_connectable;
2287 }
2288
2289 int _bt_set_connectable(gboolean is_connectable)
2290 {
2291         GDBusProxy *proxy;
2292         GError *error = NULL;
2293         GVariant *result;
2294
2295         if (__bt_is_factory_test_mode()) {
2296                 BT_ERR("Unable to set connectable in factory binary !!");
2297                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2298         }
2299
2300         proxy = _bt_get_adapter_properties_proxy();
2301
2302         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2303
2304         result = g_dbus_proxy_call_sync(proxy,
2305                                 "Set",
2306                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2307                                                 g_variant_new("b", is_connectable)),
2308                                 G_DBUS_CALL_FLAGS_NONE,
2309                                 -1,
2310                                 NULL,
2311                                 &error);
2312
2313         if (!result) {
2314                 if (error != NULL) {
2315                         BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2316                         g_clear_error(&error);
2317                 } else
2318                         BT_ERR("Failed to set connectable property");
2319                 return BLUETOOTH_ERROR_INTERNAL;
2320         }
2321
2322         BT_INFO_C("### Set connectable [%d]", is_connectable);
2323         g_variant_unref(result);
2324         return BLUETOOTH_ERROR_NONE;
2325 }
2326
2327 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2328 {
2329         GDBusProxy *proxy;
2330         gboolean discovering_v;
2331         GError *error = NULL;
2332         char *discovering_type =  NULL;
2333         GVariant *result;
2334         GVariant *temp;
2335
2336         proxy = _bt_get_adapter_properties_proxy();
2337         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2338
2339         if (discovery_type == DISCOVERY_ROLE_BREDR)
2340                 discovering_type = "Discovering";
2341         else if (discovery_type == DISCOVERY_ROLE_LE)
2342                 discovering_type = "LEDiscovering";
2343
2344         result = g_dbus_proxy_call_sync(proxy,
2345                                 "Get",
2346                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2347                                         discovering_type),
2348                                 G_DBUS_CALL_FLAGS_NONE,
2349                                 -1,
2350                                 NULL,
2351                                 &error);
2352
2353         if (!result) {
2354                 if (error != NULL) {
2355                         BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2356                         g_clear_error(&error);
2357                 } else
2358                         BT_ERR("Failed to get discovering property");
2359                 return BLUETOOTH_ERROR_INTERNAL;
2360         }
2361
2362         g_variant_get(result, "(v)", &temp);
2363         discovering_v = g_variant_get_boolean(temp);
2364         BT_DBG("discoverable_v:%d", discovering_v);
2365
2366         g_variant_unref(result);
2367         g_variant_unref(temp);
2368
2369         return discovering_v;
2370 }
2371
2372 unsigned int _bt_get_discoverable_timeout_property(void)
2373 {
2374         GDBusProxy *proxy;
2375         unsigned int timeout_v;
2376         GError *error = NULL;
2377         GVariant *result;
2378         GVariant *temp;
2379
2380         proxy = _bt_get_adapter_properties_proxy();
2381         retv_if(proxy == NULL, 0);
2382
2383         result = g_dbus_proxy_call_sync(proxy,
2384                                 "Get",
2385                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2386                                         "DiscoverableTimeout"),
2387                                 G_DBUS_CALL_FLAGS_NONE,
2388                                 -1,
2389                                 NULL,
2390                                 &error);
2391
2392         if (!result) {
2393                 BT_ERR("Fail to get discoverable timeout");
2394                 if (error != NULL) {
2395                         BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2396                         g_clear_error(&error);
2397                 }
2398                 return 0;
2399         }
2400
2401         g_variant_get(result, "(v)", &temp);
2402         timeout_v = g_variant_get_uint32(temp);
2403         BT_DBG("discoverable_v:%d", timeout_v);
2404
2405         g_variant_unref(result);
2406         g_variant_unref(temp);
2407
2408         return timeout_v;
2409 }
2410
2411 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2412 {
2413         bluetooth_device_info_t *dev_info;
2414         GVariant *value;
2415         const gchar *key;
2416         GByteArray *manufacturer_data = NULL;
2417         guint8 char_value;
2418         GVariantIter *char_value_iter;
2419
2420         dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2421
2422         while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2423
2424                 if (key == NULL)
2425                         continue;
2426
2427                 if (!g_strcmp0(key, "Address")) {
2428                         const char *address = NULL;
2429                         address = g_variant_get_string(value, NULL);
2430                         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2431                                                         address);
2432                 } else if (!g_strcmp0(key, "Class")) {
2433                         unsigned int cod;
2434                         cod = g_variant_get_uint32(value);
2435                         _bt_divide_device_class(&dev_info->device_class, cod);
2436                 } else if (!g_strcmp0(key, "Name")) {
2437                         const char *name = NULL;
2438                         name = g_variant_get_string(value, NULL);
2439                         /* If there is no Alias */
2440                         if (strlen(dev_info->device_name.name) == 0) {
2441                                 g_strlcpy(dev_info->device_name.name, name,
2442                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2443                         }
2444                 } else if (!g_strcmp0(key, "Alias")) {
2445                         const char *alias = NULL;
2446                         alias = g_variant_get_string(value, NULL);
2447                         /* Overwrite the name */
2448                         if (alias) {
2449                                 memset(dev_info->device_name.name, 0x00,
2450                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2451                                 g_strlcpy(dev_info->device_name.name, alias,
2452                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2453                         }
2454                 } else if (!g_strcmp0(key, "IsAliasSet")) {
2455                         dev_info->is_alias_set = g_variant_get_boolean(value);
2456                 } else if (!g_strcmp0(key, "Connected")) {
2457                         dev_info->connected = g_variant_get_byte(value);
2458                 } else if (!g_strcmp0(key, "Paired")) {
2459                         dev_info->paired = g_variant_get_boolean(value);
2460                 } else if (!g_strcmp0(key, "Trusted")) {
2461                         dev_info->trust = g_variant_get_boolean(value);
2462                 } else if (!g_strcmp0(key, "RSSI")) {
2463                         dev_info->rssi = g_variant_get_int16(value);
2464                 } else if (!g_strcmp0(key, "UUIDs")) {
2465                         GVariantIter *iter;
2466                         gchar *uuid = NULL;
2467                         char **parts;
2468                         int i = 0;
2469
2470                         dev_info->service_index = 0;
2471                         g_variant_get(value, "as", &iter);
2472                         while (g_variant_iter_loop(iter, "s", &uuid)) {
2473                                 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2474                                 parts = g_strsplit(uuid, "-", -1);
2475
2476                                 if (parts == NULL || parts[0] == NULL) {
2477                                         g_free(uuid);
2478                                         break;
2479                                 }
2480
2481                                 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2482                                 g_strfreev(parts);
2483
2484                                 i++;
2485                         }
2486                         dev_info->service_index = i;
2487                         g_variant_iter_free(iter);
2488                 } else if (strcasecmp(key, "LegacyManufacturerDataLen") == 0) {
2489                         dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2490                 } else if (strcasecmp(key, "LegacyManufacturerData") == 0) {
2491                         manufacturer_data = g_byte_array_new();
2492                         g_variant_get(value, "ay", &char_value_iter);
2493                         while (g_variant_iter_loop(char_value_iter, "y",  &char_value))
2494                                 g_byte_array_append(manufacturer_data, &char_value, 1);
2495
2496                         if (manufacturer_data) {
2497                                 if (manufacturer_data->len > 0)
2498                                         memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2499                         }
2500                         g_variant_iter_free(char_value_iter);
2501                         g_byte_array_free(manufacturer_data, TRUE);
2502                 }
2503         }
2504
2505         return dev_info;
2506 }
2507
2508 static void __bt_extract_device_info(GVariantIter *iter,
2509                                                         GArray **dev_list)
2510 {
2511         bluetooth_device_info_t *dev_info = NULL;
2512         char *object_path = NULL;
2513         GVariantIter *interface_iter;
2514         GVariantIter *svc_iter;
2515         char *interface_str = NULL;
2516
2517         /* Parse the signature:  oa{sa{sv}}} */
2518         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2519                 &interface_iter)) {
2520
2521                 if (object_path == NULL)
2522                         continue;
2523
2524                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2525                                 &interface_str, &svc_iter)) {
2526                         if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2527                                 BT_DBG("Found a device: %s", object_path);
2528                                 dev_info = __bt_parse_device_info(svc_iter);
2529                                 if (dev_info) {
2530                                         if (dev_info->paired == TRUE) {
2531                                                 g_array_append_vals(*dev_list, dev_info,
2532                                                                 sizeof(bluetooth_device_info_t));
2533                                         }
2534                                         g_free(dev_info);
2535                                 }
2536                                 g_free(interface_str);
2537                                 g_variant_iter_free(svc_iter);
2538                                 break;
2539                         }
2540                 }
2541         }
2542         BT_DBG("-");
2543 }
2544
2545 int _bt_get_bonded_devices(GArray **dev_list)
2546 {
2547         BT_DBG("+");
2548         GDBusConnection *conn;
2549         GDBusProxy *manager_proxy;
2550         GVariant *result = NULL;
2551         GVariantIter *iter = NULL;
2552         GError *error = NULL;
2553
2554         conn = _bt_gdbus_get_system_gconn();
2555         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2556
2557         manager_proxy = _bt_get_manager_proxy();
2558         retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2559
2560         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2561                                 NULL,
2562                                 G_DBUS_CALL_FLAGS_NONE,
2563                                 -1,
2564                                 NULL,
2565                                 NULL);
2566
2567         if (!result) {
2568                 if (error != NULL) {
2569                         BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2570                         g_clear_error(&error);
2571                 } else
2572                         BT_ERR("Failed to Failed to GetManagedObjects");
2573                 return BLUETOOTH_ERROR_INTERNAL;
2574         }
2575
2576         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
2577         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2578
2579         __bt_extract_device_info(iter, dev_list);
2580         g_variant_iter_free(iter);
2581         g_variant_unref(result);
2582
2583         BT_DBG("-");
2584         return BLUETOOTH_ERROR_NONE;
2585 }
2586
2587 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2588 {
2589         BT_DBG("+");
2590         GDBusConnection *conn;
2591         GDBusProxy *manager_proxy;
2592         GVariant *result = NULL;
2593         GVariant *result1 = NULL;
2594         GVariantIter *iter = NULL;
2595         GError *error = NULL;
2596         char *object_path = NULL;
2597         GVariantIter *interface_iter;
2598         char *interface_str = NULL;
2599         GDBusProxy *device_proxy = NULL;
2600         gboolean is_connected = FALSE;
2601
2602         conn = _bt_gdbus_get_system_gconn();
2603         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2604
2605         manager_proxy = _bt_get_manager_proxy();
2606         retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2607
2608         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2609                                 NULL,
2610                                 G_DBUS_CALL_FLAGS_NONE,
2611                                 -1,
2612                                 NULL,
2613                                 NULL);
2614
2615         if (!result) {
2616                 if (error != NULL) {
2617                         BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2618                         g_clear_error(&error);
2619                         error = NULL;
2620                 } else
2621                         BT_ERR("Failed to Failed to GetManagedObjects");
2622                 return BLUETOOTH_ERROR_INTERNAL;
2623         }
2624
2625         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
2626         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2627
2628         /* Parse the signature:  oa{sa{sv}}} */
2629         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2630                 if (object_path == NULL)
2631                         continue;
2632
2633                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2634                                 &interface_str, NULL)) {
2635                         if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2636                                 BT_DBG("Found a device: %s", object_path);
2637                                 g_free(interface_str);
2638
2639                                 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2640                                                                                         NULL, BT_BLUEZ_NAME,
2641                                                                                         object_path, BT_DEVICE_INTERFACE,  NULL, NULL);
2642
2643                                 if (device_proxy == NULL) {
2644                                         BT_DBG("Device don't have this service");
2645                                         break;
2646                                 }
2647
2648                                 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2649                                                         g_variant_new("(s)", profile_uuid),
2650                                                         G_DBUS_CALL_FLAGS_NONE,
2651                                                         -1,
2652                                                         NULL,
2653                                                         &error);
2654
2655                                 if (result1 == NULL) {
2656                                         BT_ERR("Error occured in Proxy call");
2657                                         if (error) {
2658                                                 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2659                                                 g_error_free(error);
2660                                                 error = NULL;
2661                                         }
2662                                         g_object_unref(device_proxy);
2663                                         break;
2664                                 }
2665                                 g_variant_get(result1, "(b)", &is_connected);
2666
2667                                 if (is_connected == TRUE) {
2668                                         char address[BT_ADDRESS_STRING_SIZE];
2669                                         bluetooth_device_address_t *addr = NULL;
2670
2671                                         _bt_convert_device_path_to_address(object_path, address);
2672
2673                                         addr = g_malloc0(sizeof(bluetooth_device_address_t));
2674                                         _bt_convert_addr_string_to_type(addr->addr, address);
2675
2676                                         g_array_append_vals(*addr_list, addr,
2677                                                         sizeof(bluetooth_device_address_t));
2678                                 }
2679
2680                                 g_variant_unref(result1);
2681                                 g_object_unref(device_proxy);
2682
2683                                 break;
2684                         }
2685                 }
2686         }
2687
2688         g_variant_unref(result);
2689         g_variant_iter_free(iter);
2690
2691         BT_DBG("-");
2692         return BLUETOOTH_ERROR_NONE;
2693 }
2694
2695 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2696                                 bluetooth_device_info_t *dev_info)
2697 {
2698         char *object_path = NULL;
2699         GDBusProxy *adapter_proxy;
2700         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2701         int ret = BLUETOOTH_ERROR_NONE;
2702
2703         BT_CHECK_PARAMETER(device_address, return);
2704         BT_CHECK_PARAMETER(dev_info, return);
2705
2706         adapter_proxy = _bt_get_adapter_proxy();
2707         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2708
2709         _bt_convert_addr_type_to_string(address, device_address->addr);
2710
2711         object_path = _bt_get_device_object_path(address);
2712
2713         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2714
2715         ret = __bt_get_bonded_device_info(object_path, dev_info);
2716         g_free(object_path);
2717
2718         return ret;
2719 }
2720
2721 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2722 {
2723         char *object_path = NULL;
2724         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2725         gboolean alias_set = FALSE;
2726
2727         GDBusConnection *conn;
2728         GDBusProxy *device_proxy;
2729         GError *error = NULL;
2730         GVariant *result = NULL;
2731         GVariant *temp = NULL;
2732
2733
2734         BT_CHECK_PARAMETER(device_address, return);
2735         BT_CHECK_PARAMETER(is_alias_set, return);
2736
2737         _bt_convert_addr_type_to_string(address, device_address->addr);
2738
2739         object_path = _bt_get_device_object_path(address);
2740         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2741
2742         conn = _bt_gdbus_get_system_gconn();
2743         if (conn == NULL) {
2744                 g_free(object_path);
2745                 return BLUETOOTH_ERROR_INTERNAL;
2746         }
2747
2748         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2749                         NULL,
2750                         BT_BLUEZ_NAME,
2751                         object_path,
2752                         BT_PROPERTIES_INTERFACE,
2753                         NULL, NULL);
2754         if (device_proxy == NULL) {
2755                 g_free(object_path);
2756                 return BLUETOOTH_ERROR_INTERNAL;
2757         }
2758
2759         result = g_dbus_proxy_call_sync(device_proxy, "Get",
2760                         g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2761                         G_DBUS_CALL_FLAGS_NONE,
2762                         -1,
2763                         NULL,
2764                         &error);
2765
2766         if (!result) {
2767                 BT_ERR("Error occured in Proxy call");
2768                 if (error != NULL) {
2769                         BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2770                         g_error_free(error);
2771                 }
2772                 g_object_unref(device_proxy);
2773                 g_free(object_path);
2774                 return BLUETOOTH_ERROR_INTERNAL;
2775         }
2776
2777         g_variant_get(result, "(v)", &temp);
2778         alias_set = g_variant_get_boolean(temp);
2779         *is_alias_set = alias_set;
2780         BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2781         g_variant_unref(temp);
2782         g_variant_unref(result);
2783         g_object_unref(device_proxy);
2784
2785         g_free(object_path);
2786
2787         return BLUETOOTH_ERROR_NONE;
2788 }
2789
2790 int _bt_get_timeout_value(int *timeout)
2791 {
2792         time_t current_time;
2793         int time_diff;
2794
2795         /* Take current time */
2796         time(&current_time);
2797         time_diff = difftime(current_time, visible_timer.start_time);
2798
2799         BT_DBG("Time diff = %d\n", time_diff);
2800
2801         *timeout = visible_timer.timeout - time_diff;
2802
2803         return BLUETOOTH_ERROR_NONE;
2804 }
2805
2806 int _bt_set_le_privacy(gboolean set_privacy)
2807 {
2808         GDBusProxy *proxy;
2809         GError *error = NULL;
2810         GVariant *result = NULL;
2811
2812         if (__bt_is_factory_test_mode()) {
2813                 BT_ERR("Unable to set le privacy in factory binary !!");
2814                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2815         }
2816
2817         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2818                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2819                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2820         }
2821
2822         proxy = _bt_get_adapter_proxy();
2823         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2824
2825         result = g_dbus_proxy_call_sync(proxy,
2826                                 "SetLePrivacy",
2827                                 g_variant_new("(b)", set_privacy),
2828                                 G_DBUS_CALL_FLAGS_NONE,
2829                                 -1,
2830                                 NULL,
2831                                 &error);
2832
2833         if (!result) {
2834                 if (error != NULL) {
2835                         BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2836                         g_clear_error(&error);
2837                 } else
2838                         BT_ERR("Failed to SetLePrivacy");
2839                 return BLUETOOTH_ERROR_INTERNAL;
2840         }
2841
2842         g_variant_unref(result);
2843         BT_INFO("SetLePrivacy as %d", set_privacy);
2844         return BLUETOOTH_ERROR_NONE;
2845 }
2846
2847 int _bt_set_le_static_random_address(gboolean is_enable)
2848 {
2849         GDBusProxy *proxy;
2850         GError *error = NULL;
2851         GVariant *result = NULL;
2852
2853         if (__bt_is_factory_test_mode()) {
2854                 BT_ERR("Unable to set le random address in factory binary !!");
2855                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2856         }
2857
2858         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2859                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2860                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2861         }
2862
2863         proxy = _bt_get_adapter_proxy();
2864         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2865
2866         result = g_dbus_proxy_call_sync(proxy,
2867                                 "SetLeStaticRandomAddress",
2868                                 g_variant_new("(b)", is_enable),
2869                                 G_DBUS_CALL_FLAGS_NONE,
2870                                 -1,
2871                                 NULL,
2872                                 &error);
2873
2874         if (!result) {
2875                 if (error != NULL) {
2876                         BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2877                         g_clear_error(&error);
2878                 } else
2879                         BT_ERR("Failed to SetLeStaticRandomAddress");
2880                 return BLUETOOTH_ERROR_INTERNAL;
2881         }
2882
2883         g_variant_unref(result);
2884         BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2885         return BLUETOOTH_ERROR_NONE;
2886 }
2887
2888 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2889 {
2890         GDBusProxy *proxy;
2891         GError *error = NULL;
2892         int i;
2893         GVariant *val;
2894         GVariant *result;
2895         GVariantBuilder *builder;
2896
2897         BT_CHECK_PARAMETER(m_data, return);
2898
2899         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2900                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2901                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2902         }
2903
2904         proxy = _bt_get_adapter_proxy();
2905         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2906
2907         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2908
2909         for (i = 0; i < (m_data->data_len) + 2; i++)
2910                 g_variant_builder_add(builder, "y", m_data->data[i]);
2911
2912         val = g_variant_new("(ay)", builder);
2913
2914         result = g_dbus_proxy_call_sync(proxy,
2915                                 "SetManufacturerData",
2916                                 val,
2917                                 G_DBUS_CALL_FLAGS_NONE,
2918                                 -1,
2919                                 NULL,
2920                                 &error);
2921         g_variant_builder_unref(builder);
2922         if (!result) {
2923                 if (error != NULL) {
2924                         BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2925                         g_clear_error(&error);
2926                 } else {
2927                         BT_ERR("Failed to SetManufacturerData");
2928                 }
2929                 return BLUETOOTH_ERROR_INTERNAL;
2930         }
2931         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2932
2933         for (i = 0; i < (m_data->data_len) + 2; i++)
2934                 g_variant_builder_add(builder, "y", m_data->data[i]);
2935
2936         val = g_variant_new("(ay)", builder);
2937
2938         _bt_send_event(BT_ADAPTER_EVENT,
2939                         BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2940                         val);
2941
2942         BT_INFO("Set manufacturer data");
2943
2944         g_variant_builder_unref(builder);
2945         g_variant_unref(result);
2946
2947         return BLUETOOTH_ERROR_NONE;
2948 }
2949
2950
2951 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2952 {
2953         int result = BLUETOOTH_ERROR_NONE;
2954         bt_service_alarm_t *alarm = NULL;
2955
2956         if (!call_back || !alarm_id)
2957                 return BLUETOOTH_ERROR_INVALID_PARAM;
2958
2959         if (!alarm_mgr.is_alarm_initialized) {
2960                 result = alarmmgr_init("bt-service");
2961                 if (result != 0) {
2962                         BT_ERR("Failed to initialize alarm = %d", result);
2963                         result = BLUETOOTH_ERROR_INTERNAL;
2964                         goto finish;
2965                 }
2966                 result = alarmmgr_set_cb(alarm_cb, NULL);
2967                 if (result != 0) {
2968                         BT_ERR("Failed to set the callback = %d", result);
2969                         result = BLUETOOTH_ERROR_INTERNAL;
2970                         goto finish;
2971                 }
2972                 alarm_mgr.is_alarm_initialized = TRUE;
2973         }
2974
2975         alarm = g_malloc0(sizeof(bt_service_alarm_t));
2976         if (!alarm)
2977                 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2978
2979         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
2980                                                 0, NULL, alarm_id);
2981         if (result != 0) {
2982                 BT_ERR("Failed to create alarm error = %d", result);
2983                 result = BLUETOOTH_ERROR_INTERNAL;
2984                 g_free(alarm);
2985                 goto finish;
2986         }
2987         alarm->alarm_id = *alarm_id;
2988         alarm->callback = call_back;
2989         alarm->user_data = user_data;
2990
2991         alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
2992         result = BLUETOOTH_ERROR_NONE;
2993 finish:
2994         return result;
2995 }
2996
2997 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
2998 {
2999         GList *node = NULL;
3000         bt_service_alarm_t *p_data;
3001         bt_set_alarm_cb callback = NULL;
3002         void *user_data = NULL;
3003
3004         node = g_list_find_custom(alarm_mgr.g_alarm_list,
3005                         GINT_TO_POINTER(alarm_id), compare_alarm);
3006         if (!node)
3007                 return 0;
3008
3009         p_data = (bt_service_alarm_t *)node->data;
3010         alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
3011                         node);
3012
3013         if (!p_data)
3014                 return 0;
3015
3016         callback = p_data->callback;
3017         user_data = p_data->user_data;
3018         g_free(p_data);
3019
3020         if (callback)
3021                 callback(alarm_id, user_data);
3022
3023         return 0;
3024 }
3025
3026 int _bt_service_remove_alarm(alarm_id_t alarm_id)
3027 {
3028         GList *list = NULL;
3029         bt_service_alarm_t *p_data;
3030         list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
3031
3032         if (list != NULL) {
3033                 alarmmgr_remove_alarm(alarm_id);
3034                 p_data = (bt_service_alarm_t *)list->data;
3035                 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
3036                 g_free(p_data);
3037         }
3038
3039         return 0;
3040 }
3041
3042 gint compare_alarm(gconstpointer list_data, gconstpointer data)
3043 {
3044         alarm_id_t alarm_id = (alarm_id_t)data;
3045         bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
3046
3047         if (p_data->alarm_id == alarm_id)
3048                 return 0;
3049
3050         return 1;
3051 }
3052
3053 static void alarm_data_free(void *data)
3054 {
3055         bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
3056         g_free(p_data);
3057         return;
3058 }
3059
3060 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3061 {
3062         int result;
3063         int function = (int)user_data;
3064
3065         switch (function) {
3066         case BT_ENABLE_ADAPTER:
3067                 result = _bt_enable_adapter();
3068                 if (result != BLUETOOTH_ERROR_NONE) {
3069                         BT_ERR("_bt_enable_adapter is failed");
3070                         /* Send enabled event to API */
3071                         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3072                                         g_variant_new("(i)", result));
3073                 }
3074                 break;
3075         case BT_DISABLE_ADAPTER:
3076                 result = _bt_disable_adapter();
3077                 if (result != BLUETOOTH_ERROR_NONE) {
3078                         BT_ERR("_bt_disable_adapter is failed");
3079                         /* Send disabled event to API */
3080                         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3081                                         g_variant_new("(i)", result));
3082                 }
3083                 break;
3084         default:
3085                 BT_ERR("function is NOT matched");
3086                 break;
3087         }
3088
3089         return FALSE;
3090 }
3091
3092 int _bt_adapter_request_delayed(int function)
3093 {
3094         int ret;
3095
3096         switch (function) {
3097         case BT_ENABLE_ADAPTER:
3098                 ret = _bt_enable_adapter_check_status();
3099                 if (ret == BLUETOOTH_ERROR_NONE)
3100                         _bt_adapter_set_status(BT_ACTIVATING);
3101                 else
3102                         return ret;
3103
3104                 break;
3105         case BT_DISABLE_ADAPTER:
3106                 ret = _bt_disable_adapter_check_status();
3107                 if (ret == BLUETOOTH_ERROR_NONE)
3108                         _bt_adapter_set_status(BT_DEACTIVATING);
3109                 else
3110                         return ret;
3111
3112                 break;
3113         default:
3114                 BT_ERR("function is NOT matched");
3115                 return BLUETOOTH_ERROR_INTERNAL;
3116         }
3117
3118         g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void*)function);
3119
3120         return BLUETOOTH_ERROR_NONE;
3121 }
3122
3123
3124 int _bt_get_enable_timer_id(void)
3125 {
3126         return timer_id;
3127 }
3128