2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <syspopup_caller.h>
26 #include <eventsystem.h>
27 #include <bundle_internal.h>
30 #include "bluetooth-api.h"
31 #include "bt-internal-types.h"
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
34 #include "bt-service-adapter.h"
35 #include "bt-service-util.h"
36 #include "bt-service-network.h"
37 #include "bt-service-obex-server.h"
38 #include "bt-service-opp-client.h"
39 #include "bt-service-map-client.h"
40 #include "bt-service-agent.h"
41 #include "bt-service-main.h"
42 #include "bt-service-avrcp.h"
43 #include "bt-service-device.h"
44 #ifdef TIZEN_FEATURE_BT_DPM
45 #include "bt-service-dpm.h"
55 bt_adapter_timer_t visible_timer = {0, };
59 bt_set_alarm_cb callback;
64 gboolean is_alarm_initialized;
66 } bt_service_alarm_mgr_t;
68 static bt_service_alarm_mgr_t alarm_mgr = {0, };
70 static gboolean is_discovering;
71 static gboolean discovery_req;
72 static gboolean cancel_by_user;
73 static bt_status_t adapter_status = BT_DEACTIVATED;
74 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
75 static gboolean is_le_intended = FALSE;
76 static void *adapter_agent = NULL;
77 static GDBusProxy *core_proxy = NULL;
78 static guint timer_id = 0;
79 static guint le_timer_id = 0;
80 static gboolean is_recovery_mode;
82 static uint status_reg_id;
84 #define BT_CORE_NAME "org.projectx.bt_core"
85 #define BT_CORE_PATH "/org/projectx/bt_core"
86 #define BT_CORE_INTERFACE "org.projectx.btcore"
88 #define BT_DISABLE_TIME 500 /* 500 ms */
90 static int alarm_cb(alarm_id_t alarm_id, void* user_param);
91 static void alarm_data_free(void *data);
93 GDBusProxy *_bt_init_core_proxy(void)
96 GDBusConnection *conn;
98 conn = _bt_gdbus_get_system_gconn();
102 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
117 static GDBusProxy *__bt_get_core_proxy(void)
119 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
122 static gboolean __bt_is_factory_test_mode(void)
126 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
127 BT_ERR("Get the DUT Mode fail");
132 BT_INFO("DUT Test Mode !!");
139 static gboolean __bt_timeout_handler(gpointer user_data)
141 int result = BLUETOOTH_ERROR_NONE;
145 /* Take current time */
147 time_diff = difftime(current_time, visible_timer.start_time);
149 /* Send event to application */
150 _bt_send_event(BT_ADAPTER_EVENT,
151 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
152 g_variant_new("(in)", result, time_diff));
154 if (visible_timer.timeout <= time_diff) {
155 g_source_remove(visible_timer.event_id);
156 visible_timer.event_id = 0;
157 visible_timer.timeout = 0;
159 if (!TIZEN_PROFILE_WEARABLE) {
160 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
161 BT_ERR("Set vconf failed\n");
169 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
172 int result = BLUETOOTH_ERROR_NONE;
175 if (alarm_id != visible_timer.alarm_id)
178 if (visible_timer.event_id) {
179 _bt_send_event(BT_ADAPTER_EVENT,
180 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
181 g_variant_new("(in)", result, timeout));
182 g_source_remove(visible_timer.event_id);
183 visible_timer.event_id = 0;
184 visible_timer.timeout = 0;
186 if (!TIZEN_PROFILE_WEARABLE) {
187 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
188 BT_ERR("Set vconf failed\n");
191 /* Switch Off visibility in Bluez */
192 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
193 visible_timer.alarm_id = 0;
197 static void __bt_visibility_alarm_remove()
199 if (visible_timer.event_id > 0) {
200 g_source_remove(visible_timer.event_id);
201 visible_timer.event_id = 0;
204 if (visible_timer.alarm_id > 0) {
205 _bt_service_remove_alarm(visible_timer.alarm_id);
206 visible_timer.alarm_id = 0;
210 int __bt_set_visible_time(int timeout)
214 #ifdef TIZEN_FEATURE_BT_DPM
215 int discoverable_state = DPM_BT_ERROR;
218 __bt_visibility_alarm_remove();
220 visible_timer.timeout = timeout;
222 if (!TIZEN_PROFILE_WEARABLE) {
223 #ifdef TIZEN_FEATURE_BT_DPM
224 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
225 if (discoverable_state != DPM_RESTRICTED) {
227 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
228 BT_ERR("Set vconf failed");
229 #ifdef TIZEN_FEATURE_BT_DPM
236 return BLUETOOTH_ERROR_NONE;
238 result = _bt_service_set_alarm(visible_timer.timeout,
239 __bt_visibility_alarm_cb, NULL, &alarm_id);
240 if (result != BLUETOOTH_ERROR_NONE)
241 return BLUETOOTH_ERROR_INTERNAL;
242 visible_timer.alarm_id = alarm_id;
243 /* Take start time */
244 time(&(visible_timer.start_time));
245 visible_timer.event_id = g_timeout_add_seconds(1,
246 __bt_timeout_handler, NULL);
248 return BLUETOOTH_ERROR_NONE;
251 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
258 ret_if(value == NULL);
261 dev->service_index = 0;
263 g_variant_get(value, "as", &iter);
264 while (g_variant_iter_loop(iter, "s", &uuid)) {
265 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
266 parts = g_strsplit(uuid, "-", -1);
268 if (parts == NULL || parts[0] == NULL) {
273 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
276 dev->service_index++;
279 g_variant_iter_free(iter);
282 static int __bt_get_bonded_device_info(gchar *device_path,
283 bluetooth_device_info_t *dev_info)
285 GError *error = NULL;
286 GDBusProxy *device_proxy;
287 gchar *address = NULL;
289 unsigned int cod = 0;
291 gboolean trust = FALSE;
292 gboolean paired = FALSE;
293 guchar connected = 0;
294 GByteArray *manufacturer_data = NULL;
296 GDBusConnection *conn;
298 GVariantIter *property_iter;
302 GVariantIter *char_value_iter;
304 BT_CHECK_PARAMETER(device_path, return);
305 BT_CHECK_PARAMETER(dev_info, return);
307 conn = _bt_gdbus_get_system_gconn();
308 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
310 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
314 BT_PROPERTIES_INTERFACE,
317 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
319 result = g_dbus_proxy_call_sync(device_proxy,
321 g_variant_new("(s)", BT_DEVICE_INTERFACE),
322 G_DBUS_CALL_FLAGS_NONE,
328 BT_ERR("Error occured in Proxy call");
330 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
331 g_clear_error(&error);
333 g_object_unref(device_proxy);
334 return BLUETOOTH_ERROR_INTERNAL;
337 g_object_unref(device_proxy);
339 g_variant_get(result, "(a{sv})", &property_iter);
341 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
342 if (!g_strcmp0(key, "Paired")) {
343 paired = g_variant_get_boolean(value);
344 } else if (!g_strcmp0(key, "Address")) {
345 g_variant_get(value, "s", &address);
346 } else if (!g_strcmp0(key, "Alias")) {
347 g_variant_get(value, "s", &name);
348 } else if (!g_strcmp0(key, "Name")) {
350 g_variant_get(value, "s", &name);
351 } else if (!g_strcmp0(key, "Class")) {
352 cod = g_variant_get_uint32(value);
353 } else if (!g_strcmp0(key, "Connected")) {
354 connected = g_variant_get_byte(value);
355 } else if (!g_strcmp0(key, "Trusted")) {
356 trust = g_variant_get_boolean(value);
357 } else if (!g_strcmp0(key, "RSSI")) {
358 rssi = g_variant_get_int16(value);
359 } else if (!g_strcmp0(key, "UUIDs")) {
360 __bt_get_service_list(value, dev_info);
361 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
362 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
363 } else if (!g_strcmp0(key, "ManufacturerData")) {
364 manufacturer_data = g_byte_array_new();
365 g_variant_get(value, "ay", &char_value_iter);
366 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
367 g_byte_array_append(manufacturer_data, &char_value, 1);
369 g_variant_iter_free(char_value_iter);
371 if (manufacturer_data) {
372 if (manufacturer_data->len > 0) {
373 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
374 manufacturer_data->len);
377 g_byte_array_free(manufacturer_data, TRUE);
380 g_variant_iter_free(property_iter);
382 BT_DBG("trust: %d, paired: %d", trust, paired);
384 g_variant_unref(result);
386 if ((paired == FALSE) && (trust == FALSE)) {
389 return BLUETOOTH_ERROR_NOT_PAIRED;
392 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
395 _bt_divide_device_class(&dev_info->device_class, cod);
397 g_strlcpy(dev_info->device_name.name, name,
398 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
400 dev_info->rssi = rssi;
401 dev_info->trust = trust;
402 dev_info->paired = paired;
403 dev_info->connected = connected;
404 ret = BLUETOOTH_ERROR_NONE;
411 void _bt_set_discovery_status(gboolean mode)
413 is_discovering = mode;
414 discovery_req = FALSE;
417 void _bt_set_cancel_by_user(gboolean value)
419 cancel_by_user = value;
422 gboolean _bt_get_cancel_by_user(void)
424 return cancel_by_user;
427 void _bt_adapter_set_status(bt_status_t status)
429 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
430 adapter_status = status;
433 bt_status_t _bt_adapter_get_status(void)
435 return adapter_status;
438 void _bt_adapter_set_le_status(bt_le_status_t status)
440 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
441 adapter_le_status = status;
444 bt_le_status_t _bt_adapter_get_le_status(void)
446 return adapter_le_status;
450 void _bt_set_le_intended_status(gboolean value)
452 is_le_intended = value;
455 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
457 char *phone_name = NULL;
463 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
464 phone_name = vconf_keynode_get_str(node);
466 if (phone_name && strlen(phone_name) != 0) {
467 if (!g_utf8_validate(phone_name, -1,
468 (const char **)&ptr))
471 _bt_set_local_name(phone_name);
476 static void __bt_set_local_name(void)
478 bluetooth_device_name_t local_name;
479 char *phone_name = NULL;
483 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
484 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
485 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
490 if (strlen(phone_name) != 0) {
491 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
494 _bt_set_local_name(phone_name);
500 static int __bt_set_enabled(void)
502 int adapter_status = BT_ADAPTER_DISABLED;
503 int result = BLUETOOTH_ERROR_NONE;
506 BT_DBG("g_source is removed");
507 g_source_remove(timer_id);
511 _bt_check_adapter(&adapter_status);
513 if (adapter_status == BT_ADAPTER_DISABLED) {
514 BT_ERR("Bluetoothd is not running");
515 return BLUETOOTH_ERROR_INTERNAL;
518 if (TIZEN_PROFILE_MOBILE || TIZEN_PROFILE_IVI) {
519 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
520 if (_bt_set_discoverable_mode(
521 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
522 BT_ERR("Set connectable mode failed");
523 } else if (TIZEN_PROFILE_TV) {
524 if (_bt_set_discoverable_mode(
525 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
526 BT_ERR("Fail to set discoverable mode");
529 /* Update Bluetooth Status to notify other modules */
530 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
531 BT_ERR("Set vconf failed\n");
533 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
534 BT_ERR("Set vconf failed\n");
536 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
537 EVT_VAL_BT_ON) != ES_R_OK)
538 BT_ERR("Fail to set value");
540 /* Send enabled event to API */
541 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
542 g_variant_new("(i)", result));
544 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
545 _bt_audio_start_auto_connect(FALSE);
548 __bt_set_local_name();
549 _bt_set_discovery_status(FALSE);
551 return BLUETOOTH_ERROR_NONE;
554 void _bt_set_disabled(int result)
556 int power_off_status = 0;
559 int pm_ignore_mode = 0;
561 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
562 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
564 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
566 /* Update the vconf BT status in normal Deactivation case only */
567 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
568 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
570 BT_DBG("Update vconf for BT normal Deactivation");
572 if (result == BLUETOOTH_ERROR_TIMEOUT)
573 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
574 BT_ERR("Set vconf failed");
576 /* Update Bluetooth Status to notify other modules */
577 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
578 BT_ERR("Set vconf failed");
580 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
581 EVT_VAL_BT_OFF) != ES_R_OK)
582 BT_ERR("Fail to set value");
585 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
586 BT_ERR("Set vconf failed\n");
588 _bt_cancel_queued_transfers();
589 _bt_adapter_set_status(BT_DEACTIVATED);
590 _bt_set_discovery_status(FALSE);
592 if (TIZEN_FEATURE_BT_USB_DONGLE ||
593 _bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
594 /* Send disabled event */
595 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
596 g_variant_new("(i)", result));
599 BT_INFO("Adapter disabled");
602 static int __bt_set_le_enabled(void)
605 int result = BLUETOOTH_ERROR_NONE;
608 /* Update Bluetooth Status to notify other modules */
609 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
610 BT_ERR("Set vconf failed\n");
612 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
613 EVT_VAL_BT_LE_ON) != ES_R_OK)
614 BT_ERR("Fail to set value");
616 /* Send enabled event to API */
618 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
619 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
621 status = _bt_adapter_get_status();
622 if (status == BT_DEACTIVATED) {
623 BT_INFO("BREDR is off, turn off PSCAN");
624 _bt_set_connectable(FALSE);
626 if (le_timer_id > 0) {
627 g_source_remove(le_timer_id);
631 /* Send enabled event to API */
632 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
633 g_variant_new("(i)", result));
635 __bt_set_local_name();
638 return BLUETOOTH_ERROR_NONE;
641 void _bt_set_le_disabled(int result)
643 int power_off_status;
646 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
647 BT_DBG("ret : %d", ret);
648 BT_DBG("power_off_status : %d", power_off_status);
650 /* Update Bluetooth Status to notify other modules */
651 BT_DBG("Update vconf for BT LE normal Deactivation");
652 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
653 BT_ERR("Set vconf failed\n");
654 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
656 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
657 EVT_VAL_BT_LE_OFF) != ES_R_OK)
658 BT_ERR("Fail to set value");
660 /* Send disabled event */
661 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
662 g_variant_new("(i)", result));
665 void *_bt_get_adapter_agent(void)
667 return adapter_agent;
670 int _bt_enable_core(void)
674 GError *error = NULL;
676 proxy = __bt_get_core_proxy();
677 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
679 /* Clean up the process */
680 result = g_dbus_proxy_call_sync(proxy,
683 G_DBUS_CALL_FLAGS_NONE,
690 BT_ERR("Bt core call failed(Error: %s)", error->message);
691 g_clear_error(&error);
693 BT_ERR("Bt core call failed");
694 return BLUETOOTH_ERROR_INTERNAL;
697 g_variant_unref(result);
698 return BLUETOOTH_ERROR_NONE;
701 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
703 gboolean flight_mode = FALSE;
704 int power_saving_mode = 0;
707 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
708 type = vconf_keynode_get_type(node);
709 if (type == VCONF_TYPE_BOOL) {
710 flight_mode = vconf_keynode_get_bool(node);
711 if (flight_mode != TRUE) {
712 BT_ERR("Ignore the event");
715 } else if (type == VCONF_TYPE_INT) {
716 power_saving_mode = vconf_keynode_get_int(node);
717 if (power_saving_mode != 2) {
718 BT_ERR("Ignore the event");
722 BT_ERR("Invaild vconf key type : %d", type);
729 void _bt_service_register_vconf_handler(void)
733 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
734 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
735 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
736 BT_ERR("Unable to register key handler");
738 BT_DBG("Telephony is disabled");
741 if (!TIZEN_PROFILE_WEARABLE) {
742 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
743 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
744 BT_ERR("Unable to register key handler");
748 void _bt_service_unregister_vconf_handler(void)
752 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
753 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
754 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
757 if (!TIZEN_PROFILE_WEARABLE) {
758 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
759 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
763 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
765 const char *bt_status = NULL;
766 const char *bt_le_status = NULL;
767 BT_DBG("bt state set event(%s) received", event_name);
769 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
770 BT_DBG("bt_state: (%s)", bt_status);
772 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
773 BT_DBG("bt_state: (%s)", bt_le_status);
776 void _bt_handle_adapter_added(void)
780 bt_le_status_t le_status;
784 BT_DBG("g_source is removed");
785 g_source_remove(timer_id);
790 status = _bt_adapter_get_status();
791 le_status = _bt_adapter_get_le_status();
792 BT_DBG("status : %d", status);
793 BT_DBG("le_status : %d", le_status);
795 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
796 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
797 if (!adapter_agent) {
798 BT_ERR("Fail to register agent");
802 if (adapter_agent == NULL) {
803 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
804 if (!adapter_agent) {
805 BT_ERR("Fail to register agent");
811 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
812 BT_ERR("Fail to register media player");
814 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
815 BT_ERR("Fail to init obex server");
817 #ifdef TIZEN_BT_PAN_NAP_ENABLED
818 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
819 BT_ERR("Fail to activate network");
822 /* add the vconf noti handler */
823 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
824 __bt_phone_name_changed_cb, NULL);
826 BT_ERR("Unable to register key handler");
828 if (le_status == BT_LE_ACTIVATING ||
829 status == BT_ACTIVATING) {
830 __bt_set_le_enabled();
831 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
834 if (status == BT_ACTIVATING) {
836 _bt_adapter_set_status(BT_ACTIVATED);
840 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
841 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
842 BT_ERR("Fail to register system event");
846 void _bt_handle_adapter_removed(void)
850 _bt_adapter_set_status(BT_DEACTIVATED);
852 __bt_visibility_alarm_remove();
854 if (alarm_mgr.is_alarm_initialized == TRUE) {
856 alarm_mgr.is_alarm_initialized = FALSE;
857 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
858 alarm_mgr.g_alarm_list = NULL;
861 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
862 _bt_audio_stop_auto_connect();
865 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
866 (vconf_callback_fn)__bt_phone_name_changed_cb);
868 ERR("vconf_ignore_key_changed failed\n");
870 /* unregister all the services/servers/profiles registered on bluez-adapter
871 once adapter is removed, reinitializing of the state-varaibles becomes
873 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
874 BT_ERR("Fail to unregister obex server");
876 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
877 BT_ERR("Fail to unregister media player");
879 /* Other unregister APIs should be placed here */
881 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
882 _bt_destroy_agent(adapter_agent);
883 adapter_agent = NULL;
885 if (is_recovery_mode == TRUE) {
886 /* Send disabled event */
887 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
889 /* Will recover BT by bt-core, so set the mode as activating */
890 _bt_adapter_set_status(BT_ACTIVATING);
891 is_recovery_mode = FALSE;
893 _bt_reliable_terminate_service(NULL);
896 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
899 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
900 BT_ERR("Fail to unregister system event");
903 static gboolean __bt_enable_timeout_cb(gpointer user_data)
907 GError *error = NULL;
911 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
913 BT_ERR("EnableAdapter is failed");
915 proxy = __bt_get_core_proxy();
919 /* Clean up the process */
920 result = g_dbus_proxy_call_sync(proxy,
923 G_DBUS_CALL_FLAGS_NONE,
930 BT_ERR("Bt core call failed(Error: %s)", error->message);
931 g_clear_error(&error);
933 BT_ERR("Bt core call failed");
938 g_variant_unref(result);
939 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
941 if (!TIZEN_FEATURE_BT_USB_DONGLE)
942 _bt_terminate_service(NULL);
947 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
951 GError *error = NULL;
955 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
957 BT_ERR("EnableAdapterLE is failed");
959 proxy = __bt_get_core_proxy();
963 /* Clean up the process */
964 result = g_dbus_proxy_call_sync(proxy,
967 G_DBUS_CALL_FLAGS_NONE,
974 BT_ERR("Bt core call failed(Error: %s)", error->message);
975 g_clear_error(&error);
977 BT_ERR("Bt core call failed");
981 g_variant_unref(result);
982 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
984 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
986 if (_bt_adapter_get_status() == BT_DEACTIVATED)
987 _bt_terminate_service(NULL);
992 void _bt_adapter_start_le_enable_timer(void)
994 if (le_timer_id > 0) {
995 g_source_remove(le_timer_id);
999 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1000 __bt_enable_le_timeout_cb, NULL);
1005 void _bt_adapter_start_enable_timer(void)
1008 g_source_remove(timer_id);
1012 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1013 __bt_enable_timeout_cb, NULL);
1018 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1023 _bt_adapter_set_status(BT_ACTIVATED);
1028 int _bt_enable_adapter_check_status(void)
1030 bt_status_t status = _bt_adapter_get_status();
1031 bt_le_status_t le_status = _bt_adapter_get_le_status();
1035 if (status == BT_ACTIVATING) {
1036 BT_ERR("Enabling in progress");
1037 return BLUETOOTH_ERROR_IN_PROGRESS;
1040 if (status == BT_ACTIVATED) {
1041 BT_ERR("Already enabled");
1042 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1045 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1046 BT_ERR("Disabling in progress");
1047 return BLUETOOTH_ERROR_DEVICE_BUSY;
1050 return BLUETOOTH_ERROR_NONE;
1053 int _bt_enable_adapter(void)
1056 GError *error = NULL;
1058 GVariant *result = NULL;
1059 bt_status_t status = _bt_adapter_get_status();
1060 bt_le_status_t le_status = _bt_adapter_get_le_status();
1064 if (status == BT_ACTIVATING) {
1065 BT_ERR("Enabling in progress");
1066 return BLUETOOTH_ERROR_IN_PROGRESS;
1069 if (status == BT_ACTIVATED) {
1070 BT_ERR("Already enabled");
1071 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1074 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1075 BT_ERR("Disabling in progress");
1076 return BLUETOOTH_ERROR_DEVICE_BUSY;
1079 _bt_adapter_set_status(BT_ACTIVATING);
1081 if (TIZEN_PROFILE_TV) {
1082 int adapter_status = BT_ADAPTER_DISABLED;
1084 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1085 BT_ERR("Set vconf failed");
1087 _bt_check_adapter(&adapter_status);
1088 if (adapter_status == BT_ADAPTER_ENABLED) {
1089 g_idle_add(__bt_adapter_enabled_cb, NULL);
1090 _bt_adapter_start_enable_timer();
1091 return BLUETOOTH_ERROR_NONE;
1095 proxy = __bt_get_core_proxy();
1097 return BLUETOOTH_ERROR_INTERNAL;
1099 if (le_status == BT_LE_ACTIVATED) {
1100 BT_INFO("LE Already enabled. Just turn on PSCAN");
1101 ret = _bt_set_connectable(TRUE);
1102 if (ret == BLUETOOTH_ERROR_NONE)
1103 _bt_adapter_set_status(BT_ACTIVATED);
1105 return BLUETOOTH_ERROR_INTERNAL;
1108 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1110 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1113 BT_ERR("EnableAdapterLe failed: %s", error->message);
1114 _bt_adapter_set_status(BT_DEACTIVATED);
1115 g_clear_error(&error);
1117 result = g_dbus_proxy_call_sync(proxy,
1120 G_DBUS_CALL_FLAGS_NONE,
1125 if (error != NULL) {
1126 BT_ERR("Bt core call failed(Error: %s)", error->message);
1127 g_clear_error(&error);
1129 g_variant_unref(result);
1130 /* Terminate myself */
1131 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1132 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1133 return BLUETOOTH_ERROR_INTERNAL;
1135 g_variant_unref(result);
1136 if (le_status == BT_LE_ACTIVATED)
1139 _bt_adapter_start_enable_timer();
1141 return BLUETOOTH_ERROR_NONE;
1144 static gboolean __bt_disconnect_all(void)
1147 GDBusConnection *conn;
1148 GDBusProxy *dev_proxy;
1149 gboolean ret = FALSE;
1151 GError *error = NULL;
1152 GArray *device_list;
1153 bluetooth_device_info_t info;
1155 char *device_path = NULL;
1156 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1161 conn = _bt_gdbus_get_system_gconn();
1163 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1165 if (_bt_get_bonded_devices(&device_list)
1166 != BLUETOOTH_ERROR_NONE) {
1167 g_array_free(device_list, TRUE);
1171 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1173 for (i = 0; i < size; i++) {
1175 info = g_array_index(device_list,
1176 bluetooth_device_info_t, i);
1178 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1179 BT_DBG("Found Connected device");
1180 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1181 device_path = _bt_get_device_object_path(address);
1182 if (device_path == NULL)
1185 BT_DBG("Disconnecting : %s", device_path);
1187 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1191 BT_DEVICE_INTERFACE,
1194 if (dev_proxy == NULL)
1197 result = g_dbus_proxy_call_sync(dev_proxy,
1200 G_DBUS_CALL_FLAGS_NONE,
1206 if (error != NULL) {
1207 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1208 g_clear_error(&error);
1210 BT_ERR("Disconnect call failed");
1211 g_object_unref(dev_proxy);
1215 g_variant_unref(result);
1216 g_object_unref(dev_proxy);
1220 g_array_free(device_list, TRUE);
1226 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1229 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1235 int _bt_disable_cb(void)
1243 GError *error = NULL;
1245 _bt_adapter_set_status(BT_DEACTIVATING);
1247 bt_le_status_t le_status;
1248 le_status = _bt_adapter_get_le_status();
1249 BT_DBG("le_status : %d", le_status);
1250 if (le_status == BT_LE_ACTIVATED) {
1251 BT_INFO("LE is enabled. Just turn off PSCAN");
1253 if (_bt_is_discovering())
1254 _bt_cancel_discovery();
1256 if (_bt_is_connectable() == FALSE) {
1257 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1259 ret = _bt_set_connectable(FALSE);
1260 if (ret != BLUETOOTH_ERROR_NONE) {
1261 BT_ERR("_bt_set_connectable fail!");
1262 _bt_adapter_set_status(BT_ACTIVATED);
1263 return BLUETOOTH_ERROR_INTERNAL;
1268 proxy = __bt_get_core_proxy();
1269 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1271 result = g_dbus_proxy_call_sync(proxy,
1274 G_DBUS_CALL_FLAGS_NONE,
1280 if (error != NULL) {
1281 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1282 g_clear_error(&error);
1284 BT_ERR("Failed to DisableAdapter");
1285 _bt_adapter_set_status(BT_ACTIVATED);
1286 return BLUETOOTH_ERROR_INTERNAL;
1289 g_variant_unref(result);
1290 return BLUETOOTH_ERROR_NONE;
1293 int _bt_disable_adapter_check_status(void)
1295 bt_status_t status = _bt_adapter_get_status();
1299 if (status == BT_DEACTIVATING) {
1300 BT_DBG("Disabling in progress");
1301 return BLUETOOTH_ERROR_IN_PROGRESS;
1304 if (status == BT_DEACTIVATED) {
1305 BT_DBG("Already disabled");
1306 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1309 return BLUETOOTH_ERROR_NONE;
1312 int _bt_disable_adapter(void)
1317 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1318 BT_DBG("Disabling in progress");
1319 return BLUETOOTH_ERROR_IN_PROGRESS;
1322 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1323 BT_DBG("Already disabled");
1324 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1328 g_source_remove(timer_id);
1331 /* unregister all the services/servers/profiles registered on bluez-adapter
1332 once adapter is removed, reinitializing of the state-varaibles becomes
1334 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1335 BT_ERR("Fail to unregister obex server");
1337 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
1338 BT_ERR("Fail to unregister media player");
1340 /* Other unregister APIs should be placed here */
1341 __bt_disconnect_all();
1342 ret = _bt_disable_cb();
1348 int _bt_recover_adapter(void)
1353 GError *error = NULL;
1355 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1356 BT_DBG("Disabling in progress");
1357 return BLUETOOTH_ERROR_IN_PROGRESS;
1360 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1361 BT_DBG("Already disabled");
1362 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1365 _bt_adapter_set_status(BT_DEACTIVATING);
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 RecoverAdapter (Error: %s)", error->message);
1381 g_clear_error(&error);
1383 BT_ERR("Failed to RecoverAdapter");
1384 return BLUETOOTH_ERROR_INTERNAL;
1387 is_recovery_mode = TRUE;
1389 g_variant_unref(result);
1390 __bt_disconnect_all();
1393 return BLUETOOTH_ERROR_NONE;
1396 int _bt_reset_adapter(void)
1400 GError *error = NULL;
1404 proxy = __bt_get_core_proxy();
1406 return BLUETOOTH_ERROR_INTERNAL;
1408 result = g_dbus_proxy_call_sync(proxy,
1411 G_DBUS_CALL_FLAGS_NONE,
1417 if (error != NULL) {
1418 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1419 g_clear_error(&error);
1421 BT_ERR("Failed to ResetAdapter");
1422 return BLUETOOTH_ERROR_INTERNAL;
1425 g_variant_unref(result);
1426 /* Terminate myself */
1427 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1428 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1430 return BLUETOOTH_ERROR_NONE;
1433 int _bt_check_adapter(int *status)
1435 if (!TIZEN_PROFILE_TV) {
1436 char *adapter_path = NULL;
1438 BT_CHECK_PARAMETER(status, return);
1440 *status = BT_ADAPTER_DISABLED;
1442 adapter_path = _bt_get_adapter_path();
1445 if (adapter_path != NULL)
1446 *status = BT_ADAPTER_ENABLED;
1448 g_free(adapter_path);
1449 return BLUETOOTH_ERROR_NONE;
1452 GError *error = NULL;
1455 gboolean powered = FALSE;
1457 BT_CHECK_PARAMETER(status, return);
1459 *status = BT_ADAPTER_DISABLED;
1461 proxy = _bt_get_adapter_properties_proxy();
1462 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1464 result = g_dbus_proxy_call_sync(proxy,
1466 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1468 G_DBUS_CALL_FLAGS_NONE,
1474 BT_ERR("Failed to get local address");
1475 if (error != NULL) {
1476 BT_ERR("Failed to get local address (Error: %s)", error->message);
1477 g_clear_error(&error);
1479 return BLUETOOTH_ERROR_INTERNAL;
1482 g_variant_get(result, "(v)", &temp);
1483 powered = g_variant_get_boolean(temp);
1484 BT_DBG("powered: %d", powered);
1487 *status = BT_ADAPTER_ENABLED;
1489 g_variant_unref(result);
1490 g_variant_unref(temp);
1491 return BLUETOOTH_ERROR_NONE;
1495 int _bt_enable_adapter_le(void)
1499 GError *error = NULL;
1500 bt_status_t status = _bt_adapter_get_status();
1501 bt_le_status_t le_status = _bt_adapter_get_le_status();
1504 if (le_status == BT_LE_ACTIVATING) {
1505 BT_ERR("Enabling in progress");
1506 return BLUETOOTH_ERROR_IN_PROGRESS;
1509 if (le_status == BT_LE_ACTIVATED) {
1510 BT_ERR("Already enabled");
1511 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1514 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1515 BT_ERR("Disabling in progress");
1516 return BLUETOOTH_ERROR_DEVICE_BUSY;
1519 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1521 proxy = __bt_get_core_proxy();
1522 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1524 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1526 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1529 BT_ERR("EnableAdapterLe failed: %s", error->message);
1530 _bt_adapter_set_le_status(BT_DEACTIVATED);
1531 g_clear_error(&error);
1533 /* Clean up the process */
1534 result = g_dbus_proxy_call_sync(proxy,
1537 G_DBUS_CALL_FLAGS_NONE,
1543 BT_ERR("Bt core call failed");
1545 BT_ERR("EnableAdapterLE Failed %s", error->message);
1546 g_clear_error(&error);
1549 g_variant_unref(result);
1550 /* Terminate myself */
1551 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1552 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1553 return BLUETOOTH_ERROR_INTERNAL;
1557 g_variant_unref(result);
1559 _bt_adapter_start_le_enable_timer();
1561 if (status == BT_ACTIVATED) {
1562 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1563 __bt_set_le_enabled();
1565 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1567 return BLUETOOTH_ERROR_NONE;
1570 int _bt_disable_adapter_le(void)
1574 bt_le_status_t bt_le_state;
1576 GError *error = NULL;
1578 bt_le_state = _bt_adapter_get_le_status();
1579 if (bt_le_state == BT_LE_DEACTIVATING) {
1580 BT_DBG("Disabling in progress");
1581 return BLUETOOTH_ERROR_IN_PROGRESS;
1584 if (bt_le_state == BT_LE_DEACTIVATED) {
1585 BT_DBG("Already disabled");
1586 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1589 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1591 proxy = __bt_get_core_proxy();
1593 return BLUETOOTH_ERROR_INTERNAL;
1595 result = g_dbus_proxy_call_sync(proxy,
1598 G_DBUS_CALL_FLAGS_NONE,
1604 if (error != NULL) {
1605 BT_ERR("Bt core call failed (Error: %s)", error->message);
1606 g_clear_error(&error);
1608 BT_ERR("Bt core call failed");
1609 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1610 return BLUETOOTH_ERROR_INTERNAL;
1613 g_variant_unref(result);
1614 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1615 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1617 return BLUETOOTH_ERROR_NONE;
1620 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1624 GError *error = NULL;
1625 const char *address;
1629 BT_CHECK_PARAMETER(local_address, return);
1631 proxy = _bt_get_adapter_properties_proxy();
1632 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1634 result = g_dbus_proxy_call_sync(proxy,
1636 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1638 G_DBUS_CALL_FLAGS_NONE,
1644 BT_ERR("Failed to get local address");
1645 if (error != NULL) {
1646 BT_ERR("Failed to get local address (Error: %s)", error->message);
1647 g_clear_error(&error);
1649 return BLUETOOTH_ERROR_INTERNAL;
1652 g_variant_get(result, "(v)", &temp);
1653 address = g_variant_get_string(temp, NULL);
1654 BT_DBG("Address:%s", address);
1657 _bt_convert_addr_string_to_type(local_address->addr, address);
1659 return BLUETOOTH_ERROR_INTERNAL;
1661 g_variant_unref(result);
1662 g_variant_unref(temp);
1663 return BLUETOOTH_ERROR_NONE;
1666 int _bt_get_local_version(bluetooth_version_t *local_version)
1669 const char *ver = NULL;
1671 int ret = BLUETOOTH_ERROR_NONE;
1675 BT_CHECK_PARAMETER(local_version, return);
1677 GError *error = NULL;
1679 proxy = _bt_get_adapter_properties_proxy();
1680 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1682 result = g_dbus_proxy_call_sync(proxy,
1684 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1686 G_DBUS_CALL_FLAGS_NONE,
1692 if (error != NULL) {
1693 BT_ERR("Failed to get local version (Error: %s)", error->message);
1694 g_clear_error(&error);
1696 BT_ERR("Failed to get local version");
1697 return BLUETOOTH_ERROR_INTERNAL;
1700 g_variant_get(result, "(v)", &temp);
1701 ver = g_variant_get_string(temp, NULL);
1702 BT_DBG("VERSION: %s", ver);
1704 if (ver && (strlen(ver) > 0)) {
1705 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1706 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1709 g_strlcpy(local_version->version, ver,
1710 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1713 ret = BLUETOOTH_ERROR_INTERNAL;
1716 g_variant_unref(result);
1717 g_variant_unref(temp);
1721 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1724 const char *name = NULL;
1726 int ret = BLUETOOTH_ERROR_NONE;
1729 GError *error = NULL;
1731 BT_CHECK_PARAMETER(local_name, return);
1733 proxy = _bt_get_adapter_properties_proxy();
1734 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1736 result = g_dbus_proxy_call_sync(proxy,
1738 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1740 G_DBUS_CALL_FLAGS_NONE,
1746 if (error != NULL) {
1747 BT_ERR("Failed to get local name (Error: %s)", error->message);
1748 g_clear_error(&error);
1750 BT_ERR("Failed to get local name");
1751 return BLUETOOTH_ERROR_INTERNAL;
1754 g_variant_get(result, "(v)", &temp);
1755 name = g_variant_get_string(temp, NULL);
1756 BT_DBG("LOCAL NAME:%s", name);
1758 if (name && (strlen(name) > 0)) {
1759 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1760 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1763 g_strlcpy(local_name->name, name,
1764 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1766 ret = BLUETOOTH_ERROR_INTERNAL;
1768 g_variant_unref(result);
1769 g_variant_unref(temp);
1773 int _bt_set_local_name(char *local_name)
1776 GError *error = NULL;
1780 BT_CHECK_PARAMETER(local_name, return);
1782 proxy = _bt_get_adapter_properties_proxy();
1784 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1786 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1789 result = g_dbus_proxy_call_sync(proxy,
1791 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1792 "Alias", g_variant_new("s", local_name)),
1793 G_DBUS_CALL_FLAGS_NONE,
1799 if (error != NULL) {
1800 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1801 g_clear_error(&error);
1803 BT_ERR("Failed to set Alias");
1804 return BLUETOOTH_ERROR_INTERNAL;
1807 g_variant_unref(result);
1808 return BLUETOOTH_ERROR_NONE;
1811 int _bt_is_service_used(char *service_uuid, gboolean *used)
1814 GError *error = NULL;
1815 int ret = BLUETOOTH_ERROR_NONE;
1817 GVariant *temp = NULL;
1818 GVariantIter *iter = NULL;
1822 BT_CHECK_PARAMETER(service_uuid, return);
1823 BT_CHECK_PARAMETER(used, return);
1825 proxy = _bt_get_adapter_properties_proxy();
1826 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1828 result = g_dbus_proxy_call_sync(proxy,
1830 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1832 G_DBUS_CALL_FLAGS_NONE,
1838 if (error != NULL) {
1839 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1840 g_clear_error(&error);
1842 BT_ERR("Failed to get UUIDs");
1843 return BLUETOOTH_ERROR_INTERNAL;
1846 g_variant_get(result, "(v)", &temp);
1847 g_variant_get(temp, "as", &iter);
1850 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1851 if (strcasecmp(uuid, service_uuid) == 0) {
1856 g_variant_iter_free(iter);
1857 g_variant_unref(result);
1859 BT_DBG("Service Used? %d", *used);
1864 static gboolean __bt_get_discoverable_property(void)
1867 gboolean discoverable_v;
1868 GError *error = NULL;
1872 proxy = _bt_get_adapter_properties_proxy();
1873 retv_if(proxy == NULL, FALSE);
1875 result = g_dbus_proxy_call_sync(proxy,
1877 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1879 G_DBUS_CALL_FLAGS_NONE,
1885 if (error != NULL) {
1886 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1887 g_clear_error(&error);
1889 BT_ERR("Failed to get Discoverable property");
1890 return BLUETOOTH_ERROR_INTERNAL;
1893 g_variant_get(result, "(v)", &temp);
1894 discoverable_v = g_variant_get_boolean(temp);
1895 BT_DBG("discoverable_v:%d", discoverable_v);
1897 g_variant_unref(result);
1898 g_variant_unref(temp);
1900 return discoverable_v;
1903 int _bt_get_discoverable_mode(int *mode)
1905 gboolean discoverable;
1906 unsigned int timeout;
1908 BT_CHECK_PARAMETER(mode, return);
1910 discoverable = __bt_get_discoverable_property();
1911 timeout = _bt_get_discoverable_timeout_property();
1913 if (discoverable == TRUE) {
1915 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1917 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1919 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1921 return BLUETOOTH_ERROR_NONE;
1925 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1927 int ret = BLUETOOTH_ERROR_NONE;
1930 GError *error = NULL;
1933 #ifdef TIZEN_FEATURE_BT_DPM
1934 int discoverable_state = DPM_BT_ERROR;
1937 proxy = _bt_get_adapter_properties_proxy();
1939 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1941 #ifdef TIZEN_FEATURE_BT_DPM
1942 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1943 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
1944 discoverable_state == DPM_RESTRICTED) {
1945 if (headed_plugin_info->plugin_headed_enabled)
1946 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
1948 return BLUETOOTH_ERROR_ACCESS_DENIED;
1950 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
1951 discoverable_state == DPM_RESTRICTED) {
1952 if (headed_plugin_info->plugin_headed_enabled)
1953 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
1955 return BLUETOOTH_ERROR_ACCESS_DENIED;
1959 switch (discoverable_mode) {
1960 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1965 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1970 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1975 return BLUETOOTH_ERROR_INVALID_PARAM;
1978 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1979 discoverable_mode, timeout);
1981 result = g_dbus_proxy_call_sync(proxy,
1983 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1984 "Connectable", g_variant_new("b", pg_scan)),
1985 G_DBUS_CALL_FLAGS_NONE,
1991 if (error != NULL) {
1992 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1993 g_clear_error(&error);
1995 BT_ERR("Failed to set connectable property");
1996 return BLUETOOTH_ERROR_INTERNAL;
1998 g_variant_unref(result);
1999 result = g_dbus_proxy_call_sync(proxy,
2001 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2002 g_variant_new("b", inq_scan)),
2003 G_DBUS_CALL_FLAGS_NONE,
2009 if (error != NULL) {
2010 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2011 g_clear_error(&error);
2013 BT_ERR("Failed to set Discoverable property");
2014 return BLUETOOTH_ERROR_INTERNAL;
2016 g_variant_unref(result);
2017 result = g_dbus_proxy_call_sync(proxy,
2019 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2020 "DiscoverableTimeout", g_variant_new("u", timeout)),
2021 G_DBUS_CALL_FLAGS_NONE,
2027 if (error != NULL) {
2028 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2029 g_clear_error(&error);
2031 BT_ERR("Failed to set DiscoverableTimeout property");
2032 return BLUETOOTH_ERROR_INTERNAL;
2035 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2038 ret = __bt_set_visible_time(timeout);
2040 g_variant_unref(result);
2045 int _bt_start_discovery(void)
2048 GError *error = NULL;
2051 if (_bt_is_discovering() == TRUE) {
2052 BT_ERR("BT is already in discovering");
2053 return BLUETOOTH_ERROR_IN_PROGRESS;
2054 } else if (_bt_is_device_creating() == TRUE) {
2055 BT_ERR("Bonding device is going on");
2056 return BLUETOOTH_ERROR_DEVICE_BUSY;
2059 proxy = _bt_get_adapter_proxy();
2060 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2062 result = g_dbus_proxy_call_sync(proxy,
2065 G_DBUS_CALL_FLAGS_NONE,
2071 if (error != NULL) {
2072 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2073 g_clear_error(&error);
2075 BT_ERR("StartDiscovery failed");
2076 return BLUETOOTH_ERROR_INTERNAL;
2079 discovery_req = TRUE;
2080 cancel_by_user = FALSE;
2081 /* discovery status will be change in event */
2082 g_variant_unref(result);
2083 return BLUETOOTH_ERROR_NONE;
2086 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2090 GError *error = NULL;
2091 const gchar *disc_type;
2093 if (_bt_is_discovering() == TRUE) {
2094 BT_ERR("BT is already in discovering");
2095 return BLUETOOTH_ERROR_IN_PROGRESS;
2098 proxy = _bt_get_adapter_proxy();
2099 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2101 if (role == DISCOVERY_ROLE_BREDR)
2102 disc_type = "BREDR";
2103 else if (role == DISCOVERY_ROLE_LE)
2105 else if (role == DISCOVERY_ROLE_LE_BREDR)
2106 disc_type = "LE_BREDR";
2108 return BLUETOOTH_ERROR_INVALID_PARAM;
2110 result = g_dbus_proxy_call_sync(proxy,
2111 "StartCustomDiscovery",
2112 g_variant_new("s", disc_type),
2113 G_DBUS_CALL_FLAGS_NONE,
2119 if (error != NULL) {
2120 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2121 g_clear_error(&error);
2123 BT_ERR("StartCustomDiscovery failed");
2124 return BLUETOOTH_ERROR_INTERNAL;
2127 discovery_req = TRUE;
2128 cancel_by_user = FALSE;
2129 /* discovery status will be change in event */
2130 g_variant_unref(result);
2131 return BLUETOOTH_ERROR_NONE;
2134 int _bt_cancel_discovery(void)
2137 GError *error = NULL;
2140 if (_bt_is_discovering() == FALSE) {
2141 BT_ERR("BT is not in discovering");
2142 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
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 int ret = BLUETOOTH_ERROR_INTERNAL;
2158 if (error != NULL) {
2159 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2161 if (g_strrstr(error->message, "No discovery started"))
2162 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2164 g_clear_error(&error);
2166 BT_ERR("StopDiscovery failed");
2172 discovery_req = FALSE;
2173 cancel_by_user = TRUE;
2174 /* discovery status will be change in event */
2175 g_variant_unref(result);
2176 return BLUETOOTH_ERROR_NONE;
2179 gboolean _bt_is_discovering(void)
2181 return (is_discovering || discovery_req);
2184 gboolean _bt_is_connectable(void)
2187 GError *error = NULL;
2188 gboolean is_connectable = FALSE;
2192 proxy = _bt_get_adapter_properties_proxy();
2193 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2195 result = g_dbus_proxy_call_sync(proxy,
2197 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2199 G_DBUS_CALL_FLAGS_NONE,
2205 if (error != NULL) {
2206 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2207 g_clear_error(&error);
2209 BT_ERR("Failed to get connectable property");
2210 return BLUETOOTH_ERROR_INTERNAL;
2213 g_variant_get(result, "(v)", &temp);
2214 is_connectable = g_variant_get_boolean(temp);
2215 BT_DBG("discoverable_v:%d", is_connectable);
2217 g_variant_unref(result);
2218 g_variant_unref(temp);
2220 BT_INFO("Get connectable [%d]", is_connectable);
2221 return is_connectable;
2224 int _bt_set_connectable(gboolean is_connectable)
2227 GError *error = NULL;
2230 if (__bt_is_factory_test_mode()) {
2231 BT_ERR("Unable to set connectable in factory binary !!");
2232 return BLUETOOTH_ERROR_NOT_SUPPORT;
2235 proxy = _bt_get_adapter_properties_proxy();
2237 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2239 result = g_dbus_proxy_call_sync(proxy,
2241 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2242 g_variant_new("b", is_connectable)),
2243 G_DBUS_CALL_FLAGS_NONE,
2249 if (error != NULL) {
2250 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2251 g_clear_error(&error);
2253 BT_ERR("Failed to set connectable property");
2254 return BLUETOOTH_ERROR_INTERNAL;
2257 BT_INFO_C("### Set connectable [%d]", is_connectable);
2258 g_variant_unref(result);
2259 return BLUETOOTH_ERROR_NONE;
2262 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2265 gboolean discovering_v;
2266 GError *error = NULL;
2267 char *discovering_type = NULL;
2271 proxy = _bt_get_adapter_properties_proxy();
2272 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2274 if (discovery_type == DISCOVERY_ROLE_BREDR)
2275 discovering_type = "Discovering";
2276 else if (discovery_type == DISCOVERY_ROLE_LE)
2277 discovering_type = "LEDiscovering";
2279 result = g_dbus_proxy_call_sync(proxy,
2281 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2283 G_DBUS_CALL_FLAGS_NONE,
2289 if (error != NULL) {
2290 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2291 g_clear_error(&error);
2293 BT_ERR("Failed to get discovering property");
2294 return BLUETOOTH_ERROR_INTERNAL;
2297 g_variant_get(result, "(v)", &temp);
2298 discovering_v = g_variant_get_boolean(temp);
2299 BT_DBG("discoverable_v:%d", discovering_v);
2301 g_variant_unref(result);
2302 g_variant_unref(temp);
2304 return discovering_v;
2307 unsigned int _bt_get_discoverable_timeout_property(void)
2310 unsigned int timeout_v;
2311 GError *error = NULL;
2315 proxy = _bt_get_adapter_properties_proxy();
2316 retv_if(proxy == NULL, 0);
2318 result = g_dbus_proxy_call_sync(proxy,
2320 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2321 "DiscoverableTimeout"),
2322 G_DBUS_CALL_FLAGS_NONE,
2328 BT_ERR("Fail to get discoverable timeout");
2329 if (error != NULL) {
2330 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2331 g_clear_error(&error);
2336 g_variant_get(result, "(v)", &temp);
2337 timeout_v = g_variant_get_uint32(temp);
2338 BT_DBG("discoverable_v:%d", timeout_v);
2340 g_variant_unref(result);
2341 g_variant_unref(temp);
2346 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2348 bluetooth_device_info_t *dev_info;
2351 GByteArray *manufacturer_data = NULL;
2353 GVariantIter *char_value_iter;
2355 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2357 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2362 if (!g_strcmp0(key, "Address")) {
2363 const char *address = NULL;
2364 address = g_variant_get_string(value, NULL);
2365 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2367 } else if (!g_strcmp0(key, "Class")) {
2369 cod = g_variant_get_uint32(value);
2370 _bt_divide_device_class(&dev_info->device_class, cod);
2371 } else if (!g_strcmp0(key, "Name")) {
2372 const char *name = NULL;
2373 name = g_variant_get_string(value, NULL);
2374 /* If there is no Alias */
2375 if (strlen(dev_info->device_name.name) == 0) {
2376 g_strlcpy(dev_info->device_name.name, name,
2377 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2379 } else if (!g_strcmp0(key, "Alias")) {
2380 const char *alias = NULL;
2381 alias = g_variant_get_string(value, NULL);
2382 /* Overwrite the name */
2384 memset(dev_info->device_name.name, 0x00,
2385 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2386 g_strlcpy(dev_info->device_name.name, alias,
2387 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2389 } else if (!g_strcmp0(key, "IsAliasSet")) {
2390 dev_info->is_alias_set = g_variant_get_boolean(value);
2391 } else if (!g_strcmp0(key, "Connected")) {
2392 dev_info->connected = g_variant_get_byte(value);
2393 } else if (!g_strcmp0(key, "Paired")) {
2394 dev_info->paired = g_variant_get_boolean(value);
2395 } else if (!g_strcmp0(key, "Trusted")) {
2396 dev_info->trust = g_variant_get_boolean(value);
2397 } else if (!g_strcmp0(key, "RSSI")) {
2398 dev_info->rssi = g_variant_get_int16(value);
2399 } else if (!g_strcmp0(key, "UUIDs")) {
2405 dev_info->service_index = 0;
2406 g_variant_get(value, "as", &iter);
2407 while (g_variant_iter_loop(iter, "s", &uuid)) {
2408 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2409 parts = g_strsplit(uuid, "-", -1);
2411 if (parts == NULL || parts[0] == NULL) {
2416 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2421 dev_info->service_index = i;
2422 g_variant_iter_free(iter);
2423 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2424 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2425 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2426 manufacturer_data = g_byte_array_new();
2427 g_variant_get(value, "ay", &char_value_iter);
2428 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2429 g_byte_array_append(manufacturer_data, &char_value, 1);
2431 if (manufacturer_data) {
2432 if (manufacturer_data->len > 0)
2433 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2435 g_variant_iter_free(char_value_iter);
2436 g_byte_array_free(manufacturer_data, TRUE);
2443 static void __bt_extract_device_info(GVariantIter *iter,
2446 bluetooth_device_info_t *dev_info = NULL;
2447 char *object_path = NULL;
2448 GVariantIter *interface_iter;
2449 GVariantIter *svc_iter;
2450 char *interface_str = NULL;
2452 /* Parse the signature: oa{sa{sv}}} */
2453 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2456 if (object_path == NULL)
2459 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2460 &interface_str, &svc_iter)) {
2461 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2462 BT_DBG("Found a device: %s", object_path);
2463 dev_info = __bt_parse_device_info(svc_iter);
2465 if (dev_info->paired == TRUE) {
2466 g_array_append_vals(*dev_list, dev_info,
2467 sizeof(bluetooth_device_info_t));
2471 g_free(interface_str);
2472 g_variant_iter_free(svc_iter);
2480 int _bt_get_bonded_devices(GArray **dev_list)
2483 GDBusConnection *conn;
2484 GDBusProxy *manager_proxy;
2485 GVariant *result = NULL;
2486 GVariantIter *iter = NULL;
2487 GError *error = NULL;
2489 conn = _bt_gdbus_get_system_gconn();
2490 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2492 manager_proxy = _bt_get_manager_proxy();
2493 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2495 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2497 G_DBUS_CALL_FLAGS_NONE,
2503 if (error != NULL) {
2504 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2505 g_clear_error(&error);
2507 BT_ERR("Failed to Failed to GetManagedObjects");
2508 return BLUETOOTH_ERROR_INTERNAL;
2511 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2512 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2514 __bt_extract_device_info(iter, dev_list);
2515 g_variant_iter_free(iter);
2516 g_variant_unref(result);
2519 return BLUETOOTH_ERROR_NONE;
2522 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2525 GDBusConnection *conn;
2526 GDBusProxy *manager_proxy;
2527 GVariant *result = NULL;
2528 GVariant *result1 = NULL;
2529 GVariantIter *iter = NULL;
2530 GError *error = NULL;
2531 char *object_path = NULL;
2532 GVariantIter *interface_iter;
2533 char *interface_str = NULL;
2534 GDBusProxy *device_proxy = NULL;
2535 gboolean is_connected = FALSE;
2537 conn = _bt_gdbus_get_system_gconn();
2538 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2540 manager_proxy = _bt_get_manager_proxy();
2541 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2543 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2545 G_DBUS_CALL_FLAGS_NONE,
2551 if (error != NULL) {
2552 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2553 g_clear_error(&error);
2556 BT_ERR("Failed to Failed to GetManagedObjects");
2557 return BLUETOOTH_ERROR_INTERNAL;
2560 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2561 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2563 /* Parse the signature: oa{sa{sv}}} */
2564 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2565 if (object_path == NULL)
2568 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2569 &interface_str, NULL)) {
2570 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2571 BT_DBG("Found a device: %s", object_path);
2572 g_free(interface_str);
2574 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2575 NULL, BT_BLUEZ_NAME,
2576 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2578 if (device_proxy == NULL) {
2579 BT_DBG("Device don't have this service");
2583 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2584 g_variant_new("(s)", profile_uuid),
2585 G_DBUS_CALL_FLAGS_NONE,
2590 if (result1 == NULL) {
2591 BT_ERR("Error occured in Proxy call");
2593 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2594 g_error_free(error);
2597 g_object_unref(device_proxy);
2600 g_variant_get(result1, "(b)", &is_connected);
2602 if (is_connected == TRUE) {
2603 char address[BT_ADDRESS_STRING_SIZE];
2604 bluetooth_device_address_t *addr = NULL;
2606 _bt_convert_device_path_to_address(object_path, address);
2608 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2609 _bt_convert_addr_string_to_type(addr->addr, address);
2611 g_array_append_vals(*addr_list, addr,
2612 sizeof(bluetooth_device_address_t));
2615 g_variant_unref(result1);
2616 g_object_unref(device_proxy);
2623 g_variant_unref(result);
2624 g_variant_iter_free(iter);
2627 return BLUETOOTH_ERROR_NONE;
2630 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2631 bluetooth_device_info_t *dev_info)
2633 char *object_path = NULL;
2634 GDBusProxy *adapter_proxy;
2635 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2636 int ret = BLUETOOTH_ERROR_NONE;
2638 BT_CHECK_PARAMETER(device_address, return);
2639 BT_CHECK_PARAMETER(dev_info, return);
2641 adapter_proxy = _bt_get_adapter_proxy();
2642 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2644 _bt_convert_addr_type_to_string(address, device_address->addr);
2646 object_path = _bt_get_device_object_path(address);
2648 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2650 ret = __bt_get_bonded_device_info(object_path, dev_info);
2651 g_free(object_path);
2656 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2658 char *object_path = NULL;
2659 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2660 gboolean alias_set = FALSE;
2662 GDBusConnection *conn;
2663 GDBusProxy *device_proxy;
2664 GError *error = NULL;
2665 GVariant *result = NULL;
2666 GVariant *temp = NULL;
2669 BT_CHECK_PARAMETER(device_address, return);
2670 BT_CHECK_PARAMETER(is_alias_set, return);
2672 _bt_convert_addr_type_to_string(address, device_address->addr);
2674 object_path = _bt_get_device_object_path(address);
2675 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2677 conn = _bt_gdbus_get_system_gconn();
2679 g_free(object_path);
2680 return BLUETOOTH_ERROR_INTERNAL;
2683 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2687 BT_PROPERTIES_INTERFACE,
2689 if (device_proxy == NULL) {
2690 g_free(object_path);
2691 return BLUETOOTH_ERROR_INTERNAL;
2694 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2695 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2696 G_DBUS_CALL_FLAGS_NONE,
2702 BT_ERR("Error occured in Proxy call");
2703 if (error != NULL) {
2704 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2705 g_error_free(error);
2707 g_object_unref(device_proxy);
2708 g_free(object_path);
2709 return BLUETOOTH_ERROR_INTERNAL;
2712 g_variant_get(result, "(v)", &temp);
2713 alias_set = g_variant_get_boolean(temp);
2714 *is_alias_set = alias_set;
2715 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2716 g_variant_unref(temp);
2717 g_variant_unref(result);
2718 g_object_unref(device_proxy);
2720 g_free(object_path);
2722 return BLUETOOTH_ERROR_NONE;
2725 int _bt_get_timeout_value(int *timeout)
2727 time_t current_time;
2730 /* Take current time */
2731 time(¤t_time);
2732 time_diff = difftime(current_time, visible_timer.start_time);
2734 BT_DBG("Time diff = %d\n", time_diff);
2736 *timeout = visible_timer.timeout - time_diff;
2738 return BLUETOOTH_ERROR_NONE;
2741 int _bt_set_le_privacy(gboolean set_privacy)
2744 GError *error = NULL;
2745 GVariant *result = NULL;
2747 if (__bt_is_factory_test_mode()) {
2748 BT_ERR("Unable to set le privacy in factory binary !!");
2749 return BLUETOOTH_ERROR_NOT_SUPPORT;
2752 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2753 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2754 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2757 proxy = _bt_get_adapter_proxy();
2758 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2760 result = g_dbus_proxy_call_sync(proxy,
2762 g_variant_new("(b)", set_privacy),
2763 G_DBUS_CALL_FLAGS_NONE,
2769 if (error != NULL) {
2770 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2771 g_clear_error(&error);
2773 BT_ERR("Failed to SetLePrivacy");
2774 return BLUETOOTH_ERROR_INTERNAL;
2777 g_variant_unref(result);
2778 BT_INFO("SetLePrivacy as %d", set_privacy);
2779 return BLUETOOTH_ERROR_NONE;
2782 int _bt_set_le_static_random_address(gboolean is_enable)
2785 GError *error = NULL;
2786 GVariant *result = NULL;
2788 if (__bt_is_factory_test_mode()) {
2789 BT_ERR("Unable to set le random address in factory binary !!");
2790 return BLUETOOTH_ERROR_NOT_SUPPORT;
2793 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2794 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2795 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2798 proxy = _bt_get_adapter_proxy();
2799 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2801 result = g_dbus_proxy_call_sync(proxy,
2802 "SetLeStaticRandomAddress",
2803 g_variant_new("(b)", is_enable),
2804 G_DBUS_CALL_FLAGS_NONE,
2810 if (error != NULL) {
2811 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2812 g_clear_error(&error);
2814 BT_ERR("Failed to SetLeStaticRandomAddress");
2815 return BLUETOOTH_ERROR_INTERNAL;
2818 g_variant_unref(result);
2819 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2820 return BLUETOOTH_ERROR_NONE;
2823 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2826 GError *error = NULL;
2830 GVariantBuilder *builder;
2832 BT_CHECK_PARAMETER(m_data, return);
2834 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2835 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2836 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2839 proxy = _bt_get_adapter_proxy();
2840 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2842 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2844 for (i = 0; i < (m_data->data_len) + 2; i++)
2845 g_variant_builder_add(builder, "y", m_data->data[i]);
2847 val = g_variant_new("(ay)", builder);
2849 result = g_dbus_proxy_call_sync(proxy,
2850 "SetManufacturerData",
2852 G_DBUS_CALL_FLAGS_NONE,
2856 g_variant_builder_unref(builder);
2858 if (error != NULL) {
2859 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2860 g_clear_error(&error);
2862 BT_ERR("Failed to SetManufacturerData");
2864 return BLUETOOTH_ERROR_INTERNAL;
2866 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2868 for (i = 0; i < (m_data->data_len) + 2; i++)
2869 g_variant_builder_add(builder, "y", m_data->data[i]);
2871 val = g_variant_new("(ay)", builder);
2873 _bt_send_event(BT_ADAPTER_EVENT,
2874 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2877 BT_INFO("Set manufacturer data");
2879 g_variant_builder_unref(builder);
2880 g_variant_unref(result);
2882 return BLUETOOTH_ERROR_NONE;
2886 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2888 int result = BLUETOOTH_ERROR_NONE;
2889 bt_service_alarm_t *alarm = NULL;
2891 if (!call_back || !alarm_id)
2892 return BLUETOOTH_ERROR_INVALID_PARAM;
2894 if (!alarm_mgr.is_alarm_initialized) {
2895 result = alarmmgr_init("bt-service");
2897 BT_ERR("Failed to initialize alarm = %d", result);
2898 result = BLUETOOTH_ERROR_INTERNAL;
2901 result = alarmmgr_set_cb(alarm_cb, NULL);
2903 BT_ERR("Failed to set the callback = %d", result);
2904 result = BLUETOOTH_ERROR_INTERNAL;
2907 alarm_mgr.is_alarm_initialized = TRUE;
2910 alarm = g_malloc0(sizeof(bt_service_alarm_t));
2912 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2914 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
2917 BT_ERR("Failed to create alarm error = %d", result);
2918 result = BLUETOOTH_ERROR_INTERNAL;
2922 alarm->alarm_id = *alarm_id;
2923 alarm->callback = call_back;
2924 alarm->user_data = user_data;
2926 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
2927 result = BLUETOOTH_ERROR_NONE;
2932 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
2935 bt_service_alarm_t *p_data;
2936 bt_set_alarm_cb callback = NULL;
2937 void *user_data = NULL;
2939 node = g_list_find_custom(alarm_mgr.g_alarm_list,
2940 GINT_TO_POINTER(alarm_id), compare_alarm);
2944 p_data = (bt_service_alarm_t *)node->data;
2945 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
2951 callback = p_data->callback;
2952 user_data = p_data->user_data;
2956 callback(alarm_id, user_data);
2961 int _bt_service_remove_alarm(alarm_id_t alarm_id)
2964 bt_service_alarm_t *p_data;
2965 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
2968 alarmmgr_remove_alarm(alarm_id);
2969 p_data = (bt_service_alarm_t *)list->data;
2970 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
2977 gint compare_alarm(gconstpointer list_data, gconstpointer data)
2980 alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
2982 alarm_id_t alarm_id = (alarm_id_t)data;
2984 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
2986 if (p_data->alarm_id == alarm_id)
2992 static void alarm_data_free(void *data)
2994 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
2999 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3003 int function = (int)(uintptr_t)user_data;
3005 int function = (int)user_data;
3009 case BT_ENABLE_ADAPTER:
3010 result = _bt_enable_adapter();
3011 if (result != BLUETOOTH_ERROR_NONE) {
3012 BT_ERR("_bt_enable_adapter is failed");
3013 /* Send enabled event to API */
3014 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3015 g_variant_new("(i)", result));
3018 case BT_DISABLE_ADAPTER:
3019 result = _bt_disable_adapter();
3020 if (result != BLUETOOTH_ERROR_NONE) {
3021 BT_ERR("_bt_disable_adapter is failed");
3022 /* Send disabled event to API */
3023 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3024 g_variant_new("(i)", result));
3028 BT_ERR("function is NOT matched");
3035 int _bt_adapter_request_delayed(int function)
3040 case BT_ENABLE_ADAPTER:
3041 ret = _bt_enable_adapter_check_status();
3042 if (ret == BLUETOOTH_ERROR_NONE)
3043 _bt_adapter_set_status(BT_ACTIVATING);
3048 case BT_DISABLE_ADAPTER:
3049 ret = _bt_disable_adapter_check_status();
3050 if (ret == BLUETOOTH_ERROR_NONE)
3051 _bt_adapter_set_status(BT_DEACTIVATING);
3057 BT_ERR("function is NOT matched");
3058 return BLUETOOTH_ERROR_INTERNAL;
3062 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3064 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3067 return BLUETOOTH_ERROR_NONE;
3070 int _bt_get_enable_timer_id(void)