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