2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <syspopup_caller.h>
27 #include <eventsystem.h>
28 #include <bundle_internal.h>
31 #include "bluetooth-api.h"
32 #include "bt-internal-types.h"
33 #include "bt-service-common.h"
34 #include "bt-service-event.h"
35 #include "bt-service-adapter.h"
36 #include "bt-service-util.h"
37 #include "bt-service-network.h"
38 #include "bt-service-obex-server.h"
39 #include "bt-service-opp-client.h"
40 #include "bt-service-map-client.h"
41 #include "bt-service-agent.h"
42 #include "bt-service-main.h"
43 #include "bt-service-avrcp.h"
44 #include "bt-service-device.h"
45 #ifdef TIZEN_FEATURE_BT_DPM
46 #include "bt-service-dpm.h"
56 bt_adapter_timer_t visible_timer = {0, };
60 bt_set_alarm_cb callback;
65 gboolean is_alarm_initialized;
67 } bt_service_alarm_mgr_t;
69 static bt_service_alarm_mgr_t alarm_mgr = {0, };
71 static gboolean is_discovering;
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 #ifndef 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 #ifndef 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 #ifndef TIZEN_PROFILE_WEARABLE
215 #ifdef TIZEN_FEATURE_BT_DPM
216 int discoverable_state = DPM_BT_ERROR;
220 __bt_visibility_alarm_remove();
222 visible_timer.timeout = timeout;
224 #ifndef TIZEN_PROFILE_WEARABLE
225 #ifdef TIZEN_FEATURE_BT_DPM
226 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
227 if (discoverable_state != DPM_RESTRICTED) {
229 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
230 BT_ERR("Set vconf failed");
231 #ifdef TIZEN_FEATURE_BT_DPM
238 return BLUETOOTH_ERROR_NONE;
240 result = _bt_service_set_alarm(visible_timer.timeout,
241 __bt_visibility_alarm_cb, NULL, &alarm_id);
242 if (result != BLUETOOTH_ERROR_NONE)
243 return BLUETOOTH_ERROR_INTERNAL;
244 visible_timer.alarm_id = alarm_id;
245 /* Take start time */
246 time(&(visible_timer.start_time));
247 visible_timer.event_id = g_timeout_add_seconds(1,
248 __bt_timeout_handler, NULL);
250 return BLUETOOTH_ERROR_NONE;
253 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
260 ret_if(value == NULL);
263 dev->service_index = 0;
265 g_variant_get(value, "as", &iter);
266 while (g_variant_iter_loop(iter, "s", &uuid)) {
267 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
268 parts = g_strsplit(uuid, "-", -1);
270 if (parts == NULL || parts[0] == NULL) {
275 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
278 dev->service_index++;
281 g_variant_iter_free(iter);
284 static int __bt_get_bonded_device_info(gchar *device_path,
285 bluetooth_device_info_t *dev_info)
287 GError *error = NULL;
288 GDBusProxy *device_proxy;
289 gchar *address = NULL;
291 unsigned int cod = 0;
293 gboolean trust = FALSE;
294 gboolean paired = FALSE;
295 guchar connected = 0;
296 GByteArray *manufacturer_data = NULL;
298 GDBusConnection *conn;
300 GVariantIter *property_iter;
304 GVariantIter *char_value_iter;
306 BT_CHECK_PARAMETER(device_path, return);
307 BT_CHECK_PARAMETER(dev_info, return);
309 conn = _bt_gdbus_get_system_gconn();
310 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
312 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
316 BT_PROPERTIES_INTERFACE,
319 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
321 result = g_dbus_proxy_call_sync(device_proxy,
323 g_variant_new("(s)", BT_DEVICE_INTERFACE),
324 G_DBUS_CALL_FLAGS_NONE,
330 BT_ERR("Error occured in Proxy call");
332 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
333 g_clear_error(&error);
335 g_object_unref(device_proxy);
336 return BLUETOOTH_ERROR_INTERNAL;
339 g_object_unref(device_proxy);
341 g_variant_get(result, "(a{sv})", &property_iter);
343 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
344 if (!g_strcmp0(key, "Paired")) {
345 paired = g_variant_get_boolean(value);
346 } else if (!g_strcmp0(key, "Address")) {
347 g_variant_get(value, "s", &address);
348 } else if (!g_strcmp0(key, "Alias")) {
349 g_variant_get(value, "s", &name);
350 } else if (!g_strcmp0(key, "Name")) {
352 g_variant_get(value, "s", &name);
353 } else if (!g_strcmp0(key, "Class")) {
354 cod = g_variant_get_uint32(value);
355 } else if (!g_strcmp0(key, "Connected")) {
356 connected = g_variant_get_byte(value);
357 } else if (!g_strcmp0(key, "Trusted")) {
358 trust = g_variant_get_boolean(value);
359 } else if (!g_strcmp0(key, "RSSI")) {
360 rssi = g_variant_get_int16(value);
361 } else if (!g_strcmp0(key, "UUIDs")) {
362 __bt_get_service_list(value, dev_info);
363 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
364 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
365 } else if (!g_strcmp0(key, "ManufacturerData")) {
366 manufacturer_data = g_byte_array_new();
367 g_variant_get(value, "ay", &char_value_iter);
368 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
369 g_byte_array_append(manufacturer_data, &char_value, 1);
371 g_variant_iter_free(char_value_iter);
373 if (manufacturer_data) {
374 if (manufacturer_data->len > 0) {
375 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
376 manufacturer_data->len);
379 g_byte_array_free(manufacturer_data, TRUE);
382 g_variant_iter_free(property_iter);
384 BT_DBG("trust: %d, paired: %d", trust, paired);
386 g_variant_unref(result);
388 if ((paired == FALSE) && (trust == FALSE)) {
391 return BLUETOOTH_ERROR_NOT_PAIRED;
394 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
397 _bt_divide_device_class(&dev_info->device_class, cod);
399 g_strlcpy(dev_info->device_name.name, name,
400 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
402 dev_info->rssi = rssi;
403 dev_info->trust = trust;
404 dev_info->paired = paired;
405 dev_info->connected = connected;
406 ret = BLUETOOTH_ERROR_NONE;
413 void _bt_set_discovery_status(gboolean mode)
415 is_discovering = mode;
418 void _bt_set_cancel_by_user(gboolean value)
420 cancel_by_user = value;
423 gboolean _bt_get_cancel_by_user(void)
425 return cancel_by_user;
428 void _bt_adapter_set_status(bt_status_t status)
430 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
431 adapter_status = status;
434 bt_status_t _bt_adapter_get_status(void)
436 return adapter_status;
439 void _bt_adapter_set_le_status(bt_le_status_t status)
441 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
442 adapter_le_status = status;
445 bt_le_status_t _bt_adapter_get_le_status(void)
447 return adapter_le_status;
451 void _bt_set_le_intended_status(gboolean value)
453 is_le_intended = value;
456 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
458 char *phone_name = NULL;
464 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
465 phone_name = vconf_keynode_get_str(node);
467 if (phone_name && strlen(phone_name) != 0) {
468 if (!g_utf8_validate(phone_name, -1,
469 (const char **)&ptr))
472 _bt_set_local_name(phone_name);
477 static void __bt_set_local_name(void)
479 bluetooth_device_name_t local_name;
480 char *phone_name = NULL;
484 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
485 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
486 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
491 if (strlen(phone_name) != 0) {
492 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
495 _bt_set_local_name(phone_name);
501 static int __bt_set_enabled(void)
503 int adapter_status = BT_ADAPTER_DISABLED;
504 int result = BLUETOOTH_ERROR_NONE;
507 BT_DBG("g_source is removed");
508 g_source_remove(timer_id);
512 _bt_check_adapter(&adapter_status);
514 if (adapter_status == BT_ADAPTER_DISABLED) {
515 BT_ERR("Bluetoothd is not running");
516 return BLUETOOTH_ERROR_INTERNAL;
519 #if defined(TIZEN_PROFILE_MOBILE) || defined(TIZEN_PROFILE_IVI)
520 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
521 if (_bt_set_discoverable_mode(
522 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
523 BT_ERR("Set connectable mode failed");
525 #ifdef TIZEN_PROFILE_TV
526 if (_bt_set_discoverable_mode(
527 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
528 BT_ERR("Fail to set discoverable mode");
532 /* Update Bluetooth Status to notify other modules */
533 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
534 BT_ERR("Set vconf failed\n");
536 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
537 BT_ERR("Set vconf failed\n");
539 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
540 EVT_VAL_BT_ON) != ES_R_OK)
541 BT_ERR("Fail to set value");
543 /* Send enabled event to API */
544 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
545 g_variant_new("(i)", result));
547 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
548 _bt_audio_start_auto_connect(FALSE);
551 __bt_set_local_name();
552 _bt_set_discovery_status(FALSE);
554 return BLUETOOTH_ERROR_NONE;
557 void _bt_set_disabled(int result)
559 int power_off_status = 0;
562 int pm_ignore_mode = 0;
564 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
565 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
567 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
569 /* Update the vconf BT status in normal Deactivation case only */
570 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
571 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
573 BT_DBG("Update vconf for BT normal Deactivation");
575 if (result == BLUETOOTH_ERROR_TIMEOUT)
576 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
577 BT_ERR("Set vconf failed");
579 /* Update Bluetooth Status to notify other modules */
580 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
581 BT_ERR("Set vconf failed");
583 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
584 EVT_VAL_BT_OFF) != ES_R_OK)
585 BT_ERR("Fail to set value");
588 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
589 BT_ERR("Set vconf failed\n");
591 _bt_cancel_queued_transfers();
592 _bt_adapter_set_status(BT_DEACTIVATED);
593 _bt_set_discovery_status(FALSE);
595 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
596 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
598 /* Send disabled event */
599 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
600 g_variant_new("(i)", result));
601 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
605 BT_INFO("Adapter disabled");
608 static int __bt_set_le_enabled(void)
611 int result = BLUETOOTH_ERROR_NONE;
614 /* Update Bluetooth Status to notify other modules */
615 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
616 BT_ERR("Set vconf failed\n");
618 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
619 EVT_VAL_BT_LE_ON) != ES_R_OK)
620 BT_ERR("Fail to set value");
622 /* Send enabled event to API */
624 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
625 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
627 status = _bt_adapter_get_status();
628 if (status == BT_DEACTIVATED) {
629 BT_INFO("BREDR is off, turn off PSCAN");
630 _bt_set_connectable(FALSE);
632 if (le_timer_id > 0) {
633 g_source_remove(le_timer_id);
637 /* Send enabled event to API */
638 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
639 g_variant_new("(i)", result));
641 __bt_set_local_name();
644 return BLUETOOTH_ERROR_NONE;
647 void _bt_set_le_disabled(int result)
649 int power_off_status;
652 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
653 BT_DBG("ret : %d", ret);
654 BT_DBG("power_off_status : %d", power_off_status);
656 /* Update Bluetooth Status to notify other modules */
657 BT_DBG("Update vconf for BT LE normal Deactivation");
658 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
659 BT_ERR("Set vconf failed\n");
660 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
662 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
663 EVT_VAL_BT_LE_OFF) != ES_R_OK)
664 BT_ERR("Fail to set value");
666 /* Send disabled event */
667 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
668 g_variant_new("(i)", result));
671 void *_bt_get_adapter_agent(void)
673 return adapter_agent;
676 int _bt_enable_core(void)
680 GError *error = NULL;
682 proxy = __bt_get_core_proxy();
683 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
685 /* Clean up the process */
686 result = g_dbus_proxy_call_sync(proxy,
689 G_DBUS_CALL_FLAGS_NONE,
696 BT_ERR("Bt core call failed(Error: %s)", error->message);
697 g_clear_error(&error);
699 BT_ERR("Bt core call failed");
700 return BLUETOOTH_ERROR_INTERNAL;
703 g_variant_unref(result);
704 return BLUETOOTH_ERROR_NONE;
707 #if defined(TIZEN_FEATURE_FLIGHTMODE_ENABLED) || (!defined(TIZEN_PROFILE_WEARABLE))
708 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
710 gboolean flight_mode = FALSE;
711 int power_saving_mode = 0;
714 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
715 type = vconf_keynode_get_type(node);
716 if (type == VCONF_TYPE_BOOL) {
717 flight_mode = vconf_keynode_get_bool(node);
718 if (flight_mode != TRUE) {
719 BT_ERR("Ignore the event");
722 } else if (type == VCONF_TYPE_INT) {
723 power_saving_mode = vconf_keynode_get_int(node);
724 if (power_saving_mode != 2) {
725 BT_ERR("Ignore the event");
729 BT_ERR("Invaild vconf key type : %d", type);
737 void _bt_service_register_vconf_handler(void)
741 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
742 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
743 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
744 BT_ERR("Unable to register key handler");
746 BT_DBG("Telephony is disabled");
749 #ifndef TIZEN_PROFILE_WEARABLE
750 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
751 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
752 BT_ERR("Unable to register key handler");
756 void _bt_service_unregister_vconf_handler(void)
760 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
761 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
762 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
765 #ifndef TIZEN_PROFILE_WEARABLE
766 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
767 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
771 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
773 const char *bt_status = NULL;
774 const char *bt_le_status = NULL;
775 BT_DBG("bt state set event(%s) received", event_name);
777 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
778 BT_DBG("bt_state: (%s)", bt_status);
780 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
781 BT_DBG("bt_state: (%s)", bt_le_status);
784 void _bt_handle_adapter_added(void)
788 bt_le_status_t le_status;
792 BT_DBG("g_source is removed");
793 g_source_remove(timer_id);
798 status = _bt_adapter_get_status();
799 le_status = _bt_adapter_get_le_status();
800 BT_DBG("status : %d", status);
801 BT_DBG("le_status : %d", le_status);
803 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
804 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
805 if (!adapter_agent) {
806 BT_ERR("Fail to register agent");
810 if (adapter_agent == NULL) {
811 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
812 if (!adapter_agent) {
813 BT_ERR("Fail to register agent");
819 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
820 BT_ERR("Fail to register media player");
822 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
823 BT_ERR("Fail to init obex server");
825 #ifdef TIZEN_BT_PAN_NAP_ENABLED
826 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
827 BT_ERR("Fail to activate network");
830 /* add the vconf noti handler */
831 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
832 __bt_phone_name_changed_cb, NULL);
834 BT_ERR("Unable to register key handler");
836 if (le_status == BT_LE_ACTIVATING ||
837 status == BT_ACTIVATING) {
838 __bt_set_le_enabled();
839 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
842 if (status == BT_ACTIVATING) {
844 _bt_adapter_set_status(BT_ACTIVATED);
848 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
849 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
850 BT_ERR("Fail to register system event");
854 void _bt_handle_adapter_removed(void)
858 _bt_adapter_set_status(BT_DEACTIVATED);
860 __bt_visibility_alarm_remove();
862 if (alarm_mgr.is_alarm_initialized == TRUE) {
864 alarm_mgr.is_alarm_initialized = FALSE;
865 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
866 alarm_mgr.g_alarm_list = NULL;
869 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
870 _bt_audio_stop_auto_connect();
873 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
874 (vconf_callback_fn)__bt_phone_name_changed_cb);
876 ERR("vconf_ignore_key_changed failed\n");
878 /* unregister all the services/servers/profiles registered on bluez-adapter
879 once adapter is removed, reinitializing of the state-varaibles becomes
881 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
882 BT_ERR("Fail to unregister obex server");
884 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
885 BT_ERR("Fail to unregister media player");
887 /* Other unregister APIs should be placed here */
890 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
891 _bt_destroy_agent(adapter_agent);
892 adapter_agent = NULL;
894 if (is_recovery_mode == TRUE) {
895 /* Send disabled event */
896 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
898 /* Will recover BT by bt-core, so set the mode as activating */
899 _bt_adapter_set_status(BT_ACTIVATING);
900 is_recovery_mode = FALSE;
902 _bt_reliable_terminate_service(NULL);
905 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
908 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
909 BT_ERR("Fail to unregister system event");
912 static gboolean __bt_enable_timeout_cb(gpointer user_data)
916 GError *error = NULL;
920 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
922 BT_ERR("EnableAdapter is failed");
924 proxy = __bt_get_core_proxy();
928 /* Clean up the process */
929 result = g_dbus_proxy_call_sync(proxy,
932 G_DBUS_CALL_FLAGS_NONE,
939 BT_ERR("Bt core call failed(Error: %s)", error->message);
940 g_clear_error(&error);
942 BT_ERR("Bt core call failed");
947 g_variant_unref(result);
948 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
950 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
951 _bt_terminate_service(NULL);
957 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
961 GError *error = NULL;
965 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
967 BT_ERR("EnableAdapterLE is failed");
969 proxy = __bt_get_core_proxy();
973 /* Clean up the process */
974 result = g_dbus_proxy_call_sync(proxy,
977 G_DBUS_CALL_FLAGS_NONE,
984 BT_ERR("Bt core call failed(Error: %s)", error->message);
985 g_clear_error(&error);
987 BT_ERR("Bt core call failed");
991 g_variant_unref(result);
992 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
994 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
996 if (_bt_adapter_get_status() == BT_DEACTIVATED)
997 _bt_terminate_service(NULL);
1002 void _bt_adapter_start_le_enable_timer(void)
1004 if (le_timer_id > 0) {
1005 g_source_remove(le_timer_id);
1009 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1010 __bt_enable_le_timeout_cb, NULL);
1015 void _bt_adapter_start_enable_timer(void)
1018 g_source_remove(timer_id);
1022 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1023 __bt_enable_timeout_cb, NULL);
1028 #ifdef TIZEN_PROFILE_TV
1029 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1034 _bt_adapter_set_status(BT_ACTIVATED);
1040 int _bt_enable_adapter_check_status(void)
1042 bt_status_t status = _bt_adapter_get_status();
1043 bt_le_status_t le_status = _bt_adapter_get_le_status();
1047 if (status == BT_ACTIVATING) {
1048 BT_ERR("Enabling in progress");
1049 return BLUETOOTH_ERROR_IN_PROGRESS;
1052 if (status == BT_ACTIVATED) {
1053 BT_ERR("Already enabled");
1054 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1057 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1058 BT_ERR("Disabling in progress");
1059 return BLUETOOTH_ERROR_DEVICE_BUSY;
1062 return BLUETOOTH_ERROR_NONE;
1065 int _bt_enable_adapter(void)
1068 GError *error = NULL;
1070 GVariant *result = NULL;
1071 bt_status_t status = _bt_adapter_get_status();
1072 bt_le_status_t le_status = _bt_adapter_get_le_status();
1076 if (status == BT_ACTIVATING) {
1077 BT_ERR("Enabling in progress");
1078 return BLUETOOTH_ERROR_IN_PROGRESS;
1081 if (status == BT_ACTIVATED) {
1082 BT_ERR("Already enabled");
1083 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1086 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1087 BT_ERR("Disabling in progress");
1088 return BLUETOOTH_ERROR_DEVICE_BUSY;
1091 _bt_adapter_set_status(BT_ACTIVATING);
1093 #ifdef TIZEN_PROFILE_TV
1095 int adapter_status = BT_ADAPTER_DISABLED;
1097 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1098 BT_ERR("Set vconf failed");
1100 _bt_check_adapter(&adapter_status);
1101 if (adapter_status == BT_ADAPTER_ENABLED) {
1102 g_idle_add(__bt_adapter_enabled_cb, NULL);
1103 _bt_adapter_start_enable_timer();
1104 return BLUETOOTH_ERROR_NONE;
1109 proxy = __bt_get_core_proxy();
1111 return BLUETOOTH_ERROR_INTERNAL;
1113 if (le_status == BT_LE_ACTIVATED) {
1114 BT_INFO("LE Already enabled. Just turn on PSCAN");
1115 ret = _bt_set_connectable(TRUE);
1116 if (ret == BLUETOOTH_ERROR_NONE)
1117 _bt_adapter_set_status(BT_ACTIVATED);
1119 return BLUETOOTH_ERROR_INTERNAL;
1122 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1124 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1127 BT_ERR("EnableAdapterLe failed: %s", error->message);
1128 _bt_adapter_set_status(BT_DEACTIVATED);
1129 g_clear_error(&error);
1131 result = g_dbus_proxy_call_sync(proxy,
1134 G_DBUS_CALL_FLAGS_NONE,
1139 if (error != NULL) {
1140 BT_ERR("Bt core call failed(Error: %s)", error->message);
1141 g_clear_error(&error);
1143 g_variant_unref(result);
1144 #ifndef TIZEN_FEATURE_BT_USB_DONGLE
1145 /* Terminate myself */
1146 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1148 return BLUETOOTH_ERROR_INTERNAL;
1150 g_variant_unref(result);
1151 if (le_status == BT_LE_ACTIVATED)
1154 _bt_adapter_start_enable_timer();
1156 return BLUETOOTH_ERROR_NONE;
1159 static gboolean __bt_disconnect_all(void)
1162 GDBusConnection *conn;
1163 GDBusProxy *dev_proxy;
1164 gboolean ret = FALSE;
1166 GError *error = NULL;
1167 GArray *device_list;
1168 bluetooth_device_info_t info;
1170 char *device_path = NULL;
1171 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1176 conn = _bt_gdbus_get_system_gconn();
1178 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1180 if (_bt_get_bonded_devices(&device_list)
1181 != BLUETOOTH_ERROR_NONE) {
1182 g_array_free(device_list, TRUE);
1186 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1188 for (i = 0; i < size; i++) {
1190 info = g_array_index(device_list,
1191 bluetooth_device_info_t, i);
1193 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1194 BT_DBG("Found Connected device");
1195 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1196 device_path = _bt_get_device_object_path(address);
1197 if (device_path == NULL)
1200 BT_DBG("Disconnecting : %s", device_path);
1202 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1206 BT_DEVICE_INTERFACE,
1209 if (dev_proxy == NULL)
1212 result = g_dbus_proxy_call_sync(dev_proxy,
1215 G_DBUS_CALL_FLAGS_NONE,
1221 if (error != NULL) {
1222 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1223 g_clear_error(&error);
1225 BT_ERR("Disconnect call failed");
1226 g_object_unref(dev_proxy);
1230 g_variant_unref(result);
1231 g_object_unref(dev_proxy);
1235 g_array_free(device_list, TRUE);
1241 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1244 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1250 int _bt_disable_cb(void)
1258 GError *error = NULL;
1260 _bt_adapter_set_status(BT_DEACTIVATING);
1262 bt_le_status_t le_status;
1263 le_status = _bt_adapter_get_le_status();
1264 BT_DBG("le_status : %d", le_status);
1265 if (le_status == BT_LE_ACTIVATED) {
1266 BT_INFO("LE is enabled. Just turn off PSCAN");
1268 if (_bt_is_discovering())
1269 _bt_cancel_discovery();
1271 if (_bt_is_connectable() == FALSE) {
1272 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1274 ret = _bt_set_connectable(FALSE);
1275 if (ret != BLUETOOTH_ERROR_NONE) {
1276 BT_ERR("_bt_set_connectable fail!");
1277 _bt_adapter_set_status(BT_ACTIVATED);
1278 return BLUETOOTH_ERROR_INTERNAL;
1283 proxy = __bt_get_core_proxy();
1284 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1286 result = g_dbus_proxy_call_sync(proxy,
1289 G_DBUS_CALL_FLAGS_NONE,
1295 if (error != NULL) {
1296 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1297 g_clear_error(&error);
1299 BT_ERR("Failed to DisableAdapter");
1300 _bt_adapter_set_status(BT_ACTIVATED);
1301 return BLUETOOTH_ERROR_INTERNAL;
1304 g_variant_unref(result);
1305 return BLUETOOTH_ERROR_NONE;
1308 int _bt_disable_adapter_check_status(void)
1310 bt_status_t status = _bt_adapter_get_status();
1314 if (status == BT_DEACTIVATING) {
1315 BT_DBG("Disabling in progress");
1316 return BLUETOOTH_ERROR_IN_PROGRESS;
1319 if (status == BT_DEACTIVATED) {
1320 BT_DBG("Already disabled");
1321 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1324 return BLUETOOTH_ERROR_NONE;
1327 int _bt_disable_adapter(void)
1332 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1333 BT_DBG("Disabling in progress");
1334 return BLUETOOTH_ERROR_IN_PROGRESS;
1337 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1338 BT_DBG("Already disabled");
1339 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1343 g_source_remove(timer_id);
1346 /* unregister all the services/servers/profiles registered on bluez-adapter
1347 once adapter is removed, reinitializing of the state-varaibles becomes
1349 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1350 BT_ERR("Fail to unregister obex server");
1352 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
1353 BT_ERR("Fail to unregister media player");
1355 /* Other unregister APIs should be placed here */
1356 __bt_disconnect_all();
1357 ret = _bt_disable_cb();
1363 int _bt_recover_adapter(void)
1368 GError *error = NULL;
1370 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1371 BT_DBG("Disabling in progress");
1372 return BLUETOOTH_ERROR_IN_PROGRESS;
1375 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1376 BT_DBG("Already disabled");
1377 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1380 _bt_adapter_set_status(BT_DEACTIVATING);
1382 proxy = __bt_get_core_proxy();
1383 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1385 result = g_dbus_proxy_call_sync(proxy,
1388 G_DBUS_CALL_FLAGS_NONE,
1394 if (error != NULL) {
1395 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1396 g_clear_error(&error);
1398 BT_ERR("Failed to RecoverAdapter");
1399 return BLUETOOTH_ERROR_INTERNAL;
1402 is_recovery_mode = TRUE;
1404 g_variant_unref(result);
1405 __bt_disconnect_all();
1408 return BLUETOOTH_ERROR_NONE;
1411 int _bt_reset_adapter(void)
1415 GError *error = NULL;
1419 proxy = __bt_get_core_proxy();
1421 return BLUETOOTH_ERROR_INTERNAL;
1423 result = g_dbus_proxy_call_sync(proxy,
1426 G_DBUS_CALL_FLAGS_NONE,
1432 if (error != NULL) {
1433 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1434 g_clear_error(&error);
1436 BT_ERR("Failed to ResetAdapter");
1437 return BLUETOOTH_ERROR_INTERNAL;
1440 g_variant_unref(result);
1441 /* Terminate myself */
1442 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1443 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1445 return BLUETOOTH_ERROR_NONE;
1448 #ifndef TIZEN_PROFILE_TV
1449 int _bt_check_adapter(int *status)
1452 char *adapter_path = NULL;
1454 BT_CHECK_PARAMETER(status, return);
1456 *status = BT_ADAPTER_DISABLED;
1458 adapter_path = _bt_get_adapter_path();
1461 if (adapter_path != NULL)
1462 *status = BT_ADAPTER_ENABLED;
1464 g_free(adapter_path);
1465 return BLUETOOTH_ERROR_NONE;
1468 int _bt_check_adapter(int *status)
1471 GError *error = NULL;
1474 gboolean powered = FALSE;
1476 BT_CHECK_PARAMETER(status, return);
1478 *status = BT_ADAPTER_DISABLED;
1480 proxy = _bt_get_adapter_properties_proxy();
1481 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1483 result = g_dbus_proxy_call_sync(proxy,
1485 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1487 G_DBUS_CALL_FLAGS_NONE,
1493 BT_ERR("Failed to get local address");
1494 if (error != NULL) {
1495 BT_ERR("Failed to get local address (Error: %s)", error->message);
1496 g_clear_error(&error);
1498 return BLUETOOTH_ERROR_INTERNAL;
1501 g_variant_get(result, "(v)", &temp);
1502 powered = g_variant_get_boolean(temp);
1503 BT_DBG("powered: %d", powered);
1506 *status = BT_ADAPTER_ENABLED;
1508 g_variant_unref(result);
1509 g_variant_unref(temp);
1510 return BLUETOOTH_ERROR_NONE;
1514 int _bt_enable_adapter_le(void)
1518 GError *error = NULL;
1519 bt_status_t status = _bt_adapter_get_status();
1520 bt_le_status_t le_status = _bt_adapter_get_le_status();
1523 if (le_status == BT_LE_ACTIVATING) {
1524 BT_ERR("Enabling in progress");
1525 return BLUETOOTH_ERROR_IN_PROGRESS;
1528 if (le_status == BT_LE_ACTIVATED) {
1529 BT_ERR("Already enabled");
1530 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1533 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1534 BT_ERR("Disabling in progress");
1535 return BLUETOOTH_ERROR_DEVICE_BUSY;
1538 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1540 proxy = __bt_get_core_proxy();
1541 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1543 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1545 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1548 BT_ERR("EnableAdapterLe failed: %s", error->message);
1549 _bt_adapter_set_le_status(BT_DEACTIVATED);
1550 g_clear_error(&error);
1552 /* Clean up the process */
1553 result = g_dbus_proxy_call_sync(proxy,
1556 G_DBUS_CALL_FLAGS_NONE,
1562 BT_ERR("Bt core call failed");
1564 BT_ERR("EnableAdapterLE Failed %s", error->message);
1565 g_clear_error(&error);
1568 g_variant_unref(result);
1569 /* Terminate myself */
1570 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1571 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1572 return BLUETOOTH_ERROR_INTERNAL;
1576 g_variant_unref(result);
1578 _bt_adapter_start_le_enable_timer();
1580 if (status == BT_ACTIVATED) {
1581 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1582 __bt_set_le_enabled();
1584 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1586 return BLUETOOTH_ERROR_NONE;
1589 int _bt_disable_adapter_le(void)
1593 bt_le_status_t bt_le_state;
1595 GError *error = NULL;
1597 bt_le_state = _bt_adapter_get_le_status();
1598 if (bt_le_state == BT_LE_DEACTIVATING) {
1599 BT_DBG("Disabling in progress");
1600 return BLUETOOTH_ERROR_IN_PROGRESS;
1603 if (bt_le_state == BT_LE_DEACTIVATED) {
1604 BT_DBG("Already disabled");
1605 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1608 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1610 proxy = __bt_get_core_proxy();
1612 return BLUETOOTH_ERROR_INTERNAL;
1614 result = g_dbus_proxy_call_sync(proxy,
1617 G_DBUS_CALL_FLAGS_NONE,
1623 if (error != NULL) {
1624 BT_ERR("Bt core call failed (Error: %s)", error->message);
1625 g_clear_error(&error);
1627 BT_ERR("Bt core call failed");
1628 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1629 return BLUETOOTH_ERROR_INTERNAL;
1632 g_variant_unref(result);
1633 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1634 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1636 return BLUETOOTH_ERROR_NONE;
1639 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1643 GError *error = NULL;
1644 const char *address;
1648 BT_CHECK_PARAMETER(local_address, return);
1650 proxy = _bt_get_adapter_properties_proxy();
1651 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1653 result = g_dbus_proxy_call_sync(proxy,
1655 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1657 G_DBUS_CALL_FLAGS_NONE,
1663 BT_ERR("Failed to get local address");
1664 if (error != NULL) {
1665 BT_ERR("Failed to get local address (Error: %s)", error->message);
1666 g_clear_error(&error);
1668 return BLUETOOTH_ERROR_INTERNAL;
1671 g_variant_get(result, "(v)", &temp);
1672 address = g_variant_get_string(temp, NULL);
1673 BT_DBG("Address:%s", address);
1676 _bt_convert_addr_string_to_type(local_address->addr, address);
1678 return BLUETOOTH_ERROR_INTERNAL;
1680 g_variant_unref(result);
1681 g_variant_unref(temp);
1682 return BLUETOOTH_ERROR_NONE;
1685 int _bt_get_local_version(bluetooth_version_t *local_version)
1688 const char *ver = NULL;
1690 int ret = BLUETOOTH_ERROR_NONE;
1694 BT_CHECK_PARAMETER(local_version, return);
1696 GError *error = NULL;
1698 proxy = _bt_get_adapter_properties_proxy();
1699 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1701 result = g_dbus_proxy_call_sync(proxy,
1703 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1705 G_DBUS_CALL_FLAGS_NONE,
1711 if (error != NULL) {
1712 BT_ERR("Failed to get local version (Error: %s)", error->message);
1713 g_clear_error(&error);
1715 BT_ERR("Failed to get local version");
1716 return BLUETOOTH_ERROR_INTERNAL;
1719 g_variant_get(result, "(v)", &temp);
1720 ver = g_variant_get_string(temp, NULL);
1721 BT_DBG("VERSION: %s", ver);
1723 if (ver && (strlen(ver) > 0)) {
1724 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1725 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1728 g_strlcpy(local_version->version, ver,
1729 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1732 ret = BLUETOOTH_ERROR_INTERNAL;
1735 g_variant_unref(result);
1736 g_variant_unref(temp);
1740 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1743 const char *name = NULL;
1745 int ret = BLUETOOTH_ERROR_NONE;
1748 GError *error = NULL;
1750 BT_CHECK_PARAMETER(local_name, return);
1752 proxy = _bt_get_adapter_properties_proxy();
1753 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1755 result = g_dbus_proxy_call_sync(proxy,
1757 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1759 G_DBUS_CALL_FLAGS_NONE,
1765 if (error != NULL) {
1766 BT_ERR("Failed to get local name (Error: %s)", error->message);
1767 g_clear_error(&error);
1769 BT_ERR("Failed to get local name");
1770 return BLUETOOTH_ERROR_INTERNAL;
1773 g_variant_get(result, "(v)", &temp);
1774 name = g_variant_get_string(temp, NULL);
1775 BT_DBG("LOCAL NAME:%s", name);
1777 if (name && (strlen(name) > 0)) {
1778 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1779 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1782 g_strlcpy(local_name->name, name,
1783 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1785 ret = BLUETOOTH_ERROR_INTERNAL;
1787 g_variant_unref(result);
1788 g_variant_unref(temp);
1792 int _bt_set_local_name(char *local_name)
1795 GError *error = NULL;
1799 BT_CHECK_PARAMETER(local_name, return);
1801 proxy = _bt_get_adapter_properties_proxy();
1803 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1805 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1808 result = g_dbus_proxy_call_sync(proxy,
1810 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1811 "Alias", g_variant_new("s", local_name)),
1812 G_DBUS_CALL_FLAGS_NONE,
1818 if (error != NULL) {
1819 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1820 g_clear_error(&error);
1822 BT_ERR("Failed to set Alias");
1823 return BLUETOOTH_ERROR_INTERNAL;
1826 g_variant_unref(result);
1827 return BLUETOOTH_ERROR_NONE;
1830 int _bt_is_service_used(char *service_uuid, gboolean *used)
1833 GError *error = NULL;
1834 int ret = BLUETOOTH_ERROR_NONE;
1836 GVariant *temp = NULL;
1837 GVariantIter *iter = NULL;
1841 BT_CHECK_PARAMETER(service_uuid, return);
1842 BT_CHECK_PARAMETER(used, return);
1844 proxy = _bt_get_adapter_properties_proxy();
1845 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1847 result = g_dbus_proxy_call_sync(proxy,
1849 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1851 G_DBUS_CALL_FLAGS_NONE,
1857 if (error != NULL) {
1858 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1859 g_clear_error(&error);
1861 BT_ERR("Failed to get UUIDs");
1862 return BLUETOOTH_ERROR_INTERNAL;
1865 g_variant_get(result, "(v)", &temp);
1866 g_variant_get(temp, "as", &iter);
1869 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1870 if (strcasecmp(uuid, service_uuid) == 0) {
1875 g_variant_iter_free(iter);
1876 g_variant_unref(result);
1878 BT_DBG("Service Used? %d", *used);
1883 static gboolean __bt_get_discoverable_property(void)
1886 gboolean discoverable_v;
1887 GError *error = NULL;
1891 proxy = _bt_get_adapter_properties_proxy();
1892 retv_if(proxy == NULL, FALSE);
1894 result = g_dbus_proxy_call_sync(proxy,
1896 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1898 G_DBUS_CALL_FLAGS_NONE,
1904 if (error != NULL) {
1905 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1906 g_clear_error(&error);
1908 BT_ERR("Failed to get Discoverable property");
1909 return BLUETOOTH_ERROR_INTERNAL;
1912 g_variant_get(result, "(v)", &temp);
1913 discoverable_v = g_variant_get_boolean(temp);
1914 BT_DBG("discoverable_v:%d", discoverable_v);
1916 g_variant_unref(result);
1917 g_variant_unref(temp);
1919 return discoverable_v;
1922 int _bt_get_discoverable_mode(int *mode)
1924 gboolean discoverable;
1925 unsigned int timeout;
1927 BT_CHECK_PARAMETER(mode, return);
1929 discoverable = __bt_get_discoverable_property();
1930 timeout = _bt_get_discoverable_timeout_property();
1932 if (discoverable == TRUE) {
1934 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1936 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1938 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1940 return BLUETOOTH_ERROR_NONE;
1944 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1946 int ret = BLUETOOTH_ERROR_NONE;
1949 GError *error = NULL;
1952 #ifdef TIZEN_FEATURE_BT_DPM
1953 int discoverable_state = DPM_BT_ERROR;
1956 proxy = _bt_get_adapter_properties_proxy();
1958 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1960 #ifdef TIZEN_FEATURE_BT_DPM
1961 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1962 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
1963 discoverable_state == DPM_RESTRICTED) {
1964 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT_HANDSFREE");
1965 return BLUETOOTH_ERROR_ACCESS_DENIED;
1967 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
1968 discoverable_state == DPM_RESTRICTED) {
1969 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT");
1970 return BLUETOOTH_ERROR_ACCESS_DENIED;
1974 switch (discoverable_mode) {
1975 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1980 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1985 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1990 return BLUETOOTH_ERROR_INVALID_PARAM;
1993 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1994 discoverable_mode, timeout);
1996 result = g_dbus_proxy_call_sync(proxy,
1998 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1999 "Connectable", g_variant_new("b", pg_scan)),
2000 G_DBUS_CALL_FLAGS_NONE,
2006 if (error != NULL) {
2007 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2008 g_clear_error(&error);
2010 BT_ERR("Failed to set connectable property");
2011 return BLUETOOTH_ERROR_INTERNAL;
2013 g_variant_unref(result);
2014 result = g_dbus_proxy_call_sync(proxy,
2016 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2017 g_variant_new("b", inq_scan)),
2018 G_DBUS_CALL_FLAGS_NONE,
2024 if (error != NULL) {
2025 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2026 g_clear_error(&error);
2028 BT_ERR("Failed to set Discoverable property");
2029 return BLUETOOTH_ERROR_INTERNAL;
2031 g_variant_unref(result);
2032 result = g_dbus_proxy_call_sync(proxy,
2034 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2035 "DiscoverableTimeout", g_variant_new("u", timeout)),
2036 G_DBUS_CALL_FLAGS_NONE,
2042 if (error != NULL) {
2043 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2044 g_clear_error(&error);
2046 BT_ERR("Failed to set DiscoverableTimeout property");
2047 return BLUETOOTH_ERROR_INTERNAL;
2050 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2053 ret = __bt_set_visible_time(timeout);
2055 g_variant_unref(result);
2060 int _bt_start_discovery(void)
2063 GError *error = NULL;
2066 if (_bt_is_discovering() == TRUE) {
2067 BT_ERR("BT is already in discovering");
2068 return BLUETOOTH_ERROR_IN_PROGRESS;
2069 } else if (_bt_is_device_creating() == TRUE) {
2070 BT_ERR("Bonding device is going on");
2071 return BLUETOOTH_ERROR_DEVICE_BUSY;
2074 proxy = _bt_get_adapter_proxy();
2075 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2077 result = g_dbus_proxy_call_sync(proxy,
2080 G_DBUS_CALL_FLAGS_NONE,
2086 if (error != NULL) {
2087 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2088 g_clear_error(&error);
2090 BT_ERR("StartDiscovery failed");
2091 return BLUETOOTH_ERROR_INTERNAL;
2094 is_discovering = TRUE;
2095 cancel_by_user = FALSE;
2096 /* discovery status will be change in event */
2097 g_variant_unref(result);
2098 return BLUETOOTH_ERROR_NONE;
2101 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2105 GError *error = NULL;
2106 const gchar *disc_type;
2108 if (_bt_is_discovering() == TRUE) {
2109 BT_ERR("BT is already in discovering");
2110 return BLUETOOTH_ERROR_IN_PROGRESS;
2113 proxy = _bt_get_adapter_proxy();
2114 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2116 if (role == DISCOVERY_ROLE_BREDR)
2117 disc_type = "BREDR";
2118 else if (role == DISCOVERY_ROLE_LE)
2120 else if (role == DISCOVERY_ROLE_LE_BREDR)
2121 disc_type = "LE_BREDR";
2123 return BLUETOOTH_ERROR_INVALID_PARAM;
2125 result = g_dbus_proxy_call_sync(proxy,
2126 "StartCustomDiscovery",
2127 g_variant_new("s", disc_type),
2128 G_DBUS_CALL_FLAGS_NONE,
2134 if (error != NULL) {
2135 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2136 g_clear_error(&error);
2138 BT_ERR("StartCustomDiscovery failed");
2139 return BLUETOOTH_ERROR_INTERNAL;
2142 is_discovering = TRUE;
2143 cancel_by_user = FALSE;
2144 /* discovery status will be change in event */
2145 g_variant_unref(result);
2146 return BLUETOOTH_ERROR_NONE;
2149 int _bt_cancel_discovery(void)
2152 GError *error = NULL;
2155 if (_bt_is_discovering() == FALSE) {
2156 BT_ERR("BT is not in discovering");
2157 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2160 proxy = _bt_get_adapter_proxy();
2161 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2163 result = g_dbus_proxy_call_sync(proxy,
2166 G_DBUS_CALL_FLAGS_NONE,
2172 int ret = BLUETOOTH_ERROR_INTERNAL;
2173 if (error != NULL) {
2174 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2176 if (g_strrstr(error->message, "No discovery started"))
2177 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2179 g_clear_error(&error);
2181 BT_ERR("StopDiscovery failed");
2187 cancel_by_user = TRUE;
2188 /* discovery status will be change in event */
2189 g_variant_unref(result);
2190 return BLUETOOTH_ERROR_NONE;
2193 gboolean _bt_is_discovering(void)
2195 return is_discovering;
2198 gboolean _bt_is_connectable(void)
2201 GError *error = NULL;
2202 gboolean is_connectable = FALSE;
2206 proxy = _bt_get_adapter_properties_proxy();
2207 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2209 result = g_dbus_proxy_call_sync(proxy,
2211 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2213 G_DBUS_CALL_FLAGS_NONE,
2219 if (error != NULL) {
2220 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2221 g_clear_error(&error);
2223 BT_ERR("Failed to get connectable property");
2224 return BLUETOOTH_ERROR_INTERNAL;
2227 g_variant_get(result, "(v)", &temp);
2228 is_connectable = g_variant_get_boolean(temp);
2229 BT_DBG("discoverable_v:%d", is_connectable);
2231 g_variant_unref(result);
2232 g_variant_unref(temp);
2234 BT_INFO("Get connectable [%d]", is_connectable);
2235 return is_connectable;
2238 int _bt_set_connectable(gboolean is_connectable)
2241 GError *error = NULL;
2244 if (__bt_is_factory_test_mode()) {
2245 BT_ERR("Unable to set connectable in factory binary !!");
2246 return BLUETOOTH_ERROR_NOT_SUPPORT;
2249 proxy = _bt_get_adapter_properties_proxy();
2251 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2253 result = g_dbus_proxy_call_sync(proxy,
2255 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2256 g_variant_new("b", is_connectable)),
2257 G_DBUS_CALL_FLAGS_NONE,
2263 if (error != NULL) {
2264 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2265 g_clear_error(&error);
2267 BT_ERR("Failed to set connectable property");
2268 return BLUETOOTH_ERROR_INTERNAL;
2271 BT_INFO_C("### Set connectable [%d]", is_connectable);
2272 g_variant_unref(result);
2273 return BLUETOOTH_ERROR_NONE;
2276 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2279 gboolean discovering_v;
2280 GError *error = NULL;
2281 char *discovering_type = NULL;
2285 proxy = _bt_get_adapter_properties_proxy();
2286 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2288 if (discovery_type == DISCOVERY_ROLE_BREDR)
2289 discovering_type = "Discovering";
2290 else if (discovery_type == DISCOVERY_ROLE_LE)
2291 discovering_type = "LEDiscovering";
2293 result = g_dbus_proxy_call_sync(proxy,
2295 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2297 G_DBUS_CALL_FLAGS_NONE,
2303 if (error != NULL) {
2304 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2305 g_clear_error(&error);
2307 BT_ERR("Failed to get discovering property");
2308 return BLUETOOTH_ERROR_INTERNAL;
2311 g_variant_get(result, "(v)", &temp);
2312 discovering_v = g_variant_get_boolean(temp);
2313 BT_DBG("discoverable_v:%d", discovering_v);
2315 g_variant_unref(result);
2316 g_variant_unref(temp);
2318 return discovering_v;
2321 unsigned int _bt_get_discoverable_timeout_property(void)
2324 unsigned int timeout_v;
2325 GError *error = NULL;
2329 proxy = _bt_get_adapter_properties_proxy();
2330 retv_if(proxy == NULL, 0);
2332 result = g_dbus_proxy_call_sync(proxy,
2334 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2335 "DiscoverableTimeout"),
2336 G_DBUS_CALL_FLAGS_NONE,
2342 BT_ERR("Fail to get discoverable timeout");
2343 if (error != NULL) {
2344 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2345 g_clear_error(&error);
2350 g_variant_get(result, "(v)", &temp);
2351 timeout_v = g_variant_get_uint32(temp);
2352 BT_DBG("discoverable_v:%d", timeout_v);
2354 g_variant_unref(result);
2355 g_variant_unref(temp);
2360 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2362 bluetooth_device_info_t *dev_info;
2365 GByteArray *manufacturer_data = NULL;
2367 GVariantIter *char_value_iter;
2369 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2371 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2376 if (!g_strcmp0(key, "Address")) {
2377 const char *address = NULL;
2378 address = g_variant_get_string(value, NULL);
2379 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2381 } else if (!g_strcmp0(key, "Class")) {
2383 cod = g_variant_get_uint32(value);
2384 _bt_divide_device_class(&dev_info->device_class, cod);
2385 } else if (!g_strcmp0(key, "Name")) {
2386 const char *name = NULL;
2387 name = g_variant_get_string(value, NULL);
2388 /* If there is no Alias */
2389 if (strlen(dev_info->device_name.name) == 0) {
2390 g_strlcpy(dev_info->device_name.name, name,
2391 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2393 } else if (!g_strcmp0(key, "Alias")) {
2394 const char *alias = NULL;
2395 alias = g_variant_get_string(value, NULL);
2396 /* Overwrite the name */
2398 memset(dev_info->device_name.name, 0x00,
2399 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2400 g_strlcpy(dev_info->device_name.name, alias,
2401 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2403 } else if (!g_strcmp0(key, "IsAliasSet")) {
2404 dev_info->is_alias_set = g_variant_get_boolean(value);
2405 } else if (!g_strcmp0(key, "Connected")) {
2406 dev_info->connected = g_variant_get_byte(value);
2407 } else if (!g_strcmp0(key, "Paired")) {
2408 dev_info->paired = g_variant_get_boolean(value);
2409 } else if (!g_strcmp0(key, "Trusted")) {
2410 dev_info->trust = g_variant_get_boolean(value);
2411 } else if (!g_strcmp0(key, "RSSI")) {
2412 dev_info->rssi = g_variant_get_int16(value);
2413 } else if (!g_strcmp0(key, "UUIDs")) {
2419 dev_info->service_index = 0;
2420 g_variant_get(value, "as", &iter);
2421 while (g_variant_iter_loop(iter, "s", &uuid)) {
2422 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2423 parts = g_strsplit(uuid, "-", -1);
2425 if (parts == NULL || parts[0] == NULL) {
2430 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2435 dev_info->service_index = i;
2436 g_variant_iter_free(iter);
2437 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2438 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2439 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2440 manufacturer_data = g_byte_array_new();
2441 g_variant_get(value, "ay", &char_value_iter);
2442 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2443 g_byte_array_append(manufacturer_data, &char_value, 1);
2445 if (manufacturer_data) {
2446 if (manufacturer_data->len > 0)
2447 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2449 g_variant_iter_free(char_value_iter);
2450 g_byte_array_free(manufacturer_data, TRUE);
2457 static void __bt_extract_device_info(GVariantIter *iter,
2460 bluetooth_device_info_t *dev_info = NULL;
2461 char *object_path = NULL;
2462 GVariantIter *interface_iter;
2463 GVariantIter *svc_iter;
2464 char *interface_str = NULL;
2466 /* Parse the signature: oa{sa{sv}}} */
2467 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2470 if (object_path == NULL)
2473 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2474 &interface_str, &svc_iter)) {
2475 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2476 BT_DBG("Found a device: %s", object_path);
2477 dev_info = __bt_parse_device_info(svc_iter);
2479 if (dev_info->paired == TRUE) {
2480 g_array_append_vals(*dev_list, dev_info,
2481 sizeof(bluetooth_device_info_t));
2485 g_free(interface_str);
2486 g_variant_iter_free(svc_iter);
2494 int _bt_get_bonded_devices(GArray **dev_list)
2497 GDBusConnection *conn;
2498 GDBusProxy *manager_proxy;
2499 GVariant *result = NULL;
2500 GVariantIter *iter = NULL;
2501 GError *error = NULL;
2503 conn = _bt_gdbus_get_system_gconn();
2504 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2506 manager_proxy = _bt_get_manager_proxy();
2507 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2509 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2511 G_DBUS_CALL_FLAGS_NONE,
2517 if (error != NULL) {
2518 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2519 g_clear_error(&error);
2521 BT_ERR("Failed to Failed to GetManagedObjects");
2522 return BLUETOOTH_ERROR_INTERNAL;
2525 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2526 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2528 __bt_extract_device_info(iter, dev_list);
2529 g_variant_iter_free(iter);
2530 g_variant_unref(result);
2533 return BLUETOOTH_ERROR_NONE;
2536 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2539 GDBusConnection *conn;
2540 GDBusProxy *manager_proxy;
2541 GVariant *result = NULL;
2542 GVariant *result1 = NULL;
2543 GVariantIter *iter = NULL;
2544 GError *error = NULL;
2545 char *object_path = NULL;
2546 GVariantIter *interface_iter;
2547 char *interface_str = NULL;
2548 GDBusProxy *device_proxy = NULL;
2549 gboolean is_connected = FALSE;
2551 conn = _bt_gdbus_get_system_gconn();
2552 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2554 manager_proxy = _bt_get_manager_proxy();
2555 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2557 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2559 G_DBUS_CALL_FLAGS_NONE,
2565 if (error != NULL) {
2566 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2567 g_clear_error(&error);
2570 BT_ERR("Failed to Failed to GetManagedObjects");
2571 return BLUETOOTH_ERROR_INTERNAL;
2574 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2575 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2577 /* Parse the signature: oa{sa{sv}}} */
2578 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2579 if (object_path == NULL)
2582 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2583 &interface_str, NULL)) {
2584 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2585 BT_DBG("Found a device: %s", object_path);
2586 g_free(interface_str);
2588 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2589 NULL, BT_BLUEZ_NAME,
2590 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2592 if (device_proxy == NULL) {
2593 BT_DBG("Device don't have this service");
2597 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2598 g_variant_new("(s)", profile_uuid),
2599 G_DBUS_CALL_FLAGS_NONE,
2604 if (result1 == NULL) {
2605 BT_ERR("Error occured in Proxy call");
2607 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2608 g_error_free(error);
2611 g_object_unref(device_proxy);
2614 g_variant_get(result1, "(b)", &is_connected);
2616 if (is_connected == TRUE) {
2617 char address[BT_ADDRESS_STRING_SIZE];
2618 bluetooth_device_address_t *addr = NULL;
2620 _bt_convert_device_path_to_address(object_path, address);
2622 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2623 _bt_convert_addr_string_to_type(addr->addr, address);
2625 g_array_append_vals(*addr_list, addr,
2626 sizeof(bluetooth_device_address_t));
2629 g_variant_unref(result1);
2630 g_object_unref(device_proxy);
2637 g_variant_unref(result);
2638 g_variant_iter_free(iter);
2641 return BLUETOOTH_ERROR_NONE;
2644 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2645 bluetooth_device_info_t *dev_info)
2647 char *object_path = NULL;
2648 GDBusProxy *adapter_proxy;
2649 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2650 int ret = BLUETOOTH_ERROR_NONE;
2652 BT_CHECK_PARAMETER(device_address, return);
2653 BT_CHECK_PARAMETER(dev_info, return);
2655 adapter_proxy = _bt_get_adapter_proxy();
2656 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2658 _bt_convert_addr_type_to_string(address, device_address->addr);
2660 object_path = _bt_get_device_object_path(address);
2662 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2664 ret = __bt_get_bonded_device_info(object_path, dev_info);
2665 g_free(object_path);
2670 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2672 char *object_path = NULL;
2673 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2674 gboolean alias_set = FALSE;
2676 GDBusConnection *conn;
2677 GDBusProxy *device_proxy;
2678 GError *error = NULL;
2679 GVariant *result = NULL;
2680 GVariant *temp = NULL;
2683 BT_CHECK_PARAMETER(device_address, return);
2684 BT_CHECK_PARAMETER(is_alias_set, return);
2686 _bt_convert_addr_type_to_string(address, device_address->addr);
2688 object_path = _bt_get_device_object_path(address);
2689 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2691 conn = _bt_gdbus_get_system_gconn();
2693 g_free(object_path);
2694 return BLUETOOTH_ERROR_INTERNAL;
2697 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2701 BT_PROPERTIES_INTERFACE,
2703 if (device_proxy == NULL) {
2704 g_free(object_path);
2705 return BLUETOOTH_ERROR_INTERNAL;
2708 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2709 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2710 G_DBUS_CALL_FLAGS_NONE,
2716 BT_ERR("Error occured in Proxy call");
2717 if (error != NULL) {
2718 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2719 g_error_free(error);
2721 g_object_unref(device_proxy);
2722 g_free(object_path);
2723 return BLUETOOTH_ERROR_INTERNAL;
2726 g_variant_get(result, "(v)", &temp);
2727 alias_set = g_variant_get_boolean(temp);
2728 *is_alias_set = alias_set;
2729 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2730 g_variant_unref(temp);
2731 g_variant_unref(result);
2732 g_object_unref(device_proxy);
2734 g_free(object_path);
2736 return BLUETOOTH_ERROR_NONE;
2739 int _bt_get_timeout_value(int *timeout)
2741 time_t current_time;
2744 /* Take current time */
2745 time(¤t_time);
2746 time_diff = difftime(current_time, visible_timer.start_time);
2748 BT_DBG("Time diff = %d\n", time_diff);
2750 *timeout = visible_timer.timeout - time_diff;
2752 return BLUETOOTH_ERROR_NONE;
2755 int _bt_set_le_privacy(gboolean set_privacy)
2758 GError *error = NULL;
2759 GVariant *result = NULL;
2761 if (__bt_is_factory_test_mode()) {
2762 BT_ERR("Unable to set le privacy in factory binary !!");
2763 return BLUETOOTH_ERROR_NOT_SUPPORT;
2766 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2767 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2768 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2771 proxy = _bt_get_adapter_proxy();
2772 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2774 result = g_dbus_proxy_call_sync(proxy,
2776 g_variant_new("(b)", set_privacy),
2777 G_DBUS_CALL_FLAGS_NONE,
2783 if (error != NULL) {
2784 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2785 g_clear_error(&error);
2787 BT_ERR("Failed to SetLePrivacy");
2788 return BLUETOOTH_ERROR_INTERNAL;
2791 g_variant_unref(result);
2792 BT_INFO("SetLePrivacy as %d", set_privacy);
2793 return BLUETOOTH_ERROR_NONE;
2796 int _bt_set_le_static_random_address(gboolean is_enable)
2799 GError *error = NULL;
2800 GVariant *result = NULL;
2802 if (__bt_is_factory_test_mode()) {
2803 BT_ERR("Unable to set le random address in factory binary !!");
2804 return BLUETOOTH_ERROR_NOT_SUPPORT;
2807 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2808 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2809 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2812 proxy = _bt_get_adapter_proxy();
2813 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2815 result = g_dbus_proxy_call_sync(proxy,
2816 "SetLeStaticRandomAddress",
2817 g_variant_new("(b)", is_enable),
2818 G_DBUS_CALL_FLAGS_NONE,
2824 if (error != NULL) {
2825 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2826 g_clear_error(&error);
2828 BT_ERR("Failed to SetLeStaticRandomAddress");
2829 return BLUETOOTH_ERROR_INTERNAL;
2832 g_variant_unref(result);
2833 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2834 return BLUETOOTH_ERROR_NONE;
2837 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2840 GError *error = NULL;
2844 GVariantBuilder *builder;
2846 BT_CHECK_PARAMETER(m_data, return);
2848 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2849 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2850 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2853 proxy = _bt_get_adapter_proxy();
2854 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2856 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2858 for (i = 0; i < (m_data->data_len) + 2; i++)
2859 g_variant_builder_add(builder, "y", m_data->data[i]);
2861 val = g_variant_new("(ay)", builder);
2863 result = g_dbus_proxy_call_sync(proxy,
2864 "SetManufacturerData",
2866 G_DBUS_CALL_FLAGS_NONE,
2870 g_variant_builder_unref(builder);
2872 if (error != NULL) {
2873 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2874 g_clear_error(&error);
2876 BT_ERR("Failed to SetManufacturerData");
2878 return BLUETOOTH_ERROR_INTERNAL;
2880 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2882 for (i = 0; i < (m_data->data_len) + 2; i++)
2883 g_variant_builder_add(builder, "y", m_data->data[i]);
2885 val = g_variant_new("(ay)", builder);
2887 _bt_send_event(BT_ADAPTER_EVENT,
2888 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2891 BT_INFO("Set manufacturer data");
2893 g_variant_builder_unref(builder);
2894 g_variant_unref(result);
2896 return BLUETOOTH_ERROR_NONE;
2900 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2902 int result = BLUETOOTH_ERROR_NONE;
2903 bt_service_alarm_t *alarm = NULL;
2905 if (!call_back || !alarm_id)
2906 return BLUETOOTH_ERROR_INVALID_PARAM;
2908 if (!alarm_mgr.is_alarm_initialized) {
2909 result = alarmmgr_init("bt-service");
2911 BT_ERR("Failed to initialize alarm = %d", result);
2912 result = BLUETOOTH_ERROR_INTERNAL;
2915 result = alarmmgr_set_cb(alarm_cb, NULL);
2917 BT_ERR("Failed to set the callback = %d", result);
2918 result = BLUETOOTH_ERROR_INTERNAL;
2921 alarm_mgr.is_alarm_initialized = TRUE;
2924 alarm = g_malloc0(sizeof(bt_service_alarm_t));
2926 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2928 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
2931 BT_ERR("Failed to create alarm error = %d", result);
2932 result = BLUETOOTH_ERROR_INTERNAL;
2936 alarm->alarm_id = *alarm_id;
2937 alarm->callback = call_back;
2938 alarm->user_data = user_data;
2940 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
2941 result = BLUETOOTH_ERROR_NONE;
2946 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
2949 bt_service_alarm_t *p_data;
2950 bt_set_alarm_cb callback = NULL;
2951 void *user_data = NULL;
2953 node = g_list_find_custom(alarm_mgr.g_alarm_list,
2954 GINT_TO_POINTER(alarm_id), compare_alarm);
2958 p_data = (bt_service_alarm_t *)node->data;
2959 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
2965 callback = p_data->callback;
2966 user_data = p_data->user_data;
2970 callback(alarm_id, user_data);
2975 int _bt_service_remove_alarm(alarm_id_t alarm_id)
2978 bt_service_alarm_t *p_data;
2979 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
2982 alarmmgr_remove_alarm(alarm_id);
2983 p_data = (bt_service_alarm_t *)list->data;
2984 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
2991 gint compare_alarm(gconstpointer list_data, gconstpointer data)
2994 alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
2996 alarm_id_t alarm_id = (alarm_id_t)data;
2998 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
3000 if (p_data->alarm_id == alarm_id)
3006 static void alarm_data_free(void *data)
3008 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
3013 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3017 int function = (int)(uintptr_t)user_data;
3019 int function = (int)user_data;
3023 case BT_ENABLE_ADAPTER:
3024 result = _bt_enable_adapter();
3025 if (result != BLUETOOTH_ERROR_NONE) {
3026 BT_ERR("_bt_enable_adapter is failed");
3027 /* Send enabled event to API */
3028 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3029 g_variant_new("(i)", result));
3032 case BT_DISABLE_ADAPTER:
3033 result = _bt_disable_adapter();
3034 if (result != BLUETOOTH_ERROR_NONE) {
3035 BT_ERR("_bt_disable_adapter is failed");
3036 /* Send disabled event to API */
3037 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3038 g_variant_new("(i)", result));
3042 BT_ERR("function is NOT matched");
3049 int _bt_adapter_request_delayed(int function)
3054 case BT_ENABLE_ADAPTER:
3055 ret = _bt_enable_adapter_check_status();
3056 if (ret == BLUETOOTH_ERROR_NONE)
3057 _bt_adapter_set_status(BT_ACTIVATING);
3062 case BT_DISABLE_ADAPTER:
3063 ret = _bt_disable_adapter_check_status();
3064 if (ret == BLUETOOTH_ERROR_NONE)
3065 _bt_adapter_set_status(BT_DEACTIVATING);
3071 BT_ERR("function is NOT matched");
3072 return BLUETOOTH_ERROR_INTERNAL;
3076 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3078 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3081 return BLUETOOTH_ERROR_NONE;
3084 #ifdef TIZEN_PROFILE_TV
3085 int _bt_get_enable_timer_id(void)