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