[Boiler Plate] Update Boiler plate to remove unwanted information
[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 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
25 #include <syspopup_caller.h>
26 #endif
27 #include <aul.h>
28 #include <dbus/dbus-glib.h>
29 #include <dbus/dbus.h>
30 #include <bundle.h>
31 #include <eventsystem.h>
32 #include <bundle_internal.h>
33
34 #include "alarm.h"
35 #include "bluetooth-api.h"
36 #include "bt-internal-types.h"
37 #include "bt-service-common.h"
38 #include "bt-service-event.h"
39 #include "bt-service-adapter.h"
40 #include "bt-service-util.h"
41 #include "bt-service-network.h"
42 #include "bt-service-obex-server.h"
43 #include "bt-service-agent.h"
44 #include "bt-service-main.h"
45 #include "bt-service-avrcp.h"
46 #include "bt-service-device.h"
47
48 typedef struct {
49         guint event_id;
50         int timeout;
51         time_t start_time;
52         gboolean alarm_init;
53         int alarm_id;
54 } bt_adapter_timer_t;
55
56 bt_adapter_timer_t visible_timer = {0, };
57
58 static gboolean is_discovering;
59 static gboolean cancel_by_user;
60 static bt_status_t adapter_status = BT_DEACTIVATED;
61 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
62 static void *adapter_agent = NULL;
63 static GDBusProxy *core_proxy = NULL;
64 static guint timer_id = 0;
65 static guint le_timer_id = 0;
66
67 static int status_reg_id;
68
69 #define BT_CORE_NAME "org.projectx.bt_core"
70 #define BT_CORE_PATH "/org/projectx/bt_core"
71 #define BT_CORE_INTERFACE "org.projectx.btcore"
72
73 #define BT_DISABLE_TIME 500 /* 500 ms */
74
75 GDBusProxy *_bt_init_core_proxy(void)
76 {
77         GDBusProxy *proxy;
78         GDBusConnection *conn;
79
80         conn = _bt_get_system_gconn();
81         if (!conn)
82                 return NULL;
83
84         proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
85                                         NULL,
86                                         BT_CORE_NAME,
87                                         BT_CORE_PATH,
88                                         BT_CORE_INTERFACE,
89                                         NULL, NULL);
90
91         if (!proxy)
92                 return NULL;
93
94         core_proxy = proxy;
95
96         return proxy;
97 }
98
99 static GDBusProxy *__bt_get_core_proxy(void)
100 {
101        return (core_proxy) ? core_proxy : _bt_init_core_proxy();
102 }
103
104 static gboolean __bt_is_factory_test_mode(void)
105 {
106         int mode = 0;
107
108 #ifdef ENABLE_TIZEN_2_4
109         if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
110                 BT_ERR("Get the DUT Mode fail");
111                 return TRUE;
112         }
113 #endif
114
115         if (mode != FALSE) {
116                 BT_INFO("DUT Test Mode !!");
117                 return TRUE;
118         }
119
120         return FALSE;
121 }
122
123 static gboolean __bt_timeout_handler(gpointer user_data)
124 {
125         int result = BLUETOOTH_ERROR_NONE;
126         time_t current_time;
127         int time_diff;
128
129         /* Take current time */
130         time(&current_time);
131         time_diff = difftime(current_time, visible_timer.start_time);
132
133         /* Send event to application */
134         _bt_send_event(BT_ADAPTER_EVENT,
135                         BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
136                         g_variant_new("(in)", result, time_diff));
137
138         if (visible_timer.timeout <= time_diff) {
139                 g_source_remove(visible_timer.event_id);
140                 visible_timer.event_id = 0;
141                 visible_timer.timeout = 0;
142
143 #ifndef TIZEN_WEARABLE
144                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
145                         BT_ERR("Set vconf failed\n");
146 #endif
147                 return FALSE;
148         }
149
150         return TRUE;
151 }
152
153 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
154 {
155         BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
156
157         int result = BLUETOOTH_ERROR_NONE;
158         int timeout = 0;
159
160         if (alarm_id != visible_timer.alarm_id)
161                 return 0;
162
163         if (visible_timer.event_id) {
164                 _bt_send_event(BT_ADAPTER_EVENT,
165                                 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
166                                 g_variant_new("(in)", result, timeout));
167                 g_source_remove(visible_timer.event_id);
168                 visible_timer.event_id = 0;
169                 visible_timer.timeout = 0;
170
171 #ifndef TIZEN_WEARABLE
172                 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
173                         BT_ERR("Set vconf failed\n");
174 #endif
175         }
176         /* Switch Off visibility in Bluez */
177         _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
178         visible_timer.alarm_id = 0;
179         return 0;
180 }
181
182 static void __bt_visibility_alarm_create()
183 {
184         alarm_id_t alarm_id;
185         int result;
186
187         result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
188                                                 0, NULL, &alarm_id);
189         if(result < 0) {
190                 BT_ERR("Failed to create alarm error = %d\n", result);
191         } else {
192                 BT_DBG("Alarm created = %d\n", alarm_id);
193                 visible_timer.alarm_id = alarm_id;
194         }
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                 alarmmgr_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
214         __bt_visibility_alarm_remove();
215
216         visible_timer.timeout = timeout;
217
218 #ifndef TIZEN_WEARABLE
219         if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
220                 BT_ERR("Set vconf failed");
221 #endif
222
223         if (timeout <= 0)
224                 return BLUETOOTH_ERROR_NONE;
225
226         if (!visible_timer.alarm_init) {
227                 /* Set Alarm timer to switch off BT */
228                 result = alarmmgr_init("bt-service");
229                 if (result != 0)
230                         return BLUETOOTH_ERROR_INTERNAL;
231
232                 visible_timer.alarm_init = TRUE;
233         }
234
235         result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
236         if (result != 0)
237                 return BLUETOOTH_ERROR_INTERNAL;
238
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         __bt_visibility_alarm_create();
245
246         return BLUETOOTH_ERROR_NONE;
247 }
248
249 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
250 {
251         int i = 0;
252         char **parts;
253         GVariantIter *iter;
254         gchar *uuid = NULL;
255
256         ret_if(value == NULL);
257         ret_if(dev == NULL);
258
259         dev->service_index = 0;
260
261         g_variant_get(value, "as", &iter);
262         while (g_variant_iter_loop(iter, "s", &uuid)) {
263                 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
264                 parts = g_strsplit(uuid, "-", -1);
265
266                 if (parts == NULL || parts[0] == NULL) {
267                         g_free(uuid);
268                         break;
269                 }
270
271                 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
272                 g_strfreev(parts);
273
274                 dev->service_index++;
275                 i++;
276         }
277         g_variant_iter_free(iter);
278 }
279
280 static int __bt_get_bonded_device_info(gchar *device_path,
281                 bluetooth_device_info_t *dev_info)
282 {
283         GError *error = NULL;
284         GDBusProxy *device_proxy;
285         const gchar *address = NULL;
286         const gchar *name = NULL;
287         unsigned int cod = 0;
288         gint rssi = 0;
289         gboolean trust = FALSE;
290         gboolean paired = FALSE;
291         guchar connected = 0;
292         GByteArray *manufacturer_data = NULL;
293         int ret;
294         GDBusConnection *conn;
295         GVariant *result;
296         GVariantIter *property_iter;
297         const gchar *key;
298         GVariant *value;
299         guint8 char_value;
300         GVariantIter *char_value_iter;
301
302         BT_CHECK_PARAMETER(device_path, return);
303         BT_CHECK_PARAMETER(dev_info, return);
304
305         conn = _bt_get_system_gconn();
306         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
307
308         device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
309                                         NULL,
310                                         BT_BLUEZ_NAME,
311                                         device_path,
312                                         BT_PROPERTIES_INTERFACE,
313                                         NULL, NULL);
314
315         retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
316
317         result = g_dbus_proxy_call_sync(device_proxy,
318                                 "GetAll",
319                                 g_variant_new("(s)", BT_DEVICE_INTERFACE),
320                                 G_DBUS_CALL_FLAGS_NONE,
321                                 -1,
322                                 NULL,
323                                 &error);
324
325         if (!result) {
326                 BT_ERR("Error occured in Proxy call");
327                 if (error != NULL) {
328                         BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
329                         g_clear_error(&error);
330                 }
331                 g_object_unref(device_proxy);
332                 return BLUETOOTH_ERROR_INTERNAL;
333         }
334
335         g_object_unref(device_proxy);
336
337         g_variant_get(result, "(a{sv})", &property_iter);
338
339         while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
340                 if (!g_strcmp0(key,"Paired")) {
341                         paired = g_variant_get_boolean(value);
342                 } else if(!g_strcmp0(key, "Address")) {
343                         address = g_variant_get_string(value, NULL);
344                 } else if (!g_strcmp0(key, "Alias")) {
345                         name = g_variant_get_string(value, NULL);
346                 } else if (!g_strcmp0(key, "Name")) {
347                         if (!name)
348                                 name = g_variant_get_string(value, NULL);
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                         if (manufacturer_data) {
368                                 if (manufacturer_data->len > 0) {
369                                         memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
370                                                 manufacturer_data->len);
371                                 }
372                         }
373                 }
374         }
375
376         BT_DBG("trust: %d, paired: %d", trust, paired);
377
378         g_variant_unref(result);
379
380         if ((paired == FALSE) && (trust == FALSE)) {
381                 return BLUETOOTH_ERROR_NOT_PAIRED;
382         }
383
384         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
385                                         address);
386
387         _bt_divide_device_class(&dev_info->device_class, cod);
388
389         g_strlcpy(dev_info->device_name.name, name,
390                         BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
391
392         dev_info->rssi = rssi;
393         dev_info->trust = trust;
394         dev_info->paired = paired;
395         dev_info->connected = connected;
396         ret = BLUETOOTH_ERROR_NONE;
397
398         return ret;
399 }
400
401 void _bt_set_discovery_status(gboolean mode)
402 {
403         is_discovering = mode;
404 }
405
406 void _bt_set_cancel_by_user(gboolean value)
407 {
408         cancel_by_user = value;
409 }
410
411 gboolean _bt_get_cancel_by_user(void)
412 {
413         return cancel_by_user;
414 }
415
416 void _bt_adapter_set_status(bt_status_t status)
417 {
418         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
419         adapter_status = status;
420 }
421
422 bt_status_t _bt_adapter_get_status(void)
423 {
424         return adapter_status;
425 }
426
427 void _bt_adapter_set_le_status(bt_le_status_t status)
428 {
429         BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
430         adapter_le_status = status;
431 }
432
433 bt_le_status_t _bt_adapter_get_le_status(void)
434 {
435         return adapter_le_status;
436 }
437
438 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
439 {
440         char *phone_name = NULL;
441         char *ptr = NULL;
442
443         if (node == NULL)
444                 return;
445
446         if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
447                 phone_name = vconf_keynode_get_str(node);
448
449                 if (phone_name && strlen(phone_name) != 0) {
450                         if (!g_utf8_validate(phone_name, -1,
451                                                         (const char **)&ptr))
452                                 *ptr = '\0';
453
454                         _bt_set_local_name(phone_name);
455                 }
456         }
457 }
458
459 #ifdef TIZEN_MOBILE
460 static void __bt_set_visible_mode(void)
461 {
462         int timeout = 0;
463
464         if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
465                 BT_ERR("Fail to get the timeout value");
466
467         if (timeout == -1) {
468                 if (_bt_set_discoverable_mode(
469                         BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
470                         timeout) != BLUETOOTH_ERROR_NONE) {
471                         if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
472                                 BT_ERR("Set vconf failed");
473                 }
474         } else {
475                 if (_bt_set_discoverable_mode(
476                         BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
477                         timeout) != BLUETOOTH_ERROR_NONE) {
478                                 BT_ERR("Set connectable mode failed");
479                 }
480         }
481 }
482 #endif
483
484 static void __bt_set_local_name(void)
485 {
486         char *phone_name = NULL;
487         char *ptr = NULL;
488
489         phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
490
491         if (!phone_name)
492                 return;
493
494         if (strlen(phone_name) != 0) {
495                 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
496                         *ptr = '\0';
497
498                 _bt_set_local_name(phone_name);
499         }
500         free(phone_name);
501 }
502
503 static int __bt_set_enabled(void)
504 {
505         BT_DBG("+");
506         int adapter_status = BT_ADAPTER_DISABLED;
507         int result = BLUETOOTH_ERROR_NONE;
508
509         _bt_check_adapter(&adapter_status);
510
511         if (adapter_status == BT_ADAPTER_DISABLED) {
512                 BT_ERR("Bluetoothd is not running");
513                 return BLUETOOTH_ERROR_INTERNAL;
514         }
515
516 #ifdef TIZEN_MOBILE
517         __bt_set_visible_mode();
518 #else
519 #ifdef TIZEN_TV
520         if (_bt_set_discoverable_mode(
521                 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0)!= BLUETOOTH_ERROR_NONE)
522                         BT_ERR("Fail to set discoverable mode");
523 #endif
524 #endif
525         __bt_set_local_name();
526
527         /* Update Bluetooth Status to notify other modules */
528         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
529                 BT_ERR("Set vconf failed\n");
530
531         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
532                 BT_ERR("Set vconf failed\n");
533 #if 0
534         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
535                                                 EVT_VAL_BT_ON) != ES_R_OK)
536                 BT_ERR("Fail to set value");
537 #endif
538
539         /* Send enabled event to API */
540         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
541                                 g_variant_new("(i)", result));
542         BT_DBG("-");
543
544         return BLUETOOTH_ERROR_NONE;
545 }
546
547 void _bt_set_disabled(int result)
548 {
549         int power_off_status = 0;
550         int ret;
551         int ret_pm_ignore;
552         int pm_ignore_mode = 0;
553
554         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
555         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
556
557         ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
558
559         /* Update the vconf BT status in normal Deactivation case only */
560         if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
561                 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
562
563                 BT_DBG("Update vconf for BT normal Deactivation");
564
565                 if (result == BLUETOOTH_ERROR_TIMEOUT)
566                         if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 )
567                                 BT_ERR("Set vconf failed");
568
569                 /* Update Bluetooth Status to notify other modules */
570                 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
571                         BT_ERR("Set vconf failed");
572
573                 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
574                                                         EVT_VAL_BT_OFF) != ES_R_OK)
575                         BT_ERR("Fail to set value");
576         }
577
578         if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
579                 BT_ERR("Set vconf failed\n");
580
581         _bt_adapter_set_status(BT_DEACTIVATED);
582
583         if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
584                 /* Send disabled event */
585                 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
586                                 g_variant_new("(i)", result));
587         }
588
589         BT_INFO("Adapter disabled");
590 }
591
592 static int __bt_set_le_enabled(void)
593 {
594         BT_DBG("+");
595         int result = BLUETOOTH_ERROR_NONE;
596         bt_status_t status;
597
598         __bt_set_local_name();
599
600         /* Update Bluetooth Status to notify other modules */
601         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
602                 BT_ERR("Set vconf failed\n");
603
604         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
605                                                 EVT_VAL_BT_LE_ON) != ES_R_OK)
606                 BT_ERR("Fail to set value");
607
608         /* Send enabled event to API */
609         /*
610         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
611                                 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
612         */
613         status = _bt_adapter_get_status();
614         if (status == BT_DEACTIVATED) {
615                 BT_INFO("BREDR is off, turn off PSCAN");
616                 _bt_set_connectable(FALSE);
617         }
618         if (le_timer_id > 0) {
619                 g_source_remove(le_timer_id);
620                 le_timer_id = 0;
621         }
622
623         /* Send enabled event to API */
624         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
625                                 g_variant_new("(i)", result));
626
627         BT_DBG("-");
628         return BLUETOOTH_ERROR_NONE;
629 }
630
631 void _bt_set_le_disabled(int result)
632 {
633         int power_off_status;
634         int ret;
635
636         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
637         BT_DBG("ret : %d", ret);
638         BT_DBG("power_off_status : %d", power_off_status);
639
640         /* Update Bluetooth Status to notify other modules */
641         BT_DBG("Update vconf for BT LE normal Deactivation");
642         if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
643                 BT_ERR("Set vconf failed\n");
644         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
645
646         if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
647                                                 EVT_VAL_BT_LE_OFF) != ES_R_OK)
648                 BT_ERR("Fail to set value");
649
650         /* Send disabled event */
651         _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
652                         g_variant_new_int32(result));
653 }
654
655 void *_bt_get_adapter_agent(void)
656 {
657         return adapter_agent;
658 }
659
660 int _bt_enable_core(void)
661 {
662         GDBusProxy *proxy;
663         GVariant *result;
664         GError *error = NULL;
665
666         proxy = __bt_get_core_proxy();
667         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
668
669         /* Clean up the process */
670         result = g_dbus_proxy_call_sync(proxy,
671                                 "EnableCore",
672                                 NULL,
673                                 G_DBUS_CALL_FLAGS_NONE,
674                                 -1,
675                                 NULL,
676                                 &error);
677
678         if (!result) {
679                 if (error != NULL) {
680                         BT_ERR("Bt core call failed(Error: %s)", error->message);
681                         g_clear_error(&error);
682                 } else
683                         BT_ERR("Bt core call failed");
684                 return BLUETOOTH_ERROR_INTERNAL;
685         }
686
687         g_variant_unref(result);
688         return BLUETOOTH_ERROR_NONE;
689 }
690
691 #if defined(TIZEN_BT_FLIGHTMODE_ENABLED) || !defined(TIZEN_WEARABLE)
692 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
693 {
694         gboolean flight_mode = FALSE;
695         int power_saving_mode = 0;
696         int type;
697
698         DBG_SECURE("key=%s", vconf_keynode_get_name(node));
699         type = vconf_keynode_get_type(node);
700         if (type == VCONF_TYPE_BOOL) {
701                 flight_mode = vconf_keynode_get_bool(node);
702                 if (flight_mode != TRUE) {
703                         BT_ERR("Ignore the event");
704                         return;
705                 }
706         } else if (type == VCONF_TYPE_INT) {
707                 power_saving_mode = vconf_keynode_get_int(node);
708                 if (power_saving_mode != 2) {
709                         BT_ERR("Ignore the event");
710                         return;
711                 }
712         } else {
713                 BT_ERR("Invaild vconf key type : %d", type);
714                 return;
715         }
716
717         _bt_enable_core();
718 }
719 #endif
720
721 void _bt_service_register_vconf_handler(void)
722 {
723         BT_DBG("+");
724
725 #ifdef TIZEN_TELEPHONY_ENABLED
726         if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
727                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
728                 BT_ERR("Unable to register key handler");
729 #else
730         BT_DBG("Telephony is disabled");
731 #endif
732
733 #ifndef TIZEN_WEARABLE
734 #ifdef ENABLE_TIZEN_2_4
735         if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
736                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
737                 BT_ERR("Unable to register key handler");
738 #endif
739 #endif
740 }
741
742 void _bt_service_unregister_vconf_handler(void)
743 {
744         BT_DBG("+");
745
746 #ifdef TIZEN_TELEPHONY_ENABLED
747         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
748                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
749 #endif
750
751 #ifndef TIZEN_WEARABLE
752 #ifdef ENABLE_TIZEN_2_4
753         vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
754                         (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
755 #endif
756 #endif
757 }
758
759 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
760 {
761         const char *bt_status = NULL;
762         const char *bt_le_status = NULL;
763         const char *bt_transfering_status = NULL;
764         BT_DBG("bt state set event(%s) received", event_name);
765 #ifdef ENABLE_TIZEN_2_4
766         bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
767         BT_DBG("bt_state: (%s)", bt_status);
768
769         bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
770         BT_DBG("bt_state: (%s)", bt_le_status);
771 #endif
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         status = _bt_adapter_get_status();
788         le_status = _bt_adapter_get_le_status();
789         BT_DBG("status : %d", status);
790         BT_DBG("le_status : %d", le_status);
791
792         adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
793         if (!adapter_agent) {
794                 BT_ERR("Fail to register agent");
795                 return;
796         }
797
798         if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
799                 BT_ERR("Fail to register media player");
800
801         if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
802                 BT_ERR("Fail to init obex server");
803
804 #ifdef TIZEN_BT_PAN_NAP_ENABLE
805         if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
806                 BT_ERR("Fail to activate network");
807 #endif
808
809         /* add the vconf noti handler */
810         ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
811                                         __bt_phone_name_changed_cb, NULL);
812         if (ret < 0)
813                 BT_ERR("Unable to register key handler");
814
815         if (le_status == BT_LE_ACTIVATING ||
816                  status == BT_ACTIVATING) {
817                 __bt_set_le_enabled();
818                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
819         }
820
821         if (status == BT_ACTIVATING) {
822                 __bt_set_enabled();
823                 _bt_adapter_set_status(BT_ACTIVATED);
824         }
825 #ifdef ENABLE_TIZEN_2_4
826         journal_bt_on();
827 #endif
828
829         _bt_service_register_vconf_handler();
830
831         /* eventsystem */
832         if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
833                         (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
834                 BT_ERR("Fail to register system event");
835         }
836 }
837
838 void _bt_handle_adapter_removed(void)
839 {
840         int ret;
841
842         _bt_adapter_set_status(BT_DEACTIVATED);
843 #ifdef ENABLE_TIZEN_2_4
844         journal_bt_off();
845 #endif
846
847         __bt_visibility_alarm_remove();
848
849         if (visible_timer.alarm_init) {
850                 alarmmgr_fini();
851                 visible_timer.alarm_init = FALSE;
852         }
853
854         ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
855                                 (vconf_callback_fn)__bt_phone_name_changed_cb);
856         if (0 != ret) {
857                 ERR("vconf_ignore_key_changed failed\n");
858         }
859
860         _bt_destroy_agent(adapter_agent);
861         adapter_agent = NULL;
862
863         _bt_reliable_terminate_service(NULL);
864
865         if (eventsystem_unregister_event(status_reg_id) != ES_R_OK) {
866                 BT_ERR("Fail to unregister system event");
867         }
868
869 }
870
871 static gboolean __bt_enable_timeout_cb(gpointer user_data)
872 {
873         GDBusProxy *proxy;
874         GVariant *result;
875         GError *error = NULL;
876
877         timer_id = 0;
878
879         retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
880
881         BT_ERR("EnableAdapter is failed");
882
883         proxy = __bt_get_core_proxy();
884         if (!proxy)
885                 return FALSE;
886
887         /* Clean up the process */
888         result = g_dbus_proxy_call_sync(proxy,
889                                 "DisableAdapter",
890                                 NULL,
891                                 G_DBUS_CALL_FLAGS_NONE,
892                                 -1,
893                                 NULL,
894                                 &error);
895
896         if (!result) {
897                 if (error != NULL) {
898                         BT_ERR("Bt core call failed(Error: %s)", error->message);
899                         g_clear_error(&error);
900                 } else {
901                         BT_ERR("Bt core call failed");
902                 }
903                 return FALSE;
904         }
905
906         g_variant_unref(result);
907         _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
908
909         _bt_terminate_service(NULL);
910
911         return FALSE;
912 }
913
914 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
915 {
916         GDBusProxy *proxy;
917         GVariant *result;
918         GError *error = NULL;
919
920         le_timer_id = 0;
921
922         retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
923
924         BT_ERR("EnableAdapterLE is failed");
925
926         proxy = __bt_get_core_proxy();
927         if (!proxy)
928                 return FALSE;
929
930         /* Clean up the process */
931         result = g_dbus_proxy_call_sync(proxy,
932                                 "DisableAdapterLe",
933                                 NULL,
934                                 G_DBUS_CALL_FLAGS_NONE,
935                                 -1,
936                                 NULL,
937                                 &error);
938
939         if (!result) {
940                 if (error != NULL) {
941                         BT_ERR("Bt core call failed(Error: %s)", error->message);
942                         g_clear_error(&error);
943                 } else
944                         BT_ERR("Bt core call failed");
945                 return FALSE;
946         }
947
948         g_variant_unref(result);
949         _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
950
951         _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
952
953         if (_bt_adapter_get_status() == BT_DEACTIVATED)
954                 _bt_terminate_service(NULL);
955
956         return FALSE;
957 }
958
959 void _bt_adapter_start_le_enable_timer(void)
960 {
961         if (le_timer_id > 0) {
962                 g_source_remove(le_timer_id);
963                 le_timer_id = 0;
964         }
965
966         le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
967                         __bt_enable_le_timeout_cb, NULL);
968
969         return;
970 }
971
972 void _bt_adapter_start_enable_timer(void)
973 {
974         if (timer_id > 0) {
975                 g_source_remove(timer_id);
976                 timer_id = 0;
977         }
978
979         timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
980                         __bt_enable_timeout_cb, NULL);
981
982         return;
983 }
984
985 #ifdef TIZEN_TV
986 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
987 {
988         BT_DBG("+");
989
990         __bt_set_enabled();
991         _bt_adapter_set_status(BT_ACTIVATED);
992
993         return FALSE;
994 }
995 #endif
996
997 int _bt_enable_adapter(void)
998 {
999         GDBusProxy *proxy;
1000         GError *error = NULL;
1001         int ret;
1002         GVariant *result = NULL;
1003         bt_status_t status = _bt_adapter_get_status();
1004         bt_le_status_t le_status = _bt_adapter_get_le_status();
1005
1006         BT_DBG("");
1007
1008         if (status == BT_ACTIVATING) {
1009                 BT_ERR("Enabling in progress");
1010                 return BLUETOOTH_ERROR_IN_PROGRESS;
1011         }
1012
1013         if (status == BT_ACTIVATED) {
1014                 BT_ERR("Already enabled");
1015                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1016         }
1017
1018         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1019                 BT_ERR("Disabling in progress");
1020                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1021         }
1022
1023         _bt_adapter_set_status(BT_ACTIVATING);
1024
1025 #ifdef TIZEN_TV
1026 {
1027         int adapter_status = BT_ADAPTER_DISABLED;
1028
1029         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1030                 BT_ERR("Set vconf failed");
1031
1032         _bt_check_adapter(&adapter_status);
1033         if (adapter_status == BT_ADAPTER_ENABLED) {
1034                 g_idle_add(__bt_adapter_enabled_cb, NULL);
1035                 _bt_adapter_start_enable_timer();
1036                 return BLUETOOTH_ERROR_NONE;
1037         }
1038 }
1039 #endif
1040
1041         proxy = __bt_get_core_proxy();
1042         if (!proxy)
1043                 return BLUETOOTH_ERROR_INTERNAL;
1044
1045         if (le_status == BT_LE_ACTIVATED) {
1046                 BT_INFO("LE Already enabled. Just turn on PSCAN");
1047                 ret = _bt_set_connectable(TRUE);
1048                 if (ret == BLUETOOTH_ERROR_NONE) {
1049                         _bt_adapter_set_status(BT_ACTIVATED);
1050                 } else {
1051                         return BLUETOOTH_ERROR_INTERNAL;
1052                 }
1053         }
1054
1055         result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1056                                          NULL,
1057                                          G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1058                                          NULL, &error);
1059          if (error) {
1060                  BT_ERR("EnableAdapterLe failed: %s", error->message);
1061                 _bt_adapter_set_status(BT_DEACTIVATED);
1062                 g_clear_error(&error);
1063                 error = NULL;
1064                 result = g_dbus_proxy_call_sync(proxy,
1065                                 "DisableAdapter",
1066                                 NULL,
1067                                 G_DBUS_CALL_FLAGS_NONE,
1068                                 -1,
1069                                 NULL,
1070                                 &error);
1071
1072                 if (error != NULL) {
1073                                 BT_ERR("Bt core call failed(Error: %s)", error->message);
1074                                 g_clear_error(&error);
1075                 }
1076                 g_variant_unref(result);
1077                 /* Terminate myself */
1078                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1079                 return BLUETOOTH_ERROR_INTERNAL;
1080         }
1081         g_variant_unref(result);
1082         if (le_status == BT_LE_ACTIVATED) {
1083                 __bt_set_enabled();
1084         } else {
1085                 _bt_adapter_start_enable_timer();
1086         }
1087
1088         return BLUETOOTH_ERROR_NONE;
1089 }
1090
1091 static gboolean __bt_disconnect_all(void)
1092 {
1093         int i;
1094         GDBusConnection *conn;
1095         GDBusProxy *dev_proxy;
1096         gboolean ret = FALSE;
1097         GVariant *result;
1098         GError *error = NULL;
1099         GArray *device_list;
1100         bluetooth_device_info_t info;
1101         guint size;
1102         char *device_path = NULL;
1103         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1104
1105
1106         BT_DBG("");
1107
1108         conn = _bt_get_system_gconn();
1109
1110         device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1111
1112         if (_bt_get_bonded_devices(&device_list)
1113                                         != BLUETOOTH_ERROR_NONE) {
1114                 g_array_free(device_list, TRUE);
1115                 return FALSE;
1116         }
1117
1118         size = (device_list->len) / sizeof(bluetooth_device_info_t);
1119
1120         for (i = 0; i < size; i++) {
1121
1122                 info = g_array_index(device_list,
1123                                 bluetooth_device_info_t, i);
1124
1125                 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1126                         BT_DBG("Found Connected device");
1127                         _bt_convert_addr_type_to_string(address, info.device_address.addr);
1128                         device_path = _bt_get_device_object_path(address);
1129                         if (device_path == NULL)
1130                                 continue;
1131
1132                         BT_DBG("Disconnecting : %s", device_path);
1133
1134                         dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1135                                                         NULL,
1136                                                         BT_BLUEZ_NAME,
1137                                                         device_path,
1138                                                         BT_DEVICE_INTERFACE,
1139                                                         NULL, NULL);
1140
1141                         if (dev_proxy == NULL)
1142                                 continue;
1143
1144                         result = g_dbus_proxy_call_sync(dev_proxy,
1145                                                 "Disconnect",
1146                                                 NULL,
1147                                                 G_DBUS_CALL_FLAGS_NONE,
1148                                                 -1,
1149                                                 NULL,
1150                                                 &error);
1151
1152                         if (!result) {
1153                                 if (error != NULL) {
1154                                         BT_ERR("Disconnect call failed(Error: %s)", error->message);
1155                                         g_clear_error(&error);
1156                                 } else
1157                                         BT_ERR("Disconnect call failed");
1158                                 g_object_unref(dev_proxy);
1159                                 return FALSE;
1160                         }
1161
1162                         g_variant_unref(result);
1163                         g_object_unref(dev_proxy);
1164                 }
1165         }
1166         ret = TRUE;
1167         g_array_free(device_list, TRUE);
1168
1169         return ret;
1170 }
1171
1172 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1173 {
1174         BT_DBG("");
1175         _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1176
1177         return FALSE;
1178 }
1179
1180 int __bt_disable_cb(void)
1181 {
1182         FN_START;
1183         GDBusProxy *proxy;
1184         bt_le_status_t le_status;
1185         int ret;
1186         GVariant *result;
1187         GError *error = NULL;
1188
1189         _bt_adapter_set_status(BT_DEACTIVATING);
1190         le_status = _bt_adapter_get_le_status();
1191         BT_DBG("le_status : %d", le_status);
1192         if (le_status == BT_LE_ACTIVATED) {
1193                 BT_INFO("LE is enabled. Just turn off PSCAN");
1194
1195                 if (_bt_is_discovering())
1196                         _bt_cancel_discovery();
1197
1198                 if (_bt_is_connectable() == FALSE) {
1199                         g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1200                 } else {
1201                         ret = _bt_set_connectable(FALSE);
1202                         if (ret != BLUETOOTH_ERROR_NONE) {
1203                                 BT_ERR("_bt_set_connectable fail!");
1204                                 _bt_adapter_set_status(BT_ACTIVATED);
1205                                 return BLUETOOTH_ERROR_INTERNAL;
1206                         }
1207                 }
1208         }
1209
1210         proxy = __bt_get_core_proxy();
1211         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1212
1213         result = g_dbus_proxy_call_sync(proxy,
1214                                 "DisableAdapter",
1215                                 NULL,
1216                                 G_DBUS_CALL_FLAGS_NONE,
1217                                 -1,
1218                                 NULL,
1219                                 &error);
1220
1221         if (!result) {
1222                 if (error != NULL) {
1223                         BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1224                         g_clear_error(&error);
1225                 } else
1226                         BT_ERR("Failed to DisableAdapter");
1227                 _bt_adapter_set_status(BT_ACTIVATED);
1228                 return BLUETOOTH_ERROR_INTERNAL;
1229         }
1230
1231         g_variant_unref(result);
1232         return BLUETOOTH_ERROR_NONE;
1233 }
1234
1235 int _bt_disable_adapter(void)
1236 {
1237         BT_DBG("+");
1238         int ret;
1239
1240         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1241                 BT_DBG("Disabling in progress");
1242                 return BLUETOOTH_ERROR_IN_PROGRESS;
1243         }
1244
1245         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1246                 BT_DBG("Already disabled");
1247                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1248         }
1249
1250         if (timer_id > 0) {
1251                 g_source_remove(timer_id);
1252                 timer_id = 0;
1253         }
1254
1255         __bt_disconnect_all();
1256         ret = __bt_disable_cb();
1257
1258         BT_DBG("-");
1259         return ret;
1260 }
1261
1262 int _bt_recover_adapter(void)
1263 {
1264         BT_DBG("+");
1265         GDBusProxy *proxy;
1266         GVariant *result;
1267         GError *error = NULL;
1268
1269         if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1270                 BT_DBG("Disabling in progress");
1271                 return BLUETOOTH_ERROR_IN_PROGRESS;
1272         }
1273
1274         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1275                 BT_DBG("Already disabled");
1276                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1277         }
1278
1279         _bt_adapter_set_status(BT_DEACTIVATING);
1280
1281         proxy = __bt_get_core_proxy();
1282         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1283
1284         result = g_dbus_proxy_call_sync(proxy,
1285                                 "RecoverAdapter",
1286                                 NULL,
1287                                 G_DBUS_CALL_FLAGS_NONE,
1288                                 -1,
1289                                 NULL,
1290                                 &error);
1291
1292         if (!result) {
1293                 if (error != NULL) {
1294                         BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1295                         g_clear_error(&error);
1296                 } else
1297                         BT_ERR("Failed to RecoverAdapter");
1298                 return BLUETOOTH_ERROR_INTERNAL;
1299         }
1300
1301         g_variant_unref(result);
1302         __bt_disconnect_all();
1303
1304         BT_DBG("-");
1305         return BLUETOOTH_ERROR_NONE;
1306 }
1307
1308 int _bt_reset_adapter(void)
1309 {
1310         GDBusProxy *proxy;
1311         GVariant *result;
1312         GError *error = NULL;
1313
1314         BT_DBG("");
1315
1316         proxy = __bt_get_core_proxy();
1317         if (!proxy)
1318                 return BLUETOOTH_ERROR_INTERNAL;
1319
1320         result = g_dbus_proxy_call_sync(proxy,
1321                                 "ResetAdapter",
1322                                 NULL,
1323                                 G_DBUS_CALL_FLAGS_NONE,
1324                                 -1,
1325                                 NULL,
1326                                 &error);
1327
1328         if (!result) {
1329                 if (error != NULL) {
1330                         BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1331                         g_clear_error(&error);
1332                 } else
1333                         BT_ERR("Failed to ResetAdapter");
1334                 return BLUETOOTH_ERROR_INTERNAL;
1335         }
1336
1337         g_variant_unref(result);
1338         /* Terminate myself */
1339         if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1340                 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1341         }
1342
1343         return BLUETOOTH_ERROR_NONE;
1344 }
1345
1346 #ifndef TIZEN_TV
1347 int _bt_check_adapter(int *status)
1348 {
1349
1350         char *adapter_path = NULL;
1351
1352         BT_CHECK_PARAMETER(status, return);
1353
1354         *status = BT_ADAPTER_DISABLED;
1355
1356         adapter_path = _bt_get_adapter_path();
1357
1358
1359         if (adapter_path != NULL)
1360                 *status = BT_ADAPTER_ENABLED;
1361
1362         g_free(adapter_path);
1363         return BLUETOOTH_ERROR_NONE;
1364 }
1365 #else
1366 int _bt_check_adapter(int *status)
1367 {
1368         GDBusProxy *proxy;
1369         GError *error = NULL;
1370         GVariant *result;
1371         GVariant *temp;
1372         gboolean powered = FALSE;
1373
1374         BT_CHECK_PARAMETER(status, return);
1375
1376         *status = BT_ADAPTER_DISABLED;
1377
1378         proxy = _bt_get_adapter_properties_proxy();
1379         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1380
1381         result = g_dbus_proxy_call_sync(proxy,
1382                                 "Get",
1383                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1384                                         "Powered"),
1385                                 G_DBUS_CALL_FLAGS_NONE,
1386                                 -1,
1387                                 NULL,
1388                                 &error);
1389
1390         if (!result) {
1391                 BT_ERR("Failed to get local address");
1392                 if (error != NULL) {
1393                         BT_ERR("Failed to get local address (Error: %s)", error->message);
1394                         g_clear_error(&error);
1395                 }
1396                 return BLUETOOTH_ERROR_INTERNAL;
1397         }
1398
1399         g_variant_get(result, "(v)", &temp);
1400         powered = g_variant_get_boolean(temp);
1401         BT_DBG("powered: %d", powered);
1402
1403         if (powered)
1404                 *status = BT_ADAPTER_ENABLED;
1405
1406         g_variant_unref(result);
1407         g_variant_unref(temp);
1408         return BLUETOOTH_ERROR_NONE;
1409 }
1410 #endif
1411
1412 int _bt_enable_adapter_le(void)
1413 {
1414         BT_DBG("+");
1415         GDBusProxy *proxy;
1416         GError *error = NULL;
1417         bt_status_t status = _bt_adapter_get_status();
1418         bt_le_status_t le_status = _bt_adapter_get_le_status();
1419         GVariant *result;
1420
1421         if (le_status == BT_LE_ACTIVATING) {
1422                 BT_ERR("Enabling in progress");
1423                 return BLUETOOTH_ERROR_IN_PROGRESS;
1424         }
1425
1426         if (le_status == BT_LE_ACTIVATED) {
1427                 BT_ERR("Already enabled");
1428                 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1429         }
1430
1431         if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1432                 BT_ERR("Disabling in progress");
1433                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1434         }
1435
1436         _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1437
1438         proxy = __bt_get_core_proxy();
1439         retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1440
1441         result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1442                                         NULL,
1443                                         G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1444                                         NULL, &error);
1445         if (error) {
1446                 BT_ERR("EnableAdapterLe failed: %s", error->message);
1447                 _bt_adapter_set_le_status(BT_DEACTIVATED);
1448                 g_clear_error(&error);
1449
1450                 /* Clean up the process */
1451                 result = g_dbus_proxy_call_sync(proxy,
1452                                         "DisableAdapterLe",
1453                                         NULL,
1454                                         G_DBUS_CALL_FLAGS_NONE,
1455                                         -1,
1456                                         NULL,
1457                                         &error);
1458
1459                 if (!result) {
1460                                 BT_ERR("Bt core call failed");
1461                                 if (error) {
1462                                         BT_ERR("EnableAdapterLE Failed %s", error->message);
1463                                         g_clear_error(&error);
1464                                 }
1465                 }
1466                 g_variant_unref(result);
1467                 /* Terminate myself */
1468                 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1469                         g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1470                 return BLUETOOTH_ERROR_INTERNAL;
1471         }
1472
1473         if (result)
1474                 g_variant_unref(result);
1475
1476         _bt_adapter_start_le_enable_timer();
1477
1478         if (status == BT_ACTIVATED) {
1479                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1480                 __bt_set_le_enabled();
1481         }
1482         BT_DBG("le status : %d", _bt_adapter_get_le_status());
1483         BT_DBG("-");
1484         return BLUETOOTH_ERROR_NONE;
1485 }
1486
1487 int _bt_disable_adapter_le(void)
1488 {
1489         BT_DBG("+");
1490         GDBusProxy *proxy;
1491         bt_le_status_t bt_le_state;
1492         GVariant *result;
1493         GError *error = NULL;
1494
1495         bt_le_state = _bt_adapter_get_le_status();
1496         if (bt_le_state == BT_LE_DEACTIVATING) {
1497                 BT_DBG("Disabling in progress");
1498                 return BLUETOOTH_ERROR_IN_PROGRESS;
1499         }
1500
1501         if (bt_le_state == BT_LE_DEACTIVATED) {
1502                 BT_DBG("Already disabled");
1503                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1504         }
1505
1506         _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1507
1508         proxy = __bt_get_core_proxy();
1509         if (!proxy)
1510                 return BLUETOOTH_ERROR_INTERNAL;
1511
1512         result = g_dbus_proxy_call_sync(proxy,
1513                                 "DisableAdapterLe",
1514                                 NULL,
1515                                 G_DBUS_CALL_FLAGS_NONE,
1516                                 -1,
1517                                 NULL,
1518                                 &error);
1519
1520         if (!result) {
1521                 if (error != NULL) {
1522                         BT_ERR("Bt core call failed (Error: %s)", error->message);
1523                         g_clear_error(&error);
1524                 } else
1525                         BT_ERR("Bt core call failed");
1526                 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1527                 return BLUETOOTH_ERROR_INTERNAL;
1528         }
1529
1530         g_variant_unref(result);
1531         _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1532         BT_DBG("le status : %d", _bt_adapter_get_le_status());
1533         BT_DBG("-");
1534         return BLUETOOTH_ERROR_NONE;
1535 }
1536
1537 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1538 {
1539
1540         GDBusProxy *proxy;
1541         GError *error = NULL;
1542         const char *address;
1543         GVariant *result;
1544         GVariant *temp;
1545
1546         BT_CHECK_PARAMETER(local_address, return);
1547
1548         proxy = _bt_get_adapter_properties_proxy();
1549         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1550
1551         result = g_dbus_proxy_call_sync(proxy,
1552                                 "Get",
1553                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1554                                         "Address"),
1555                                 G_DBUS_CALL_FLAGS_NONE,
1556                                 -1,
1557                                 NULL,
1558                                 &error);
1559
1560         if (!result) {
1561                 BT_ERR("Failed to get local address");
1562                 if (error != NULL) {
1563                         BT_ERR("Failed to get local address (Error: %s)", error->message);
1564                         g_clear_error(&error);
1565                 }
1566                 return BLUETOOTH_ERROR_INTERNAL;
1567         }
1568
1569         g_variant_get(result, "(v)", &temp);
1570         address = g_variant_get_string(temp, NULL);
1571         BT_DBG("Address:%s", address);
1572
1573         if (address) {
1574                 _bt_convert_addr_string_to_type(local_address->addr, address);
1575         } else {
1576                 return BLUETOOTH_ERROR_INTERNAL;
1577         }
1578
1579         g_variant_unref(result);
1580         g_variant_unref(temp);
1581         return BLUETOOTH_ERROR_NONE;
1582 }
1583
1584 int _bt_get_local_version(bluetooth_version_t *local_version)
1585 {
1586         GDBusProxy *proxy;
1587         const char *ver = NULL;
1588         char *ptr = NULL;
1589         int ret = BLUETOOTH_ERROR_NONE;
1590         GVariant *result;
1591         GVariant *temp;
1592
1593         BT_CHECK_PARAMETER(local_version, return);
1594
1595         GError *error = NULL;
1596
1597         proxy = _bt_get_adapter_properties_proxy();
1598         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1599
1600         result = g_dbus_proxy_call_sync(proxy,
1601                                 "Get",
1602                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1603                                         "Version"),
1604                                 G_DBUS_CALL_FLAGS_NONE,
1605                                 -1,
1606                                 NULL,
1607                                 &error);
1608
1609         if (!result) {
1610                 if (error != NULL) {
1611                         BT_ERR("Failed to get local version (Error: %s)", error->message);
1612                         g_clear_error(&error);
1613                 } else
1614                         BT_ERR("Failed to get local version");
1615                 return BLUETOOTH_ERROR_INTERNAL;
1616         }
1617
1618         g_variant_get(result, "(v)", &temp);
1619         ver = g_variant_get_string(temp, NULL);
1620         BT_DBG("VERSION: %s", ver);
1621
1622         if (ver && (strlen(ver) > 0)) {
1623                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1624                 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1625                         *ptr = '\0';
1626
1627                 g_strlcpy(local_version->version, ver,
1628                                 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1629
1630         } else {
1631                 ret = BLUETOOTH_ERROR_INTERNAL;
1632         }
1633
1634         g_variant_unref(result);
1635         g_variant_unref(temp);
1636         return ret;
1637 }
1638
1639 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1640 {
1641         GDBusProxy *proxy;
1642         const char *name = NULL;
1643         char *ptr = NULL;
1644         int ret = BLUETOOTH_ERROR_NONE;
1645         GVariant *result;
1646         GVariant *temp;
1647         GError *error = NULL;
1648
1649         BT_CHECK_PARAMETER(local_name, return);
1650
1651         proxy = _bt_get_adapter_properties_proxy();
1652         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1653
1654         result = g_dbus_proxy_call_sync(proxy,
1655                                 "Get",
1656                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1657                                         "Alias"),
1658                                 G_DBUS_CALL_FLAGS_NONE,
1659                                 -1,
1660                                 NULL,
1661                                 &error);
1662
1663         if (!result) {
1664                 if (error != NULL) {
1665                         BT_ERR("Failed to get local name (Error: %s)", error->message);
1666                         g_clear_error(&error);
1667                 } else
1668                         BT_ERR("Failed to get local name");
1669                 return BLUETOOTH_ERROR_INTERNAL;
1670         }
1671
1672         g_variant_get(result, "(v)", &temp);
1673         name = g_variant_get_string(temp, NULL);
1674         BT_DBG("LOCAL NAME:%s", name);
1675
1676         if (name && (strlen(name) > 0)) {
1677                 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1678                 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1679                         *ptr = '\0';
1680
1681                 g_strlcpy(local_name->name, name,
1682                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1683         } else {
1684                 ret = BLUETOOTH_ERROR_INTERNAL;
1685         }
1686         g_variant_unref(result);
1687         g_variant_unref(temp);
1688         return ret;
1689 }
1690
1691 int _bt_set_local_name(char *local_name)
1692 {
1693         GDBusProxy *proxy;
1694         GError *error = NULL;
1695         char *ptr = NULL;
1696         GVariant *result;
1697
1698         BT_CHECK_PARAMETER(local_name, return);
1699
1700         proxy = _bt_get_adapter_properties_proxy();
1701
1702         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1703
1704         if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1705                 *ptr = '\0';
1706
1707         result = g_dbus_proxy_call_sync(proxy,
1708                                 "Set",
1709                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1710                                         "Alias", g_variant_new("s", local_name)),
1711                                 G_DBUS_CALL_FLAGS_NONE,
1712                                 -1,
1713                                 NULL,
1714                                 &error);
1715
1716         if (!result) {
1717                 if (error != NULL) {
1718                         BT_ERR("Failed to set Alias (Error: %s)", error->message);
1719                         g_clear_error(&error);
1720                 } else
1721                         BT_ERR("Failed to set Alias");
1722                 return BLUETOOTH_ERROR_INTERNAL;
1723         }
1724
1725         g_variant_unref(result);
1726         return BLUETOOTH_ERROR_NONE;
1727 }
1728
1729 int _bt_is_service_used(char *service_uuid, gboolean *used)
1730 {
1731         GDBusProxy *proxy;
1732         GError *error = NULL;
1733         int ret = BLUETOOTH_ERROR_NONE;
1734         GVariant *result;
1735         GVariant *value;
1736         GVariantIter *iter = NULL;
1737         gchar *uuid;
1738
1739         BT_DBG("+");
1740         BT_CHECK_PARAMETER(service_uuid, return);
1741         BT_CHECK_PARAMETER(used, return);
1742
1743         proxy = _bt_get_adapter_properties_proxy();
1744         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1745
1746         result = g_dbus_proxy_call_sync(proxy,
1747                                 "Get",
1748                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1749                                         "UUIDs"),
1750                                 G_DBUS_CALL_FLAGS_NONE,
1751                                 -1,
1752                                 NULL,
1753                                 &error);
1754
1755         if (!result) {
1756                 if (error != NULL) {
1757                         BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1758                         g_clear_error(&error);
1759                 } else
1760                         BT_ERR("Failed to get UUIDs");
1761                 return BLUETOOTH_ERROR_INTERNAL;
1762         }
1763
1764         g_variant_get(result, "(v)", &value);
1765         g_variant_get(value, "as", &iter);
1766         if(iter == NULL) {
1767                 BT_ERR("Failed to get UUIDs(%s)",service_uuid);
1768                 *used = FALSE;
1769                 g_variant_unref(result);
1770                 g_variant_unref(value);
1771                 return ret;
1772         }
1773
1774         while (g_variant_iter_loop(iter, "s", &uuid)) {
1775                 if (strcasecmp(uuid, service_uuid) == 0) {
1776                         *used = TRUE;
1777                         g_free(uuid);
1778                         goto done;
1779                 }
1780         }
1781
1782         *used = FALSE;
1783
1784 done:
1785         g_variant_iter_free(iter);
1786         g_variant_unref(value);
1787         g_variant_unref(result);
1788         BT_DBG("Service Used? %d", *used);
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         switch (discoverable_mode) {
1867         case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1868                 pg_scan = TRUE;
1869                 inq_scan = FALSE;
1870                 timeout = 0;
1871                 break;
1872         case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1873                 pg_scan = TRUE;
1874                 inq_scan = TRUE;
1875                 timeout = 0;
1876                 break;
1877         case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1878                 inq_scan = TRUE;
1879                 pg_scan = TRUE;
1880                 break;
1881         default:
1882                 return BLUETOOTH_ERROR_INVALID_PARAM;
1883         }
1884
1885         BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1886                         discoverable_mode, timeout);
1887
1888         result = g_dbus_proxy_call_sync(proxy,
1889                                 "Set",
1890                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1891                                         "Connectable", g_variant_new("b", pg_scan)),
1892                                 G_DBUS_CALL_FLAGS_NONE,
1893                                 -1,
1894                                 NULL,
1895                                 &error);
1896
1897         if (!result) {
1898                 if (error != NULL) {
1899                         BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1900                         g_clear_error(&error);
1901                 } else
1902                         BT_ERR("Failed to set connectable property");
1903                 return BLUETOOTH_ERROR_INTERNAL;
1904         }
1905         g_variant_unref(result);
1906         result = g_dbus_proxy_call_sync(proxy,
1907                                 "Set",
1908                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
1909                                                 g_variant_new("b", inq_scan)),
1910                                 G_DBUS_CALL_FLAGS_NONE,
1911                                 -1,
1912                                 NULL,
1913                                 &error);
1914
1915         if (!result) {
1916                 if (error != NULL) {
1917                         BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
1918                         g_clear_error(&error);
1919                 } else
1920                         BT_ERR("Failed to set Discoverable property");
1921                 return BLUETOOTH_ERROR_INTERNAL;
1922         }
1923         g_variant_unref(result);
1924         result = g_dbus_proxy_call_sync(proxy,
1925                                 "Set",
1926                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1927                                         "DiscoverableTimeout", g_variant_new("u", timeout)),
1928                                 G_DBUS_CALL_FLAGS_NONE,
1929                                 -1,
1930                                 NULL,
1931                                 &error);
1932
1933         if (!result) {
1934                 if (error != NULL) {
1935                         BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
1936                         g_clear_error(&error);
1937                 } else
1938                         BT_ERR("Failed to set DiscoverableTimeout property");
1939                 return BLUETOOTH_ERROR_INTERNAL;
1940         }
1941
1942         if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1943                 timeout = -1;
1944
1945         ret = __bt_set_visible_time(timeout);
1946
1947         g_variant_unref(result);
1948
1949         return ret;
1950 }
1951
1952 int _bt_start_discovery(void)
1953 {
1954         GDBusProxy *proxy;
1955         GError *error = NULL;
1956         GVariant *result;
1957
1958         if (_bt_is_discovering() == TRUE) {
1959                 BT_ERR("BT is already in discovering");
1960                 return BLUETOOTH_ERROR_IN_PROGRESS;
1961         } else if (_bt_is_device_creating() == TRUE) {
1962                 BT_ERR("Bonding device is going on");
1963                 return BLUETOOTH_ERROR_DEVICE_BUSY;
1964         }
1965
1966         proxy = _bt_get_adapter_proxy();
1967         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1968
1969         result = g_dbus_proxy_call_sync(proxy,
1970                                 "StartDiscovery",
1971                                 NULL,
1972                                 G_DBUS_CALL_FLAGS_NONE,
1973                                 -1,
1974                                 NULL,
1975                                 &error);
1976
1977         if (!result) {
1978                 if (error != NULL) {
1979                         BT_ERR("StartDiscovery failed (Error: %s)", error->message);
1980                         g_clear_error(&error);
1981                 } else
1982                         BT_ERR("StartDiscovery failed");
1983                 return BLUETOOTH_ERROR_INTERNAL;
1984         }
1985
1986         is_discovering = TRUE;
1987         cancel_by_user = FALSE;
1988         /* discovery status will be change in event */
1989         g_variant_unref(result);
1990         return BLUETOOTH_ERROR_NONE;
1991 }
1992
1993 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
1994 {
1995         GDBusProxy *proxy;
1996         GVariant *result;
1997         GError *error = NULL;
1998         const gchar *disc_type;
1999
2000         if (_bt_is_discovering() == TRUE) {
2001                 BT_ERR("BT is already in discovering");
2002                 return BLUETOOTH_ERROR_IN_PROGRESS;
2003         }
2004
2005         proxy = _bt_get_adapter_proxy();
2006         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2007
2008         if (role == DISCOVERY_ROLE_BREDR)
2009                 disc_type = "BREDR";
2010         else if (role == DISCOVERY_ROLE_LE)
2011                 disc_type = "LE";
2012         else if (role == DISCOVERY_ROLE_LE_BREDR)
2013                 disc_type = "LE_BREDR";
2014         else
2015                 return BLUETOOTH_ERROR_INVALID_PARAM;
2016
2017         result = g_dbus_proxy_call_sync(proxy,
2018                                 "StartCustomDiscovery",
2019                                 g_variant_new("s", disc_type),
2020                                 G_DBUS_CALL_FLAGS_NONE,
2021                                 -1,
2022                                 NULL,
2023                                 &error);
2024
2025         if (!result) {
2026                 if (error != NULL) {
2027                         BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2028                         g_clear_error(&error);
2029                 } else
2030                         BT_ERR("StartCustomDiscovery failed");
2031                 return BLUETOOTH_ERROR_INTERNAL;
2032         }
2033
2034         is_discovering = TRUE;
2035         cancel_by_user = FALSE;
2036         /* discovery status will be change in event */
2037         g_variant_unref(result);
2038         return BLUETOOTH_ERROR_NONE;
2039 }
2040
2041 int _bt_cancel_discovery(void)
2042 {
2043         GDBusProxy *proxy;
2044         GError *error = NULL;
2045         GVariant *result;
2046
2047         if (_bt_is_discovering() == FALSE) {
2048                 BT_ERR("BT is not in discovering");
2049                 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2050         }
2051
2052         proxy = _bt_get_adapter_proxy();
2053         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2054
2055         result = g_dbus_proxy_call_sync(proxy,
2056                                 "StopDiscovery",
2057                                 NULL,
2058                                 G_DBUS_CALL_FLAGS_NONE,
2059                                 -1,
2060                                 NULL,
2061                                 &error);
2062
2063         if (!result) {
2064                 if (error != NULL) {
2065                         BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2066                         g_clear_error(&error);
2067                 } else
2068                         BT_ERR("StopDiscovery failed");
2069                 return BLUETOOTH_ERROR_INTERNAL;
2070         }
2071
2072         cancel_by_user = TRUE;
2073         /* discovery status will be change in event */
2074         g_variant_unref(result);
2075         return BLUETOOTH_ERROR_NONE;
2076 }
2077
2078 gboolean _bt_is_discovering(void)
2079 {
2080         return is_discovering;
2081 }
2082
2083 gboolean _bt_is_connectable(void)
2084 {
2085         GDBusProxy *proxy;
2086         GError *error = NULL;
2087         gboolean is_connectable = FALSE;
2088         GVariant *result;
2089         GVariant *temp;
2090
2091         proxy = _bt_get_adapter_properties_proxy();
2092         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2093
2094         result = g_dbus_proxy_call_sync(proxy,
2095                                 "Get",
2096                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2097                                         "Connectable"),
2098                                 G_DBUS_CALL_FLAGS_NONE,
2099                                 -1,
2100                                 NULL,
2101                                 &error);
2102
2103         if (!result) {
2104                 if (error != NULL) {
2105                         BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2106                         g_clear_error(&error);
2107                 } else
2108                         BT_ERR("Failed to get connectable property");
2109                 return BLUETOOTH_ERROR_INTERNAL;
2110         }
2111
2112         g_variant_get(result, "(v)", &temp);
2113         is_connectable = g_variant_get_boolean(temp);
2114         BT_DBG("discoverable_v:%d", is_connectable);
2115
2116         g_variant_unref(result);
2117         g_variant_unref(temp);
2118
2119         BT_INFO("Get connectable [%d]", is_connectable);
2120         return is_connectable;
2121 }
2122
2123 int _bt_set_connectable(gboolean is_connectable)
2124 {
2125         GDBusProxy *proxy;
2126         GError *error = NULL;
2127         GVariant *result;
2128
2129         if (__bt_is_factory_test_mode()) {
2130                 BT_ERR("Unable to set connectable in factory binary !!");
2131                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2132         }
2133
2134         proxy = _bt_get_adapter_properties_proxy();
2135
2136         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2137
2138         result = g_dbus_proxy_call_sync(proxy,
2139                                 "Set",
2140                                 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2141                                                 g_variant_new("b", is_connectable)),
2142                                 G_DBUS_CALL_FLAGS_NONE,
2143                                 -1,
2144                                 NULL,
2145                                 &error);
2146
2147         if (!result) {
2148                 if (error != NULL) {
2149                         BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2150                         g_clear_error(&error);
2151                 } else
2152                         BT_ERR("Failed to set connectable property");
2153                 return BLUETOOTH_ERROR_INTERNAL;
2154         }
2155
2156         BT_INFO("Set connectable [%d]", is_connectable);
2157         g_variant_unref(result);
2158         return BLUETOOTH_ERROR_NONE;
2159 }
2160
2161 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2162 {
2163         GDBusProxy *proxy;
2164         gboolean discovering_v;
2165         GError *error = NULL;
2166         char *discovering_type =  NULL;
2167         GVariant *result;
2168         GVariant *temp;
2169
2170         proxy = _bt_get_adapter_properties_proxy();
2171         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2172
2173         if (discovery_type == DISCOVERY_ROLE_BREDR)
2174                 discovering_type = "Discovering";
2175         else if (discovery_type == DISCOVERY_ROLE_LE)
2176                 discovering_type = "LEDiscovering";
2177
2178         result = g_dbus_proxy_call_sync(proxy,
2179                                 "Get",
2180                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2181                                         discovering_type),
2182                                 G_DBUS_CALL_FLAGS_NONE,
2183                                 -1,
2184                                 NULL,
2185                                 &error);
2186
2187         if (!result) {
2188                 if (error != NULL) {
2189                         BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2190                         g_clear_error(&error);
2191                 } else
2192                         BT_ERR("Failed to get discovering property");
2193                 return BLUETOOTH_ERROR_INTERNAL;
2194         }
2195
2196         g_variant_get(result, "(v)", &temp);
2197         discovering_v = g_variant_get_boolean(temp);
2198         BT_DBG("discoverable_v:%d", discovering_v);
2199
2200         g_variant_unref(result);
2201         g_variant_unref(temp);
2202
2203         return discovering_v;
2204 }
2205
2206 unsigned int _bt_get_discoverable_timeout_property(void)
2207 {
2208         GDBusProxy *proxy;
2209         unsigned int timeout_v;
2210         GError *error = NULL;
2211         GVariant *result;
2212         GVariant *temp;
2213
2214         proxy = _bt_get_adapter_properties_proxy();
2215         retv_if(proxy == NULL, 0);
2216
2217         result = g_dbus_proxy_call_sync(proxy,
2218                                 "Get",
2219                                 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2220                                         "DiscoverableTimeout"),
2221                                 G_DBUS_CALL_FLAGS_NONE,
2222                                 -1,
2223                                 NULL,
2224                                 &error);
2225
2226         if (!result) {
2227                 BT_ERR("Fail to get discoverable timeout");
2228                 if (error != NULL) {
2229                         BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2230                         g_clear_error(&error);
2231                 }
2232                 return 0;
2233         }
2234
2235         g_variant_get(result, "(v)", &temp);
2236         timeout_v = g_variant_get_uint32(temp);
2237         BT_DBG("discoverable_v:%d", timeout_v);
2238
2239         g_variant_unref(result);
2240         g_variant_unref(temp);
2241
2242         return timeout_v;
2243 }
2244
2245 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2246 {
2247         bluetooth_device_info_t *dev_info;
2248         GVariant *value;
2249         const gchar *key;
2250         GByteArray *manufacturer_data = NULL;
2251         guint8 char_value;
2252         GVariantIter *char_value_iter;
2253
2254         dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2255
2256         while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2257
2258                 if (key == NULL)
2259                         continue;
2260
2261                 if (!g_strcmp0(key, "Address")) {
2262                         const char *address = NULL;
2263                         address = g_variant_get_string(value, NULL);
2264                         _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2265                                                         address);
2266                 } else if(!g_strcmp0(key, "Class")) {
2267                         unsigned int cod;
2268                         cod = g_variant_get_uint32(value);
2269                         _bt_divide_device_class(&dev_info->device_class, cod);
2270                 } else if(!g_strcmp0(key, "Name")) {
2271                         const char *name = NULL;
2272                         name = g_variant_get_string(value, NULL);
2273                         /* If there is no Alias */
2274                         if (strlen(dev_info->device_name.name) == 0) {
2275                                 g_strlcpy(dev_info->device_name.name, name,
2276                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2277                         }
2278                 } else if(!g_strcmp0(key, "Alias")) {
2279                         const char *alias = NULL;
2280                         alias = g_variant_get_string(value, NULL);
2281                         /* Overwrite the name */
2282                         if (alias) {
2283                                 memset(dev_info->device_name.name, 0x00,
2284                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2285                                 g_strlcpy(dev_info->device_name.name, alias,
2286                                                 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2287                         }
2288                 } else if (!g_strcmp0(key, "Connected")) {
2289                         dev_info->connected = g_variant_get_byte(value);
2290                 } else if (!g_strcmp0(key, "Paired")) {
2291                         dev_info->paired = g_variant_get_boolean(value);
2292                 } else if (!g_strcmp0(key, "Trusted")) {
2293                         dev_info->trust = g_variant_get_boolean(value);
2294                 } else if (!g_strcmp0(key, "RSSI")) {
2295                         dev_info->rssi = g_variant_get_int16(value);
2296                 } else if (!g_strcmp0(key, "UUIDs")) {
2297                         GVariantIter *iter;
2298                         gchar *uuid = NULL;
2299                         char **parts;
2300                         int i = 0;
2301
2302                         dev_info->service_index = 0;
2303                         g_variant_get(value, "as", &iter);
2304                         while (g_variant_iter_loop(iter, "s", &uuid)) {
2305                                 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2306                                 parts = g_strsplit(uuid, "-", -1);
2307
2308                                 if (parts == NULL || parts[0] == NULL) {
2309                                         g_free(uuid);
2310                                         break;
2311                                 }
2312
2313                                 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2314                                 g_strfreev(parts);
2315
2316                                 i++;
2317                         }
2318                         dev_info->service_index = i;
2319                         g_variant_iter_free(iter);
2320                 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2321                         dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2322                 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2323                         manufacturer_data = g_byte_array_new();
2324                         g_variant_get(value, "ay", &char_value_iter);
2325                         while(g_variant_iter_loop(char_value_iter, "y",  &char_value)) {
2326                                 g_byte_array_append(manufacturer_data, &char_value, 1);
2327                         }
2328                         if (manufacturer_data) {
2329                                 if (manufacturer_data->len > 0) {
2330                                         memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2331                                 }
2332                         }
2333                         g_variant_iter_free(char_value_iter);
2334                         g_byte_array_free(manufacturer_data, TRUE);
2335                 }
2336         }
2337
2338         return dev_info;
2339 }
2340
2341 static void __bt_extract_device_info(GVariantIter *iter,
2342                                                         GArray **dev_list)
2343 {
2344         bluetooth_device_info_t *dev_info = NULL;
2345         char *object_path = NULL;
2346         GVariantIter *interface_iter;
2347         GVariantIter *svc_iter;
2348         char *interface_str = NULL;
2349
2350         /* Parse the signature:  oa{sa{sv}}} */
2351         while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2352                 &interface_iter)) {
2353
2354                 if (object_path == NULL)
2355                         continue;
2356
2357                 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2358                                 &interface_str, &svc_iter)) {
2359                         if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2360                                 BT_DBG("Found a device: %s", object_path);
2361                                 dev_info = __bt_parse_device_info(svc_iter);
2362                                 if (dev_info) {
2363                                         if (dev_info->paired == TRUE) {
2364                                                 g_array_append_vals(*dev_list, dev_info,
2365                                                                 sizeof(bluetooth_device_info_t));
2366                                         }
2367                                         g_free(dev_info);
2368                                 }
2369                                 g_free(interface_str);
2370                                 g_variant_iter_free(svc_iter);
2371                                 break;
2372                         }
2373                 }
2374         }
2375         BT_DBG("-");
2376 }
2377
2378 int _bt_get_bonded_devices(GArray **dev_list)
2379 {
2380         BT_DBG("+");
2381         GDBusConnection *conn;
2382         GDBusProxy *manager_proxy;
2383         GVariant *result = NULL;
2384         GVariantIter *iter = NULL;
2385         GError *error = NULL;
2386
2387         conn = _bt_get_system_conn();
2388         retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2389
2390         manager_proxy = _bt_get_manager_proxy();
2391         retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2392
2393         result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2394                                 NULL,
2395                                 G_DBUS_CALL_FLAGS_NONE,
2396                                 -1,
2397                                 NULL,
2398                                 NULL);
2399
2400         if (!result) {
2401                 if (error != NULL) {
2402                         BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2403                         g_clear_error(&error);
2404                 } else
2405                         BT_ERR("Failed to Failed to GetManagedObjects");
2406                 return BLUETOOTH_ERROR_INTERNAL;
2407         }
2408
2409         /* signature of GetManagedObjects:  a{oa{sa{sv}}} */
2410         g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2411
2412         __bt_extract_device_info(iter, dev_list);
2413         g_variant_iter_free(iter);
2414         g_variant_unref(result);
2415
2416         BT_DBG("-");
2417         return BLUETOOTH_ERROR_NONE;
2418 }
2419
2420 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2421                                 bluetooth_device_info_t *dev_info)
2422 {
2423         char *object_path = NULL;
2424         GDBusProxy *adapter_proxy;
2425         char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2426         int ret = BLUETOOTH_ERROR_NONE;
2427
2428         BT_CHECK_PARAMETER(device_address, return);
2429         BT_CHECK_PARAMETER(dev_info, return);
2430
2431         adapter_proxy = _bt_get_adapter_proxy();
2432         retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2433
2434         _bt_convert_addr_type_to_string(address, device_address->addr);
2435
2436         object_path = _bt_get_device_object_path(address);
2437
2438         retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2439
2440         ret = __bt_get_bonded_device_info(object_path, dev_info);
2441         g_free(object_path);
2442
2443         return ret;
2444 }
2445
2446 int _bt_get_timeout_value(int *timeout)
2447 {
2448         time_t current_time;
2449         int time_diff;
2450
2451         /* Take current time */
2452         time(&current_time);
2453         time_diff = difftime(current_time, visible_timer.start_time);
2454
2455         BT_DBG("Time diff = %d\n", time_diff);
2456
2457         *timeout = visible_timer.timeout - time_diff;
2458
2459         return BLUETOOTH_ERROR_NONE;
2460 }
2461
2462 int _bt_set_le_privacy(gboolean set_privacy)
2463 {
2464         GDBusProxy *proxy;
2465         GError *error = NULL;
2466         GVariant *result = NULL;
2467
2468         if (__bt_is_factory_test_mode()) {
2469                 BT_ERR("Unable to set le privacy in factory binary !!");
2470                 return BLUETOOTH_ERROR_NOT_SUPPORT;
2471         }
2472
2473         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2474                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2475                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2476         }
2477
2478         proxy = _bt_get_adapter_proxy();
2479         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2480
2481         result = g_dbus_proxy_call_sync(proxy,
2482                                 "SetLePrivacy",
2483                                 g_variant_new("(b)", set_privacy),
2484                                 G_DBUS_CALL_FLAGS_NONE,
2485                                 -1,
2486                                 NULL,
2487                                 &error);
2488
2489         if (!result) {
2490                 if (error != NULL) {
2491                         BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2492                         g_clear_error(&error);
2493                 } else
2494                         BT_ERR("Failed to SetLePrivacy");
2495                 return BLUETOOTH_ERROR_INTERNAL;
2496         }
2497
2498         g_variant_unref(result);
2499         BT_INFO("SetLePrivacy as %d", set_privacy);
2500         return BLUETOOTH_ERROR_NONE;
2501 }
2502
2503 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2504 {
2505         GDBusProxy *proxy;
2506         GError *error = NULL;
2507         int i;
2508         GVariant *val;
2509         GVariant *result;
2510         GVariantBuilder *builder;
2511
2512         BT_CHECK_PARAMETER(m_data, return);
2513
2514         if (_bt_adapter_get_status() != BT_ACTIVATED &&
2515                 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2516                 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2517         }
2518
2519         proxy = _bt_get_adapter_proxy();
2520         retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2521
2522         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2523
2524         for (i = 0; i < (m_data->data_len) + 2; i++) {
2525                 g_variant_builder_add(builder, "y", m_data->data[i]);
2526         }
2527
2528         val = g_variant_new("(ay)", builder);
2529
2530         result = g_dbus_proxy_call_sync(proxy,
2531                                 "SetManufacturerData",
2532                                 val,
2533                                 G_DBUS_CALL_FLAGS_NONE,
2534                                 -1,
2535                                 NULL,
2536                                 &error);
2537         g_variant_builder_unref(builder);
2538         if (!result) {
2539                 if (error != NULL) {
2540                         BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2541                         g_clear_error(&error);
2542                 } else {
2543                         BT_ERR("Failed to SetManufacturerData");
2544                 }
2545                 return BLUETOOTH_ERROR_INTERNAL;
2546         }
2547         builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2548
2549         for (i = 0; i < (m_data->data_len) + 2; i++) {
2550                 g_variant_builder_add(builder, "y", m_data->data[i]);
2551         }
2552
2553         val = g_variant_new("(ay)", builder);
2554
2555         _bt_send_event(BT_ADAPTER_EVENT,
2556                         BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2557                         val);
2558
2559         BT_INFO("Set manufacturer data");
2560
2561         g_variant_builder_unref(builder);
2562         g_variant_unref(result);
2563
2564         return BLUETOOTH_ERROR_NONE;
2565 }
2566
2567 #ifdef TIZEN_TV
2568 int _bt_get_enable_timer_id(void)
2569 {
2570         return timer_id;
2571 }
2572 #endif