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