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