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