2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
25 #include <syspopup_caller.h>
28 #include <dbus/dbus-glib.h>
29 #include <dbus/dbus.h>
31 #include <eventsystem.h>
32 #include <bundle_internal.h>
35 #include "bluetooth-api.h"
36 #include "bt-internal-types.h"
37 #include "bt-service-common.h"
38 #include "bt-service-event.h"
39 #include "bt-service-adapter.h"
40 #include "bt-service-util.h"
41 #include "bt-service-network.h"
42 #include "bt-service-obex-server.h"
43 #include "bt-service-agent.h"
44 #include "bt-service-main.h"
45 #include "bt-service-avrcp.h"
46 #include "bt-service-device.h"
56 bt_adapter_timer_t visible_timer = {0, };
58 static gboolean is_discovering;
59 static gboolean cancel_by_user;
60 static bt_status_t adapter_status = BT_DEACTIVATED;
61 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
62 static void *adapter_agent = NULL;
63 static GDBusProxy *core_proxy = NULL;
64 static guint timer_id = 0;
65 static guint le_timer_id = 0;
67 static int status_reg_id;
69 #define BT_CORE_NAME "org.projectx.bt_core"
70 #define BT_CORE_PATH "/org/projectx/bt_core"
71 #define BT_CORE_INTERFACE "org.projectx.btcore"
73 #define BT_DISABLE_TIME 500 /* 500 ms */
75 GDBusProxy *_bt_init_core_proxy(void)
78 GDBusConnection *conn;
80 conn = _bt_get_system_gconn();
84 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
99 static GDBusProxy *__bt_get_core_proxy(void)
101 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
104 static gboolean __bt_is_factory_test_mode(void)
108 #ifdef ENABLE_TIZEN_2_4
109 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
110 BT_ERR("Get the DUT Mode fail");
116 BT_INFO("DUT Test Mode !!");
123 static gboolean __bt_timeout_handler(gpointer user_data)
125 int result = BLUETOOTH_ERROR_NONE;
129 /* Take current time */
131 time_diff = difftime(current_time, visible_timer.start_time);
133 /* Send event to application */
134 _bt_send_event(BT_ADAPTER_EVENT,
135 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
136 g_variant_new("(in)", result, time_diff));
138 if (visible_timer.timeout <= time_diff) {
139 g_source_remove(visible_timer.event_id);
140 visible_timer.event_id = 0;
141 visible_timer.timeout = 0;
143 #ifndef TIZEN_WEARABLE
144 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
145 BT_ERR("Set vconf failed\n");
153 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
155 BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
157 int result = BLUETOOTH_ERROR_NONE;
160 if (alarm_id != visible_timer.alarm_id)
163 if (visible_timer.event_id) {
164 _bt_send_event(BT_ADAPTER_EVENT,
165 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
166 g_variant_new("(in)", result, timeout));
167 g_source_remove(visible_timer.event_id);
168 visible_timer.event_id = 0;
169 visible_timer.timeout = 0;
171 #ifndef TIZEN_WEARABLE
172 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
173 BT_ERR("Set vconf failed\n");
176 /* Switch Off visibility in Bluez */
177 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
178 visible_timer.alarm_id = 0;
182 static void __bt_visibility_alarm_create()
187 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
190 BT_ERR("Failed to create alarm error = %d\n", result);
192 BT_DBG("Alarm created = %d\n", alarm_id);
193 visible_timer.alarm_id = alarm_id;
197 static void __bt_visibility_alarm_remove()
199 if (visible_timer.event_id > 0) {
200 g_source_remove(visible_timer.event_id);
201 visible_timer.event_id = 0;
204 if (visible_timer.alarm_id > 0) {
205 alarmmgr_remove_alarm(visible_timer.alarm_id);
206 visible_timer.alarm_id = 0;
210 int __bt_set_visible_time(int timeout)
214 __bt_visibility_alarm_remove();
216 visible_timer.timeout = timeout;
218 #ifndef TIZEN_WEARABLE
219 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
220 BT_ERR("Set vconf failed");
224 return BLUETOOTH_ERROR_NONE;
226 if (!visible_timer.alarm_init) {
227 /* Set Alarm timer to switch off BT */
228 result = alarmmgr_init("bt-service");
230 return BLUETOOTH_ERROR_INTERNAL;
232 visible_timer.alarm_init = TRUE;
235 result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
237 return BLUETOOTH_ERROR_INTERNAL;
239 /* Take start time */
240 time(&(visible_timer.start_time));
241 visible_timer.event_id = g_timeout_add_seconds(1,
242 __bt_timeout_handler, NULL);
244 __bt_visibility_alarm_create();
246 return BLUETOOTH_ERROR_NONE;
249 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
256 ret_if(value == NULL);
259 dev->service_index = 0;
261 g_variant_get(value, "as", &iter);
262 while (g_variant_iter_loop(iter, "s", &uuid)) {
263 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
264 parts = g_strsplit(uuid, "-", -1);
266 if (parts == NULL || parts[0] == NULL) {
271 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
274 dev->service_index++;
277 g_variant_iter_free(iter);
280 static int __bt_get_bonded_device_info(gchar *device_path,
281 bluetooth_device_info_t *dev_info)
283 GError *error = NULL;
284 GDBusProxy *device_proxy;
285 const gchar *address = NULL;
286 const gchar *name = NULL;
287 unsigned int cod = 0;
289 gboolean trust = FALSE;
290 gboolean paired = FALSE;
291 guchar connected = 0;
292 GByteArray *manufacturer_data = NULL;
294 GDBusConnection *conn;
296 GVariantIter *property_iter;
300 GVariantIter *char_value_iter;
302 BT_CHECK_PARAMETER(device_path, return);
303 BT_CHECK_PARAMETER(dev_info, return);
305 conn = _bt_get_system_gconn();
306 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
308 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
312 BT_PROPERTIES_INTERFACE,
315 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
317 result = g_dbus_proxy_call_sync(device_proxy,
319 g_variant_new("(s)", BT_DEVICE_INTERFACE),
320 G_DBUS_CALL_FLAGS_NONE,
326 BT_ERR("Error occured in Proxy call");
328 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
329 g_clear_error(&error);
331 g_object_unref(device_proxy);
332 return BLUETOOTH_ERROR_INTERNAL;
335 g_object_unref(device_proxy);
337 g_variant_get(result, "(a{sv})", &property_iter);
339 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
340 if (!g_strcmp0(key,"Paired")) {
341 paired = g_variant_get_boolean(value);
342 } else if(!g_strcmp0(key, "Address")) {
343 address = g_variant_get_string(value, NULL);
344 } else if (!g_strcmp0(key, "Alias")) {
345 name = g_variant_get_string(value, NULL);
346 } else if (!g_strcmp0(key, "Name")) {
348 name = g_variant_get_string(value, NULL);
349 } else if (!g_strcmp0(key, "Class")) {
350 cod = g_variant_get_uint32(value);
351 } else if (!g_strcmp0(key, "Connected")) {
352 connected = g_variant_get_byte(value);
353 } else if (!g_strcmp0(key, "Trusted")) {
354 trust = g_variant_get_boolean(value);
355 } else if (!g_strcmp0(key, "RSSI")) {
356 rssi = g_variant_get_int16(value);
357 } else if (!g_strcmp0(key, "UUIDs")) {
358 __bt_get_service_list(value, dev_info);
359 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
360 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
361 } else if (!g_strcmp0(key, "ManufacturerData")) {
362 manufacturer_data = g_byte_array_new();
363 g_variant_get(value, "ay", &char_value_iter);
364 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
365 g_byte_array_append(manufacturer_data, &char_value, 1);
367 if (manufacturer_data) {
368 if (manufacturer_data->len > 0) {
369 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
370 manufacturer_data->len);
376 BT_DBG("trust: %d, paired: %d", trust, paired);
378 g_variant_unref(result);
380 if ((paired == FALSE) && (trust == FALSE)) {
381 return BLUETOOTH_ERROR_NOT_PAIRED;
384 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
387 _bt_divide_device_class(&dev_info->device_class, cod);
389 g_strlcpy(dev_info->device_name.name, name,
390 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
392 dev_info->rssi = rssi;
393 dev_info->trust = trust;
394 dev_info->paired = paired;
395 dev_info->connected = connected;
396 ret = BLUETOOTH_ERROR_NONE;
401 void _bt_set_discovery_status(gboolean mode)
403 is_discovering = mode;
406 void _bt_set_cancel_by_user(gboolean value)
408 cancel_by_user = value;
411 gboolean _bt_get_cancel_by_user(void)
413 return cancel_by_user;
416 void _bt_adapter_set_status(bt_status_t status)
418 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
419 adapter_status = status;
422 bt_status_t _bt_adapter_get_status(void)
424 return adapter_status;
427 void _bt_adapter_set_le_status(bt_le_status_t status)
429 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
430 adapter_le_status = status;
433 bt_le_status_t _bt_adapter_get_le_status(void)
435 return adapter_le_status;
438 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
440 char *phone_name = NULL;
446 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
447 phone_name = vconf_keynode_get_str(node);
449 if (phone_name && strlen(phone_name) != 0) {
450 if (!g_utf8_validate(phone_name, -1,
451 (const char **)&ptr))
454 _bt_set_local_name(phone_name);
460 static void __bt_set_visible_mode(void)
464 if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
465 BT_ERR("Fail to get the timeout value");
468 if (_bt_set_discoverable_mode(
469 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
470 timeout) != BLUETOOTH_ERROR_NONE) {
471 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
472 BT_ERR("Set vconf failed");
475 if (_bt_set_discoverable_mode(
476 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
477 timeout) != BLUETOOTH_ERROR_NONE) {
478 BT_ERR("Set connectable mode failed");
484 static void __bt_set_local_name(void)
486 char *phone_name = NULL;
489 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
494 if (strlen(phone_name) != 0) {
495 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
498 _bt_set_local_name(phone_name);
503 static int __bt_set_enabled(void)
506 int adapter_status = BT_ADAPTER_DISABLED;
507 int result = BLUETOOTH_ERROR_NONE;
509 _bt_check_adapter(&adapter_status);
511 if (adapter_status == BT_ADAPTER_DISABLED) {
512 BT_ERR("Bluetoothd is not running");
513 return BLUETOOTH_ERROR_INTERNAL;
517 __bt_set_visible_mode();
520 if (_bt_set_discoverable_mode(
521 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0)!= BLUETOOTH_ERROR_NONE)
522 BT_ERR("Fail to set discoverable mode");
525 __bt_set_local_name();
527 /* Update Bluetooth Status to notify other modules */
528 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
529 BT_ERR("Set vconf failed\n");
531 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
532 BT_ERR("Set vconf failed\n");
534 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
535 EVT_VAL_BT_ON) != ES_R_OK)
536 BT_ERR("Fail to set value");
539 /* Send enabled event to API */
540 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
541 g_variant_new("(i)", result));
544 return BLUETOOTH_ERROR_NONE;
547 void _bt_set_disabled(int result)
549 int power_off_status = 0;
552 int pm_ignore_mode = 0;
554 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
555 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
557 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
559 /* Update the vconf BT status in normal Deactivation case only */
560 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
561 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
563 BT_DBG("Update vconf for BT normal Deactivation");
565 if (result == BLUETOOTH_ERROR_TIMEOUT)
566 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 )
567 BT_ERR("Set vconf failed");
569 /* Update Bluetooth Status to notify other modules */
570 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
571 BT_ERR("Set vconf failed");
573 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
574 EVT_VAL_BT_OFF) != ES_R_OK)
575 BT_ERR("Fail to set value");
578 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
579 BT_ERR("Set vconf failed\n");
581 _bt_adapter_set_status(BT_DEACTIVATED);
583 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
584 /* Send disabled event */
585 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
586 g_variant_new("(i)", result));
589 BT_INFO("Adapter disabled");
592 static int __bt_set_le_enabled(void)
595 int result = BLUETOOTH_ERROR_NONE;
598 __bt_set_local_name();
600 /* Update Bluetooth Status to notify other modules */
601 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
602 BT_ERR("Set vconf failed\n");
604 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
605 EVT_VAL_BT_LE_ON) != ES_R_OK)
606 BT_ERR("Fail to set value");
608 /* Send enabled event to API */
610 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
611 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
613 status = _bt_adapter_get_status();
614 if (status == BT_DEACTIVATED) {
615 BT_INFO("BREDR is off, turn off PSCAN");
616 _bt_set_connectable(FALSE);
618 if (le_timer_id > 0) {
619 g_source_remove(le_timer_id);
623 /* Send enabled event to API */
624 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
625 g_variant_new("(i)", result));
628 return BLUETOOTH_ERROR_NONE;
631 void _bt_set_le_disabled(int result)
633 int power_off_status;
636 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
637 BT_DBG("ret : %d", ret);
638 BT_DBG("power_off_status : %d", power_off_status);
640 /* Update Bluetooth Status to notify other modules */
641 BT_DBG("Update vconf for BT LE normal Deactivation");
642 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
643 BT_ERR("Set vconf failed\n");
644 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
646 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
647 EVT_VAL_BT_LE_OFF) != ES_R_OK)
648 BT_ERR("Fail to set value");
650 /* Send disabled event */
651 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
652 g_variant_new_int32(result));
655 void *_bt_get_adapter_agent(void)
657 return adapter_agent;
660 int _bt_enable_core(void)
664 GError *error = NULL;
666 proxy = __bt_get_core_proxy();
667 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
669 /* Clean up the process */
670 result = g_dbus_proxy_call_sync(proxy,
673 G_DBUS_CALL_FLAGS_NONE,
680 BT_ERR("Bt core call failed(Error: %s)", error->message);
681 g_clear_error(&error);
683 BT_ERR("Bt core call failed");
684 return BLUETOOTH_ERROR_INTERNAL;
687 g_variant_unref(result);
688 return BLUETOOTH_ERROR_NONE;
691 #if defined(TIZEN_BT_FLIGHTMODE_ENABLED) || !defined(TIZEN_WEARABLE)
692 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
694 gboolean flight_mode = FALSE;
695 int power_saving_mode = 0;
698 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
699 type = vconf_keynode_get_type(node);
700 if (type == VCONF_TYPE_BOOL) {
701 flight_mode = vconf_keynode_get_bool(node);
702 if (flight_mode != TRUE) {
703 BT_ERR("Ignore the event");
706 } else if (type == VCONF_TYPE_INT) {
707 power_saving_mode = vconf_keynode_get_int(node);
708 if (power_saving_mode != 2) {
709 BT_ERR("Ignore the event");
713 BT_ERR("Invaild vconf key type : %d", type);
721 void _bt_service_register_vconf_handler(void)
725 #ifdef TIZEN_TELEPHONY_ENABLED
726 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
727 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
728 BT_ERR("Unable to register key handler");
730 BT_DBG("Telephony is disabled");
733 #ifndef TIZEN_WEARABLE
734 #ifdef ENABLE_TIZEN_2_4
735 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
736 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
737 BT_ERR("Unable to register key handler");
742 void _bt_service_unregister_vconf_handler(void)
746 #ifdef TIZEN_TELEPHONY_ENABLED
747 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
748 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
751 #ifndef TIZEN_WEARABLE
752 #ifdef ENABLE_TIZEN_2_4
753 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
754 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
759 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
761 const char *bt_status = NULL;
762 const char *bt_le_status = NULL;
763 const char *bt_transfering_status = NULL;
764 BT_DBG("bt state set event(%s) received", event_name);
765 #ifdef ENABLE_TIZEN_2_4
766 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
767 BT_DBG("bt_state: (%s)", bt_status);
769 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
770 BT_DBG("bt_state: (%s)", bt_le_status);
774 void _bt_handle_adapter_added(void)
778 bt_le_status_t le_status;
782 BT_DBG("g_source is removed");
783 g_source_remove(timer_id);
787 status = _bt_adapter_get_status();
788 le_status = _bt_adapter_get_le_status();
789 BT_DBG("status : %d", status);
790 BT_DBG("le_status : %d", le_status);
792 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
793 if (!adapter_agent) {
794 BT_ERR("Fail to register agent");
798 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
799 BT_ERR("Fail to register media player");
801 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
802 BT_ERR("Fail to init obex server");
804 #ifdef TIZEN_BT_PAN_NAP_ENABLE
805 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
806 BT_ERR("Fail to activate network");
809 /* add the vconf noti handler */
810 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
811 __bt_phone_name_changed_cb, NULL);
813 BT_ERR("Unable to register key handler");
815 if (le_status == BT_LE_ACTIVATING ||
816 status == BT_ACTIVATING) {
817 __bt_set_le_enabled();
818 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
821 if (status == BT_ACTIVATING) {
823 _bt_adapter_set_status(BT_ACTIVATED);
825 #ifdef ENABLE_TIZEN_2_4
829 _bt_service_register_vconf_handler();
832 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
833 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
834 BT_ERR("Fail to register system event");
838 void _bt_handle_adapter_removed(void)
842 _bt_adapter_set_status(BT_DEACTIVATED);
843 #ifdef ENABLE_TIZEN_2_4
847 __bt_visibility_alarm_remove();
849 if (visible_timer.alarm_init) {
851 visible_timer.alarm_init = FALSE;
854 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
855 (vconf_callback_fn)__bt_phone_name_changed_cb);
857 ERR("vconf_ignore_key_changed failed\n");
860 _bt_destroy_agent(adapter_agent);
861 adapter_agent = NULL;
863 _bt_reliable_terminate_service(NULL);
865 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK) {
866 BT_ERR("Fail to unregister system event");
871 static gboolean __bt_enable_timeout_cb(gpointer user_data)
875 GError *error = NULL;
879 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
881 BT_ERR("EnableAdapter is failed");
883 proxy = __bt_get_core_proxy();
887 /* Clean up the process */
888 result = g_dbus_proxy_call_sync(proxy,
891 G_DBUS_CALL_FLAGS_NONE,
898 BT_ERR("Bt core call failed(Error: %s)", error->message);
899 g_clear_error(&error);
901 BT_ERR("Bt core call failed");
906 g_variant_unref(result);
907 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
909 _bt_terminate_service(NULL);
914 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
918 GError *error = NULL;
922 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
924 BT_ERR("EnableAdapterLE is failed");
926 proxy = __bt_get_core_proxy();
930 /* Clean up the process */
931 result = g_dbus_proxy_call_sync(proxy,
934 G_DBUS_CALL_FLAGS_NONE,
941 BT_ERR("Bt core call failed(Error: %s)", error->message);
942 g_clear_error(&error);
944 BT_ERR("Bt core call failed");
948 g_variant_unref(result);
949 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
951 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
953 if (_bt_adapter_get_status() == BT_DEACTIVATED)
954 _bt_terminate_service(NULL);
959 void _bt_adapter_start_le_enable_timer(void)
961 if (le_timer_id > 0) {
962 g_source_remove(le_timer_id);
966 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
967 __bt_enable_le_timeout_cb, NULL);
972 void _bt_adapter_start_enable_timer(void)
975 g_source_remove(timer_id);
979 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
980 __bt_enable_timeout_cb, NULL);
986 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
991 _bt_adapter_set_status(BT_ACTIVATED);
997 int _bt_enable_adapter(void)
1000 GError *error = NULL;
1002 GVariant *result = NULL;
1003 bt_status_t status = _bt_adapter_get_status();
1004 bt_le_status_t le_status = _bt_adapter_get_le_status();
1008 if (status == BT_ACTIVATING) {
1009 BT_ERR("Enabling in progress");
1010 return BLUETOOTH_ERROR_IN_PROGRESS;
1013 if (status == BT_ACTIVATED) {
1014 BT_ERR("Already enabled");
1015 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1018 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1019 BT_ERR("Disabling in progress");
1020 return BLUETOOTH_ERROR_DEVICE_BUSY;
1023 _bt_adapter_set_status(BT_ACTIVATING);
1027 int adapter_status = BT_ADAPTER_DISABLED;
1029 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1030 BT_ERR("Set vconf failed");
1032 _bt_check_adapter(&adapter_status);
1033 if (adapter_status == BT_ADAPTER_ENABLED) {
1034 g_idle_add(__bt_adapter_enabled_cb, NULL);
1035 _bt_adapter_start_enable_timer();
1036 return BLUETOOTH_ERROR_NONE;
1041 proxy = __bt_get_core_proxy();
1043 return BLUETOOTH_ERROR_INTERNAL;
1045 if (le_status == BT_LE_ACTIVATED) {
1046 BT_INFO("LE Already enabled. Just turn on PSCAN");
1047 ret = _bt_set_connectable(TRUE);
1048 if (ret == BLUETOOTH_ERROR_NONE) {
1049 _bt_adapter_set_status(BT_ACTIVATED);
1051 return BLUETOOTH_ERROR_INTERNAL;
1055 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1057 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1060 BT_ERR("EnableAdapterLe failed: %s", error->message);
1061 _bt_adapter_set_status(BT_DEACTIVATED);
1062 g_clear_error(&error);
1064 result = g_dbus_proxy_call_sync(proxy,
1067 G_DBUS_CALL_FLAGS_NONE,
1072 if (error != NULL) {
1073 BT_ERR("Bt core call failed(Error: %s)", error->message);
1074 g_clear_error(&error);
1076 g_variant_unref(result);
1077 /* Terminate myself */
1078 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1079 return BLUETOOTH_ERROR_INTERNAL;
1081 g_variant_unref(result);
1082 if (le_status == BT_LE_ACTIVATED) {
1085 _bt_adapter_start_enable_timer();
1088 return BLUETOOTH_ERROR_NONE;
1091 static gboolean __bt_disconnect_all(void)
1094 GDBusConnection *conn;
1095 GDBusProxy *dev_proxy;
1096 gboolean ret = FALSE;
1098 GError *error = NULL;
1099 GArray *device_list;
1100 bluetooth_device_info_t info;
1102 char *device_path = NULL;
1103 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1108 conn = _bt_get_system_gconn();
1110 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1112 if (_bt_get_bonded_devices(&device_list)
1113 != BLUETOOTH_ERROR_NONE) {
1114 g_array_free(device_list, TRUE);
1118 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1120 for (i = 0; i < size; i++) {
1122 info = g_array_index(device_list,
1123 bluetooth_device_info_t, i);
1125 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1126 BT_DBG("Found Connected device");
1127 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1128 device_path = _bt_get_device_object_path(address);
1129 if (device_path == NULL)
1132 BT_DBG("Disconnecting : %s", device_path);
1134 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1138 BT_DEVICE_INTERFACE,
1141 if (dev_proxy == NULL)
1144 result = g_dbus_proxy_call_sync(dev_proxy,
1147 G_DBUS_CALL_FLAGS_NONE,
1153 if (error != NULL) {
1154 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1155 g_clear_error(&error);
1157 BT_ERR("Disconnect call failed");
1158 g_object_unref(dev_proxy);
1162 g_variant_unref(result);
1163 g_object_unref(dev_proxy);
1167 g_array_free(device_list, TRUE);
1172 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1175 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1180 int __bt_disable_cb(void)
1184 bt_le_status_t le_status;
1187 GError *error = NULL;
1189 _bt_adapter_set_status(BT_DEACTIVATING);
1190 le_status = _bt_adapter_get_le_status();
1191 BT_DBG("le_status : %d", le_status);
1192 if (le_status == BT_LE_ACTIVATED) {
1193 BT_INFO("LE is enabled. Just turn off PSCAN");
1195 if (_bt_is_discovering())
1196 _bt_cancel_discovery();
1198 if (_bt_is_connectable() == FALSE) {
1199 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1201 ret = _bt_set_connectable(FALSE);
1202 if (ret != BLUETOOTH_ERROR_NONE) {
1203 BT_ERR("_bt_set_connectable fail!");
1204 _bt_adapter_set_status(BT_ACTIVATED);
1205 return BLUETOOTH_ERROR_INTERNAL;
1210 proxy = __bt_get_core_proxy();
1211 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1213 result = g_dbus_proxy_call_sync(proxy,
1216 G_DBUS_CALL_FLAGS_NONE,
1222 if (error != NULL) {
1223 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1224 g_clear_error(&error);
1226 BT_ERR("Failed to DisableAdapter");
1227 _bt_adapter_set_status(BT_ACTIVATED);
1228 return BLUETOOTH_ERROR_INTERNAL;
1231 g_variant_unref(result);
1232 return BLUETOOTH_ERROR_NONE;
1235 int _bt_disable_adapter(void)
1240 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1241 BT_DBG("Disabling in progress");
1242 return BLUETOOTH_ERROR_IN_PROGRESS;
1245 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1246 BT_DBG("Already disabled");
1247 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1251 g_source_remove(timer_id);
1255 __bt_disconnect_all();
1256 ret = __bt_disable_cb();
1262 int _bt_recover_adapter(void)
1267 GError *error = NULL;
1269 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1270 BT_DBG("Disabling in progress");
1271 return BLUETOOTH_ERROR_IN_PROGRESS;
1274 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1275 BT_DBG("Already disabled");
1276 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1279 _bt_adapter_set_status(BT_DEACTIVATING);
1281 proxy = __bt_get_core_proxy();
1282 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1284 result = g_dbus_proxy_call_sync(proxy,
1287 G_DBUS_CALL_FLAGS_NONE,
1293 if (error != NULL) {
1294 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1295 g_clear_error(&error);
1297 BT_ERR("Failed to RecoverAdapter");
1298 return BLUETOOTH_ERROR_INTERNAL;
1301 g_variant_unref(result);
1302 __bt_disconnect_all();
1305 return BLUETOOTH_ERROR_NONE;
1308 int _bt_reset_adapter(void)
1312 GError *error = NULL;
1316 proxy = __bt_get_core_proxy();
1318 return BLUETOOTH_ERROR_INTERNAL;
1320 result = g_dbus_proxy_call_sync(proxy,
1323 G_DBUS_CALL_FLAGS_NONE,
1329 if (error != NULL) {
1330 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1331 g_clear_error(&error);
1333 BT_ERR("Failed to ResetAdapter");
1334 return BLUETOOTH_ERROR_INTERNAL;
1337 g_variant_unref(result);
1338 /* Terminate myself */
1339 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1340 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1343 return BLUETOOTH_ERROR_NONE;
1347 int _bt_check_adapter(int *status)
1350 char *adapter_path = NULL;
1352 BT_CHECK_PARAMETER(status, return);
1354 *status = BT_ADAPTER_DISABLED;
1356 adapter_path = _bt_get_adapter_path();
1359 if (adapter_path != NULL)
1360 *status = BT_ADAPTER_ENABLED;
1362 g_free(adapter_path);
1363 return BLUETOOTH_ERROR_NONE;
1366 int _bt_check_adapter(int *status)
1369 GError *error = NULL;
1372 gboolean powered = FALSE;
1374 BT_CHECK_PARAMETER(status, return);
1376 *status = BT_ADAPTER_DISABLED;
1378 proxy = _bt_get_adapter_properties_proxy();
1379 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1381 result = g_dbus_proxy_call_sync(proxy,
1383 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1385 G_DBUS_CALL_FLAGS_NONE,
1391 BT_ERR("Failed to get local address");
1392 if (error != NULL) {
1393 BT_ERR("Failed to get local address (Error: %s)", error->message);
1394 g_clear_error(&error);
1396 return BLUETOOTH_ERROR_INTERNAL;
1399 g_variant_get(result, "(v)", &temp);
1400 powered = g_variant_get_boolean(temp);
1401 BT_DBG("powered: %d", powered);
1404 *status = BT_ADAPTER_ENABLED;
1406 g_variant_unref(result);
1407 g_variant_unref(temp);
1408 return BLUETOOTH_ERROR_NONE;
1412 int _bt_enable_adapter_le(void)
1416 GError *error = NULL;
1417 bt_status_t status = _bt_adapter_get_status();
1418 bt_le_status_t le_status = _bt_adapter_get_le_status();
1421 if (le_status == BT_LE_ACTIVATING) {
1422 BT_ERR("Enabling in progress");
1423 return BLUETOOTH_ERROR_IN_PROGRESS;
1426 if (le_status == BT_LE_ACTIVATED) {
1427 BT_ERR("Already enabled");
1428 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1431 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1432 BT_ERR("Disabling in progress");
1433 return BLUETOOTH_ERROR_DEVICE_BUSY;
1436 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1438 proxy = __bt_get_core_proxy();
1439 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1441 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1443 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1446 BT_ERR("EnableAdapterLe failed: %s", error->message);
1447 _bt_adapter_set_le_status(BT_DEACTIVATED);
1448 g_clear_error(&error);
1450 /* Clean up the process */
1451 result = g_dbus_proxy_call_sync(proxy,
1454 G_DBUS_CALL_FLAGS_NONE,
1460 BT_ERR("Bt core call failed");
1462 BT_ERR("EnableAdapterLE Failed %s", error->message);
1463 g_clear_error(&error);
1466 g_variant_unref(result);
1467 /* Terminate myself */
1468 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1469 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1470 return BLUETOOTH_ERROR_INTERNAL;
1474 g_variant_unref(result);
1476 _bt_adapter_start_le_enable_timer();
1478 if (status == BT_ACTIVATED) {
1479 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1480 __bt_set_le_enabled();
1482 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1484 return BLUETOOTH_ERROR_NONE;
1487 int _bt_disable_adapter_le(void)
1491 bt_le_status_t bt_le_state;
1493 GError *error = NULL;
1495 bt_le_state = _bt_adapter_get_le_status();
1496 if (bt_le_state == BT_LE_DEACTIVATING) {
1497 BT_DBG("Disabling in progress");
1498 return BLUETOOTH_ERROR_IN_PROGRESS;
1501 if (bt_le_state == BT_LE_DEACTIVATED) {
1502 BT_DBG("Already disabled");
1503 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1506 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1508 proxy = __bt_get_core_proxy();
1510 return BLUETOOTH_ERROR_INTERNAL;
1512 result = g_dbus_proxy_call_sync(proxy,
1515 G_DBUS_CALL_FLAGS_NONE,
1521 if (error != NULL) {
1522 BT_ERR("Bt core call failed (Error: %s)", error->message);
1523 g_clear_error(&error);
1525 BT_ERR("Bt core call failed");
1526 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1527 return BLUETOOTH_ERROR_INTERNAL;
1530 g_variant_unref(result);
1531 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1532 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1534 return BLUETOOTH_ERROR_NONE;
1537 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1541 GError *error = NULL;
1542 const char *address;
1546 BT_CHECK_PARAMETER(local_address, return);
1548 proxy = _bt_get_adapter_properties_proxy();
1549 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1551 result = g_dbus_proxy_call_sync(proxy,
1553 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1555 G_DBUS_CALL_FLAGS_NONE,
1561 BT_ERR("Failed to get local address");
1562 if (error != NULL) {
1563 BT_ERR("Failed to get local address (Error: %s)", error->message);
1564 g_clear_error(&error);
1566 return BLUETOOTH_ERROR_INTERNAL;
1569 g_variant_get(result, "(v)", &temp);
1570 address = g_variant_get_string(temp, NULL);
1571 BT_DBG("Address:%s", address);
1574 _bt_convert_addr_string_to_type(local_address->addr, address);
1576 return BLUETOOTH_ERROR_INTERNAL;
1579 g_variant_unref(result);
1580 g_variant_unref(temp);
1581 return BLUETOOTH_ERROR_NONE;
1584 int _bt_get_local_version(bluetooth_version_t *local_version)
1587 const char *ver = NULL;
1589 int ret = BLUETOOTH_ERROR_NONE;
1593 BT_CHECK_PARAMETER(local_version, return);
1595 GError *error = NULL;
1597 proxy = _bt_get_adapter_properties_proxy();
1598 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1600 result = g_dbus_proxy_call_sync(proxy,
1602 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1604 G_DBUS_CALL_FLAGS_NONE,
1610 if (error != NULL) {
1611 BT_ERR("Failed to get local version (Error: %s)", error->message);
1612 g_clear_error(&error);
1614 BT_ERR("Failed to get local version");
1615 return BLUETOOTH_ERROR_INTERNAL;
1618 g_variant_get(result, "(v)", &temp);
1619 ver = g_variant_get_string(temp, NULL);
1620 BT_DBG("VERSION: %s", ver);
1622 if (ver && (strlen(ver) > 0)) {
1623 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1624 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1627 g_strlcpy(local_version->version, ver,
1628 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1631 ret = BLUETOOTH_ERROR_INTERNAL;
1634 g_variant_unref(result);
1635 g_variant_unref(temp);
1639 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1642 const char *name = NULL;
1644 int ret = BLUETOOTH_ERROR_NONE;
1647 GError *error = NULL;
1649 BT_CHECK_PARAMETER(local_name, return);
1651 proxy = _bt_get_adapter_properties_proxy();
1652 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1654 result = g_dbus_proxy_call_sync(proxy,
1656 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1658 G_DBUS_CALL_FLAGS_NONE,
1664 if (error != NULL) {
1665 BT_ERR("Failed to get local name (Error: %s)", error->message);
1666 g_clear_error(&error);
1668 BT_ERR("Failed to get local name");
1669 return BLUETOOTH_ERROR_INTERNAL;
1672 g_variant_get(result, "(v)", &temp);
1673 name = g_variant_get_string(temp, NULL);
1674 BT_DBG("LOCAL NAME:%s", name);
1676 if (name && (strlen(name) > 0)) {
1677 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1678 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1681 g_strlcpy(local_name->name, name,
1682 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1684 ret = BLUETOOTH_ERROR_INTERNAL;
1686 g_variant_unref(result);
1687 g_variant_unref(temp);
1691 int _bt_set_local_name(char *local_name)
1694 GError *error = NULL;
1698 BT_CHECK_PARAMETER(local_name, return);
1700 proxy = _bt_get_adapter_properties_proxy();
1702 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1704 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1707 result = g_dbus_proxy_call_sync(proxy,
1709 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1710 "Alias", g_variant_new("s", local_name)),
1711 G_DBUS_CALL_FLAGS_NONE,
1717 if (error != NULL) {
1718 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1719 g_clear_error(&error);
1721 BT_ERR("Failed to set Alias");
1722 return BLUETOOTH_ERROR_INTERNAL;
1725 g_variant_unref(result);
1726 return BLUETOOTH_ERROR_NONE;
1729 int _bt_is_service_used(char *service_uuid, gboolean *used)
1732 GError *error = NULL;
1733 int ret = BLUETOOTH_ERROR_NONE;
1736 GVariantIter *iter = NULL;
1740 BT_CHECK_PARAMETER(service_uuid, return);
1741 BT_CHECK_PARAMETER(used, return);
1743 proxy = _bt_get_adapter_properties_proxy();
1744 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1746 result = g_dbus_proxy_call_sync(proxy,
1748 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1750 G_DBUS_CALL_FLAGS_NONE,
1756 if (error != NULL) {
1757 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1758 g_clear_error(&error);
1760 BT_ERR("Failed to get UUIDs");
1761 return BLUETOOTH_ERROR_INTERNAL;
1764 g_variant_get(result, "(v)", &value);
1765 g_variant_get(value, "as", &iter);
1767 BT_ERR("Failed to get UUIDs(%s)",service_uuid);
1769 g_variant_unref(result);
1770 g_variant_unref(value);
1774 while (g_variant_iter_loop(iter, "s", &uuid)) {
1775 if (strcasecmp(uuid, service_uuid) == 0) {
1785 g_variant_iter_free(iter);
1786 g_variant_unref(value);
1787 g_variant_unref(result);
1788 BT_DBG("Service Used? %d", *used);
1792 static gboolean __bt_get_discoverable_property(void)
1795 gboolean discoverable_v;
1796 GError *error = NULL;
1800 proxy = _bt_get_adapter_properties_proxy();
1801 retv_if(proxy == NULL, FALSE);
1803 result = g_dbus_proxy_call_sync(proxy,
1805 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1807 G_DBUS_CALL_FLAGS_NONE,
1813 if (error != NULL) {
1814 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1815 g_clear_error(&error);
1817 BT_ERR("Failed to get Discoverable property");
1818 return BLUETOOTH_ERROR_INTERNAL;
1821 g_variant_get(result, "(v)", &temp);
1822 discoverable_v = g_variant_get_boolean(temp);
1823 BT_DBG("discoverable_v:%d", discoverable_v);
1825 g_variant_unref(result);
1826 g_variant_unref(temp);
1828 return discoverable_v;
1831 int _bt_get_discoverable_mode(int *mode)
1833 gboolean discoverable;
1834 unsigned int timeout;
1836 BT_CHECK_PARAMETER(mode, return);
1838 discoverable = __bt_get_discoverable_property();
1839 timeout = _bt_get_discoverable_timeout_property();
1841 if (discoverable == TRUE) {
1843 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1845 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1847 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1849 return BLUETOOTH_ERROR_NONE;
1853 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1855 int ret = BLUETOOTH_ERROR_NONE;
1858 GError *error = NULL;
1862 proxy = _bt_get_adapter_properties_proxy();
1864 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1866 switch (discoverable_mode) {
1867 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1872 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1877 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1882 return BLUETOOTH_ERROR_INVALID_PARAM;
1885 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1886 discoverable_mode, timeout);
1888 result = g_dbus_proxy_call_sync(proxy,
1890 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1891 "Connectable", g_variant_new("b", pg_scan)),
1892 G_DBUS_CALL_FLAGS_NONE,
1898 if (error != NULL) {
1899 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1900 g_clear_error(&error);
1902 BT_ERR("Failed to set connectable property");
1903 return BLUETOOTH_ERROR_INTERNAL;
1905 g_variant_unref(result);
1906 result = g_dbus_proxy_call_sync(proxy,
1908 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
1909 g_variant_new("b", inq_scan)),
1910 G_DBUS_CALL_FLAGS_NONE,
1916 if (error != NULL) {
1917 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
1918 g_clear_error(&error);
1920 BT_ERR("Failed to set Discoverable property");
1921 return BLUETOOTH_ERROR_INTERNAL;
1923 g_variant_unref(result);
1924 result = g_dbus_proxy_call_sync(proxy,
1926 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1927 "DiscoverableTimeout", g_variant_new("u", timeout)),
1928 G_DBUS_CALL_FLAGS_NONE,
1934 if (error != NULL) {
1935 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
1936 g_clear_error(&error);
1938 BT_ERR("Failed to set DiscoverableTimeout property");
1939 return BLUETOOTH_ERROR_INTERNAL;
1942 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1945 ret = __bt_set_visible_time(timeout);
1947 g_variant_unref(result);
1952 int _bt_start_discovery(void)
1955 GError *error = NULL;
1958 if (_bt_is_discovering() == TRUE) {
1959 BT_ERR("BT is already in discovering");
1960 return BLUETOOTH_ERROR_IN_PROGRESS;
1961 } else if (_bt_is_device_creating() == TRUE) {
1962 BT_ERR("Bonding device is going on");
1963 return BLUETOOTH_ERROR_DEVICE_BUSY;
1966 proxy = _bt_get_adapter_proxy();
1967 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1969 result = g_dbus_proxy_call_sync(proxy,
1972 G_DBUS_CALL_FLAGS_NONE,
1978 if (error != NULL) {
1979 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
1980 g_clear_error(&error);
1982 BT_ERR("StartDiscovery failed");
1983 return BLUETOOTH_ERROR_INTERNAL;
1986 is_discovering = TRUE;
1987 cancel_by_user = FALSE;
1988 /* discovery status will be change in event */
1989 g_variant_unref(result);
1990 return BLUETOOTH_ERROR_NONE;
1993 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
1997 GError *error = NULL;
1998 const gchar *disc_type;
2000 if (_bt_is_discovering() == TRUE) {
2001 BT_ERR("BT is already in discovering");
2002 return BLUETOOTH_ERROR_IN_PROGRESS;
2005 proxy = _bt_get_adapter_proxy();
2006 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2008 if (role == DISCOVERY_ROLE_BREDR)
2009 disc_type = "BREDR";
2010 else if (role == DISCOVERY_ROLE_LE)
2012 else if (role == DISCOVERY_ROLE_LE_BREDR)
2013 disc_type = "LE_BREDR";
2015 return BLUETOOTH_ERROR_INVALID_PARAM;
2017 result = g_dbus_proxy_call_sync(proxy,
2018 "StartCustomDiscovery",
2019 g_variant_new("s", disc_type),
2020 G_DBUS_CALL_FLAGS_NONE,
2026 if (error != NULL) {
2027 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2028 g_clear_error(&error);
2030 BT_ERR("StartCustomDiscovery failed");
2031 return BLUETOOTH_ERROR_INTERNAL;
2034 is_discovering = TRUE;
2035 cancel_by_user = FALSE;
2036 /* discovery status will be change in event */
2037 g_variant_unref(result);
2038 return BLUETOOTH_ERROR_NONE;
2041 int _bt_cancel_discovery(void)
2044 GError *error = NULL;
2047 if (_bt_is_discovering() == FALSE) {
2048 BT_ERR("BT is not in discovering");
2049 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2052 proxy = _bt_get_adapter_proxy();
2053 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2055 result = g_dbus_proxy_call_sync(proxy,
2058 G_DBUS_CALL_FLAGS_NONE,
2064 if (error != NULL) {
2065 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2066 g_clear_error(&error);
2068 BT_ERR("StopDiscovery failed");
2069 return BLUETOOTH_ERROR_INTERNAL;
2072 cancel_by_user = TRUE;
2073 /* discovery status will be change in event */
2074 g_variant_unref(result);
2075 return BLUETOOTH_ERROR_NONE;
2078 gboolean _bt_is_discovering(void)
2080 return is_discovering;
2083 gboolean _bt_is_connectable(void)
2086 GError *error = NULL;
2087 gboolean is_connectable = FALSE;
2091 proxy = _bt_get_adapter_properties_proxy();
2092 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2094 result = g_dbus_proxy_call_sync(proxy,
2096 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2098 G_DBUS_CALL_FLAGS_NONE,
2104 if (error != NULL) {
2105 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2106 g_clear_error(&error);
2108 BT_ERR("Failed to get connectable property");
2109 return BLUETOOTH_ERROR_INTERNAL;
2112 g_variant_get(result, "(v)", &temp);
2113 is_connectable = g_variant_get_boolean(temp);
2114 BT_DBG("discoverable_v:%d", is_connectable);
2116 g_variant_unref(result);
2117 g_variant_unref(temp);
2119 BT_INFO("Get connectable [%d]", is_connectable);
2120 return is_connectable;
2123 int _bt_set_connectable(gboolean is_connectable)
2126 GError *error = NULL;
2129 if (__bt_is_factory_test_mode()) {
2130 BT_ERR("Unable to set connectable in factory binary !!");
2131 return BLUETOOTH_ERROR_NOT_SUPPORT;
2134 proxy = _bt_get_adapter_properties_proxy();
2136 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2138 result = g_dbus_proxy_call_sync(proxy,
2140 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2141 g_variant_new("b", is_connectable)),
2142 G_DBUS_CALL_FLAGS_NONE,
2148 if (error != NULL) {
2149 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2150 g_clear_error(&error);
2152 BT_ERR("Failed to set connectable property");
2153 return BLUETOOTH_ERROR_INTERNAL;
2156 BT_INFO("Set connectable [%d]", is_connectable);
2157 g_variant_unref(result);
2158 return BLUETOOTH_ERROR_NONE;
2161 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2164 gboolean discovering_v;
2165 GError *error = NULL;
2166 char *discovering_type = NULL;
2170 proxy = _bt_get_adapter_properties_proxy();
2171 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2173 if (discovery_type == DISCOVERY_ROLE_BREDR)
2174 discovering_type = "Discovering";
2175 else if (discovery_type == DISCOVERY_ROLE_LE)
2176 discovering_type = "LEDiscovering";
2178 result = g_dbus_proxy_call_sync(proxy,
2180 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2182 G_DBUS_CALL_FLAGS_NONE,
2188 if (error != NULL) {
2189 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2190 g_clear_error(&error);
2192 BT_ERR("Failed to get discovering property");
2193 return BLUETOOTH_ERROR_INTERNAL;
2196 g_variant_get(result, "(v)", &temp);
2197 discovering_v = g_variant_get_boolean(temp);
2198 BT_DBG("discoverable_v:%d", discovering_v);
2200 g_variant_unref(result);
2201 g_variant_unref(temp);
2203 return discovering_v;
2206 unsigned int _bt_get_discoverable_timeout_property(void)
2209 unsigned int timeout_v;
2210 GError *error = NULL;
2214 proxy = _bt_get_adapter_properties_proxy();
2215 retv_if(proxy == NULL, 0);
2217 result = g_dbus_proxy_call_sync(proxy,
2219 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2220 "DiscoverableTimeout"),
2221 G_DBUS_CALL_FLAGS_NONE,
2227 BT_ERR("Fail to get discoverable timeout");
2228 if (error != NULL) {
2229 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2230 g_clear_error(&error);
2235 g_variant_get(result, "(v)", &temp);
2236 timeout_v = g_variant_get_uint32(temp);
2237 BT_DBG("discoverable_v:%d", timeout_v);
2239 g_variant_unref(result);
2240 g_variant_unref(temp);
2245 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2247 bluetooth_device_info_t *dev_info;
2250 GByteArray *manufacturer_data = NULL;
2252 GVariantIter *char_value_iter;
2254 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2256 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2261 if (!g_strcmp0(key, "Address")) {
2262 const char *address = NULL;
2263 address = g_variant_get_string(value, NULL);
2264 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2266 } else if(!g_strcmp0(key, "Class")) {
2268 cod = g_variant_get_uint32(value);
2269 _bt_divide_device_class(&dev_info->device_class, cod);
2270 } else if(!g_strcmp0(key, "Name")) {
2271 const char *name = NULL;
2272 name = g_variant_get_string(value, NULL);
2273 /* If there is no Alias */
2274 if (strlen(dev_info->device_name.name) == 0) {
2275 g_strlcpy(dev_info->device_name.name, name,
2276 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2278 } else if(!g_strcmp0(key, "Alias")) {
2279 const char *alias = NULL;
2280 alias = g_variant_get_string(value, NULL);
2281 /* Overwrite the name */
2283 memset(dev_info->device_name.name, 0x00,
2284 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2285 g_strlcpy(dev_info->device_name.name, alias,
2286 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2288 } else if (!g_strcmp0(key, "Connected")) {
2289 dev_info->connected = g_variant_get_byte(value);
2290 } else if (!g_strcmp0(key, "Paired")) {
2291 dev_info->paired = g_variant_get_boolean(value);
2292 } else if (!g_strcmp0(key, "Trusted")) {
2293 dev_info->trust = g_variant_get_boolean(value);
2294 } else if (!g_strcmp0(key, "RSSI")) {
2295 dev_info->rssi = g_variant_get_int16(value);
2296 } else if (!g_strcmp0(key, "UUIDs")) {
2302 dev_info->service_index = 0;
2303 g_variant_get(value, "as", &iter);
2304 while (g_variant_iter_loop(iter, "s", &uuid)) {
2305 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2306 parts = g_strsplit(uuid, "-", -1);
2308 if (parts == NULL || parts[0] == NULL) {
2313 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2318 dev_info->service_index = i;
2319 g_variant_iter_free(iter);
2320 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2321 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2322 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2323 manufacturer_data = g_byte_array_new();
2324 g_variant_get(value, "ay", &char_value_iter);
2325 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
2326 g_byte_array_append(manufacturer_data, &char_value, 1);
2328 if (manufacturer_data) {
2329 if (manufacturer_data->len > 0) {
2330 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2333 g_variant_iter_free(char_value_iter);
2334 g_byte_array_free(manufacturer_data, TRUE);
2341 static void __bt_extract_device_info(GVariantIter *iter,
2344 bluetooth_device_info_t *dev_info = NULL;
2345 char *object_path = NULL;
2346 GVariantIter *interface_iter;
2347 GVariantIter *svc_iter;
2348 char *interface_str = NULL;
2350 /* Parse the signature: oa{sa{sv}}} */
2351 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2354 if (object_path == NULL)
2357 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2358 &interface_str, &svc_iter)) {
2359 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2360 BT_DBG("Found a device: %s", object_path);
2361 dev_info = __bt_parse_device_info(svc_iter);
2363 if (dev_info->paired == TRUE) {
2364 g_array_append_vals(*dev_list, dev_info,
2365 sizeof(bluetooth_device_info_t));
2369 g_free(interface_str);
2370 g_variant_iter_free(svc_iter);
2378 int _bt_get_bonded_devices(GArray **dev_list)
2381 GDBusConnection *conn;
2382 GDBusProxy *manager_proxy;
2383 GVariant *result = NULL;
2384 GVariantIter *iter = NULL;
2385 GError *error = NULL;
2387 conn = _bt_get_system_conn();
2388 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2390 manager_proxy = _bt_get_manager_proxy();
2391 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2393 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2395 G_DBUS_CALL_FLAGS_NONE,
2401 if (error != NULL) {
2402 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2403 g_clear_error(&error);
2405 BT_ERR("Failed to Failed to GetManagedObjects");
2406 return BLUETOOTH_ERROR_INTERNAL;
2409 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2410 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2412 __bt_extract_device_info(iter, dev_list);
2413 g_variant_iter_free(iter);
2414 g_variant_unref(result);
2417 return BLUETOOTH_ERROR_NONE;
2420 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2421 bluetooth_device_info_t *dev_info)
2423 char *object_path = NULL;
2424 GDBusProxy *adapter_proxy;
2425 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2426 int ret = BLUETOOTH_ERROR_NONE;
2428 BT_CHECK_PARAMETER(device_address, return);
2429 BT_CHECK_PARAMETER(dev_info, return);
2431 adapter_proxy = _bt_get_adapter_proxy();
2432 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2434 _bt_convert_addr_type_to_string(address, device_address->addr);
2436 object_path = _bt_get_device_object_path(address);
2438 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2440 ret = __bt_get_bonded_device_info(object_path, dev_info);
2441 g_free(object_path);
2446 int _bt_get_timeout_value(int *timeout)
2448 time_t current_time;
2451 /* Take current time */
2452 time(¤t_time);
2453 time_diff = difftime(current_time, visible_timer.start_time);
2455 BT_DBG("Time diff = %d\n", time_diff);
2457 *timeout = visible_timer.timeout - time_diff;
2459 return BLUETOOTH_ERROR_NONE;
2462 int _bt_set_le_privacy(gboolean set_privacy)
2465 GError *error = NULL;
2466 GVariant *result = NULL;
2468 if (__bt_is_factory_test_mode()) {
2469 BT_ERR("Unable to set le privacy in factory binary !!");
2470 return BLUETOOTH_ERROR_NOT_SUPPORT;
2473 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2474 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2475 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2478 proxy = _bt_get_adapter_proxy();
2479 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2481 result = g_dbus_proxy_call_sync(proxy,
2483 g_variant_new("(b)", set_privacy),
2484 G_DBUS_CALL_FLAGS_NONE,
2490 if (error != NULL) {
2491 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2492 g_clear_error(&error);
2494 BT_ERR("Failed to SetLePrivacy");
2495 return BLUETOOTH_ERROR_INTERNAL;
2498 g_variant_unref(result);
2499 BT_INFO("SetLePrivacy as %d", set_privacy);
2500 return BLUETOOTH_ERROR_NONE;
2503 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2506 GError *error = NULL;
2510 GVariantBuilder *builder;
2512 BT_CHECK_PARAMETER(m_data, return);
2514 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2515 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2516 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2519 proxy = _bt_get_adapter_proxy();
2520 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2522 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2524 for (i = 0; i < (m_data->data_len) + 2; i++) {
2525 g_variant_builder_add(builder, "y", m_data->data[i]);
2528 val = g_variant_new("(ay)", builder);
2530 result = g_dbus_proxy_call_sync(proxy,
2531 "SetManufacturerData",
2533 G_DBUS_CALL_FLAGS_NONE,
2537 g_variant_builder_unref(builder);
2539 if (error != NULL) {
2540 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2541 g_clear_error(&error);
2543 BT_ERR("Failed to SetManufacturerData");
2545 return BLUETOOTH_ERROR_INTERNAL;
2547 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2549 for (i = 0; i < (m_data->data_len) + 2; i++) {
2550 g_variant_builder_add(builder, "y", m_data->data[i]);
2553 val = g_variant_new("(ay)", builder);
2555 _bt_send_event(BT_ADAPTER_EVENT,
2556 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2559 BT_INFO("Set manufacturer data");
2561 g_variant_builder_unref(builder);
2562 g_variant_unref(result);
2564 return BLUETOOTH_ERROR_NONE;
2568 int _bt_get_enable_timer_id(void)