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