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