4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
30 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
31 #include <syspopup_caller.h>
34 #include <dbus/dbus-glib.h>
35 #include <dbus/dbus.h>
37 #include <eventsystem.h>
38 #include <bundle_internal.h>
41 #include "bluetooth-api.h"
42 #include "bt-internal-types.h"
43 #include "bt-service-common.h"
44 #include "bt-service-event.h"
45 #include "bt-service-adapter.h"
46 #include "bt-service-util.h"
47 #include "bt-service-network.h"
48 #include "bt-service-obex-server.h"
49 #include "bt-service-agent.h"
50 #include "bt-service-main.h"
51 #include "bt-service-avrcp.h"
52 #include "bt-service-device.h"
62 bt_adapter_timer_t visible_timer = {0, };
64 static gboolean is_discovering;
65 static gboolean cancel_by_user;
66 static bt_status_t adapter_status = BT_DEACTIVATED;
67 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
68 static void *adapter_agent = NULL;
69 static GDBusProxy *core_proxy = NULL;
70 static guint timer_id = 0;
71 static guint le_timer_id = 0;
73 static int status_reg_id;
75 #define BT_CORE_NAME "org.projectx.bt_core"
76 #define BT_CORE_PATH "/org/projectx/bt_core"
77 #define BT_CORE_INTERFACE "org.projectx.btcore"
79 #define BT_DISABLE_TIME 500 /* 500 ms */
81 GDBusProxy *_bt_init_core_proxy(void)
84 GDBusConnection *conn;
86 conn = _bt_get_system_gconn();
90 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
105 static GDBusProxy *__bt_get_core_proxy(void)
107 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
110 static gboolean __bt_is_factory_test_mode(void)
114 #ifdef ENABLE_TIZEN_2_4
115 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
116 BT_ERR("Get the DUT Mode fail");
122 BT_INFO("DUT Test Mode !!");
129 static gboolean __bt_timeout_handler(gpointer user_data)
131 int result = BLUETOOTH_ERROR_NONE;
135 /* Take current time */
137 time_diff = difftime(current_time, visible_timer.start_time);
139 /* Send event to application */
140 _bt_send_event(BT_ADAPTER_EVENT,
141 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
142 g_variant_new("(in)", result, time_diff));
144 if (visible_timer.timeout <= time_diff) {
145 g_source_remove(visible_timer.event_id);
146 visible_timer.event_id = 0;
147 visible_timer.timeout = 0;
149 #ifndef TIZEN_WEARABLE
150 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
151 BT_ERR("Set vconf failed\n");
159 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
161 BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
163 int result = BLUETOOTH_ERROR_NONE;
166 if (alarm_id != visible_timer.alarm_id)
169 if (visible_timer.event_id) {
170 _bt_send_event(BT_ADAPTER_EVENT,
171 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
172 g_variant_new("(in)", result, timeout));
173 g_source_remove(visible_timer.event_id);
174 visible_timer.event_id = 0;
175 visible_timer.timeout = 0;
177 #ifndef TIZEN_WEARABLE
178 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
179 BT_ERR("Set vconf failed\n");
182 /* Switch Off visibility in Bluez */
183 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
184 visible_timer.alarm_id = 0;
188 static void __bt_visibility_alarm_create()
193 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
196 BT_ERR("Failed to create alarm error = %d\n", result);
198 BT_DBG("Alarm created = %d\n", alarm_id);
199 visible_timer.alarm_id = alarm_id;
203 static void __bt_visibility_alarm_remove()
205 if (visible_timer.event_id > 0) {
206 g_source_remove(visible_timer.event_id);
207 visible_timer.event_id = 0;
210 if (visible_timer.alarm_id > 0) {
211 alarmmgr_remove_alarm(visible_timer.alarm_id);
212 visible_timer.alarm_id = 0;
216 int __bt_set_visible_time(int timeout)
220 __bt_visibility_alarm_remove();
222 visible_timer.timeout = timeout;
224 #ifndef TIZEN_WEARABLE
225 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
226 BT_ERR("Set vconf failed");
230 return BLUETOOTH_ERROR_NONE;
232 if (!visible_timer.alarm_init) {
233 /* Set Alarm timer to switch off BT */
234 result = alarmmgr_init("bt-service");
236 return BLUETOOTH_ERROR_INTERNAL;
238 visible_timer.alarm_init = TRUE;
241 result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
243 return BLUETOOTH_ERROR_INTERNAL;
245 /* Take start time */
246 time(&(visible_timer.start_time));
247 visible_timer.event_id = g_timeout_add_seconds(1,
248 __bt_timeout_handler, NULL);
250 __bt_visibility_alarm_create();
252 return BLUETOOTH_ERROR_NONE;
255 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
262 ret_if(value == NULL);
265 dev->service_index = 0;
267 g_variant_get(value, "as", &iter);
268 while (g_variant_iter_loop(iter, "s", &uuid)) {
269 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
270 parts = g_strsplit(uuid, "-", -1);
272 if (parts == NULL || parts[0] == NULL) {
277 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
280 dev->service_index++;
283 g_variant_iter_free(iter);
286 static int __bt_get_bonded_device_info(gchar *device_path,
287 bluetooth_device_info_t *dev_info)
289 GError *error = NULL;
290 GDBusProxy *device_proxy;
291 const gchar *address = NULL;
292 const gchar *name = NULL;
293 unsigned int cod = 0;
295 gboolean trust = FALSE;
296 gboolean paired = FALSE;
297 guchar connected = 0;
298 GByteArray *manufacturer_data = NULL;
300 GDBusConnection *conn;
302 GVariantIter *property_iter;
306 GVariantIter *char_value_iter;
308 BT_CHECK_PARAMETER(device_path, return);
309 BT_CHECK_PARAMETER(dev_info, return);
311 conn = _bt_get_system_gconn();
312 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
314 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
318 BT_PROPERTIES_INTERFACE,
321 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
323 result = g_dbus_proxy_call_sync(device_proxy,
325 g_variant_new("(s)", BT_DEVICE_INTERFACE),
326 G_DBUS_CALL_FLAGS_NONE,
332 BT_ERR("Error occured in Proxy call");
334 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
335 g_clear_error(&error);
337 g_object_unref(device_proxy);
338 return BLUETOOTH_ERROR_INTERNAL;
341 g_object_unref(device_proxy);
343 g_variant_get(result, "(a{sv})", &property_iter);
345 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
346 if (!g_strcmp0(key,"Paired")) {
347 paired = g_variant_get_boolean(value);
348 } else if(!g_strcmp0(key, "Address")) {
349 address = g_variant_get_string(value, NULL);
350 } else if (!g_strcmp0(key, "Alias")) {
351 name = g_variant_get_string(value, NULL);
352 } else if (!g_strcmp0(key, "Name")) {
354 name = g_variant_get_string(value, NULL);
355 } else if (!g_strcmp0(key, "Class")) {
356 cod = g_variant_get_uint32(value);
357 } else if (!g_strcmp0(key, "Connected")) {
358 connected = g_variant_get_byte(value);
359 } else if (!g_strcmp0(key, "Trusted")) {
360 trust = g_variant_get_boolean(value);
361 } else if (!g_strcmp0(key, "RSSI")) {
362 rssi = g_variant_get_int16(value);
363 } else if (!g_strcmp0(key, "UUIDs")) {
364 __bt_get_service_list(value, dev_info);
365 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
366 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
367 } else if (!g_strcmp0(key, "ManufacturerData")) {
368 manufacturer_data = g_byte_array_new();
369 g_variant_get(value, "ay", &char_value_iter);
370 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
371 g_byte_array_append(manufacturer_data, &char_value, 1);
373 if (manufacturer_data) {
374 if (manufacturer_data->len > 0) {
375 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
376 manufacturer_data->len);
382 BT_DBG("trust: %d, paired: %d", trust, paired);
384 g_variant_unref(result);
386 if ((paired == FALSE) && (trust == FALSE)) {
387 return BLUETOOTH_ERROR_NOT_PAIRED;
390 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
393 _bt_divide_device_class(&dev_info->device_class, cod);
395 g_strlcpy(dev_info->device_name.name, name,
396 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
398 dev_info->rssi = rssi;
399 dev_info->trust = trust;
400 dev_info->paired = paired;
401 dev_info->connected = connected;
402 ret = BLUETOOTH_ERROR_NONE;
407 void _bt_set_discovery_status(gboolean mode)
409 is_discovering = mode;
412 void _bt_set_cancel_by_user(gboolean value)
414 cancel_by_user = value;
417 gboolean _bt_get_cancel_by_user(void)
419 return cancel_by_user;
422 void _bt_adapter_set_status(bt_status_t status)
424 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
425 adapter_status = status;
428 bt_status_t _bt_adapter_get_status(void)
430 return adapter_status;
433 void _bt_adapter_set_le_status(bt_le_status_t status)
435 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
436 adapter_le_status = status;
439 bt_le_status_t _bt_adapter_get_le_status(void)
441 return adapter_le_status;
444 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
446 char *phone_name = NULL;
452 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
453 phone_name = vconf_keynode_get_str(node);
455 if (phone_name && strlen(phone_name) != 0) {
456 if (!g_utf8_validate(phone_name, -1,
457 (const char **)&ptr))
460 _bt_set_local_name(phone_name);
466 static void __bt_set_visible_mode(void)
470 if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
471 BT_ERR("Fail to get the timeout value");
474 if (_bt_set_discoverable_mode(
475 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE,
476 timeout) != BLUETOOTH_ERROR_NONE) {
477 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
478 BT_ERR("Set vconf failed");
481 if (_bt_set_discoverable_mode(
482 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE,
483 timeout) != BLUETOOTH_ERROR_NONE) {
484 BT_ERR("Set connectable mode 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;
523 __bt_set_visible_mode();
526 if (_bt_set_discoverable_mode(
527 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0)!= BLUETOOTH_ERROR_NONE)
528 BT_ERR("Fail to set discoverable mode");
531 __bt_set_local_name();
533 /* Update Bluetooth Status to notify other modules */
534 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
535 BT_ERR("Set vconf failed\n");
537 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
538 BT_ERR("Set vconf failed\n");
540 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
541 EVT_VAL_BT_ON) != ES_R_OK)
542 BT_ERR("Fail to set value");
545 /* Send enabled event to API */
546 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
547 g_variant_new("(i)", result));
550 return BLUETOOTH_ERROR_NONE;
553 void _bt_set_disabled(int result)
555 int power_off_status = 0;
558 int pm_ignore_mode = 0;
560 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
561 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
563 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
565 /* Update the vconf BT status in normal Deactivation case only */
566 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
567 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
569 BT_DBG("Update vconf for BT normal Deactivation");
571 if (result == BLUETOOTH_ERROR_TIMEOUT)
572 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 )
573 BT_ERR("Set vconf failed");
575 /* Update Bluetooth Status to notify other modules */
576 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
577 BT_ERR("Set vconf failed");
579 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
580 EVT_VAL_BT_OFF) != ES_R_OK)
581 BT_ERR("Fail to set value");
584 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
585 BT_ERR("Set vconf failed\n");
587 _bt_adapter_set_status(BT_DEACTIVATED);
589 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
590 /* Send disabled event */
591 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
592 g_variant_new("(i)", result));
595 BT_INFO("Adapter disabled");
598 static int __bt_set_le_enabled(void)
601 int result = BLUETOOTH_ERROR_NONE;
604 __bt_set_local_name();
606 /* Update Bluetooth Status to notify other modules */
607 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
608 BT_ERR("Set vconf failed\n");
610 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
611 EVT_VAL_BT_LE_ON) != ES_R_OK)
612 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");
648 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
649 BT_ERR("Set vconf failed\n");
650 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
652 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
653 EVT_VAL_BT_LE_OFF) != ES_R_OK)
654 BT_ERR("Fail to set value");
656 /* Send disabled event */
657 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
658 g_variant_new_int32(result));
661 void *_bt_get_adapter_agent(void)
663 return adapter_agent;
666 int _bt_enable_core(void)
670 GError *error = NULL;
672 proxy = __bt_get_core_proxy();
673 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
675 /* Clean up the process */
676 result = g_dbus_proxy_call_sync(proxy,
679 G_DBUS_CALL_FLAGS_NONE,
686 BT_ERR("Bt core call failed(Error: %s)", error->message);
687 g_clear_error(&error);
689 BT_ERR("Bt core call failed");
690 return BLUETOOTH_ERROR_INTERNAL;
693 g_variant_unref(result);
694 return BLUETOOTH_ERROR_NONE;
697 #if defined(TIZEN_BT_FLIGHTMODE_ENABLED) || !defined(TIZEN_WEARABLE)
698 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
700 gboolean flight_mode = FALSE;
701 int power_saving_mode = 0;
704 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
705 type = vconf_keynode_get_type(node);
706 if (type == VCONF_TYPE_BOOL) {
707 flight_mode = vconf_keynode_get_bool(node);
708 if (flight_mode != TRUE) {
709 BT_ERR("Ignore the event");
712 } else if (type == VCONF_TYPE_INT) {
713 power_saving_mode = vconf_keynode_get_int(node);
714 if (power_saving_mode != 2) {
715 BT_ERR("Ignore the event");
719 BT_ERR("Invaild vconf key type : %d", type);
727 void _bt_service_register_vconf_handler(void)
731 #ifdef TIZEN_TELEPHONY_ENABLED
732 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
733 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
734 BT_ERR("Unable to register key handler");
736 BT_DBG("Telephony is disabled");
739 #ifndef TIZEN_WEARABLE
740 #ifdef ENABLE_TIZEN_2_4
741 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
742 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
743 BT_ERR("Unable to register key handler");
748 void _bt_service_unregister_vconf_handler(void)
752 #ifdef TIZEN_TELEPHONY_ENABLED
753 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
754 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
757 #ifndef TIZEN_WEARABLE
758 #ifdef ENABLE_TIZEN_2_4
759 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
760 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
765 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
767 const char *bt_status = NULL;
768 const char *bt_le_status = NULL;
769 const char *bt_transfering_status = NULL;
770 BT_DBG("bt state set event(%s) received", event_name);
771 #ifdef ENABLE_TIZEN_2_4
772 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
773 BT_DBG("bt_state: (%s)", bt_status);
775 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
776 BT_DBG("bt_state: (%s)", bt_le_status);
780 void _bt_handle_adapter_added(void)
784 bt_le_status_t le_status;
788 BT_DBG("g_source is removed");
789 g_source_remove(timer_id);
793 status = _bt_adapter_get_status();
794 le_status = _bt_adapter_get_le_status();
795 BT_DBG("status : %d", status);
796 BT_DBG("le_status : %d", le_status);
798 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
799 if (!adapter_agent) {
800 BT_ERR("Fail to register agent");
804 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
805 BT_ERR("Fail to register media player");
807 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
808 BT_ERR("Fail to init obex server");
810 #ifdef TIZEN_BT_PAN_NAP_ENABLE
811 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
812 BT_ERR("Fail to activate network");
815 /* add the vconf noti handler */
816 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
817 __bt_phone_name_changed_cb, NULL);
819 BT_ERR("Unable to register key handler");
821 if (le_status == BT_LE_ACTIVATING ||
822 status == BT_ACTIVATING) {
823 __bt_set_le_enabled();
824 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
827 if (status == BT_ACTIVATING) {
829 _bt_adapter_set_status(BT_ACTIVATED);
831 #ifdef ENABLE_TIZEN_2_4
835 _bt_service_register_vconf_handler();
838 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
839 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
840 BT_ERR("Fail to register system event");
844 void _bt_handle_adapter_removed(void)
848 _bt_adapter_set_status(BT_DEACTIVATED);
849 #ifdef ENABLE_TIZEN_2_4
853 __bt_visibility_alarm_remove();
855 if (visible_timer.alarm_init) {
857 visible_timer.alarm_init = FALSE;
860 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
861 (vconf_callback_fn)__bt_phone_name_changed_cb);
863 ERR("vconf_ignore_key_changed failed\n");
866 _bt_destroy_agent(adapter_agent);
867 adapter_agent = NULL;
869 _bt_reliable_terminate_service(NULL);
871 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK) {
872 BT_ERR("Fail to unregister system event");
877 static gboolean __bt_enable_timeout_cb(gpointer user_data)
881 GError *error = NULL;
885 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
887 BT_ERR("EnableAdapter is failed");
889 proxy = __bt_get_core_proxy();
893 /* Clean up the process */
894 result = g_dbus_proxy_call_sync(proxy,
897 G_DBUS_CALL_FLAGS_NONE,
904 BT_ERR("Bt core call failed(Error: %s)", error->message);
905 g_clear_error(&error);
907 BT_ERR("Bt core call failed");
912 g_variant_unref(result);
913 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
915 _bt_terminate_service(NULL);
920 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
924 GError *error = NULL;
928 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
930 BT_ERR("EnableAdapterLE is failed");
932 proxy = __bt_get_core_proxy();
936 /* Clean up the process */
937 result = g_dbus_proxy_call_sync(proxy,
940 G_DBUS_CALL_FLAGS_NONE,
947 BT_ERR("Bt core call failed(Error: %s)", error->message);
948 g_clear_error(&error);
950 BT_ERR("Bt core call failed");
954 g_variant_unref(result);
955 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
957 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
959 if (_bt_adapter_get_status() == BT_DEACTIVATED)
960 _bt_terminate_service(NULL);
965 void _bt_adapter_start_le_enable_timer(void)
967 if (le_timer_id > 0) {
968 g_source_remove(le_timer_id);
972 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
973 __bt_enable_le_timeout_cb, NULL);
978 void _bt_adapter_start_enable_timer(void)
981 g_source_remove(timer_id);
985 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
986 __bt_enable_timeout_cb, NULL);
991 int _bt_enable_adapter(void)
994 GError *error = NULL;
996 GVariant *result = NULL;
997 bt_status_t status = _bt_adapter_get_status();
998 bt_le_status_t le_status = _bt_adapter_get_le_status();
1002 if (status == BT_ACTIVATING) {
1003 BT_ERR("Enabling in progress");
1004 return BLUETOOTH_ERROR_IN_PROGRESS;
1007 if (status == BT_ACTIVATED) {
1008 BT_ERR("Already enabled");
1009 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1012 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1013 BT_ERR("Disabling in progress");
1014 return BLUETOOTH_ERROR_DEVICE_BUSY;
1017 _bt_adapter_set_status(BT_ACTIVATING);
1021 int adapter_status = BT_ADAPTER_DISABLED;
1023 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1024 BT_ERR("Set vconf failed");
1026 _bt_check_adapter(&adapter_status);
1027 if (adapter_status == BT_ADAPTER_ENABLED) {
1028 g_idle_add(__bt_adapter_enabled_cb, NULL);
1029 _bt_adapter_start_enable_timer();
1030 return BLUETOOTH_ERROR_NONE;
1035 proxy = __bt_get_core_proxy();
1037 return BLUETOOTH_ERROR_INTERNAL;
1039 if (le_status == BT_LE_ACTIVATED) {
1040 BT_INFO("LE Already enabled. Just turn on PSCAN");
1041 ret = _bt_set_connectable(TRUE);
1042 if (ret == BLUETOOTH_ERROR_NONE) {
1043 _bt_adapter_set_status(BT_ACTIVATED);
1045 return BLUETOOTH_ERROR_INTERNAL;
1049 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1051 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1054 BT_ERR("EnableAdapterLe failed: %s", error->message);
1055 _bt_adapter_set_status(BT_DEACTIVATED);
1056 g_clear_error(&error);
1058 result = g_dbus_proxy_call_sync(proxy,
1061 G_DBUS_CALL_FLAGS_NONE,
1066 if (error != NULL) {
1067 BT_ERR("Bt core call failed(Error: %s)", error->message);
1068 g_clear_error(&error);
1070 g_variant_unref(result);
1071 /* Terminate myself */
1072 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1073 return BLUETOOTH_ERROR_INTERNAL;
1075 g_variant_unref(result);
1076 if (le_status == BT_LE_ACTIVATED) {
1079 _bt_adapter_start_enable_timer();
1082 return BLUETOOTH_ERROR_NONE;
1085 static gboolean __bt_disconnect_all(void)
1088 GDBusConnection *conn;
1089 GDBusProxy *dev_proxy;
1090 gboolean ret = FALSE;
1092 GError *error = NULL;
1093 GArray *device_list;
1094 bluetooth_device_info_t info;
1096 char *device_path = NULL;
1097 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1102 conn = _bt_get_system_gconn();
1104 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1106 if (_bt_get_bonded_devices(&device_list)
1107 != BLUETOOTH_ERROR_NONE) {
1108 g_array_free(device_list, TRUE);
1112 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1114 for (i = 0; i < size; i++) {
1116 info = g_array_index(device_list,
1117 bluetooth_device_info_t, i);
1119 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1120 BT_DBG("Found Connected device");
1121 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1122 device_path = _bt_get_device_object_path(address);
1123 if (device_path == NULL)
1126 BT_DBG("Disconnecting : %s", device_path);
1128 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1132 BT_DEVICE_INTERFACE,
1135 if (dev_proxy == NULL)
1138 result = g_dbus_proxy_call_sync(dev_proxy,
1141 G_DBUS_CALL_FLAGS_NONE,
1147 if (error != NULL) {
1148 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1149 g_clear_error(&error);
1151 BT_ERR("Disconnect call failed");
1152 g_object_unref(dev_proxy);
1156 g_variant_unref(result);
1157 g_object_unref(dev_proxy);
1161 g_array_free(device_list, TRUE);
1166 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1169 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1174 int __bt_disable_cb(void)
1178 bt_le_status_t le_status;
1181 GError *error = NULL;
1183 _bt_adapter_set_status(BT_DEACTIVATING);
1184 le_status = _bt_adapter_get_le_status();
1185 BT_DBG("le_status : %d", le_status);
1186 if (le_status == BT_LE_ACTIVATED) {
1187 BT_INFO("LE is enabled. Just turn off PSCAN");
1189 if (_bt_is_discovering())
1190 _bt_cancel_discovery();
1192 if (_bt_is_connectable() == FALSE) {
1193 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1195 ret = _bt_set_connectable(FALSE);
1196 if (ret != BLUETOOTH_ERROR_NONE) {
1197 BT_ERR("_bt_set_connectable fail!");
1198 _bt_adapter_set_status(BT_ACTIVATED);
1199 return BLUETOOTH_ERROR_INTERNAL;
1204 proxy = __bt_get_core_proxy();
1205 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1207 result = g_dbus_proxy_call_sync(proxy,
1210 G_DBUS_CALL_FLAGS_NONE,
1216 if (error != NULL) {
1217 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1218 g_clear_error(&error);
1220 BT_ERR("Failed to DisableAdapter");
1221 _bt_adapter_set_status(BT_ACTIVATED);
1222 return BLUETOOTH_ERROR_INTERNAL;
1225 g_variant_unref(result);
1226 return BLUETOOTH_ERROR_NONE;
1229 int _bt_disable_adapter(void)
1234 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1235 BT_DBG("Disabling in progress");
1236 return BLUETOOTH_ERROR_IN_PROGRESS;
1239 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1240 BT_DBG("Already disabled");
1241 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1245 g_source_remove(timer_id);
1249 __bt_disconnect_all();
1250 ret = __bt_disable_cb();
1256 int _bt_recover_adapter(void)
1261 GError *error = NULL;
1263 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1264 BT_DBG("Disabling in progress");
1265 return BLUETOOTH_ERROR_IN_PROGRESS;
1268 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1269 BT_DBG("Already disabled");
1270 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1273 _bt_adapter_set_status(BT_DEACTIVATING);
1275 proxy = __bt_get_core_proxy();
1276 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1278 result = g_dbus_proxy_call_sync(proxy,
1281 G_DBUS_CALL_FLAGS_NONE,
1287 if (error != NULL) {
1288 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1289 g_clear_error(&error);
1291 BT_ERR("Failed to RecoverAdapter");
1292 return BLUETOOTH_ERROR_INTERNAL;
1295 g_variant_unref(result);
1296 __bt_disconnect_all();
1299 return BLUETOOTH_ERROR_NONE;
1302 int _bt_reset_adapter(void)
1306 GError *error = NULL;
1310 proxy = __bt_get_core_proxy();
1312 return BLUETOOTH_ERROR_INTERNAL;
1314 result = g_dbus_proxy_call_sync(proxy,
1317 G_DBUS_CALL_FLAGS_NONE,
1323 if (error != NULL) {
1324 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1325 g_clear_error(&error);
1327 BT_ERR("Failed to ResetAdapter");
1328 return BLUETOOTH_ERROR_INTERNAL;
1331 g_variant_unref(result);
1332 /* Terminate myself */
1333 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1334 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1337 return BLUETOOTH_ERROR_NONE;
1341 int _bt_check_adapter(int *status)
1344 char *adapter_path = NULL;
1346 BT_CHECK_PARAMETER(status, return);
1348 *status = BT_ADAPTER_DISABLED;
1350 adapter_path = _bt_get_adapter_path();
1353 if (adapter_path != NULL)
1354 *status = BT_ADAPTER_ENABLED;
1356 g_free(adapter_path);
1357 return BLUETOOTH_ERROR_NONE;
1360 int _bt_check_adapter(int *status)
1363 GError *error = NULL;
1366 gboolean powered = FALSE;
1368 BT_CHECK_PARAMETER(status, return);
1370 *status = BT_ADAPTER_DISABLED;
1372 proxy = _bt_get_adapter_properties_proxy();
1373 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1375 result = g_dbus_proxy_call_sync(proxy,
1377 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1379 G_DBUS_CALL_FLAGS_NONE,
1385 BT_ERR("Failed to get local address");
1386 if (error != NULL) {
1387 BT_ERR("Failed to get local address (Error: %s)", error->message);
1388 g_clear_error(&error);
1390 return BLUETOOTH_ERROR_INTERNAL;
1393 g_variant_get(result, "(v)", &temp);
1394 powered = g_variant_get_boolean(temp);
1395 BT_DBG("powered: %d", powered);
1398 *status = BT_ADAPTER_ENABLED;
1400 g_variant_unref(result);
1401 g_variant_unref(temp);
1402 return BLUETOOTH_ERROR_NONE;
1406 int _bt_enable_adapter_le(void)
1410 GError *error = NULL;
1411 bt_status_t status = _bt_adapter_get_status();
1412 bt_le_status_t le_status = _bt_adapter_get_le_status();
1415 if (le_status == BT_LE_ACTIVATING) {
1416 BT_ERR("Enabling in progress");
1417 return BLUETOOTH_ERROR_IN_PROGRESS;
1420 if (le_status == BT_LE_ACTIVATED) {
1421 BT_ERR("Already enabled");
1422 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1425 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1426 BT_ERR("Disabling in progress");
1427 return BLUETOOTH_ERROR_DEVICE_BUSY;
1430 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1432 proxy = __bt_get_core_proxy();
1433 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1435 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1437 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1440 BT_ERR("EnableAdapterLe failed: %s", error->message);
1441 _bt_adapter_set_le_status(BT_DEACTIVATED);
1442 g_clear_error(&error);
1444 /* Clean up the process */
1445 result = g_dbus_proxy_call_sync(proxy,
1448 G_DBUS_CALL_FLAGS_NONE,
1454 BT_ERR("Bt core call failed");
1456 BT_ERR("EnableAdapterLE Failed %s", error->message);
1457 g_clear_error(&error);
1460 g_variant_unref(result);
1461 /* Terminate myself */
1462 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1463 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1464 return BLUETOOTH_ERROR_INTERNAL;
1468 g_variant_unref(result);
1470 _bt_adapter_start_le_enable_timer();
1472 if (status == BT_ACTIVATED) {
1473 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1474 __bt_set_le_enabled();
1476 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1478 return BLUETOOTH_ERROR_NONE;
1481 int _bt_disable_adapter_le(void)
1485 bt_le_status_t bt_le_state;
1487 GError *error = NULL;
1489 bt_le_state = _bt_adapter_get_le_status();
1490 if (bt_le_state == BT_LE_DEACTIVATING) {
1491 BT_DBG("Disabling in progress");
1492 return BLUETOOTH_ERROR_IN_PROGRESS;
1495 if (bt_le_state == BT_LE_DEACTIVATED) {
1496 BT_DBG("Already disabled");
1497 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1500 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1502 proxy = __bt_get_core_proxy();
1504 return BLUETOOTH_ERROR_INTERNAL;
1506 result = g_dbus_proxy_call_sync(proxy,
1509 G_DBUS_CALL_FLAGS_NONE,
1515 if (error != NULL) {
1516 BT_ERR("Bt core call failed (Error: %s)", error->message);
1517 g_clear_error(&error);
1519 BT_ERR("Bt core call failed");
1520 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1521 return BLUETOOTH_ERROR_INTERNAL;
1524 g_variant_unref(result);
1525 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1526 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1528 return BLUETOOTH_ERROR_NONE;
1531 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1535 GError *error = NULL;
1536 const char *address;
1540 BT_CHECK_PARAMETER(local_address, return);
1542 proxy = _bt_get_adapter_properties_proxy();
1543 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1545 result = g_dbus_proxy_call_sync(proxy,
1547 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1549 G_DBUS_CALL_FLAGS_NONE,
1555 BT_ERR("Failed to get local address");
1556 if (error != NULL) {
1557 BT_ERR("Failed to get local address (Error: %s)", error->message);
1558 g_clear_error(&error);
1560 return BLUETOOTH_ERROR_INTERNAL;
1563 g_variant_get(result, "(v)", &temp);
1564 address = g_variant_get_string(temp, NULL);
1565 BT_DBG("Address:%s", address);
1568 _bt_convert_addr_string_to_type(local_address->addr, address);
1570 return BLUETOOTH_ERROR_INTERNAL;
1573 g_variant_unref(result);
1574 g_variant_unref(temp);
1575 return BLUETOOTH_ERROR_NONE;
1578 int _bt_get_local_version(bluetooth_version_t *local_version)
1581 const char *ver = NULL;
1583 int ret = BLUETOOTH_ERROR_NONE;
1587 BT_CHECK_PARAMETER(local_version, return);
1589 GError *error = NULL;
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 version (Error: %s)", error->message);
1606 g_clear_error(&error);
1608 BT_ERR("Failed to get local version");
1609 return BLUETOOTH_ERROR_INTERNAL;
1612 g_variant_get(result, "(v)", &temp);
1613 ver = g_variant_get_string(temp, NULL);
1614 BT_DBG("VERSION: %s", ver);
1616 if (ver && (strlen(ver) > 0)) {
1617 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1618 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1621 g_strlcpy(local_version->version, ver,
1622 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1625 ret = BLUETOOTH_ERROR_INTERNAL;
1628 g_variant_unref(result);
1629 g_variant_unref(temp);
1633 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1636 const char *name = NULL;
1638 int ret = BLUETOOTH_ERROR_NONE;
1641 GError *error = NULL;
1643 BT_CHECK_PARAMETER(local_name, return);
1645 proxy = _bt_get_adapter_properties_proxy();
1646 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1648 result = g_dbus_proxy_call_sync(proxy,
1650 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1652 G_DBUS_CALL_FLAGS_NONE,
1658 if (error != NULL) {
1659 BT_ERR("Failed to get local name (Error: %s)", error->message);
1660 g_clear_error(&error);
1662 BT_ERR("Failed to get local name");
1663 return BLUETOOTH_ERROR_INTERNAL;
1666 g_variant_get(result, "(v)", &temp);
1667 name = g_variant_get_string(temp, NULL);
1668 BT_DBG("LOCAL NAME:%s", name);
1670 if (name && (strlen(name) > 0)) {
1671 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1672 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1675 g_strlcpy(local_name->name, name,
1676 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1678 ret = BLUETOOTH_ERROR_INTERNAL;
1680 g_variant_unref(result);
1681 g_variant_unref(temp);
1685 int _bt_set_local_name(char *local_name)
1688 GError *error = NULL;
1692 BT_CHECK_PARAMETER(local_name, return);
1694 proxy = _bt_get_adapter_properties_proxy();
1696 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1698 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1701 result = g_dbus_proxy_call_sync(proxy,
1703 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1704 "Alias", g_variant_new("s", local_name)),
1705 G_DBUS_CALL_FLAGS_NONE,
1711 if (error != NULL) {
1712 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1713 g_clear_error(&error);
1715 BT_ERR("Failed to set Alias");
1716 return BLUETOOTH_ERROR_INTERNAL;
1719 g_variant_unref(result);
1720 return BLUETOOTH_ERROR_NONE;
1723 int _bt_is_service_used(char *service_uuid, gboolean *used)
1726 GError *error = NULL;
1727 int ret = BLUETOOTH_ERROR_NONE;
1730 GVariantIter *iter = NULL;
1734 BT_CHECK_PARAMETER(service_uuid, return);
1735 BT_CHECK_PARAMETER(used, return);
1737 proxy = _bt_get_adapter_properties_proxy();
1738 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1740 result = g_dbus_proxy_call_sync(proxy,
1742 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1744 G_DBUS_CALL_FLAGS_NONE,
1750 if (error != NULL) {
1751 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1752 g_clear_error(&error);
1754 BT_ERR("Failed to get UUIDs");
1755 return BLUETOOTH_ERROR_INTERNAL;
1758 g_variant_get(result, "(v)", &value);
1759 g_variant_get(value, "as", &iter);
1761 BT_ERR("Failed to get UUIDs(%s)",service_uuid);
1763 g_variant_unref(result);
1764 g_variant_unref(value);
1768 while (g_variant_iter_loop(iter, "s", &uuid)) {
1769 if (strcasecmp(uuid, service_uuid) == 0) {
1779 g_variant_iter_free(iter);
1780 g_variant_unref(value);
1781 g_variant_unref(result);
1782 BT_DBG("Service Used? %d", *used);
1786 static gboolean __bt_get_discoverable_property(void)
1789 gboolean discoverable_v;
1790 GError *error = NULL;
1794 proxy = _bt_get_adapter_properties_proxy();
1795 retv_if(proxy == NULL, FALSE);
1797 result = g_dbus_proxy_call_sync(proxy,
1799 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1801 G_DBUS_CALL_FLAGS_NONE,
1807 if (error != NULL) {
1808 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1809 g_clear_error(&error);
1811 BT_ERR("Failed to get Discoverable property");
1812 return BLUETOOTH_ERROR_INTERNAL;
1815 g_variant_get(result, "(v)", &temp);
1816 discoverable_v = g_variant_get_boolean(temp);
1817 BT_DBG("discoverable_v:%d", discoverable_v);
1819 g_variant_unref(result);
1820 g_variant_unref(temp);
1822 return discoverable_v;
1825 int _bt_get_discoverable_mode(int *mode)
1827 gboolean discoverable;
1828 unsigned int timeout;
1830 BT_CHECK_PARAMETER(mode, return);
1832 discoverable = __bt_get_discoverable_property();
1833 timeout = _bt_get_discoverable_timeout_property();
1835 if (discoverable == TRUE) {
1837 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1839 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1841 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1843 return BLUETOOTH_ERROR_NONE;
1847 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1849 int ret = BLUETOOTH_ERROR_NONE;
1852 GError *error = NULL;
1856 proxy = _bt_get_adapter_properties_proxy();
1858 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1860 switch (discoverable_mode) {
1861 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1866 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1871 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1876 return BLUETOOTH_ERROR_INVALID_PARAM;
1879 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1880 discoverable_mode, timeout);
1882 result = g_dbus_proxy_call_sync(proxy,
1884 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1885 "Connectable", g_variant_new("b", pg_scan)),
1886 G_DBUS_CALL_FLAGS_NONE,
1892 if (error != NULL) {
1893 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1894 g_clear_error(&error);
1896 BT_ERR("Failed to set connectable property");
1897 return BLUETOOTH_ERROR_INTERNAL;
1899 g_variant_unref(result);
1900 result = g_dbus_proxy_call_sync(proxy,
1902 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
1903 g_variant_new("b", inq_scan)),
1904 G_DBUS_CALL_FLAGS_NONE,
1910 if (error != NULL) {
1911 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
1912 g_clear_error(&error);
1914 BT_ERR("Failed to set Discoverable property");
1915 return BLUETOOTH_ERROR_INTERNAL;
1917 g_variant_unref(result);
1918 result = g_dbus_proxy_call_sync(proxy,
1920 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1921 "DiscoverableTimeout", g_variant_new("u", timeout)),
1922 G_DBUS_CALL_FLAGS_NONE,
1928 if (error != NULL) {
1929 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
1930 g_clear_error(&error);
1932 BT_ERR("Failed to set DiscoverableTimeout property");
1933 return BLUETOOTH_ERROR_INTERNAL;
1936 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1939 ret = __bt_set_visible_time(timeout);
1941 g_variant_unref(result);
1946 int _bt_start_discovery(void)
1949 GError *error = NULL;
1952 if (_bt_is_discovering() == TRUE) {
1953 BT_ERR("BT is already in discovering");
1954 return BLUETOOTH_ERROR_IN_PROGRESS;
1955 } else if (_bt_is_device_creating() == TRUE) {
1956 BT_ERR("Bonding device is going on");
1957 return BLUETOOTH_ERROR_DEVICE_BUSY;
1960 proxy = _bt_get_adapter_proxy();
1961 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1963 result = g_dbus_proxy_call_sync(proxy,
1966 G_DBUS_CALL_FLAGS_NONE,
1972 if (error != NULL) {
1973 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
1974 g_clear_error(&error);
1976 BT_ERR("StartDiscovery failed");
1977 return BLUETOOTH_ERROR_INTERNAL;
1980 is_discovering = TRUE;
1981 cancel_by_user = FALSE;
1982 /* discovery status will be change in event */
1983 g_variant_unref(result);
1984 return BLUETOOTH_ERROR_NONE;
1987 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
1991 GError *error = NULL;
1992 const gchar *disc_type;
1994 if (_bt_is_discovering() == TRUE) {
1995 BT_ERR("BT is already in discovering");
1996 return BLUETOOTH_ERROR_IN_PROGRESS;
1999 proxy = _bt_get_adapter_proxy();
2000 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2002 if (role == DISCOVERY_ROLE_BREDR)
2003 disc_type = "BREDR";
2004 else if (role == DISCOVERY_ROLE_LE)
2006 else if (role == DISCOVERY_ROLE_LE_BREDR)
2007 disc_type = "LE_BREDR";
2009 return BLUETOOTH_ERROR_INVALID_PARAM;
2011 result = g_dbus_proxy_call_sync(proxy,
2012 "StartCustomDiscovery",
2013 g_variant_new("s", disc_type),
2014 G_DBUS_CALL_FLAGS_NONE,
2020 if (error != NULL) {
2021 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2022 g_clear_error(&error);
2024 BT_ERR("StartCustomDiscovery failed");
2025 return BLUETOOTH_ERROR_INTERNAL;
2028 is_discovering = TRUE;
2029 cancel_by_user = FALSE;
2030 /* discovery status will be change in event */
2031 g_variant_unref(result);
2032 return BLUETOOTH_ERROR_NONE;
2035 int _bt_cancel_discovery(void)
2038 GError *error = NULL;
2041 if (_bt_is_discovering() == FALSE) {
2042 BT_ERR("BT is not in discovering");
2043 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2046 proxy = _bt_get_adapter_proxy();
2047 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2049 result = g_dbus_proxy_call_sync(proxy,
2052 G_DBUS_CALL_FLAGS_NONE,
2058 if (error != NULL) {
2059 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2060 g_clear_error(&error);
2062 BT_ERR("StopDiscovery failed");
2063 return BLUETOOTH_ERROR_INTERNAL;
2066 cancel_by_user = TRUE;
2067 /* discovery status will be change in event */
2068 g_variant_unref(result);
2069 return BLUETOOTH_ERROR_NONE;
2072 gboolean _bt_is_discovering(void)
2074 return is_discovering;
2077 gboolean _bt_is_connectable(void)
2080 GError *error = NULL;
2081 gboolean is_connectable = FALSE;
2085 proxy = _bt_get_adapter_properties_proxy();
2086 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2088 result = g_dbus_proxy_call_sync(proxy,
2090 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2092 G_DBUS_CALL_FLAGS_NONE,
2098 if (error != NULL) {
2099 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2100 g_clear_error(&error);
2102 BT_ERR("Failed to get connectable property");
2103 return BLUETOOTH_ERROR_INTERNAL;
2106 g_variant_get(result, "(v)", &temp);
2107 is_connectable = g_variant_get_boolean(temp);
2108 BT_DBG("discoverable_v:%d", is_connectable);
2110 g_variant_unref(result);
2111 g_variant_unref(temp);
2113 BT_INFO("Get connectable [%d]", is_connectable);
2114 return is_connectable;
2117 int _bt_set_connectable(gboolean is_connectable)
2120 GError *error = NULL;
2123 if (__bt_is_factory_test_mode()) {
2124 BT_ERR("Unable to set connectable in factory binary !!");
2125 return BLUETOOTH_ERROR_NOT_SUPPORT;
2128 proxy = _bt_get_adapter_properties_proxy();
2130 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2132 result = g_dbus_proxy_call_sync(proxy,
2134 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2135 g_variant_new("b", is_connectable)),
2136 G_DBUS_CALL_FLAGS_NONE,
2142 if (error != NULL) {
2143 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2144 g_clear_error(&error);
2146 BT_ERR("Failed to set connectable property");
2147 return BLUETOOTH_ERROR_INTERNAL;
2150 BT_INFO("Set connectable [%d]", is_connectable);
2151 g_variant_unref(result);
2152 return BLUETOOTH_ERROR_NONE;
2155 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2158 gboolean discovering_v;
2159 GError *error = NULL;
2160 char *discovering_type = NULL;
2164 proxy = _bt_get_adapter_properties_proxy();
2165 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2167 if (discovery_type == DISCOVERY_ROLE_BREDR)
2168 discovering_type = "Discovering";
2169 else if (discovery_type == DISCOVERY_ROLE_LE)
2170 discovering_type = "LEDiscovering";
2172 result = g_dbus_proxy_call_sync(proxy,
2174 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2176 G_DBUS_CALL_FLAGS_NONE,
2182 if (error != NULL) {
2183 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2184 g_clear_error(&error);
2186 BT_ERR("Failed to get discovering property");
2187 return BLUETOOTH_ERROR_INTERNAL;
2190 g_variant_get(result, "(v)", &temp);
2191 discovering_v = g_variant_get_boolean(temp);
2192 BT_DBG("discoverable_v:%d", discovering_v);
2194 g_variant_unref(result);
2195 g_variant_unref(temp);
2197 return discovering_v;
2200 unsigned int _bt_get_discoverable_timeout_property(void)
2203 unsigned int timeout_v;
2204 GError *error = NULL;
2208 proxy = _bt_get_adapter_properties_proxy();
2209 retv_if(proxy == NULL, 0);
2211 result = g_dbus_proxy_call_sync(proxy,
2213 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2214 "DiscoverableTimeout"),
2215 G_DBUS_CALL_FLAGS_NONE,
2221 BT_ERR("Fail to get discoverable timeout");
2222 if (error != NULL) {
2223 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2224 g_clear_error(&error);
2229 g_variant_get(result, "(v)", &temp);
2230 timeout_v = g_variant_get_uint32(temp);
2231 BT_DBG("discoverable_v:%d", timeout_v);
2233 g_variant_unref(result);
2234 g_variant_unref(temp);
2239 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2241 bluetooth_device_info_t *dev_info;
2244 GByteArray *manufacturer_data = NULL;
2246 GVariantIter *char_value_iter;
2248 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2250 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2255 if (!g_strcmp0(key, "Address")) {
2256 const char *address = NULL;
2257 address = g_variant_get_string(value, NULL);
2258 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2260 } else if(!g_strcmp0(key, "Class")) {
2262 cod = g_variant_get_uint32(value);
2263 _bt_divide_device_class(&dev_info->device_class, cod);
2264 } else if(!g_strcmp0(key, "Name")) {
2265 const char *name = NULL;
2266 name = g_variant_get_string(value, NULL);
2267 /* If there is no Alias */
2268 if (strlen(dev_info->device_name.name) == 0) {
2269 g_strlcpy(dev_info->device_name.name, name,
2270 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2272 } else if(!g_strcmp0(key, "Alias")) {
2273 const char *alias = NULL;
2274 alias = g_variant_get_string(value, NULL);
2275 /* Overwrite the name */
2277 memset(dev_info->device_name.name, 0x00,
2278 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2279 g_strlcpy(dev_info->device_name.name, alias,
2280 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2282 } else if (!g_strcmp0(key, "Connected")) {
2283 dev_info->connected = g_variant_get_byte(value);
2284 } else if (!g_strcmp0(key, "Paired")) {
2285 dev_info->paired = g_variant_get_boolean(value);
2286 } else if (!g_strcmp0(key, "Trusted")) {
2287 dev_info->trust = g_variant_get_boolean(value);
2288 } else if (!g_strcmp0(key, "RSSI")) {
2289 dev_info->rssi = g_variant_get_int16(value);
2290 } else if (!g_strcmp0(key, "UUIDs")) {
2296 dev_info->service_index = 0;
2297 g_variant_get(value, "as", &iter);
2298 while (g_variant_iter_loop(iter, "s", &uuid)) {
2299 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2300 parts = g_strsplit(uuid, "-", -1);
2302 if (parts == NULL || parts[0] == NULL) {
2307 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2312 dev_info->service_index = i;
2313 g_variant_iter_free(iter);
2314 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2315 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2316 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2317 manufacturer_data = g_byte_array_new();
2318 g_variant_get(value, "ay", &char_value_iter);
2319 while(g_variant_iter_loop(char_value_iter, "y", &char_value)) {
2320 g_byte_array_append(manufacturer_data, &char_value, 1);
2322 if (manufacturer_data) {
2323 if (manufacturer_data->len > 0) {
2324 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2327 g_variant_iter_free(char_value_iter);
2328 g_byte_array_free(manufacturer_data, TRUE);
2335 static void __bt_extract_device_info(GVariantIter *iter,
2338 bluetooth_device_info_t *dev_info = NULL;
2339 char *object_path = NULL;
2340 GVariantIter *interface_iter;
2341 GVariantIter *svc_iter;
2342 char *interface_str = NULL;
2344 /* Parse the signature: oa{sa{sv}}} */
2345 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2348 if (object_path == NULL)
2351 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2352 &interface_str, &svc_iter)) {
2353 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2354 BT_DBG("Found a device: %s", object_path);
2355 dev_info = __bt_parse_device_info(svc_iter);
2357 if (dev_info->paired == TRUE) {
2358 g_array_append_vals(*dev_list, dev_info,
2359 sizeof(bluetooth_device_info_t));
2363 g_free(interface_str);
2364 g_variant_iter_free(svc_iter);
2372 int _bt_get_bonded_devices(GArray **dev_list)
2375 GDBusConnection *conn;
2376 GDBusProxy *manager_proxy;
2377 GVariant *result = NULL;
2378 GVariantIter *iter = NULL;
2379 GError *error = NULL;
2381 conn = _bt_get_system_conn();
2382 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2384 manager_proxy = _bt_get_manager_proxy();
2385 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2387 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2389 G_DBUS_CALL_FLAGS_NONE,
2395 if (error != NULL) {
2396 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2397 g_clear_error(&error);
2399 BT_ERR("Failed to Failed to GetManagedObjects");
2400 return BLUETOOTH_ERROR_INTERNAL;
2403 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2404 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2406 __bt_extract_device_info(iter, dev_list);
2407 g_variant_iter_free(iter);
2408 g_variant_unref(result);
2411 return BLUETOOTH_ERROR_NONE;
2414 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2415 bluetooth_device_info_t *dev_info)
2417 char *object_path = NULL;
2418 GDBusProxy *adapter_proxy;
2419 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2420 int ret = BLUETOOTH_ERROR_NONE;
2422 BT_CHECK_PARAMETER(device_address, return);
2423 BT_CHECK_PARAMETER(dev_info, return);
2425 adapter_proxy = _bt_get_adapter_proxy();
2426 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2428 _bt_convert_addr_type_to_string(address, device_address->addr);
2430 object_path = _bt_get_device_object_path(address);
2432 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2434 ret = __bt_get_bonded_device_info(object_path, dev_info);
2435 g_free(object_path);
2440 int _bt_get_timeout_value(int *timeout)
2442 time_t current_time;
2445 /* Take current time */
2446 time(¤t_time);
2447 time_diff = difftime(current_time, visible_timer.start_time);
2449 BT_DBG("Time diff = %d\n", time_diff);
2451 *timeout = visible_timer.timeout - time_diff;
2453 return BLUETOOTH_ERROR_NONE;
2456 int _bt_set_le_privacy(gboolean set_privacy)
2459 GError *error = NULL;
2460 GVariant *result = NULL;
2462 if (__bt_is_factory_test_mode()) {
2463 BT_ERR("Unable to set le privacy in factory binary !!");
2464 return BLUETOOTH_ERROR_NOT_SUPPORT;
2467 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2468 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2469 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2472 proxy = _bt_get_adapter_proxy();
2473 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2475 result = g_dbus_proxy_call_sync(proxy,
2477 g_variant_new("(b)", set_privacy),
2478 G_DBUS_CALL_FLAGS_NONE,
2484 if (error != NULL) {
2485 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2486 g_clear_error(&error);
2488 BT_ERR("Failed to SetLePrivacy");
2489 return BLUETOOTH_ERROR_INTERNAL;
2492 g_variant_unref(result);
2493 BT_INFO("SetLePrivacy as %d", set_privacy);
2494 return BLUETOOTH_ERROR_NONE;
2497 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2500 GError *error = NULL;
2504 GVariantBuilder *builder;
2506 BT_CHECK_PARAMETER(m_data, return);
2508 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2509 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2510 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2513 proxy = _bt_get_adapter_proxy();
2514 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2516 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2518 for (i = 0; i < (m_data->data_len) + 2; i++) {
2519 g_variant_builder_add(builder, "y", m_data->data[i]);
2522 val = g_variant_new("(ay)", builder);
2524 result = g_dbus_proxy_call_sync(proxy,
2525 "SetManufacturerData",
2527 G_DBUS_CALL_FLAGS_NONE,
2531 g_variant_builder_unref(builder);
2533 if (error != NULL) {
2534 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2535 g_clear_error(&error);
2537 BT_ERR("Failed to SetManufacturerData");
2539 return BLUETOOTH_ERROR_INTERNAL;
2541 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2543 for (i = 0; i < (m_data->data_len) + 2; i++) {
2544 g_variant_builder_add(builder, "y", m_data->data[i]);
2547 val = g_variant_new("(ay)", builder);
2549 _bt_send_event(BT_ADAPTER_EVENT,
2550 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2553 BT_INFO("Set manufacturer data");
2555 g_variant_builder_unref(builder);
2556 g_variant_unref(result);
2558 return BLUETOOTH_ERROR_NONE;