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