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 #ifdef ENABLE_TIZEN_2_4
35 #include <journal/device.h>
37 #include <dbus/dbus-glib.h>
38 #include <dbus/dbus.h>
42 #include <eventsystem.h>
44 #include <bundle_internal.h>
47 #include "bluetooth-api.h"
48 #include "bt-internal-types.h"
49 #include "bt-service-common.h"
50 #include "bt-service-event.h"
51 #include "bt-service-adapter.h"
52 #include "bt-service-util.h"
53 #include "bt-service-network.h"
54 #include "bt-service-obex-server.h"
55 #include "bt-service-agent.h"
56 #include "bt-service-main.h"
57 #include "bt-service-avrcp.h"
58 #include "bt-service-device.h"
68 bt_adapter_timer_t visible_timer = {0, };
70 static gboolean is_discovering;
71 static gboolean cancel_by_user;
72 static bt_status_t adapter_status = BT_DEACTIVATED;
73 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
74 static void *adapter_agent = NULL;
75 static GDBusProxy *core_proxy = NULL;
76 static guint timer_id = 0;
77 static guint le_timer_id = 0;
79 static int status_reg_id;
81 #define BT_CORE_NAME "org.projectx.bt_core"
82 #define BT_CORE_PATH "/org/projectx/bt_core"
83 #define BT_CORE_INTERFACE "org.projectx.btcore"
85 #define BT_DISABLE_TIME 500 /* 500 ms */
87 GDBusProxy *_bt_init_core_proxy(void)
90 GDBusConnection *conn;
92 conn = _bt_get_system_gconn();
96 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
111 static GDBusProxy *__bt_get_core_proxy(void)
113 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
116 static gboolean __bt_is_factory_test_mode(void)
120 #ifdef ENABLE_TIZEN_2_4
121 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
122 BT_ERR("Get the DUT Mode fail");
128 BT_INFO("DUT Test Mode !!");
135 static gboolean __bt_timeout_handler(gpointer user_data)
137 int result = BLUETOOTH_ERROR_NONE;
141 /* Take current time */
143 time_diff = difftime(current_time, visible_timer.start_time);
145 /* Send event to application */
146 _bt_send_event(BT_ADAPTER_EVENT,
147 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
148 g_variant_new("(in)", result, time_diff));
150 if (visible_timer.timeout <= time_diff) {
151 g_source_remove(visible_timer.event_id);
152 visible_timer.event_id = 0;
153 visible_timer.timeout = 0;
155 #ifndef TIZEN_WEARABLE
156 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
157 BT_ERR("Set vconf failed\n");
165 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
167 BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
169 int result = BLUETOOTH_ERROR_NONE;
172 if (alarm_id != visible_timer.alarm_id)
175 if (visible_timer.event_id) {
176 _bt_send_event(BT_ADAPTER_EVENT,
177 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
178 g_variant_new("(in)", result, timeout));
179 g_source_remove(visible_timer.event_id);
180 visible_timer.event_id = 0;
181 visible_timer.timeout = 0;
183 #ifndef TIZEN_WEARABLE
184 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
185 BT_ERR("Set vconf failed\n");
188 /* Switch Off visibility in Bluez */
189 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
190 visible_timer.alarm_id = 0;
194 static void __bt_visibility_alarm_create()
199 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
202 BT_ERR("Failed to create alarm error = %d\n", result);
204 BT_DBG("Alarm created = %d\n", alarm_id);
205 visible_timer.alarm_id = alarm_id;
209 static void __bt_visibility_alarm_remove()
211 if (visible_timer.event_id > 0) {
212 g_source_remove(visible_timer.event_id);
213 visible_timer.event_id = 0;
216 if (visible_timer.alarm_id > 0) {
217 alarmmgr_remove_alarm(visible_timer.alarm_id);
218 visible_timer.alarm_id = 0;
222 int __bt_set_visible_time(int timeout)
226 __bt_visibility_alarm_remove();
228 visible_timer.timeout = timeout;
231 return BLUETOOTH_ERROR_NONE;
233 #ifndef TIZEN_WEARABLE
234 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
235 BT_ERR("Set vconf failed");
238 if (!visible_timer.alarm_init) {
239 /* Set Alarm timer to switch off BT */
240 result = alarmmgr_init("bt-service");
242 return BLUETOOTH_ERROR_INTERNAL;
244 visible_timer.alarm_init = TRUE;
247 result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
249 return BLUETOOTH_ERROR_INTERNAL;
251 /* Take start time */
252 time(&(visible_timer.start_time));
253 visible_timer.event_id = g_timeout_add_seconds(1,
254 __bt_timeout_handler, NULL);
256 __bt_visibility_alarm_create();
258 return BLUETOOTH_ERROR_NONE;
261 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
268 ret_if(value == NULL);
271 dev->service_index = 0;
273 g_variant_get(value, "as", &iter);
274 while (g_variant_iter_loop(iter, "s", &uuid)) {
275 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
276 parts = g_strsplit(uuid, "-", -1);
278 if (parts == NULL || parts[0] == NULL) {
283 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
286 dev->service_index++;
289 g_variant_iter_free(iter);
292 static int __bt_get_bonded_device_info(gchar *device_path,
293 bluetooth_device_info_t *dev_info)
295 GError *error = NULL;
296 GDBusProxy *device_proxy;
297 const gchar *address = NULL;
298 const gchar *name = NULL;
299 unsigned int cod = 0;
301 gboolean trust = FALSE;
302 gboolean paired = FALSE;
303 guchar connected = 0;
304 GByteArray *manufacturer_data = NULL;
306 GDBusConnection *conn;
308 GVariantIter *property_iter;
312 GVariantIter *char_value_iter;
314 BT_CHECK_PARAMETER(device_path, return);
315 BT_CHECK_PARAMETER(dev_info, return);
317 conn = _bt_get_system_gconn();
318 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
320 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
324 BT_PROPERTIES_INTERFACE,
327 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
329 result = g_dbus_proxy_call_sync(device_proxy,
331 g_variant_new("(s)", BT_DEVICE_INTERFACE),
332 G_DBUS_CALL_FLAGS_NONE,
338 BT_ERR("Error occured in Proxy call");
340 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
341 g_clear_error(&error);
343 g_object_unref(device_proxy);
344 return BLUETOOTH_ERROR_INTERNAL;
347 g_object_unref(device_proxy);
349 g_variant_get(result, "(a{sv})", &property_iter);
351 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
352 if (!g_strcmp0(key,"Paired")) {
353 paired = g_variant_get_boolean(value);
354 } else if(!g_strcmp0(key, "Address")) {
355 address = g_variant_get_string(value, NULL);
356 } else if (!g_strcmp0(key, "Alias")) {
357 name = g_variant_get_string(value, NULL);
358 } else if (!g_strcmp0(key, "Name")) {
360 name = g_variant_get_string(value, NULL);
361 } else if (!g_strcmp0(key, "Class")) {
362 cod = g_variant_get_uint32(value);
363 } else if (!g_strcmp0(key, "Connected")) {
364 connected = g_variant_get_byte(value);
365 } else if (!g_strcmp0(key, "Trusted")) {
366 trust = g_variant_get_boolean(value);
367 } else if (!g_strcmp0(key, "RSSI")) {
368 rssi = g_variant_get_int16(value);
369 } else if (!g_strcmp0(key, "UUIDs")) {
370 __bt_get_service_list(value, dev_info);
371 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
372 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
373 } else if (!g_strcmp0(key, "ManufacturerData")) {
374 manufacturer_data = g_byte_array_new();
375 g_variant_get(value, "ay", &char_value_iter);
376 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
377 g_byte_array_append(manufacturer_data, &char_value, 1);
379 if (manufacturer_data) {
380 if (manufacturer_data->len > 0) {
381 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
382 manufacturer_data->len);
388 BT_DBG("trust: %d, paired: %d", trust, paired);
390 g_variant_unref(result);
392 if ((paired == FALSE) && (trust == FALSE)) {
393 return BLUETOOTH_ERROR_NOT_PAIRED;
396 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
399 _bt_divide_device_class(&dev_info->device_class, cod);
401 g_strlcpy(dev_info->device_name.name, name,
402 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
404 dev_info->rssi = rssi;
405 dev_info->trust = trust;
406 dev_info->paired = paired;
407 dev_info->connected = connected;
408 ret = BLUETOOTH_ERROR_NONE;
413 void _bt_set_discovery_status(gboolean mode)
415 is_discovering = mode;
418 void _bt_set_cancel_by_user(gboolean value)
420 cancel_by_user = value;
423 gboolean _bt_get_cancel_by_user(void)
425 return cancel_by_user;
428 void _bt_adapter_set_status(bt_status_t status)
430 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
431 adapter_status = status;
434 bt_status_t _bt_adapter_get_status(void)
436 return adapter_status;
439 void _bt_adapter_set_le_status(bt_le_status_t status)
441 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
442 adapter_le_status = status;
445 bt_le_status_t _bt_adapter_get_le_status(void)
447 return adapter_le_status;
450 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
452 char *phone_name = NULL;
458 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
459 phone_name = vconf_keynode_get_str(node);
461 if (phone_name && strlen(phone_name) != 0) {
462 if (!g_utf8_validate(phone_name, -1,
463 (const char **)&ptr))
466 _bt_set_local_name(phone_name);
471 #ifndef TIZEN_WEARABLE
472 static void __bt_set_visible_mode(void)
476 if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
477 BT_ERR("Fail to get the timeout value");
480 if (_bt_set_discoverable_mode(
481 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
482 timeout) != BLUETOOTH_ERROR_NONE) {
483 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
484 BT_ERR("Set vconf failed");
490 static void __bt_set_local_name(void)
492 char *phone_name = NULL;
495 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
500 if (strlen(phone_name) != 0) {
501 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
504 _bt_set_local_name(phone_name);
509 static int __bt_set_enabled(void)
512 int adapter_status = BT_ADAPTER_DISABLED;
513 int result = BLUETOOTH_ERROR_NONE;
515 _bt_check_adapter(&adapter_status);
517 if (adapter_status == BT_ADAPTER_DISABLED) {
518 BT_ERR("Bluetoothd is not running");
519 return BLUETOOTH_ERROR_INTERNAL;
522 #ifndef TIZEN_WEARABLE
523 __bt_set_visible_mode();
526 __bt_set_local_name();
528 /* Update Bluetooth Status to notify other modules */
529 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
530 BT_ERR("Set vconf failed\n");
532 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
533 BT_ERR("Set vconf failed\n");
535 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
536 EVT_VAL_BT_ON) != ES_R_OK)
537 BT_ERR("Fail to set value");
540 /* Send enabled event to API */
541 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
542 g_variant_new("(i)", result));
545 return BLUETOOTH_ERROR_NONE;
548 void _bt_set_disabled(int result)
550 int power_off_status = 0;
553 int pm_ignore_mode = 0;
555 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
556 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
558 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
560 /* Update the vconf BT status in normal Deactivation case only */
563 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
564 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
566 BT_DBG("Update vconf for BT normal Deactivation");
568 if (result == BLUETOOTH_ERROR_TIMEOUT)
569 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 )
570 BT_ERR("Set vconf failed");
572 /* Update Bluetooth Status to notify other modules */
573 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
574 BT_ERR("Set vconf failed");
576 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
577 EVT_VAL_BT_OFF) != ES_R_OK)
578 BT_ERR("Fail to set value");
582 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
583 BT_ERR("Set vconf failed\n");
585 _bt_adapter_set_status(BT_DEACTIVATED);
587 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
588 /* Send disabled event */
589 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
590 g_variant_new("(i)", result));
593 BT_INFO("Adapter disabled");
596 static int __bt_set_le_enabled(void)
599 int result = BLUETOOTH_ERROR_NONE;
602 __bt_set_local_name();
604 /* Update Bluetooth Status to notify other modules */
605 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
606 BT_ERR("Set vconf failed\n");
609 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
610 EVT_VAL_BT_LE_ON) != ES_R_OK)
611 BT_ERR("Fail to set value");
614 /* Send enabled event to API */
616 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
617 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
619 status = _bt_adapter_get_status();
620 if (status == BT_DEACTIVATED) {
621 BT_INFO("BREDR is off, turn off PSCAN");
622 _bt_set_connectable(FALSE);
624 if (le_timer_id > 0) {
625 g_source_remove(le_timer_id);
629 /* Send enabled event to API */
630 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
631 g_variant_new("(i)", result));
634 return BLUETOOTH_ERROR_NONE;
637 void _bt_set_le_disabled(int result)
639 int power_off_status;
642 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
643 BT_DBG("ret : %d", ret);
644 BT_DBG("power_off_status : %d", power_off_status);
646 /* Update Bluetooth Status to notify other modules */
647 BT_DBG("Update vconf for BT LE normal Deactivation");
649 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
650 BT_ERR("Set vconf failed\n");
651 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
653 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
654 EVT_VAL_BT_LE_OFF) != ES_R_OK)
655 BT_ERR("Fail to set value");
658 if (_bt_adapter_get_status() != BT_DEACTIVATED) {
659 /* Send disabled event */
660 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
661 g_variant_new_int32(result));
665 void *_bt_get_adapter_agent(void)
667 return adapter_agent;
670 int _bt_enable_core(void)
674 GError *error = NULL;
676 proxy = __bt_get_core_proxy();
677 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
679 /* Clean up the process */
680 result = g_dbus_proxy_call_sync(proxy,
683 G_DBUS_CALL_FLAGS_NONE,
690 BT_ERR("Bt core call failed(Error: %s)", error->message);
691 g_clear_error(&error);
693 BT_ERR("Bt core call failed");
694 return BLUETOOTH_ERROR_INTERNAL;
697 g_variant_unref(result);
698 return BLUETOOTH_ERROR_NONE;
701 #if defined(TIZEN_BT_FLIGHTMODE_ENABLED) || !defined(TIZEN_WEARABLE)
702 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
704 gboolean flight_mode = FALSE;
705 int power_saving_mode = 0;
708 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
709 type = vconf_keynode_get_type(node);
710 if (type == VCONF_TYPE_BOOL) {
711 flight_mode = vconf_keynode_get_bool(node);
712 if (flight_mode != TRUE) {
713 BT_ERR("Ignore the event");
716 } else if (type == VCONF_TYPE_INT) {
717 power_saving_mode = vconf_keynode_get_int(node);
718 if (power_saving_mode != 2) {
719 BT_ERR("Ignore the event");
723 BT_ERR("Invaild vconf key type : %d", type);
731 void _bt_service_register_vconf_handler(void)
735 #ifdef TIZEN_TELEPHONY_ENABLED
736 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
737 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
738 BT_ERR("Unable to register key handler");
740 BT_DBG("Telephony is disabled");
743 #ifndef TIZEN_WEARABLE
744 #ifdef ENABLE_TIZEN_2_4
745 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
746 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
747 BT_ERR("Unable to register key handler");
752 void _bt_service_unregister_vconf_handler(void)
756 #ifdef TIZEN_TELEPHONY_ENABLED
757 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
758 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
761 #ifndef TIZEN_WEARABLE
762 #ifdef ENABLE_TIZEN_2_4
763 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
764 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
769 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
771 const char *bt_status = NULL;
772 const char *bt_le_status = NULL;
773 const char *bt_transfering_status = NULL;
774 BT_DBG("bt state set event(%s) received", event_name);
775 #ifdef ENABLE_TIZEN_2_4
776 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
777 BT_DBG("bt_state: (%s)", bt_status);
779 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
780 BT_DBG("bt_state: (%s)", bt_le_status);
784 void _bt_handle_adapter_added(void)
788 bt_le_status_t le_status;
792 BT_DBG("g_source is removed");
793 g_source_remove(timer_id);
797 status = _bt_adapter_get_status();
798 le_status = _bt_adapter_get_le_status();
799 BT_DBG("status : %d", status);
800 BT_DBG("le_status : %d", le_status);
802 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
803 if (!adapter_agent) {
804 BT_ERR("Fail to register agent");
808 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
809 BT_ERR("Fail to register media player");
811 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
812 BT_ERR("Fail to init obex server");
814 #ifdef TIZEN_BT_PAN_NAP_ENABLE
815 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
816 BT_ERR("Fail to activate network");
819 /* add the vconf noti handler */
820 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
821 __bt_phone_name_changed_cb, NULL);
823 BT_ERR("Unable to register key handler");
825 if (le_status == BT_LE_ACTIVATING) {
826 __bt_set_le_enabled();
827 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
829 if (status == BT_ACTIVATING) {
831 _bt_adapter_set_status(BT_ACTIVATED);
833 #ifdef ENABLE_TIZEN_2_4
837 _bt_service_register_vconf_handler();
840 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
841 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
842 BT_ERR("Fail to register system event");
847 void _bt_handle_adapter_removed(void)
851 _bt_adapter_set_status(BT_DEACTIVATED);
852 #ifdef ENABLE_TIZEN_2_4
856 __bt_visibility_alarm_remove();
858 if (visible_timer.alarm_init) {
860 visible_timer.alarm_init = FALSE;
863 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
864 (vconf_callback_fn)__bt_phone_name_changed_cb);
866 ERR("vconf_ignore_key_changed failed\n");
869 _bt_destroy_agent(adapter_agent);
870 adapter_agent = NULL;
872 _bt_reliable_terminate_service(NULL);
874 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK) {
875 BT_ERR("Fail to unregister system event");
881 static gboolean __bt_enable_timeout_cb(gpointer user_data)
885 GError *error = NULL;
889 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
891 BT_ERR("EnableAdapter is failed");
893 proxy = __bt_get_core_proxy();
897 /* Clean up the process */
898 result = g_dbus_proxy_call_sync(proxy,
901 G_DBUS_CALL_FLAGS_NONE,
908 BT_ERR("Bt core call failed(Error: %s)", error->message);
909 g_clear_error(&error);
911 BT_ERR("Bt core call failed");
916 g_variant_unref(result);
918 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
920 _bt_terminate_service(NULL);
925 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
929 GError *error = NULL;
933 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
935 BT_ERR("EnableAdapterLE is failed");
937 proxy = __bt_get_core_proxy();
941 /* Clean up the process */
942 result = g_dbus_proxy_call_sync(proxy,
945 G_DBUS_CALL_FLAGS_NONE,
952 BT_ERR("Bt core call failed(Error: %s)", error->message);
953 g_clear_error(&error);
955 BT_ERR("Bt core call failed");
959 g_variant_unref(result);
961 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
963 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
965 if (_bt_adapter_get_status() == BT_DEACTIVATED)
966 _bt_terminate_service(NULL);
971 void _bt_adapter_start_le_enable_timer(void)
973 if (le_timer_id > 0) {
974 g_source_remove(le_timer_id);
978 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
979 __bt_enable_le_timeout_cb, NULL);
984 void _bt_adapter_start_enable_timer(void)
987 g_source_remove(timer_id);
991 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
992 __bt_enable_timeout_cb, NULL);
997 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1002 _bt_adapter_set_status(BT_ACTIVATED);
1008 int _bt_enable_adapter(void)
1011 GError *error = NULL;
1013 GVariant *result = NULL;
1014 bt_status_t status = _bt_adapter_get_status();
1015 bt_le_status_t le_status = _bt_adapter_get_le_status();
1019 if (status == BT_ACTIVATING) {
1020 BT_ERR("Enabling in progress");
1021 return BLUETOOTH_ERROR_IN_PROGRESS;
1024 if (status == BT_ACTIVATED) {
1025 BT_ERR("Already enabled");
1026 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1029 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1030 BT_ERR("Disabling in progress");
1031 return BLUETOOTH_ERROR_DEVICE_BUSY;
1034 _bt_adapter_set_status(BT_ACTIVATING);
1038 int adapter_status = BT_ADAPTER_DISABLED;
1040 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1041 BT_ERR("Set vconf failed");
1043 _bt_check_adapter(&adapter_status);
1044 if (adapter_status == BT_ADAPTER_ENABLED) {
1045 g_idle_add(__bt_adapter_enabled_cb, NULL);
1046 _bt_adapter_start_enable_timer();
1047 return BLUETOOTH_ERROR_NONE;
1052 proxy = __bt_get_core_proxy();
1054 return BLUETOOTH_ERROR_INTERNAL;
1056 if (le_status == BT_LE_ACTIVATED) {
1057 BT_INFO("LE Already enabled. Just turn on PSCAN");
1058 ret = _bt_set_connectable(TRUE);
1059 if (ret == BLUETOOTH_ERROR_NONE) {
1060 _bt_adapter_set_status(BT_ACTIVATED);
1062 return BLUETOOTH_ERROR_INTERNAL;
1066 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1068 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1071 BT_ERR("EnableAdapterLe failed: %s", error->message);
1072 _bt_adapter_set_status(BT_DEACTIVATED);
1073 g_clear_error(&error);
1075 result = g_dbus_proxy_call_sync(proxy,
1078 G_DBUS_CALL_FLAGS_NONE,
1083 if (error != NULL) {
1084 BT_ERR("Bt core call failed(Error: %s)", error->message);
1085 g_clear_error(&error);
1087 g_variant_unref(result);
1088 /* Terminate myself */
1089 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1090 return BLUETOOTH_ERROR_INTERNAL;
1092 g_variant_unref(result);
1094 if (le_status == BT_LE_ACTIVATED) {
1097 _bt_adapter_start_enable_timer();
1100 return BLUETOOTH_ERROR_NONE;
1103 static gboolean __bt_disconnect_all(void)
1106 GDBusConnection *conn;
1107 GDBusProxy *dev_proxy;
1108 gboolean ret = FALSE;
1110 GError *error = NULL;
1111 GArray *device_list;
1112 bluetooth_device_info_t info;
1114 char *device_path = NULL;
1115 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1120 conn = _bt_get_system_gconn();
1122 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1124 if (_bt_get_bonded_devices(&device_list)
1125 != BLUETOOTH_ERROR_NONE) {
1126 g_array_free(device_list, TRUE);
1130 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1132 for (i = 0; i < size; i++) {
1134 info = g_array_index(device_list,
1135 bluetooth_device_info_t, i);
1137 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1138 BT_DBG("Found Connected device");
1139 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1140 device_path = _bt_get_device_object_path(address);
1141 if (device_path == NULL)
1144 BT_DBG("Disconnecting : %s", device_path);
1146 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1150 BT_DEVICE_INTERFACE,
1153 if (dev_proxy == NULL)
1156 result = g_dbus_proxy_call_sync(dev_proxy,
1159 G_DBUS_CALL_FLAGS_NONE,
1165 if (error != NULL) {
1166 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1167 g_clear_error(&error);
1169 BT_ERR("Disconnect call failed");
1170 g_object_unref(dev_proxy);
1174 g_variant_unref(result);
1175 g_object_unref(dev_proxy);
1179 g_array_free(device_list, TRUE);
1184 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1187 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1192 int __bt_disable_cb(void)
1196 bt_le_status_t le_status;
1199 GError *error = NULL;
1201 _bt_adapter_set_status(BT_DEACTIVATING);
1202 le_status = _bt_adapter_get_le_status();
1203 BT_DBG("le_status : %d", le_status);
1204 if (le_status == BT_LE_ACTIVATED) {
1205 BT_INFO("LE is enabled. Just turn off PSCAN");
1207 if (_bt_is_discovering())
1208 _bt_cancel_discovery();
1210 if (_bt_is_connectable() == FALSE) {
1211 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1213 ret = _bt_set_connectable(FALSE);
1214 if (ret != BLUETOOTH_ERROR_NONE) {
1215 BT_ERR("_bt_set_connectable fail!");
1216 _bt_adapter_set_status(BT_ACTIVATED);
1217 return BLUETOOTH_ERROR_INTERNAL;
1222 proxy = __bt_get_core_proxy();
1223 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1225 result = g_dbus_proxy_call_sync(proxy,
1228 G_DBUS_CALL_FLAGS_NONE,
1234 if (error != NULL) {
1235 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1236 g_clear_error(&error);
1238 BT_ERR("Failed to DisableAdapter");
1239 _bt_adapter_set_status(BT_ACTIVATED);
1240 return BLUETOOTH_ERROR_INTERNAL;
1243 g_variant_unref(result);
1245 return BLUETOOTH_ERROR_NONE;
1248 int _bt_disable_adapter(void)
1253 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1254 BT_DBG("Disabling in progress");
1255 return BLUETOOTH_ERROR_IN_PROGRESS;
1258 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1259 BT_DBG("Already disabled");
1260 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1264 g_source_remove(timer_id);
1268 __bt_disconnect_all();
1269 ret = __bt_disable_cb();
1275 int _bt_recover_adapter(void)
1280 GError *error = NULL;
1282 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1283 BT_DBG("Disabling in progress");
1284 return BLUETOOTH_ERROR_IN_PROGRESS;
1287 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1288 BT_DBG("Already disabled");
1289 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1292 _bt_adapter_set_status(BT_DEACTIVATING);
1294 proxy = __bt_get_core_proxy();
1295 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1297 result = g_dbus_proxy_call_sync(proxy,
1300 G_DBUS_CALL_FLAGS_NONE,
1306 if (error != NULL) {
1307 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1308 g_clear_error(&error);
1310 BT_ERR("Failed to RecoverAdapter");
1311 return BLUETOOTH_ERROR_INTERNAL;
1314 g_variant_unref(result);
1315 __bt_disconnect_all();
1318 return BLUETOOTH_ERROR_NONE;
1321 int _bt_reset_adapter(void)
1325 GError *error = NULL;
1329 proxy = __bt_get_core_proxy();
1331 return BLUETOOTH_ERROR_INTERNAL;
1333 result = g_dbus_proxy_call_sync(proxy,
1336 G_DBUS_CALL_FLAGS_NONE,
1342 if (error != NULL) {
1343 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1344 g_clear_error(&error);
1346 BT_ERR("Failed to ResetAdapter");
1347 return BLUETOOTH_ERROR_INTERNAL;
1350 g_variant_unref(result);
1351 /* Terminate myself */
1352 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1353 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1356 return BLUETOOTH_ERROR_NONE;
1360 int _bt_check_adapter(int *status)
1363 char *adapter_path = NULL;
1365 BT_CHECK_PARAMETER(status, return);
1367 *status = BT_ADAPTER_DISABLED;
1369 adapter_path = _bt_get_adapter_path();
1372 if (adapter_path != NULL)
1373 *status = BT_ADAPTER_ENABLED;
1375 g_free(adapter_path);
1376 return BLUETOOTH_ERROR_NONE;
1379 int _bt_check_adapter(int *status)
1382 GError *error = NULL;
1385 gboolean powered = FALSE;
1387 BT_CHECK_PARAMETER(status, return);
1389 *status = BT_ADAPTER_DISABLED;
1391 proxy = _bt_get_adapter_properties_proxy();
1392 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1394 result = g_dbus_proxy_call_sync(proxy,
1396 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1398 G_DBUS_CALL_FLAGS_NONE,
1404 BT_ERR("Failed to get local address");
1405 if (error != NULL) {
1406 BT_ERR("Failed to get local address (Error: %s)", error->message);
1407 g_clear_error(&error);
1409 return BLUETOOTH_ERROR_INTERNAL;
1412 g_variant_get(result, "(v)", &temp);
1413 powered = g_variant_get_boolean(temp);
1414 BT_DBG("powered: %d", powered);
1417 *status = BT_ADAPTER_ENABLED;
1419 g_variant_unref(result);
1420 g_variant_unref(temp);
1421 return BLUETOOTH_ERROR_NONE;
1425 int _bt_enable_adapter_le(void)
1429 GError *error = NULL;
1430 bt_status_t status = _bt_adapter_get_status();
1431 bt_le_status_t le_status = _bt_adapter_get_le_status();
1434 if (le_status == BT_LE_ACTIVATING) {
1435 BT_ERR("Enabling in progress");
1436 return BLUETOOTH_ERROR_IN_PROGRESS;
1439 if (le_status == BT_LE_ACTIVATED) {
1440 BT_ERR("Already enabled");
1441 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1444 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1445 BT_ERR("Disabling in progress");
1446 return BLUETOOTH_ERROR_DEVICE_BUSY;
1449 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1451 proxy = __bt_get_core_proxy();
1452 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1454 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1456 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1459 BT_ERR("EnableAdapterLe failed: %s", error->message);
1460 _bt_adapter_set_le_status(BT_DEACTIVATED);
1461 g_clear_error(&error);
1463 /* Clean up the process */
1464 result = g_dbus_proxy_call_sync(proxy,
1467 G_DBUS_CALL_FLAGS_NONE,
1473 BT_ERR("Bt core call failed");
1475 BT_ERR("EnableAdapterLE Failed %s", error->message);
1476 g_clear_error(&error);
1479 g_variant_unref(result);
1480 /* Terminate myself */
1481 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1482 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1483 return BLUETOOTH_ERROR_INTERNAL;
1487 g_variant_unref(result);
1489 _bt_adapter_start_le_enable_timer();
1491 if (status == BT_ACTIVATED) {
1492 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1493 __bt_set_le_enabled();
1495 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1497 return BLUETOOTH_ERROR_NONE;
1500 int _bt_disable_adapter_le(void)
1504 bt_le_status_t bt_le_state;
1506 GError *error = NULL;
1508 bt_le_state = _bt_adapter_get_le_status();
1509 if (bt_le_state == BT_LE_DEACTIVATING) {
1510 BT_DBG("Disabling in progress");
1511 return BLUETOOTH_ERROR_IN_PROGRESS;
1514 if (bt_le_state == BT_LE_DEACTIVATED) {
1515 BT_DBG("Already disabled");
1516 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1519 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1521 proxy = __bt_get_core_proxy();
1523 return BLUETOOTH_ERROR_INTERNAL;
1525 result = g_dbus_proxy_call_sync(proxy,
1528 G_DBUS_CALL_FLAGS_NONE,
1534 if (error != NULL) {
1535 BT_ERR("Bt core call failed (Error: %s)", error->message);
1536 g_clear_error(&error);
1538 BT_ERR("Bt core call failed");
1539 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1540 return BLUETOOTH_ERROR_INTERNAL;
1543 g_variant_unref(result);
1545 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1546 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1548 return BLUETOOTH_ERROR_NONE;
1551 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1555 GError *error = NULL;
1556 const char *address;
1560 BT_CHECK_PARAMETER(local_address, return);
1562 proxy = _bt_get_adapter_properties_proxy();
1563 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1565 result = g_dbus_proxy_call_sync(proxy,
1567 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1569 G_DBUS_CALL_FLAGS_NONE,
1575 BT_ERR("Failed to get local address");
1576 if (error != NULL) {
1577 BT_ERR("Failed to get local address (Error: %s)", error->message);
1578 g_clear_error(&error);
1580 return BLUETOOTH_ERROR_INTERNAL;
1583 g_variant_get(result, "(v)", &temp);
1584 address = g_variant_get_string(temp, NULL);
1585 BT_DBG("Address:%s", address);
1588 _bt_convert_addr_string_to_type(local_address->addr, address);
1590 return BLUETOOTH_ERROR_INTERNAL;
1593 g_variant_unref(result);
1594 g_variant_unref(temp);
1595 return BLUETOOTH_ERROR_NONE;
1598 int _bt_get_local_version(bluetooth_version_t *local_version)
1601 const char *ver = NULL;
1603 int ret = BLUETOOTH_ERROR_NONE;
1607 BT_CHECK_PARAMETER(local_version, return);
1609 GError *error = NULL;
1611 proxy = _bt_get_adapter_properties_proxy();
1612 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1614 result = g_dbus_proxy_call_sync(proxy,
1616 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1618 G_DBUS_CALL_FLAGS_NONE,
1624 if (error != NULL) {
1625 BT_ERR("Failed to get local version (Error: %s)", error->message);
1626 g_clear_error(&error);
1628 BT_ERR("Failed to get local version");
1629 return BLUETOOTH_ERROR_INTERNAL;
1632 g_variant_get(result, "(v)", &temp);
1633 ver = g_variant_get_string(temp, NULL);
1634 BT_DBG("VERSION: %s", ver);
1636 if (ver && (strlen(ver) > 0)) {
1637 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1638 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1641 g_strlcpy(local_version->version, ver,
1642 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1645 ret = BLUETOOTH_ERROR_INTERNAL;
1648 g_variant_unref(result);
1649 g_variant_unref(temp);
1653 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1656 const char *name = NULL;
1658 int ret = BLUETOOTH_ERROR_NONE;
1661 GError *error = NULL;
1663 BT_CHECK_PARAMETER(local_name, return);
1665 proxy = _bt_get_adapter_properties_proxy();
1666 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1668 result = g_dbus_proxy_call_sync(proxy,
1670 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1672 G_DBUS_CALL_FLAGS_NONE,
1678 if (error != NULL) {
1679 BT_ERR("Failed to get local name (Error: %s)", error->message);
1680 g_clear_error(&error);
1682 BT_ERR("Failed to get local name");
1683 return BLUETOOTH_ERROR_INTERNAL;
1686 g_variant_get(result, "(v)", &temp);
1687 name = g_variant_get_string(temp, NULL);
1688 BT_DBG("LOCAL NAME:%s", name);
1690 if (name && (strlen(name) > 0)) {
1691 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1692 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1695 g_strlcpy(local_name->name, name,
1696 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1698 ret = BLUETOOTH_ERROR_INTERNAL;
1700 g_variant_unref(result);
1701 g_variant_unref(temp);
1705 int _bt_set_local_name(char *local_name)
1708 GError *error = NULL;
1712 BT_CHECK_PARAMETER(local_name, return);
1714 proxy = _bt_get_adapter_properties_proxy();
1716 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1718 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1721 result = g_dbus_proxy_call_sync(proxy,
1723 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1724 "Alias", g_variant_new("s", local_name)),
1725 G_DBUS_CALL_FLAGS_NONE,
1731 if (error != NULL) {
1732 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1733 g_clear_error(&error);
1735 BT_ERR("Failed to set Alias");
1736 return BLUETOOTH_ERROR_INTERNAL;
1739 g_variant_unref(result);
1740 return BLUETOOTH_ERROR_NONE;
1743 int _bt_is_service_used(char *service_uuid, gboolean *used)
1746 GError *error = NULL;
1747 int ret = BLUETOOTH_ERROR_NONE;
1753 BT_CHECK_PARAMETER(service_uuid, return);
1754 BT_CHECK_PARAMETER(used, return);
1756 proxy = _bt_get_adapter_properties_proxy();
1757 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1759 result = g_dbus_proxy_call_sync(proxy,
1761 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1763 G_DBUS_CALL_FLAGS_NONE,
1769 if (error != NULL) {
1770 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1771 g_clear_error(&error);
1773 BT_ERR("Failed to get UUIDs");
1774 return BLUETOOTH_ERROR_INTERNAL;
1777 g_variant_get(result, "as", &iter);
1778 while (g_variant_iter_loop(iter, "s", &uuid)) {
1779 if (strcasecmp(uuid, service_uuid) == 0) {
1789 g_variant_iter_free(iter);
1790 g_variant_unref(result);
1791 BT_DBG("Service Used? %d", *used);
1795 static gboolean __bt_get_discoverable_property(void)
1798 gboolean discoverable_v;
1799 GError *error = NULL;
1803 proxy = _bt_get_adapter_properties_proxy();
1804 retv_if(proxy == NULL, FALSE);
1806 result = g_dbus_proxy_call_sync(proxy,
1808 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1810 G_DBUS_CALL_FLAGS_NONE,
1816 if (error != NULL) {
1817 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1818 g_clear_error(&error);
1820 BT_ERR("Failed to get Discoverable property");
1824 g_variant_get(result, "(v)", &temp);
1825 discoverable_v = g_variant_get_boolean(temp);
1826 BT_DBG("discoverable_v:%d", discoverable_v);
1828 g_variant_unref(result);
1829 g_variant_unref(temp);
1831 return discoverable_v;
1834 int _bt_get_discoverable_mode(int *mode)
1836 gboolean discoverable;
1837 unsigned int timeout;
1839 BT_CHECK_PARAMETER(mode, return);
1841 discoverable = __bt_get_discoverable_property();
1842 timeout = _bt_get_discoverable_timeout_property();
1844 if (discoverable == TRUE) {
1846 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1848 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1850 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1852 return BLUETOOTH_ERROR_NONE;
1856 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1858 int ret = BLUETOOTH_ERROR_NONE;
1861 GError *error = NULL;
1865 proxy = _bt_get_adapter_properties_proxy();
1867 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1869 switch (discoverable_mode) {
1870 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1875 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1880 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1885 return BLUETOOTH_ERROR_INVALID_PARAM;
1888 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1889 discoverable_mode, timeout);
1891 result = g_dbus_proxy_call_sync(proxy,
1893 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1894 "Connectable", g_variant_new("b", pg_scan)),
1895 G_DBUS_CALL_FLAGS_NONE,
1901 if (error != NULL) {
1902 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1903 g_clear_error(&error);
1905 BT_ERR("Failed to set connectable property");
1906 return BLUETOOTH_ERROR_INTERNAL;
1908 g_variant_unref(result);
1909 result = g_dbus_proxy_call_sync(proxy,
1911 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
1912 g_variant_new("b", inq_scan)),
1913 G_DBUS_CALL_FLAGS_NONE,
1919 if (error != NULL) {
1920 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
1921 g_clear_error(&error);
1923 BT_ERR("Failed to set Discoverable property");
1924 return BLUETOOTH_ERROR_INTERNAL;
1926 g_variant_unref(result);
1927 result = g_dbus_proxy_call_sync(proxy,
1929 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1930 "DiscoverableTimeout", g_variant_new("u", timeout)),
1931 G_DBUS_CALL_FLAGS_NONE,
1937 if (error != NULL) {
1938 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
1939 g_clear_error(&error);
1941 BT_ERR("Failed to set DiscoverableTimeout property");
1942 return BLUETOOTH_ERROR_INTERNAL;
1945 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1948 ret = __bt_set_visible_time(timeout);
1950 g_variant_unref(result);
1955 int _bt_start_discovery(void)
1958 GError *error = NULL;
1961 if (_bt_is_discovering() == TRUE) {
1962 BT_ERR("BT is already in discovering");
1963 return BLUETOOTH_ERROR_IN_PROGRESS;
1964 } else if (_bt_is_device_creating() == TRUE) {
1965 BT_ERR("Bonding device is going on");
1966 return BLUETOOTH_ERROR_DEVICE_BUSY;
1969 proxy = _bt_get_adapter_proxy();
1970 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1972 result = g_dbus_proxy_call_sync(proxy,
1975 G_DBUS_CALL_FLAGS_NONE,
1981 if (error != NULL) {
1982 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
1983 g_clear_error(&error);
1985 BT_ERR("StartDiscovery failed");
1986 return BLUETOOTH_ERROR_INTERNAL;
1989 is_discovering = TRUE;
1990 cancel_by_user = FALSE;
1991 /* discovery status will be change in event */
1992 g_variant_unref(result);
1993 return BLUETOOTH_ERROR_NONE;
1996 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2000 GError *error = NULL;
2001 const gchar *disc_type;
2003 if (_bt_is_discovering() == TRUE) {
2004 BT_ERR("BT is already in discovering");
2005 return BLUETOOTH_ERROR_IN_PROGRESS;
2008 proxy = _bt_get_adapter_proxy();
2009 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2011 if (role == DISCOVERY_ROLE_BREDR)
2012 disc_type = "BREDR";
2013 else if (role == DISCOVERY_ROLE_LE)
2015 else if (role == DISCOVERY_ROLE_LE_BREDR)
2016 disc_type = "LE_BREDR";
2018 return BLUETOOTH_ERROR_INVALID_PARAM;
2020 result = g_dbus_proxy_call_sync(proxy,
2021 "StartCustomDiscovery",
2022 g_variant_new("s", disc_type),
2023 G_DBUS_CALL_FLAGS_NONE,
2029 if (error != NULL) {
2030 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2031 g_clear_error(&error);
2033 BT_ERR("StartCustomDiscovery failed");
2034 return BLUETOOTH_ERROR_INTERNAL;
2037 is_discovering = TRUE;
2038 cancel_by_user = FALSE;
2039 /* discovery status will be change in event */
2040 g_variant_unref(result);
2041 return BLUETOOTH_ERROR_NONE;
2044 int _bt_cancel_discovery(void)
2047 GError *error = NULL;
2050 if (_bt_is_discovering() == FALSE) {
2051 BT_ERR("BT is not in discovering");
2052 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2055 proxy = _bt_get_adapter_proxy();
2056 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2058 result = g_dbus_proxy_call_sync(proxy,
2061 G_DBUS_CALL_FLAGS_NONE,
2067 if (error != NULL) {
2068 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2069 g_clear_error(&error);
2071 BT_ERR("StopDiscovery failed");
2072 return BLUETOOTH_ERROR_INTERNAL;
2075 cancel_by_user = TRUE;
2076 /* discovery status will be change in event */
2077 g_variant_unref(result);
2078 return BLUETOOTH_ERROR_NONE;
2081 gboolean _bt_is_discovering(void)
2083 return is_discovering;
2086 gboolean _bt_is_connectable(void)
2089 GError *error = NULL;
2090 gboolean is_connectable = FALSE;
2094 proxy = _bt_get_adapter_properties_proxy();
2095 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2097 result = g_dbus_proxy_call_sync(proxy,
2099 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2101 G_DBUS_CALL_FLAGS_NONE,
2107 if (error != NULL) {
2108 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2109 g_clear_error(&error);
2111 BT_ERR("Failed to get connectable property");
2112 return BLUETOOTH_ERROR_INTERNAL;
2115 g_variant_get(result, "(v)", &temp);
2116 is_connectable = g_variant_get_boolean(temp);
2117 BT_DBG("discoverable_v:%d", is_connectable);
2119 g_variant_unref(result);
2120 g_variant_unref(temp);
2122 BT_INFO("Get connectable [%d]", is_connectable);
2123 return is_connectable;
2126 int _bt_set_connectable(gboolean is_connectable)
2129 GError *error = NULL;
2132 if (__bt_is_factory_test_mode()) {
2133 BT_ERR("Unable to set connectable in factory binary !!");
2134 return BLUETOOTH_ERROR_NOT_SUPPORT;
2137 proxy = _bt_get_adapter_properties_proxy();
2139 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2141 result = g_dbus_proxy_call_sync(proxy,
2143 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2144 g_variant_new("b", is_connectable)),
2145 G_DBUS_CALL_FLAGS_NONE,
2151 if (error != NULL) {
2152 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2153 g_clear_error(&error);
2155 BT_ERR("Failed to set connectable property");
2156 return BLUETOOTH_ERROR_INTERNAL;
2159 BT_INFO("Set connectable [%d]", is_connectable);
2160 g_variant_unref(result);
2161 return BLUETOOTH_ERROR_NONE;
2164 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2167 gboolean discovering_v;
2168 GError *error = NULL;
2169 char *discovering_type = NULL;
2173 proxy = _bt_get_adapter_properties_proxy();
2174 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2176 if (discovery_type == DISCOVERY_ROLE_BREDR)
2177 discovering_type = "Discovering";
2178 else if (discovery_type == DISCOVERY_ROLE_LE)
2179 discovering_type = "LEDiscovering";
2181 result = g_dbus_proxy_call_sync(proxy,
2183 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2185 G_DBUS_CALL_FLAGS_NONE,
2191 if (error != NULL) {
2192 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2193 g_clear_error(&error);
2195 BT_ERR("Failed to get discovering property");
2196 return BLUETOOTH_ERROR_INTERNAL;
2199 g_variant_get(result, "(v)", &temp);
2200 discovering_v = g_variant_get_boolean(temp);
2201 BT_DBG("discoverable_v:%d", discovering_v);
2203 g_variant_unref(result);
2204 g_variant_unref(temp);
2206 return discovering_v;
2209 unsigned int _bt_get_discoverable_timeout_property(void)
2212 unsigned int timeout_v;
2213 GError *error = NULL;
2217 proxy = _bt_get_adapter_properties_proxy();
2218 retv_if(proxy == NULL, 0);
2220 result = g_dbus_proxy_call_sync(proxy,
2222 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2223 "DiscoverableTimeout"),
2224 G_DBUS_CALL_FLAGS_NONE,
2230 BT_ERR("Fail to get discoverable timeout");
2231 if (error != NULL) {
2232 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2233 g_clear_error(&error);
2238 g_variant_get(result, "(v)", &temp);
2239 timeout_v = g_variant_get_uint32(temp);
2240 BT_DBG("discoverable_v:%d", timeout_v);
2242 g_variant_unref(result);
2243 g_variant_unref(temp);
2248 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2250 bluetooth_device_info_t *dev_info;
2253 GByteArray *manufacturer_data = NULL;
2255 GVariantIter *char_value_iter;
2257 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2259 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2264 if (!g_strcmp0(key, "Address")) {
2265 const char *address = NULL;
2266 address = g_variant_get_string(value, NULL);
2267 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2269 } else if(!g_strcmp0(key, "Class")) {
2271 cod = g_variant_get_uint32(value);
2272 _bt_divide_device_class(&dev_info->device_class, cod);
2273 } else if(!g_strcmp0(key, "Name")) {
2274 const char *name = NULL;
2275 name = g_variant_get_string(value, NULL);
2276 /* If there is no Alias */
2277 if (strlen(dev_info->device_name.name) == 0) {
2278 g_strlcpy(dev_info->device_name.name, name,
2279 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2281 } else if(!g_strcmp0(key, "Alias")) {
2282 const char *alias = NULL;
2283 alias = g_variant_get_string(value, NULL);
2284 /* Overwrite the name */
2286 memset(dev_info->device_name.name, 0x00,
2287 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2288 g_strlcpy(dev_info->device_name.name, alias,
2289 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2291 } else if (!g_strcmp0(key, "Connected")) {
2292 dev_info->connected = g_variant_get_byte(value);
2293 } else if (!g_strcmp0(key, "Paired")) {
2294 dev_info->paired = g_variant_get_boolean(value);
2295 } else if (!g_strcmp0(key, "Trusted")) {
2296 dev_info->trust = g_variant_get_boolean(value);
2297 } else if (!g_strcmp0(key, "RSSI")) {
2298 dev_info->rssi = g_variant_get_int16(value);
2299 } else if (!g_strcmp0(key, "UUIDs")) {
2305 dev_info->service_index = 0;
2306 g_variant_get(value, "as", &iter);
2307 while (g_variant_iter_loop(iter, "s", &uuid)) {
2308 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2309 parts = g_strsplit(uuid, "-", -1);
2311 if (parts == NULL || parts[0] == NULL) {
2316 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2321 dev_info->service_index = i;
2322 g_variant_iter_free(iter);
2323 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2324 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2325 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2326 manufacturer_data = g_byte_array_new();
2327 g_variant_get(value, "ay", &char_value_iter);
2328 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
2329 g_byte_array_append(manufacturer_data, &char_value, 1);
2331 if (manufacturer_data) {
2332 if (manufacturer_data->len > 0) {
2333 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2336 g_variant_iter_free(char_value_iter);
2337 g_byte_array_free(manufacturer_data, TRUE);
2344 static void __bt_extract_device_info(GVariantIter *iter,
2347 bluetooth_device_info_t *dev_info = NULL;
2348 char *object_path = NULL;
2349 GVariantIter *interface_iter;
2350 GVariantIter *svc_iter;
2351 char *interface_str = NULL;
2353 /* Parse the signature: oa{sa{sv}}} */
2354 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2357 if (object_path == NULL)
2360 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2361 &interface_str, &svc_iter)) {
2362 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2363 BT_DBG("Found a device: %s", object_path);
2364 dev_info = __bt_parse_device_info(svc_iter);
2366 if (dev_info->paired == TRUE) {
2367 g_array_append_vals(*dev_list, dev_info,
2368 sizeof(bluetooth_device_info_t));
2372 g_free(interface_str);
2373 g_variant_iter_free(svc_iter);
2381 int _bt_get_bonded_devices(GArray **dev_list)
2384 GDBusConnection *conn;
2385 GDBusProxy *manager_proxy;
2386 GVariant *result = NULL;
2387 GVariantIter *iter = NULL;
2388 GError *error = NULL;
2390 conn = _bt_get_system_conn();
2391 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2393 manager_proxy = _bt_get_manager_proxy();
2394 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2396 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2398 G_DBUS_CALL_FLAGS_NONE,
2404 if (error != NULL) {
2405 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2406 g_clear_error(&error);
2408 BT_ERR("Failed to Failed to GetManagedObjects");
2409 return BLUETOOTH_ERROR_INTERNAL;
2412 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2413 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2415 __bt_extract_device_info(iter, dev_list);
2416 g_variant_iter_free(iter);
2417 g_variant_unref(result);
2420 return BLUETOOTH_ERROR_NONE;
2423 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2424 bluetooth_device_info_t *dev_info)
2426 char *object_path = NULL;
2427 GDBusProxy *adapter_proxy;
2428 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2429 int ret = BLUETOOTH_ERROR_NONE;
2431 BT_CHECK_PARAMETER(device_address, return);
2432 BT_CHECK_PARAMETER(dev_info, return);
2434 adapter_proxy = _bt_get_adapter_proxy();
2435 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2437 _bt_convert_addr_type_to_string(address, device_address->addr);
2439 object_path = _bt_get_device_object_path(address);
2441 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2443 ret = __bt_get_bonded_device_info(object_path, dev_info);
2444 g_free(object_path);
2449 int _bt_get_timeout_value(int *timeout)
2451 time_t current_time;
2454 /* Take current time */
2455 time(¤t_time);
2456 time_diff = difftime(current_time, visible_timer.start_time);
2458 BT_DBG("Time diff = %d\n", time_diff);
2460 *timeout = visible_timer.timeout - time_diff;
2462 return BLUETOOTH_ERROR_NONE;
2465 int _bt_set_le_privacy(gboolean set_privacy)
2468 GError *error = NULL;
2469 GVariant *result = NULL;
2471 if (__bt_is_factory_test_mode()) {
2472 BT_ERR("Unable to set le privacy in factory binary !!");
2473 return BLUETOOTH_ERROR_NOT_SUPPORT;
2476 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2477 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2478 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2481 proxy = _bt_get_adapter_proxy();
2482 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2484 result = g_dbus_proxy_call_sync(proxy,
2486 g_variant_new("(b)", set_privacy),
2487 G_DBUS_CALL_FLAGS_NONE,
2493 if (error != NULL) {
2494 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2495 g_clear_error(&error);
2497 BT_ERR("Failed to SetLePrivacy");
2498 return BLUETOOTH_ERROR_INTERNAL;
2501 g_variant_unref(result);
2502 BT_INFO("SetLePrivacy as %d", set_privacy);
2503 return BLUETOOTH_ERROR_NONE;
2506 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2509 GError *error = NULL;
2513 GVariantBuilder *builder;
2515 BT_CHECK_PARAMETER(m_data, return);
2517 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2518 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2519 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2522 proxy = _bt_get_adapter_proxy();
2523 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2525 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2527 for (i = 0; i < (m_data->data_len) + 2; i++) {
2528 g_variant_builder_add(builder, "y", m_data->data[i]);
2531 val = g_variant_new("(ay)", builder);
2533 result = g_dbus_proxy_call_sync(proxy,
2534 "SetManufacturerData",
2536 G_DBUS_CALL_FLAGS_NONE,
2540 g_variant_builder_unref(builder);
2542 if (error != NULL) {
2543 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2544 g_clear_error(&error);
2546 BT_ERR("Failed to SetManufacturerData");
2548 return BLUETOOTH_ERROR_INTERNAL;
2550 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2552 for (i = 0; i < (m_data->data_len) + 2; i++) {
2553 g_variant_builder_add(builder, "y", m_data->data[i]);
2556 val = g_variant_new("(ay)", builder);
2558 _bt_send_event(BT_ADAPTER_EVENT,
2559 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2562 BT_INFO("Set manufacturer data");
2564 g_variant_builder_unref(builder);
2565 g_variant_unref(result);
2567 return BLUETOOTH_ERROR_NONE;
2570 int _bt_get_enable_timer_id(void)