2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <syspopup_caller.h>
27 #include <eventsystem.h>
28 #include <bundle_internal.h>
31 #include "bluetooth-api.h"
32 #include "bt-internal-types.h"
33 #include "bt-service-common.h"
34 #include "bt-service-event.h"
35 #include "bt-service-adapter.h"
36 #include "bt-service-util.h"
37 #include "bt-service-network.h"
38 #include "bt-service-obex-server.h"
39 #include "bt-service-opp-client.h"
40 #include "bt-service-map-client.h"
41 #include "bt-service-agent.h"
42 #include "bt-service-main.h"
43 #include "bt-service-avrcp.h"
44 #include "bt-service-device.h"
45 #ifdef TIZEN_FEATURE_BT_DPM
46 #include "bt-service-dpm.h"
56 bt_adapter_timer_t visible_timer = {0, };
60 bt_set_alarm_cb callback;
65 gboolean is_alarm_initialized;
67 } bt_service_alarm_mgr_t;
69 #define BT_RECOVERY_MAX_COUNT 3
71 static bt_service_alarm_mgr_t alarm_mgr = {0, };
73 static gboolean is_discovering;
74 static gboolean cancel_by_user;
75 static bt_status_t adapter_status = BT_DEACTIVATED;
76 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
77 static gboolean is_le_intended = FALSE;
78 static void *adapter_agent = NULL;
79 static GDBusProxy *core_proxy = NULL;
80 static guint timer_id = 0;
81 static guint le_timer_id = 0;
82 static int recovery_cnt = -1;
83 static guint recovery_timer = 0;
85 static uint status_reg_id;
87 #define BT_CORE_NAME "org.projectx.bt_core"
88 #define BT_CORE_PATH "/org/projectx/bt_core"
89 #define BT_CORE_INTERFACE "org.projectx.btcore"
91 #define BT_DISABLE_TIME 500 /* 500 ms */
92 #ifdef TIZEN_PROFILE_WEARABLE
93 #define BT_RECOVERY_TIME 2000 /*2 sec*/
95 #define BT_RECOVERY_TIME 5000 /*5 sec*/
98 static int alarm_cb(alarm_id_t alarm_id, void* user_param);
99 static void alarm_data_free(void *data);
101 GDBusProxy *_bt_init_core_proxy(void)
104 GDBusConnection *conn;
106 conn = _bt_gdbus_get_system_gconn();
110 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
125 static GDBusProxy *__bt_get_core_proxy(void)
127 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
130 static gboolean __bt_is_factory_test_mode(void)
134 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
135 BT_ERR("Get the DUT Mode fail");
140 BT_INFO("DUT Test Mode !!");
147 static gboolean __bt_timeout_handler(gpointer user_data)
149 int result = BLUETOOTH_ERROR_NONE;
153 /* Take current time */
155 time_diff = difftime(current_time, visible_timer.start_time);
157 /* Send event to application */
158 _bt_send_event(BT_ADAPTER_EVENT,
159 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
160 g_variant_new("(in)", result, time_diff));
162 if (visible_timer.timeout <= time_diff) {
163 g_source_remove(visible_timer.event_id);
164 visible_timer.event_id = 0;
165 visible_timer.timeout = 0;
167 #ifndef TIZEN_PROFILE_WEARABLE
168 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
169 BT_ERR("Set vconf failed\n");
177 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
180 int result = BLUETOOTH_ERROR_NONE;
183 if (alarm_id != visible_timer.alarm_id)
186 if (visible_timer.event_id) {
187 _bt_send_event(BT_ADAPTER_EVENT,
188 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
189 g_variant_new("(in)", result, timeout));
190 g_source_remove(visible_timer.event_id);
191 visible_timer.event_id = 0;
192 visible_timer.timeout = 0;
194 #ifndef TIZEN_PROFILE_WEARABLE
195 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
196 BT_ERR("Set vconf failed\n");
199 /* Switch Off visibility in Bluez */
200 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
201 visible_timer.alarm_id = 0;
205 static void __bt_visibility_alarm_remove()
207 if (visible_timer.event_id > 0) {
208 g_source_remove(visible_timer.event_id);
209 visible_timer.event_id = 0;
212 if (visible_timer.alarm_id > 0) {
213 _bt_service_remove_alarm(visible_timer.alarm_id);
214 visible_timer.alarm_id = 0;
218 int __bt_set_visible_time(int timeout)
222 #ifndef TIZEN_PROFILE_WEARABLE
223 #ifdef TIZEN_FEATURE_BT_DPM
224 int discoverable_state = DPM_BT_ERROR;
228 __bt_visibility_alarm_remove();
230 visible_timer.timeout = timeout;
232 #ifndef TIZEN_PROFILE_WEARABLE
233 #ifdef TIZEN_FEATURE_BT_DPM
234 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
235 if (discoverable_state != DPM_RESTRICTED) {
237 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
238 BT_ERR("Set vconf failed");
239 #ifdef TIZEN_FEATURE_BT_DPM
246 return BLUETOOTH_ERROR_NONE;
248 result = _bt_service_set_alarm(visible_timer.timeout,
249 __bt_visibility_alarm_cb, NULL, &alarm_id);
250 if (result != BLUETOOTH_ERROR_NONE)
251 return BLUETOOTH_ERROR_INTERNAL;
252 visible_timer.alarm_id = alarm_id;
253 /* Take start time */
254 time(&(visible_timer.start_time));
255 visible_timer.event_id = g_timeout_add_seconds(1,
256 __bt_timeout_handler, NULL);
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 gchar *address = 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_gdbus_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 g_variant_get(value, "s", &address);
356 } else if (!g_strcmp0(key, "Alias")) {
357 g_variant_get(value, "s", &name);
358 } else if (!g_strcmp0(key, "Name")) {
360 g_variant_get(value, "s", &name);
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 g_variant_iter_free(char_value_iter);
381 if (manufacturer_data) {
382 if (manufacturer_data->len > 0) {
383 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
384 manufacturer_data->len);
387 g_byte_array_free(manufacturer_data, TRUE);
390 g_variant_iter_free(property_iter);
392 BT_DBG("trust: %d, paired: %d", trust, paired);
394 g_variant_unref(result);
396 if ((paired == FALSE) && (trust == FALSE)) {
399 return BLUETOOTH_ERROR_NOT_PAIRED;
402 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
405 _bt_divide_device_class(&dev_info->device_class, cod);
407 g_strlcpy(dev_info->device_name.name, name,
408 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
410 dev_info->rssi = rssi;
411 dev_info->trust = trust;
412 dev_info->paired = paired;
413 dev_info->connected = connected;
414 ret = BLUETOOTH_ERROR_NONE;
421 void _bt_set_discovery_status(gboolean mode)
423 is_discovering = mode;
426 void _bt_set_cancel_by_user(gboolean value)
428 cancel_by_user = value;
431 gboolean _bt_get_cancel_by_user(void)
433 return cancel_by_user;
436 void _bt_adapter_set_status(bt_status_t status)
438 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
439 adapter_status = status;
442 bt_status_t _bt_adapter_get_status(void)
444 return adapter_status;
447 void _bt_adapter_set_le_status(bt_le_status_t status)
449 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
450 adapter_le_status = status;
453 bt_le_status_t _bt_adapter_get_le_status(void)
455 return adapter_le_status;
459 void _bt_set_le_intended_status(gboolean value)
461 is_le_intended = value;
464 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
466 char *phone_name = NULL;
472 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
473 phone_name = vconf_keynode_get_str(node);
475 if (phone_name && strlen(phone_name) != 0) {
476 if (!g_utf8_validate(phone_name, -1,
477 (const char **)&ptr))
480 _bt_set_local_name(phone_name);
485 static void __bt_set_local_name(void)
487 bluetooth_device_name_t local_name;
488 char *phone_name = NULL;
492 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
493 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
494 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
499 if (strlen(phone_name) != 0) {
500 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
503 _bt_set_local_name(phone_name);
509 static int __bt_set_enabled(void)
511 int adapter_status = BT_ADAPTER_DISABLED;
512 int result = BLUETOOTH_ERROR_NONE;
515 BT_DBG("g_source is removed");
516 g_source_remove(timer_id);
520 _bt_check_adapter(&adapter_status);
522 if (adapter_status == BT_ADAPTER_DISABLED) {
523 BT_ERR("Bluetoothd is not running");
524 return BLUETOOTH_ERROR_INTERNAL;
527 #if defined(TIZEN_PROFILE_MOBILE) || defined(TIZEN_PROFILE_IVI)
528 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
529 if (_bt_set_discoverable_mode(
530 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
531 BT_ERR("Set connectable mode failed");
533 #ifdef TIZEN_PROFILE_TV
534 if (_bt_set_discoverable_mode(
535 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
536 BT_ERR("Fail to set discoverable mode");
540 /* Update Bluetooth Status to notify other modules */
541 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
542 BT_ERR("Set vconf failed\n");
544 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
545 BT_ERR("Set vconf failed\n");
547 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
548 EVT_VAL_BT_ON) != ES_R_OK)
549 BT_ERR("Fail to set value");
551 /* Send enabled event to API */
552 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
553 g_variant_new("(i)", result));
555 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
556 _bt_audio_start_auto_connect(FALSE);
559 __bt_set_local_name();
560 _bt_set_discovery_status(FALSE);
562 return BLUETOOTH_ERROR_NONE;
565 void _bt_set_disabled(int result)
567 int power_off_status = 0;
570 int pm_ignore_mode = 0;
572 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
573 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
575 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
577 /* Update the vconf BT status in normal Deactivation case only */
578 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
579 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
581 BT_DBG("Update vconf for BT normal Deactivation");
583 if (result == BLUETOOTH_ERROR_TIMEOUT)
584 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
585 BT_ERR("Set vconf failed");
587 /* Update Bluetooth Status to notify other modules */
588 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
589 BT_ERR("Set vconf failed");
591 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
592 EVT_VAL_BT_OFF) != ES_R_OK)
593 BT_ERR("Fail to set value");
596 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
597 BT_ERR("Set vconf failed\n");
599 _bt_cancel_queued_transfers();
600 _bt_adapter_set_status(BT_DEACTIVATED);
601 _bt_set_discovery_status(FALSE);
603 BT_INFO("Adapter disabled");
606 static int __bt_set_le_enabled(void)
609 int result = BLUETOOTH_ERROR_NONE;
612 /* Update Bluetooth Status to notify other modules */
613 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
614 BT_ERR("Set vconf failed\n");
616 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
617 EVT_VAL_BT_LE_ON) != ES_R_OK)
618 BT_ERR("Fail to set value");
620 /* Send enabled event to API */
622 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
623 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
625 status = _bt_adapter_get_status();
626 if (status == BT_DEACTIVATED) {
627 BT_INFO("BREDR is off, turn off PSCAN");
628 _bt_set_connectable(FALSE);
630 if (le_timer_id > 0) {
631 g_source_remove(le_timer_id);
635 /* Send enabled event to API */
636 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
637 g_variant_new("(i)", result));
639 __bt_set_local_name();
642 return BLUETOOTH_ERROR_NONE;
645 void _bt_set_le_disabled(int result)
647 int power_off_status;
650 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
651 BT_DBG("ret : %d", ret);
652 BT_DBG("power_off_status : %d", power_off_status);
654 /* Update Bluetooth Status to notify other modules */
655 BT_DBG("Update vconf for BT LE normal Deactivation");
656 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
657 BT_ERR("Set vconf failed\n");
658 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
660 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
661 EVT_VAL_BT_LE_OFF) != ES_R_OK)
662 BT_ERR("Fail to set value");
664 /* Send disabled event */
665 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
666 g_variant_new("(i)", result));
669 void *_bt_get_adapter_agent(void)
671 return adapter_agent;
674 int _bt_enable_core(void)
678 GError *error = NULL;
680 proxy = __bt_get_core_proxy();
681 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
683 /* Clean up the process */
684 result = g_dbus_proxy_call_sync(proxy,
687 G_DBUS_CALL_FLAGS_NONE,
694 BT_ERR("Bt core call failed(Error: %s)", error->message);
695 g_clear_error(&error);
697 BT_ERR("Bt core call failed");
698 return BLUETOOTH_ERROR_INTERNAL;
701 g_variant_unref(result);
702 return BLUETOOTH_ERROR_NONE;
705 #if defined(TIZEN_FEATURE_FLIGHTMODE_ENABLED) || (!defined(TIZEN_PROFILE_WEARABLE))
706 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
708 gboolean flight_mode = FALSE;
709 int power_saving_mode = 0;
712 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
713 type = vconf_keynode_get_type(node);
714 if (type == VCONF_TYPE_BOOL) {
715 flight_mode = vconf_keynode_get_bool(node);
716 if (flight_mode != TRUE) {
717 BT_ERR("Ignore the event");
720 } else if (type == VCONF_TYPE_INT) {
721 power_saving_mode = vconf_keynode_get_int(node);
722 if (power_saving_mode != 2) {
723 BT_ERR("Ignore the event");
727 BT_ERR("Invaild vconf key type : %d", type);
735 void _bt_service_register_vconf_handler(void)
739 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
740 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
741 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
742 BT_ERR("Unable to register key handler");
744 BT_DBG("Telephony is disabled");
747 #ifndef TIZEN_PROFILE_WEARABLE
748 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
749 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
750 BT_ERR("Unable to register key handler");
754 void _bt_service_unregister_vconf_handler(void)
758 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
759 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
760 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
763 #ifndef TIZEN_PROFILE_WEARABLE
764 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
765 (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 BT_DBG("bt state set event(%s) received", event_name);
775 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
776 BT_DBG("bt_state: (%s)", bt_status);
778 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
779 BT_DBG("bt_state: (%s)", bt_le_status);
782 static gboolean __bt_adapter_recovery_cb(gpointer data)
790 _bt_service_initialize();
792 ret = _bt_enable_adapter_check_status();
793 if (ret == BLUETOOTH_ERROR_NONE) {
794 ret = _bt_enable_adapter();
796 BT_ERR("_bt_enable_adapter() failed");
798 ret = _bt_enable_adapter_le();
800 BT_ERR("_bt_enable_adapter_le() failed");
810 void _bt_handle_adapter_added(void)
814 bt_le_status_t le_status;
818 BT_DBG("g_source is removed");
819 g_source_remove(timer_id);
826 status = _bt_adapter_get_status();
827 le_status = _bt_adapter_get_le_status();
828 BT_DBG("status : %d", status);
829 BT_DBG("le_status : %d", le_status);
831 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
832 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
833 if (!adapter_agent) {
834 BT_ERR("Fail to register agent");
838 if (adapter_agent == NULL) {
839 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
840 if (!adapter_agent) {
841 BT_ERR("Fail to register agent");
847 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
848 BT_ERR("Fail to register media player");
850 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
851 BT_ERR("Fail to init obex server");
853 #ifdef TIZEN_BT_PAN_NAP_ENABLED
854 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
855 BT_ERR("Fail to activate network");
858 /* add the vconf noti handler */
859 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
860 __bt_phone_name_changed_cb, NULL);
862 BT_ERR("Unable to register key handler");
864 if (le_status == BT_LE_ACTIVATING ||
865 status == BT_ACTIVATING) {
866 __bt_set_le_enabled();
867 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
870 if (status == BT_ACTIVATING) {
872 _bt_adapter_set_status(BT_ACTIVATED);
876 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
877 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
878 BT_ERR("Fail to register system event");
882 void _bt_handle_adapter_removed(void)
886 _bt_adapter_set_status(BT_DEACTIVATED);
888 __bt_visibility_alarm_remove();
890 if (alarm_mgr.is_alarm_initialized == TRUE) {
892 alarm_mgr.is_alarm_initialized = FALSE;
893 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
894 alarm_mgr.g_alarm_list = NULL;
897 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
898 _bt_audio_stop_auto_connect();
901 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
902 (vconf_callback_fn)__bt_phone_name_changed_cb);
904 ERR("vconf_ignore_key_changed failed\n");
906 /* unregister all the services/servers/profiles registered on bluez-adapter
907 once adapter is removed, reinitializing of the state-varaibles becomes
909 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
910 BT_ERR("Fail to unregister obex server");
912 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
913 BT_ERR("Fail to unregister media player");
915 /* Other unregister APIs should be placed here */
917 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
918 _bt_destroy_agent(adapter_agent);
919 adapter_agent = NULL;
921 if (recovery_cnt > 0) {
922 /* Send disabled event */
923 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
924 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
925 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
927 if (recovery_timer > 0)
928 g_source_remove(recovery_timer);
929 recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
930 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
932 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
933 BT_ERR("Fail to unregister system event");
937 _bt_reliable_terminate_service(NULL);
940 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
941 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
942 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
945 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
946 BT_ERR("Fail to unregister system event");
949 static gboolean __bt_enable_timeout_cb(gpointer user_data)
953 GError *error = NULL;
957 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
959 BT_ERR("EnableAdapter is failed");
961 proxy = __bt_get_core_proxy();
965 /* Clean up the process */
966 result = g_dbus_proxy_call_sync(proxy,
969 G_DBUS_CALL_FLAGS_NONE,
976 BT_ERR("Bt core call failed(Error: %s)", error->message);
977 g_clear_error(&error);
979 BT_ERR("Bt core call failed");
984 g_variant_unref(result);
985 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
987 if (recovery_cnt > 0) {
988 BT_ERR("Try recovery again(remain:%d)", recovery_cnt);
989 if (recovery_timer > 0)
990 g_source_remove(recovery_timer);
991 recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
992 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
997 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
998 _bt_terminate_service(NULL);
1004 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
1008 GError *error = NULL;
1012 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
1014 BT_ERR("EnableAdapterLE is failed");
1016 proxy = __bt_get_core_proxy();
1020 /* Clean up the process */
1021 result = g_dbus_proxy_call_sync(proxy,
1024 G_DBUS_CALL_FLAGS_NONE,
1030 if (error != NULL) {
1031 BT_ERR("Bt core call failed(Error: %s)", error->message);
1032 g_clear_error(&error);
1034 BT_ERR("Bt core call failed");
1038 g_variant_unref(result);
1040 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED)
1041 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
1043 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1044 _bt_terminate_service(NULL);
1049 void _bt_adapter_start_le_enable_timer(void)
1051 if (le_timer_id > 0) {
1052 g_source_remove(le_timer_id);
1056 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1057 __bt_enable_le_timeout_cb, NULL);
1062 void _bt_adapter_start_enable_timer(void)
1065 g_source_remove(timer_id);
1069 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1070 __bt_enable_timeout_cb, NULL);
1075 #ifdef TIZEN_PROFILE_TV
1076 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1081 _bt_adapter_set_status(BT_ACTIVATED);
1087 int _bt_enable_adapter_check_status(void)
1089 bt_status_t status = _bt_adapter_get_status();
1090 bt_le_status_t le_status = _bt_adapter_get_le_status();
1094 if (status == BT_ACTIVATING) {
1095 BT_ERR("Enabling in progress");
1096 return BLUETOOTH_ERROR_IN_PROGRESS;
1099 if (status == BT_ACTIVATED) {
1100 BT_ERR("Already enabled");
1101 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1104 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1105 BT_ERR("Disabling in progress");
1106 return BLUETOOTH_ERROR_DEVICE_BUSY;
1109 return BLUETOOTH_ERROR_NONE;
1112 int _bt_enable_adapter(void)
1115 GError *error = NULL;
1117 GVariant *result = NULL;
1118 bt_status_t status = _bt_adapter_get_status();
1119 bt_le_status_t le_status = _bt_adapter_get_le_status();
1123 if (status == BT_ACTIVATING) {
1124 BT_ERR("Enabling in progress");
1125 return BLUETOOTH_ERROR_IN_PROGRESS;
1128 if (status == BT_ACTIVATED) {
1129 BT_ERR("Already enabled");
1130 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1133 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1134 BT_ERR("Disabling in progress");
1135 return BLUETOOTH_ERROR_DEVICE_BUSY;
1138 _bt_adapter_set_status(BT_ACTIVATING);
1140 #ifdef TIZEN_PROFILE_TV
1142 int adapter_status = BT_ADAPTER_DISABLED;
1144 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1145 BT_ERR("Set vconf failed");
1147 _bt_check_adapter(&adapter_status);
1148 if (adapter_status == BT_ADAPTER_ENABLED) {
1149 g_idle_add(__bt_adapter_enabled_cb, NULL);
1150 _bt_adapter_start_enable_timer();
1151 return BLUETOOTH_ERROR_NONE;
1156 proxy = __bt_get_core_proxy();
1158 return BLUETOOTH_ERROR_INTERNAL;
1160 if (le_status == BT_LE_ACTIVATED) {
1161 BT_INFO("LE Already enabled. Just turn on PSCAN");
1162 ret = _bt_set_connectable(TRUE);
1163 if (ret == BLUETOOTH_ERROR_NONE)
1164 _bt_adapter_set_status(BT_ACTIVATED);
1166 return BLUETOOTH_ERROR_INTERNAL;
1169 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1171 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1174 BT_ERR("EnableAdapterLe failed: %s", error->message);
1175 _bt_adapter_set_status(BT_DEACTIVATED);
1176 g_clear_error(&error);
1178 result = g_dbus_proxy_call_sync(proxy,
1181 G_DBUS_CALL_FLAGS_NONE,
1186 if (error != NULL) {
1187 BT_ERR("Bt core call failed(Error: %s)", error->message);
1188 g_clear_error(&error);
1190 g_variant_unref(result);
1191 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
1192 /* Terminate myself */
1193 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1195 return BLUETOOTH_ERROR_INTERNAL;
1197 g_variant_unref(result);
1198 if (le_status == BT_LE_ACTIVATED)
1201 _bt_adapter_start_enable_timer();
1203 return BLUETOOTH_ERROR_NONE;
1206 static gboolean __bt_disconnect_all(void)
1209 GDBusConnection *conn;
1210 GDBusProxy *dev_proxy;
1211 gboolean ret = FALSE;
1213 GError *error = NULL;
1214 GArray *device_list;
1215 bluetooth_device_info_t info;
1217 char *device_path = NULL;
1218 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1223 conn = _bt_gdbus_get_system_gconn();
1225 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1227 if (_bt_get_bonded_devices(&device_list)
1228 != BLUETOOTH_ERROR_NONE) {
1229 g_array_free(device_list, TRUE);
1233 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1235 for (i = 0; i < size; i++) {
1237 info = g_array_index(device_list,
1238 bluetooth_device_info_t, i);
1240 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1241 BT_DBG("Found Connected device");
1242 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1243 device_path = _bt_get_device_object_path(address);
1244 if (device_path == NULL)
1247 BT_DBG("Disconnecting : %s", device_path);
1249 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1253 BT_DEVICE_INTERFACE,
1256 if (dev_proxy == NULL)
1259 result = g_dbus_proxy_call_sync(dev_proxy,
1262 G_DBUS_CALL_FLAGS_NONE,
1268 if (error != NULL) {
1269 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1270 g_clear_error(&error);
1272 BT_ERR("Disconnect call failed");
1273 g_object_unref(dev_proxy);
1277 g_variant_unref(result);
1278 g_object_unref(dev_proxy);
1282 g_array_free(device_list, TRUE);
1288 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1291 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1292 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
1293 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
1299 int _bt_disable_cb(void)
1307 GError *error = NULL;
1309 _bt_adapter_set_status(BT_DEACTIVATING);
1311 bt_le_status_t le_status;
1312 le_status = _bt_adapter_get_le_status();
1313 BT_DBG("le_status : %d", le_status);
1314 if (le_status == BT_LE_ACTIVATED) {
1315 BT_INFO("LE is enabled. Just turn off PSCAN");
1317 if (_bt_is_discovering())
1318 _bt_cancel_discovery();
1320 if (_bt_is_connectable() == FALSE) {
1321 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1323 ret = _bt_set_connectable(FALSE);
1324 if (ret != BLUETOOTH_ERROR_NONE) {
1325 BT_ERR("_bt_set_connectable fail!");
1326 _bt_adapter_set_status(BT_ACTIVATED);
1327 return BLUETOOTH_ERROR_INTERNAL;
1332 proxy = __bt_get_core_proxy();
1333 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1335 result = g_dbus_proxy_call_sync(proxy,
1338 G_DBUS_CALL_FLAGS_NONE,
1344 if (error != NULL) {
1345 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1346 g_clear_error(&error);
1348 BT_ERR("Failed to DisableAdapter");
1349 _bt_adapter_set_status(BT_ACTIVATED);
1350 return BLUETOOTH_ERROR_INTERNAL;
1353 g_variant_unref(result);
1354 return BLUETOOTH_ERROR_NONE;
1357 int _bt_disable_adapter_check_status(void)
1359 bt_status_t status = _bt_adapter_get_status();
1363 if (status == BT_DEACTIVATING) {
1364 BT_DBG("Disabling in progress");
1365 return BLUETOOTH_ERROR_IN_PROGRESS;
1368 if (status == BT_DEACTIVATED) {
1369 BT_DBG("Already disabled");
1370 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1373 return BLUETOOTH_ERROR_NONE;
1376 int _bt_disable_adapter(void)
1381 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1382 BT_DBG("Disabling in progress");
1383 return BLUETOOTH_ERROR_IN_PROGRESS;
1386 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1387 BT_DBG("Already disabled");
1388 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1392 g_source_remove(timer_id);
1395 /* unregister all the services/servers/profiles registered on bluez-adapter
1396 once adapter is removed, reinitializing of the state-varaibles becomes
1398 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1399 BT_ERR("Fail to unregister obex server");
1401 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
1402 BT_ERR("Fail to unregister media player");
1404 /* Other unregister APIs should be placed here */
1405 __bt_disconnect_all();
1406 ret = _bt_disable_cb();
1412 int _bt_recover_adapter(void)
1416 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1417 BT_DBG("Disabling in progress");
1418 return BLUETOOTH_ERROR_IN_PROGRESS;
1421 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1422 BT_DBG("Already disabled");
1423 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1426 recovery_cnt = BT_RECOVERY_MAX_COUNT;
1428 _bt_disable_adapter();
1429 _bt_disable_adapter_le();
1432 return BLUETOOTH_ERROR_NONE;
1435 int _bt_reset_adapter(void)
1439 GError *error = NULL;
1443 proxy = __bt_get_core_proxy();
1445 return BLUETOOTH_ERROR_INTERNAL;
1447 result = g_dbus_proxy_call_sync(proxy,
1450 G_DBUS_CALL_FLAGS_NONE,
1456 if (error != NULL) {
1457 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1458 g_clear_error(&error);
1460 BT_ERR("Failed to ResetAdapter");
1461 return BLUETOOTH_ERROR_INTERNAL;
1464 g_variant_unref(result);
1465 /* Terminate myself */
1466 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1467 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1469 return BLUETOOTH_ERROR_NONE;
1472 #ifndef TIZEN_PROFILE_TV
1473 int _bt_check_adapter(int *status)
1476 char *adapter_path = NULL;
1478 BT_CHECK_PARAMETER(status, return);
1480 *status = BT_ADAPTER_DISABLED;
1482 adapter_path = _bt_get_adapter_path();
1485 if (adapter_path != NULL)
1486 *status = BT_ADAPTER_ENABLED;
1488 g_free(adapter_path);
1489 return BLUETOOTH_ERROR_NONE;
1492 int _bt_check_adapter(int *status)
1495 GError *error = NULL;
1498 gboolean powered = FALSE;
1500 BT_CHECK_PARAMETER(status, return);
1502 *status = BT_ADAPTER_DISABLED;
1504 proxy = _bt_get_adapter_properties_proxy();
1505 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1507 result = g_dbus_proxy_call_sync(proxy,
1509 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1511 G_DBUS_CALL_FLAGS_NONE,
1517 BT_ERR("Failed to get local address");
1518 if (error != NULL) {
1519 BT_ERR("Failed to get local address (Error: %s)", error->message);
1520 g_clear_error(&error);
1522 return BLUETOOTH_ERROR_INTERNAL;
1525 g_variant_get(result, "(v)", &temp);
1526 powered = g_variant_get_boolean(temp);
1527 BT_DBG("powered: %d", powered);
1530 *status = BT_ADAPTER_ENABLED;
1532 g_variant_unref(result);
1533 g_variant_unref(temp);
1534 return BLUETOOTH_ERROR_NONE;
1538 int _bt_enable_adapter_le(void)
1542 GError *error = NULL;
1543 bt_status_t status = _bt_adapter_get_status();
1544 bt_le_status_t le_status = _bt_adapter_get_le_status();
1547 if (le_status == BT_LE_ACTIVATING) {
1548 BT_ERR("Enabling in progress");
1549 return BLUETOOTH_ERROR_IN_PROGRESS;
1552 if (le_status == BT_LE_ACTIVATED) {
1553 BT_ERR("Already enabled");
1554 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1557 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1558 BT_ERR("Disabling in progress");
1559 return BLUETOOTH_ERROR_DEVICE_BUSY;
1562 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1564 proxy = __bt_get_core_proxy();
1565 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1567 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1569 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1572 BT_ERR("EnableAdapterLe failed: %s", error->message);
1573 _bt_adapter_set_le_status(BT_DEACTIVATED);
1574 g_clear_error(&error);
1576 /* Clean up the process */
1577 result = g_dbus_proxy_call_sync(proxy,
1580 G_DBUS_CALL_FLAGS_NONE,
1586 BT_ERR("Bt core call failed");
1588 BT_ERR("EnableAdapterLE Failed %s", error->message);
1589 g_clear_error(&error);
1592 g_variant_unref(result);
1593 /* Terminate myself */
1594 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1595 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1596 return BLUETOOTH_ERROR_INTERNAL;
1600 g_variant_unref(result);
1602 _bt_adapter_start_le_enable_timer();
1604 if (status == BT_ACTIVATED) {
1605 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1606 __bt_set_le_enabled();
1608 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1610 return BLUETOOTH_ERROR_NONE;
1613 int _bt_disable_adapter_le(void)
1617 bt_le_status_t bt_le_state;
1619 GError *error = NULL;
1621 bt_le_state = _bt_adapter_get_le_status();
1622 if (bt_le_state == BT_LE_DEACTIVATING) {
1623 BT_DBG("Disabling in progress");
1624 return BLUETOOTH_ERROR_IN_PROGRESS;
1627 if (bt_le_state == BT_LE_DEACTIVATED) {
1628 BT_DBG("Already disabled");
1629 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1632 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1634 proxy = __bt_get_core_proxy();
1636 return BLUETOOTH_ERROR_INTERNAL;
1638 result = g_dbus_proxy_call_sync(proxy,
1641 G_DBUS_CALL_FLAGS_NONE,
1647 if (error != NULL) {
1648 BT_ERR("Bt core call failed (Error: %s)", error->message);
1649 g_clear_error(&error);
1651 BT_ERR("Bt core call failed");
1652 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1653 return BLUETOOTH_ERROR_INTERNAL;
1656 g_variant_unref(result);
1657 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1658 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1660 return BLUETOOTH_ERROR_NONE;
1663 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1667 GError *error = NULL;
1668 const char *address;
1672 BT_CHECK_PARAMETER(local_address, return);
1674 proxy = _bt_get_adapter_properties_proxy();
1675 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1677 result = g_dbus_proxy_call_sync(proxy,
1679 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1681 G_DBUS_CALL_FLAGS_NONE,
1687 BT_ERR("Failed to get local address");
1688 if (error != NULL) {
1689 BT_ERR("Failed to get local address (Error: %s)", error->message);
1690 g_clear_error(&error);
1692 return BLUETOOTH_ERROR_INTERNAL;
1695 g_variant_get(result, "(v)", &temp);
1696 address = g_variant_get_string(temp, NULL);
1697 BT_DBG("Address:%s", address);
1700 _bt_convert_addr_string_to_type(local_address->addr, address);
1702 return BLUETOOTH_ERROR_INTERNAL;
1704 g_variant_unref(result);
1705 g_variant_unref(temp);
1706 return BLUETOOTH_ERROR_NONE;
1709 int _bt_get_local_version(bluetooth_version_t *local_version)
1712 const char *ver = NULL;
1714 int ret = BLUETOOTH_ERROR_NONE;
1718 BT_CHECK_PARAMETER(local_version, return);
1720 GError *error = NULL;
1722 proxy = _bt_get_adapter_properties_proxy();
1723 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1725 result = g_dbus_proxy_call_sync(proxy,
1727 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1729 G_DBUS_CALL_FLAGS_NONE,
1735 if (error != NULL) {
1736 BT_ERR("Failed to get local version (Error: %s)", error->message);
1737 g_clear_error(&error);
1739 BT_ERR("Failed to get local version");
1740 return BLUETOOTH_ERROR_INTERNAL;
1743 g_variant_get(result, "(v)", &temp);
1744 ver = g_variant_get_string(temp, NULL);
1745 BT_DBG("VERSION: %s", ver);
1747 if (ver && (strlen(ver) > 0)) {
1748 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1749 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1752 g_strlcpy(local_version->version, ver,
1753 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1756 ret = BLUETOOTH_ERROR_INTERNAL;
1759 g_variant_unref(result);
1760 g_variant_unref(temp);
1764 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1767 const char *name = NULL;
1769 int ret = BLUETOOTH_ERROR_NONE;
1772 GError *error = NULL;
1774 BT_CHECK_PARAMETER(local_name, return);
1776 proxy = _bt_get_adapter_properties_proxy();
1777 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1779 result = g_dbus_proxy_call_sync(proxy,
1781 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1783 G_DBUS_CALL_FLAGS_NONE,
1789 if (error != NULL) {
1790 BT_ERR("Failed to get local name (Error: %s)", error->message);
1791 g_clear_error(&error);
1793 BT_ERR("Failed to get local name");
1794 return BLUETOOTH_ERROR_INTERNAL;
1797 g_variant_get(result, "(v)", &temp);
1798 name = g_variant_get_string(temp, NULL);
1799 BT_DBG("LOCAL NAME:%s", name);
1801 if (name && (strlen(name) > 0)) {
1802 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1803 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1806 g_strlcpy(local_name->name, name,
1807 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1809 ret = BLUETOOTH_ERROR_INTERNAL;
1811 g_variant_unref(result);
1812 g_variant_unref(temp);
1816 int _bt_set_local_name(char *local_name)
1819 GError *error = NULL;
1823 BT_CHECK_PARAMETER(local_name, return);
1825 proxy = _bt_get_adapter_properties_proxy();
1827 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1829 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1832 result = g_dbus_proxy_call_sync(proxy,
1834 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1835 "Alias", g_variant_new("s", local_name)),
1836 G_DBUS_CALL_FLAGS_NONE,
1842 if (error != NULL) {
1843 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1844 g_clear_error(&error);
1846 BT_ERR("Failed to set Alias");
1847 return BLUETOOTH_ERROR_INTERNAL;
1850 g_variant_unref(result);
1851 return BLUETOOTH_ERROR_NONE;
1854 int _bt_is_service_used(char *service_uuid, gboolean *used)
1857 GError *error = NULL;
1858 int ret = BLUETOOTH_ERROR_NONE;
1860 GVariant *temp = NULL;
1861 GVariantIter *iter = NULL;
1865 BT_CHECK_PARAMETER(service_uuid, return);
1866 BT_CHECK_PARAMETER(used, return);
1868 proxy = _bt_get_adapter_properties_proxy();
1869 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1871 result = g_dbus_proxy_call_sync(proxy,
1873 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1875 G_DBUS_CALL_FLAGS_NONE,
1881 if (error != NULL) {
1882 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1883 g_clear_error(&error);
1885 BT_ERR("Failed to get UUIDs");
1886 return BLUETOOTH_ERROR_INTERNAL;
1889 g_variant_get(result, "(v)", &temp);
1890 g_variant_get(temp, "as", &iter);
1893 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1894 if (strcasecmp(uuid, service_uuid) == 0) {
1899 g_variant_iter_free(iter);
1900 g_variant_unref(result);
1902 BT_DBG("Service Used? %d", *used);
1907 static gboolean __bt_get_discoverable_property(void)
1910 gboolean discoverable_v;
1911 GError *error = NULL;
1915 proxy = _bt_get_adapter_properties_proxy();
1916 retv_if(proxy == NULL, FALSE);
1918 result = g_dbus_proxy_call_sync(proxy,
1920 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1922 G_DBUS_CALL_FLAGS_NONE,
1928 if (error != NULL) {
1929 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1930 g_clear_error(&error);
1932 BT_ERR("Failed to get Discoverable property");
1933 return BLUETOOTH_ERROR_INTERNAL;
1936 g_variant_get(result, "(v)", &temp);
1937 discoverable_v = g_variant_get_boolean(temp);
1938 BT_DBG("discoverable_v:%d", discoverable_v);
1940 g_variant_unref(result);
1941 g_variant_unref(temp);
1943 return discoverable_v;
1946 int _bt_get_discoverable_mode(int *mode)
1948 gboolean discoverable;
1949 unsigned int timeout;
1951 BT_CHECK_PARAMETER(mode, return);
1953 discoverable = __bt_get_discoverable_property();
1954 timeout = _bt_get_discoverable_timeout_property();
1956 if (discoverable == TRUE) {
1958 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1960 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1962 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1964 return BLUETOOTH_ERROR_NONE;
1968 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1970 int ret = BLUETOOTH_ERROR_NONE;
1973 GError *error = NULL;
1976 #ifdef TIZEN_FEATURE_BT_DPM
1977 int discoverable_state = DPM_BT_ERROR;
1980 proxy = _bt_get_adapter_properties_proxy();
1982 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1984 #ifdef TIZEN_FEATURE_BT_DPM
1985 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1986 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
1987 discoverable_state == DPM_RESTRICTED) {
1988 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT_HANDSFREE");
1989 return BLUETOOTH_ERROR_ACCESS_DENIED;
1991 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
1992 discoverable_state == DPM_RESTRICTED) {
1993 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT");
1994 return BLUETOOTH_ERROR_ACCESS_DENIED;
1998 switch (discoverable_mode) {
1999 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
2004 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
2009 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
2014 return BLUETOOTH_ERROR_INVALID_PARAM;
2017 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
2018 discoverable_mode, timeout);
2020 result = g_dbus_proxy_call_sync(proxy,
2022 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2023 "Connectable", g_variant_new("b", pg_scan)),
2024 G_DBUS_CALL_FLAGS_NONE,
2030 if (error != NULL) {
2031 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2032 g_clear_error(&error);
2034 BT_ERR("Failed to set connectable property");
2035 return BLUETOOTH_ERROR_INTERNAL;
2037 g_variant_unref(result);
2038 result = g_dbus_proxy_call_sync(proxy,
2040 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2041 g_variant_new("b", inq_scan)),
2042 G_DBUS_CALL_FLAGS_NONE,
2048 if (error != NULL) {
2049 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2050 g_clear_error(&error);
2052 BT_ERR("Failed to set Discoverable property");
2053 return BLUETOOTH_ERROR_INTERNAL;
2055 g_variant_unref(result);
2056 result = g_dbus_proxy_call_sync(proxy,
2058 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2059 "DiscoverableTimeout", g_variant_new("u", timeout)),
2060 G_DBUS_CALL_FLAGS_NONE,
2066 if (error != NULL) {
2067 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2068 g_clear_error(&error);
2070 BT_ERR("Failed to set DiscoverableTimeout property");
2071 return BLUETOOTH_ERROR_INTERNAL;
2074 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2077 ret = __bt_set_visible_time(timeout);
2079 g_variant_unref(result);
2084 int _bt_start_discovery(void)
2087 GError *error = NULL;
2090 if (_bt_is_discovering() == TRUE) {
2091 BT_ERR("BT is already in discovering");
2092 return BLUETOOTH_ERROR_IN_PROGRESS;
2093 } else if (_bt_is_device_creating() == TRUE) {
2094 BT_ERR("Bonding device is going on");
2095 return BLUETOOTH_ERROR_DEVICE_BUSY;
2098 proxy = _bt_get_adapter_proxy();
2099 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2101 result = g_dbus_proxy_call_sync(proxy,
2104 G_DBUS_CALL_FLAGS_NONE,
2110 if (error != NULL) {
2111 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2112 g_clear_error(&error);
2114 BT_ERR("StartDiscovery failed");
2115 return BLUETOOTH_ERROR_INTERNAL;
2118 is_discovering = TRUE;
2119 cancel_by_user = FALSE;
2120 /* discovery status will be change in event */
2121 g_variant_unref(result);
2122 return BLUETOOTH_ERROR_NONE;
2125 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2129 GError *error = NULL;
2130 const gchar *disc_type;
2132 if (_bt_is_discovering() == TRUE) {
2133 BT_ERR("BT is already in discovering");
2134 return BLUETOOTH_ERROR_IN_PROGRESS;
2137 proxy = _bt_get_adapter_proxy();
2138 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2140 if (role == DISCOVERY_ROLE_BREDR)
2141 disc_type = "BREDR";
2142 else if (role == DISCOVERY_ROLE_LE)
2144 else if (role == DISCOVERY_ROLE_LE_BREDR)
2145 disc_type = "LE_BREDR";
2147 return BLUETOOTH_ERROR_INVALID_PARAM;
2149 result = g_dbus_proxy_call_sync(proxy,
2150 "StartCustomDiscovery",
2151 g_variant_new("s", disc_type),
2152 G_DBUS_CALL_FLAGS_NONE,
2158 if (error != NULL) {
2159 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2160 g_clear_error(&error);
2162 BT_ERR("StartCustomDiscovery failed");
2163 return BLUETOOTH_ERROR_INTERNAL;
2166 is_discovering = TRUE;
2167 cancel_by_user = FALSE;
2168 /* discovery status will be change in event */
2169 g_variant_unref(result);
2170 return BLUETOOTH_ERROR_NONE;
2173 int _bt_cancel_discovery(void)
2176 GError *error = NULL;
2179 if (_bt_is_discovering() == FALSE) {
2180 BT_ERR("BT is not in discovering");
2181 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2184 proxy = _bt_get_adapter_proxy();
2185 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2187 result = g_dbus_proxy_call_sync(proxy,
2190 G_DBUS_CALL_FLAGS_NONE,
2196 int ret = BLUETOOTH_ERROR_INTERNAL;
2197 if (error != NULL) {
2198 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2200 if (g_strrstr(error->message, "No discovery started"))
2201 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2203 g_clear_error(&error);
2205 BT_ERR("StopDiscovery failed");
2211 cancel_by_user = TRUE;
2212 /* discovery status will be change in event */
2213 g_variant_unref(result);
2214 return BLUETOOTH_ERROR_NONE;
2217 gboolean _bt_is_discovering(void)
2219 return is_discovering;
2222 gboolean _bt_is_connectable(void)
2225 GError *error = NULL;
2226 gboolean is_connectable = FALSE;
2230 proxy = _bt_get_adapter_properties_proxy();
2231 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2233 result = g_dbus_proxy_call_sync(proxy,
2235 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2237 G_DBUS_CALL_FLAGS_NONE,
2243 if (error != NULL) {
2244 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2245 g_clear_error(&error);
2247 BT_ERR("Failed to get connectable property");
2248 return BLUETOOTH_ERROR_INTERNAL;
2251 g_variant_get(result, "(v)", &temp);
2252 is_connectable = g_variant_get_boolean(temp);
2253 BT_DBG("discoverable_v:%d", is_connectable);
2255 g_variant_unref(result);
2256 g_variant_unref(temp);
2258 BT_INFO("Get connectable [%d]", is_connectable);
2259 return is_connectable;
2262 int _bt_set_connectable(gboolean is_connectable)
2265 GError *error = NULL;
2268 if (__bt_is_factory_test_mode()) {
2269 BT_ERR("Unable to set connectable in factory binary !!");
2270 return BLUETOOTH_ERROR_NOT_SUPPORT;
2273 proxy = _bt_get_adapter_properties_proxy();
2275 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2277 result = g_dbus_proxy_call_sync(proxy,
2279 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2280 g_variant_new("b", is_connectable)),
2281 G_DBUS_CALL_FLAGS_NONE,
2287 if (error != NULL) {
2288 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2289 g_clear_error(&error);
2291 BT_ERR("Failed to set connectable property");
2292 return BLUETOOTH_ERROR_INTERNAL;
2295 BT_INFO_C("### Set connectable [%d]", is_connectable);
2296 g_variant_unref(result);
2297 return BLUETOOTH_ERROR_NONE;
2300 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2303 gboolean discovering_v;
2304 GError *error = NULL;
2305 char *discovering_type = NULL;
2309 proxy = _bt_get_adapter_properties_proxy();
2310 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2312 if (discovery_type == DISCOVERY_ROLE_BREDR)
2313 discovering_type = "Discovering";
2314 else if (discovery_type == DISCOVERY_ROLE_LE)
2315 discovering_type = "LEDiscovering";
2317 result = g_dbus_proxy_call_sync(proxy,
2319 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2321 G_DBUS_CALL_FLAGS_NONE,
2327 if (error != NULL) {
2328 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2329 g_clear_error(&error);
2331 BT_ERR("Failed to get discovering property");
2332 return BLUETOOTH_ERROR_INTERNAL;
2335 g_variant_get(result, "(v)", &temp);
2336 discovering_v = g_variant_get_boolean(temp);
2337 BT_DBG("discoverable_v:%d", discovering_v);
2339 g_variant_unref(result);
2340 g_variant_unref(temp);
2342 return discovering_v;
2345 unsigned int _bt_get_discoverable_timeout_property(void)
2348 unsigned int timeout_v;
2349 GError *error = NULL;
2353 proxy = _bt_get_adapter_properties_proxy();
2354 retv_if(proxy == NULL, 0);
2356 result = g_dbus_proxy_call_sync(proxy,
2358 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2359 "DiscoverableTimeout"),
2360 G_DBUS_CALL_FLAGS_NONE,
2366 BT_ERR("Fail to get discoverable timeout");
2367 if (error != NULL) {
2368 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2369 g_clear_error(&error);
2374 g_variant_get(result, "(v)", &temp);
2375 timeout_v = g_variant_get_uint32(temp);
2376 BT_DBG("discoverable_v:%d", timeout_v);
2378 g_variant_unref(result);
2379 g_variant_unref(temp);
2384 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2386 bluetooth_device_info_t *dev_info;
2389 GByteArray *manufacturer_data = NULL;
2391 GVariantIter *char_value_iter;
2393 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2395 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2400 if (!g_strcmp0(key, "Address")) {
2401 const char *address = NULL;
2402 address = g_variant_get_string(value, NULL);
2403 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2405 } else if (!g_strcmp0(key, "Class")) {
2407 cod = g_variant_get_uint32(value);
2408 _bt_divide_device_class(&dev_info->device_class, cod);
2409 } else if (!g_strcmp0(key, "Name")) {
2410 const char *name = NULL;
2411 name = g_variant_get_string(value, NULL);
2412 /* If there is no Alias */
2413 if (strlen(dev_info->device_name.name) == 0) {
2414 g_strlcpy(dev_info->device_name.name, name,
2415 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2417 } else if (!g_strcmp0(key, "Alias")) {
2418 const char *alias = NULL;
2419 alias = g_variant_get_string(value, NULL);
2420 /* Overwrite the name */
2422 memset(dev_info->device_name.name, 0x00,
2423 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2424 g_strlcpy(dev_info->device_name.name, alias,
2425 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2427 } else if (!g_strcmp0(key, "IsAliasSet")) {
2428 dev_info->is_alias_set = g_variant_get_boolean(value);
2429 } else if (!g_strcmp0(key, "Connected")) {
2430 dev_info->connected = g_variant_get_byte(value);
2431 } else if (!g_strcmp0(key, "Paired")) {
2432 dev_info->paired = g_variant_get_boolean(value);
2433 } else if (!g_strcmp0(key, "Trusted")) {
2434 dev_info->trust = g_variant_get_boolean(value);
2435 } else if (!g_strcmp0(key, "RSSI")) {
2436 dev_info->rssi = g_variant_get_int16(value);
2437 } else if (!g_strcmp0(key, "UUIDs")) {
2443 dev_info->service_index = 0;
2444 g_variant_get(value, "as", &iter);
2445 while (g_variant_iter_loop(iter, "s", &uuid)) {
2446 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2447 parts = g_strsplit(uuid, "-", -1);
2449 if (parts == NULL || parts[0] == NULL) {
2454 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2459 dev_info->service_index = i;
2460 g_variant_iter_free(iter);
2461 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2462 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2463 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2464 manufacturer_data = g_byte_array_new();
2465 g_variant_get(value, "ay", &char_value_iter);
2466 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2467 g_byte_array_append(manufacturer_data, &char_value, 1);
2469 if (manufacturer_data) {
2470 if (manufacturer_data->len > 0)
2471 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2473 g_variant_iter_free(char_value_iter);
2474 g_byte_array_free(manufacturer_data, TRUE);
2481 static void __bt_extract_device_info(GVariantIter *iter,
2484 bluetooth_device_info_t *dev_info = NULL;
2485 char *object_path = NULL;
2486 GVariantIter *interface_iter;
2487 GVariantIter *svc_iter;
2488 char *interface_str = NULL;
2490 /* Parse the signature: oa{sa{sv}}} */
2491 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2494 if (object_path == NULL)
2497 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2498 &interface_str, &svc_iter)) {
2499 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2500 BT_DBG("Found a device: %s", object_path);
2501 dev_info = __bt_parse_device_info(svc_iter);
2503 if (dev_info->paired == TRUE) {
2504 g_array_append_vals(*dev_list, dev_info,
2505 sizeof(bluetooth_device_info_t));
2509 g_free(interface_str);
2510 g_variant_iter_free(svc_iter);
2518 int _bt_get_bonded_devices(GArray **dev_list)
2521 GDBusConnection *conn;
2522 GDBusProxy *manager_proxy;
2523 GVariant *result = NULL;
2524 GVariantIter *iter = NULL;
2525 GError *error = NULL;
2527 conn = _bt_gdbus_get_system_gconn();
2528 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2530 manager_proxy = _bt_get_manager_proxy();
2531 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2533 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2535 G_DBUS_CALL_FLAGS_NONE,
2541 if (error != NULL) {
2542 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2543 g_clear_error(&error);
2545 BT_ERR("Failed to Failed to GetManagedObjects");
2546 return BLUETOOTH_ERROR_INTERNAL;
2549 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2550 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2552 __bt_extract_device_info(iter, dev_list);
2553 g_variant_iter_free(iter);
2554 g_variant_unref(result);
2557 return BLUETOOTH_ERROR_NONE;
2560 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2563 GDBusConnection *conn;
2564 GDBusProxy *manager_proxy;
2565 GVariant *result = NULL;
2566 GVariant *result1 = NULL;
2567 GVariantIter *iter = NULL;
2568 GError *error = NULL;
2569 char *object_path = NULL;
2570 GVariantIter *interface_iter;
2571 char *interface_str = NULL;
2572 GDBusProxy *device_proxy = NULL;
2573 gboolean is_connected = FALSE;
2575 conn = _bt_gdbus_get_system_gconn();
2576 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2578 manager_proxy = _bt_get_manager_proxy();
2579 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2581 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2583 G_DBUS_CALL_FLAGS_NONE,
2589 if (error != NULL) {
2590 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2591 g_clear_error(&error);
2594 BT_ERR("Failed to Failed to GetManagedObjects");
2595 return BLUETOOTH_ERROR_INTERNAL;
2598 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2599 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2601 /* Parse the signature: oa{sa{sv}}} */
2602 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2603 if (object_path == NULL)
2606 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2607 &interface_str, NULL)) {
2608 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2609 BT_DBG("Found a device: %s", object_path);
2610 g_free(interface_str);
2612 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2613 NULL, BT_BLUEZ_NAME,
2614 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2616 if (device_proxy == NULL) {
2617 BT_DBG("Device don't have this service");
2621 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2622 g_variant_new("(s)", profile_uuid),
2623 G_DBUS_CALL_FLAGS_NONE,
2628 if (result1 == NULL) {
2629 BT_ERR("Error occured in Proxy call");
2631 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2632 g_error_free(error);
2635 g_object_unref(device_proxy);
2638 g_variant_get(result1, "(b)", &is_connected);
2640 if (is_connected == TRUE) {
2641 char address[BT_ADDRESS_STRING_SIZE];
2642 bluetooth_device_address_t *addr = NULL;
2644 _bt_convert_device_path_to_address(object_path, address);
2646 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2647 _bt_convert_addr_string_to_type(addr->addr, address);
2649 g_array_append_vals(*addr_list, addr,
2650 sizeof(bluetooth_device_address_t));
2653 g_variant_unref(result1);
2654 g_object_unref(device_proxy);
2661 g_variant_unref(result);
2662 g_variant_iter_free(iter);
2665 return BLUETOOTH_ERROR_NONE;
2668 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2669 bluetooth_device_info_t *dev_info)
2671 char *object_path = NULL;
2672 GDBusProxy *adapter_proxy;
2673 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2674 int ret = BLUETOOTH_ERROR_NONE;
2676 BT_CHECK_PARAMETER(device_address, return);
2677 BT_CHECK_PARAMETER(dev_info, return);
2679 adapter_proxy = _bt_get_adapter_proxy();
2680 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2682 _bt_convert_addr_type_to_string(address, device_address->addr);
2684 object_path = _bt_get_device_object_path(address);
2686 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2688 ret = __bt_get_bonded_device_info(object_path, dev_info);
2689 g_free(object_path);
2694 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2696 char *object_path = NULL;
2697 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2698 gboolean alias_set = FALSE;
2700 GDBusConnection *conn;
2701 GDBusProxy *device_proxy;
2702 GError *error = NULL;
2703 GVariant *result = NULL;
2704 GVariant *temp = NULL;
2707 BT_CHECK_PARAMETER(device_address, return);
2708 BT_CHECK_PARAMETER(is_alias_set, return);
2710 _bt_convert_addr_type_to_string(address, device_address->addr);
2712 object_path = _bt_get_device_object_path(address);
2713 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2715 conn = _bt_gdbus_get_system_gconn();
2717 g_free(object_path);
2718 return BLUETOOTH_ERROR_INTERNAL;
2721 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2725 BT_PROPERTIES_INTERFACE,
2727 if (device_proxy == NULL) {
2728 g_free(object_path);
2729 return BLUETOOTH_ERROR_INTERNAL;
2732 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2733 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2734 G_DBUS_CALL_FLAGS_NONE,
2740 BT_ERR("Error occured in Proxy call");
2741 if (error != NULL) {
2742 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2743 g_error_free(error);
2745 g_object_unref(device_proxy);
2746 g_free(object_path);
2747 return BLUETOOTH_ERROR_INTERNAL;
2750 g_variant_get(result, "(v)", &temp);
2751 alias_set = g_variant_get_boolean(temp);
2752 *is_alias_set = alias_set;
2753 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2754 g_variant_unref(temp);
2755 g_variant_unref(result);
2756 g_object_unref(device_proxy);
2758 g_free(object_path);
2760 return BLUETOOTH_ERROR_NONE;
2763 int _bt_get_timeout_value(int *timeout)
2765 time_t current_time;
2768 /* Take current time */
2769 time(¤t_time);
2770 time_diff = difftime(current_time, visible_timer.start_time);
2772 BT_DBG("Time diff = %d\n", time_diff);
2774 *timeout = visible_timer.timeout - time_diff;
2776 return BLUETOOTH_ERROR_NONE;
2779 int _bt_set_le_privacy(gboolean set_privacy)
2782 GError *error = NULL;
2783 GVariant *result = NULL;
2785 if (__bt_is_factory_test_mode()) {
2786 BT_ERR("Unable to set le privacy in factory binary !!");
2787 return BLUETOOTH_ERROR_NOT_SUPPORT;
2790 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2791 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2792 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2795 proxy = _bt_get_adapter_proxy();
2796 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2798 result = g_dbus_proxy_call_sync(proxy,
2800 g_variant_new("(b)", set_privacy),
2801 G_DBUS_CALL_FLAGS_NONE,
2807 if (error != NULL) {
2808 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2809 g_clear_error(&error);
2811 BT_ERR("Failed to SetLePrivacy");
2812 return BLUETOOTH_ERROR_INTERNAL;
2815 g_variant_unref(result);
2816 BT_INFO("SetLePrivacy as %d", set_privacy);
2817 return BLUETOOTH_ERROR_NONE;
2820 int _bt_set_le_static_random_address(gboolean is_enable)
2823 GError *error = NULL;
2824 GVariant *result = NULL;
2826 if (__bt_is_factory_test_mode()) {
2827 BT_ERR("Unable to set le random address in factory binary !!");
2828 return BLUETOOTH_ERROR_NOT_SUPPORT;
2831 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2832 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2833 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2836 proxy = _bt_get_adapter_proxy();
2837 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2839 result = g_dbus_proxy_call_sync(proxy,
2840 "SetLeStaticRandomAddress",
2841 g_variant_new("(b)", is_enable),
2842 G_DBUS_CALL_FLAGS_NONE,
2848 if (error != NULL) {
2849 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2850 g_clear_error(&error);
2852 BT_ERR("Failed to SetLeStaticRandomAddress");
2853 return BLUETOOTH_ERROR_INTERNAL;
2856 g_variant_unref(result);
2857 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2858 return BLUETOOTH_ERROR_NONE;
2861 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2864 GError *error = NULL;
2868 GVariantBuilder *builder;
2870 BT_CHECK_PARAMETER(m_data, return);
2872 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2873 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2874 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2877 proxy = _bt_get_adapter_proxy();
2878 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2880 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2882 for (i = 0; i < (m_data->data_len) + 2; i++)
2883 g_variant_builder_add(builder, "y", m_data->data[i]);
2885 val = g_variant_new("(ay)", builder);
2887 result = g_dbus_proxy_call_sync(proxy,
2888 "SetManufacturerData",
2890 G_DBUS_CALL_FLAGS_NONE,
2894 g_variant_builder_unref(builder);
2896 if (error != NULL) {
2897 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2898 g_clear_error(&error);
2900 BT_ERR("Failed to SetManufacturerData");
2902 return BLUETOOTH_ERROR_INTERNAL;
2904 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2906 for (i = 0; i < (m_data->data_len) + 2; i++)
2907 g_variant_builder_add(builder, "y", m_data->data[i]);
2909 val = g_variant_new("(ay)", builder);
2911 _bt_send_event(BT_ADAPTER_EVENT,
2912 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2915 BT_INFO("Set manufacturer data");
2917 g_variant_builder_unref(builder);
2918 g_variant_unref(result);
2920 return BLUETOOTH_ERROR_NONE;
2924 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2926 int result = BLUETOOTH_ERROR_NONE;
2927 bt_service_alarm_t *alarm = NULL;
2929 if (!call_back || !alarm_id)
2930 return BLUETOOTH_ERROR_INVALID_PARAM;
2932 if (!alarm_mgr.is_alarm_initialized) {
2933 result = alarmmgr_init("bt-service");
2935 BT_ERR("Failed to initialize alarm = %d", result);
2936 result = BLUETOOTH_ERROR_INTERNAL;
2939 result = alarmmgr_set_cb(alarm_cb, NULL);
2941 BT_ERR("Failed to set the callback = %d", result);
2942 result = BLUETOOTH_ERROR_INTERNAL;
2945 alarm_mgr.is_alarm_initialized = TRUE;
2948 alarm = g_malloc0(sizeof(bt_service_alarm_t));
2950 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2952 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
2955 BT_ERR("Failed to create alarm error = %d", result);
2956 result = BLUETOOTH_ERROR_INTERNAL;
2960 alarm->alarm_id = *alarm_id;
2961 alarm->callback = call_back;
2962 alarm->user_data = user_data;
2964 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
2965 result = BLUETOOTH_ERROR_NONE;
2970 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
2973 bt_service_alarm_t *p_data;
2974 bt_set_alarm_cb callback = NULL;
2975 void *user_data = NULL;
2977 node = g_list_find_custom(alarm_mgr.g_alarm_list,
2978 GINT_TO_POINTER(alarm_id), compare_alarm);
2982 p_data = (bt_service_alarm_t *)node->data;
2983 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
2989 callback = p_data->callback;
2990 user_data = p_data->user_data;
2994 callback(alarm_id, user_data);
2999 int _bt_service_remove_alarm(alarm_id_t alarm_id)
3002 bt_service_alarm_t *p_data;
3003 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
3006 alarmmgr_remove_alarm(alarm_id);
3007 p_data = (bt_service_alarm_t *)list->data;
3008 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
3015 gint compare_alarm(gconstpointer list_data, gconstpointer data)
3018 alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
3020 alarm_id_t alarm_id = (alarm_id_t)data;
3022 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
3024 if (p_data->alarm_id == alarm_id)
3030 static void alarm_data_free(void *data)
3032 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
3037 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3041 int function = (int)(uintptr_t)user_data;
3043 int function = (int)user_data;
3047 case BT_ENABLE_ADAPTER:
3048 result = _bt_enable_adapter();
3049 if (result != BLUETOOTH_ERROR_NONE) {
3050 BT_ERR("_bt_enable_adapter is failed");
3051 /* Send enabled event to API */
3052 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3053 g_variant_new("(i)", result));
3056 case BT_DISABLE_ADAPTER:
3057 result = _bt_disable_adapter();
3058 if (result != BLUETOOTH_ERROR_NONE) {
3059 BT_ERR("_bt_disable_adapter is failed");
3060 /* Send disabled event to API */
3061 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3062 g_variant_new("(i)", result));
3066 BT_ERR("function is NOT matched");
3073 int _bt_adapter_request_delayed(int function)
3078 case BT_ENABLE_ADAPTER:
3079 ret = _bt_enable_adapter_check_status();
3080 if (ret == BLUETOOTH_ERROR_NONE)
3081 _bt_adapter_set_status(BT_ACTIVATING);
3086 case BT_DISABLE_ADAPTER:
3087 ret = _bt_disable_adapter_check_status();
3088 if (ret == BLUETOOTH_ERROR_NONE)
3089 _bt_adapter_set_status(BT_DEACTIVATING);
3095 BT_ERR("function is NOT matched");
3096 return BLUETOOTH_ERROR_INTERNAL;
3100 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3102 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3105 return BLUETOOTH_ERROR_NONE;
3108 #ifdef TIZEN_PROFILE_TV
3109 int _bt_get_enable_timer_id(void)