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 #define BT_RECOVERY_MAX_COUNT 3
70 static bt_service_alarm_mgr_t alarm_mgr = {0, };
72 static gboolean is_discovering;
73 static gboolean discovery_req;
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 = BT_RECOVERY_MAX_COUNT;
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 */
93 #define BT_RECOVERY_TIME_W 2000 /*2 sec*/
94 #define BT_RECOVERY_TIME 5000 /*5 sec*/
96 static int alarm_cb(alarm_id_t alarm_id, void* user_param);
97 static void alarm_data_free(void *data);
99 GDBusProxy *_bt_init_core_proxy(void)
102 GDBusConnection *conn;
104 conn = _bt_gdbus_get_system_gconn();
108 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
123 static GDBusProxy *__bt_get_core_proxy(void)
125 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
128 static gboolean __bt_is_factory_test_mode(void)
132 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
133 BT_ERR("Get the DUT Mode fail");
138 BT_INFO("DUT Test Mode !!");
145 static gboolean __bt_timeout_handler(gpointer user_data)
147 int result = BLUETOOTH_ERROR_NONE;
151 /* Take current time */
153 time_diff = difftime(current_time, visible_timer.start_time);
155 /* Send event to application */
156 _bt_send_event(BT_ADAPTER_EVENT,
157 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
158 g_variant_new("(in)", result, time_diff));
160 if (visible_timer.timeout <= time_diff) {
161 g_source_remove(visible_timer.event_id);
162 visible_timer.event_id = 0;
163 visible_timer.timeout = 0;
165 if (!TIZEN_PROFILE_WEARABLE) {
166 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
167 BT_ERR("Set vconf failed\n");
175 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
178 int result = BLUETOOTH_ERROR_NONE;
181 if (alarm_id != visible_timer.alarm_id)
184 if (visible_timer.event_id) {
185 _bt_send_event(BT_ADAPTER_EVENT,
186 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
187 g_variant_new("(in)", result, timeout));
188 g_source_remove(visible_timer.event_id);
189 visible_timer.event_id = 0;
190 visible_timer.timeout = 0;
192 if (!TIZEN_PROFILE_WEARABLE) {
193 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
194 BT_ERR("Set vconf failed\n");
198 /* Switch Off visibility in Bluez */
199 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
200 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_start_visibility_timer(int timeout)
221 alarm_id_t alarm_id = 0;
222 #ifdef TIZEN_FEATURE_BT_DPM
223 int discoverable_state = DPM_BT_ERROR;
227 BT_ERR("Invalid timeout : %d", timeout);
228 return BLUETOOTH_ERROR_INVALID_PARAM;
231 #ifdef TIZEN_FEATURE_BT_DPM
232 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
233 if (discoverable_state != DPM_RESTRICTED) {
234 BT_ERR("Limited discoverable mode is not allowed");
235 return BLUETOOTH_ERROR_ACCESS_DENIED;
239 __bt_visibility_alarm_remove();
241 result = _bt_service_set_alarm(timeout, __bt_visibility_alarm_cb, NULL,
243 if (result != BLUETOOTH_ERROR_NONE) {
244 BT_ERR("_bt_service_set_alarm is failed : 0x%X", result);
245 return BLUETOOTH_ERROR_INTERNAL;
248 if (!TIZEN_PROFILE_WEARABLE) {
249 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
250 BT_ERR("Set vconf failed");
253 visible_timer.timeout = timeout;
254 visible_timer.alarm_id = alarm_id;
255 /* Take start time */
256 time(&(visible_timer.start_time));
257 visible_timer.event_id = g_timeout_add_seconds(1, __bt_timeout_handler, NULL);
259 return BLUETOOTH_ERROR_NONE;
262 int _bt_stop_visibility_timer(void)
264 __bt_visibility_alarm_remove();
266 visible_timer.timeout = 0;
268 if (!TIZEN_PROFILE_WEARABLE) {
269 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
270 BT_ERR("Set vconf failed");
273 return BLUETOOTH_ERROR_NONE;
276 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
283 ret_if(value == NULL);
286 dev->service_index = 0;
288 g_variant_get(value, "as", &iter);
289 while (g_variant_iter_loop(iter, "s", &uuid)) {
290 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
291 parts = g_strsplit(uuid, "-", -1);
293 if (parts == NULL || parts[0] == NULL) {
298 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
301 dev->service_index++;
304 g_variant_iter_free(iter);
307 static int __bt_get_bonded_device_info(gchar *device_path,
308 bluetooth_device_info_t *dev_info)
310 GError *error = NULL;
311 GDBusProxy *device_proxy;
312 gchar *address = NULL;
315 unsigned int cod = 0;
317 gboolean trust = FALSE;
318 gboolean paired = FALSE;
319 guchar connected = 0;
320 GByteArray *manufacturer_data = NULL;
322 GDBusConnection *conn;
324 GVariantIter *property_iter;
328 GVariantIter *char_value_iter;
330 BT_CHECK_PARAMETER(device_path, return);
331 BT_CHECK_PARAMETER(dev_info, return);
333 conn = _bt_gdbus_get_system_gconn();
334 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
336 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
340 BT_PROPERTIES_INTERFACE,
343 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
345 result = g_dbus_proxy_call_sync(device_proxy,
347 g_variant_new("(s)", BT_DEVICE_INTERFACE),
348 G_DBUS_CALL_FLAGS_NONE,
354 BT_ERR("Error occured in Proxy call");
356 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
357 g_clear_error(&error);
359 g_object_unref(device_proxy);
360 return BLUETOOTH_ERROR_INTERNAL;
363 g_object_unref(device_proxy);
365 g_variant_get(result, "(a{sv})", &property_iter);
367 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
368 if (!g_strcmp0(key, "Paired")) {
369 paired = g_variant_get_boolean(value);
370 } else if (!g_strcmp0(key, "Address")) {
371 g_variant_get(value, "s", &address);
372 } else if (!g_strcmp0(key, "Alias")) {
373 g_variant_get(value, "s", &alias);
374 } else if (!g_strcmp0(key, "Name")) {
375 g_variant_get(value, "s", &name);
376 } else if (!g_strcmp0(key, "Class")) {
377 cod = g_variant_get_uint32(value);
378 } else if (!g_strcmp0(key, "Connected")) {
379 connected = g_variant_get_byte(value);
380 } else if (!g_strcmp0(key, "Trusted")) {
381 trust = g_variant_get_boolean(value);
382 } else if (!g_strcmp0(key, "RSSI")) {
383 rssi = g_variant_get_int16(value);
384 } else if (!g_strcmp0(key, "UUIDs")) {
385 __bt_get_service_list(value, dev_info);
386 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
387 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
388 } else if (!g_strcmp0(key, "ManufacturerData")) {
389 manufacturer_data = g_byte_array_new();
390 g_variant_get(value, "ay", &char_value_iter);
391 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
392 g_byte_array_append(manufacturer_data, &char_value, 1);
394 g_variant_iter_free(char_value_iter);
396 if (manufacturer_data) {
397 if (manufacturer_data->len > 0) {
398 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
399 manufacturer_data->len);
402 g_byte_array_free(manufacturer_data, TRUE);
405 g_variant_iter_free(property_iter);
407 BT_DBG("trust: %d, paired: %d", trust, paired);
409 g_variant_unref(result);
411 if ((paired == FALSE) && (trust == FALSE)) {
415 return BLUETOOTH_ERROR_NOT_PAIRED;
418 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
421 _bt_divide_device_class(&dev_info->device_class, cod);
423 g_strlcpy(dev_info->device_name.name, alias ? alias : name,
424 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
426 dev_info->rssi = rssi;
427 dev_info->trust = trust;
428 dev_info->paired = paired;
429 dev_info->connected = connected;
430 ret = BLUETOOTH_ERROR_NONE;
438 void _bt_set_discovery_status(gboolean mode)
440 is_discovering = mode;
441 discovery_req = FALSE;
444 void _bt_set_cancel_by_user(gboolean value)
446 cancel_by_user = value;
449 gboolean _bt_get_cancel_by_user(void)
451 return cancel_by_user;
454 void _bt_adapter_set_status(bt_status_t status)
456 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
457 adapter_status = status;
460 bt_status_t _bt_adapter_get_status(void)
462 return adapter_status;
465 void _bt_adapter_set_le_status(bt_le_status_t status)
467 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
468 adapter_le_status = status;
471 bt_le_status_t _bt_adapter_get_le_status(void)
473 return adapter_le_status;
477 void _bt_set_le_intended_status(gboolean value)
479 is_le_intended = value;
482 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
484 char *phone_name = NULL;
487 ret_if(node == NULL);
489 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
490 phone_name = vconf_keynode_get_str(node);
492 if (phone_name && strlen(phone_name) != 0) {
493 if (!g_utf8_validate(phone_name, -1,
494 (const char **)&ptr))
497 BT_INFO("device_name is changed to %s", phone_name);
498 _bt_set_local_name(phone_name);
500 BT_ERR("phone_name is NOT valid");
503 BT_ERR("vconf type is NOT string");
507 static void __bt_set_local_name(void)
509 bluetooth_device_name_t local_name;
510 char *phone_name = NULL;
514 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
515 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
516 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
521 if (strlen(phone_name) != 0) {
522 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
525 _bt_set_local_name(phone_name);
531 static int __bt_set_enabled(void)
533 int adapter_status = BT_ADAPTER_DISABLED;
534 int result = BLUETOOTH_ERROR_NONE;
537 BT_DBG("g_source is removed");
538 g_source_remove(timer_id);
542 _bt_check_adapter(&adapter_status);
544 if (adapter_status == BT_ADAPTER_DISABLED) {
545 BT_ERR("Bluetoothd is not running");
546 return BLUETOOTH_ERROR_INTERNAL;
549 if (TIZEN_PROFILE_MOBILE || TIZEN_PROFILE_IVI) {
550 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
551 if (_bt_set_discoverable_mode(
552 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
553 BT_ERR("Set connectable mode failed");
554 } else if (TIZEN_PROFILE_TV) {
555 if (_bt_set_discoverable_mode(
556 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
557 BT_ERR("Fail to set discoverable mode");
560 /* Update Bluetooth Status to notify other modules */
561 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
562 BT_ERR("Set vconf failed\n");
564 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
565 BT_ERR("Set vconf failed\n");
567 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
568 EVT_VAL_BT_ON) != ES_R_OK)
569 BT_ERR("Fail to set value");
571 /* Send enabled event to API */
572 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
573 g_variant_new("(i)", result));
575 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
576 _bt_audio_start_auto_connect(FALSE);
579 __bt_set_local_name();
580 _bt_set_discovery_status(FALSE);
582 return BLUETOOTH_ERROR_NONE;
585 void _bt_set_disabled(int result)
587 int power_off_status = 0;
590 int pm_ignore_mode = 0;
592 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
593 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
595 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
597 /* Update the vconf BT status in normal Deactivation case only */
598 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
599 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
601 BT_DBG("Update vconf for BT normal Deactivation");
603 if (result == BLUETOOTH_ERROR_TIMEOUT)
604 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
605 BT_ERR("Set vconf failed");
607 /* Update Bluetooth Status to notify other modules */
608 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
609 BT_ERR("Set vconf failed");
611 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
612 EVT_VAL_BT_OFF) != ES_R_OK)
613 BT_ERR("Fail to set value");
616 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
617 BT_ERR("Set vconf failed\n");
619 _bt_cancel_queued_transfers();
620 _bt_adapter_set_status(BT_DEACTIVATED);
621 _bt_set_discovery_status(FALSE);
623 BT_INFO("Adapter disabled");
626 static int __bt_set_le_enabled(void)
629 int result = BLUETOOTH_ERROR_NONE;
632 /* Update Bluetooth Status to notify other modules */
633 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
634 BT_ERR("Set vconf failed\n");
636 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
637 EVT_VAL_BT_LE_ON) != ES_R_OK)
638 BT_ERR("Fail to set value");
640 /* Send enabled event to API */
642 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
643 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
645 status = _bt_adapter_get_status();
646 if (status == BT_DEACTIVATED) {
647 BT_INFO("BREDR is off, turn off PSCAN");
648 _bt_set_connectable(FALSE);
650 if (le_timer_id > 0) {
651 g_source_remove(le_timer_id);
655 /* Send enabled event to API */
656 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
657 g_variant_new("(i)", result));
659 __bt_set_local_name();
662 return BLUETOOTH_ERROR_NONE;
665 void _bt_set_le_disabled(int result)
667 int power_off_status;
670 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
671 BT_DBG("ret : %d", ret);
672 BT_DBG("power_off_status : %d", power_off_status);
674 /* Update Bluetooth Status to notify other modules */
675 BT_DBG("Update vconf for BT LE normal Deactivation");
676 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
677 BT_ERR("Set vconf failed\n");
678 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
680 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
681 EVT_VAL_BT_LE_OFF) != ES_R_OK)
682 BT_ERR("Fail to set value");
684 /* Send disabled event */
685 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
686 g_variant_new("(i)", result));
689 void *_bt_get_adapter_agent(void)
691 return adapter_agent;
694 int _bt_enable_core(void)
698 GError *error = NULL;
700 proxy = __bt_get_core_proxy();
701 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
703 /* Clean up the process */
704 result = g_dbus_proxy_call_sync(proxy,
707 G_DBUS_CALL_FLAGS_NONE,
714 BT_ERR("Bt core call failed(Error: %s)", error->message);
715 g_clear_error(&error);
717 BT_ERR("Bt core call failed");
718 return BLUETOOTH_ERROR_INTERNAL;
721 g_variant_unref(result);
722 return BLUETOOTH_ERROR_NONE;
725 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
727 gboolean flight_mode = FALSE;
728 int power_saving_mode = 0;
731 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
732 type = vconf_keynode_get_type(node);
733 if (type == VCONF_TYPE_BOOL) {
734 flight_mode = vconf_keynode_get_bool(node);
735 if (flight_mode != TRUE) {
736 BT_ERR("Ignore the event");
739 } else if (type == VCONF_TYPE_INT) {
740 power_saving_mode = vconf_keynode_get_int(node);
741 if (power_saving_mode != 2) {
742 BT_ERR("Ignore the event");
746 BT_ERR("Invaild vconf key type : %d", type);
753 void _bt_service_register_vconf_handler(void)
757 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
758 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
759 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
760 BT_ERR("Unable to register key handler");
762 BT_DBG("Telephony is disabled");
765 if (!TIZEN_PROFILE_WEARABLE) {
766 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
767 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
768 BT_ERR("Unable to register key handler");
772 void _bt_service_unregister_vconf_handler(void)
776 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
777 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
778 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
781 if (!TIZEN_PROFILE_WEARABLE) {
782 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
783 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
787 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
789 const char *bt_status = NULL;
790 const char *bt_le_status = NULL;
791 BT_DBG("bt state set event(%s) received", event_name);
793 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
794 BT_DBG("bt_state: (%s)", bt_status);
796 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
797 BT_DBG("bt_state: (%s)", bt_le_status);
800 static gboolean __bt_adapter_recovery_cb(gpointer data)
808 _bt_service_initialize();
810 ret = _bt_enable_adapter_check_status();
811 if (ret == BLUETOOTH_ERROR_NONE) {
812 ret = _bt_enable_adapter();
814 BT_ERR("_bt_enable_adapter() failed");
816 ret = _bt_enable_adapter_le();
818 BT_ERR("_bt_enable_adapter_le() failed");
828 void _bt_handle_adapter_added(void)
832 bt_le_status_t le_status;
836 BT_DBG("g_source is removed");
837 g_source_remove(timer_id);
844 status = _bt_adapter_get_status();
845 le_status = _bt_adapter_get_le_status();
846 BT_INFO("status : %d", status);
847 BT_INFO("le_status : %d", le_status);
848 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
849 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
850 if (!adapter_agent) {
851 BT_ERR("Fail to register agent");
855 if (adapter_agent == NULL) {
856 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
857 if (!adapter_agent) {
858 BT_ERR("Fail to register agent");
864 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
865 BT_ERR("Fail to register media player");
867 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
868 BT_ERR("Fail to init obex server");
870 #ifdef TIZEN_BT_PAN_NAP_ENABLED
871 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
872 BT_ERR("Fail to activate network");
875 /* add the vconf noti handler */
876 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
877 __bt_phone_name_changed_cb, NULL);
879 BT_ERR("Unable to register key handler");
881 if (le_status == BT_LE_ACTIVATING ||
882 status == BT_ACTIVATING) {
883 __bt_set_le_enabled();
884 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
887 if (status == BT_ACTIVATING) {
889 _bt_adapter_set_status(BT_ACTIVATED);
893 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
894 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
895 BT_ERR("Fail to register system event");
899 void _bt_handle_adapter_removed(void)
903 _bt_adapter_set_status(BT_DEACTIVATED);
905 __bt_visibility_alarm_remove();
907 if (alarm_mgr.is_alarm_initialized == TRUE) {
909 alarm_mgr.is_alarm_initialized = FALSE;
910 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
911 alarm_mgr.g_alarm_list = NULL;
914 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
915 _bt_audio_stop_auto_connect();
918 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
919 (vconf_callback_fn)__bt_phone_name_changed_cb);
921 ERR("vconf_ignore_key_changed failed\n");
923 /* unregister all the services/servers/profiles registered on bluez-adapter
924 once adapter is removed, reinitializing of the state-varaibles becomes
926 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
927 BT_ERR("Fail to unregister obex server");
929 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
930 BT_ERR("Fail to unregister media player");
932 /* Other unregister APIs should be placed here */
934 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
935 _bt_destroy_agent(adapter_agent);
936 adapter_agent = NULL;
938 if (recovery_cnt > 0) {
939 /* Send disabled event */
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));
944 if (recovery_timer > 0)
945 g_source_remove(recovery_timer);
947 if (TIZEN_PROFILE_WEARABLE) {
948 recovery_timer = g_timeout_add(BT_RECOVERY_TIME_W,
949 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
951 recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
952 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
955 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
956 BT_ERR("Fail to unregister system event");
960 if (recovery_timer == 0)
961 _bt_reliable_terminate_service(NULL);
963 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
964 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
965 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
968 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
969 BT_ERR("Fail to unregister system event");
972 static gboolean __bt_enable_timeout_cb(gpointer user_data)
976 GError *error = NULL;
980 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
982 BT_ERR("EnableAdapter is failed");
984 proxy = __bt_get_core_proxy();
988 /* Clean up the process */
989 result = g_dbus_proxy_call_sync(proxy,
992 G_DBUS_CALL_FLAGS_NONE,
999 BT_ERR("Bt core call failed(Error: %s)", error->message);
1000 g_clear_error(&error);
1002 BT_ERR("Bt core call failed");
1007 g_variant_unref(result);
1008 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
1010 if (recovery_cnt > 0) {
1011 BT_ERR("Try recovery again(remain:%d)", recovery_cnt);
1012 if (recovery_timer > 0)
1013 g_source_remove(recovery_timer);
1015 if (TIZEN_PROFILE_WEARABLE) {
1016 recovery_timer = g_timeout_add(BT_RECOVERY_TIME_W,
1017 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
1019 recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
1020 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
1026 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1027 _bt_terminate_service(NULL);
1032 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
1036 GError *error = NULL;
1040 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
1042 BT_ERR("EnableAdapterLE is failed");
1044 proxy = __bt_get_core_proxy();
1048 /* Clean up the process */
1049 result = g_dbus_proxy_call_sync(proxy,
1052 G_DBUS_CALL_FLAGS_NONE,
1058 if (error != NULL) {
1059 BT_ERR("Bt core call failed(Error: %s)", error->message);
1060 g_clear_error(&error);
1062 BT_ERR("Bt core call failed");
1066 g_variant_unref(result);
1068 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED)
1069 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
1071 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1072 _bt_terminate_service(NULL);
1077 void _bt_adapter_start_le_enable_timer(void)
1079 if (le_timer_id > 0) {
1080 g_source_remove(le_timer_id);
1084 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1085 __bt_enable_le_timeout_cb, NULL);
1090 void _bt_adapter_start_enable_timer(void)
1093 g_source_remove(timer_id);
1097 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1098 __bt_enable_timeout_cb, NULL);
1103 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1108 _bt_adapter_set_status(BT_ACTIVATED);
1113 int _bt_enable_adapter_check_status(void)
1115 bt_status_t status = _bt_adapter_get_status();
1116 bt_le_status_t le_status = _bt_adapter_get_le_status();
1120 if (status == BT_ACTIVATING) {
1121 BT_ERR("Enabling in progress");
1122 return BLUETOOTH_ERROR_IN_PROGRESS;
1125 if (status == BT_ACTIVATED) {
1126 BT_ERR("Already enabled");
1127 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1130 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1131 BT_ERR("Disabling in progress");
1132 return BLUETOOTH_ERROR_DEVICE_BUSY;
1135 return BLUETOOTH_ERROR_NONE;
1138 int _bt_enable_adapter(void)
1141 GError *error = NULL;
1143 GVariant *result = NULL;
1144 bt_status_t status = _bt_adapter_get_status();
1145 bt_le_status_t le_status = _bt_adapter_get_le_status();
1149 if (status == BT_ACTIVATING) {
1150 BT_ERR("Enabling in progress");
1151 return BLUETOOTH_ERROR_IN_PROGRESS;
1154 if (status == BT_ACTIVATED) {
1155 BT_ERR("Already enabled");
1156 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1159 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1160 BT_ERR("Disabling in progress");
1161 return BLUETOOTH_ERROR_DEVICE_BUSY;
1164 _bt_adapter_set_status(BT_ACTIVATING);
1166 if (TIZEN_PROFILE_TV) {
1167 int adapter_status = BT_ADAPTER_DISABLED;
1169 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1170 BT_ERR("Set vconf failed");
1172 _bt_check_adapter(&adapter_status);
1173 if (adapter_status == BT_ADAPTER_ENABLED) {
1174 g_idle_add(__bt_adapter_enabled_cb, NULL);
1175 _bt_adapter_start_enable_timer();
1176 return BLUETOOTH_ERROR_NONE;
1180 proxy = __bt_get_core_proxy();
1182 return BLUETOOTH_ERROR_INTERNAL;
1184 if (le_status == BT_LE_ACTIVATED) {
1185 BT_INFO("LE Already enabled. Just turn on PSCAN");
1186 ret = _bt_set_connectable(TRUE);
1187 if (ret == BLUETOOTH_ERROR_NONE)
1188 _bt_adapter_set_status(BT_ACTIVATED);
1190 return BLUETOOTH_ERROR_INTERNAL;
1193 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1195 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1198 BT_ERR("EnableAdapterLe failed: %s", error->message);
1199 _bt_adapter_set_status(BT_DEACTIVATED);
1200 g_clear_error(&error);
1202 result = g_dbus_proxy_call_sync(proxy,
1205 G_DBUS_CALL_FLAGS_NONE,
1210 if (error != NULL) {
1211 BT_ERR("Bt core call failed(Error: %s)", error->message);
1212 g_clear_error(&error);
1214 g_variant_unref(result);
1215 /* Terminate myself */
1216 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1217 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1218 return BLUETOOTH_ERROR_INTERNAL;
1220 g_variant_unref(result);
1221 if (le_status == BT_LE_ACTIVATED)
1224 _bt_adapter_start_enable_timer();
1226 return BLUETOOTH_ERROR_NONE;
1229 static gboolean __bt_set_powered(gboolean powered)
1232 GError *error = NULL;
1237 proxy = _bt_get_adapter_properties_proxy();
1238 retv_if(proxy == NULL, FALSE);
1240 result = g_dbus_proxy_call_sync(proxy, "Set",
1241 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Powered",
1242 g_variant_new("b", powered)),
1243 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1245 if (error != NULL) {
1246 BT_ERR("Failed to set powered property (Error: %s)",
1248 g_clear_error(&error);
1250 BT_ERR("Failed to set powered property");
1255 BT_INFO("Set powered [%d]", powered);
1256 g_variant_unref(result);
1260 static gboolean __bt_disconnect_all(void)
1263 GDBusConnection *conn;
1264 GDBusProxy *dev_proxy;
1265 gboolean ret = FALSE;
1267 GError *error = NULL;
1268 GArray *device_list;
1269 bluetooth_device_info_t info;
1271 char *device_path = NULL;
1272 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1277 conn = _bt_gdbus_get_system_gconn();
1279 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1281 if (_bt_get_bonded_devices(&device_list)
1282 != BLUETOOTH_ERROR_NONE) {
1283 g_array_free(device_list, TRUE);
1287 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1289 for (i = 0; i < size; i++) {
1291 info = g_array_index(device_list,
1292 bluetooth_device_info_t, i);
1294 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1295 BT_DBG("Found Connected device");
1296 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1297 device_path = _bt_get_device_object_path(address);
1298 if (device_path == NULL)
1301 BT_DBG("Disconnecting : %s", device_path);
1303 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1307 BT_DEVICE_INTERFACE,
1310 if (dev_proxy == NULL)
1313 result = g_dbus_proxy_call_sync(dev_proxy,
1316 G_DBUS_CALL_FLAGS_NONE,
1322 if (error != NULL) {
1323 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1324 g_clear_error(&error);
1326 BT_ERR("Disconnect call failed");
1327 g_object_unref(dev_proxy);
1331 g_variant_unref(result);
1332 g_object_unref(dev_proxy);
1336 g_array_free(device_list, TRUE);
1342 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1345 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1346 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
1347 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
1353 int _bt_disable_cb(void)
1361 GError *error = NULL;
1363 _bt_adapter_set_status(BT_DEACTIVATING);
1365 bt_le_status_t le_status;
1366 le_status = _bt_adapter_get_le_status();
1367 BT_DBG("le_status : %d", le_status);
1368 if (le_status == BT_LE_ACTIVATED) {
1369 BT_INFO("LE is enabled. Just turn off PSCAN");
1371 if (_bt_is_discovering())
1372 _bt_cancel_discovery();
1374 if (_bt_is_connectable() == FALSE) {
1375 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1377 ret = _bt_set_connectable(FALSE);
1378 if (ret != BLUETOOTH_ERROR_NONE) {
1379 BT_ERR("_bt_set_connectable fail!");
1380 _bt_adapter_set_status(BT_ACTIVATED);
1381 return BLUETOOTH_ERROR_INTERNAL;
1386 proxy = __bt_get_core_proxy();
1387 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1389 result = g_dbus_proxy_call_sync(proxy,
1392 G_DBUS_CALL_FLAGS_NONE,
1398 if (error != NULL) {
1399 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1400 g_clear_error(&error);
1402 BT_ERR("Failed to DisableAdapter");
1403 _bt_adapter_set_status(BT_ACTIVATED);
1404 return BLUETOOTH_ERROR_INTERNAL;
1407 g_variant_unref(result);
1408 return BLUETOOTH_ERROR_NONE;
1411 int _bt_disable_adapter_check_status(void)
1413 bt_status_t status = _bt_adapter_get_status();
1417 if (status == BT_DEACTIVATING) {
1418 BT_DBG("Disabling in progress");
1419 return BLUETOOTH_ERROR_IN_PROGRESS;
1422 if (status == BT_DEACTIVATED) {
1423 BT_DBG("Already disabled");
1424 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1427 return BLUETOOTH_ERROR_NONE;
1430 int _bt_disable_adapter(void)
1434 bt_le_status_t le_status;
1436 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1437 BT_DBG("Disabling in progress");
1438 return BLUETOOTH_ERROR_IN_PROGRESS;
1441 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1442 BT_DBG("Already disabled");
1443 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1447 g_source_remove(timer_id);
1451 /* unregister all the services/servers/profiles registered on bluez-adapter
1452 once adapter is removed, reinitializing of the state-varaibles becomes
1454 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1455 BT_ERR("Fail to unregister obex server");
1457 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
1458 BT_ERR("Fail to unregister media player");
1459 /* Other unregister APIs should be placed here */
1461 le_status = _bt_adapter_get_le_status();
1462 if (le_status == BT_LE_ACTIVATED && is_le_intended == TRUE) {
1463 __bt_disconnect_all();
1465 if (le_status == BT_LE_ACTIVATED)
1466 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1468 __bt_set_powered(FALSE);
1471 ret = _bt_disable_cb();
1477 int _bt_recover_adapter(void)
1481 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1482 BT_ERR("Disabling in progress");
1483 return BLUETOOTH_ERROR_IN_PROGRESS;
1486 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1487 BT_ERR("Already disabled");
1488 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1491 recovery_cnt = BT_RECOVERY_MAX_COUNT;
1493 _bt_disable_adapter();
1494 _bt_disable_adapter_le();
1497 return BLUETOOTH_ERROR_NONE;
1500 int _bt_reset_adapter(void)
1504 GError *error = NULL;
1508 proxy = __bt_get_core_proxy();
1510 return BLUETOOTH_ERROR_INTERNAL;
1512 result = g_dbus_proxy_call_sync(proxy,
1515 G_DBUS_CALL_FLAGS_NONE,
1521 if (error != NULL) {
1522 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1523 g_clear_error(&error);
1525 BT_ERR("Failed to ResetAdapter");
1526 return BLUETOOTH_ERROR_INTERNAL;
1529 g_variant_unref(result);
1530 /* Terminate myself */
1531 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1532 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1534 return BLUETOOTH_ERROR_NONE;
1537 int _bt_check_adapter(int *status)
1539 if (!TIZEN_PROFILE_TV) {
1540 char *adapter_path = NULL;
1542 BT_CHECK_PARAMETER(status, return);
1544 *status = BT_ADAPTER_DISABLED;
1546 adapter_path = _bt_get_adapter_path();
1549 if (adapter_path != NULL)
1550 *status = BT_ADAPTER_ENABLED;
1552 g_free(adapter_path);
1553 return BLUETOOTH_ERROR_NONE;
1556 GError *error = NULL;
1559 gboolean powered = FALSE;
1561 BT_CHECK_PARAMETER(status, return);
1563 *status = BT_ADAPTER_DISABLED;
1565 proxy = _bt_get_adapter_properties_proxy();
1566 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1568 result = g_dbus_proxy_call_sync(proxy,
1570 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1572 G_DBUS_CALL_FLAGS_NONE,
1578 BT_ERR("Failed to get local address");
1579 if (error != NULL) {
1580 BT_ERR("Failed to get local address (Error: %s)", error->message);
1581 g_clear_error(&error);
1583 return BLUETOOTH_ERROR_INTERNAL;
1586 g_variant_get(result, "(v)", &temp);
1587 powered = g_variant_get_boolean(temp);
1588 BT_DBG("powered: %d", powered);
1591 *status = BT_ADAPTER_ENABLED;
1593 g_variant_unref(result);
1594 g_variant_unref(temp);
1595 return BLUETOOTH_ERROR_NONE;
1599 int _bt_enable_adapter_le(void)
1603 GError *error = NULL;
1604 bt_status_t status = _bt_adapter_get_status();
1605 bt_le_status_t le_status = _bt_adapter_get_le_status();
1608 if (le_status == BT_LE_ACTIVATING) {
1609 BT_ERR("Enabling in progress");
1610 return BLUETOOTH_ERROR_IN_PROGRESS;
1613 if (le_status == BT_LE_ACTIVATED) {
1614 BT_ERR("Already enabled");
1615 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1618 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1619 BT_ERR("Disabling in progress");
1620 _bt_set_le_intended_status(FALSE);
1621 return BLUETOOTH_ERROR_DEVICE_BUSY;
1624 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1626 proxy = __bt_get_core_proxy();
1627 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1629 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1631 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1634 BT_ERR("EnableAdapterLe failed: %s", error->message);
1635 _bt_adapter_set_le_status(BT_DEACTIVATED);
1636 g_clear_error(&error);
1638 /* Clean up the process */
1639 result = g_dbus_proxy_call_sync(proxy,
1642 G_DBUS_CALL_FLAGS_NONE,
1648 BT_ERR("Bt core call failed");
1650 BT_ERR("EnableAdapterLE Failed %s", error->message);
1651 g_clear_error(&error);
1654 g_variant_unref(result);
1655 /* Terminate myself */
1656 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1657 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1658 return BLUETOOTH_ERROR_INTERNAL;
1662 g_variant_unref(result);
1664 _bt_adapter_start_le_enable_timer();
1666 if (status == BT_ACTIVATED) {
1667 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1668 __bt_set_le_enabled();
1670 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1672 return BLUETOOTH_ERROR_NONE;
1675 int _bt_disable_adapter_le(void)
1679 bt_le_status_t bt_le_state;
1681 GError *error = NULL;
1683 bt_le_state = _bt_adapter_get_le_status();
1684 if (bt_le_state == BT_LE_DEACTIVATING) {
1685 BT_DBG("Disabling in progress");
1686 return BLUETOOTH_ERROR_IN_PROGRESS;
1689 if (bt_le_state == BT_LE_DEACTIVATED) {
1690 BT_DBG("Already disabled");
1691 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1694 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1696 proxy = __bt_get_core_proxy();
1698 return BLUETOOTH_ERROR_INTERNAL;
1700 result = g_dbus_proxy_call_sync(proxy,
1703 G_DBUS_CALL_FLAGS_NONE,
1709 if (error != NULL) {
1710 BT_ERR("Bt core call failed (Error: %s)", error->message);
1711 g_clear_error(&error);
1713 BT_ERR("Bt core call failed");
1714 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1715 return BLUETOOTH_ERROR_INTERNAL;
1718 g_variant_unref(result);
1719 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1720 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1722 return BLUETOOTH_ERROR_NONE;
1725 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1729 GError *error = NULL;
1730 const char *address;
1734 BT_CHECK_PARAMETER(local_address, return);
1736 proxy = _bt_get_adapter_properties_proxy();
1737 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1739 result = g_dbus_proxy_call_sync(proxy,
1741 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1743 G_DBUS_CALL_FLAGS_NONE,
1749 BT_ERR("Failed to get local address");
1750 if (error != NULL) {
1751 BT_ERR("Failed to get local address (Error: %s)", error->message);
1752 g_clear_error(&error);
1754 return BLUETOOTH_ERROR_INTERNAL;
1757 g_variant_get(result, "(v)", &temp);
1758 address = g_variant_get_string(temp, NULL);
1759 BT_DBG("Address:%s", address);
1762 _bt_convert_addr_string_to_type(local_address->addr, address);
1764 return BLUETOOTH_ERROR_INTERNAL;
1766 g_variant_unref(result);
1767 g_variant_unref(temp);
1768 return BLUETOOTH_ERROR_NONE;
1771 int _bt_get_local_version(bluetooth_version_t *local_version)
1774 const char *ver = NULL;
1776 int ret = BLUETOOTH_ERROR_NONE;
1780 BT_CHECK_PARAMETER(local_version, return);
1782 GError *error = NULL;
1784 proxy = _bt_get_adapter_properties_proxy();
1785 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1787 result = g_dbus_proxy_call_sync(proxy,
1789 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1791 G_DBUS_CALL_FLAGS_NONE,
1797 if (error != NULL) {
1798 BT_ERR("Failed to get local version (Error: %s)", error->message);
1799 g_clear_error(&error);
1801 BT_ERR("Failed to get local version");
1802 return BLUETOOTH_ERROR_INTERNAL;
1805 g_variant_get(result, "(v)", &temp);
1806 ver = g_variant_get_string(temp, NULL);
1807 BT_DBG("VERSION: %s", ver);
1809 if (ver && (strlen(ver) > 0)) {
1810 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1811 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1814 g_strlcpy(local_version->version, ver,
1815 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1818 ret = BLUETOOTH_ERROR_INTERNAL;
1821 g_variant_unref(result);
1822 g_variant_unref(temp);
1826 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1829 const char *name = NULL;
1831 int ret = BLUETOOTH_ERROR_NONE;
1834 GError *error = NULL;
1836 BT_CHECK_PARAMETER(local_name, return);
1838 proxy = _bt_get_adapter_properties_proxy();
1839 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1841 result = g_dbus_proxy_call_sync(proxy,
1843 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1845 G_DBUS_CALL_FLAGS_NONE,
1851 if (error != NULL) {
1852 BT_ERR("Failed to get local name (Error: %s)", error->message);
1853 g_clear_error(&error);
1855 BT_ERR("Failed to get local name");
1856 return BLUETOOTH_ERROR_INTERNAL;
1859 g_variant_get(result, "(v)", &temp);
1860 name = g_variant_get_string(temp, NULL);
1861 BT_DBG("LOCAL NAME:%s", name);
1863 if (name && (strlen(name) > 0)) {
1864 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1865 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1868 g_strlcpy(local_name->name, name,
1869 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1871 ret = BLUETOOTH_ERROR_INTERNAL;
1873 g_variant_unref(result);
1874 g_variant_unref(temp);
1878 int _bt_set_local_name(char *local_name)
1881 GError *error = NULL;
1885 BT_CHECK_PARAMETER(local_name, return);
1887 proxy = _bt_get_adapter_properties_proxy();
1889 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1891 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1894 result = g_dbus_proxy_call_sync(proxy,
1896 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1897 "Alias", g_variant_new("s", local_name)),
1898 G_DBUS_CALL_FLAGS_NONE,
1904 if (error != NULL) {
1905 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1906 g_clear_error(&error);
1908 BT_ERR("Failed to set Alias");
1909 return BLUETOOTH_ERROR_INTERNAL;
1912 g_variant_unref(result);
1913 return BLUETOOTH_ERROR_NONE;
1916 int _bt_is_service_used(char *service_uuid, gboolean *used)
1919 GError *error = NULL;
1920 int ret = BLUETOOTH_ERROR_NONE;
1922 GVariant *temp = NULL;
1923 GVariantIter *iter = NULL;
1927 BT_CHECK_PARAMETER(service_uuid, return);
1928 BT_CHECK_PARAMETER(used, return);
1930 proxy = _bt_get_adapter_properties_proxy();
1931 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1933 result = g_dbus_proxy_call_sync(proxy,
1935 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1937 G_DBUS_CALL_FLAGS_NONE,
1943 if (error != NULL) {
1944 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1945 g_clear_error(&error);
1947 BT_ERR("Failed to get UUIDs");
1948 return BLUETOOTH_ERROR_INTERNAL;
1951 g_variant_get(result, "(v)", &temp);
1952 g_variant_get(temp, "as", &iter);
1955 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1956 if (strcasecmp(uuid, service_uuid) == 0) {
1961 g_variant_iter_free(iter);
1962 g_variant_unref(result);
1964 BT_DBG("Service Used? %d", *used);
1969 static gboolean __bt_get_discoverable_property(void)
1972 gboolean discoverable_v;
1973 GError *error = NULL;
1977 proxy = _bt_get_adapter_properties_proxy();
1978 retv_if(proxy == NULL, FALSE);
1980 result = g_dbus_proxy_call_sync(proxy,
1982 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1984 G_DBUS_CALL_FLAGS_NONE,
1990 if (error != NULL) {
1991 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1992 g_clear_error(&error);
1994 BT_ERR("Failed to get Discoverable property");
1995 return BLUETOOTH_ERROR_INTERNAL;
1998 g_variant_get(result, "(v)", &temp);
1999 discoverable_v = g_variant_get_boolean(temp);
2000 BT_DBG("discoverable_v:%d", discoverable_v);
2002 g_variant_unref(result);
2003 g_variant_unref(temp);
2005 return discoverable_v;
2008 int _bt_get_discoverable_mode(int *mode)
2010 gboolean discoverable;
2011 unsigned int timeout;
2013 BT_CHECK_PARAMETER(mode, return);
2015 discoverable = __bt_get_discoverable_property();
2016 timeout = _bt_get_discoverable_timeout_property();
2018 if (discoverable == TRUE) {
2020 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
2022 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
2024 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
2026 return BLUETOOTH_ERROR_NONE;
2030 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
2032 int ret = BLUETOOTH_ERROR_NONE;
2035 GError *error = NULL;
2038 #ifdef TIZEN_FEATURE_BT_DPM
2039 int discoverable_state = DPM_BT_ERROR;
2042 proxy = _bt_get_adapter_properties_proxy();
2044 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2046 #ifdef TIZEN_FEATURE_BT_DPM
2047 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
2048 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
2049 discoverable_state == DPM_RESTRICTED) {
2050 if (headed_plugin_info->plugin_headed_enabled)
2051 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
2053 return BLUETOOTH_ERROR_ACCESS_DENIED;
2056 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE &&
2057 discoverable_state == DPM_RESTRICTED) {
2058 if (headed_plugin_info->plugin_headed_enabled)
2059 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
2061 return BLUETOOTH_ERROR_ACCESS_DENIED;
2065 switch (discoverable_mode) {
2066 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
2071 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
2076 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
2081 return BLUETOOTH_ERROR_INVALID_PARAM;
2084 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
2085 discoverable_mode, timeout);
2087 result = g_dbus_proxy_call_sync(proxy,
2089 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2090 "Connectable", g_variant_new("b", pg_scan)),
2091 G_DBUS_CALL_FLAGS_NONE,
2097 if (error != NULL) {
2098 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2099 g_clear_error(&error);
2101 BT_ERR("Failed to set connectable property");
2102 return BLUETOOTH_ERROR_INTERNAL;
2104 g_variant_unref(result);
2105 result = g_dbus_proxy_call_sync(proxy,
2107 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2108 g_variant_new("b", inq_scan)),
2109 G_DBUS_CALL_FLAGS_NONE,
2115 if (error != NULL) {
2116 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2117 g_clear_error(&error);
2119 BT_ERR("Failed to set Discoverable property");
2120 return BLUETOOTH_ERROR_INTERNAL;
2122 g_variant_unref(result);
2123 result = g_dbus_proxy_call_sync(proxy,
2125 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2126 "DiscoverableTimeout", g_variant_new("u", timeout)),
2127 G_DBUS_CALL_FLAGS_NONE,
2133 if (error != NULL) {
2134 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2135 g_clear_error(&error);
2137 BT_ERR("Failed to set DiscoverableTimeout property");
2138 return BLUETOOTH_ERROR_INTERNAL;
2141 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE) {
2142 ret = _bt_stop_visibility_timer();
2143 if (!TIZEN_PROFILE_WEARABLE) {
2144 if (vconf_set_int(BT_FILE_VISIBLE_TIME, -1) != 0)
2145 BT_ERR("Set vconf failed");
2147 } else if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE) {
2148 ret = _bt_start_visibility_timer(timeout);
2150 ret = _bt_stop_visibility_timer();
2153 g_variant_unref(result);
2158 int _bt_start_discovery(void)
2161 GError *error = NULL;
2164 if (_bt_is_discovering() == TRUE) {
2165 BT_ERR("BT is already in discovering");
2166 return BLUETOOTH_ERROR_IN_PROGRESS;
2167 } else if (_bt_is_device_creating() == TRUE) {
2168 BT_ERR("Bonding device is going on");
2169 return BLUETOOTH_ERROR_DEVICE_BUSY;
2172 proxy = _bt_get_adapter_proxy();
2173 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2175 result = g_dbus_proxy_call_sync(proxy,
2178 G_DBUS_CALL_FLAGS_NONE,
2184 if (error != NULL) {
2185 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2186 g_clear_error(&error);
2188 BT_ERR("StartDiscovery failed");
2189 return BLUETOOTH_ERROR_INTERNAL;
2192 discovery_req = TRUE;
2193 cancel_by_user = FALSE;
2194 /* discovery status will be change in event */
2195 g_variant_unref(result);
2196 return BLUETOOTH_ERROR_NONE;
2199 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2203 GError *error = NULL;
2204 const gchar *disc_type;
2206 if (_bt_is_discovering() == TRUE) {
2207 BT_ERR("BT is already in discovering");
2208 return BLUETOOTH_ERROR_IN_PROGRESS;
2211 proxy = _bt_get_adapter_proxy();
2212 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2214 if (role == DISCOVERY_ROLE_BREDR)
2215 disc_type = "BREDR";
2216 else if (role == DISCOVERY_ROLE_LE)
2218 else if (role == DISCOVERY_ROLE_LE_BREDR)
2219 disc_type = "LE_BREDR";
2221 return BLUETOOTH_ERROR_INVALID_PARAM;
2223 result = g_dbus_proxy_call_sync(proxy,
2224 "StartCustomDiscovery",
2225 g_variant_new("s", disc_type),
2226 G_DBUS_CALL_FLAGS_NONE,
2232 if (error != NULL) {
2233 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2234 g_clear_error(&error);
2236 BT_ERR("StartCustomDiscovery failed");
2237 return BLUETOOTH_ERROR_INTERNAL;
2240 discovery_req = TRUE;
2241 cancel_by_user = FALSE;
2242 /* discovery status will be change in event */
2243 g_variant_unref(result);
2244 return BLUETOOTH_ERROR_NONE;
2247 int _bt_cancel_discovery(void)
2250 GError *error = NULL;
2253 if (_bt_is_discovering() == FALSE) {
2254 BT_ERR("BT is not in discovering");
2255 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2258 proxy = _bt_get_adapter_proxy();
2259 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2261 result = g_dbus_proxy_call_sync(proxy,
2264 G_DBUS_CALL_FLAGS_NONE,
2270 int ret = BLUETOOTH_ERROR_INTERNAL;
2271 if (error != NULL) {
2272 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2274 if (g_strrstr(error->message, "No discovery started"))
2275 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2277 g_clear_error(&error);
2279 BT_ERR("StopDiscovery failed");
2285 discovery_req = FALSE;
2286 cancel_by_user = TRUE;
2287 /* discovery status will be change in event */
2288 g_variant_unref(result);
2289 return BLUETOOTH_ERROR_NONE;
2292 gboolean _bt_is_discovering(void)
2294 return (is_discovering || discovery_req);
2297 gboolean _bt_is_connectable(void)
2300 GError *error = NULL;
2301 gboolean is_connectable = FALSE;
2305 proxy = _bt_get_adapter_properties_proxy();
2306 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2308 result = g_dbus_proxy_call_sync(proxy,
2310 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2312 G_DBUS_CALL_FLAGS_NONE,
2318 if (error != NULL) {
2319 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2320 g_clear_error(&error);
2322 BT_ERR("Failed to get connectable property");
2323 return BLUETOOTH_ERROR_INTERNAL;
2326 g_variant_get(result, "(v)", &temp);
2327 is_connectable = g_variant_get_boolean(temp);
2328 BT_DBG("discoverable_v:%d", is_connectable);
2330 g_variant_unref(result);
2331 g_variant_unref(temp);
2333 BT_INFO("Get connectable [%d]", is_connectable);
2334 return is_connectable;
2337 int _bt_set_connectable(gboolean is_connectable)
2340 GError *error = NULL;
2343 if (__bt_is_factory_test_mode()) {
2344 BT_ERR("Unable to set connectable in factory binary !!");
2345 return BLUETOOTH_ERROR_NOT_SUPPORT;
2348 proxy = _bt_get_adapter_properties_proxy();
2350 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2352 result = g_dbus_proxy_call_sync(proxy,
2354 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2355 g_variant_new("b", is_connectable)),
2356 G_DBUS_CALL_FLAGS_NONE,
2362 if (error != NULL) {
2363 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2364 g_clear_error(&error);
2366 BT_ERR("Failed to set connectable property");
2367 return BLUETOOTH_ERROR_INTERNAL;
2370 BT_INFO_C("### Set connectable [%d]", is_connectable);
2371 g_variant_unref(result);
2372 return BLUETOOTH_ERROR_NONE;
2375 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2378 gboolean discovering_v;
2379 GError *error = NULL;
2380 char *discovering_type = NULL;
2384 proxy = _bt_get_adapter_properties_proxy();
2385 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2387 if (discovery_type == DISCOVERY_ROLE_BREDR)
2388 discovering_type = "Discovering";
2389 else if (discovery_type == DISCOVERY_ROLE_LE)
2390 discovering_type = "LEDiscovering";
2392 result = g_dbus_proxy_call_sync(proxy,
2394 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2396 G_DBUS_CALL_FLAGS_NONE,
2402 if (error != NULL) {
2403 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2404 g_clear_error(&error);
2406 BT_ERR("Failed to get discovering property");
2407 return BLUETOOTH_ERROR_INTERNAL;
2410 g_variant_get(result, "(v)", &temp);
2411 discovering_v = g_variant_get_boolean(temp);
2412 BT_DBG("discoverable_v:%d", discovering_v);
2414 g_variant_unref(result);
2415 g_variant_unref(temp);
2417 return discovering_v;
2420 unsigned int _bt_get_discoverable_timeout_property(void)
2423 unsigned int timeout_v;
2424 GError *error = NULL;
2428 proxy = _bt_get_adapter_properties_proxy();
2429 retv_if(proxy == NULL, 0);
2431 result = g_dbus_proxy_call_sync(proxy,
2433 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2434 "DiscoverableTimeout"),
2435 G_DBUS_CALL_FLAGS_NONE,
2441 BT_ERR("Fail to get discoverable timeout");
2442 if (error != NULL) {
2443 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2444 g_clear_error(&error);
2449 g_variant_get(result, "(v)", &temp);
2450 timeout_v = g_variant_get_uint32(temp);
2451 BT_DBG("discoverable_v:%d", timeout_v);
2453 g_variant_unref(result);
2454 g_variant_unref(temp);
2459 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2461 bluetooth_device_info_t *dev_info;
2464 GByteArray *manufacturer_data = NULL;
2466 GVariantIter *char_value_iter;
2468 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2470 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2475 if (!g_strcmp0(key, "Address")) {
2476 const char *address = NULL;
2477 address = g_variant_get_string(value, NULL);
2478 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2480 } else if (!g_strcmp0(key, "Class")) {
2482 cod = g_variant_get_uint32(value);
2483 _bt_divide_device_class(&dev_info->device_class, cod);
2484 } else if (!g_strcmp0(key, "Name")) {
2485 const char *name = NULL;
2486 name = g_variant_get_string(value, NULL);
2487 /* If there is no Alias */
2488 if (strlen(dev_info->device_name.name) == 0) {
2489 g_strlcpy(dev_info->device_name.name, name,
2490 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2492 } else if (!g_strcmp0(key, "Alias")) {
2493 const char *alias = NULL;
2494 alias = g_variant_get_string(value, NULL);
2495 /* Overwrite the name */
2497 memset(dev_info->device_name.name, 0x00,
2498 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2499 g_strlcpy(dev_info->device_name.name, alias,
2500 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2502 } else if (!g_strcmp0(key, "IsAliasSet")) {
2503 dev_info->is_alias_set = g_variant_get_boolean(value);
2504 } else if (!g_strcmp0(key, "Connected")) {
2505 dev_info->connected = g_variant_get_byte(value);
2506 } else if (!g_strcmp0(key, "Paired")) {
2507 dev_info->paired = g_variant_get_boolean(value);
2508 } else if (!g_strcmp0(key, "Trusted")) {
2509 dev_info->trust = g_variant_get_boolean(value);
2510 } else if (!g_strcmp0(key, "RSSI")) {
2511 dev_info->rssi = g_variant_get_int16(value);
2512 } else if (!g_strcmp0(key, "UUIDs")) {
2518 dev_info->service_index = 0;
2519 g_variant_get(value, "as", &iter);
2520 while (g_variant_iter_loop(iter, "s", &uuid)) {
2521 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2522 parts = g_strsplit(uuid, "-", -1);
2524 if (parts == NULL || parts[0] == NULL) {
2529 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2534 dev_info->service_index = i;
2535 g_variant_iter_free(iter);
2536 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2537 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2538 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2539 manufacturer_data = g_byte_array_new();
2540 g_variant_get(value, "ay", &char_value_iter);
2541 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2542 g_byte_array_append(manufacturer_data, &char_value, 1);
2544 if (manufacturer_data) {
2545 if (manufacturer_data->len > 0)
2546 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2548 g_variant_iter_free(char_value_iter);
2549 g_byte_array_free(manufacturer_data, TRUE);
2556 static void __bt_extract_device_info(GVariantIter *iter,
2559 bluetooth_device_info_t *dev_info = NULL;
2560 char *object_path = NULL;
2561 GVariantIter *interface_iter;
2562 GVariantIter *svc_iter;
2563 char *interface_str = NULL;
2565 /* Parse the signature: oa{sa{sv}}} */
2566 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2569 if (object_path == NULL)
2572 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2573 &interface_str, &svc_iter)) {
2574 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2575 BT_DBG("Found a device: %s", object_path);
2576 dev_info = __bt_parse_device_info(svc_iter);
2578 if (dev_info->paired == TRUE) {
2579 g_array_append_vals(*dev_list, dev_info,
2580 sizeof(bluetooth_device_info_t));
2584 g_free(interface_str);
2585 g_variant_iter_free(svc_iter);
2593 int _bt_get_bonded_devices(GArray **dev_list)
2596 GDBusConnection *conn;
2597 GDBusProxy *manager_proxy;
2598 GVariant *result = NULL;
2599 GVariantIter *iter = NULL;
2600 GError *error = NULL;
2602 conn = _bt_gdbus_get_system_gconn();
2603 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2605 manager_proxy = _bt_get_manager_proxy();
2606 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2608 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2610 G_DBUS_CALL_FLAGS_NONE,
2616 if (error != NULL) {
2617 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2618 g_clear_error(&error);
2620 BT_ERR("Failed to Failed to GetManagedObjects");
2621 return BLUETOOTH_ERROR_INTERNAL;
2624 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2625 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2627 __bt_extract_device_info(iter, dev_list);
2628 g_variant_iter_free(iter);
2629 g_variant_unref(result);
2632 return BLUETOOTH_ERROR_NONE;
2635 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2638 GDBusConnection *conn;
2639 GDBusProxy *manager_proxy;
2640 GVariant *result = NULL;
2641 GVariant *result1 = NULL;
2642 GVariantIter *iter = NULL;
2643 GError *error = NULL;
2644 char *object_path = NULL;
2645 GVariantIter *interface_iter;
2646 char *interface_str = NULL;
2647 GDBusProxy *device_proxy = NULL;
2648 gboolean is_connected = FALSE;
2650 conn = _bt_gdbus_get_system_gconn();
2651 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2653 manager_proxy = _bt_get_manager_proxy();
2654 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2656 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2658 G_DBUS_CALL_FLAGS_NONE,
2664 if (error != NULL) {
2665 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2666 g_clear_error(&error);
2669 BT_ERR("Failed to Failed to GetManagedObjects");
2670 return BLUETOOTH_ERROR_INTERNAL;
2673 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2674 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2676 /* Parse the signature: oa{sa{sv}}} */
2677 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2678 if (object_path == NULL)
2681 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2682 &interface_str, NULL)) {
2683 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2684 BT_DBG("Found a device: %s", object_path);
2685 g_free(interface_str);
2687 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2688 NULL, BT_BLUEZ_NAME,
2689 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2691 if (device_proxy == NULL) {
2692 BT_DBG("Device don't have this service");
2696 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2697 g_variant_new("(s)", profile_uuid),
2698 G_DBUS_CALL_FLAGS_NONE,
2703 if (result1 == NULL) {
2704 BT_ERR("Error occured in Proxy call");
2706 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2707 g_error_free(error);
2710 g_object_unref(device_proxy);
2713 g_variant_get(result1, "(b)", &is_connected);
2715 if (is_connected == TRUE) {
2716 char address[BT_ADDRESS_STRING_SIZE];
2717 bluetooth_device_address_t *addr = NULL;
2719 _bt_convert_device_path_to_address(object_path, address);
2721 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2722 _bt_convert_addr_string_to_type(addr->addr, address);
2724 g_array_append_vals(*addr_list, addr,
2725 sizeof(bluetooth_device_address_t));
2728 g_variant_unref(result1);
2729 g_object_unref(device_proxy);
2736 g_variant_unref(result);
2737 g_variant_iter_free(iter);
2740 return BLUETOOTH_ERROR_NONE;
2743 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2744 bluetooth_device_info_t *dev_info)
2746 char *object_path = NULL;
2747 GDBusProxy *adapter_proxy;
2748 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2749 int ret = BLUETOOTH_ERROR_NONE;
2751 BT_CHECK_PARAMETER(device_address, return);
2752 BT_CHECK_PARAMETER(dev_info, return);
2754 adapter_proxy = _bt_get_adapter_proxy();
2755 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2757 _bt_convert_addr_type_to_string(address, device_address->addr);
2759 object_path = _bt_get_device_object_path(address);
2761 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2763 ret = __bt_get_bonded_device_info(object_path, dev_info);
2764 g_free(object_path);
2769 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2771 char *object_path = NULL;
2772 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2773 gboolean alias_set = FALSE;
2775 GDBusConnection *conn;
2776 GDBusProxy *device_proxy;
2777 GError *error = NULL;
2778 GVariant *result = NULL;
2779 GVariant *temp = NULL;
2782 BT_CHECK_PARAMETER(device_address, return);
2783 BT_CHECK_PARAMETER(is_alias_set, return);
2785 _bt_convert_addr_type_to_string(address, device_address->addr);
2787 object_path = _bt_get_device_object_path(address);
2788 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2790 conn = _bt_gdbus_get_system_gconn();
2792 g_free(object_path);
2793 return BLUETOOTH_ERROR_INTERNAL;
2796 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2800 BT_PROPERTIES_INTERFACE,
2802 if (device_proxy == NULL) {
2803 g_free(object_path);
2804 return BLUETOOTH_ERROR_INTERNAL;
2807 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2808 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2809 G_DBUS_CALL_FLAGS_NONE,
2815 BT_ERR("Error occured in Proxy call");
2816 if (error != NULL) {
2817 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2818 g_error_free(error);
2820 g_object_unref(device_proxy);
2821 g_free(object_path);
2822 return BLUETOOTH_ERROR_INTERNAL;
2825 g_variant_get(result, "(v)", &temp);
2826 alias_set = g_variant_get_boolean(temp);
2827 *is_alias_set = alias_set;
2828 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2829 g_variant_unref(temp);
2830 g_variant_unref(result);
2831 g_object_unref(device_proxy);
2833 g_free(object_path);
2835 return BLUETOOTH_ERROR_NONE;
2838 int _bt_get_timeout_value(int *timeout)
2840 time_t current_time;
2843 /* Take current time */
2844 time(¤t_time);
2845 time_diff = difftime(current_time, visible_timer.start_time);
2847 BT_DBG("Time diff = %d\n", time_diff);
2849 *timeout = visible_timer.timeout - time_diff;
2851 return BLUETOOTH_ERROR_NONE;
2854 int _bt_set_le_privacy(gboolean set_privacy)
2857 GError *error = NULL;
2858 GVariant *result = NULL;
2860 if (__bt_is_factory_test_mode()) {
2861 BT_ERR("Unable to set le privacy in factory binary !!");
2862 return BLUETOOTH_ERROR_NOT_SUPPORT;
2865 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2866 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2867 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2870 proxy = _bt_get_adapter_proxy();
2871 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2873 result = g_dbus_proxy_call_sync(proxy,
2875 g_variant_new("(b)", set_privacy),
2876 G_DBUS_CALL_FLAGS_NONE,
2882 if (error != NULL) {
2883 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2884 g_clear_error(&error);
2886 BT_ERR("Failed to SetLePrivacy");
2887 return BLUETOOTH_ERROR_INTERNAL;
2890 g_variant_unref(result);
2891 BT_INFO("SetLePrivacy as %d", set_privacy);
2892 return BLUETOOTH_ERROR_NONE;
2895 int _bt_set_le_static_random_address(gboolean is_enable)
2898 GError *error = NULL;
2899 GVariant *result = NULL;
2901 if (__bt_is_factory_test_mode()) {
2902 BT_ERR("Unable to set le random address in factory binary !!");
2903 return BLUETOOTH_ERROR_NOT_SUPPORT;
2906 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2907 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2908 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2911 proxy = _bt_get_adapter_proxy();
2912 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2914 result = g_dbus_proxy_call_sync(proxy,
2915 "SetLeStaticRandomAddress",
2916 g_variant_new("(b)", is_enable),
2917 G_DBUS_CALL_FLAGS_NONE,
2923 if (error != NULL) {
2924 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2925 g_clear_error(&error);
2927 BT_ERR("Failed to SetLeStaticRandomAddress");
2928 return BLUETOOTH_ERROR_INTERNAL;
2931 g_variant_unref(result);
2932 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2933 return BLUETOOTH_ERROR_NONE;
2936 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2939 GError *error = NULL;
2943 GVariantBuilder *builder;
2945 BT_CHECK_PARAMETER(m_data, return);
2947 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2948 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2949 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2952 proxy = _bt_get_adapter_proxy();
2953 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2955 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2957 for (i = 0; i < (m_data->data_len) + 2; i++)
2958 g_variant_builder_add(builder, "y", m_data->data[i]);
2960 val = g_variant_new("(ay)", builder);
2962 result = g_dbus_proxy_call_sync(proxy,
2963 "SetManufacturerData",
2965 G_DBUS_CALL_FLAGS_NONE,
2969 g_variant_builder_unref(builder);
2971 if (error != NULL) {
2972 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2973 g_clear_error(&error);
2975 BT_ERR("Failed to SetManufacturerData");
2977 return BLUETOOTH_ERROR_INTERNAL;
2979 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2981 for (i = 0; i < (m_data->data_len) + 2; i++)
2982 g_variant_builder_add(builder, "y", m_data->data[i]);
2984 val = g_variant_new("(ay)", builder);
2986 _bt_send_event(BT_ADAPTER_EVENT,
2987 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2990 BT_INFO("Set manufacturer data");
2992 g_variant_builder_unref(builder);
2993 g_variant_unref(result);
2995 return BLUETOOTH_ERROR_NONE;
2999 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
3001 int result = BLUETOOTH_ERROR_NONE;
3002 bt_service_alarm_t *alarm = NULL;
3004 if (!call_back || !alarm_id)
3005 return BLUETOOTH_ERROR_INVALID_PARAM;
3007 if (!alarm_mgr.is_alarm_initialized) {
3008 result = alarmmgr_init("bt-service");
3010 BT_ERR("Failed to initialize alarm = %d", result);
3011 result = BLUETOOTH_ERROR_INTERNAL;
3014 result = alarmmgr_set_cb(alarm_cb, NULL);
3016 BT_ERR("Failed to set the callback = %d", result);
3017 result = BLUETOOTH_ERROR_INTERNAL;
3020 alarm_mgr.is_alarm_initialized = TRUE;
3023 alarm = g_malloc0(sizeof(bt_service_alarm_t));
3025 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
3027 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
3030 BT_ERR("Failed to create alarm error = %d", result);
3031 result = BLUETOOTH_ERROR_INTERNAL;
3035 alarm->alarm_id = *alarm_id;
3036 alarm->callback = call_back;
3037 alarm->user_data = user_data;
3039 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
3040 result = BLUETOOTH_ERROR_NONE;
3045 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
3048 bt_service_alarm_t *p_data;
3049 bt_set_alarm_cb callback = NULL;
3050 void *user_data = NULL;
3052 node = g_list_find_custom(alarm_mgr.g_alarm_list,
3053 GINT_TO_POINTER(alarm_id), compare_alarm);
3057 p_data = (bt_service_alarm_t *)node->data;
3058 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
3064 callback = p_data->callback;
3065 user_data = p_data->user_data;
3069 callback(alarm_id, user_data);
3074 int _bt_service_remove_alarm(alarm_id_t alarm_id)
3077 bt_service_alarm_t *p_data;
3078 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
3081 alarmmgr_remove_alarm(alarm_id);
3082 p_data = (bt_service_alarm_t *)list->data;
3083 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
3090 gint compare_alarm(gconstpointer list_data, gconstpointer data)
3093 alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
3095 alarm_id_t alarm_id = (alarm_id_t)data;
3097 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
3099 if (p_data->alarm_id == alarm_id)
3105 static void alarm_data_free(void *data)
3107 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
3112 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3116 int function = (int)(uintptr_t)user_data;
3118 int function = (int)user_data;
3122 case BT_ENABLE_ADAPTER:
3123 result = _bt_enable_adapter();
3124 if (result != BLUETOOTH_ERROR_NONE) {
3125 BT_ERR("_bt_enable_adapter is failed");
3126 /* Send enabled event to API */
3127 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3128 g_variant_new("(i)", result));
3131 case BT_DISABLE_ADAPTER:
3132 result = _bt_disable_adapter();
3133 if (result != BLUETOOTH_ERROR_NONE) {
3134 BT_ERR("_bt_disable_adapter is failed");
3135 /* Send disabled event to API */
3136 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3137 g_variant_new("(i)", result));
3141 BT_ERR("function is NOT matched");
3148 int _bt_adapter_request_delayed(int function)
3153 case BT_ENABLE_ADAPTER:
3154 ret = _bt_enable_adapter_check_status();
3155 if (ret == BLUETOOTH_ERROR_NONE)
3156 _bt_adapter_set_status(BT_ACTIVATING);
3161 case BT_DISABLE_ADAPTER:
3162 ret = _bt_disable_adapter_check_status();
3163 if (ret == BLUETOOTH_ERROR_NONE)
3164 _bt_adapter_set_status(BT_DEACTIVATING);
3170 BT_ERR("function is NOT matched");
3171 return BLUETOOTH_ERROR_INTERNAL;
3175 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3177 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3180 return BLUETOOTH_ERROR_NONE;
3183 int _bt_get_enable_timer_id(void)