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