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;
1756 BT_CHECK_PARAMETER(service_uuid, return);
1757 BT_CHECK_PARAMETER(used, return);
1759 proxy = _bt_get_adapter_properties_proxy();
1760 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1762 result = g_dbus_proxy_call_sync(proxy,
1764 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1766 G_DBUS_CALL_FLAGS_NONE,
1772 if (error != NULL) {
1773 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1774 g_clear_error(&error);
1776 BT_ERR("Failed to get UUIDs");
1777 return BLUETOOTH_ERROR_INTERNAL;
1780 g_variant_get(result, "(v)", &value);
1781 g_variant_get(value, "as", &iter);
1784 BT_ERR("Failed to get UUIDs(%s)",service_uuid);
1786 g_variant_unref(result);
1787 g_variant_unref(value);
1791 while (g_variant_iter_loop(iter, "s", &uuid)) {
1792 if (strcasecmp(uuid, service_uuid) == 0) {
1802 g_variant_iter_free(iter);
1803 g_variant_unref(value);
1804 g_variant_unref(result);
1805 BT_DBG("Service Used? %d", *used);
1809 static gboolean __bt_get_discoverable_property(void)
1812 gboolean discoverable_v;
1813 GError *error = NULL;
1817 proxy = _bt_get_adapter_properties_proxy();
1818 retv_if(proxy == NULL, FALSE);
1820 result = g_dbus_proxy_call_sync(proxy,
1822 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1824 G_DBUS_CALL_FLAGS_NONE,
1830 if (error != NULL) {
1831 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1832 g_clear_error(&error);
1834 BT_ERR("Failed to get Discoverable property");
1838 g_variant_get(result, "(v)", &temp);
1839 discoverable_v = g_variant_get_boolean(temp);
1840 BT_DBG("discoverable_v:%d", discoverable_v);
1842 g_variant_unref(result);
1843 g_variant_unref(temp);
1845 return discoverable_v;
1848 int _bt_get_discoverable_mode(int *mode)
1850 gboolean discoverable;
1851 unsigned int timeout;
1853 BT_CHECK_PARAMETER(mode, return);
1855 discoverable = __bt_get_discoverable_property();
1856 timeout = _bt_get_discoverable_timeout_property();
1858 if (discoverable == TRUE) {
1860 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1862 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1864 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1866 return BLUETOOTH_ERROR_NONE;
1870 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1872 int ret = BLUETOOTH_ERROR_NONE;
1875 GError *error = NULL;
1879 proxy = _bt_get_adapter_properties_proxy();
1881 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1883 switch (discoverable_mode) {
1884 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1889 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1894 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1899 return BLUETOOTH_ERROR_INVALID_PARAM;
1902 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1903 discoverable_mode, timeout);
1905 result = g_dbus_proxy_call_sync(proxy,
1907 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1908 "Connectable", g_variant_new("b", pg_scan)),
1909 G_DBUS_CALL_FLAGS_NONE,
1915 if (error != NULL) {
1916 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1917 g_clear_error(&error);
1919 BT_ERR("Failed to set connectable property");
1920 return BLUETOOTH_ERROR_INTERNAL;
1922 g_variant_unref(result);
1923 result = g_dbus_proxy_call_sync(proxy,
1925 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
1926 g_variant_new("b", inq_scan)),
1927 G_DBUS_CALL_FLAGS_NONE,
1933 if (error != NULL) {
1934 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
1935 g_clear_error(&error);
1937 BT_ERR("Failed to set Discoverable property");
1938 return BLUETOOTH_ERROR_INTERNAL;
1940 g_variant_unref(result);
1941 result = g_dbus_proxy_call_sync(proxy,
1943 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1944 "DiscoverableTimeout", g_variant_new("u", timeout)),
1945 G_DBUS_CALL_FLAGS_NONE,
1951 if (error != NULL) {
1952 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
1953 g_clear_error(&error);
1955 BT_ERR("Failed to set DiscoverableTimeout property");
1956 return BLUETOOTH_ERROR_INTERNAL;
1959 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1962 ret = __bt_set_visible_time(timeout);
1964 g_variant_unref(result);
1969 int _bt_start_discovery(void)
1972 GError *error = NULL;
1975 if (_bt_is_discovering() == TRUE) {
1976 BT_ERR("BT is already in discovering");
1977 return BLUETOOTH_ERROR_IN_PROGRESS;
1978 } else if (_bt_is_device_creating() == TRUE) {
1979 BT_ERR("Bonding device is going on");
1980 return BLUETOOTH_ERROR_DEVICE_BUSY;
1983 proxy = _bt_get_adapter_proxy();
1984 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1986 result = g_dbus_proxy_call_sync(proxy,
1989 G_DBUS_CALL_FLAGS_NONE,
1995 if (error != NULL) {
1996 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
1997 g_clear_error(&error);
1999 BT_ERR("StartDiscovery failed");
2000 return BLUETOOTH_ERROR_INTERNAL;
2003 is_discovering = TRUE;
2004 cancel_by_user = FALSE;
2005 /* discovery status will be change in event */
2006 g_variant_unref(result);
2007 return BLUETOOTH_ERROR_NONE;
2010 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2014 GError *error = NULL;
2015 const gchar *disc_type;
2017 if (_bt_is_discovering() == TRUE) {
2018 BT_ERR("BT is already in discovering");
2019 return BLUETOOTH_ERROR_IN_PROGRESS;
2022 proxy = _bt_get_adapter_proxy();
2023 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2025 if (role == DISCOVERY_ROLE_BREDR)
2026 disc_type = "BREDR";
2027 else if (role == DISCOVERY_ROLE_LE)
2029 else if (role == DISCOVERY_ROLE_LE_BREDR)
2030 disc_type = "LE_BREDR";
2032 return BLUETOOTH_ERROR_INVALID_PARAM;
2034 result = g_dbus_proxy_call_sync(proxy,
2035 "StartCustomDiscovery",
2036 g_variant_new("s", disc_type),
2037 G_DBUS_CALL_FLAGS_NONE,
2043 if (error != NULL) {
2044 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2045 g_clear_error(&error);
2047 BT_ERR("StartCustomDiscovery failed");
2048 return BLUETOOTH_ERROR_INTERNAL;
2051 is_discovering = TRUE;
2052 cancel_by_user = FALSE;
2053 /* discovery status will be change in event */
2054 g_variant_unref(result);
2055 return BLUETOOTH_ERROR_NONE;
2058 int _bt_cancel_discovery(void)
2061 GError *error = NULL;
2064 if (_bt_is_discovering() == FALSE) {
2065 BT_ERR("BT is not in discovering");
2066 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2069 proxy = _bt_get_adapter_proxy();
2070 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2072 result = g_dbus_proxy_call_sync(proxy,
2075 G_DBUS_CALL_FLAGS_NONE,
2081 if (error != NULL) {
2082 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2083 g_clear_error(&error);
2085 BT_ERR("StopDiscovery failed");
2086 return BLUETOOTH_ERROR_INTERNAL;
2089 cancel_by_user = TRUE;
2090 /* discovery status will be change in event */
2091 g_variant_unref(result);
2092 return BLUETOOTH_ERROR_NONE;
2095 gboolean _bt_is_discovering(void)
2097 return is_discovering;
2100 gboolean _bt_is_connectable(void)
2103 GError *error = NULL;
2104 gboolean is_connectable = FALSE;
2108 proxy = _bt_get_adapter_properties_proxy();
2109 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2111 result = g_dbus_proxy_call_sync(proxy,
2113 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2115 G_DBUS_CALL_FLAGS_NONE,
2121 if (error != NULL) {
2122 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2123 g_clear_error(&error);
2125 BT_ERR("Failed to get connectable property");
2126 return BLUETOOTH_ERROR_INTERNAL;
2129 g_variant_get(result, "(v)", &temp);
2130 is_connectable = g_variant_get_boolean(temp);
2131 BT_DBG("discoverable_v:%d", is_connectable);
2133 g_variant_unref(result);
2134 g_variant_unref(temp);
2136 BT_INFO("Get connectable [%d]", is_connectable);
2137 return is_connectable;
2140 int _bt_set_connectable(gboolean is_connectable)
2143 GError *error = NULL;
2146 if (__bt_is_factory_test_mode()) {
2147 BT_ERR("Unable to set connectable in factory binary !!");
2148 return BLUETOOTH_ERROR_NOT_SUPPORT;
2151 proxy = _bt_get_adapter_properties_proxy();
2153 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2155 result = g_dbus_proxy_call_sync(proxy,
2157 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2158 g_variant_new("b", is_connectable)),
2159 G_DBUS_CALL_FLAGS_NONE,
2165 if (error != NULL) {
2166 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2167 g_clear_error(&error);
2169 BT_ERR("Failed to set connectable property");
2170 return BLUETOOTH_ERROR_INTERNAL;
2173 BT_INFO("Set connectable [%d]", is_connectable);
2174 g_variant_unref(result);
2175 return BLUETOOTH_ERROR_NONE;
2178 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2181 gboolean discovering_v;
2182 GError *error = NULL;
2183 char *discovering_type = NULL;
2187 proxy = _bt_get_adapter_properties_proxy();
2188 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2190 if (discovery_type == DISCOVERY_ROLE_BREDR)
2191 discovering_type = "Discovering";
2192 else if (discovery_type == DISCOVERY_ROLE_LE)
2193 discovering_type = "LEDiscovering";
2195 result = g_dbus_proxy_call_sync(proxy,
2197 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2199 G_DBUS_CALL_FLAGS_NONE,
2205 if (error != NULL) {
2206 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2207 g_clear_error(&error);
2209 BT_ERR("Failed to get discovering property");
2210 return BLUETOOTH_ERROR_INTERNAL;
2213 g_variant_get(result, "(v)", &temp);
2214 discovering_v = g_variant_get_boolean(temp);
2215 BT_DBG("discoverable_v:%d", discovering_v);
2217 g_variant_unref(result);
2218 g_variant_unref(temp);
2220 return discovering_v;
2223 unsigned int _bt_get_discoverable_timeout_property(void)
2226 unsigned int timeout_v;
2227 GError *error = NULL;
2231 proxy = _bt_get_adapter_properties_proxy();
2232 retv_if(proxy == NULL, 0);
2234 result = g_dbus_proxy_call_sync(proxy,
2236 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2237 "DiscoverableTimeout"),
2238 G_DBUS_CALL_FLAGS_NONE,
2244 BT_ERR("Fail to get discoverable timeout");
2245 if (error != NULL) {
2246 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2247 g_clear_error(&error);
2252 g_variant_get(result, "(v)", &temp);
2253 timeout_v = g_variant_get_uint32(temp);
2254 BT_DBG("discoverable_v:%d", timeout_v);
2256 g_variant_unref(result);
2257 g_variant_unref(temp);
2262 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2264 bluetooth_device_info_t *dev_info;
2267 GByteArray *manufacturer_data = NULL;
2269 GVariantIter *char_value_iter;
2271 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2273 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2278 if (!g_strcmp0(key, "Address")) {
2279 const char *address = NULL;
2280 address = g_variant_get_string(value, NULL);
2281 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2283 } else if(!g_strcmp0(key, "Class")) {
2285 cod = g_variant_get_uint32(value);
2286 _bt_divide_device_class(&dev_info->device_class, cod);
2287 } else if(!g_strcmp0(key, "Name")) {
2288 const char *name = NULL;
2289 name = g_variant_get_string(value, NULL);
2290 /* If there is no Alias */
2291 if (strlen(dev_info->device_name.name) == 0) {
2292 g_strlcpy(dev_info->device_name.name, name,
2293 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2295 } else if(!g_strcmp0(key, "Alias")) {
2296 const char *alias = NULL;
2297 alias = g_variant_get_string(value, NULL);
2298 /* Overwrite the name */
2300 memset(dev_info->device_name.name, 0x00,
2301 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2302 g_strlcpy(dev_info->device_name.name, alias,
2303 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2305 } else if (!g_strcmp0(key, "Connected")) {
2306 dev_info->connected = g_variant_get_byte(value);
2307 } else if (!g_strcmp0(key, "Paired")) {
2308 dev_info->paired = g_variant_get_boolean(value);
2309 } else if (!g_strcmp0(key, "Trusted")) {
2310 dev_info->trust = g_variant_get_boolean(value);
2311 } else if (!g_strcmp0(key, "RSSI")) {
2312 dev_info->rssi = g_variant_get_int16(value);
2313 } else if (!g_strcmp0(key, "UUIDs")) {
2319 dev_info->service_index = 0;
2320 g_variant_get(value, "as", &iter);
2321 while (g_variant_iter_loop(iter, "s", &uuid)) {
2322 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2323 parts = g_strsplit(uuid, "-", -1);
2325 if (parts == NULL || parts[0] == NULL) {
2330 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2335 dev_info->service_index = i;
2336 g_variant_iter_free(iter);
2337 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2338 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2339 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2340 manufacturer_data = g_byte_array_new();
2341 g_variant_get(value, "ay", &char_value_iter);
2342 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
2343 g_byte_array_append(manufacturer_data, &char_value, 1);
2345 if (manufacturer_data) {
2346 if (manufacturer_data->len > 0) {
2347 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2350 g_variant_iter_free(char_value_iter);
2351 g_byte_array_free(manufacturer_data, TRUE);
2358 static void __bt_extract_device_info(GVariantIter *iter,
2361 bluetooth_device_info_t *dev_info = NULL;
2362 char *object_path = NULL;
2363 GVariantIter *interface_iter;
2364 GVariantIter *svc_iter;
2365 char *interface_str = NULL;
2367 /* Parse the signature: oa{sa{sv}}} */
2368 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2371 if (object_path == NULL)
2374 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2375 &interface_str, &svc_iter)) {
2376 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2377 BT_DBG("Found a device: %s", object_path);
2378 dev_info = __bt_parse_device_info(svc_iter);
2380 if (dev_info->paired == TRUE) {
2381 g_array_append_vals(*dev_list, dev_info,
2382 sizeof(bluetooth_device_info_t));
2386 g_free(interface_str);
2387 g_variant_iter_free(svc_iter);
2395 int _bt_get_bonded_devices(GArray **dev_list)
2398 GDBusConnection *conn;
2399 GDBusProxy *manager_proxy;
2400 GVariant *result = NULL;
2401 GVariantIter *iter = NULL;
2402 GError *error = NULL;
2404 conn = _bt_get_system_conn();
2405 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2407 manager_proxy = _bt_get_manager_proxy();
2408 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2410 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2412 G_DBUS_CALL_FLAGS_NONE,
2418 if (error != NULL) {
2419 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2420 g_clear_error(&error);
2422 BT_ERR("Failed to Failed to GetManagedObjects");
2423 return BLUETOOTH_ERROR_INTERNAL;
2426 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2427 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2429 __bt_extract_device_info(iter, dev_list);
2430 g_variant_iter_free(iter);
2431 g_variant_unref(result);
2434 return BLUETOOTH_ERROR_NONE;
2437 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2438 bluetooth_device_info_t *dev_info)
2440 char *object_path = NULL;
2441 GDBusProxy *adapter_proxy;
2442 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2443 int ret = BLUETOOTH_ERROR_NONE;
2445 BT_CHECK_PARAMETER(device_address, return);
2446 BT_CHECK_PARAMETER(dev_info, return);
2448 adapter_proxy = _bt_get_adapter_proxy();
2449 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2451 _bt_convert_addr_type_to_string(address, device_address->addr);
2453 object_path = _bt_get_device_object_path(address);
2455 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2457 ret = __bt_get_bonded_device_info(object_path, dev_info);
2458 g_free(object_path);
2463 int _bt_get_timeout_value(int *timeout)
2465 time_t current_time;
2468 /* Take current time */
2469 time(¤t_time);
2470 time_diff = difftime(current_time, visible_timer.start_time);
2472 BT_DBG("Time diff = %d\n", time_diff);
2474 *timeout = visible_timer.timeout - time_diff;
2476 return BLUETOOTH_ERROR_NONE;
2479 int _bt_set_le_privacy(gboolean set_privacy)
2482 GError *error = NULL;
2483 GVariant *result = NULL;
2485 if (__bt_is_factory_test_mode()) {
2486 BT_ERR("Unable to set le privacy in factory binary !!");
2487 return BLUETOOTH_ERROR_NOT_SUPPORT;
2490 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2491 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2492 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2495 proxy = _bt_get_adapter_proxy();
2496 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2498 result = g_dbus_proxy_call_sync(proxy,
2500 g_variant_new("(b)", set_privacy),
2501 G_DBUS_CALL_FLAGS_NONE,
2507 if (error != NULL) {
2508 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2509 g_clear_error(&error);
2511 BT_ERR("Failed to SetLePrivacy");
2512 return BLUETOOTH_ERROR_INTERNAL;
2515 g_variant_unref(result);
2516 BT_INFO("SetLePrivacy as %d", set_privacy);
2517 return BLUETOOTH_ERROR_NONE;
2520 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2523 GError *error = NULL;
2527 GVariantBuilder *builder;
2529 BT_CHECK_PARAMETER(m_data, return);
2531 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2532 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2533 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2536 proxy = _bt_get_adapter_proxy();
2537 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2539 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2541 for (i = 0; i < (m_data->data_len) + 2; i++) {
2542 g_variant_builder_add(builder, "y", m_data->data[i]);
2545 val = g_variant_new("(ay)", builder);
2547 result = g_dbus_proxy_call_sync(proxy,
2548 "SetManufacturerData",
2550 G_DBUS_CALL_FLAGS_NONE,
2554 g_variant_builder_unref(builder);
2556 if (error != NULL) {
2557 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2558 g_clear_error(&error);
2560 BT_ERR("Failed to SetManufacturerData");
2562 return BLUETOOTH_ERROR_INTERNAL;
2564 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2566 for (i = 0; i < (m_data->data_len) + 2; i++) {
2567 g_variant_builder_add(builder, "y", m_data->data[i]);
2570 val = g_variant_new("(ay)", builder);
2572 _bt_send_event(BT_ADAPTER_EVENT,
2573 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2576 BT_INFO("Set manufacturer data");
2578 g_variant_builder_unref(builder);
2579 g_variant_unref(result);
2581 return BLUETOOTH_ERROR_NONE;
2584 int _bt_get_enable_timer_id(void)