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