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>
26 #include <eventsystem.h>
27 #include <bundle_internal.h>
30 #include "bluetooth-api.h"
31 #include "bt-internal-types.h"
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
34 #include "bt-service-adapter.h"
35 #include "bt-service-util.h"
36 #include "bt-service-network.h"
37 #include "bt-service-obex-server.h"
38 #include "bt-service-opp-client.h"
39 #include "bt-service-map-client.h"
40 #include "bt-service-agent.h"
41 #include "bt-service-main.h"
42 #include "bt-service-avrcp.h"
43 #include "bt-service-device.h"
44 #ifdef TIZEN_FEATURE_BT_DPM
45 #include "bt-service-dpm.h"
55 bt_adapter_timer_t visible_timer = {0, };
59 bt_set_alarm_cb callback;
64 gboolean is_alarm_initialized;
66 } bt_service_alarm_mgr_t;
68 static bt_service_alarm_mgr_t alarm_mgr = {0, };
70 static gboolean is_discovering;
71 static gboolean discovery_req;
72 static gboolean cancel_by_user;
73 static bt_status_t adapter_status = BT_DEACTIVATED;
74 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
75 static gboolean is_le_intended = FALSE;
76 static void *adapter_agent = NULL;
77 static GDBusProxy *core_proxy = NULL;
78 static guint timer_id = 0;
79 static guint le_timer_id = 0;
80 static gboolean is_recovery_mode;
82 static uint status_reg_id;
84 #define BT_CORE_NAME "org.projectx.bt_core"
85 #define BT_CORE_PATH "/org/projectx/bt_core"
86 #define BT_CORE_INTERFACE "org.projectx.btcore"
88 #define BT_DISABLE_TIME 500 /* 500 ms */
90 static int alarm_cb(alarm_id_t alarm_id, void* user_param);
91 static void alarm_data_free(void *data);
93 GDBusProxy *_bt_init_core_proxy(void)
96 GDBusConnection *conn;
98 conn = _bt_gdbus_get_system_gconn();
102 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
117 static GDBusProxy *__bt_get_core_proxy(void)
119 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
122 static gboolean __bt_is_factory_test_mode(void)
126 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
127 BT_ERR("Get the DUT Mode fail");
132 BT_INFO("DUT Test Mode !!");
139 static gboolean __bt_timeout_handler(gpointer user_data)
141 int result = BLUETOOTH_ERROR_NONE;
145 /* Take current time */
147 time_diff = difftime(current_time, visible_timer.start_time);
149 /* Send event to application */
150 _bt_send_event(BT_ADAPTER_EVENT,
151 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
152 g_variant_new("(in)", result, time_diff));
154 if (visible_timer.timeout <= time_diff) {
155 g_source_remove(visible_timer.event_id);
156 visible_timer.event_id = 0;
157 visible_timer.timeout = 0;
159 if (!TIZEN_PROFILE_WEARABLE) {
160 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
161 BT_ERR("Set vconf failed\n");
169 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
172 int result = BLUETOOTH_ERROR_NONE;
175 if (alarm_id != visible_timer.alarm_id)
178 if (visible_timer.event_id) {
179 _bt_send_event(BT_ADAPTER_EVENT,
180 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
181 g_variant_new("(in)", result, timeout));
182 g_source_remove(visible_timer.event_id);
183 visible_timer.event_id = 0;
184 visible_timer.timeout = 0;
186 if (!TIZEN_PROFILE_WEARABLE) {
187 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
188 BT_ERR("Set vconf failed\n");
191 /* Switch Off visibility in Bluez */
192 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
193 visible_timer.alarm_id = 0;
197 static void __bt_visibility_alarm_remove()
199 if (visible_timer.event_id > 0) {
200 g_source_remove(visible_timer.event_id);
201 visible_timer.event_id = 0;
204 if (visible_timer.alarm_id > 0) {
205 _bt_service_remove_alarm(visible_timer.alarm_id);
206 visible_timer.alarm_id = 0;
210 int __bt_set_visible_time(int timeout)
214 #ifdef TIZEN_FEATURE_BT_DPM
215 int discoverable_state = DPM_BT_ERROR;
218 __bt_visibility_alarm_remove();
220 visible_timer.timeout = timeout;
222 if (!TIZEN_PROFILE_WEARABLE) {
223 #ifdef TIZEN_FEATURE_BT_DPM
224 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
225 if (discoverable_state != DPM_RESTRICTED) {
227 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
228 BT_ERR("Set vconf failed");
229 #ifdef TIZEN_FEATURE_BT_DPM
236 return BLUETOOTH_ERROR_NONE;
238 result = _bt_service_set_alarm(visible_timer.timeout,
239 __bt_visibility_alarm_cb, NULL, &alarm_id);
240 if (result != BLUETOOTH_ERROR_NONE)
241 return BLUETOOTH_ERROR_INTERNAL;
242 visible_timer.alarm_id = alarm_id;
243 /* Take start time */
244 time(&(visible_timer.start_time));
245 visible_timer.event_id = g_timeout_add_seconds(1,
246 __bt_timeout_handler, NULL);
248 return BLUETOOTH_ERROR_NONE;
251 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
258 ret_if(value == NULL);
261 dev->service_index = 0;
263 g_variant_get(value, "as", &iter);
264 while (g_variant_iter_loop(iter, "s", &uuid)) {
265 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
266 parts = g_strsplit(uuid, "-", -1);
268 if (parts == NULL || parts[0] == NULL) {
273 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
276 dev->service_index++;
279 g_variant_iter_free(iter);
282 static int __bt_get_bonded_device_info(gchar *device_path,
283 bluetooth_device_info_t *dev_info)
285 GError *error = NULL;
286 GDBusProxy *device_proxy;
287 gchar *address = NULL;
289 unsigned int cod = 0;
291 gboolean trust = FALSE;
292 gboolean paired = FALSE;
293 guchar connected = 0;
294 GByteArray *manufacturer_data = NULL;
296 GDBusConnection *conn;
298 GVariantIter *property_iter;
302 GVariantIter *char_value_iter;
304 BT_CHECK_PARAMETER(device_path, return);
305 BT_CHECK_PARAMETER(dev_info, return);
307 conn = _bt_gdbus_get_system_gconn();
308 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
310 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
314 BT_PROPERTIES_INTERFACE,
317 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
319 result = g_dbus_proxy_call_sync(device_proxy,
321 g_variant_new("(s)", BT_DEVICE_INTERFACE),
322 G_DBUS_CALL_FLAGS_NONE,
328 BT_ERR("Error occured in Proxy call");
330 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
331 g_clear_error(&error);
333 g_object_unref(device_proxy);
334 return BLUETOOTH_ERROR_INTERNAL;
337 g_object_unref(device_proxy);
339 g_variant_get(result, "(a{sv})", &property_iter);
341 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
342 if (!g_strcmp0(key, "Paired")) {
343 paired = g_variant_get_boolean(value);
344 } else if (!g_strcmp0(key, "Address")) {
345 g_variant_get(value, "s", &address);
346 } else if (!g_strcmp0(key, "Alias")) {
347 g_variant_get(value, "s", &name);
348 } else if (!g_strcmp0(key, "Name")) {
350 g_variant_get(value, "s", &name);
351 } else if (!g_strcmp0(key, "Class")) {
352 cod = g_variant_get_uint32(value);
353 } else if (!g_strcmp0(key, "Connected")) {
354 connected = g_variant_get_byte(value);
355 } else if (!g_strcmp0(key, "Trusted")) {
356 trust = g_variant_get_boolean(value);
357 } else if (!g_strcmp0(key, "RSSI")) {
358 rssi = g_variant_get_int16(value);
359 } else if (!g_strcmp0(key, "UUIDs")) {
360 __bt_get_service_list(value, dev_info);
361 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
362 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
363 } else if (!g_strcmp0(key, "ManufacturerData")) {
364 manufacturer_data = g_byte_array_new();
365 g_variant_get(value, "ay", &char_value_iter);
366 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
367 g_byte_array_append(manufacturer_data, &char_value, 1);
369 g_variant_iter_free(char_value_iter);
371 if (manufacturer_data) {
372 if (manufacturer_data->len > 0) {
373 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
374 manufacturer_data->len);
377 g_byte_array_free(manufacturer_data, TRUE);
380 g_variant_iter_free(property_iter);
382 BT_DBG("trust: %d, paired: %d", trust, paired);
384 g_variant_unref(result);
386 if ((paired == FALSE) && (trust == FALSE)) {
389 return BLUETOOTH_ERROR_NOT_PAIRED;
392 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
395 _bt_divide_device_class(&dev_info->device_class, cod);
397 g_strlcpy(dev_info->device_name.name, name,
398 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
400 dev_info->rssi = rssi;
401 dev_info->trust = trust;
402 dev_info->paired = paired;
403 dev_info->connected = connected;
404 ret = BLUETOOTH_ERROR_NONE;
411 void _bt_set_discovery_status(gboolean mode)
413 is_discovering = mode;
416 void _bt_set_cancel_by_user(gboolean value)
418 cancel_by_user = value;
421 gboolean _bt_get_cancel_by_user(void)
423 return cancel_by_user;
426 void _bt_adapter_set_status(bt_status_t status)
428 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
429 adapter_status = status;
432 bt_status_t _bt_adapter_get_status(void)
434 return adapter_status;
437 void _bt_adapter_set_le_status(bt_le_status_t status)
439 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
440 adapter_le_status = status;
443 bt_le_status_t _bt_adapter_get_le_status(void)
445 return adapter_le_status;
449 void _bt_set_le_intended_status(gboolean value)
451 is_le_intended = value;
454 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
456 char *phone_name = NULL;
462 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
463 phone_name = vconf_keynode_get_str(node);
465 if (phone_name && strlen(phone_name) != 0) {
466 if (!g_utf8_validate(phone_name, -1,
467 (const char **)&ptr))
470 _bt_set_local_name(phone_name);
475 static void __bt_set_local_name(void)
477 bluetooth_device_name_t local_name;
478 char *phone_name = NULL;
482 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
483 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
484 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
489 if (strlen(phone_name) != 0) {
490 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
493 _bt_set_local_name(phone_name);
499 static int __bt_set_enabled(void)
501 int adapter_status = BT_ADAPTER_DISABLED;
502 int result = BLUETOOTH_ERROR_NONE;
505 BT_DBG("g_source is removed");
506 g_source_remove(timer_id);
510 _bt_check_adapter(&adapter_status);
512 if (adapter_status == BT_ADAPTER_DISABLED) {
513 BT_ERR("Bluetoothd is not running");
514 return BLUETOOTH_ERROR_INTERNAL;
517 if (TIZEN_PROFILE_MOBILE || TIZEN_PROFILE_IVI) {
518 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
519 if (_bt_set_discoverable_mode(
520 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
521 BT_ERR("Set connectable mode failed");
522 } else if (TIZEN_PROFILE_TV) {
523 if (_bt_set_discoverable_mode(
524 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
525 BT_ERR("Fail to set discoverable mode");
528 /* Update Bluetooth Status to notify other modules */
529 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
530 BT_ERR("Set vconf failed\n");
532 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
533 BT_ERR("Set vconf failed\n");
535 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
536 EVT_VAL_BT_ON) != ES_R_OK)
537 BT_ERR("Fail to set value");
539 /* Send enabled event to API */
540 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
541 g_variant_new("(i)", result));
543 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
544 _bt_audio_start_auto_connect(FALSE);
547 __bt_set_local_name();
548 _bt_set_discovery_status(FALSE);
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_cancel_queued_transfers();
588 _bt_adapter_set_status(BT_DEACTIVATED);
589 _bt_set_discovery_status(FALSE);
591 if (TIZEN_FEATURE_BT_USB_DONGLE ||
592 _bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
593 /* Send disabled event */
594 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
595 g_variant_new("(i)", result));
598 BT_INFO("Adapter disabled");
601 static int __bt_set_le_enabled(void)
604 int result = BLUETOOTH_ERROR_NONE;
607 /* Update Bluetooth Status to notify other modules */
608 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
609 BT_ERR("Set vconf failed\n");
611 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
612 EVT_VAL_BT_LE_ON) != ES_R_OK)
613 BT_ERR("Fail to set value");
615 /* Send enabled event to API */
617 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
618 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
620 status = _bt_adapter_get_status();
621 if (status == BT_DEACTIVATED) {
622 BT_INFO("BREDR is off, turn off PSCAN");
623 _bt_set_connectable(FALSE);
625 if (le_timer_id > 0) {
626 g_source_remove(le_timer_id);
630 /* Send enabled event to API */
631 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
632 g_variant_new("(i)", result));
634 __bt_set_local_name();
637 return BLUETOOTH_ERROR_NONE;
640 void _bt_set_le_disabled(int result)
642 int power_off_status;
645 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
646 BT_DBG("ret : %d", ret);
647 BT_DBG("power_off_status : %d", power_off_status);
649 /* Update Bluetooth Status to notify other modules */
650 BT_DBG("Update vconf for BT LE normal Deactivation");
651 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
652 BT_ERR("Set vconf failed\n");
653 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
655 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
656 EVT_VAL_BT_LE_OFF) != ES_R_OK)
657 BT_ERR("Fail to set value");
659 /* Send disabled event */
660 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
661 g_variant_new("(i)", result));
664 void *_bt_get_adapter_agent(void)
666 return adapter_agent;
669 int _bt_enable_core(void)
673 GError *error = NULL;
675 proxy = __bt_get_core_proxy();
676 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
678 /* Clean up the process */
679 result = g_dbus_proxy_call_sync(proxy,
682 G_DBUS_CALL_FLAGS_NONE,
689 BT_ERR("Bt core call failed(Error: %s)", error->message);
690 g_clear_error(&error);
692 BT_ERR("Bt core call failed");
693 return BLUETOOTH_ERROR_INTERNAL;
696 g_variant_unref(result);
697 return BLUETOOTH_ERROR_NONE;
700 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
702 gboolean flight_mode = FALSE;
703 int power_saving_mode = 0;
706 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
707 type = vconf_keynode_get_type(node);
708 if (type == VCONF_TYPE_BOOL) {
709 flight_mode = vconf_keynode_get_bool(node);
710 if (flight_mode != TRUE) {
711 BT_ERR("Ignore the event");
714 } else if (type == VCONF_TYPE_INT) {
715 power_saving_mode = vconf_keynode_get_int(node);
716 if (power_saving_mode != 2) {
717 BT_ERR("Ignore the event");
721 BT_ERR("Invaild vconf key type : %d", type);
728 void _bt_service_register_vconf_handler(void)
732 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
733 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
734 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
735 BT_ERR("Unable to register key handler");
737 BT_DBG("Telephony is disabled");
740 if (!TIZEN_PROFILE_WEARABLE) {
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");
747 void _bt_service_unregister_vconf_handler(void)
751 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
752 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
753 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
756 if (!TIZEN_PROFILE_WEARABLE) {
757 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
758 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
762 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
764 const char *bt_status = NULL;
765 const char *bt_le_status = NULL;
766 BT_DBG("bt state set event(%s) received", event_name);
768 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
769 BT_DBG("bt_state: (%s)", bt_status);
771 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
772 BT_DBG("bt_state: (%s)", bt_le_status);
775 void _bt_handle_adapter_added(void)
779 bt_le_status_t le_status;
783 BT_DBG("g_source is removed");
784 g_source_remove(timer_id);
789 status = _bt_adapter_get_status();
790 le_status = _bt_adapter_get_le_status();
791 BT_DBG("status : %d", status);
792 BT_DBG("le_status : %d", le_status);
794 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
795 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
796 if (!adapter_agent) {
797 BT_ERR("Fail to register agent");
801 if (adapter_agent == NULL) {
802 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
803 if (!adapter_agent) {
804 BT_ERR("Fail to register agent");
810 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
811 BT_ERR("Fail to register media player");
813 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
814 BT_ERR("Fail to init obex server");
816 #ifdef TIZEN_BT_PAN_NAP_ENABLED
817 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
818 BT_ERR("Fail to activate network");
821 /* add the vconf noti handler */
822 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
823 __bt_phone_name_changed_cb, NULL);
825 BT_ERR("Unable to register key handler");
827 if (le_status == BT_LE_ACTIVATING ||
828 status == BT_ACTIVATING) {
829 __bt_set_le_enabled();
830 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
833 if (status == BT_ACTIVATING) {
835 _bt_adapter_set_status(BT_ACTIVATED);
839 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
840 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
841 BT_ERR("Fail to register system event");
845 void _bt_handle_adapter_removed(void)
849 _bt_adapter_set_status(BT_DEACTIVATED);
851 __bt_visibility_alarm_remove();
853 if (alarm_mgr.is_alarm_initialized == TRUE) {
855 alarm_mgr.is_alarm_initialized = FALSE;
856 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
857 alarm_mgr.g_alarm_list = NULL;
860 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
861 _bt_audio_stop_auto_connect();
864 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
865 (vconf_callback_fn)__bt_phone_name_changed_cb);
867 ERR("vconf_ignore_key_changed failed\n");
869 /* unregister all the services/servers/profiles registered on bluez-adapter
870 once adapter is removed, reinitializing of the state-varaibles becomes
872 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
873 BT_ERR("Fail to unregister obex server");
875 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
876 BT_ERR("Fail to unregister media player");
878 /* Other unregister APIs should be placed here */
880 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
881 _bt_destroy_agent(adapter_agent);
882 adapter_agent = NULL;
884 if (is_recovery_mode == TRUE) {
885 /* Send disabled event */
886 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
888 /* Will recover BT by bt-core, so set the mode as activating */
889 _bt_adapter_set_status(BT_ACTIVATING);
890 is_recovery_mode = FALSE;
892 _bt_reliable_terminate_service(NULL);
895 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
898 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
899 BT_ERR("Fail to unregister system event");
902 static gboolean __bt_enable_timeout_cb(gpointer user_data)
906 GError *error = NULL;
910 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
912 BT_ERR("EnableAdapter is failed");
914 proxy = __bt_get_core_proxy();
918 /* Clean up the process */
919 result = g_dbus_proxy_call_sync(proxy,
922 G_DBUS_CALL_FLAGS_NONE,
929 BT_ERR("Bt core call failed(Error: %s)", error->message);
930 g_clear_error(&error);
932 BT_ERR("Bt core call failed");
937 g_variant_unref(result);
938 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
940 if (!TIZEN_FEATURE_BT_USB_DONGLE)
941 _bt_terminate_service(NULL);
946 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
950 GError *error = NULL;
954 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
956 BT_ERR("EnableAdapterLE is failed");
958 proxy = __bt_get_core_proxy();
962 /* Clean up the process */
963 result = g_dbus_proxy_call_sync(proxy,
966 G_DBUS_CALL_FLAGS_NONE,
973 BT_ERR("Bt core call failed(Error: %s)", error->message);
974 g_clear_error(&error);
976 BT_ERR("Bt core call failed");
980 g_variant_unref(result);
981 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
983 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
985 if (_bt_adapter_get_status() == BT_DEACTIVATED)
986 _bt_terminate_service(NULL);
991 void _bt_adapter_start_le_enable_timer(void)
993 if (le_timer_id > 0) {
994 g_source_remove(le_timer_id);
998 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
999 __bt_enable_le_timeout_cb, NULL);
1004 void _bt_adapter_start_enable_timer(void)
1007 g_source_remove(timer_id);
1011 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1012 __bt_enable_timeout_cb, NULL);
1017 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1022 _bt_adapter_set_status(BT_ACTIVATED);
1027 int _bt_enable_adapter_check_status(void)
1029 bt_status_t status = _bt_adapter_get_status();
1030 bt_le_status_t le_status = _bt_adapter_get_le_status();
1034 if (status == BT_ACTIVATING) {
1035 BT_ERR("Enabling in progress");
1036 return BLUETOOTH_ERROR_IN_PROGRESS;
1039 if (status == BT_ACTIVATED) {
1040 BT_ERR("Already enabled");
1041 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1044 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1045 BT_ERR("Disabling in progress");
1046 return BLUETOOTH_ERROR_DEVICE_BUSY;
1049 return BLUETOOTH_ERROR_NONE;
1052 int _bt_enable_adapter(void)
1055 GError *error = NULL;
1057 GVariant *result = NULL;
1058 bt_status_t status = _bt_adapter_get_status();
1059 bt_le_status_t le_status = _bt_adapter_get_le_status();
1063 if (status == BT_ACTIVATING) {
1064 BT_ERR("Enabling in progress");
1065 return BLUETOOTH_ERROR_IN_PROGRESS;
1068 if (status == BT_ACTIVATED) {
1069 BT_ERR("Already enabled");
1070 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1073 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1074 BT_ERR("Disabling in progress");
1075 return BLUETOOTH_ERROR_DEVICE_BUSY;
1078 _bt_adapter_set_status(BT_ACTIVATING);
1080 if (TIZEN_PROFILE_TV) {
1081 int adapter_status = BT_ADAPTER_DISABLED;
1083 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1084 BT_ERR("Set vconf failed");
1086 _bt_check_adapter(&adapter_status);
1087 if (adapter_status == BT_ADAPTER_ENABLED) {
1088 g_idle_add(__bt_adapter_enabled_cb, NULL);
1089 _bt_adapter_start_enable_timer();
1090 return BLUETOOTH_ERROR_NONE;
1094 proxy = __bt_get_core_proxy();
1096 return BLUETOOTH_ERROR_INTERNAL;
1098 if (le_status == BT_LE_ACTIVATED) {
1099 BT_INFO("LE Already enabled. Just turn on PSCAN");
1100 ret = _bt_set_connectable(TRUE);
1101 if (ret == BLUETOOTH_ERROR_NONE)
1102 _bt_adapter_set_status(BT_ACTIVATED);
1104 return BLUETOOTH_ERROR_INTERNAL;
1107 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1109 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1112 BT_ERR("EnableAdapterLe failed: %s", error->message);
1113 _bt_adapter_set_status(BT_DEACTIVATED);
1114 g_clear_error(&error);
1116 result = g_dbus_proxy_call_sync(proxy,
1119 G_DBUS_CALL_FLAGS_NONE,
1124 if (error != NULL) {
1125 BT_ERR("Bt core call failed(Error: %s)", error->message);
1126 g_clear_error(&error);
1128 g_variant_unref(result);
1129 /* Terminate myself */
1130 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1131 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1132 return BLUETOOTH_ERROR_INTERNAL;
1134 g_variant_unref(result);
1135 if (le_status == BT_LE_ACTIVATED)
1138 _bt_adapter_start_enable_timer();
1140 return BLUETOOTH_ERROR_NONE;
1143 static gboolean __bt_disconnect_all(void)
1146 GDBusConnection *conn;
1147 GDBusProxy *dev_proxy;
1148 gboolean ret = FALSE;
1150 GError *error = NULL;
1151 GArray *device_list;
1152 bluetooth_device_info_t info;
1154 char *device_path = NULL;
1155 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1160 conn = _bt_gdbus_get_system_gconn();
1162 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1164 if (_bt_get_bonded_devices(&device_list)
1165 != BLUETOOTH_ERROR_NONE) {
1166 g_array_free(device_list, TRUE);
1170 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1172 for (i = 0; i < size; i++) {
1174 info = g_array_index(device_list,
1175 bluetooth_device_info_t, i);
1177 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1178 BT_DBG("Found Connected device");
1179 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1180 device_path = _bt_get_device_object_path(address);
1181 if (device_path == NULL)
1184 BT_DBG("Disconnecting : %s", device_path);
1186 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1190 BT_DEVICE_INTERFACE,
1193 if (dev_proxy == NULL)
1196 result = g_dbus_proxy_call_sync(dev_proxy,
1199 G_DBUS_CALL_FLAGS_NONE,
1205 if (error != NULL) {
1206 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1207 g_clear_error(&error);
1209 BT_ERR("Disconnect call failed");
1210 g_object_unref(dev_proxy);
1214 g_variant_unref(result);
1215 g_object_unref(dev_proxy);
1219 g_array_free(device_list, TRUE);
1225 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1228 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1234 int _bt_disable_cb(void)
1242 GError *error = NULL;
1244 _bt_adapter_set_status(BT_DEACTIVATING);
1246 bt_le_status_t le_status;
1247 le_status = _bt_adapter_get_le_status();
1248 BT_DBG("le_status : %d", le_status);
1249 if (le_status == BT_LE_ACTIVATED) {
1250 BT_INFO("LE is enabled. Just turn off PSCAN");
1252 if (_bt_is_discovering())
1253 _bt_cancel_discovery();
1255 if (_bt_is_connectable() == FALSE) {
1256 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1258 ret = _bt_set_connectable(FALSE);
1259 if (ret != BLUETOOTH_ERROR_NONE) {
1260 BT_ERR("_bt_set_connectable fail!");
1261 _bt_adapter_set_status(BT_ACTIVATED);
1262 return BLUETOOTH_ERROR_INTERNAL;
1267 proxy = __bt_get_core_proxy();
1268 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1270 result = g_dbus_proxy_call_sync(proxy,
1273 G_DBUS_CALL_FLAGS_NONE,
1279 if (error != NULL) {
1280 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1281 g_clear_error(&error);
1283 BT_ERR("Failed to DisableAdapter");
1284 _bt_adapter_set_status(BT_ACTIVATED);
1285 return BLUETOOTH_ERROR_INTERNAL;
1288 g_variant_unref(result);
1289 return BLUETOOTH_ERROR_NONE;
1292 int _bt_disable_adapter_check_status(void)
1294 bt_status_t status = _bt_adapter_get_status();
1298 if (status == BT_DEACTIVATING) {
1299 BT_DBG("Disabling in progress");
1300 return BLUETOOTH_ERROR_IN_PROGRESS;
1303 if (status == BT_DEACTIVATED) {
1304 BT_DBG("Already disabled");
1305 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1308 return BLUETOOTH_ERROR_NONE;
1311 int _bt_disable_adapter(void)
1316 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1317 BT_DBG("Disabling in progress");
1318 return BLUETOOTH_ERROR_IN_PROGRESS;
1321 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1322 BT_DBG("Already disabled");
1323 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1327 g_source_remove(timer_id);
1330 /* unregister all the services/servers/profiles registered on bluez-adapter
1331 once adapter is removed, reinitializing of the state-varaibles becomes
1333 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1334 BT_ERR("Fail to unregister obex server");
1336 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
1337 BT_ERR("Fail to unregister media player");
1339 /* Other unregister APIs should be placed here */
1340 __bt_disconnect_all();
1341 ret = _bt_disable_cb();
1347 int _bt_recover_adapter(void)
1352 GError *error = NULL;
1354 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1355 BT_DBG("Disabling in progress");
1356 return BLUETOOTH_ERROR_IN_PROGRESS;
1359 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1360 BT_DBG("Already disabled");
1361 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1364 _bt_adapter_set_status(BT_DEACTIVATING);
1366 proxy = __bt_get_core_proxy();
1367 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1369 result = g_dbus_proxy_call_sync(proxy,
1372 G_DBUS_CALL_FLAGS_NONE,
1378 if (error != NULL) {
1379 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1380 g_clear_error(&error);
1382 BT_ERR("Failed to RecoverAdapter");
1383 return BLUETOOTH_ERROR_INTERNAL;
1386 is_recovery_mode = TRUE;
1388 g_variant_unref(result);
1389 __bt_disconnect_all();
1392 return BLUETOOTH_ERROR_NONE;
1395 int _bt_reset_adapter(void)
1399 GError *error = NULL;
1403 proxy = __bt_get_core_proxy();
1405 return BLUETOOTH_ERROR_INTERNAL;
1407 result = g_dbus_proxy_call_sync(proxy,
1410 G_DBUS_CALL_FLAGS_NONE,
1416 if (error != NULL) {
1417 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1418 g_clear_error(&error);
1420 BT_ERR("Failed to ResetAdapter");
1421 return BLUETOOTH_ERROR_INTERNAL;
1424 g_variant_unref(result);
1425 /* Terminate myself */
1426 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1427 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1429 return BLUETOOTH_ERROR_NONE;
1432 int _bt_check_adapter(int *status)
1434 if (!TIZEN_PROFILE_TV) {
1435 char *adapter_path = NULL;
1437 BT_CHECK_PARAMETER(status, return);
1439 *status = BT_ADAPTER_DISABLED;
1441 adapter_path = _bt_get_adapter_path();
1444 if (adapter_path != NULL)
1445 *status = BT_ADAPTER_ENABLED;
1447 g_free(adapter_path);
1448 return BLUETOOTH_ERROR_NONE;
1451 GError *error = NULL;
1454 gboolean powered = FALSE;
1456 BT_CHECK_PARAMETER(status, return);
1458 *status = BT_ADAPTER_DISABLED;
1460 proxy = _bt_get_adapter_properties_proxy();
1461 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1463 result = g_dbus_proxy_call_sync(proxy,
1465 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1467 G_DBUS_CALL_FLAGS_NONE,
1473 BT_ERR("Failed to get local address");
1474 if (error != NULL) {
1475 BT_ERR("Failed to get local address (Error: %s)", error->message);
1476 g_clear_error(&error);
1478 return BLUETOOTH_ERROR_INTERNAL;
1481 g_variant_get(result, "(v)", &temp);
1482 powered = g_variant_get_boolean(temp);
1483 BT_DBG("powered: %d", powered);
1486 *status = BT_ADAPTER_ENABLED;
1488 g_variant_unref(result);
1489 g_variant_unref(temp);
1490 return BLUETOOTH_ERROR_NONE;
1494 int _bt_enable_adapter_le(void)
1498 GError *error = NULL;
1499 bt_status_t status = _bt_adapter_get_status();
1500 bt_le_status_t le_status = _bt_adapter_get_le_status();
1503 if (le_status == BT_LE_ACTIVATING) {
1504 BT_ERR("Enabling in progress");
1505 return BLUETOOTH_ERROR_IN_PROGRESS;
1508 if (le_status == BT_LE_ACTIVATED) {
1509 BT_ERR("Already enabled");
1510 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1513 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1514 BT_ERR("Disabling in progress");
1515 return BLUETOOTH_ERROR_DEVICE_BUSY;
1518 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1520 proxy = __bt_get_core_proxy();
1521 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1523 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1525 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1528 BT_ERR("EnableAdapterLe failed: %s", error->message);
1529 _bt_adapter_set_le_status(BT_DEACTIVATED);
1530 g_clear_error(&error);
1532 /* Clean up the process */
1533 result = g_dbus_proxy_call_sync(proxy,
1536 G_DBUS_CALL_FLAGS_NONE,
1542 BT_ERR("Bt core call failed");
1544 BT_ERR("EnableAdapterLE Failed %s", error->message);
1545 g_clear_error(&error);
1548 g_variant_unref(result);
1549 /* Terminate myself */
1550 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1551 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1552 return BLUETOOTH_ERROR_INTERNAL;
1556 g_variant_unref(result);
1558 _bt_adapter_start_le_enable_timer();
1560 if (status == BT_ACTIVATED) {
1561 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1562 __bt_set_le_enabled();
1564 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1566 return BLUETOOTH_ERROR_NONE;
1569 int _bt_disable_adapter_le(void)
1573 bt_le_status_t bt_le_state;
1575 GError *error = NULL;
1577 bt_le_state = _bt_adapter_get_le_status();
1578 if (bt_le_state == BT_LE_DEACTIVATING) {
1579 BT_DBG("Disabling in progress");
1580 return BLUETOOTH_ERROR_IN_PROGRESS;
1583 if (bt_le_state == BT_LE_DEACTIVATED) {
1584 BT_DBG("Already disabled");
1585 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1588 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1590 proxy = __bt_get_core_proxy();
1592 return BLUETOOTH_ERROR_INTERNAL;
1594 result = g_dbus_proxy_call_sync(proxy,
1597 G_DBUS_CALL_FLAGS_NONE,
1603 if (error != NULL) {
1604 BT_ERR("Bt core call failed (Error: %s)", error->message);
1605 g_clear_error(&error);
1607 BT_ERR("Bt core call failed");
1608 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1609 return BLUETOOTH_ERROR_INTERNAL;
1612 g_variant_unref(result);
1613 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1614 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1616 return BLUETOOTH_ERROR_NONE;
1619 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1623 GError *error = NULL;
1624 const char *address;
1628 BT_CHECK_PARAMETER(local_address, return);
1630 proxy = _bt_get_adapter_properties_proxy();
1631 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1633 result = g_dbus_proxy_call_sync(proxy,
1635 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1637 G_DBUS_CALL_FLAGS_NONE,
1643 BT_ERR("Failed to get local address");
1644 if (error != NULL) {
1645 BT_ERR("Failed to get local address (Error: %s)", error->message);
1646 g_clear_error(&error);
1648 return BLUETOOTH_ERROR_INTERNAL;
1651 g_variant_get(result, "(v)", &temp);
1652 address = g_variant_get_string(temp, NULL);
1653 BT_DBG("Address:%s", address);
1656 _bt_convert_addr_string_to_type(local_address->addr, address);
1658 return BLUETOOTH_ERROR_INTERNAL;
1660 g_variant_unref(result);
1661 g_variant_unref(temp);
1662 return BLUETOOTH_ERROR_NONE;
1665 int _bt_get_local_version(bluetooth_version_t *local_version)
1668 const char *ver = NULL;
1670 int ret = BLUETOOTH_ERROR_NONE;
1674 BT_CHECK_PARAMETER(local_version, return);
1676 GError *error = NULL;
1678 proxy = _bt_get_adapter_properties_proxy();
1679 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1681 result = g_dbus_proxy_call_sync(proxy,
1683 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1685 G_DBUS_CALL_FLAGS_NONE,
1691 if (error != NULL) {
1692 BT_ERR("Failed to get local version (Error: %s)", error->message);
1693 g_clear_error(&error);
1695 BT_ERR("Failed to get local version");
1696 return BLUETOOTH_ERROR_INTERNAL;
1699 g_variant_get(result, "(v)", &temp);
1700 ver = g_variant_get_string(temp, NULL);
1701 BT_DBG("VERSION: %s", ver);
1703 if (ver && (strlen(ver) > 0)) {
1704 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1705 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1708 g_strlcpy(local_version->version, ver,
1709 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1712 ret = BLUETOOTH_ERROR_INTERNAL;
1715 g_variant_unref(result);
1716 g_variant_unref(temp);
1720 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1723 const char *name = NULL;
1725 int ret = BLUETOOTH_ERROR_NONE;
1728 GError *error = NULL;
1730 BT_CHECK_PARAMETER(local_name, return);
1732 proxy = _bt_get_adapter_properties_proxy();
1733 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1735 result = g_dbus_proxy_call_sync(proxy,
1737 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1739 G_DBUS_CALL_FLAGS_NONE,
1745 if (error != NULL) {
1746 BT_ERR("Failed to get local name (Error: %s)", error->message);
1747 g_clear_error(&error);
1749 BT_ERR("Failed to get local name");
1750 return BLUETOOTH_ERROR_INTERNAL;
1753 g_variant_get(result, "(v)", &temp);
1754 name = g_variant_get_string(temp, NULL);
1755 BT_DBG("LOCAL NAME:%s", name);
1757 if (name && (strlen(name) > 0)) {
1758 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1759 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1762 g_strlcpy(local_name->name, name,
1763 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1765 ret = BLUETOOTH_ERROR_INTERNAL;
1767 g_variant_unref(result);
1768 g_variant_unref(temp);
1772 int _bt_set_local_name(char *local_name)
1775 GError *error = NULL;
1779 BT_CHECK_PARAMETER(local_name, return);
1781 proxy = _bt_get_adapter_properties_proxy();
1783 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1785 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1788 result = g_dbus_proxy_call_sync(proxy,
1790 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1791 "Alias", g_variant_new("s", local_name)),
1792 G_DBUS_CALL_FLAGS_NONE,
1798 if (error != NULL) {
1799 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1800 g_clear_error(&error);
1802 BT_ERR("Failed to set Alias");
1803 return BLUETOOTH_ERROR_INTERNAL;
1806 g_variant_unref(result);
1807 return BLUETOOTH_ERROR_NONE;
1810 int _bt_is_service_used(char *service_uuid, gboolean *used)
1813 GError *error = NULL;
1814 int ret = BLUETOOTH_ERROR_NONE;
1816 GVariant *temp = NULL;
1817 GVariantIter *iter = NULL;
1821 BT_CHECK_PARAMETER(service_uuid, return);
1822 BT_CHECK_PARAMETER(used, return);
1824 proxy = _bt_get_adapter_properties_proxy();
1825 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1827 result = g_dbus_proxy_call_sync(proxy,
1829 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1831 G_DBUS_CALL_FLAGS_NONE,
1837 if (error != NULL) {
1838 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1839 g_clear_error(&error);
1841 BT_ERR("Failed to get UUIDs");
1842 return BLUETOOTH_ERROR_INTERNAL;
1845 g_variant_get(result, "(v)", &temp);
1846 g_variant_get(temp, "as", &iter);
1849 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1850 if (strcasecmp(uuid, service_uuid) == 0) {
1855 g_variant_iter_free(iter);
1856 g_variant_unref(result);
1858 BT_DBG("Service Used? %d", *used);
1863 static gboolean __bt_get_discoverable_property(void)
1866 gboolean discoverable_v;
1867 GError *error = NULL;
1871 proxy = _bt_get_adapter_properties_proxy();
1872 retv_if(proxy == NULL, FALSE);
1874 result = g_dbus_proxy_call_sync(proxy,
1876 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1878 G_DBUS_CALL_FLAGS_NONE,
1884 if (error != NULL) {
1885 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1886 g_clear_error(&error);
1888 BT_ERR("Failed to get Discoverable property");
1889 return BLUETOOTH_ERROR_INTERNAL;
1892 g_variant_get(result, "(v)", &temp);
1893 discoverable_v = g_variant_get_boolean(temp);
1894 BT_DBG("discoverable_v:%d", discoverable_v);
1896 g_variant_unref(result);
1897 g_variant_unref(temp);
1899 return discoverable_v;
1902 int _bt_get_discoverable_mode(int *mode)
1904 gboolean discoverable;
1905 unsigned int timeout;
1907 BT_CHECK_PARAMETER(mode, return);
1909 discoverable = __bt_get_discoverable_property();
1910 timeout = _bt_get_discoverable_timeout_property();
1912 if (discoverable == TRUE) {
1914 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1916 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1918 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1920 return BLUETOOTH_ERROR_NONE;
1924 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1926 int ret = BLUETOOTH_ERROR_NONE;
1929 GError *error = NULL;
1932 #ifdef TIZEN_FEATURE_BT_DPM
1933 int discoverable_state = DPM_BT_ERROR;
1936 proxy = _bt_get_adapter_properties_proxy();
1938 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1940 #ifdef TIZEN_FEATURE_BT_DPM
1941 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1942 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
1943 discoverable_state == DPM_RESTRICTED) {
1944 if (headed_plugin_info->plugin_headed_enabled)
1945 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
1947 return BLUETOOTH_ERROR_ACCESS_DENIED;
1949 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
1950 discoverable_state == DPM_RESTRICTED) {
1951 if (headed_plugin_info->plugin_headed_enabled)
1952 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
1954 return BLUETOOTH_ERROR_ACCESS_DENIED;
1958 switch (discoverable_mode) {
1959 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1964 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1969 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1974 return BLUETOOTH_ERROR_INVALID_PARAM;
1977 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1978 discoverable_mode, timeout);
1980 result = g_dbus_proxy_call_sync(proxy,
1982 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1983 "Connectable", g_variant_new("b", pg_scan)),
1984 G_DBUS_CALL_FLAGS_NONE,
1990 if (error != NULL) {
1991 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1992 g_clear_error(&error);
1994 BT_ERR("Failed to set connectable property");
1995 return BLUETOOTH_ERROR_INTERNAL;
1997 g_variant_unref(result);
1998 result = g_dbus_proxy_call_sync(proxy,
2000 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2001 g_variant_new("b", inq_scan)),
2002 G_DBUS_CALL_FLAGS_NONE,
2008 if (error != NULL) {
2009 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2010 g_clear_error(&error);
2012 BT_ERR("Failed to set Discoverable property");
2013 return BLUETOOTH_ERROR_INTERNAL;
2015 g_variant_unref(result);
2016 result = g_dbus_proxy_call_sync(proxy,
2018 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2019 "DiscoverableTimeout", g_variant_new("u", timeout)),
2020 G_DBUS_CALL_FLAGS_NONE,
2026 if (error != NULL) {
2027 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2028 g_clear_error(&error);
2030 BT_ERR("Failed to set DiscoverableTimeout property");
2031 return BLUETOOTH_ERROR_INTERNAL;
2034 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2037 ret = __bt_set_visible_time(timeout);
2039 g_variant_unref(result);
2044 int _bt_start_discovery(void)
2047 GError *error = NULL;
2050 if (_bt_is_discovering() == TRUE) {
2051 BT_ERR("BT is already in discovering");
2052 return BLUETOOTH_ERROR_IN_PROGRESS;
2053 } else if (_bt_is_device_creating() == TRUE) {
2054 BT_ERR("Bonding device is going on");
2055 return BLUETOOTH_ERROR_DEVICE_BUSY;
2058 proxy = _bt_get_adapter_proxy();
2059 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2061 result = g_dbus_proxy_call_sync(proxy,
2064 G_DBUS_CALL_FLAGS_NONE,
2070 if (error != NULL) {
2071 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2072 g_clear_error(&error);
2074 BT_ERR("StartDiscovery failed");
2075 return BLUETOOTH_ERROR_INTERNAL;
2078 discovery_req = TRUE;
2079 cancel_by_user = FALSE;
2080 /* discovery status will be change in event */
2081 g_variant_unref(result);
2082 return BLUETOOTH_ERROR_NONE;
2085 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2089 GError *error = NULL;
2090 const gchar *disc_type;
2092 if (_bt_is_discovering() == TRUE) {
2093 BT_ERR("BT is already in discovering");
2094 return BLUETOOTH_ERROR_IN_PROGRESS;
2097 proxy = _bt_get_adapter_proxy();
2098 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2100 if (role == DISCOVERY_ROLE_BREDR)
2101 disc_type = "BREDR";
2102 else if (role == DISCOVERY_ROLE_LE)
2104 else if (role == DISCOVERY_ROLE_LE_BREDR)
2105 disc_type = "LE_BREDR";
2107 return BLUETOOTH_ERROR_INVALID_PARAM;
2109 result = g_dbus_proxy_call_sync(proxy,
2110 "StartCustomDiscovery",
2111 g_variant_new("s", disc_type),
2112 G_DBUS_CALL_FLAGS_NONE,
2118 if (error != NULL) {
2119 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2120 g_clear_error(&error);
2122 BT_ERR("StartCustomDiscovery failed");
2123 return BLUETOOTH_ERROR_INTERNAL;
2126 discovery_req = TRUE;
2127 cancel_by_user = FALSE;
2128 /* discovery status will be change in event */
2129 g_variant_unref(result);
2130 return BLUETOOTH_ERROR_NONE;
2133 int _bt_cancel_discovery(void)
2136 GError *error = NULL;
2139 if (_bt_is_discovering() == FALSE) {
2140 BT_ERR("BT is not in discovering");
2141 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2144 proxy = _bt_get_adapter_proxy();
2145 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2147 result = g_dbus_proxy_call_sync(proxy,
2150 G_DBUS_CALL_FLAGS_NONE,
2156 int ret = BLUETOOTH_ERROR_INTERNAL;
2157 if (error != NULL) {
2158 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2160 if (g_strrstr(error->message, "No discovery started"))
2161 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2163 g_clear_error(&error);
2165 BT_ERR("StopDiscovery failed");
2171 discovery_req = FALSE;
2172 cancel_by_user = TRUE;
2173 /* discovery status will be change in event */
2174 g_variant_unref(result);
2175 return BLUETOOTH_ERROR_NONE;
2178 gboolean _bt_is_discovering(void)
2180 return (is_discovering || discovery_req);
2183 gboolean _bt_is_connectable(void)
2186 GError *error = NULL;
2187 gboolean is_connectable = FALSE;
2191 proxy = _bt_get_adapter_properties_proxy();
2192 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2194 result = g_dbus_proxy_call_sync(proxy,
2196 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2198 G_DBUS_CALL_FLAGS_NONE,
2204 if (error != NULL) {
2205 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2206 g_clear_error(&error);
2208 BT_ERR("Failed to get connectable property");
2209 return BLUETOOTH_ERROR_INTERNAL;
2212 g_variant_get(result, "(v)", &temp);
2213 is_connectable = g_variant_get_boolean(temp);
2214 BT_DBG("discoverable_v:%d", is_connectable);
2216 g_variant_unref(result);
2217 g_variant_unref(temp);
2219 BT_INFO("Get connectable [%d]", is_connectable);
2220 return is_connectable;
2223 int _bt_set_connectable(gboolean is_connectable)
2226 GError *error = NULL;
2229 if (__bt_is_factory_test_mode()) {
2230 BT_ERR("Unable to set connectable in factory binary !!");
2231 return BLUETOOTH_ERROR_NOT_SUPPORT;
2234 proxy = _bt_get_adapter_properties_proxy();
2236 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2238 result = g_dbus_proxy_call_sync(proxy,
2240 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2241 g_variant_new("b", is_connectable)),
2242 G_DBUS_CALL_FLAGS_NONE,
2248 if (error != NULL) {
2249 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2250 g_clear_error(&error);
2252 BT_ERR("Failed to set connectable property");
2253 return BLUETOOTH_ERROR_INTERNAL;
2256 BT_INFO_C("### Set connectable [%d]", is_connectable);
2257 g_variant_unref(result);
2258 return BLUETOOTH_ERROR_NONE;
2261 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2264 gboolean discovering_v;
2265 GError *error = NULL;
2266 char *discovering_type = NULL;
2270 proxy = _bt_get_adapter_properties_proxy();
2271 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2273 if (discovery_type == DISCOVERY_ROLE_BREDR)
2274 discovering_type = "Discovering";
2275 else if (discovery_type == DISCOVERY_ROLE_LE)
2276 discovering_type = "LEDiscovering";
2278 result = g_dbus_proxy_call_sync(proxy,
2280 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2282 G_DBUS_CALL_FLAGS_NONE,
2288 if (error != NULL) {
2289 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2290 g_clear_error(&error);
2292 BT_ERR("Failed to get discovering property");
2293 return BLUETOOTH_ERROR_INTERNAL;
2296 g_variant_get(result, "(v)", &temp);
2297 discovering_v = g_variant_get_boolean(temp);
2298 BT_DBG("discoverable_v:%d", discovering_v);
2300 g_variant_unref(result);
2301 g_variant_unref(temp);
2303 return discovering_v;
2306 unsigned int _bt_get_discoverable_timeout_property(void)
2309 unsigned int timeout_v;
2310 GError *error = NULL;
2314 proxy = _bt_get_adapter_properties_proxy();
2315 retv_if(proxy == NULL, 0);
2317 result = g_dbus_proxy_call_sync(proxy,
2319 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2320 "DiscoverableTimeout"),
2321 G_DBUS_CALL_FLAGS_NONE,
2327 BT_ERR("Fail to get discoverable timeout");
2328 if (error != NULL) {
2329 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2330 g_clear_error(&error);
2335 g_variant_get(result, "(v)", &temp);
2336 timeout_v = g_variant_get_uint32(temp);
2337 BT_DBG("discoverable_v:%d", timeout_v);
2339 g_variant_unref(result);
2340 g_variant_unref(temp);
2345 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2347 bluetooth_device_info_t *dev_info;
2350 GByteArray *manufacturer_data = NULL;
2352 GVariantIter *char_value_iter;
2354 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2356 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2361 if (!g_strcmp0(key, "Address")) {
2362 const char *address = NULL;
2363 address = g_variant_get_string(value, NULL);
2364 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2366 } else if (!g_strcmp0(key, "Class")) {
2368 cod = g_variant_get_uint32(value);
2369 _bt_divide_device_class(&dev_info->device_class, cod);
2370 } else if (!g_strcmp0(key, "Name")) {
2371 const char *name = NULL;
2372 name = g_variant_get_string(value, NULL);
2373 /* If there is no Alias */
2374 if (strlen(dev_info->device_name.name) == 0) {
2375 g_strlcpy(dev_info->device_name.name, name,
2376 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2378 } else if (!g_strcmp0(key, "Alias")) {
2379 const char *alias = NULL;
2380 alias = g_variant_get_string(value, NULL);
2381 /* Overwrite the name */
2383 memset(dev_info->device_name.name, 0x00,
2384 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2385 g_strlcpy(dev_info->device_name.name, alias,
2386 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2388 } else if (!g_strcmp0(key, "IsAliasSet")) {
2389 dev_info->is_alias_set = g_variant_get_boolean(value);
2390 } else if (!g_strcmp0(key, "Connected")) {
2391 dev_info->connected = g_variant_get_byte(value);
2392 } else if (!g_strcmp0(key, "Paired")) {
2393 dev_info->paired = g_variant_get_boolean(value);
2394 } else if (!g_strcmp0(key, "Trusted")) {
2395 dev_info->trust = g_variant_get_boolean(value);
2396 } else if (!g_strcmp0(key, "RSSI")) {
2397 dev_info->rssi = g_variant_get_int16(value);
2398 } else if (!g_strcmp0(key, "UUIDs")) {
2404 dev_info->service_index = 0;
2405 g_variant_get(value, "as", &iter);
2406 while (g_variant_iter_loop(iter, "s", &uuid)) {
2407 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2408 parts = g_strsplit(uuid, "-", -1);
2410 if (parts == NULL || parts[0] == NULL) {
2415 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2420 dev_info->service_index = i;
2421 g_variant_iter_free(iter);
2422 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2423 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2424 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2425 manufacturer_data = g_byte_array_new();
2426 g_variant_get(value, "ay", &char_value_iter);
2427 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2428 g_byte_array_append(manufacturer_data, &char_value, 1);
2430 if (manufacturer_data) {
2431 if (manufacturer_data->len > 0)
2432 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2434 g_variant_iter_free(char_value_iter);
2435 g_byte_array_free(manufacturer_data, TRUE);
2442 static void __bt_extract_device_info(GVariantIter *iter,
2445 bluetooth_device_info_t *dev_info = NULL;
2446 char *object_path = NULL;
2447 GVariantIter *interface_iter;
2448 GVariantIter *svc_iter;
2449 char *interface_str = NULL;
2451 /* Parse the signature: oa{sa{sv}}} */
2452 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2455 if (object_path == NULL)
2458 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2459 &interface_str, &svc_iter)) {
2460 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2461 BT_DBG("Found a device: %s", object_path);
2462 dev_info = __bt_parse_device_info(svc_iter);
2464 if (dev_info->paired == TRUE) {
2465 g_array_append_vals(*dev_list, dev_info,
2466 sizeof(bluetooth_device_info_t));
2470 g_free(interface_str);
2471 g_variant_iter_free(svc_iter);
2479 int _bt_get_bonded_devices(GArray **dev_list)
2482 GDBusConnection *conn;
2483 GDBusProxy *manager_proxy;
2484 GVariant *result = NULL;
2485 GVariantIter *iter = NULL;
2486 GError *error = NULL;
2488 conn = _bt_gdbus_get_system_gconn();
2489 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2491 manager_proxy = _bt_get_manager_proxy();
2492 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2494 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2496 G_DBUS_CALL_FLAGS_NONE,
2502 if (error != NULL) {
2503 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2504 g_clear_error(&error);
2506 BT_ERR("Failed to Failed to GetManagedObjects");
2507 return BLUETOOTH_ERROR_INTERNAL;
2510 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2511 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2513 __bt_extract_device_info(iter, dev_list);
2514 g_variant_iter_free(iter);
2515 g_variant_unref(result);
2518 return BLUETOOTH_ERROR_NONE;
2521 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2524 GDBusConnection *conn;
2525 GDBusProxy *manager_proxy;
2526 GVariant *result = NULL;
2527 GVariant *result1 = NULL;
2528 GVariantIter *iter = NULL;
2529 GError *error = NULL;
2530 char *object_path = NULL;
2531 GVariantIter *interface_iter;
2532 char *interface_str = NULL;
2533 GDBusProxy *device_proxy = NULL;
2534 gboolean is_connected = FALSE;
2536 conn = _bt_gdbus_get_system_gconn();
2537 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2539 manager_proxy = _bt_get_manager_proxy();
2540 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2542 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2544 G_DBUS_CALL_FLAGS_NONE,
2550 if (error != NULL) {
2551 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2552 g_clear_error(&error);
2555 BT_ERR("Failed to Failed to GetManagedObjects");
2556 return BLUETOOTH_ERROR_INTERNAL;
2559 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2560 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2562 /* Parse the signature: oa{sa{sv}}} */
2563 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2564 if (object_path == NULL)
2567 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2568 &interface_str, NULL)) {
2569 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2570 BT_DBG("Found a device: %s", object_path);
2571 g_free(interface_str);
2573 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2574 NULL, BT_BLUEZ_NAME,
2575 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2577 if (device_proxy == NULL) {
2578 BT_DBG("Device don't have this service");
2582 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2583 g_variant_new("(s)", profile_uuid),
2584 G_DBUS_CALL_FLAGS_NONE,
2589 if (result1 == NULL) {
2590 BT_ERR("Error occured in Proxy call");
2592 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2593 g_error_free(error);
2596 g_object_unref(device_proxy);
2599 g_variant_get(result1, "(b)", &is_connected);
2601 if (is_connected == TRUE) {
2602 char address[BT_ADDRESS_STRING_SIZE];
2603 bluetooth_device_address_t *addr = NULL;
2605 _bt_convert_device_path_to_address(object_path, address);
2607 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2608 _bt_convert_addr_string_to_type(addr->addr, address);
2610 g_array_append_vals(*addr_list, addr,
2611 sizeof(bluetooth_device_address_t));
2614 g_variant_unref(result1);
2615 g_object_unref(device_proxy);
2622 g_variant_unref(result);
2623 g_variant_iter_free(iter);
2626 return BLUETOOTH_ERROR_NONE;
2629 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2630 bluetooth_device_info_t *dev_info)
2632 char *object_path = NULL;
2633 GDBusProxy *adapter_proxy;
2634 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2635 int ret = BLUETOOTH_ERROR_NONE;
2637 BT_CHECK_PARAMETER(device_address, return);
2638 BT_CHECK_PARAMETER(dev_info, return);
2640 adapter_proxy = _bt_get_adapter_proxy();
2641 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2643 _bt_convert_addr_type_to_string(address, device_address->addr);
2645 object_path = _bt_get_device_object_path(address);
2647 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2649 ret = __bt_get_bonded_device_info(object_path, dev_info);
2650 g_free(object_path);
2655 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2657 char *object_path = NULL;
2658 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2659 gboolean alias_set = FALSE;
2661 GDBusConnection *conn;
2662 GDBusProxy *device_proxy;
2663 GError *error = NULL;
2664 GVariant *result = NULL;
2665 GVariant *temp = NULL;
2668 BT_CHECK_PARAMETER(device_address, return);
2669 BT_CHECK_PARAMETER(is_alias_set, return);
2671 _bt_convert_addr_type_to_string(address, device_address->addr);
2673 object_path = _bt_get_device_object_path(address);
2674 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2676 conn = _bt_gdbus_get_system_gconn();
2678 g_free(object_path);
2679 return BLUETOOTH_ERROR_INTERNAL;
2682 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2686 BT_PROPERTIES_INTERFACE,
2688 if (device_proxy == NULL) {
2689 g_free(object_path);
2690 return BLUETOOTH_ERROR_INTERNAL;
2693 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2694 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2695 G_DBUS_CALL_FLAGS_NONE,
2701 BT_ERR("Error occured in Proxy call");
2702 if (error != NULL) {
2703 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2704 g_error_free(error);
2706 g_object_unref(device_proxy);
2707 g_free(object_path);
2708 return BLUETOOTH_ERROR_INTERNAL;
2711 g_variant_get(result, "(v)", &temp);
2712 alias_set = g_variant_get_boolean(temp);
2713 *is_alias_set = alias_set;
2714 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2715 g_variant_unref(temp);
2716 g_variant_unref(result);
2717 g_object_unref(device_proxy);
2719 g_free(object_path);
2721 return BLUETOOTH_ERROR_NONE;
2724 int _bt_get_timeout_value(int *timeout)
2726 time_t current_time;
2729 /* Take current time */
2730 time(¤t_time);
2731 time_diff = difftime(current_time, visible_timer.start_time);
2733 BT_DBG("Time diff = %d\n", time_diff);
2735 *timeout = visible_timer.timeout - time_diff;
2737 return BLUETOOTH_ERROR_NONE;
2740 int _bt_set_le_privacy(gboolean set_privacy)
2743 GError *error = NULL;
2744 GVariant *result = NULL;
2746 if (__bt_is_factory_test_mode()) {
2747 BT_ERR("Unable to set le privacy in factory binary !!");
2748 return BLUETOOTH_ERROR_NOT_SUPPORT;
2751 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2752 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2753 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2756 proxy = _bt_get_adapter_proxy();
2757 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2759 result = g_dbus_proxy_call_sync(proxy,
2761 g_variant_new("(b)", set_privacy),
2762 G_DBUS_CALL_FLAGS_NONE,
2768 if (error != NULL) {
2769 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2770 g_clear_error(&error);
2772 BT_ERR("Failed to SetLePrivacy");
2773 return BLUETOOTH_ERROR_INTERNAL;
2776 g_variant_unref(result);
2777 BT_INFO("SetLePrivacy as %d", set_privacy);
2778 return BLUETOOTH_ERROR_NONE;
2781 int _bt_set_le_static_random_address(gboolean is_enable)
2784 GError *error = NULL;
2785 GVariant *result = NULL;
2787 if (__bt_is_factory_test_mode()) {
2788 BT_ERR("Unable to set le random address in factory binary !!");
2789 return BLUETOOTH_ERROR_NOT_SUPPORT;
2792 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2793 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2794 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2797 proxy = _bt_get_adapter_proxy();
2798 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2800 result = g_dbus_proxy_call_sync(proxy,
2801 "SetLeStaticRandomAddress",
2802 g_variant_new("(b)", is_enable),
2803 G_DBUS_CALL_FLAGS_NONE,
2809 if (error != NULL) {
2810 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2811 g_clear_error(&error);
2813 BT_ERR("Failed to SetLeStaticRandomAddress");
2814 return BLUETOOTH_ERROR_INTERNAL;
2817 g_variant_unref(result);
2818 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2819 return BLUETOOTH_ERROR_NONE;
2822 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2825 GError *error = NULL;
2829 GVariantBuilder *builder;
2831 BT_CHECK_PARAMETER(m_data, return);
2833 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2834 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2835 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2838 proxy = _bt_get_adapter_proxy();
2839 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2841 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2843 for (i = 0; i < (m_data->data_len) + 2; i++)
2844 g_variant_builder_add(builder, "y", m_data->data[i]);
2846 val = g_variant_new("(ay)", builder);
2848 result = g_dbus_proxy_call_sync(proxy,
2849 "SetManufacturerData",
2851 G_DBUS_CALL_FLAGS_NONE,
2855 g_variant_builder_unref(builder);
2857 if (error != NULL) {
2858 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2859 g_clear_error(&error);
2861 BT_ERR("Failed to SetManufacturerData");
2863 return BLUETOOTH_ERROR_INTERNAL;
2865 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2867 for (i = 0; i < (m_data->data_len) + 2; i++)
2868 g_variant_builder_add(builder, "y", m_data->data[i]);
2870 val = g_variant_new("(ay)", builder);
2872 _bt_send_event(BT_ADAPTER_EVENT,
2873 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2876 BT_INFO("Set manufacturer data");
2878 g_variant_builder_unref(builder);
2879 g_variant_unref(result);
2881 return BLUETOOTH_ERROR_NONE;
2885 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2887 int result = BLUETOOTH_ERROR_NONE;
2888 bt_service_alarm_t *alarm = NULL;
2890 if (!call_back || !alarm_id)
2891 return BLUETOOTH_ERROR_INVALID_PARAM;
2893 if (!alarm_mgr.is_alarm_initialized) {
2894 result = alarmmgr_init("bt-service");
2896 BT_ERR("Failed to initialize alarm = %d", result);
2897 result = BLUETOOTH_ERROR_INTERNAL;
2900 result = alarmmgr_set_cb(alarm_cb, NULL);
2902 BT_ERR("Failed to set the callback = %d", result);
2903 result = BLUETOOTH_ERROR_INTERNAL;
2906 alarm_mgr.is_alarm_initialized = TRUE;
2909 alarm = g_malloc0(sizeof(bt_service_alarm_t));
2911 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2913 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
2916 BT_ERR("Failed to create alarm error = %d", result);
2917 result = BLUETOOTH_ERROR_INTERNAL;
2921 alarm->alarm_id = *alarm_id;
2922 alarm->callback = call_back;
2923 alarm->user_data = user_data;
2925 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
2926 result = BLUETOOTH_ERROR_NONE;
2931 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
2934 bt_service_alarm_t *p_data;
2935 bt_set_alarm_cb callback = NULL;
2936 void *user_data = NULL;
2938 node = g_list_find_custom(alarm_mgr.g_alarm_list,
2939 GINT_TO_POINTER(alarm_id), compare_alarm);
2943 p_data = (bt_service_alarm_t *)node->data;
2944 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
2950 callback = p_data->callback;
2951 user_data = p_data->user_data;
2955 callback(alarm_id, user_data);
2960 int _bt_service_remove_alarm(alarm_id_t alarm_id)
2963 bt_service_alarm_t *p_data;
2964 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
2967 alarmmgr_remove_alarm(alarm_id);
2968 p_data = (bt_service_alarm_t *)list->data;
2969 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
2976 gint compare_alarm(gconstpointer list_data, gconstpointer data)
2979 alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
2981 alarm_id_t alarm_id = (alarm_id_t)data;
2983 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
2985 if (p_data->alarm_id == alarm_id)
2991 static void alarm_data_free(void *data)
2993 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
2998 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3002 int function = (int)(uintptr_t)user_data;
3004 int function = (int)user_data;
3008 case BT_ENABLE_ADAPTER:
3009 result = _bt_enable_adapter();
3010 if (result != BLUETOOTH_ERROR_NONE) {
3011 BT_ERR("_bt_enable_adapter is failed");
3012 /* Send enabled event to API */
3013 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3014 g_variant_new("(i)", result));
3017 case BT_DISABLE_ADAPTER:
3018 result = _bt_disable_adapter();
3019 if (result != BLUETOOTH_ERROR_NONE) {
3020 BT_ERR("_bt_disable_adapter is failed");
3021 /* Send disabled event to API */
3022 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3023 g_variant_new("(i)", result));
3027 BT_ERR("function is NOT matched");
3034 int _bt_adapter_request_delayed(int function)
3039 case BT_ENABLE_ADAPTER:
3040 ret = _bt_enable_adapter_check_status();
3041 if (ret == BLUETOOTH_ERROR_NONE)
3042 _bt_adapter_set_status(BT_ACTIVATING);
3047 case BT_DISABLE_ADAPTER:
3048 ret = _bt_disable_adapter_check_status();
3049 if (ret == BLUETOOTH_ERROR_NONE)
3050 _bt_adapter_set_status(BT_DEACTIVATING);
3056 BT_ERR("function is NOT matched");
3057 return BLUETOOTH_ERROR_INTERNAL;
3061 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3063 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3066 return BLUETOOTH_ERROR_NONE;
3069 int _bt_get_enable_timer_id(void)