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");
197 /* Switch Off visibility in Bluez */
198 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
199 visible_timer.alarm_id = 0;
203 static void __bt_visibility_alarm_remove()
205 if (visible_timer.event_id > 0) {
206 g_source_remove(visible_timer.event_id);
207 visible_timer.event_id = 0;
210 if (visible_timer.alarm_id > 0) {
211 _bt_service_remove_alarm(visible_timer.alarm_id);
212 visible_timer.alarm_id = 0;
216 int __bt_set_visible_time(int timeout)
220 #ifdef TIZEN_FEATURE_BT_DPM
221 int discoverable_state = DPM_BT_ERROR;
224 __bt_visibility_alarm_remove();
226 visible_timer.timeout = timeout;
228 if (!TIZEN_PROFILE_WEARABLE) {
229 #ifdef TIZEN_FEATURE_BT_DPM
230 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
231 if (discoverable_state != DPM_RESTRICTED) {
233 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
234 BT_ERR("Set vconf failed");
235 #ifdef TIZEN_FEATURE_BT_DPM
242 return BLUETOOTH_ERROR_NONE;
244 result = _bt_service_set_alarm(visible_timer.timeout,
245 __bt_visibility_alarm_cb, NULL, &alarm_id);
246 if (result != BLUETOOTH_ERROR_NONE)
247 return BLUETOOTH_ERROR_INTERNAL;
248 visible_timer.alarm_id = alarm_id;
249 /* Take start time */
250 time(&(visible_timer.start_time));
251 visible_timer.event_id = g_timeout_add_seconds(1,
252 __bt_timeout_handler, NULL);
254 return BLUETOOTH_ERROR_NONE;
257 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
264 ret_if(value == NULL);
267 dev->service_index = 0;
269 g_variant_get(value, "as", &iter);
270 while (g_variant_iter_loop(iter, "s", &uuid)) {
271 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
272 parts = g_strsplit(uuid, "-", -1);
274 if (parts == NULL || parts[0] == NULL) {
279 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
282 dev->service_index++;
285 g_variant_iter_free(iter);
288 static int __bt_get_bonded_device_info(gchar *device_path,
289 bluetooth_device_info_t *dev_info)
291 GError *error = NULL;
292 GDBusProxy *device_proxy;
293 gchar *address = NULL;
296 unsigned int cod = 0;
298 gboolean trust = FALSE;
299 gboolean paired = FALSE;
300 guchar connected = 0;
301 GByteArray *manufacturer_data = NULL;
303 GDBusConnection *conn;
305 GVariantIter *property_iter;
309 GVariantIter *char_value_iter;
311 BT_CHECK_PARAMETER(device_path, return);
312 BT_CHECK_PARAMETER(dev_info, return);
314 conn = _bt_gdbus_get_system_gconn();
315 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
317 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
321 BT_PROPERTIES_INTERFACE,
324 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
326 result = g_dbus_proxy_call_sync(device_proxy,
328 g_variant_new("(s)", BT_DEVICE_INTERFACE),
329 G_DBUS_CALL_FLAGS_NONE,
335 BT_ERR("Error occured in Proxy call");
337 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
338 g_clear_error(&error);
340 g_object_unref(device_proxy);
341 return BLUETOOTH_ERROR_INTERNAL;
344 g_object_unref(device_proxy);
346 g_variant_get(result, "(a{sv})", &property_iter);
348 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
349 if (!g_strcmp0(key, "Paired")) {
350 paired = g_variant_get_boolean(value);
351 } else if (!g_strcmp0(key, "Address")) {
352 g_variant_get(value, "s", &address);
353 } else if (!g_strcmp0(key, "Alias")) {
354 g_variant_get(value, "s", &alias);
355 } else if (!g_strcmp0(key, "Name")) {
356 g_variant_get(value, "s", &name);
357 } else if (!g_strcmp0(key, "Class")) {
358 cod = g_variant_get_uint32(value);
359 } else if (!g_strcmp0(key, "Connected")) {
360 connected = g_variant_get_byte(value);
361 } else if (!g_strcmp0(key, "Trusted")) {
362 trust = g_variant_get_boolean(value);
363 } else if (!g_strcmp0(key, "RSSI")) {
364 rssi = g_variant_get_int16(value);
365 } else if (!g_strcmp0(key, "UUIDs")) {
366 __bt_get_service_list(value, dev_info);
367 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
368 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
369 } else if (!g_strcmp0(key, "ManufacturerData")) {
370 manufacturer_data = g_byte_array_new();
371 g_variant_get(value, "ay", &char_value_iter);
372 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
373 g_byte_array_append(manufacturer_data, &char_value, 1);
375 g_variant_iter_free(char_value_iter);
377 if (manufacturer_data) {
378 if (manufacturer_data->len > 0) {
379 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
380 manufacturer_data->len);
383 g_byte_array_free(manufacturer_data, TRUE);
386 g_variant_iter_free(property_iter);
388 BT_DBG("trust: %d, paired: %d", trust, paired);
390 g_variant_unref(result);
392 if ((paired == FALSE) && (trust == FALSE)) {
396 return BLUETOOTH_ERROR_NOT_PAIRED;
399 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
402 _bt_divide_device_class(&dev_info->device_class, cod);
404 g_strlcpy(dev_info->device_name.name, alias ? alias : name,
405 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
407 dev_info->rssi = rssi;
408 dev_info->trust = trust;
409 dev_info->paired = paired;
410 dev_info->connected = connected;
411 ret = BLUETOOTH_ERROR_NONE;
419 void _bt_set_discovery_status(gboolean mode)
421 is_discovering = mode;
422 discovery_req = FALSE;
425 void _bt_set_cancel_by_user(gboolean value)
427 cancel_by_user = value;
430 gboolean _bt_get_cancel_by_user(void)
432 return cancel_by_user;
435 void _bt_adapter_set_status(bt_status_t status)
437 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
438 adapter_status = status;
441 bt_status_t _bt_adapter_get_status(void)
443 return adapter_status;
446 void _bt_adapter_set_le_status(bt_le_status_t status)
448 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
449 adapter_le_status = status;
452 bt_le_status_t _bt_adapter_get_le_status(void)
454 return adapter_le_status;
458 void _bt_set_le_intended_status(gboolean value)
460 is_le_intended = value;
463 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
465 char *phone_name = NULL;
468 ret_if(node == NULL);
470 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
471 phone_name = vconf_keynode_get_str(node);
473 if (phone_name && strlen(phone_name) != 0) {
474 if (!g_utf8_validate(phone_name, -1,
475 (const char **)&ptr))
478 BT_INFO("device_name is changed to %s", phone_name);
479 _bt_set_local_name(phone_name);
481 BT_ERR("phone_name is NOT valid");
484 BT_ERR("vconf type is NOT string");
488 static void __bt_set_local_name(void)
490 bluetooth_device_name_t local_name;
491 char *phone_name = NULL;
495 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
496 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
497 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
502 if (strlen(phone_name) != 0) {
503 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
506 _bt_set_local_name(phone_name);
512 static int __bt_set_enabled(void)
514 int adapter_status = BT_ADAPTER_DISABLED;
515 int result = BLUETOOTH_ERROR_NONE;
518 BT_DBG("g_source is removed");
519 g_source_remove(timer_id);
523 _bt_check_adapter(&adapter_status);
525 if (adapter_status == BT_ADAPTER_DISABLED) {
526 BT_ERR("Bluetoothd is not running");
527 return BLUETOOTH_ERROR_INTERNAL;
530 if (TIZEN_PROFILE_MOBILE || TIZEN_PROFILE_IVI) {
531 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
532 if (_bt_set_discoverable_mode(
533 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
534 BT_ERR("Set connectable mode failed");
535 } else if (TIZEN_PROFILE_TV) {
536 if (_bt_set_discoverable_mode(
537 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
538 BT_ERR("Fail to set discoverable mode");
541 /* Update Bluetooth Status to notify other modules */
542 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
543 BT_ERR("Set vconf failed\n");
545 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
546 BT_ERR("Set vconf failed\n");
548 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
549 EVT_VAL_BT_ON) != ES_R_OK)
550 BT_ERR("Fail to set value");
552 /* Send enabled event to API */
553 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
554 g_variant_new("(i)", result));
556 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
557 _bt_audio_start_auto_connect(FALSE);
560 __bt_set_local_name();
561 _bt_set_discovery_status(FALSE);
563 return BLUETOOTH_ERROR_NONE;
566 void _bt_set_disabled(int result)
568 int power_off_status = 0;
571 int pm_ignore_mode = 0;
573 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
574 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
576 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
578 /* Update the vconf BT status in normal Deactivation case only */
579 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
580 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
582 BT_DBG("Update vconf for BT normal Deactivation");
584 if (result == BLUETOOTH_ERROR_TIMEOUT)
585 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
586 BT_ERR("Set vconf failed");
588 /* Update Bluetooth Status to notify other modules */
589 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
590 BT_ERR("Set vconf failed");
592 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
593 EVT_VAL_BT_OFF) != ES_R_OK)
594 BT_ERR("Fail to set value");
597 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
598 BT_ERR("Set vconf failed\n");
600 _bt_cancel_queued_transfers();
601 _bt_adapter_set_status(BT_DEACTIVATED);
602 _bt_set_discovery_status(FALSE);
604 BT_INFO("Adapter disabled");
607 static int __bt_set_le_enabled(void)
610 int result = BLUETOOTH_ERROR_NONE;
613 /* Update Bluetooth Status to notify other modules */
614 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
615 BT_ERR("Set vconf failed\n");
617 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
618 EVT_VAL_BT_LE_ON) != ES_R_OK)
619 BT_ERR("Fail to set value");
621 /* Send enabled event to API */
623 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
624 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
626 status = _bt_adapter_get_status();
627 if (status == BT_DEACTIVATED) {
628 BT_INFO("BREDR is off, turn off PSCAN");
629 _bt_set_connectable(FALSE);
631 if (le_timer_id > 0) {
632 g_source_remove(le_timer_id);
636 /* Send enabled event to API */
637 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
638 g_variant_new("(i)", result));
640 __bt_set_local_name();
643 return BLUETOOTH_ERROR_NONE;
646 void _bt_set_le_disabled(int result)
648 int power_off_status;
651 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
652 BT_DBG("ret : %d", ret);
653 BT_DBG("power_off_status : %d", power_off_status);
655 /* Update Bluetooth Status to notify other modules */
656 BT_DBG("Update vconf for BT LE normal Deactivation");
657 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
658 BT_ERR("Set vconf failed\n");
659 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
661 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
662 EVT_VAL_BT_LE_OFF) != ES_R_OK)
663 BT_ERR("Fail to set value");
665 /* Send disabled event */
666 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
667 g_variant_new("(i)", result));
670 void *_bt_get_adapter_agent(void)
672 return adapter_agent;
675 int _bt_enable_core(void)
679 GError *error = NULL;
681 proxy = __bt_get_core_proxy();
682 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
684 /* Clean up the process */
685 result = g_dbus_proxy_call_sync(proxy,
688 G_DBUS_CALL_FLAGS_NONE,
695 BT_ERR("Bt core call failed(Error: %s)", error->message);
696 g_clear_error(&error);
698 BT_ERR("Bt core call failed");
699 return BLUETOOTH_ERROR_INTERNAL;
702 g_variant_unref(result);
703 return BLUETOOTH_ERROR_NONE;
706 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
708 gboolean flight_mode = FALSE;
709 int power_saving_mode = 0;
712 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
713 type = vconf_keynode_get_type(node);
714 if (type == VCONF_TYPE_BOOL) {
715 flight_mode = vconf_keynode_get_bool(node);
716 if (flight_mode != TRUE) {
717 BT_ERR("Ignore the event");
720 } else if (type == VCONF_TYPE_INT) {
721 power_saving_mode = vconf_keynode_get_int(node);
722 if (power_saving_mode != 2) {
723 BT_ERR("Ignore the event");
727 BT_ERR("Invaild vconf key type : %d", type);
734 void _bt_service_register_vconf_handler(void)
738 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
739 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
740 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
741 BT_ERR("Unable to register key handler");
743 BT_DBG("Telephony is disabled");
746 if (!TIZEN_PROFILE_WEARABLE) {
747 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
748 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
749 BT_ERR("Unable to register key handler");
753 void _bt_service_unregister_vconf_handler(void)
757 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
758 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
759 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
762 if (!TIZEN_PROFILE_WEARABLE) {
763 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
764 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
768 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
770 const char *bt_status = NULL;
771 const char *bt_le_status = NULL;
772 BT_DBG("bt state set event(%s) received", event_name);
774 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
775 BT_DBG("bt_state: (%s)", bt_status);
777 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
778 BT_DBG("bt_state: (%s)", bt_le_status);
781 static gboolean __bt_adapter_recovery_cb(gpointer data)
789 _bt_service_initialize();
791 ret = _bt_enable_adapter_check_status();
792 if (ret == BLUETOOTH_ERROR_NONE) {
793 ret = _bt_enable_adapter();
795 BT_ERR("_bt_enable_adapter() failed");
797 ret = _bt_enable_adapter_le();
799 BT_ERR("_bt_enable_adapter_le() failed");
809 void _bt_handle_adapter_added(void)
813 bt_le_status_t le_status;
817 BT_DBG("g_source is removed");
818 g_source_remove(timer_id);
825 status = _bt_adapter_get_status();
826 le_status = _bt_adapter_get_le_status();
827 BT_INFO("status : %d", status);
828 BT_INFO("le_status : %d", le_status);
829 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
830 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
831 if (!adapter_agent) {
832 BT_ERR("Fail to register agent");
836 if (adapter_agent == NULL) {
837 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
838 if (!adapter_agent) {
839 BT_ERR("Fail to register agent");
845 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
846 BT_ERR("Fail to register media player");
848 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
849 BT_ERR("Fail to init obex server");
851 #ifdef TIZEN_BT_PAN_NAP_ENABLED
852 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
853 BT_ERR("Fail to activate network");
856 /* add the vconf noti handler */
857 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
858 __bt_phone_name_changed_cb, NULL);
860 BT_ERR("Unable to register key handler");
862 if (le_status == BT_LE_ACTIVATING ||
863 status == BT_ACTIVATING) {
864 __bt_set_le_enabled();
865 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
868 if (status == BT_ACTIVATING) {
870 _bt_adapter_set_status(BT_ACTIVATED);
874 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
875 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
876 BT_ERR("Fail to register system event");
880 void _bt_handle_adapter_removed(void)
884 _bt_adapter_set_status(BT_DEACTIVATED);
886 __bt_visibility_alarm_remove();
888 if (alarm_mgr.is_alarm_initialized == TRUE) {
890 alarm_mgr.is_alarm_initialized = FALSE;
891 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
892 alarm_mgr.g_alarm_list = NULL;
895 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
896 _bt_audio_stop_auto_connect();
899 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
900 (vconf_callback_fn)__bt_phone_name_changed_cb);
902 ERR("vconf_ignore_key_changed failed\n");
904 /* unregister all the services/servers/profiles registered on bluez-adapter
905 once adapter is removed, reinitializing of the state-varaibles becomes
907 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
908 BT_ERR("Fail to unregister obex server");
910 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
911 BT_ERR("Fail to unregister media player");
913 /* Other unregister APIs should be placed here */
915 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
916 _bt_destroy_agent(adapter_agent);
917 adapter_agent = NULL;
919 if (recovery_cnt > 0) {
920 /* Send disabled event */
921 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
922 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
923 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
925 if (recovery_timer > 0)
926 g_source_remove(recovery_timer);
928 if (TIZEN_PROFILE_WEARABLE) {
929 recovery_timer = g_timeout_add(BT_RECOVERY_TIME_W,
930 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
932 recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
933 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
936 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
937 BT_ERR("Fail to unregister system event");
941 if (recovery_timer == 0)
942 _bt_reliable_terminate_service(NULL);
944 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
945 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
946 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
949 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
950 BT_ERR("Fail to unregister system event");
953 static gboolean __bt_enable_timeout_cb(gpointer user_data)
957 GError *error = NULL;
961 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
963 BT_ERR("EnableAdapter is failed");
965 proxy = __bt_get_core_proxy();
969 /* Clean up the process */
970 result = g_dbus_proxy_call_sync(proxy,
973 G_DBUS_CALL_FLAGS_NONE,
980 BT_ERR("Bt core call failed(Error: %s)", error->message);
981 g_clear_error(&error);
983 BT_ERR("Bt core call failed");
988 g_variant_unref(result);
989 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
991 if (recovery_cnt > 0) {
992 BT_ERR("Try recovery again(remain:%d)", recovery_cnt);
993 if (recovery_timer > 0)
994 g_source_remove(recovery_timer);
996 if (TIZEN_PROFILE_WEARABLE) {
997 recovery_timer = g_timeout_add(BT_RECOVERY_TIME_W,
998 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
1000 recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
1001 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
1007 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1008 _bt_terminate_service(NULL);
1013 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
1017 GError *error = NULL;
1021 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
1023 BT_ERR("EnableAdapterLE is failed");
1025 proxy = __bt_get_core_proxy();
1029 /* Clean up the process */
1030 result = g_dbus_proxy_call_sync(proxy,
1033 G_DBUS_CALL_FLAGS_NONE,
1039 if (error != NULL) {
1040 BT_ERR("Bt core call failed(Error: %s)", error->message);
1041 g_clear_error(&error);
1043 BT_ERR("Bt core call failed");
1047 g_variant_unref(result);
1049 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED)
1050 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
1052 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1053 _bt_terminate_service(NULL);
1058 void _bt_adapter_start_le_enable_timer(void)
1060 if (le_timer_id > 0) {
1061 g_source_remove(le_timer_id);
1065 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1066 __bt_enable_le_timeout_cb, NULL);
1071 void _bt_adapter_start_enable_timer(void)
1074 g_source_remove(timer_id);
1078 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1079 __bt_enable_timeout_cb, NULL);
1084 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1089 _bt_adapter_set_status(BT_ACTIVATED);
1094 int _bt_enable_adapter_check_status(void)
1096 bt_status_t status = _bt_adapter_get_status();
1097 bt_le_status_t le_status = _bt_adapter_get_le_status();
1101 if (status == BT_ACTIVATING) {
1102 BT_ERR("Enabling in progress");
1103 return BLUETOOTH_ERROR_IN_PROGRESS;
1106 if (status == BT_ACTIVATED) {
1107 BT_ERR("Already enabled");
1108 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1111 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1112 BT_ERR("Disabling in progress");
1113 return BLUETOOTH_ERROR_DEVICE_BUSY;
1116 return BLUETOOTH_ERROR_NONE;
1119 int _bt_enable_adapter(void)
1122 GError *error = NULL;
1124 GVariant *result = NULL;
1125 bt_status_t status = _bt_adapter_get_status();
1126 bt_le_status_t le_status = _bt_adapter_get_le_status();
1130 if (status == BT_ACTIVATING) {
1131 BT_ERR("Enabling in progress");
1132 return BLUETOOTH_ERROR_IN_PROGRESS;
1135 if (status == BT_ACTIVATED) {
1136 BT_ERR("Already enabled");
1137 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1140 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1141 BT_ERR("Disabling in progress");
1142 return BLUETOOTH_ERROR_DEVICE_BUSY;
1145 _bt_adapter_set_status(BT_ACTIVATING);
1147 if (TIZEN_PROFILE_TV) {
1148 int adapter_status = BT_ADAPTER_DISABLED;
1150 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1151 BT_ERR("Set vconf failed");
1153 _bt_check_adapter(&adapter_status);
1154 if (adapter_status == BT_ADAPTER_ENABLED) {
1155 g_idle_add(__bt_adapter_enabled_cb, NULL);
1156 _bt_adapter_start_enable_timer();
1157 return BLUETOOTH_ERROR_NONE;
1161 proxy = __bt_get_core_proxy();
1163 return BLUETOOTH_ERROR_INTERNAL;
1165 if (le_status == BT_LE_ACTIVATED) {
1166 BT_INFO("LE Already enabled. Just turn on PSCAN");
1167 ret = _bt_set_connectable(TRUE);
1168 if (ret == BLUETOOTH_ERROR_NONE)
1169 _bt_adapter_set_status(BT_ACTIVATED);
1171 return BLUETOOTH_ERROR_INTERNAL;
1174 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1176 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1179 BT_ERR("EnableAdapterLe failed: %s", error->message);
1180 _bt_adapter_set_status(BT_DEACTIVATED);
1181 g_clear_error(&error);
1183 result = g_dbus_proxy_call_sync(proxy,
1186 G_DBUS_CALL_FLAGS_NONE,
1191 if (error != NULL) {
1192 BT_ERR("Bt core call failed(Error: %s)", error->message);
1193 g_clear_error(&error);
1195 g_variant_unref(result);
1196 /* Terminate myself */
1197 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1198 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1199 return BLUETOOTH_ERROR_INTERNAL;
1201 g_variant_unref(result);
1202 if (le_status == BT_LE_ACTIVATED)
1205 _bt_adapter_start_enable_timer();
1207 return BLUETOOTH_ERROR_NONE;
1210 static gboolean __bt_set_powered(gboolean powered)
1213 GError *error = NULL;
1218 proxy = _bt_get_adapter_properties_proxy();
1219 retv_if(proxy == NULL, FALSE);
1221 result = g_dbus_proxy_call_sync(proxy, "Set",
1222 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Powered",
1223 g_variant_new("b", powered)),
1224 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1226 if (error != NULL) {
1227 BT_ERR("Failed to set powered property (Error: %s)",
1229 g_clear_error(&error);
1231 BT_ERR("Failed to set powered property");
1236 BT_INFO("Set powered [%d]", powered);
1237 g_variant_unref(result);
1241 static gboolean __bt_disconnect_all(void)
1244 GDBusConnection *conn;
1245 GDBusProxy *dev_proxy;
1246 gboolean ret = FALSE;
1248 GError *error = NULL;
1249 GArray *device_list;
1250 bluetooth_device_info_t info;
1252 char *device_path = NULL;
1253 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1258 conn = _bt_gdbus_get_system_gconn();
1260 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1262 if (_bt_get_bonded_devices(&device_list)
1263 != BLUETOOTH_ERROR_NONE) {
1264 g_array_free(device_list, TRUE);
1268 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1270 for (i = 0; i < size; i++) {
1272 info = g_array_index(device_list,
1273 bluetooth_device_info_t, i);
1275 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1276 BT_DBG("Found Connected device");
1277 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1278 device_path = _bt_get_device_object_path(address);
1279 if (device_path == NULL)
1282 BT_DBG("Disconnecting : %s", device_path);
1284 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1288 BT_DEVICE_INTERFACE,
1291 if (dev_proxy == NULL)
1294 result = g_dbus_proxy_call_sync(dev_proxy,
1297 G_DBUS_CALL_FLAGS_NONE,
1303 if (error != NULL) {
1304 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1305 g_clear_error(&error);
1307 BT_ERR("Disconnect call failed");
1308 g_object_unref(dev_proxy);
1312 g_variant_unref(result);
1313 g_object_unref(dev_proxy);
1317 g_array_free(device_list, TRUE);
1323 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1326 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1327 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
1328 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
1334 int _bt_disable_cb(void)
1342 GError *error = NULL;
1344 _bt_adapter_set_status(BT_DEACTIVATING);
1346 bt_le_status_t le_status;
1347 le_status = _bt_adapter_get_le_status();
1348 BT_DBG("le_status : %d", le_status);
1349 if (le_status == BT_LE_ACTIVATED) {
1350 BT_INFO("LE is enabled. Just turn off PSCAN");
1352 if (_bt_is_discovering())
1353 _bt_cancel_discovery();
1355 if (_bt_is_connectable() == FALSE) {
1356 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1358 ret = _bt_set_connectable(FALSE);
1359 if (ret != BLUETOOTH_ERROR_NONE) {
1360 BT_ERR("_bt_set_connectable fail!");
1361 _bt_adapter_set_status(BT_ACTIVATED);
1362 return BLUETOOTH_ERROR_INTERNAL;
1367 proxy = __bt_get_core_proxy();
1368 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1370 result = g_dbus_proxy_call_sync(proxy,
1373 G_DBUS_CALL_FLAGS_NONE,
1379 if (error != NULL) {
1380 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1381 g_clear_error(&error);
1383 BT_ERR("Failed to DisableAdapter");
1384 _bt_adapter_set_status(BT_ACTIVATED);
1385 return BLUETOOTH_ERROR_INTERNAL;
1388 g_variant_unref(result);
1389 return BLUETOOTH_ERROR_NONE;
1392 int _bt_disable_adapter_check_status(void)
1394 bt_status_t status = _bt_adapter_get_status();
1398 if (status == BT_DEACTIVATING) {
1399 BT_DBG("Disabling in progress");
1400 return BLUETOOTH_ERROR_IN_PROGRESS;
1403 if (status == BT_DEACTIVATED) {
1404 BT_DBG("Already disabled");
1405 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1408 return BLUETOOTH_ERROR_NONE;
1411 int _bt_disable_adapter(void)
1415 bt_le_status_t le_status;
1417 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1418 BT_DBG("Disabling in progress");
1419 return BLUETOOTH_ERROR_IN_PROGRESS;
1422 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1423 BT_DBG("Already disabled");
1424 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1428 g_source_remove(timer_id);
1432 /* unregister all the services/servers/profiles registered on bluez-adapter
1433 once adapter is removed, reinitializing of the state-varaibles becomes
1435 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1436 BT_ERR("Fail to unregister obex server");
1438 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
1439 BT_ERR("Fail to unregister media player");
1440 /* Other unregister APIs should be placed here */
1442 le_status = _bt_adapter_get_le_status();
1443 if (le_status == BT_LE_ACTIVATED && is_le_intended == TRUE) {
1444 __bt_disconnect_all();
1446 if (le_status == BT_LE_ACTIVATED)
1447 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1449 __bt_set_powered(FALSE);
1452 ret = _bt_disable_cb();
1458 int _bt_recover_adapter(void)
1462 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1463 BT_ERR("Disabling in progress");
1464 return BLUETOOTH_ERROR_IN_PROGRESS;
1467 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1468 BT_ERR("Already disabled");
1469 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1472 recovery_cnt = BT_RECOVERY_MAX_COUNT;
1474 _bt_disable_adapter();
1475 _bt_disable_adapter_le();
1478 return BLUETOOTH_ERROR_NONE;
1481 int _bt_reset_adapter(void)
1485 GError *error = NULL;
1489 proxy = __bt_get_core_proxy();
1491 return BLUETOOTH_ERROR_INTERNAL;
1493 result = g_dbus_proxy_call_sync(proxy,
1496 G_DBUS_CALL_FLAGS_NONE,
1502 if (error != NULL) {
1503 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1504 g_clear_error(&error);
1506 BT_ERR("Failed to ResetAdapter");
1507 return BLUETOOTH_ERROR_INTERNAL;
1510 g_variant_unref(result);
1511 /* Terminate myself */
1512 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1513 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1515 return BLUETOOTH_ERROR_NONE;
1518 int _bt_check_adapter(int *status)
1520 if (!TIZEN_PROFILE_TV) {
1521 char *adapter_path = NULL;
1523 BT_CHECK_PARAMETER(status, return);
1525 *status = BT_ADAPTER_DISABLED;
1527 adapter_path = _bt_get_adapter_path();
1530 if (adapter_path != NULL)
1531 *status = BT_ADAPTER_ENABLED;
1533 g_free(adapter_path);
1534 return BLUETOOTH_ERROR_NONE;
1537 GError *error = NULL;
1540 gboolean powered = FALSE;
1542 BT_CHECK_PARAMETER(status, return);
1544 *status = BT_ADAPTER_DISABLED;
1546 proxy = _bt_get_adapter_properties_proxy();
1547 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1549 result = g_dbus_proxy_call_sync(proxy,
1551 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1553 G_DBUS_CALL_FLAGS_NONE,
1559 BT_ERR("Failed to get local address");
1560 if (error != NULL) {
1561 BT_ERR("Failed to get local address (Error: %s)", error->message);
1562 g_clear_error(&error);
1564 return BLUETOOTH_ERROR_INTERNAL;
1567 g_variant_get(result, "(v)", &temp);
1568 powered = g_variant_get_boolean(temp);
1569 BT_DBG("powered: %d", powered);
1572 *status = BT_ADAPTER_ENABLED;
1574 g_variant_unref(result);
1575 g_variant_unref(temp);
1576 return BLUETOOTH_ERROR_NONE;
1580 int _bt_enable_adapter_le(void)
1584 GError *error = NULL;
1585 bt_status_t status = _bt_adapter_get_status();
1586 bt_le_status_t le_status = _bt_adapter_get_le_status();
1589 if (le_status == BT_LE_ACTIVATING) {
1590 BT_ERR("Enabling in progress");
1591 return BLUETOOTH_ERROR_IN_PROGRESS;
1594 if (le_status == BT_LE_ACTIVATED) {
1595 BT_ERR("Already enabled");
1596 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1599 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1600 BT_ERR("Disabling in progress");
1601 _bt_set_le_intended_status(FALSE);
1602 return BLUETOOTH_ERROR_DEVICE_BUSY;
1605 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1607 proxy = __bt_get_core_proxy();
1608 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1610 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1612 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1615 BT_ERR("EnableAdapterLe failed: %s", error->message);
1616 _bt_adapter_set_le_status(BT_DEACTIVATED);
1617 g_clear_error(&error);
1619 /* Clean up the process */
1620 result = g_dbus_proxy_call_sync(proxy,
1623 G_DBUS_CALL_FLAGS_NONE,
1629 BT_ERR("Bt core call failed");
1631 BT_ERR("EnableAdapterLE Failed %s", error->message);
1632 g_clear_error(&error);
1635 g_variant_unref(result);
1636 /* Terminate myself */
1637 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1638 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1639 return BLUETOOTH_ERROR_INTERNAL;
1643 g_variant_unref(result);
1645 _bt_adapter_start_le_enable_timer();
1647 if (status == BT_ACTIVATED) {
1648 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1649 __bt_set_le_enabled();
1651 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1653 return BLUETOOTH_ERROR_NONE;
1656 int _bt_disable_adapter_le(void)
1660 bt_le_status_t bt_le_state;
1662 GError *error = NULL;
1664 bt_le_state = _bt_adapter_get_le_status();
1665 if (bt_le_state == BT_LE_DEACTIVATING) {
1666 BT_DBG("Disabling in progress");
1667 return BLUETOOTH_ERROR_IN_PROGRESS;
1670 if (bt_le_state == BT_LE_DEACTIVATED) {
1671 BT_DBG("Already disabled");
1672 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1675 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1677 proxy = __bt_get_core_proxy();
1679 return BLUETOOTH_ERROR_INTERNAL;
1681 result = g_dbus_proxy_call_sync(proxy,
1684 G_DBUS_CALL_FLAGS_NONE,
1690 if (error != NULL) {
1691 BT_ERR("Bt core call failed (Error: %s)", error->message);
1692 g_clear_error(&error);
1694 BT_ERR("Bt core call failed");
1695 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1696 return BLUETOOTH_ERROR_INTERNAL;
1699 g_variant_unref(result);
1700 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1701 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1703 return BLUETOOTH_ERROR_NONE;
1706 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1710 GError *error = NULL;
1711 const char *address;
1715 BT_CHECK_PARAMETER(local_address, return);
1717 proxy = _bt_get_adapter_properties_proxy();
1718 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1720 result = g_dbus_proxy_call_sync(proxy,
1722 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1724 G_DBUS_CALL_FLAGS_NONE,
1730 BT_ERR("Failed to get local address");
1731 if (error != NULL) {
1732 BT_ERR("Failed to get local address (Error: %s)", error->message);
1733 g_clear_error(&error);
1735 return BLUETOOTH_ERROR_INTERNAL;
1738 g_variant_get(result, "(v)", &temp);
1739 address = g_variant_get_string(temp, NULL);
1740 BT_DBG("Address:%s", address);
1743 _bt_convert_addr_string_to_type(local_address->addr, address);
1745 return BLUETOOTH_ERROR_INTERNAL;
1747 g_variant_unref(result);
1748 g_variant_unref(temp);
1749 return BLUETOOTH_ERROR_NONE;
1752 int _bt_get_local_version(bluetooth_version_t *local_version)
1755 const char *ver = NULL;
1757 int ret = BLUETOOTH_ERROR_NONE;
1761 BT_CHECK_PARAMETER(local_version, return);
1763 GError *error = NULL;
1765 proxy = _bt_get_adapter_properties_proxy();
1766 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1768 result = g_dbus_proxy_call_sync(proxy,
1770 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1772 G_DBUS_CALL_FLAGS_NONE,
1778 if (error != NULL) {
1779 BT_ERR("Failed to get local version (Error: %s)", error->message);
1780 g_clear_error(&error);
1782 BT_ERR("Failed to get local version");
1783 return BLUETOOTH_ERROR_INTERNAL;
1786 g_variant_get(result, "(v)", &temp);
1787 ver = g_variant_get_string(temp, NULL);
1788 BT_DBG("VERSION: %s", ver);
1790 if (ver && (strlen(ver) > 0)) {
1791 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1792 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1795 g_strlcpy(local_version->version, ver,
1796 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1799 ret = BLUETOOTH_ERROR_INTERNAL;
1802 g_variant_unref(result);
1803 g_variant_unref(temp);
1807 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1810 const char *name = NULL;
1812 int ret = BLUETOOTH_ERROR_NONE;
1815 GError *error = NULL;
1817 BT_CHECK_PARAMETER(local_name, return);
1819 proxy = _bt_get_adapter_properties_proxy();
1820 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1822 result = g_dbus_proxy_call_sync(proxy,
1824 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1826 G_DBUS_CALL_FLAGS_NONE,
1832 if (error != NULL) {
1833 BT_ERR("Failed to get local name (Error: %s)", error->message);
1834 g_clear_error(&error);
1836 BT_ERR("Failed to get local name");
1837 return BLUETOOTH_ERROR_INTERNAL;
1840 g_variant_get(result, "(v)", &temp);
1841 name = g_variant_get_string(temp, NULL);
1842 BT_DBG("LOCAL NAME:%s", name);
1844 if (name && (strlen(name) > 0)) {
1845 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1846 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1849 g_strlcpy(local_name->name, name,
1850 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1852 ret = BLUETOOTH_ERROR_INTERNAL;
1854 g_variant_unref(result);
1855 g_variant_unref(temp);
1859 int _bt_set_local_name(char *local_name)
1862 GError *error = NULL;
1866 BT_CHECK_PARAMETER(local_name, return);
1868 proxy = _bt_get_adapter_properties_proxy();
1870 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1872 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1875 result = g_dbus_proxy_call_sync(proxy,
1877 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1878 "Alias", g_variant_new("s", local_name)),
1879 G_DBUS_CALL_FLAGS_NONE,
1885 if (error != NULL) {
1886 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1887 g_clear_error(&error);
1889 BT_ERR("Failed to set Alias");
1890 return BLUETOOTH_ERROR_INTERNAL;
1893 g_variant_unref(result);
1894 return BLUETOOTH_ERROR_NONE;
1897 int _bt_is_service_used(char *service_uuid, gboolean *used)
1900 GError *error = NULL;
1901 int ret = BLUETOOTH_ERROR_NONE;
1903 GVariant *temp = NULL;
1904 GVariantIter *iter = NULL;
1908 BT_CHECK_PARAMETER(service_uuid, return);
1909 BT_CHECK_PARAMETER(used, return);
1911 proxy = _bt_get_adapter_properties_proxy();
1912 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1914 result = g_dbus_proxy_call_sync(proxy,
1916 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1918 G_DBUS_CALL_FLAGS_NONE,
1924 if (error != NULL) {
1925 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1926 g_clear_error(&error);
1928 BT_ERR("Failed to get UUIDs");
1929 return BLUETOOTH_ERROR_INTERNAL;
1932 g_variant_get(result, "(v)", &temp);
1933 g_variant_get(temp, "as", &iter);
1936 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1937 if (strcasecmp(uuid, service_uuid) == 0) {
1942 g_variant_iter_free(iter);
1943 g_variant_unref(result);
1945 BT_DBG("Service Used? %d", *used);
1950 static gboolean __bt_get_discoverable_property(void)
1953 gboolean discoverable_v;
1954 GError *error = NULL;
1958 proxy = _bt_get_adapter_properties_proxy();
1959 retv_if(proxy == NULL, FALSE);
1961 result = g_dbus_proxy_call_sync(proxy,
1963 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1965 G_DBUS_CALL_FLAGS_NONE,
1971 if (error != NULL) {
1972 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1973 g_clear_error(&error);
1975 BT_ERR("Failed to get Discoverable property");
1976 return BLUETOOTH_ERROR_INTERNAL;
1979 g_variant_get(result, "(v)", &temp);
1980 discoverable_v = g_variant_get_boolean(temp);
1981 BT_DBG("discoverable_v:%d", discoverable_v);
1983 g_variant_unref(result);
1984 g_variant_unref(temp);
1986 return discoverable_v;
1989 int _bt_get_discoverable_mode(int *mode)
1991 gboolean discoverable;
1992 unsigned int timeout;
1994 BT_CHECK_PARAMETER(mode, return);
1996 discoverable = __bt_get_discoverable_property();
1997 timeout = _bt_get_discoverable_timeout_property();
1999 if (discoverable == TRUE) {
2001 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
2003 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
2005 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
2007 return BLUETOOTH_ERROR_NONE;
2011 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
2013 int ret = BLUETOOTH_ERROR_NONE;
2016 GError *error = NULL;
2019 #ifdef TIZEN_FEATURE_BT_DPM
2020 int discoverable_state = DPM_BT_ERROR;
2023 proxy = _bt_get_adapter_properties_proxy();
2025 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2027 #ifdef TIZEN_FEATURE_BT_DPM
2028 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
2029 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
2030 discoverable_state == DPM_RESTRICTED) {
2031 if (headed_plugin_info->plugin_headed_enabled)
2032 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
2034 return BLUETOOTH_ERROR_ACCESS_DENIED;
2036 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
2037 discoverable_state == DPM_RESTRICTED) {
2038 if (headed_plugin_info->plugin_headed_enabled)
2039 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
2041 return BLUETOOTH_ERROR_ACCESS_DENIED;
2045 switch (discoverable_mode) {
2046 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
2051 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
2056 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
2061 return BLUETOOTH_ERROR_INVALID_PARAM;
2064 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
2065 discoverable_mode, timeout);
2067 result = g_dbus_proxy_call_sync(proxy,
2069 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2070 "Connectable", g_variant_new("b", pg_scan)),
2071 G_DBUS_CALL_FLAGS_NONE,
2077 if (error != NULL) {
2078 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2079 g_clear_error(&error);
2081 BT_ERR("Failed to set connectable property");
2082 return BLUETOOTH_ERROR_INTERNAL;
2084 g_variant_unref(result);
2085 result = g_dbus_proxy_call_sync(proxy,
2087 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2088 g_variant_new("b", inq_scan)),
2089 G_DBUS_CALL_FLAGS_NONE,
2095 if (error != NULL) {
2096 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2097 g_clear_error(&error);
2099 BT_ERR("Failed to set Discoverable property");
2100 return BLUETOOTH_ERROR_INTERNAL;
2102 g_variant_unref(result);
2103 result = g_dbus_proxy_call_sync(proxy,
2105 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2106 "DiscoverableTimeout", g_variant_new("u", timeout)),
2107 G_DBUS_CALL_FLAGS_NONE,
2113 if (error != NULL) {
2114 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2115 g_clear_error(&error);
2117 BT_ERR("Failed to set DiscoverableTimeout property");
2118 return BLUETOOTH_ERROR_INTERNAL;
2121 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2124 ret = __bt_set_visible_time(timeout);
2126 g_variant_unref(result);
2131 int _bt_start_discovery(void)
2134 GError *error = NULL;
2137 if (_bt_is_discovering() == TRUE) {
2138 BT_ERR("BT is already in discovering");
2139 return BLUETOOTH_ERROR_IN_PROGRESS;
2140 } else if (_bt_is_device_creating() == TRUE) {
2141 BT_ERR("Bonding device is going on");
2142 return BLUETOOTH_ERROR_DEVICE_BUSY;
2145 proxy = _bt_get_adapter_proxy();
2146 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2148 result = g_dbus_proxy_call_sync(proxy,
2151 G_DBUS_CALL_FLAGS_NONE,
2157 if (error != NULL) {
2158 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2159 g_clear_error(&error);
2161 BT_ERR("StartDiscovery failed");
2162 return BLUETOOTH_ERROR_INTERNAL;
2165 discovery_req = TRUE;
2166 cancel_by_user = FALSE;
2167 /* discovery status will be change in event */
2168 g_variant_unref(result);
2169 return BLUETOOTH_ERROR_NONE;
2172 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2176 GError *error = NULL;
2177 const gchar *disc_type;
2179 if (_bt_is_discovering() == TRUE) {
2180 BT_ERR("BT is already in discovering");
2181 return BLUETOOTH_ERROR_IN_PROGRESS;
2184 proxy = _bt_get_adapter_proxy();
2185 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2187 if (role == DISCOVERY_ROLE_BREDR)
2188 disc_type = "BREDR";
2189 else if (role == DISCOVERY_ROLE_LE)
2191 else if (role == DISCOVERY_ROLE_LE_BREDR)
2192 disc_type = "LE_BREDR";
2194 return BLUETOOTH_ERROR_INVALID_PARAM;
2196 result = g_dbus_proxy_call_sync(proxy,
2197 "StartCustomDiscovery",
2198 g_variant_new("s", disc_type),
2199 G_DBUS_CALL_FLAGS_NONE,
2205 if (error != NULL) {
2206 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2207 g_clear_error(&error);
2209 BT_ERR("StartCustomDiscovery failed");
2210 return BLUETOOTH_ERROR_INTERNAL;
2213 discovery_req = TRUE;
2214 cancel_by_user = FALSE;
2215 /* discovery status will be change in event */
2216 g_variant_unref(result);
2217 return BLUETOOTH_ERROR_NONE;
2220 int _bt_cancel_discovery(void)
2223 GError *error = NULL;
2226 if (_bt_is_discovering() == FALSE) {
2227 BT_ERR("BT is not in discovering");
2228 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2231 proxy = _bt_get_adapter_proxy();
2232 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2234 result = g_dbus_proxy_call_sync(proxy,
2237 G_DBUS_CALL_FLAGS_NONE,
2243 int ret = BLUETOOTH_ERROR_INTERNAL;
2244 if (error != NULL) {
2245 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2247 if (g_strrstr(error->message, "No discovery started"))
2248 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2250 g_clear_error(&error);
2252 BT_ERR("StopDiscovery failed");
2258 discovery_req = FALSE;
2259 cancel_by_user = TRUE;
2260 /* discovery status will be change in event */
2261 g_variant_unref(result);
2262 return BLUETOOTH_ERROR_NONE;
2265 gboolean _bt_is_discovering(void)
2267 return (is_discovering || discovery_req);
2270 gboolean _bt_is_connectable(void)
2273 GError *error = NULL;
2274 gboolean is_connectable = FALSE;
2278 proxy = _bt_get_adapter_properties_proxy();
2279 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2281 result = g_dbus_proxy_call_sync(proxy,
2283 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2285 G_DBUS_CALL_FLAGS_NONE,
2291 if (error != NULL) {
2292 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2293 g_clear_error(&error);
2295 BT_ERR("Failed to get connectable property");
2296 return BLUETOOTH_ERROR_INTERNAL;
2299 g_variant_get(result, "(v)", &temp);
2300 is_connectable = g_variant_get_boolean(temp);
2301 BT_DBG("discoverable_v:%d", is_connectable);
2303 g_variant_unref(result);
2304 g_variant_unref(temp);
2306 BT_INFO("Get connectable [%d]", is_connectable);
2307 return is_connectable;
2310 int _bt_set_connectable(gboolean is_connectable)
2313 GError *error = NULL;
2316 if (__bt_is_factory_test_mode()) {
2317 BT_ERR("Unable to set connectable in factory binary !!");
2318 return BLUETOOTH_ERROR_NOT_SUPPORT;
2321 proxy = _bt_get_adapter_properties_proxy();
2323 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2325 result = g_dbus_proxy_call_sync(proxy,
2327 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2328 g_variant_new("b", is_connectable)),
2329 G_DBUS_CALL_FLAGS_NONE,
2335 if (error != NULL) {
2336 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2337 g_clear_error(&error);
2339 BT_ERR("Failed to set connectable property");
2340 return BLUETOOTH_ERROR_INTERNAL;
2343 BT_INFO_C("### Set connectable [%d]", is_connectable);
2344 g_variant_unref(result);
2345 return BLUETOOTH_ERROR_NONE;
2348 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2351 gboolean discovering_v;
2352 GError *error = NULL;
2353 char *discovering_type = NULL;
2357 proxy = _bt_get_adapter_properties_proxy();
2358 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2360 if (discovery_type == DISCOVERY_ROLE_BREDR)
2361 discovering_type = "Discovering";
2362 else if (discovery_type == DISCOVERY_ROLE_LE)
2363 discovering_type = "LEDiscovering";
2365 result = g_dbus_proxy_call_sync(proxy,
2367 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2369 G_DBUS_CALL_FLAGS_NONE,
2375 if (error != NULL) {
2376 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2377 g_clear_error(&error);
2379 BT_ERR("Failed to get discovering property");
2380 return BLUETOOTH_ERROR_INTERNAL;
2383 g_variant_get(result, "(v)", &temp);
2384 discovering_v = g_variant_get_boolean(temp);
2385 BT_DBG("discoverable_v:%d", discovering_v);
2387 g_variant_unref(result);
2388 g_variant_unref(temp);
2390 return discovering_v;
2393 unsigned int _bt_get_discoverable_timeout_property(void)
2396 unsigned int timeout_v;
2397 GError *error = NULL;
2401 proxy = _bt_get_adapter_properties_proxy();
2402 retv_if(proxy == NULL, 0);
2404 result = g_dbus_proxy_call_sync(proxy,
2406 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2407 "DiscoverableTimeout"),
2408 G_DBUS_CALL_FLAGS_NONE,
2414 BT_ERR("Fail to get discoverable timeout");
2415 if (error != NULL) {
2416 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2417 g_clear_error(&error);
2422 g_variant_get(result, "(v)", &temp);
2423 timeout_v = g_variant_get_uint32(temp);
2424 BT_DBG("discoverable_v:%d", timeout_v);
2426 g_variant_unref(result);
2427 g_variant_unref(temp);
2432 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2434 bluetooth_device_info_t *dev_info;
2437 GByteArray *manufacturer_data = NULL;
2439 GVariantIter *char_value_iter;
2441 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2443 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2448 if (!g_strcmp0(key, "Address")) {
2449 const char *address = NULL;
2450 address = g_variant_get_string(value, NULL);
2451 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2453 } else if (!g_strcmp0(key, "Class")) {
2455 cod = g_variant_get_uint32(value);
2456 _bt_divide_device_class(&dev_info->device_class, cod);
2457 } else if (!g_strcmp0(key, "Name")) {
2458 const char *name = NULL;
2459 name = g_variant_get_string(value, NULL);
2460 /* If there is no Alias */
2461 if (strlen(dev_info->device_name.name) == 0) {
2462 g_strlcpy(dev_info->device_name.name, name,
2463 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2465 } else if (!g_strcmp0(key, "Alias")) {
2466 const char *alias = NULL;
2467 alias = g_variant_get_string(value, NULL);
2468 /* Overwrite the name */
2470 memset(dev_info->device_name.name, 0x00,
2471 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2472 g_strlcpy(dev_info->device_name.name, alias,
2473 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2475 } else if (!g_strcmp0(key, "IsAliasSet")) {
2476 dev_info->is_alias_set = g_variant_get_boolean(value);
2477 } else if (!g_strcmp0(key, "Connected")) {
2478 dev_info->connected = g_variant_get_byte(value);
2479 } else if (!g_strcmp0(key, "Paired")) {
2480 dev_info->paired = g_variant_get_boolean(value);
2481 } else if (!g_strcmp0(key, "Trusted")) {
2482 dev_info->trust = g_variant_get_boolean(value);
2483 } else if (!g_strcmp0(key, "RSSI")) {
2484 dev_info->rssi = g_variant_get_int16(value);
2485 } else if (!g_strcmp0(key, "UUIDs")) {
2491 dev_info->service_index = 0;
2492 g_variant_get(value, "as", &iter);
2493 while (g_variant_iter_loop(iter, "s", &uuid)) {
2494 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2495 parts = g_strsplit(uuid, "-", -1);
2497 if (parts == NULL || parts[0] == NULL) {
2502 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2507 dev_info->service_index = i;
2508 g_variant_iter_free(iter);
2509 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2510 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2511 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2512 manufacturer_data = g_byte_array_new();
2513 g_variant_get(value, "ay", &char_value_iter);
2514 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2515 g_byte_array_append(manufacturer_data, &char_value, 1);
2517 if (manufacturer_data) {
2518 if (manufacturer_data->len > 0)
2519 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2521 g_variant_iter_free(char_value_iter);
2522 g_byte_array_free(manufacturer_data, TRUE);
2529 static void __bt_extract_device_info(GVariantIter *iter,
2532 bluetooth_device_info_t *dev_info = NULL;
2533 char *object_path = NULL;
2534 GVariantIter *interface_iter;
2535 GVariantIter *svc_iter;
2536 char *interface_str = NULL;
2538 /* Parse the signature: oa{sa{sv}}} */
2539 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2542 if (object_path == NULL)
2545 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2546 &interface_str, &svc_iter)) {
2547 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2548 BT_DBG("Found a device: %s", object_path);
2549 dev_info = __bt_parse_device_info(svc_iter);
2551 if (dev_info->paired == TRUE) {
2552 g_array_append_vals(*dev_list, dev_info,
2553 sizeof(bluetooth_device_info_t));
2557 g_free(interface_str);
2558 g_variant_iter_free(svc_iter);
2566 int _bt_get_bonded_devices(GArray **dev_list)
2569 GDBusConnection *conn;
2570 GDBusProxy *manager_proxy;
2571 GVariant *result = NULL;
2572 GVariantIter *iter = NULL;
2573 GError *error = NULL;
2575 conn = _bt_gdbus_get_system_gconn();
2576 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2578 manager_proxy = _bt_get_manager_proxy();
2579 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2581 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2583 G_DBUS_CALL_FLAGS_NONE,
2589 if (error != NULL) {
2590 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2591 g_clear_error(&error);
2593 BT_ERR("Failed to Failed to GetManagedObjects");
2594 return BLUETOOTH_ERROR_INTERNAL;
2597 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2598 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2600 __bt_extract_device_info(iter, dev_list);
2601 g_variant_iter_free(iter);
2602 g_variant_unref(result);
2605 return BLUETOOTH_ERROR_NONE;
2608 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2611 GDBusConnection *conn;
2612 GDBusProxy *manager_proxy;
2613 GVariant *result = NULL;
2614 GVariant *result1 = NULL;
2615 GVariantIter *iter = NULL;
2616 GError *error = NULL;
2617 char *object_path = NULL;
2618 GVariantIter *interface_iter;
2619 char *interface_str = NULL;
2620 GDBusProxy *device_proxy = NULL;
2621 gboolean is_connected = FALSE;
2623 conn = _bt_gdbus_get_system_gconn();
2624 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2626 manager_proxy = _bt_get_manager_proxy();
2627 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2629 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2631 G_DBUS_CALL_FLAGS_NONE,
2637 if (error != NULL) {
2638 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2639 g_clear_error(&error);
2642 BT_ERR("Failed to Failed to GetManagedObjects");
2643 return BLUETOOTH_ERROR_INTERNAL;
2646 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2647 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2649 /* Parse the signature: oa{sa{sv}}} */
2650 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2651 if (object_path == NULL)
2654 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2655 &interface_str, NULL)) {
2656 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2657 BT_DBG("Found a device: %s", object_path);
2658 g_free(interface_str);
2660 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2661 NULL, BT_BLUEZ_NAME,
2662 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2664 if (device_proxy == NULL) {
2665 BT_DBG("Device don't have this service");
2669 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2670 g_variant_new("(s)", profile_uuid),
2671 G_DBUS_CALL_FLAGS_NONE,
2676 if (result1 == NULL) {
2677 BT_ERR("Error occured in Proxy call");
2679 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2680 g_error_free(error);
2683 g_object_unref(device_proxy);
2686 g_variant_get(result1, "(b)", &is_connected);
2688 if (is_connected == TRUE) {
2689 char address[BT_ADDRESS_STRING_SIZE];
2690 bluetooth_device_address_t *addr = NULL;
2692 _bt_convert_device_path_to_address(object_path, address);
2694 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2695 _bt_convert_addr_string_to_type(addr->addr, address);
2697 g_array_append_vals(*addr_list, addr,
2698 sizeof(bluetooth_device_address_t));
2701 g_variant_unref(result1);
2702 g_object_unref(device_proxy);
2709 g_variant_unref(result);
2710 g_variant_iter_free(iter);
2713 return BLUETOOTH_ERROR_NONE;
2716 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2717 bluetooth_device_info_t *dev_info)
2719 char *object_path = NULL;
2720 GDBusProxy *adapter_proxy;
2721 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2722 int ret = BLUETOOTH_ERROR_NONE;
2724 BT_CHECK_PARAMETER(device_address, return);
2725 BT_CHECK_PARAMETER(dev_info, return);
2727 adapter_proxy = _bt_get_adapter_proxy();
2728 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2730 _bt_convert_addr_type_to_string(address, device_address->addr);
2732 object_path = _bt_get_device_object_path(address);
2734 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2736 ret = __bt_get_bonded_device_info(object_path, dev_info);
2737 g_free(object_path);
2742 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2744 char *object_path = NULL;
2745 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2746 gboolean alias_set = FALSE;
2748 GDBusConnection *conn;
2749 GDBusProxy *device_proxy;
2750 GError *error = NULL;
2751 GVariant *result = NULL;
2752 GVariant *temp = NULL;
2755 BT_CHECK_PARAMETER(device_address, return);
2756 BT_CHECK_PARAMETER(is_alias_set, return);
2758 _bt_convert_addr_type_to_string(address, device_address->addr);
2760 object_path = _bt_get_device_object_path(address);
2761 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2763 conn = _bt_gdbus_get_system_gconn();
2765 g_free(object_path);
2766 return BLUETOOTH_ERROR_INTERNAL;
2769 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2773 BT_PROPERTIES_INTERFACE,
2775 if (device_proxy == NULL) {
2776 g_free(object_path);
2777 return BLUETOOTH_ERROR_INTERNAL;
2780 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2781 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2782 G_DBUS_CALL_FLAGS_NONE,
2788 BT_ERR("Error occured in Proxy call");
2789 if (error != NULL) {
2790 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2791 g_error_free(error);
2793 g_object_unref(device_proxy);
2794 g_free(object_path);
2795 return BLUETOOTH_ERROR_INTERNAL;
2798 g_variant_get(result, "(v)", &temp);
2799 alias_set = g_variant_get_boolean(temp);
2800 *is_alias_set = alias_set;
2801 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2802 g_variant_unref(temp);
2803 g_variant_unref(result);
2804 g_object_unref(device_proxy);
2806 g_free(object_path);
2808 return BLUETOOTH_ERROR_NONE;
2811 int _bt_get_timeout_value(int *timeout)
2813 time_t current_time;
2816 /* Take current time */
2817 time(¤t_time);
2818 time_diff = difftime(current_time, visible_timer.start_time);
2820 BT_DBG("Time diff = %d\n", time_diff);
2822 *timeout = visible_timer.timeout - time_diff;
2824 return BLUETOOTH_ERROR_NONE;
2827 int _bt_set_le_privacy(gboolean set_privacy)
2830 GError *error = NULL;
2831 GVariant *result = NULL;
2833 if (__bt_is_factory_test_mode()) {
2834 BT_ERR("Unable to set le privacy in factory binary !!");
2835 return BLUETOOTH_ERROR_NOT_SUPPORT;
2838 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2839 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2840 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2843 proxy = _bt_get_adapter_proxy();
2844 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2846 result = g_dbus_proxy_call_sync(proxy,
2848 g_variant_new("(b)", set_privacy),
2849 G_DBUS_CALL_FLAGS_NONE,
2855 if (error != NULL) {
2856 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2857 g_clear_error(&error);
2859 BT_ERR("Failed to SetLePrivacy");
2860 return BLUETOOTH_ERROR_INTERNAL;
2863 g_variant_unref(result);
2864 BT_INFO("SetLePrivacy as %d", set_privacy);
2865 return BLUETOOTH_ERROR_NONE;
2868 int _bt_set_le_static_random_address(gboolean is_enable)
2871 GError *error = NULL;
2872 GVariant *result = NULL;
2874 if (__bt_is_factory_test_mode()) {
2875 BT_ERR("Unable to set le random address in factory binary !!");
2876 return BLUETOOTH_ERROR_NOT_SUPPORT;
2879 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2880 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2881 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2884 proxy = _bt_get_adapter_proxy();
2885 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2887 result = g_dbus_proxy_call_sync(proxy,
2888 "SetLeStaticRandomAddress",
2889 g_variant_new("(b)", is_enable),
2890 G_DBUS_CALL_FLAGS_NONE,
2896 if (error != NULL) {
2897 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2898 g_clear_error(&error);
2900 BT_ERR("Failed to SetLeStaticRandomAddress");
2901 return BLUETOOTH_ERROR_INTERNAL;
2904 g_variant_unref(result);
2905 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2906 return BLUETOOTH_ERROR_NONE;
2909 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2912 GError *error = NULL;
2916 GVariantBuilder *builder;
2918 BT_CHECK_PARAMETER(m_data, return);
2920 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2921 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2922 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2925 proxy = _bt_get_adapter_proxy();
2926 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2928 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2930 for (i = 0; i < (m_data->data_len) + 2; i++)
2931 g_variant_builder_add(builder, "y", m_data->data[i]);
2933 val = g_variant_new("(ay)", builder);
2935 result = g_dbus_proxy_call_sync(proxy,
2936 "SetManufacturerData",
2938 G_DBUS_CALL_FLAGS_NONE,
2942 g_variant_builder_unref(builder);
2944 if (error != NULL) {
2945 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2946 g_clear_error(&error);
2948 BT_ERR("Failed to SetManufacturerData");
2950 return BLUETOOTH_ERROR_INTERNAL;
2952 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2954 for (i = 0; i < (m_data->data_len) + 2; i++)
2955 g_variant_builder_add(builder, "y", m_data->data[i]);
2957 val = g_variant_new("(ay)", builder);
2959 _bt_send_event(BT_ADAPTER_EVENT,
2960 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2963 BT_INFO("Set manufacturer data");
2965 g_variant_builder_unref(builder);
2966 g_variant_unref(result);
2968 return BLUETOOTH_ERROR_NONE;
2972 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2974 int result = BLUETOOTH_ERROR_NONE;
2975 bt_service_alarm_t *alarm = NULL;
2977 if (!call_back || !alarm_id)
2978 return BLUETOOTH_ERROR_INVALID_PARAM;
2980 if (!alarm_mgr.is_alarm_initialized) {
2981 result = alarmmgr_init("bt-service");
2983 BT_ERR("Failed to initialize alarm = %d", result);
2984 result = BLUETOOTH_ERROR_INTERNAL;
2987 result = alarmmgr_set_cb(alarm_cb, NULL);
2989 BT_ERR("Failed to set the callback = %d", result);
2990 result = BLUETOOTH_ERROR_INTERNAL;
2993 alarm_mgr.is_alarm_initialized = TRUE;
2996 alarm = g_malloc0(sizeof(bt_service_alarm_t));
2998 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
3000 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
3003 BT_ERR("Failed to create alarm error = %d", result);
3004 result = BLUETOOTH_ERROR_INTERNAL;
3008 alarm->alarm_id = *alarm_id;
3009 alarm->callback = call_back;
3010 alarm->user_data = user_data;
3012 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
3013 result = BLUETOOTH_ERROR_NONE;
3018 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
3021 bt_service_alarm_t *p_data;
3022 bt_set_alarm_cb callback = NULL;
3023 void *user_data = NULL;
3025 node = g_list_find_custom(alarm_mgr.g_alarm_list,
3026 GINT_TO_POINTER(alarm_id), compare_alarm);
3030 p_data = (bt_service_alarm_t *)node->data;
3031 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
3037 callback = p_data->callback;
3038 user_data = p_data->user_data;
3042 callback(alarm_id, user_data);
3047 int _bt_service_remove_alarm(alarm_id_t alarm_id)
3050 bt_service_alarm_t *p_data;
3051 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
3054 alarmmgr_remove_alarm(alarm_id);
3055 p_data = (bt_service_alarm_t *)list->data;
3056 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
3063 gint compare_alarm(gconstpointer list_data, gconstpointer data)
3066 alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
3068 alarm_id_t alarm_id = (alarm_id_t)data;
3070 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
3072 if (p_data->alarm_id == alarm_id)
3078 static void alarm_data_free(void *data)
3080 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
3085 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3089 int function = (int)(uintptr_t)user_data;
3091 int function = (int)user_data;
3095 case BT_ENABLE_ADAPTER:
3096 result = _bt_enable_adapter();
3097 if (result != BLUETOOTH_ERROR_NONE) {
3098 BT_ERR("_bt_enable_adapter is failed");
3099 /* Send enabled event to API */
3100 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3101 g_variant_new("(i)", result));
3104 case BT_DISABLE_ADAPTER:
3105 result = _bt_disable_adapter();
3106 if (result != BLUETOOTH_ERROR_NONE) {
3107 BT_ERR("_bt_disable_adapter is failed");
3108 /* Send disabled event to API */
3109 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3110 g_variant_new("(i)", result));
3114 BT_ERR("function is NOT matched");
3121 int _bt_adapter_request_delayed(int function)
3126 case BT_ENABLE_ADAPTER:
3127 ret = _bt_enable_adapter_check_status();
3128 if (ret == BLUETOOTH_ERROR_NONE)
3129 _bt_adapter_set_status(BT_ACTIVATING);
3134 case BT_DISABLE_ADAPTER:
3135 ret = _bt_disable_adapter_check_status();
3136 if (ret == BLUETOOTH_ERROR_NONE)
3137 _bt_adapter_set_status(BT_DEACTIVATING);
3143 BT_ERR("function is NOT matched");
3144 return BLUETOOTH_ERROR_INTERNAL;
3148 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3150 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3153 return BLUETOOTH_ERROR_NONE;
3156 int _bt_get_enable_timer_id(void)