4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
30 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
31 #include <syspopup_caller.h>
34 #include <dbus/dbus-glib.h>
35 #include <dbus/dbus.h>
39 #include <eventsystem.h>
41 #include <bundle_internal.h>
44 #include "bluetooth-api.h"
45 #include "bt-internal-types.h"
46 #include "bt-service-common.h"
47 #include "bt-service-event.h"
48 #include "bt-service-adapter.h"
49 #include "bt-service-util.h"
50 #include "bt-service-network.h"
51 #include "bt-service-obex-server.h"
52 #include "bt-service-agent.h"
53 #include "bt-service-main.h"
54 #include "bt-service-avrcp.h"
55 #include "bt-service-device.h"
65 bt_adapter_timer_t visible_timer = {0, };
67 static gboolean is_discovering;
68 static gboolean cancel_by_user;
69 static bt_status_t adapter_status = BT_DEACTIVATED;
70 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
71 static void *adapter_agent = NULL;
72 static GDBusProxy *core_proxy = NULL;
73 static guint timer_id = 0;
74 static guint le_timer_id = 0;
76 static int status_reg_id;
78 #define BT_CORE_NAME "org.projectx.bt_core"
79 #define BT_CORE_PATH "/org/projectx/bt_core"
80 #define BT_CORE_INTERFACE "org.projectx.btcore"
82 #define BT_DISABLE_TIME 500 /* 500 ms */
84 GDBusProxy *_bt_init_core_proxy(void)
87 GDBusConnection *conn;
89 conn = _bt_get_system_gconn();
93 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
108 static GDBusProxy *__bt_get_core_proxy(void)
110 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
113 static gboolean __bt_is_factory_test_mode(void)
117 #ifdef ENABLE_TIZEN_2_4
118 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
119 BT_ERR("Get the DUT Mode fail");
125 BT_INFO("DUT Test Mode !!");
132 static gboolean __bt_timeout_handler(gpointer user_data)
134 int result = BLUETOOTH_ERROR_NONE;
138 /* Take current time */
140 time_diff = difftime(current_time, visible_timer.start_time);
142 /* Send event to application */
143 _bt_send_event(BT_ADAPTER_EVENT,
144 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
145 g_variant_new("(in)", result, time_diff));
147 if (visible_timer.timeout <= time_diff) {
148 g_source_remove(visible_timer.event_id);
149 visible_timer.event_id = 0;
150 visible_timer.timeout = 0;
152 #ifndef TIZEN_WEARABLE
153 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
154 BT_ERR("Set vconf failed\n");
162 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
164 BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
166 int result = BLUETOOTH_ERROR_NONE;
169 if (alarm_id != visible_timer.alarm_id)
172 if (visible_timer.event_id) {
173 _bt_send_event(BT_ADAPTER_EVENT,
174 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
175 g_variant_new("(in)", result, timeout));
176 g_source_remove(visible_timer.event_id);
177 visible_timer.event_id = 0;
178 visible_timer.timeout = 0;
180 #ifndef TIZEN_WEARABLE
181 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
182 BT_ERR("Set vconf failed\n");
185 /* Switch Off visibility in Bluez */
186 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
187 visible_timer.alarm_id = 0;
191 static void __bt_visibility_alarm_create()
196 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
199 BT_ERR("Failed to create alarm error = %d\n", result);
201 BT_DBG("Alarm created = %d\n", alarm_id);
202 visible_timer.alarm_id = alarm_id;
206 static void __bt_visibility_alarm_remove()
208 if (visible_timer.event_id > 0) {
209 g_source_remove(visible_timer.event_id);
210 visible_timer.event_id = 0;
213 if (visible_timer.alarm_id > 0) {
214 alarmmgr_remove_alarm(visible_timer.alarm_id);
215 visible_timer.alarm_id = 0;
219 int __bt_set_visible_time(int timeout)
223 __bt_visibility_alarm_remove();
225 visible_timer.timeout = timeout;
228 return BLUETOOTH_ERROR_NONE;
230 #ifndef TIZEN_WEARABLE
231 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
232 BT_ERR("Set vconf failed");
235 if (!visible_timer.alarm_init) {
236 /* Set Alarm timer to switch off BT */
237 result = alarmmgr_init("bt-service");
239 return BLUETOOTH_ERROR_INTERNAL;
241 visible_timer.alarm_init = TRUE;
244 result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
246 return BLUETOOTH_ERROR_INTERNAL;
248 /* Take start time */
249 time(&(visible_timer.start_time));
250 visible_timer.event_id = g_timeout_add_seconds(1,
251 __bt_timeout_handler, NULL);
253 __bt_visibility_alarm_create();
255 return BLUETOOTH_ERROR_NONE;
258 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
265 ret_if(value == NULL);
268 dev->service_index = 0;
270 g_variant_get(value, "as", &iter);
271 while (g_variant_iter_loop(iter, "s", &uuid)) {
272 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
273 parts = g_strsplit(uuid, "-", -1);
275 if (parts == NULL || parts[0] == NULL) {
280 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
283 dev->service_index++;
286 g_variant_iter_free(iter);
289 static int __bt_get_bonded_device_info(gchar *device_path,
290 bluetooth_device_info_t *dev_info)
292 GError *error = NULL;
293 GDBusProxy *device_proxy;
294 const gchar *address = NULL;
295 const gchar *name = NULL;
296 unsigned int cod = 0;
298 gboolean trust = FALSE;
299 gboolean paired = FALSE;
300 guchar connected = 0;
301 GByteArray *manufacturer_data = NULL;
303 GDBusConnection *conn;
305 GVariantIter *property_iter;
309 GVariantIter *char_value_iter;
311 BT_CHECK_PARAMETER(device_path, return);
312 BT_CHECK_PARAMETER(dev_info, return);
314 conn = _bt_get_system_gconn();
315 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
317 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
321 BT_PROPERTIES_INTERFACE,
324 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
326 result = g_dbus_proxy_call_sync(device_proxy,
328 g_variant_new("(s)", BT_DEVICE_INTERFACE),
329 G_DBUS_CALL_FLAGS_NONE,
335 BT_ERR("Error occured in Proxy call");
337 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
338 g_clear_error(&error);
340 g_object_unref(device_proxy);
341 return BLUETOOTH_ERROR_INTERNAL;
344 g_object_unref(device_proxy);
346 g_variant_get(result, "(a{sv})", &property_iter);
348 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
349 if (!g_strcmp0(key,"Paired")) {
350 paired = g_variant_get_boolean(value);
351 } else if(!g_strcmp0(key, "Address")) {
352 address = g_variant_get_string(value, NULL);
353 } else if (!g_strcmp0(key, "Alias")) {
354 name = g_variant_get_string(value, NULL);
355 } else if (!g_strcmp0(key, "Name")) {
357 name = g_variant_get_string(value, NULL);
358 } else if (!g_strcmp0(key, "Class")) {
359 cod = g_variant_get_uint32(value);
360 } else if (!g_strcmp0(key, "Connected")) {
361 connected = g_variant_get_byte(value);
362 } else if (!g_strcmp0(key, "Trusted")) {
363 trust = g_variant_get_boolean(value);
364 } else if (!g_strcmp0(key, "RSSI")) {
365 rssi = g_variant_get_int16(value);
366 } else if (!g_strcmp0(key, "UUIDs")) {
367 __bt_get_service_list(value, dev_info);
368 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
369 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
370 } else if (!g_strcmp0(key, "ManufacturerData")) {
371 manufacturer_data = g_byte_array_new();
372 g_variant_get(value, "ay", &char_value_iter);
373 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
374 g_byte_array_append(manufacturer_data, &char_value, 1);
376 if (manufacturer_data) {
377 if (manufacturer_data->len > 0) {
378 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
379 manufacturer_data->len);
385 BT_DBG("trust: %d, paired: %d", trust, paired);
387 g_variant_unref(result);
389 if ((paired == FALSE) && (trust == FALSE)) {
390 return BLUETOOTH_ERROR_NOT_PAIRED;
393 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
396 _bt_divide_device_class(&dev_info->device_class, cod);
398 g_strlcpy(dev_info->device_name.name, name,
399 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
401 dev_info->rssi = rssi;
402 dev_info->trust = trust;
403 dev_info->paired = paired;
404 dev_info->connected = connected;
405 ret = BLUETOOTH_ERROR_NONE;
410 void _bt_set_discovery_status(gboolean mode)
412 is_discovering = mode;
415 void _bt_set_cancel_by_user(gboolean value)
417 cancel_by_user = value;
420 gboolean _bt_get_cancel_by_user(void)
422 return cancel_by_user;
425 void _bt_adapter_set_status(bt_status_t status)
427 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
428 adapter_status = status;
431 bt_status_t _bt_adapter_get_status(void)
433 return adapter_status;
436 void _bt_adapter_set_le_status(bt_le_status_t status)
438 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
439 adapter_le_status = status;
442 bt_le_status_t _bt_adapter_get_le_status(void)
444 return adapter_le_status;
447 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
449 char *phone_name = NULL;
455 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
456 phone_name = vconf_keynode_get_str(node);
458 if (phone_name && strlen(phone_name) != 0) {
459 if (!g_utf8_validate(phone_name, -1,
460 (const char **)&ptr))
463 _bt_set_local_name(phone_name);
469 static void __bt_set_visible_mode(void)
473 if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
474 BT_ERR("Fail to get the timeout value");
477 if (_bt_set_discoverable_mode(
478 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
479 timeout) != BLUETOOTH_ERROR_NONE) {
480 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
481 BT_ERR("Set vconf failed");
487 static void __bt_set_local_name(void)
489 char *phone_name = NULL;
492 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
497 if (strlen(phone_name) != 0) {
498 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
501 _bt_set_local_name(phone_name);
506 static int __bt_set_enabled(void)
509 int adapter_status = BT_ADAPTER_DISABLED;
510 int result = BLUETOOTH_ERROR_NONE;
512 _bt_check_adapter(&adapter_status);
514 if (adapter_status == BT_ADAPTER_DISABLED) {
515 BT_ERR("Bluetoothd is not running");
516 return BLUETOOTH_ERROR_INTERNAL;
520 __bt_set_visible_mode();
523 if (_bt_set_discoverable_mode(
524 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0)!= BLUETOOTH_ERROR_NONE)
525 BT_ERR("Fail to set discoverable mode");
528 __bt_set_local_name();
530 /* Update Bluetooth Status to notify other modules */
531 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
532 BT_ERR("Set vconf failed\n");
534 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
535 BT_ERR("Set vconf failed\n");
537 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
538 EVT_VAL_BT_ON) != ES_R_OK)
539 BT_ERR("Fail to set value");
542 /* Send enabled event to API */
543 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
544 g_variant_new("(i)", result));
547 return BLUETOOTH_ERROR_NONE;
550 void _bt_set_disabled(int result)
552 int power_off_status = 0;
555 int pm_ignore_mode = 0;
557 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
558 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
560 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
562 /* Update the vconf BT status in normal Deactivation case only */
565 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
566 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
568 BT_DBG("Update vconf for BT normal Deactivation");
570 if (result == BLUETOOTH_ERROR_TIMEOUT)
571 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 )
572 BT_ERR("Set vconf failed");
574 /* Update Bluetooth Status to notify other modules */
575 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
576 BT_ERR("Set vconf failed");
578 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
579 EVT_VAL_BT_OFF) != ES_R_OK)
580 BT_ERR("Fail to set value");
584 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
585 BT_ERR("Set vconf failed\n");
587 _bt_adapter_set_status(BT_DEACTIVATED);
589 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
590 /* Send disabled event */
591 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
592 g_variant_new("(i)", result));
595 BT_INFO("Adapter disabled");
598 static int __bt_set_le_enabled(void)
601 int result = BLUETOOTH_ERROR_NONE;
604 __bt_set_local_name();
606 /* Update Bluetooth Status to notify other modules */
607 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
608 BT_ERR("Set vconf failed\n");
611 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
612 EVT_VAL_BT_LE_ON) != ES_R_OK)
613 BT_ERR("Fail to set value");
616 /* Send enabled event to API */
618 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
619 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
621 status = _bt_adapter_get_status();
622 if (status == BT_DEACTIVATED) {
623 BT_INFO("BREDR is off, turn off PSCAN");
624 _bt_set_connectable(FALSE);
626 if (le_timer_id > 0) {
627 g_source_remove(le_timer_id);
631 /* Send enabled event to API */
632 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
633 g_variant_new("(i)", result));
636 return BLUETOOTH_ERROR_NONE;
639 void _bt_set_le_disabled(int result)
641 int power_off_status;
644 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
645 BT_DBG("ret : %d", ret);
646 BT_DBG("power_off_status : %d", power_off_status);
648 /* Update Bluetooth Status to notify other modules */
649 BT_DBG("Update vconf for BT LE normal Deactivation");
651 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
652 BT_ERR("Set vconf failed\n");
653 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
655 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
656 EVT_VAL_BT_LE_OFF) != ES_R_OK)
657 BT_ERR("Fail to set value");
660 if (_bt_adapter_get_status() != BT_DEACTIVATED) {
661 /* Send disabled event */
662 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
663 g_variant_new_int32(result));
667 void *_bt_get_adapter_agent(void)
669 return adapter_agent;
672 int _bt_enable_core(void)
676 GError *error = NULL;
678 proxy = __bt_get_core_proxy();
679 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
681 /* Clean up the process */
682 result = g_dbus_proxy_call_sync(proxy,
685 G_DBUS_CALL_FLAGS_NONE,
692 BT_ERR("Bt core call failed(Error: %s)", error->message);
693 g_clear_error(&error);
695 BT_ERR("Bt core call failed");
696 return BLUETOOTH_ERROR_INTERNAL;
699 g_variant_unref(result);
700 return BLUETOOTH_ERROR_NONE;
703 #if defined(TIZEN_BT_FLIGHTMODE_ENABLED) || !defined(TIZEN_WEARABLE)
704 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
706 gboolean flight_mode = FALSE;
707 int power_saving_mode = 0;
710 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
711 type = vconf_keynode_get_type(node);
712 if (type == VCONF_TYPE_BOOL) {
713 flight_mode = vconf_keynode_get_bool(node);
714 if (flight_mode != TRUE) {
715 BT_ERR("Ignore the event");
718 } else if (type == VCONF_TYPE_INT) {
719 power_saving_mode = vconf_keynode_get_int(node);
720 if (power_saving_mode != 2) {
721 BT_ERR("Ignore the event");
725 BT_ERR("Invaild vconf key type : %d", type);
733 void _bt_service_register_vconf_handler(void)
737 #ifdef TIZEN_TELEPHONY_ENABLED
738 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
739 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
740 BT_ERR("Unable to register key handler");
742 BT_DBG("Telephony is disabled");
745 #ifndef TIZEN_WEARABLE
746 #ifdef ENABLE_TIZEN_2_4
747 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
748 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
749 BT_ERR("Unable to register key handler");
754 void _bt_service_unregister_vconf_handler(void)
758 #ifdef TIZEN_TELEPHONY_ENABLED
759 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
760 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
763 #ifndef TIZEN_WEARABLE
764 #ifdef ENABLE_TIZEN_2_4
765 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
766 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
771 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
773 const char *bt_status = NULL;
774 const char *bt_le_status = NULL;
775 const char *bt_transfering_status = NULL;
776 BT_DBG("bt state set event(%s) received", event_name);
777 #ifdef ENABLE_TIZEN_2_4
778 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
779 BT_DBG("bt_state: (%s)", bt_status);
781 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
782 BT_DBG("bt_state: (%s)", bt_le_status);
786 void _bt_handle_adapter_added(void)
790 bt_le_status_t le_status;
794 BT_DBG("g_source is removed");
795 g_source_remove(timer_id);
799 status = _bt_adapter_get_status();
800 le_status = _bt_adapter_get_le_status();
801 BT_DBG("status : %d", status);
802 BT_DBG("le_status : %d", le_status);
804 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
805 if (!adapter_agent) {
806 BT_ERR("Fail to register agent");
810 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
811 BT_ERR("Fail to register media player");
813 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
814 BT_ERR("Fail to init obex server");
816 #ifdef TIZEN_BT_PAN_NAP_ENABLE
817 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
818 BT_ERR("Fail to activate network");
821 /* add the vconf noti handler */
822 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
823 __bt_phone_name_changed_cb, NULL);
825 BT_ERR("Unable to register key handler");
827 if (le_status == BT_LE_ACTIVATING) {
828 __bt_set_le_enabled();
829 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
831 if (status == BT_ACTIVATING) {
833 _bt_adapter_set_status(BT_ACTIVATED);
835 #ifdef ENABLE_TIZEN_2_4
839 _bt_service_register_vconf_handler();
842 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
843 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
844 BT_ERR("Fail to register system event");
849 void _bt_handle_adapter_removed(void)
853 _bt_adapter_set_status(BT_DEACTIVATED);
854 #ifdef ENABLE_TIZEN_2_4
858 __bt_visibility_alarm_remove();
860 if (visible_timer.alarm_init) {
862 visible_timer.alarm_init = FALSE;
865 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
866 (vconf_callback_fn)__bt_phone_name_changed_cb);
868 ERR("vconf_ignore_key_changed failed\n");
871 _bt_destroy_agent(adapter_agent);
872 adapter_agent = NULL;
874 _bt_reliable_terminate_service(NULL);
876 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK) {
877 BT_ERR("Fail to unregister system event");
883 static gboolean __bt_enable_timeout_cb(gpointer user_data)
887 GError *error = NULL;
891 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
893 BT_ERR("EnableAdapter is failed");
895 proxy = __bt_get_core_proxy();
899 /* Clean up the process */
900 result = g_dbus_proxy_call_sync(proxy,
903 G_DBUS_CALL_FLAGS_NONE,
910 BT_ERR("Bt core call failed(Error: %s)", error->message);
911 g_clear_error(&error);
913 BT_ERR("Bt core call failed");
918 g_variant_unref(result);
920 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
922 _bt_terminate_service(NULL);
927 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
931 GError *error = NULL;
935 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
937 BT_ERR("EnableAdapterLE is failed");
939 proxy = __bt_get_core_proxy();
943 /* Clean up the process */
944 result = g_dbus_proxy_call_sync(proxy,
947 G_DBUS_CALL_FLAGS_NONE,
954 BT_ERR("Bt core call failed(Error: %s)", error->message);
955 g_clear_error(&error);
957 BT_ERR("Bt core call failed");
961 g_variant_unref(result);
963 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
965 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
967 if (_bt_adapter_get_status() == BT_DEACTIVATED)
968 _bt_terminate_service(NULL);
973 void _bt_adapter_start_le_enable_timer(void)
975 if (le_timer_id > 0) {
976 g_source_remove(le_timer_id);
980 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
981 __bt_enable_le_timeout_cb, NULL);
986 void _bt_adapter_start_enable_timer(void)
989 g_source_remove(timer_id);
993 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
994 __bt_enable_timeout_cb, NULL);
999 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1004 _bt_adapter_set_status(BT_ACTIVATED);
1010 int _bt_enable_adapter(void)
1013 GError *error = NULL;
1015 GVariant *result = NULL;
1016 bt_status_t status = _bt_adapter_get_status();
1017 bt_le_status_t le_status = _bt_adapter_get_le_status();
1021 if (status == BT_ACTIVATING) {
1022 BT_ERR("Enabling in progress");
1023 return BLUETOOTH_ERROR_IN_PROGRESS;
1026 if (status == BT_ACTIVATED) {
1027 BT_ERR("Already enabled");
1028 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1031 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1032 BT_ERR("Disabling in progress");
1033 return BLUETOOTH_ERROR_DEVICE_BUSY;
1036 _bt_adapter_set_status(BT_ACTIVATING);
1040 int adapter_status = BT_ADAPTER_DISABLED;
1042 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1043 BT_ERR("Set vconf failed");
1045 _bt_check_adapter(&adapter_status);
1046 if (adapter_status == BT_ADAPTER_ENABLED) {
1047 g_idle_add(__bt_adapter_enabled_cb, NULL);
1048 _bt_adapter_start_enable_timer();
1049 return BLUETOOTH_ERROR_NONE;
1054 proxy = __bt_get_core_proxy();
1056 return BLUETOOTH_ERROR_INTERNAL;
1058 if (le_status == BT_LE_ACTIVATED) {
1059 BT_INFO("LE Already enabled. Just turn on PSCAN");
1060 ret = _bt_set_connectable(TRUE);
1061 if (ret == BLUETOOTH_ERROR_NONE) {
1062 _bt_adapter_set_status(BT_ACTIVATED);
1064 return BLUETOOTH_ERROR_INTERNAL;
1068 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1070 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1073 BT_ERR("EnableAdapterLe failed: %s", error->message);
1074 _bt_adapter_set_status(BT_DEACTIVATED);
1075 g_clear_error(&error);
1077 result = g_dbus_proxy_call_sync(proxy,
1080 G_DBUS_CALL_FLAGS_NONE,
1085 if (error != NULL) {
1086 BT_ERR("Bt core call failed(Error: %s)", error->message);
1087 g_clear_error(&error);
1089 g_variant_unref(result);
1090 /* Terminate myself */
1091 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1092 return BLUETOOTH_ERROR_INTERNAL;
1094 g_variant_unref(result);
1096 if (le_status == BT_LE_ACTIVATED) {
1099 _bt_adapter_start_enable_timer();
1102 return BLUETOOTH_ERROR_NONE;
1105 static gboolean __bt_disconnect_all(void)
1108 GDBusConnection *conn;
1109 GDBusProxy *dev_proxy;
1110 gboolean ret = FALSE;
1112 GError *error = NULL;
1113 GArray *device_list;
1114 bluetooth_device_info_t info;
1116 char *device_path = NULL;
1117 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1122 conn = _bt_get_system_gconn();
1124 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1126 if (_bt_get_bonded_devices(&device_list)
1127 != BLUETOOTH_ERROR_NONE) {
1128 g_array_free(device_list, TRUE);
1132 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1134 for (i = 0; i < size; i++) {
1136 info = g_array_index(device_list,
1137 bluetooth_device_info_t, i);
1139 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1140 BT_DBG("Found Connected device");
1141 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1142 device_path = _bt_get_device_object_path(address);
1143 if (device_path == NULL)
1146 BT_DBG("Disconnecting : %s", device_path);
1148 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1152 BT_DEVICE_INTERFACE,
1155 if (dev_proxy == NULL)
1158 result = g_dbus_proxy_call_sync(dev_proxy,
1161 G_DBUS_CALL_FLAGS_NONE,
1167 if (error != NULL) {
1168 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1169 g_clear_error(&error);
1171 BT_ERR("Disconnect call failed");
1172 g_object_unref(dev_proxy);
1176 g_variant_unref(result);
1177 g_object_unref(dev_proxy);
1181 g_array_free(device_list, TRUE);
1186 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1189 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1194 int __bt_disable_cb(void)
1198 bt_le_status_t le_status;
1201 GError *error = NULL;
1203 _bt_adapter_set_status(BT_DEACTIVATING);
1204 le_status = _bt_adapter_get_le_status();
1205 BT_DBG("le_status : %d", le_status);
1206 if (le_status == BT_LE_ACTIVATED) {
1207 BT_INFO("LE is enabled. Just turn off PSCAN");
1209 if (_bt_is_discovering())
1210 _bt_cancel_discovery();
1212 if (_bt_is_connectable() == FALSE) {
1213 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1215 ret = _bt_set_connectable(FALSE);
1216 if (ret != BLUETOOTH_ERROR_NONE) {
1217 BT_ERR("_bt_set_connectable fail!");
1218 _bt_adapter_set_status(BT_ACTIVATED);
1219 return BLUETOOTH_ERROR_INTERNAL;
1224 proxy = __bt_get_core_proxy();
1225 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1227 result = g_dbus_proxy_call_sync(proxy,
1230 G_DBUS_CALL_FLAGS_NONE,
1236 if (error != NULL) {
1237 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1238 g_clear_error(&error);
1240 BT_ERR("Failed to DisableAdapter");
1241 _bt_adapter_set_status(BT_ACTIVATED);
1242 return BLUETOOTH_ERROR_INTERNAL;
1245 g_variant_unref(result);
1247 return BLUETOOTH_ERROR_NONE;
1250 int _bt_disable_adapter(void)
1255 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1256 BT_DBG("Disabling in progress");
1257 return BLUETOOTH_ERROR_IN_PROGRESS;
1260 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1261 BT_DBG("Already disabled");
1262 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1266 g_source_remove(timer_id);
1270 __bt_disconnect_all();
1271 ret = __bt_disable_cb();
1277 int _bt_recover_adapter(void)
1282 GError *error = NULL;
1284 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1285 BT_DBG("Disabling in progress");
1286 return BLUETOOTH_ERROR_IN_PROGRESS;
1289 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1290 BT_DBG("Already disabled");
1291 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1294 _bt_adapter_set_status(BT_DEACTIVATING);
1296 proxy = __bt_get_core_proxy();
1297 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1299 result = g_dbus_proxy_call_sync(proxy,
1302 G_DBUS_CALL_FLAGS_NONE,
1308 if (error != NULL) {
1309 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1310 g_clear_error(&error);
1312 BT_ERR("Failed to RecoverAdapter");
1313 return BLUETOOTH_ERROR_INTERNAL;
1316 g_variant_unref(result);
1317 __bt_disconnect_all();
1320 return BLUETOOTH_ERROR_NONE;
1323 int _bt_reset_adapter(void)
1327 GError *error = NULL;
1331 proxy = __bt_get_core_proxy();
1333 return BLUETOOTH_ERROR_INTERNAL;
1335 result = g_dbus_proxy_call_sync(proxy,
1338 G_DBUS_CALL_FLAGS_NONE,
1344 if (error != NULL) {
1345 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1346 g_clear_error(&error);
1348 BT_ERR("Failed to ResetAdapter");
1349 return BLUETOOTH_ERROR_INTERNAL;
1352 g_variant_unref(result);
1353 /* Terminate myself */
1354 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1355 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1358 return BLUETOOTH_ERROR_NONE;
1362 int _bt_check_adapter(int *status)
1365 char *adapter_path = NULL;
1367 BT_CHECK_PARAMETER(status, return);
1369 *status = BT_ADAPTER_DISABLED;
1371 adapter_path = _bt_get_adapter_path();
1374 if (adapter_path != NULL)
1375 *status = BT_ADAPTER_ENABLED;
1377 g_free(adapter_path);
1378 return BLUETOOTH_ERROR_NONE;
1381 int _bt_check_adapter(int *status)
1384 GError *error = NULL;
1387 gboolean powered = FALSE;
1389 BT_CHECK_PARAMETER(status, return);
1391 *status = BT_ADAPTER_DISABLED;
1393 proxy = _bt_get_adapter_properties_proxy();
1394 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1396 result = g_dbus_proxy_call_sync(proxy,
1398 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1400 G_DBUS_CALL_FLAGS_NONE,
1406 BT_ERR("Failed to get local address");
1407 if (error != NULL) {
1408 BT_ERR("Failed to get local address (Error: %s)", error->message);
1409 g_clear_error(&error);
1411 return BLUETOOTH_ERROR_INTERNAL;
1414 g_variant_get(result, "(v)", &temp);
1415 powered = g_variant_get_boolean(temp);
1416 BT_DBG("powered: %d", powered);
1419 *status = BT_ADAPTER_ENABLED;
1421 g_variant_unref(result);
1422 g_variant_unref(temp);
1423 return BLUETOOTH_ERROR_NONE;
1427 int _bt_enable_adapter_le(void)
1431 GError *error = NULL;
1432 bt_status_t status = _bt_adapter_get_status();
1433 bt_le_status_t le_status = _bt_adapter_get_le_status();
1436 if (le_status == BT_LE_ACTIVATING) {
1437 BT_ERR("Enabling in progress");
1438 return BLUETOOTH_ERROR_IN_PROGRESS;
1441 if (le_status == BT_LE_ACTIVATED) {
1442 BT_ERR("Already enabled");
1443 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1446 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1447 BT_ERR("Disabling in progress");
1448 return BLUETOOTH_ERROR_DEVICE_BUSY;
1451 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1453 proxy = __bt_get_core_proxy();
1454 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1456 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1458 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1461 BT_ERR("EnableAdapterLe failed: %s", error->message);
1462 _bt_adapter_set_le_status(BT_DEACTIVATED);
1463 g_clear_error(&error);
1465 /* Clean up the process */
1466 result = g_dbus_proxy_call_sync(proxy,
1469 G_DBUS_CALL_FLAGS_NONE,
1475 BT_ERR("Bt core call failed");
1477 BT_ERR("EnableAdapterLE Failed %s", error->message);
1478 g_clear_error(&error);
1481 g_variant_unref(result);
1482 /* Terminate myself */
1483 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1484 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1485 return BLUETOOTH_ERROR_INTERNAL;
1489 g_variant_unref(result);
1491 _bt_adapter_start_le_enable_timer();
1493 if (status == BT_ACTIVATED) {
1494 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1495 __bt_set_le_enabled();
1497 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1499 return BLUETOOTH_ERROR_NONE;
1502 int _bt_disable_adapter_le(void)
1506 bt_le_status_t bt_le_state;
1508 GError *error = NULL;
1510 bt_le_state = _bt_adapter_get_le_status();
1511 if (bt_le_state == BT_LE_DEACTIVATING) {
1512 BT_DBG("Disabling in progress");
1513 return BLUETOOTH_ERROR_IN_PROGRESS;
1516 if (bt_le_state == BT_LE_DEACTIVATED) {
1517 BT_DBG("Already disabled");
1518 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1521 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1523 proxy = __bt_get_core_proxy();
1525 return BLUETOOTH_ERROR_INTERNAL;
1527 result = g_dbus_proxy_call_sync(proxy,
1530 G_DBUS_CALL_FLAGS_NONE,
1536 if (error != NULL) {
1537 BT_ERR("Bt core call failed (Error: %s)", error->message);
1538 g_clear_error(&error);
1540 BT_ERR("Bt core call failed");
1541 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1542 return BLUETOOTH_ERROR_INTERNAL;
1545 g_variant_unref(result);
1547 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1548 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1550 return BLUETOOTH_ERROR_NONE;
1553 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1557 GError *error = NULL;
1558 const char *address;
1562 BT_CHECK_PARAMETER(local_address, return);
1564 proxy = _bt_get_adapter_properties_proxy();
1565 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1567 result = g_dbus_proxy_call_sync(proxy,
1569 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1571 G_DBUS_CALL_FLAGS_NONE,
1577 BT_ERR("Failed to get local address");
1578 if (error != NULL) {
1579 BT_ERR("Failed to get local address (Error: %s)", error->message);
1580 g_clear_error(&error);
1582 return BLUETOOTH_ERROR_INTERNAL;
1585 g_variant_get(result, "(v)", &temp);
1586 address = g_variant_get_string(temp, NULL);
1587 BT_DBG("Address:%s", address);
1590 _bt_convert_addr_string_to_type(local_address->addr, address);
1592 return BLUETOOTH_ERROR_INTERNAL;
1595 g_variant_unref(result);
1596 g_variant_unref(temp);
1597 return BLUETOOTH_ERROR_NONE;
1600 int _bt_get_local_version(bluetooth_version_t *local_version)
1603 const char *ver = NULL;
1605 int ret = BLUETOOTH_ERROR_NONE;
1609 BT_CHECK_PARAMETER(local_version, return);
1611 GError *error = NULL;
1613 proxy = _bt_get_adapter_properties_proxy();
1614 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1616 result = g_dbus_proxy_call_sync(proxy,
1618 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1620 G_DBUS_CALL_FLAGS_NONE,
1626 if (error != NULL) {
1627 BT_ERR("Failed to get local version (Error: %s)", error->message);
1628 g_clear_error(&error);
1630 BT_ERR("Failed to get local version");
1631 return BLUETOOTH_ERROR_INTERNAL;
1634 g_variant_get(result, "(v)", &temp);
1635 ver = g_variant_get_string(temp, NULL);
1636 BT_DBG("VERSION: %s", ver);
1638 if (ver && (strlen(ver) > 0)) {
1639 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1640 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1643 g_strlcpy(local_version->version, ver,
1644 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1647 ret = BLUETOOTH_ERROR_INTERNAL;
1650 g_variant_unref(result);
1651 g_variant_unref(temp);
1655 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1658 const char *name = NULL;
1660 int ret = BLUETOOTH_ERROR_NONE;
1663 GError *error = NULL;
1665 BT_CHECK_PARAMETER(local_name, return);
1667 proxy = _bt_get_adapter_properties_proxy();
1668 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1670 result = g_dbus_proxy_call_sync(proxy,
1672 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1674 G_DBUS_CALL_FLAGS_NONE,
1680 if (error != NULL) {
1681 BT_ERR("Failed to get local name (Error: %s)", error->message);
1682 g_clear_error(&error);
1684 BT_ERR("Failed to get local name");
1685 return BLUETOOTH_ERROR_INTERNAL;
1688 g_variant_get(result, "(v)", &temp);
1689 name = g_variant_get_string(temp, NULL);
1690 BT_DBG("LOCAL NAME:%s", name);
1692 if (name && (strlen(name) > 0)) {
1693 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1694 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1697 g_strlcpy(local_name->name, name,
1698 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1700 ret = BLUETOOTH_ERROR_INTERNAL;
1702 g_variant_unref(result);
1703 g_variant_unref(temp);
1707 int _bt_set_local_name(char *local_name)
1710 GError *error = NULL;
1714 BT_CHECK_PARAMETER(local_name, return);
1716 proxy = _bt_get_adapter_properties_proxy();
1718 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1720 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1723 result = g_dbus_proxy_call_sync(proxy,
1725 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1726 "Alias", g_variant_new("s", local_name)),
1727 G_DBUS_CALL_FLAGS_NONE,
1733 if (error != NULL) {
1734 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1735 g_clear_error(&error);
1737 BT_ERR("Failed to set Alias");
1738 return BLUETOOTH_ERROR_INTERNAL;
1741 g_variant_unref(result);
1742 return BLUETOOTH_ERROR_NONE;
1745 int _bt_is_service_used(char *service_uuid, gboolean *used)
1748 GError *error = NULL;
1749 int ret = BLUETOOTH_ERROR_NONE;
1755 BT_CHECK_PARAMETER(service_uuid, return);
1756 BT_CHECK_PARAMETER(used, return);
1758 proxy = _bt_get_adapter_properties_proxy();
1759 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1761 result = g_dbus_proxy_call_sync(proxy,
1763 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1765 G_DBUS_CALL_FLAGS_NONE,
1771 if (error != NULL) {
1772 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1773 g_clear_error(&error);
1775 BT_ERR("Failed to get UUIDs");
1776 return BLUETOOTH_ERROR_INTERNAL;
1779 g_variant_get(result, "as", &iter);
1780 while (g_variant_iter_loop(iter, "s", &uuid)) {
1781 if (strcasecmp(uuid, service_uuid) == 0) {
1791 g_variant_iter_free(iter);
1792 g_variant_unref(result);
1793 BT_DBG("Service Used? %d", *used);
1797 static gboolean __bt_get_discoverable_property(void)
1800 gboolean discoverable_v;
1801 GError *error = NULL;
1805 proxy = _bt_get_adapter_properties_proxy();
1806 retv_if(proxy == NULL, FALSE);
1808 result = g_dbus_proxy_call_sync(proxy,
1810 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1812 G_DBUS_CALL_FLAGS_NONE,
1818 if (error != NULL) {
1819 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1820 g_clear_error(&error);
1822 BT_ERR("Failed to get Discoverable property");
1826 g_variant_get(result, "(v)", &temp);
1827 discoverable_v = g_variant_get_boolean(temp);
1828 BT_DBG("discoverable_v:%d", discoverable_v);
1830 g_variant_unref(result);
1831 g_variant_unref(temp);
1833 return discoverable_v;
1836 int _bt_get_discoverable_mode(int *mode)
1838 gboolean discoverable;
1839 unsigned int timeout;
1841 BT_CHECK_PARAMETER(mode, return);
1843 discoverable = __bt_get_discoverable_property();
1844 timeout = _bt_get_discoverable_timeout_property();
1846 if (discoverable == TRUE) {
1848 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1850 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1852 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1854 return BLUETOOTH_ERROR_NONE;
1858 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1860 int ret = BLUETOOTH_ERROR_NONE;
1863 GError *error = NULL;
1867 proxy = _bt_get_adapter_properties_proxy();
1869 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1871 switch (discoverable_mode) {
1872 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1877 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1882 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1887 return BLUETOOTH_ERROR_INVALID_PARAM;
1890 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1891 discoverable_mode, timeout);
1893 result = g_dbus_proxy_call_sync(proxy,
1895 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1896 "Connectable", g_variant_new("b", pg_scan)),
1897 G_DBUS_CALL_FLAGS_NONE,
1903 if (error != NULL) {
1904 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1905 g_clear_error(&error);
1907 BT_ERR("Failed to set connectable property");
1908 return BLUETOOTH_ERROR_INTERNAL;
1910 g_variant_unref(result);
1911 result = g_dbus_proxy_call_sync(proxy,
1913 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
1914 g_variant_new("b", inq_scan)),
1915 G_DBUS_CALL_FLAGS_NONE,
1921 if (error != NULL) {
1922 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
1923 g_clear_error(&error);
1925 BT_ERR("Failed to set Discoverable property");
1926 return BLUETOOTH_ERROR_INTERNAL;
1928 g_variant_unref(result);
1929 result = g_dbus_proxy_call_sync(proxy,
1931 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1932 "DiscoverableTimeout", g_variant_new("u", timeout)),
1933 G_DBUS_CALL_FLAGS_NONE,
1939 if (error != NULL) {
1940 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
1941 g_clear_error(&error);
1943 BT_ERR("Failed to set DiscoverableTimeout property");
1944 return BLUETOOTH_ERROR_INTERNAL;
1947 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1950 ret = __bt_set_visible_time(timeout);
1952 g_variant_unref(result);
1957 int _bt_start_discovery(void)
1960 GError *error = NULL;
1963 if (_bt_is_discovering() == TRUE) {
1964 BT_ERR("BT is already in discovering");
1965 return BLUETOOTH_ERROR_IN_PROGRESS;
1966 } else if (_bt_is_device_creating() == TRUE) {
1967 BT_ERR("Bonding device is going on");
1968 return BLUETOOTH_ERROR_DEVICE_BUSY;
1971 proxy = _bt_get_adapter_proxy();
1972 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1974 result = g_dbus_proxy_call_sync(proxy,
1977 G_DBUS_CALL_FLAGS_NONE,
1983 if (error != NULL) {
1984 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
1985 g_clear_error(&error);
1987 BT_ERR("StartDiscovery failed");
1988 return BLUETOOTH_ERROR_INTERNAL;
1991 is_discovering = TRUE;
1992 cancel_by_user = FALSE;
1993 /* discovery status will be change in event */
1994 g_variant_unref(result);
1995 return BLUETOOTH_ERROR_NONE;
1998 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2002 GError *error = NULL;
2003 const gchar *disc_type;
2005 if (_bt_is_discovering() == TRUE) {
2006 BT_ERR("BT is already in discovering");
2007 return BLUETOOTH_ERROR_IN_PROGRESS;
2010 proxy = _bt_get_adapter_proxy();
2011 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2013 if (role == DISCOVERY_ROLE_BREDR)
2014 disc_type = "BREDR";
2015 else if (role == DISCOVERY_ROLE_LE)
2017 else if (role == DISCOVERY_ROLE_LE_BREDR)
2018 disc_type = "LE_BREDR";
2020 return BLUETOOTH_ERROR_INVALID_PARAM;
2022 result = g_dbus_proxy_call_sync(proxy,
2023 "StartCustomDiscovery",
2024 g_variant_new("s", disc_type),
2025 G_DBUS_CALL_FLAGS_NONE,
2031 if (error != NULL) {
2032 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2033 g_clear_error(&error);
2035 BT_ERR("StartCustomDiscovery failed");
2036 return BLUETOOTH_ERROR_INTERNAL;
2039 is_discovering = TRUE;
2040 cancel_by_user = FALSE;
2041 /* discovery status will be change in event */
2042 g_variant_unref(result);
2043 return BLUETOOTH_ERROR_NONE;
2046 int _bt_cancel_discovery(void)
2049 GError *error = NULL;
2052 if (_bt_is_discovering() == FALSE) {
2053 BT_ERR("BT is not in discovering");
2054 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2057 proxy = _bt_get_adapter_proxy();
2058 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2060 result = g_dbus_proxy_call_sync(proxy,
2063 G_DBUS_CALL_FLAGS_NONE,
2069 if (error != NULL) {
2070 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2071 g_clear_error(&error);
2073 BT_ERR("StopDiscovery failed");
2074 return BLUETOOTH_ERROR_INTERNAL;
2077 cancel_by_user = TRUE;
2078 /* discovery status will be change in event */
2079 g_variant_unref(result);
2080 return BLUETOOTH_ERROR_NONE;
2083 gboolean _bt_is_discovering(void)
2085 return is_discovering;
2088 gboolean _bt_is_connectable(void)
2091 GError *error = NULL;
2092 gboolean is_connectable = FALSE;
2096 proxy = _bt_get_adapter_properties_proxy();
2097 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2099 result = g_dbus_proxy_call_sync(proxy,
2101 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2103 G_DBUS_CALL_FLAGS_NONE,
2109 if (error != NULL) {
2110 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2111 g_clear_error(&error);
2113 BT_ERR("Failed to get connectable property");
2114 return BLUETOOTH_ERROR_INTERNAL;
2117 g_variant_get(result, "(v)", &temp);
2118 is_connectable = g_variant_get_boolean(temp);
2119 BT_DBG("discoverable_v:%d", is_connectable);
2121 g_variant_unref(result);
2122 g_variant_unref(temp);
2124 BT_INFO("Get connectable [%d]", is_connectable);
2125 return is_connectable;
2128 int _bt_set_connectable(gboolean is_connectable)
2131 GError *error = NULL;
2134 if (__bt_is_factory_test_mode()) {
2135 BT_ERR("Unable to set connectable in factory binary !!");
2136 return BLUETOOTH_ERROR_NOT_SUPPORT;
2139 proxy = _bt_get_adapter_properties_proxy();
2141 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2143 result = g_dbus_proxy_call_sync(proxy,
2145 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2146 g_variant_new("b", is_connectable)),
2147 G_DBUS_CALL_FLAGS_NONE,
2153 if (error != NULL) {
2154 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2155 g_clear_error(&error);
2157 BT_ERR("Failed to set connectable property");
2158 return BLUETOOTH_ERROR_INTERNAL;
2161 BT_INFO("Set connectable [%d]", is_connectable);
2162 g_variant_unref(result);
2163 return BLUETOOTH_ERROR_NONE;
2166 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2169 gboolean discovering_v;
2170 GError *error = NULL;
2171 char *discovering_type = NULL;
2175 proxy = _bt_get_adapter_properties_proxy();
2176 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2178 if (discovery_type == DISCOVERY_ROLE_BREDR)
2179 discovering_type = "Discovering";
2180 else if (discovery_type == DISCOVERY_ROLE_LE)
2181 discovering_type = "LEDiscovering";
2183 result = g_dbus_proxy_call_sync(proxy,
2185 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2187 G_DBUS_CALL_FLAGS_NONE,
2193 if (error != NULL) {
2194 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2195 g_clear_error(&error);
2197 BT_ERR("Failed to get discovering property");
2198 return BLUETOOTH_ERROR_INTERNAL;
2201 g_variant_get(result, "(v)", &temp);
2202 discovering_v = g_variant_get_boolean(temp);
2203 BT_DBG("discoverable_v:%d", discovering_v);
2205 g_variant_unref(result);
2206 g_variant_unref(temp);
2208 return discovering_v;
2211 unsigned int _bt_get_discoverable_timeout_property(void)
2214 unsigned int timeout_v;
2215 GError *error = NULL;
2219 proxy = _bt_get_adapter_properties_proxy();
2220 retv_if(proxy == NULL, 0);
2222 result = g_dbus_proxy_call_sync(proxy,
2224 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2225 "DiscoverableTimeout"),
2226 G_DBUS_CALL_FLAGS_NONE,
2232 BT_ERR("Fail to get discoverable timeout");
2233 if (error != NULL) {
2234 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2235 g_clear_error(&error);
2240 g_variant_get(result, "(v)", &temp);
2241 timeout_v = g_variant_get_uint32(temp);
2242 BT_DBG("discoverable_v:%d", timeout_v);
2244 g_variant_unref(result);
2245 g_variant_unref(temp);
2250 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2252 bluetooth_device_info_t *dev_info;
2255 GByteArray *manufacturer_data = NULL;
2257 GVariantIter *char_value_iter;
2259 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2261 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2266 if (!g_strcmp0(key, "Address")) {
2267 const char *address = NULL;
2268 address = g_variant_get_string(value, NULL);
2269 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2271 } else if(!g_strcmp0(key, "Class")) {
2273 cod = g_variant_get_uint32(value);
2274 _bt_divide_device_class(&dev_info->device_class, cod);
2275 } else if(!g_strcmp0(key, "Name")) {
2276 const char *name = NULL;
2277 name = g_variant_get_string(value, NULL);
2278 /* If there is no Alias */
2279 if (strlen(dev_info->device_name.name) == 0) {
2280 g_strlcpy(dev_info->device_name.name, name,
2281 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2283 } else if(!g_strcmp0(key, "Alias")) {
2284 const char *alias = NULL;
2285 alias = g_variant_get_string(value, NULL);
2286 /* Overwrite the name */
2288 memset(dev_info->device_name.name, 0x00,
2289 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2290 g_strlcpy(dev_info->device_name.name, alias,
2291 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2293 } else if (!g_strcmp0(key, "Connected")) {
2294 dev_info->connected = g_variant_get_byte(value);
2295 } else if (!g_strcmp0(key, "Paired")) {
2296 dev_info->paired = g_variant_get_boolean(value);
2297 } else if (!g_strcmp0(key, "Trusted")) {
2298 dev_info->trust = g_variant_get_boolean(value);
2299 } else if (!g_strcmp0(key, "RSSI")) {
2300 dev_info->rssi = g_variant_get_int16(value);
2301 } else if (!g_strcmp0(key, "UUIDs")) {
2307 dev_info->service_index = 0;
2308 g_variant_get(value, "as", &iter);
2309 while (g_variant_iter_loop(iter, "s", &uuid)) {
2310 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2311 parts = g_strsplit(uuid, "-", -1);
2313 if (parts == NULL || parts[0] == NULL) {
2318 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2323 dev_info->service_index = i;
2324 g_variant_iter_free(iter);
2325 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2326 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2327 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2328 manufacturer_data = g_byte_array_new();
2329 g_variant_get(value, "ay", &char_value_iter);
2330 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
2331 g_byte_array_append(manufacturer_data, &char_value, 1);
2333 if (manufacturer_data) {
2334 if (manufacturer_data->len > 0) {
2335 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2338 g_variant_iter_free(char_value_iter);
2339 g_byte_array_free(manufacturer_data, TRUE);
2346 static void __bt_extract_device_info(GVariantIter *iter,
2349 bluetooth_device_info_t *dev_info = NULL;
2350 char *object_path = NULL;
2351 GVariantIter *interface_iter;
2352 GVariantIter *svc_iter;
2353 char *interface_str = NULL;
2355 /* Parse the signature: oa{sa{sv}}} */
2356 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2359 if (object_path == NULL)
2362 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2363 &interface_str, &svc_iter)) {
2364 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2365 BT_DBG("Found a device: %s", object_path);
2366 dev_info = __bt_parse_device_info(svc_iter);
2368 if (dev_info->paired == TRUE) {
2369 g_array_append_vals(*dev_list, dev_info,
2370 sizeof(bluetooth_device_info_t));
2374 g_free(interface_str);
2375 g_variant_iter_free(svc_iter);
2383 int _bt_get_bonded_devices(GArray **dev_list)
2386 GDBusConnection *conn;
2387 GDBusProxy *manager_proxy;
2388 GVariant *result = NULL;
2389 GVariantIter *iter = NULL;
2390 GError *error = NULL;
2392 conn = _bt_get_system_conn();
2393 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2395 manager_proxy = _bt_get_manager_proxy();
2396 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2398 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2400 G_DBUS_CALL_FLAGS_NONE,
2406 if (error != NULL) {
2407 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2408 g_clear_error(&error);
2410 BT_ERR("Failed to Failed to GetManagedObjects");
2411 return BLUETOOTH_ERROR_INTERNAL;
2414 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2415 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2417 __bt_extract_device_info(iter, dev_list);
2418 g_variant_iter_free(iter);
2419 g_variant_unref(result);
2422 return BLUETOOTH_ERROR_NONE;
2425 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2426 bluetooth_device_info_t *dev_info)
2428 char *object_path = NULL;
2429 GDBusProxy *adapter_proxy;
2430 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2431 int ret = BLUETOOTH_ERROR_NONE;
2433 BT_CHECK_PARAMETER(device_address, return);
2434 BT_CHECK_PARAMETER(dev_info, return);
2436 adapter_proxy = _bt_get_adapter_proxy();
2437 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2439 _bt_convert_addr_type_to_string(address, device_address->addr);
2441 object_path = _bt_get_device_object_path(address);
2443 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2445 ret = __bt_get_bonded_device_info(object_path, dev_info);
2446 g_free(object_path);
2451 int _bt_get_timeout_value(int *timeout)
2453 time_t current_time;
2456 /* Take current time */
2457 time(¤t_time);
2458 time_diff = difftime(current_time, visible_timer.start_time);
2460 BT_DBG("Time diff = %d\n", time_diff);
2462 *timeout = visible_timer.timeout - time_diff;
2464 return BLUETOOTH_ERROR_NONE;
2467 int _bt_set_le_privacy(gboolean set_privacy)
2470 GError *error = NULL;
2471 GVariant *result = NULL;
2473 if (__bt_is_factory_test_mode()) {
2474 BT_ERR("Unable to set le privacy in factory binary !!");
2475 return BLUETOOTH_ERROR_NOT_SUPPORT;
2478 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2479 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2480 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2483 proxy = _bt_get_adapter_proxy();
2484 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2486 result = g_dbus_proxy_call_sync(proxy,
2488 g_variant_new("(b)", set_privacy),
2489 G_DBUS_CALL_FLAGS_NONE,
2495 if (error != NULL) {
2496 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2497 g_clear_error(&error);
2499 BT_ERR("Failed to SetLePrivacy");
2500 return BLUETOOTH_ERROR_INTERNAL;
2503 g_variant_unref(result);
2504 BT_INFO("SetLePrivacy as %d", set_privacy);
2505 return BLUETOOTH_ERROR_NONE;
2508 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2511 GError *error = NULL;
2515 GVariantBuilder *builder;
2517 BT_CHECK_PARAMETER(m_data, return);
2519 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2520 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2521 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2524 proxy = _bt_get_adapter_proxy();
2525 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2527 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2529 for (i = 0; i < (m_data->data_len) + 2; i++) {
2530 g_variant_builder_add(builder, "y", m_data->data[i]);
2533 val = g_variant_new("(ay)", builder);
2535 result = g_dbus_proxy_call_sync(proxy,
2536 "SetManufacturerData",
2538 G_DBUS_CALL_FLAGS_NONE,
2542 g_variant_builder_unref(builder);
2544 if (error != NULL) {
2545 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2546 g_clear_error(&error);
2548 BT_ERR("Failed to SetManufacturerData");
2550 return BLUETOOTH_ERROR_INTERNAL;
2552 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2554 for (i = 0; i < (m_data->data_len) + 2; i++) {
2555 g_variant_builder_add(builder, "y", m_data->data[i]);
2558 val = g_variant_new("(ay)", builder);
2560 _bt_send_event(BT_ADAPTER_EVENT,
2561 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2564 BT_INFO("Set manufacturer data");
2566 g_variant_builder_unref(builder);
2567 g_variant_unref(result);
2569 return BLUETOOTH_ERROR_NONE;
2572 int _bt_get_enable_timer_id(void)