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