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