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_WEARABLEi
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 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);
1025 proxy = __bt_get_core_proxy();
1027 return BLUETOOTH_ERROR_INTERNAL;
1029 if (le_status == BT_LE_ACTIVATED) {
1030 BT_INFO("LE Already enabled. Just turn on PSCAN");
1031 ret = _bt_set_connectable(TRUE);
1032 if (ret == BLUETOOTH_ERROR_NONE) {
1033 _bt_adapter_set_status(BT_ACTIVATED);
1035 return BLUETOOTH_ERROR_INTERNAL;
1039 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1041 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1044 BT_ERR("EnableAdapterLe failed: %s", error->message);
1045 _bt_adapter_set_status(BT_DEACTIVATED);
1046 g_clear_error(&error);
1048 result = g_dbus_proxy_call_sync(proxy,
1051 G_DBUS_CALL_FLAGS_NONE,
1056 if (error != NULL) {
1057 BT_ERR("Bt core call failed(Error: %s)", error->message);
1058 g_clear_error(&error);
1060 g_variant_unref(result);
1061 /* Terminate myself */
1062 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1063 return BLUETOOTH_ERROR_INTERNAL;
1065 g_variant_unref(result);
1067 if (le_status == BT_LE_ACTIVATED) {
1070 _bt_adapter_start_enable_timer();
1073 return BLUETOOTH_ERROR_NONE;
1076 static gboolean __bt_disconnect_all(void)
1079 GDBusConnection *conn;
1080 GDBusProxy *dev_proxy;
1081 gboolean ret = FALSE;
1083 GError *error = NULL;
1084 GArray *device_list;
1085 bluetooth_device_info_t info;
1087 char *device_path = NULL;
1088 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1093 conn = _bt_get_system_gconn();
1095 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1097 if (_bt_get_bonded_devices(&device_list)
1098 != BLUETOOTH_ERROR_NONE) {
1099 g_array_free(device_list, TRUE);
1103 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1105 for (i = 0; i < size; i++) {
1107 info = g_array_index(device_list,
1108 bluetooth_device_info_t, i);
1110 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1111 BT_DBG("Found Connected device");
1112 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1113 device_path = _bt_get_device_object_path(address);
1114 if (device_path == NULL)
1117 BT_DBG("Disconnecting : %s", device_path);
1119 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1123 BT_DEVICE_INTERFACE,
1126 if (dev_proxy == NULL)
1129 result = g_dbus_proxy_call_sync(dev_proxy,
1132 G_DBUS_CALL_FLAGS_NONE,
1138 if (error != NULL) {
1139 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1140 g_clear_error(&error);
1142 BT_ERR("Disconnect call failed");
1143 g_object_unref(dev_proxy);
1147 g_variant_unref(result);
1148 g_object_unref(dev_proxy);
1152 g_array_free(device_list, TRUE);
1157 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1160 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1165 int __bt_disable_cb(void)
1169 bt_le_status_t le_status;
1172 GError *error = NULL;
1174 _bt_adapter_set_status(BT_DEACTIVATING);
1175 le_status = _bt_adapter_get_le_status();
1176 BT_DBG("le_status : %d", le_status);
1177 if (le_status == BT_LE_ACTIVATED) {
1178 BT_INFO("LE is enabled. Just turn off PSCAN");
1180 if (_bt_is_discovering())
1181 _bt_cancel_discovery();
1183 if (_bt_is_connectable() == FALSE) {
1184 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1186 ret = _bt_set_connectable(FALSE);
1187 if (ret != BLUETOOTH_ERROR_NONE) {
1188 BT_ERR("_bt_set_connectable fail!");
1189 _bt_adapter_set_status(BT_ACTIVATED);
1190 return BLUETOOTH_ERROR_INTERNAL;
1195 proxy = __bt_get_core_proxy();
1196 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1198 result = g_dbus_proxy_call_sync(proxy,
1201 G_DBUS_CALL_FLAGS_NONE,
1207 if (error != NULL) {
1208 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1209 g_clear_error(&error);
1211 BT_ERR("Failed to DisableAdapter");
1212 _bt_adapter_set_status(BT_ACTIVATED);
1213 return BLUETOOTH_ERROR_INTERNAL;
1216 g_variant_unref(result);
1218 return BLUETOOTH_ERROR_NONE;
1221 int _bt_disable_adapter(void)
1226 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1227 BT_DBG("Disabling in progress");
1228 return BLUETOOTH_ERROR_IN_PROGRESS;
1231 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1232 BT_DBG("Already disabled");
1233 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1237 g_source_remove(timer_id);
1241 __bt_disconnect_all();
1242 ret = __bt_disable_cb();
1248 int _bt_recover_adapter(void)
1253 GError *error = NULL;
1255 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1256 BT_DBG("Disabling in progress");
1257 return BLUETOOTH_ERROR_IN_PROGRESS;
1260 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1261 BT_DBG("Already disabled");
1262 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1265 _bt_adapter_set_status(BT_DEACTIVATING);
1267 proxy = __bt_get_core_proxy();
1268 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1270 result = g_dbus_proxy_call_sync(proxy,
1273 G_DBUS_CALL_FLAGS_NONE,
1279 if (error != NULL) {
1280 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1281 g_clear_error(&error);
1283 BT_ERR("Failed to RecoverAdapter");
1284 return BLUETOOTH_ERROR_INTERNAL;
1287 g_variant_unref(result);
1288 __bt_disconnect_all();
1291 return BLUETOOTH_ERROR_NONE;
1294 int _bt_reset_adapter(void)
1298 GError *error = NULL;
1302 proxy = __bt_get_core_proxy();
1304 return BLUETOOTH_ERROR_INTERNAL;
1306 result = g_dbus_proxy_call_sync(proxy,
1309 G_DBUS_CALL_FLAGS_NONE,
1315 if (error != NULL) {
1316 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1317 g_clear_error(&error);
1319 BT_ERR("Failed to ResetAdapter");
1320 return BLUETOOTH_ERROR_INTERNAL;
1323 g_variant_unref(result);
1324 /* Terminate myself */
1325 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1326 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1329 return BLUETOOTH_ERROR_NONE;
1332 int _bt_check_adapter(int *status)
1335 char *adapter_path = NULL;
1337 BT_CHECK_PARAMETER(status, return);
1339 *status = BT_ADAPTER_DISABLED;
1341 adapter_path = _bt_get_adapter_path();
1344 if (adapter_path != NULL)
1345 *status = BT_ADAPTER_ENABLED;
1347 g_free(adapter_path);
1348 return BLUETOOTH_ERROR_NONE;
1351 int _bt_enable_adapter_le(void)
1355 GError *error = NULL;
1356 bt_status_t status = _bt_adapter_get_status();
1357 bt_le_status_t le_status = _bt_adapter_get_le_status();
1360 if (le_status == BT_LE_ACTIVATING) {
1361 BT_ERR("Enabling in progress");
1362 return BLUETOOTH_ERROR_IN_PROGRESS;
1365 if (le_status == BT_LE_ACTIVATED) {
1366 BT_ERR("Already enabled");
1367 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1370 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1371 BT_ERR("Disabling in progress");
1372 return BLUETOOTH_ERROR_DEVICE_BUSY;
1375 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1377 proxy = __bt_get_core_proxy();
1378 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1380 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1382 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1385 BT_ERR("EnableAdapterLe failed: %s", error->message);
1386 _bt_adapter_set_le_status(BT_DEACTIVATED);
1387 g_clear_error(&error);
1389 /* Clean up the process */
1390 result = g_dbus_proxy_call_sync(proxy,
1393 G_DBUS_CALL_FLAGS_NONE,
1399 BT_ERR("Bt core call failed");
1401 BT_ERR("EnableAdapterLE Failed %s", error->message);
1402 g_clear_error(&error);
1405 g_variant_unref(result);
1406 /* Terminate myself */
1407 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1408 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1409 return BLUETOOTH_ERROR_INTERNAL;
1413 g_variant_unref(result);
1415 _bt_adapter_start_le_enable_timer();
1417 if (status == BT_ACTIVATED) {
1418 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1419 __bt_set_le_enabled();
1421 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1423 return BLUETOOTH_ERROR_NONE;
1426 int _bt_disable_adapter_le(void)
1430 bt_le_status_t bt_le_state;
1432 GError *error = NULL;
1434 bt_le_state = _bt_adapter_get_le_status();
1435 if (bt_le_state == BT_LE_DEACTIVATING) {
1436 BT_DBG("Disabling in progress");
1437 return BLUETOOTH_ERROR_IN_PROGRESS;
1440 if (bt_le_state == BT_LE_DEACTIVATED) {
1441 BT_DBG("Already disabled");
1442 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1445 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1447 proxy = __bt_get_core_proxy();
1449 return BLUETOOTH_ERROR_INTERNAL;
1451 result = g_dbus_proxy_call_sync(proxy,
1454 G_DBUS_CALL_FLAGS_NONE,
1460 if (error != NULL) {
1461 BT_ERR("Bt core call failed (Error: %s)", error->message);
1462 g_clear_error(&error);
1464 BT_ERR("Bt core call failed");
1465 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1466 return BLUETOOTH_ERROR_INTERNAL;
1469 g_variant_unref(result);
1471 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1472 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1474 return BLUETOOTH_ERROR_NONE;
1477 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1481 GError *error = NULL;
1482 const char *address;
1486 BT_CHECK_PARAMETER(local_address, return);
1488 proxy = _bt_get_adapter_properties_proxy();
1489 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1491 result = g_dbus_proxy_call_sync(proxy,
1493 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1495 G_DBUS_CALL_FLAGS_NONE,
1501 BT_ERR("Failed to get local address");
1502 if (error != NULL) {
1503 BT_ERR("Failed to get local address (Error: %s)", error->message);
1504 g_clear_error(&error);
1506 return BLUETOOTH_ERROR_INTERNAL;
1509 g_variant_get(result, "(v)", &temp);
1510 address = g_variant_get_string(temp, NULL);
1511 BT_DBG("Address:%s", address);
1514 _bt_convert_addr_string_to_type(local_address->addr, address);
1516 return BLUETOOTH_ERROR_INTERNAL;
1519 g_variant_unref(result);
1520 g_variant_unref(temp);
1521 return BLUETOOTH_ERROR_NONE;
1524 int _bt_get_local_version(bluetooth_version_t *local_version)
1527 const char *ver = NULL;
1529 int ret = BLUETOOTH_ERROR_NONE;
1533 BT_CHECK_PARAMETER(local_version, return);
1535 GError *error = NULL;
1537 proxy = _bt_get_adapter_properties_proxy();
1538 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1540 result = g_dbus_proxy_call_sync(proxy,
1542 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1544 G_DBUS_CALL_FLAGS_NONE,
1550 if (error != NULL) {
1551 BT_ERR("Failed to get local version (Error: %s)", error->message);
1552 g_clear_error(&error);
1554 BT_ERR("Failed to get local version");
1555 return BLUETOOTH_ERROR_INTERNAL;
1558 g_variant_get(result, "(v)", &temp);
1559 ver = g_variant_get_string(temp, NULL);
1560 BT_DBG("VERSION: %s", ver);
1562 if (ver && (strlen(ver) > 0)) {
1563 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1564 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1567 g_strlcpy(local_version->version, ver,
1568 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1571 ret = BLUETOOTH_ERROR_INTERNAL;
1574 g_variant_unref(result);
1575 g_variant_unref(temp);
1579 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1582 const char *name = NULL;
1584 int ret = BLUETOOTH_ERROR_NONE;
1587 GError *error = NULL;
1589 BT_CHECK_PARAMETER(local_name, return);
1591 proxy = _bt_get_adapter_properties_proxy();
1592 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1594 result = g_dbus_proxy_call_sync(proxy,
1596 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1598 G_DBUS_CALL_FLAGS_NONE,
1604 if (error != NULL) {
1605 BT_ERR("Failed to get local name (Error: %s)", error->message);
1606 g_clear_error(&error);
1608 BT_ERR("Failed to get local name");
1609 return BLUETOOTH_ERROR_INTERNAL;
1612 g_variant_get(result, "(v)", &temp);
1613 name = g_variant_get_string(temp, NULL);
1614 BT_DBG("LOCAL NAME:%s", name);
1616 if (name && (strlen(name) > 0)) {
1617 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1618 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1621 g_strlcpy(local_name->name, name,
1622 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1624 ret = BLUETOOTH_ERROR_INTERNAL;
1626 g_variant_unref(result);
1627 g_variant_unref(temp);
1631 int _bt_set_local_name(char *local_name)
1634 GError *error = NULL;
1638 BT_CHECK_PARAMETER(local_name, return);
1640 proxy = _bt_get_adapter_properties_proxy();
1642 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1644 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1647 result = g_dbus_proxy_call_sync(proxy,
1649 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1650 "Alias", g_variant_new("s", local_name)),
1651 G_DBUS_CALL_FLAGS_NONE,
1657 if (error != NULL) {
1658 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1659 g_clear_error(&error);
1661 BT_ERR("Failed to set Alias");
1662 return BLUETOOTH_ERROR_INTERNAL;
1665 g_variant_unref(result);
1666 return BLUETOOTH_ERROR_NONE;
1669 int _bt_is_service_used(char *service_uuid, gboolean *used)
1672 GError *error = NULL;
1673 int ret = BLUETOOTH_ERROR_NONE;
1679 BT_CHECK_PARAMETER(service_uuid, return);
1680 BT_CHECK_PARAMETER(used, return);
1682 proxy = _bt_get_adapter_properties_proxy();
1683 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1685 result = g_dbus_proxy_call_sync(proxy,
1687 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1689 G_DBUS_CALL_FLAGS_NONE,
1695 if (error != NULL) {
1696 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1697 g_clear_error(&error);
1699 BT_ERR("Failed to get UUIDs");
1700 return BLUETOOTH_ERROR_INTERNAL;
1703 g_variant_get(result, "as", &iter);
1704 while (g_variant_iter_loop(iter, "s", &uuid)) {
1705 if (strcasecmp(uuid, service_uuid) == 0) {
1715 g_variant_iter_free(iter);
1716 g_variant_unref(result);
1717 BT_DBG("Service Used? %d", *used);
1721 static gboolean __bt_get_discoverable_property(void)
1724 gboolean discoverable_v;
1725 GError *error = NULL;
1729 proxy = _bt_get_adapter_properties_proxy();
1730 retv_if(proxy == NULL, FALSE);
1732 result = g_dbus_proxy_call_sync(proxy,
1734 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1736 G_DBUS_CALL_FLAGS_NONE,
1742 if (error != NULL) {
1743 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1744 g_clear_error(&error);
1746 BT_ERR("Failed to get Discoverable property");
1747 return BLUETOOTH_ERROR_INTERNAL;
1750 g_variant_get(result, "(v)", &temp);
1751 discoverable_v = g_variant_get_boolean(temp);
1752 BT_DBG("discoverable_v:%d", discoverable_v);
1754 g_variant_unref(result);
1755 g_variant_unref(temp);
1757 return discoverable_v;
1760 int _bt_get_discoverable_mode(int *mode)
1762 gboolean discoverable;
1763 unsigned int timeout;
1765 BT_CHECK_PARAMETER(mode, return);
1767 discoverable = __bt_get_discoverable_property();
1768 timeout = _bt_get_discoverable_timeout_property();
1770 if (discoverable == TRUE) {
1772 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1774 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1776 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1778 return BLUETOOTH_ERROR_NONE;
1782 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1784 int ret = BLUETOOTH_ERROR_NONE;
1787 GError *error = NULL;
1791 proxy = _bt_get_adapter_properties_proxy();
1793 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1795 switch (discoverable_mode) {
1796 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1801 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1806 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1811 return BLUETOOTH_ERROR_INVALID_PARAM;
1814 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1815 discoverable_mode, timeout);
1817 result = g_dbus_proxy_call_sync(proxy,
1819 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1820 "Connectable", g_variant_new("b", pg_scan)),
1821 G_DBUS_CALL_FLAGS_NONE,
1827 if (error != NULL) {
1828 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1829 g_clear_error(&error);
1831 BT_ERR("Failed to set connectable property");
1832 return BLUETOOTH_ERROR_INTERNAL;
1834 g_variant_unref(result);
1835 result = g_dbus_proxy_call_sync(proxy,
1837 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
1838 g_variant_new("b", inq_scan)),
1839 G_DBUS_CALL_FLAGS_NONE,
1845 if (error != NULL) {
1846 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
1847 g_clear_error(&error);
1849 BT_ERR("Failed to set Discoverable property");
1850 return BLUETOOTH_ERROR_INTERNAL;
1852 g_variant_unref(result);
1853 result = g_dbus_proxy_call_sync(proxy,
1855 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1856 "DiscoverableTimeout", g_variant_new("u", timeout)),
1857 G_DBUS_CALL_FLAGS_NONE,
1863 if (error != NULL) {
1864 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
1865 g_clear_error(&error);
1867 BT_ERR("Failed to set DiscoverableTimeout property");
1868 return BLUETOOTH_ERROR_INTERNAL;
1871 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1874 ret = __bt_set_visible_time(timeout);
1876 g_variant_unref(result);
1881 int _bt_start_discovery(void)
1884 GError *error = NULL;
1887 if (_bt_is_discovering() == TRUE) {
1888 BT_ERR("BT is already in discovering");
1889 return BLUETOOTH_ERROR_IN_PROGRESS;
1890 } else if (_bt_is_device_creating() == TRUE) {
1891 BT_ERR("Bonding device is going on");
1892 return BLUETOOTH_ERROR_DEVICE_BUSY;
1895 proxy = _bt_get_adapter_proxy();
1896 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1898 result = g_dbus_proxy_call_sync(proxy,
1901 G_DBUS_CALL_FLAGS_NONE,
1907 if (error != NULL) {
1908 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
1909 g_clear_error(&error);
1911 BT_ERR("StartDiscovery failed");
1912 return BLUETOOTH_ERROR_INTERNAL;
1915 is_discovering = TRUE;
1916 cancel_by_user = FALSE;
1917 /* discovery status will be change in event */
1918 g_variant_unref(result);
1919 return BLUETOOTH_ERROR_NONE;
1922 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
1926 GError *error = NULL;
1927 const gchar *disc_type;
1929 if (_bt_is_discovering() == TRUE) {
1930 BT_ERR("BT is already in discovering");
1931 return BLUETOOTH_ERROR_IN_PROGRESS;
1934 proxy = _bt_get_adapter_proxy();
1935 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1937 if (role == DISCOVERY_ROLE_BREDR)
1938 disc_type = "BREDR";
1939 else if (role == DISCOVERY_ROLE_LE)
1941 else if (role == DISCOVERY_ROLE_LE_BREDR)
1942 disc_type = "LE_BREDR";
1944 return BLUETOOTH_ERROR_INVALID_PARAM;
1946 result = g_dbus_proxy_call_sync(proxy,
1947 "StartCustomDiscovery",
1948 g_variant_new("s", disc_type),
1949 G_DBUS_CALL_FLAGS_NONE,
1955 if (error != NULL) {
1956 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
1957 g_clear_error(&error);
1959 BT_ERR("StartCustomDiscovery failed");
1960 return BLUETOOTH_ERROR_INTERNAL;
1963 is_discovering = TRUE;
1964 cancel_by_user = FALSE;
1965 /* discovery status will be change in event */
1966 g_variant_unref(result);
1967 return BLUETOOTH_ERROR_NONE;
1970 int _bt_cancel_discovery(void)
1973 GError *error = NULL;
1976 if (_bt_is_discovering() == FALSE) {
1977 BT_ERR("BT is not in discovering");
1978 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1981 proxy = _bt_get_adapter_proxy();
1982 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1984 result = g_dbus_proxy_call_sync(proxy,
1987 G_DBUS_CALL_FLAGS_NONE,
1993 if (error != NULL) {
1994 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
1995 g_clear_error(&error);
1997 BT_ERR("StopDiscovery failed");
1998 return BLUETOOTH_ERROR_INTERNAL;
2001 cancel_by_user = TRUE;
2002 /* discovery status will be change in event */
2003 g_variant_unref(result);
2004 return BLUETOOTH_ERROR_NONE;
2007 gboolean _bt_is_discovering(void)
2009 return is_discovering;
2012 gboolean _bt_is_connectable(void)
2015 GError *error = NULL;
2016 gboolean is_connectable = FALSE;
2020 proxy = _bt_get_adapter_properties_proxy();
2021 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2023 result = g_dbus_proxy_call_sync(proxy,
2025 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2027 G_DBUS_CALL_FLAGS_NONE,
2033 if (error != NULL) {
2034 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2035 g_clear_error(&error);
2037 BT_ERR("Failed to get connectable property");
2038 return BLUETOOTH_ERROR_INTERNAL;
2041 g_variant_get(result, "(v)", &temp);
2042 is_connectable = g_variant_get_boolean(temp);
2043 BT_DBG("discoverable_v:%d", is_connectable);
2045 g_variant_unref(result);
2046 g_variant_unref(temp);
2048 BT_INFO("Get connectable [%d]", is_connectable);
2049 return is_connectable;
2052 int _bt_set_connectable(gboolean is_connectable)
2055 GError *error = NULL;
2058 if (__bt_is_factory_test_mode()) {
2059 BT_ERR("Unable to set connectable in factory binary !!");
2060 return BLUETOOTH_ERROR_NOT_SUPPORT;
2063 proxy = _bt_get_adapter_properties_proxy();
2065 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2067 result = g_dbus_proxy_call_sync(proxy,
2069 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2070 g_variant_new("b", is_connectable)),
2071 G_DBUS_CALL_FLAGS_NONE,
2077 if (error != NULL) {
2078 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2079 g_clear_error(&error);
2081 BT_ERR("Failed to set connectable property");
2082 return BLUETOOTH_ERROR_INTERNAL;
2085 BT_INFO("Set connectable [%d]", is_connectable);
2086 g_variant_unref(result);
2087 return BLUETOOTH_ERROR_NONE;
2090 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2093 gboolean discovering_v;
2094 GError *error = NULL;
2095 char *discovering_type = NULL;
2099 proxy = _bt_get_adapter_properties_proxy();
2100 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2102 if (discovery_type == DISCOVERY_ROLE_BREDR)
2103 discovering_type = "Discovering";
2104 else if (discovery_type == DISCOVERY_ROLE_LE)
2105 discovering_type = "LEDiscovering";
2107 result = g_dbus_proxy_call_sync(proxy,
2109 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2111 G_DBUS_CALL_FLAGS_NONE,
2117 if (error != NULL) {
2118 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2119 g_clear_error(&error);
2121 BT_ERR("Failed to get discovering property");
2122 return BLUETOOTH_ERROR_INTERNAL;
2125 g_variant_get(result, "(v)", &temp);
2126 discovering_v = g_variant_get_boolean(temp);
2127 BT_DBG("discoverable_v:%d", discovering_v);
2129 g_variant_unref(result);
2130 g_variant_unref(temp);
2132 return discovering_v;
2135 unsigned int _bt_get_discoverable_timeout_property(void)
2138 unsigned int timeout_v;
2139 GError *error = NULL;
2143 proxy = _bt_get_adapter_properties_proxy();
2144 retv_if(proxy == NULL, 0);
2146 result = g_dbus_proxy_call_sync(proxy,
2148 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2149 "DiscoverableTimeout"),
2150 G_DBUS_CALL_FLAGS_NONE,
2156 BT_ERR("Fail to get discoverable timeout");
2157 if (error != NULL) {
2158 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2159 g_clear_error(&error);
2164 g_variant_get(result, "(v)", &temp);
2165 timeout_v = g_variant_get_uint32(temp);
2166 BT_DBG("discoverable_v:%d", timeout_v);
2168 g_variant_unref(result);
2169 g_variant_unref(temp);
2174 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2176 bluetooth_device_info_t *dev_info;
2179 GByteArray *manufacturer_data = NULL;
2181 GVariantIter *char_value_iter;
2183 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2185 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2190 if (!g_strcmp0(key, "Address")) {
2191 const char *address = NULL;
2192 address = g_variant_get_string(value, NULL);
2193 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2195 } else if(!g_strcmp0(key, "Class")) {
2197 cod = g_variant_get_uint32(value);
2198 _bt_divide_device_class(&dev_info->device_class, cod);
2199 } else if(!g_strcmp0(key, "Name")) {
2200 const char *name = NULL;
2201 name = g_variant_get_string(value, NULL);
2202 /* If there is no Alias */
2203 if (strlen(dev_info->device_name.name) == 0) {
2204 g_strlcpy(dev_info->device_name.name, name,
2205 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2207 } else if(!g_strcmp0(key, "Alias")) {
2208 const char *alias = NULL;
2209 alias = g_variant_get_string(value, NULL);
2210 /* Overwrite the name */
2212 memset(dev_info->device_name.name, 0x00,
2213 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2214 g_strlcpy(dev_info->device_name.name, alias,
2215 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2217 } else if (!g_strcmp0(key, "Connected")) {
2218 dev_info->connected = g_variant_get_byte(value);
2219 } else if (!g_strcmp0(key, "Paired")) {
2220 dev_info->paired = g_variant_get_boolean(value);
2221 } else if (!g_strcmp0(key, "Trusted")) {
2222 dev_info->trust = g_variant_get_boolean(value);
2223 } else if (!g_strcmp0(key, "RSSI")) {
2224 dev_info->rssi = g_variant_get_int16(value);
2225 } else if (!g_strcmp0(key, "UUIDs")) {
2231 dev_info->service_index = 0;
2232 g_variant_get(value, "as", &iter);
2233 while (g_variant_iter_loop(iter, "s", &uuid)) {
2234 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2235 parts = g_strsplit(uuid, "-", -1);
2237 if (parts == NULL || parts[0] == NULL) {
2242 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2247 dev_info->service_index = i;
2248 g_variant_iter_free(iter);
2249 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2250 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2251 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2252 manufacturer_data = g_byte_array_new();
2253 g_variant_get(value, "ay", &char_value_iter);
2254 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
2255 g_byte_array_append(manufacturer_data, &char_value, 1);
2257 if (manufacturer_data) {
2258 if (manufacturer_data->len > 0) {
2259 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2262 g_variant_iter_free(char_value_iter);
2263 g_byte_array_free(manufacturer_data, TRUE);
2270 static void __bt_extract_device_info(GVariantIter *iter,
2273 bluetooth_device_info_t *dev_info = NULL;
2274 char *object_path = NULL;
2275 GVariantIter *interface_iter;
2276 GVariantIter *svc_iter;
2277 char *interface_str = NULL;
2279 /* Parse the signature: oa{sa{sv}}} */
2280 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2283 if (object_path == NULL)
2286 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2287 &interface_str, &svc_iter)) {
2288 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2289 BT_DBG("Found a device: %s", object_path);
2290 dev_info = __bt_parse_device_info(svc_iter);
2292 if (dev_info->paired == TRUE) {
2293 g_array_append_vals(*dev_list, dev_info,
2294 sizeof(bluetooth_device_info_t));
2298 g_free(interface_str);
2299 g_variant_iter_free(svc_iter);
2307 int _bt_get_bonded_devices(GArray **dev_list)
2310 GDBusConnection *conn;
2311 GDBusProxy *manager_proxy;
2312 GVariant *result = NULL;
2313 GVariantIter *iter = NULL;
2314 GError *error = NULL;
2316 conn = _bt_get_system_conn();
2317 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2319 manager_proxy = _bt_get_manager_proxy();
2320 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2322 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2324 G_DBUS_CALL_FLAGS_NONE,
2330 if (error != NULL) {
2331 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2332 g_clear_error(&error);
2334 BT_ERR("Failed to Failed to GetManagedObjects");
2335 return BLUETOOTH_ERROR_INTERNAL;
2338 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2339 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2341 __bt_extract_device_info(iter, dev_list);
2342 g_variant_iter_free(iter);
2343 g_variant_unref(result);
2346 return BLUETOOTH_ERROR_NONE;
2349 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2350 bluetooth_device_info_t *dev_info)
2352 char *object_path = NULL;
2353 GDBusProxy *adapter_proxy;
2354 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2355 int ret = BLUETOOTH_ERROR_NONE;
2357 BT_CHECK_PARAMETER(device_address, return);
2358 BT_CHECK_PARAMETER(dev_info, return);
2360 adapter_proxy = _bt_get_adapter_proxy();
2361 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2363 _bt_convert_addr_type_to_string(address, device_address->addr);
2365 object_path = _bt_get_device_object_path(address);
2367 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2369 ret = __bt_get_bonded_device_info(object_path, dev_info);
2370 g_free(object_path);
2375 int _bt_get_timeout_value(int *timeout)
2377 time_t current_time;
2380 /* Take current time */
2381 time(¤t_time);
2382 time_diff = difftime(current_time, visible_timer.start_time);
2384 BT_DBG("Time diff = %d\n", time_diff);
2386 *timeout = visible_timer.timeout - time_diff;
2388 return BLUETOOTH_ERROR_NONE;
2391 int _bt_set_le_privacy(gboolean set_privacy)
2394 GError *error = NULL;
2395 GVariant *result = NULL;
2397 if (__bt_is_factory_test_mode()) {
2398 BT_ERR("Unable to set le privacy in factory binary !!");
2399 return BLUETOOTH_ERROR_NOT_SUPPORT;
2402 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2403 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2404 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2407 proxy = _bt_get_adapter_proxy();
2408 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2410 result = g_dbus_proxy_call_sync(proxy,
2412 g_variant_new("(b)", set_privacy),
2413 G_DBUS_CALL_FLAGS_NONE,
2419 if (error != NULL) {
2420 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2421 g_clear_error(&error);
2423 BT_ERR("Failed to SetLePrivacy");
2424 return BLUETOOTH_ERROR_INTERNAL;
2427 g_variant_unref(result);
2428 BT_INFO("SetLePrivacy as %d", set_privacy);
2429 return BLUETOOTH_ERROR_NONE;
2432 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2435 GError *error = NULL;
2439 GVariantBuilder *builder;
2441 BT_CHECK_PARAMETER(m_data, return);
2443 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2444 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2445 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2448 proxy = _bt_get_adapter_proxy();
2449 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2451 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2453 for (i = 0; i < (m_data->data_len) + 2; i++) {
2454 g_variant_builder_add(builder, "y", m_data->data[i]);
2457 val = g_variant_new("(ay)", builder);
2459 result = g_dbus_proxy_call_sync(proxy,
2460 "SetManufacturerData",
2462 G_DBUS_CALL_FLAGS_NONE,
2466 g_variant_builder_unref(builder);
2468 if (error != NULL) {
2469 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2470 g_clear_error(&error);
2472 BT_ERR("Failed to SetManufacturerData");
2474 return BLUETOOTH_ERROR_INTERNAL;
2476 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2478 for (i = 0; i < (m_data->data_len) + 2; i++) {
2479 g_variant_builder_add(builder, "y", m_data->data[i]);
2482 val = g_variant_new("(ay)", builder);
2484 _bt_send_event(BT_ADAPTER_EVENT,
2485 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2488 BT_INFO("Set manufacturer data");
2490 g_variant_builder_unref(builder);
2491 g_variant_unref(result);
2493 return BLUETOOTH_ERROR_NONE;