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 cancel_by_user;
72 static bt_status_t adapter_status = BT_DEACTIVATED;
73 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
74 static gboolean is_le_intended = FALSE;
75 static void *adapter_agent = NULL;
76 static GDBusProxy *core_proxy = NULL;
77 static guint timer_id = 0;
78 static guint le_timer_id = 0;
79 static gboolean is_recovery_mode;
81 static uint status_reg_id;
83 #define BT_CORE_NAME "org.projectx.bt_core"
84 #define BT_CORE_PATH "/org/projectx/bt_core"
85 #define BT_CORE_INTERFACE "org.projectx.btcore"
87 #define BT_DISABLE_TIME 500 /* 500 ms */
89 static int alarm_cb(alarm_id_t alarm_id, void* user_param);
90 static void alarm_data_free(void *data);
92 GDBusProxy *_bt_init_core_proxy(void)
95 GDBusConnection *conn;
97 conn = _bt_gdbus_get_system_gconn();
101 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
116 static GDBusProxy *__bt_get_core_proxy(void)
118 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
121 static gboolean __bt_is_factory_test_mode(void)
125 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
126 BT_ERR("Get the DUT Mode fail");
131 BT_INFO("DUT Test Mode !!");
138 static gboolean __bt_timeout_handler(gpointer user_data)
140 int result = BLUETOOTH_ERROR_NONE;
144 /* Take current time */
146 time_diff = difftime(current_time, visible_timer.start_time);
148 /* Send event to application */
149 _bt_send_event(BT_ADAPTER_EVENT,
150 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
151 g_variant_new("(in)", result, time_diff));
153 if (visible_timer.timeout <= time_diff) {
154 g_source_remove(visible_timer.event_id);
155 visible_timer.event_id = 0;
156 visible_timer.timeout = 0;
158 if (!TIZEN_PROFILE_WEARABLE) {
159 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
160 BT_ERR("Set vconf failed\n");
168 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
171 int result = BLUETOOTH_ERROR_NONE;
174 if (alarm_id != visible_timer.alarm_id)
177 if (visible_timer.event_id) {
178 _bt_send_event(BT_ADAPTER_EVENT,
179 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
180 g_variant_new("(in)", result, timeout));
181 g_source_remove(visible_timer.event_id);
182 visible_timer.event_id = 0;
183 visible_timer.timeout = 0;
185 if (!TIZEN_PROFILE_WEARABLE) {
186 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
187 BT_ERR("Set vconf failed\n");
190 /* Switch Off visibility in Bluez */
191 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
192 visible_timer.alarm_id = 0;
196 static void __bt_visibility_alarm_remove()
198 if (visible_timer.event_id > 0) {
199 g_source_remove(visible_timer.event_id);
200 visible_timer.event_id = 0;
203 if (visible_timer.alarm_id > 0) {
204 _bt_service_remove_alarm(visible_timer.alarm_id);
205 visible_timer.alarm_id = 0;
209 int __bt_set_visible_time(int timeout)
213 #ifdef TIZEN_FEATURE_BT_DPM
214 int discoverable_state = DPM_BT_ERROR;
217 __bt_visibility_alarm_remove();
219 visible_timer.timeout = timeout;
221 if (!TIZEN_PROFILE_WEARABLE) {
222 #ifdef TIZEN_FEATURE_BT_DPM
223 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
224 if (discoverable_state != DPM_RESTRICTED) {
226 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
227 BT_ERR("Set vconf failed");
228 #ifdef TIZEN_FEATURE_BT_DPM
235 return BLUETOOTH_ERROR_NONE;
237 result = _bt_service_set_alarm(visible_timer.timeout,
238 __bt_visibility_alarm_cb, NULL, &alarm_id);
239 if (result != BLUETOOTH_ERROR_NONE)
240 return BLUETOOTH_ERROR_INTERNAL;
241 visible_timer.alarm_id = alarm_id;
242 /* Take start time */
243 time(&(visible_timer.start_time));
244 visible_timer.event_id = g_timeout_add_seconds(1,
245 __bt_timeout_handler, NULL);
247 return BLUETOOTH_ERROR_NONE;
250 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
257 ret_if(value == NULL);
260 dev->service_index = 0;
262 g_variant_get(value, "as", &iter);
263 while (g_variant_iter_loop(iter, "s", &uuid)) {
264 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
265 parts = g_strsplit(uuid, "-", -1);
267 if (parts == NULL || parts[0] == NULL) {
272 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
275 dev->service_index++;
278 g_variant_iter_free(iter);
281 static int __bt_get_bonded_device_info(gchar *device_path,
282 bluetooth_device_info_t *dev_info)
284 GError *error = NULL;
285 GDBusProxy *device_proxy;
286 gchar *address = NULL;
288 unsigned int cod = 0;
290 gboolean trust = FALSE;
291 gboolean paired = FALSE;
292 guchar connected = 0;
293 GByteArray *manufacturer_data = NULL;
295 GDBusConnection *conn;
297 GVariantIter *property_iter;
301 GVariantIter *char_value_iter;
303 BT_CHECK_PARAMETER(device_path, return);
304 BT_CHECK_PARAMETER(dev_info, return);
306 conn = _bt_gdbus_get_system_gconn();
307 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
309 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
313 BT_PROPERTIES_INTERFACE,
316 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
318 result = g_dbus_proxy_call_sync(device_proxy,
320 g_variant_new("(s)", BT_DEVICE_INTERFACE),
321 G_DBUS_CALL_FLAGS_NONE,
327 BT_ERR("Error occured in Proxy call");
329 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
330 g_clear_error(&error);
332 g_object_unref(device_proxy);
333 return BLUETOOTH_ERROR_INTERNAL;
336 g_object_unref(device_proxy);
338 g_variant_get(result, "(a{sv})", &property_iter);
340 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
341 if (!g_strcmp0(key, "Paired")) {
342 paired = g_variant_get_boolean(value);
343 } else if (!g_strcmp0(key, "Address")) {
344 g_variant_get(value, "s", &address);
345 } else if (!g_strcmp0(key, "Alias")) {
346 g_variant_get(value, "s", &name);
347 } else if (!g_strcmp0(key, "Name")) {
349 g_variant_get(value, "s", &name);
350 } else if (!g_strcmp0(key, "Class")) {
351 cod = g_variant_get_uint32(value);
352 } else if (!g_strcmp0(key, "Connected")) {
353 connected = g_variant_get_byte(value);
354 } else if (!g_strcmp0(key, "Trusted")) {
355 trust = g_variant_get_boolean(value);
356 } else if (!g_strcmp0(key, "RSSI")) {
357 rssi = g_variant_get_int16(value);
358 } else if (!g_strcmp0(key, "UUIDs")) {
359 __bt_get_service_list(value, dev_info);
360 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
361 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
362 } else if (!g_strcmp0(key, "ManufacturerData")) {
363 manufacturer_data = g_byte_array_new();
364 g_variant_get(value, "ay", &char_value_iter);
365 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
366 g_byte_array_append(manufacturer_data, &char_value, 1);
368 g_variant_iter_free(char_value_iter);
370 if (manufacturer_data) {
371 if (manufacturer_data->len > 0) {
372 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
373 manufacturer_data->len);
376 g_byte_array_free(manufacturer_data, TRUE);
379 g_variant_iter_free(property_iter);
381 BT_DBG("trust: %d, paired: %d", trust, paired);
383 g_variant_unref(result);
385 if ((paired == FALSE) && (trust == FALSE)) {
388 return BLUETOOTH_ERROR_NOT_PAIRED;
391 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
394 _bt_divide_device_class(&dev_info->device_class, cod);
396 g_strlcpy(dev_info->device_name.name, name,
397 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
399 dev_info->rssi = rssi;
400 dev_info->trust = trust;
401 dev_info->paired = paired;
402 dev_info->connected = connected;
403 ret = BLUETOOTH_ERROR_NONE;
410 void _bt_set_discovery_status(gboolean mode)
412 is_discovering = mode;
415 void _bt_set_cancel_by_user(gboolean value)
417 cancel_by_user = value;
420 gboolean _bt_get_cancel_by_user(void)
422 return cancel_by_user;
425 void _bt_adapter_set_status(bt_status_t status)
427 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
428 adapter_status = status;
431 bt_status_t _bt_adapter_get_status(void)
433 return adapter_status;
436 void _bt_adapter_set_le_status(bt_le_status_t status)
438 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
439 adapter_le_status = status;
442 bt_le_status_t _bt_adapter_get_le_status(void)
444 return adapter_le_status;
448 void _bt_set_le_intended_status(gboolean value)
450 is_le_intended = value;
453 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
455 char *phone_name = NULL;
461 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
462 phone_name = vconf_keynode_get_str(node);
464 if (phone_name && strlen(phone_name) != 0) {
465 if (!g_utf8_validate(phone_name, -1,
466 (const char **)&ptr))
469 _bt_set_local_name(phone_name);
474 static void __bt_set_local_name(void)
476 bluetooth_device_name_t local_name;
477 char *phone_name = NULL;
481 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
482 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
483 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
488 if (strlen(phone_name) != 0) {
489 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
492 _bt_set_local_name(phone_name);
498 static int __bt_set_enabled(void)
500 int adapter_status = BT_ADAPTER_DISABLED;
501 int result = BLUETOOTH_ERROR_NONE;
504 BT_DBG("g_source is removed");
505 g_source_remove(timer_id);
509 _bt_check_adapter(&adapter_status);
511 if (adapter_status == BT_ADAPTER_DISABLED) {
512 BT_ERR("Bluetoothd is not running");
513 return BLUETOOTH_ERROR_INTERNAL;
516 if (TIZEN_PROFILE_MOBILE || TIZEN_PROFILE_IVI) {
517 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
518 if (_bt_set_discoverable_mode(
519 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
520 BT_ERR("Set connectable mode failed");
521 } else if (TIZEN_PROFILE_TV) {
522 if (_bt_set_discoverable_mode(
523 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
524 BT_ERR("Fail to set discoverable mode");
527 /* Update Bluetooth Status to notify other modules */
528 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
529 BT_ERR("Set vconf failed\n");
531 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
532 BT_ERR("Set vconf failed\n");
534 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
535 EVT_VAL_BT_ON) != ES_R_OK)
536 BT_ERR("Fail to set value");
538 /* Send enabled event to API */
539 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
540 g_variant_new("(i)", result));
542 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
543 _bt_audio_start_auto_connect(FALSE);
546 __bt_set_local_name();
547 _bt_set_discovery_status(FALSE);
549 return BLUETOOTH_ERROR_NONE;
552 void _bt_set_disabled(int result)
554 int power_off_status = 0;
557 int pm_ignore_mode = 0;
559 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
560 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
562 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
564 /* Update the vconf BT status in normal Deactivation case only */
565 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
566 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
568 BT_DBG("Update vconf for BT normal Deactivation");
570 if (result == BLUETOOTH_ERROR_TIMEOUT)
571 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
572 BT_ERR("Set vconf failed");
574 /* Update Bluetooth Status to notify other modules */
575 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
576 BT_ERR("Set vconf failed");
578 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
579 EVT_VAL_BT_OFF) != ES_R_OK)
580 BT_ERR("Fail to set value");
583 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
584 BT_ERR("Set vconf failed\n");
586 _bt_cancel_queued_transfers();
587 _bt_adapter_set_status(BT_DEACTIVATED);
588 _bt_set_discovery_status(FALSE);
590 if (TIZEN_FEATURE_BT_USB_DONGLE ||
591 _bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
592 /* Send disabled event */
593 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
594 g_variant_new("(i)", result));
597 BT_INFO("Adapter disabled");
600 static int __bt_set_le_enabled(void)
603 int result = BLUETOOTH_ERROR_NONE;
606 /* Update Bluetooth Status to notify other modules */
607 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
608 BT_ERR("Set vconf failed\n");
610 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
611 EVT_VAL_BT_LE_ON) != ES_R_OK)
612 BT_ERR("Fail to set value");
614 /* Send enabled event to API */
616 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
617 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
619 status = _bt_adapter_get_status();
620 if (status == BT_DEACTIVATED) {
621 BT_INFO("BREDR is off, turn off PSCAN");
622 _bt_set_connectable(FALSE);
624 if (le_timer_id > 0) {
625 g_source_remove(le_timer_id);
629 /* Send enabled event to API */
630 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
631 g_variant_new("(i)", result));
633 __bt_set_local_name();
636 return BLUETOOTH_ERROR_NONE;
639 void _bt_set_le_disabled(int result)
641 int power_off_status;
644 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
645 BT_DBG("ret : %d", ret);
646 BT_DBG("power_off_status : %d", power_off_status);
648 /* Update Bluetooth Status to notify other modules */
649 BT_DBG("Update vconf for BT LE normal Deactivation");
650 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
651 BT_ERR("Set vconf failed\n");
652 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
654 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
655 EVT_VAL_BT_LE_OFF) != ES_R_OK)
656 BT_ERR("Fail to set value");
658 /* Send disabled event */
659 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
660 g_variant_new("(i)", result));
663 void *_bt_get_adapter_agent(void)
665 return adapter_agent;
668 int _bt_enable_core(void)
672 GError *error = NULL;
674 proxy = __bt_get_core_proxy();
675 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
677 /* Clean up the process */
678 result = g_dbus_proxy_call_sync(proxy,
681 G_DBUS_CALL_FLAGS_NONE,
688 BT_ERR("Bt core call failed(Error: %s)", error->message);
689 g_clear_error(&error);
691 BT_ERR("Bt core call failed");
692 return BLUETOOTH_ERROR_INTERNAL;
695 g_variant_unref(result);
696 return BLUETOOTH_ERROR_NONE;
699 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
701 gboolean flight_mode = FALSE;
702 int power_saving_mode = 0;
705 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
706 type = vconf_keynode_get_type(node);
707 if (type == VCONF_TYPE_BOOL) {
708 flight_mode = vconf_keynode_get_bool(node);
709 if (flight_mode != TRUE) {
710 BT_ERR("Ignore the event");
713 } else if (type == VCONF_TYPE_INT) {
714 power_saving_mode = vconf_keynode_get_int(node);
715 if (power_saving_mode != 2) {
716 BT_ERR("Ignore the event");
720 BT_ERR("Invaild vconf key type : %d", type);
727 void _bt_service_register_vconf_handler(void)
731 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
732 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
733 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
734 BT_ERR("Unable to register key handler");
736 BT_DBG("Telephony is disabled");
739 if (!TIZEN_PROFILE_WEARABLE) {
740 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
741 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
742 BT_ERR("Unable to register key handler");
746 void _bt_service_unregister_vconf_handler(void)
750 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
751 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
752 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
755 if (!TIZEN_PROFILE_WEARABLE) {
756 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
757 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
761 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
763 const char *bt_status = NULL;
764 const char *bt_le_status = NULL;
765 BT_DBG("bt state set event(%s) received", event_name);
767 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
768 BT_DBG("bt_state: (%s)", bt_status);
770 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
771 BT_DBG("bt_state: (%s)", bt_le_status);
774 void _bt_handle_adapter_added(void)
778 bt_le_status_t le_status;
782 BT_DBG("g_source is removed");
783 g_source_remove(timer_id);
788 status = _bt_adapter_get_status();
789 le_status = _bt_adapter_get_le_status();
790 BT_DBG("status : %d", status);
791 BT_DBG("le_status : %d", le_status);
793 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
794 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
795 if (!adapter_agent) {
796 BT_ERR("Fail to register agent");
800 if (adapter_agent == NULL) {
801 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
802 if (!adapter_agent) {
803 BT_ERR("Fail to register agent");
809 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
810 BT_ERR("Fail to register media player");
812 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
813 BT_ERR("Fail to init obex server");
815 #ifdef TIZEN_BT_PAN_NAP_ENABLED
816 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
817 BT_ERR("Fail to activate network");
820 /* add the vconf noti handler */
821 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
822 __bt_phone_name_changed_cb, NULL);
824 BT_ERR("Unable to register key handler");
826 if (le_status == BT_LE_ACTIVATING ||
827 status == BT_ACTIVATING) {
828 __bt_set_le_enabled();
829 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
832 if (status == BT_ACTIVATING) {
834 _bt_adapter_set_status(BT_ACTIVATED);
838 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
839 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
840 BT_ERR("Fail to register system event");
844 void _bt_handle_adapter_removed(void)
848 _bt_adapter_set_status(BT_DEACTIVATED);
850 __bt_visibility_alarm_remove();
852 if (alarm_mgr.is_alarm_initialized == TRUE) {
854 alarm_mgr.is_alarm_initialized = FALSE;
855 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
856 alarm_mgr.g_alarm_list = NULL;
859 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
860 _bt_audio_stop_auto_connect();
863 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
864 (vconf_callback_fn)__bt_phone_name_changed_cb);
866 ERR("vconf_ignore_key_changed failed\n");
868 /* unregister all the services/servers/profiles registered on bluez-adapter
869 once adapter is removed, reinitializing of the state-varaibles becomes
871 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
872 BT_ERR("Fail to unregister obex server");
874 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
875 BT_ERR("Fail to unregister media player");
877 /* Other unregister APIs should be placed here */
879 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
880 _bt_destroy_agent(adapter_agent);
881 adapter_agent = NULL;
883 if (is_recovery_mode == TRUE) {
884 /* Send disabled event */
885 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
887 /* Will recover BT by bt-core, so set the mode as activating */
888 _bt_adapter_set_status(BT_ACTIVATING);
889 is_recovery_mode = FALSE;
891 _bt_reliable_terminate_service(NULL);
894 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
897 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
898 BT_ERR("Fail to unregister system event");
901 static gboolean __bt_enable_timeout_cb(gpointer user_data)
905 GError *error = NULL;
909 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
911 BT_ERR("EnableAdapter is failed");
913 proxy = __bt_get_core_proxy();
917 /* Clean up the process */
918 result = g_dbus_proxy_call_sync(proxy,
921 G_DBUS_CALL_FLAGS_NONE,
928 BT_ERR("Bt core call failed(Error: %s)", error->message);
929 g_clear_error(&error);
931 BT_ERR("Bt core call failed");
936 g_variant_unref(result);
937 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
939 if (!TIZEN_FEATURE_BT_USB_DONGLE)
940 _bt_terminate_service(NULL);
945 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
949 GError *error = NULL;
953 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
955 BT_ERR("EnableAdapterLE is failed");
957 proxy = __bt_get_core_proxy();
961 /* Clean up the process */
962 result = g_dbus_proxy_call_sync(proxy,
965 G_DBUS_CALL_FLAGS_NONE,
972 BT_ERR("Bt core call failed(Error: %s)", error->message);
973 g_clear_error(&error);
975 BT_ERR("Bt core call failed");
979 g_variant_unref(result);
980 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
982 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
984 if (_bt_adapter_get_status() == BT_DEACTIVATED)
985 _bt_terminate_service(NULL);
990 void _bt_adapter_start_le_enable_timer(void)
992 if (le_timer_id > 0) {
993 g_source_remove(le_timer_id);
997 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
998 __bt_enable_le_timeout_cb, NULL);
1003 void _bt_adapter_start_enable_timer(void)
1006 g_source_remove(timer_id);
1010 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1011 __bt_enable_timeout_cb, NULL);
1016 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1021 _bt_adapter_set_status(BT_ACTIVATED);
1026 int _bt_enable_adapter_check_status(void)
1028 bt_status_t status = _bt_adapter_get_status();
1029 bt_le_status_t le_status = _bt_adapter_get_le_status();
1033 if (status == BT_ACTIVATING) {
1034 BT_ERR("Enabling in progress");
1035 return BLUETOOTH_ERROR_IN_PROGRESS;
1038 if (status == BT_ACTIVATED) {
1039 BT_ERR("Already enabled");
1040 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1043 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1044 BT_ERR("Disabling in progress");
1045 return BLUETOOTH_ERROR_DEVICE_BUSY;
1048 return BLUETOOTH_ERROR_NONE;
1051 int _bt_enable_adapter(void)
1054 GError *error = NULL;
1056 GVariant *result = NULL;
1057 bt_status_t status = _bt_adapter_get_status();
1058 bt_le_status_t le_status = _bt_adapter_get_le_status();
1062 if (status == BT_ACTIVATING) {
1063 BT_ERR("Enabling in progress");
1064 return BLUETOOTH_ERROR_IN_PROGRESS;
1067 if (status == BT_ACTIVATED) {
1068 BT_ERR("Already enabled");
1069 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1072 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1073 BT_ERR("Disabling in progress");
1074 return BLUETOOTH_ERROR_DEVICE_BUSY;
1077 _bt_adapter_set_status(BT_ACTIVATING);
1079 if (TIZEN_PROFILE_TV) {
1080 int adapter_status = BT_ADAPTER_DISABLED;
1082 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1083 BT_ERR("Set vconf failed");
1085 _bt_check_adapter(&adapter_status);
1086 if (adapter_status == BT_ADAPTER_ENABLED) {
1087 g_idle_add(__bt_adapter_enabled_cb, NULL);
1088 _bt_adapter_start_enable_timer();
1089 return BLUETOOTH_ERROR_NONE;
1093 proxy = __bt_get_core_proxy();
1095 return BLUETOOTH_ERROR_INTERNAL;
1097 if (le_status == BT_LE_ACTIVATED) {
1098 BT_INFO("LE Already enabled. Just turn on PSCAN");
1099 ret = _bt_set_connectable(TRUE);
1100 if (ret == BLUETOOTH_ERROR_NONE)
1101 _bt_adapter_set_status(BT_ACTIVATED);
1103 return BLUETOOTH_ERROR_INTERNAL;
1106 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1108 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1111 BT_ERR("EnableAdapterLe failed: %s", error->message);
1112 _bt_adapter_set_status(BT_DEACTIVATED);
1113 g_clear_error(&error);
1115 result = g_dbus_proxy_call_sync(proxy,
1118 G_DBUS_CALL_FLAGS_NONE,
1123 if (error != NULL) {
1124 BT_ERR("Bt core call failed(Error: %s)", error->message);
1125 g_clear_error(&error);
1127 g_variant_unref(result);
1128 /* Terminate myself */
1129 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1130 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1131 return BLUETOOTH_ERROR_INTERNAL;
1133 g_variant_unref(result);
1134 if (le_status == BT_LE_ACTIVATED)
1137 _bt_adapter_start_enable_timer();
1139 return BLUETOOTH_ERROR_NONE;
1142 static gboolean __bt_disconnect_all(void)
1145 GDBusConnection *conn;
1146 GDBusProxy *dev_proxy;
1147 gboolean ret = FALSE;
1149 GError *error = NULL;
1150 GArray *device_list;
1151 bluetooth_device_info_t info;
1153 char *device_path = NULL;
1154 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1159 conn = _bt_gdbus_get_system_gconn();
1161 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1163 if (_bt_get_bonded_devices(&device_list)
1164 != BLUETOOTH_ERROR_NONE) {
1165 g_array_free(device_list, TRUE);
1169 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1171 for (i = 0; i < size; i++) {
1173 info = g_array_index(device_list,
1174 bluetooth_device_info_t, i);
1176 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1177 BT_DBG("Found Connected device");
1178 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1179 device_path = _bt_get_device_object_path(address);
1180 if (device_path == NULL)
1183 BT_DBG("Disconnecting : %s", device_path);
1185 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1189 BT_DEVICE_INTERFACE,
1192 if (dev_proxy == NULL)
1195 result = g_dbus_proxy_call_sync(dev_proxy,
1198 G_DBUS_CALL_FLAGS_NONE,
1204 if (error != NULL) {
1205 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1206 g_clear_error(&error);
1208 BT_ERR("Disconnect call failed");
1209 g_object_unref(dev_proxy);
1213 g_variant_unref(result);
1214 g_object_unref(dev_proxy);
1218 g_array_free(device_list, TRUE);
1224 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1227 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1233 int _bt_disable_cb(void)
1241 GError *error = NULL;
1243 _bt_adapter_set_status(BT_DEACTIVATING);
1245 bt_le_status_t le_status;
1246 le_status = _bt_adapter_get_le_status();
1247 BT_DBG("le_status : %d", le_status);
1248 if (le_status == BT_LE_ACTIVATED) {
1249 BT_INFO("LE is enabled. Just turn off PSCAN");
1251 if (_bt_is_discovering())
1252 _bt_cancel_discovery();
1254 if (_bt_is_connectable() == FALSE) {
1255 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1257 ret = _bt_set_connectable(FALSE);
1258 if (ret != BLUETOOTH_ERROR_NONE) {
1259 BT_ERR("_bt_set_connectable fail!");
1260 _bt_adapter_set_status(BT_ACTIVATED);
1261 return BLUETOOTH_ERROR_INTERNAL;
1266 proxy = __bt_get_core_proxy();
1267 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1269 result = g_dbus_proxy_call_sync(proxy,
1272 G_DBUS_CALL_FLAGS_NONE,
1278 if (error != NULL) {
1279 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1280 g_clear_error(&error);
1282 BT_ERR("Failed to DisableAdapter");
1283 _bt_adapter_set_status(BT_ACTIVATED);
1284 return BLUETOOTH_ERROR_INTERNAL;
1287 g_variant_unref(result);
1288 return BLUETOOTH_ERROR_NONE;
1291 int _bt_disable_adapter_check_status(void)
1293 bt_status_t status = _bt_adapter_get_status();
1297 if (status == BT_DEACTIVATING) {
1298 BT_DBG("Disabling in progress");
1299 return BLUETOOTH_ERROR_IN_PROGRESS;
1302 if (status == BT_DEACTIVATED) {
1303 BT_DBG("Already disabled");
1304 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1307 return BLUETOOTH_ERROR_NONE;
1310 int _bt_disable_adapter(void)
1315 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1316 BT_DBG("Disabling in progress");
1317 return BLUETOOTH_ERROR_IN_PROGRESS;
1320 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1321 BT_DBG("Already disabled");
1322 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1326 g_source_remove(timer_id);
1329 /* unregister all the services/servers/profiles registered on bluez-adapter
1330 once adapter is removed, reinitializing of the state-varaibles becomes
1332 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1333 BT_ERR("Fail to unregister obex server");
1335 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
1336 BT_ERR("Fail to unregister media player");
1338 /* Other unregister APIs should be placed here */
1339 __bt_disconnect_all();
1340 ret = _bt_disable_cb();
1346 int _bt_recover_adapter(void)
1351 GError *error = NULL;
1353 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1354 BT_DBG("Disabling in progress");
1355 return BLUETOOTH_ERROR_IN_PROGRESS;
1358 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1359 BT_DBG("Already disabled");
1360 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1363 _bt_adapter_set_status(BT_DEACTIVATING);
1365 proxy = __bt_get_core_proxy();
1366 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1368 result = g_dbus_proxy_call_sync(proxy,
1371 G_DBUS_CALL_FLAGS_NONE,
1377 if (error != NULL) {
1378 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1379 g_clear_error(&error);
1381 BT_ERR("Failed to RecoverAdapter");
1382 return BLUETOOTH_ERROR_INTERNAL;
1385 is_recovery_mode = TRUE;
1387 g_variant_unref(result);
1388 __bt_disconnect_all();
1391 return BLUETOOTH_ERROR_NONE;
1394 int _bt_reset_adapter(void)
1398 GError *error = NULL;
1402 proxy = __bt_get_core_proxy();
1404 return BLUETOOTH_ERROR_INTERNAL;
1406 result = g_dbus_proxy_call_sync(proxy,
1409 G_DBUS_CALL_FLAGS_NONE,
1415 if (error != NULL) {
1416 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1417 g_clear_error(&error);
1419 BT_ERR("Failed to ResetAdapter");
1420 return BLUETOOTH_ERROR_INTERNAL;
1423 g_variant_unref(result);
1424 /* Terminate myself */
1425 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1426 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1428 return BLUETOOTH_ERROR_NONE;
1431 int _bt_check_adapter(int *status)
1433 if (!TIZEN_PROFILE_TV) {
1434 char *adapter_path = NULL;
1436 BT_CHECK_PARAMETER(status, return);
1438 *status = BT_ADAPTER_DISABLED;
1440 adapter_path = _bt_get_adapter_path();
1443 if (adapter_path != NULL)
1444 *status = BT_ADAPTER_ENABLED;
1446 g_free(adapter_path);
1447 return BLUETOOTH_ERROR_NONE;
1450 GError *error = NULL;
1453 gboolean powered = FALSE;
1455 BT_CHECK_PARAMETER(status, return);
1457 *status = BT_ADAPTER_DISABLED;
1459 proxy = _bt_get_adapter_properties_proxy();
1460 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1462 result = g_dbus_proxy_call_sync(proxy,
1464 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1466 G_DBUS_CALL_FLAGS_NONE,
1472 BT_ERR("Failed to get local address");
1473 if (error != NULL) {
1474 BT_ERR("Failed to get local address (Error: %s)", error->message);
1475 g_clear_error(&error);
1477 return BLUETOOTH_ERROR_INTERNAL;
1480 g_variant_get(result, "(v)", &temp);
1481 powered = g_variant_get_boolean(temp);
1482 BT_DBG("powered: %d", powered);
1485 *status = BT_ADAPTER_ENABLED;
1487 g_variant_unref(result);
1488 g_variant_unref(temp);
1489 return BLUETOOTH_ERROR_NONE;
1493 int _bt_enable_adapter_le(void)
1497 GError *error = NULL;
1498 bt_status_t status = _bt_adapter_get_status();
1499 bt_le_status_t le_status = _bt_adapter_get_le_status();
1502 if (le_status == BT_LE_ACTIVATING) {
1503 BT_ERR("Enabling in progress");
1504 return BLUETOOTH_ERROR_IN_PROGRESS;
1507 if (le_status == BT_LE_ACTIVATED) {
1508 BT_ERR("Already enabled");
1509 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1512 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1513 BT_ERR("Disabling in progress");
1514 return BLUETOOTH_ERROR_DEVICE_BUSY;
1517 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1519 proxy = __bt_get_core_proxy();
1520 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1522 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1524 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1527 BT_ERR("EnableAdapterLe failed: %s", error->message);
1528 _bt_adapter_set_le_status(BT_DEACTIVATED);
1529 g_clear_error(&error);
1531 /* Clean up the process */
1532 result = g_dbus_proxy_call_sync(proxy,
1535 G_DBUS_CALL_FLAGS_NONE,
1541 BT_ERR("Bt core call failed");
1543 BT_ERR("EnableAdapterLE Failed %s", error->message);
1544 g_clear_error(&error);
1547 g_variant_unref(result);
1548 /* Terminate myself */
1549 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1550 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1551 return BLUETOOTH_ERROR_INTERNAL;
1555 g_variant_unref(result);
1557 _bt_adapter_start_le_enable_timer();
1559 if (status == BT_ACTIVATED) {
1560 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1561 __bt_set_le_enabled();
1563 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1565 return BLUETOOTH_ERROR_NONE;
1568 int _bt_disable_adapter_le(void)
1572 bt_le_status_t bt_le_state;
1574 GError *error = NULL;
1576 bt_le_state = _bt_adapter_get_le_status();
1577 if (bt_le_state == BT_LE_DEACTIVATING) {
1578 BT_DBG("Disabling in progress");
1579 return BLUETOOTH_ERROR_IN_PROGRESS;
1582 if (bt_le_state == BT_LE_DEACTIVATED) {
1583 BT_DBG("Already disabled");
1584 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1587 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1589 proxy = __bt_get_core_proxy();
1591 return BLUETOOTH_ERROR_INTERNAL;
1593 result = g_dbus_proxy_call_sync(proxy,
1596 G_DBUS_CALL_FLAGS_NONE,
1602 if (error != NULL) {
1603 BT_ERR("Bt core call failed (Error: %s)", error->message);
1604 g_clear_error(&error);
1606 BT_ERR("Bt core call failed");
1607 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1608 return BLUETOOTH_ERROR_INTERNAL;
1611 g_variant_unref(result);
1612 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1613 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1615 return BLUETOOTH_ERROR_NONE;
1618 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1622 GError *error = NULL;
1623 const char *address;
1627 BT_CHECK_PARAMETER(local_address, return);
1629 proxy = _bt_get_adapter_properties_proxy();
1630 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1632 result = g_dbus_proxy_call_sync(proxy,
1634 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1636 G_DBUS_CALL_FLAGS_NONE,
1642 BT_ERR("Failed to get local address");
1643 if (error != NULL) {
1644 BT_ERR("Failed to get local address (Error: %s)", error->message);
1645 g_clear_error(&error);
1647 return BLUETOOTH_ERROR_INTERNAL;
1650 g_variant_get(result, "(v)", &temp);
1651 address = g_variant_get_string(temp, NULL);
1652 BT_DBG("Address:%s", address);
1655 _bt_convert_addr_string_to_type(local_address->addr, address);
1657 return BLUETOOTH_ERROR_INTERNAL;
1659 g_variant_unref(result);
1660 g_variant_unref(temp);
1661 return BLUETOOTH_ERROR_NONE;
1664 int _bt_get_local_version(bluetooth_version_t *local_version)
1667 const char *ver = NULL;
1669 int ret = BLUETOOTH_ERROR_NONE;
1673 BT_CHECK_PARAMETER(local_version, return);
1675 GError *error = NULL;
1677 proxy = _bt_get_adapter_properties_proxy();
1678 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1680 result = g_dbus_proxy_call_sync(proxy,
1682 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1684 G_DBUS_CALL_FLAGS_NONE,
1690 if (error != NULL) {
1691 BT_ERR("Failed to get local version (Error: %s)", error->message);
1692 g_clear_error(&error);
1694 BT_ERR("Failed to get local version");
1695 return BLUETOOTH_ERROR_INTERNAL;
1698 g_variant_get(result, "(v)", &temp);
1699 ver = g_variant_get_string(temp, NULL);
1700 BT_DBG("VERSION: %s", ver);
1702 if (ver && (strlen(ver) > 0)) {
1703 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1704 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1707 g_strlcpy(local_version->version, ver,
1708 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1711 ret = BLUETOOTH_ERROR_INTERNAL;
1714 g_variant_unref(result);
1715 g_variant_unref(temp);
1719 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1722 const char *name = NULL;
1724 int ret = BLUETOOTH_ERROR_NONE;
1727 GError *error = NULL;
1729 BT_CHECK_PARAMETER(local_name, return);
1731 proxy = _bt_get_adapter_properties_proxy();
1732 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1734 result = g_dbus_proxy_call_sync(proxy,
1736 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1738 G_DBUS_CALL_FLAGS_NONE,
1744 if (error != NULL) {
1745 BT_ERR("Failed to get local name (Error: %s)", error->message);
1746 g_clear_error(&error);
1748 BT_ERR("Failed to get local name");
1749 return BLUETOOTH_ERROR_INTERNAL;
1752 g_variant_get(result, "(v)", &temp);
1753 name = g_variant_get_string(temp, NULL);
1754 BT_DBG("LOCAL NAME:%s", name);
1756 if (name && (strlen(name) > 0)) {
1757 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1758 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1761 g_strlcpy(local_name->name, name,
1762 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1764 ret = BLUETOOTH_ERROR_INTERNAL;
1766 g_variant_unref(result);
1767 g_variant_unref(temp);
1771 int _bt_set_local_name(char *local_name)
1774 GError *error = NULL;
1778 BT_CHECK_PARAMETER(local_name, return);
1780 proxy = _bt_get_adapter_properties_proxy();
1782 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1784 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1787 result = g_dbus_proxy_call_sync(proxy,
1789 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1790 "Alias", g_variant_new("s", local_name)),
1791 G_DBUS_CALL_FLAGS_NONE,
1797 if (error != NULL) {
1798 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1799 g_clear_error(&error);
1801 BT_ERR("Failed to set Alias");
1802 return BLUETOOTH_ERROR_INTERNAL;
1805 g_variant_unref(result);
1806 return BLUETOOTH_ERROR_NONE;
1809 int _bt_is_service_used(char *service_uuid, gboolean *used)
1812 GError *error = NULL;
1813 int ret = BLUETOOTH_ERROR_NONE;
1815 GVariant *temp = NULL;
1816 GVariantIter *iter = NULL;
1820 BT_CHECK_PARAMETER(service_uuid, return);
1821 BT_CHECK_PARAMETER(used, return);
1823 proxy = _bt_get_adapter_properties_proxy();
1824 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1826 result = g_dbus_proxy_call_sync(proxy,
1828 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1830 G_DBUS_CALL_FLAGS_NONE,
1836 if (error != NULL) {
1837 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1838 g_clear_error(&error);
1840 BT_ERR("Failed to get UUIDs");
1841 return BLUETOOTH_ERROR_INTERNAL;
1844 g_variant_get(result, "(v)", &temp);
1845 g_variant_get(temp, "as", &iter);
1848 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1849 if (strcasecmp(uuid, service_uuid) == 0) {
1854 g_variant_iter_free(iter);
1855 g_variant_unref(result);
1857 BT_DBG("Service Used? %d", *used);
1862 static gboolean __bt_get_discoverable_property(void)
1865 gboolean discoverable_v;
1866 GError *error = NULL;
1870 proxy = _bt_get_adapter_properties_proxy();
1871 retv_if(proxy == NULL, FALSE);
1873 result = g_dbus_proxy_call_sync(proxy,
1875 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1877 G_DBUS_CALL_FLAGS_NONE,
1883 if (error != NULL) {
1884 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1885 g_clear_error(&error);
1887 BT_ERR("Failed to get Discoverable property");
1888 return BLUETOOTH_ERROR_INTERNAL;
1891 g_variant_get(result, "(v)", &temp);
1892 discoverable_v = g_variant_get_boolean(temp);
1893 BT_DBG("discoverable_v:%d", discoverable_v);
1895 g_variant_unref(result);
1896 g_variant_unref(temp);
1898 return discoverable_v;
1901 int _bt_get_discoverable_mode(int *mode)
1903 gboolean discoverable;
1904 unsigned int timeout;
1906 BT_CHECK_PARAMETER(mode, return);
1908 discoverable = __bt_get_discoverable_property();
1909 timeout = _bt_get_discoverable_timeout_property();
1911 if (discoverable == TRUE) {
1913 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1915 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1917 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1919 return BLUETOOTH_ERROR_NONE;
1923 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1925 int ret = BLUETOOTH_ERROR_NONE;
1928 GError *error = NULL;
1931 #ifdef TIZEN_FEATURE_BT_DPM
1932 int discoverable_state = DPM_BT_ERROR;
1935 proxy = _bt_get_adapter_properties_proxy();
1937 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1939 #ifdef TIZEN_FEATURE_BT_DPM
1940 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
1941 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
1942 discoverable_state == DPM_RESTRICTED) {
1943 if (headed_plugin_info->plugin_headed_enabled)
1944 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
1946 return BLUETOOTH_ERROR_ACCESS_DENIED;
1948 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
1949 discoverable_state == DPM_RESTRICTED) {
1950 if (headed_plugin_info->plugin_headed_enabled)
1951 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
1953 return BLUETOOTH_ERROR_ACCESS_DENIED;
1957 switch (discoverable_mode) {
1958 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1963 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1968 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1973 return BLUETOOTH_ERROR_INVALID_PARAM;
1976 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1977 discoverable_mode, timeout);
1979 result = g_dbus_proxy_call_sync(proxy,
1981 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1982 "Connectable", g_variant_new("b", pg_scan)),
1983 G_DBUS_CALL_FLAGS_NONE,
1989 if (error != NULL) {
1990 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
1991 g_clear_error(&error);
1993 BT_ERR("Failed to set connectable property");
1994 return BLUETOOTH_ERROR_INTERNAL;
1996 g_variant_unref(result);
1997 result = g_dbus_proxy_call_sync(proxy,
1999 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2000 g_variant_new("b", inq_scan)),
2001 G_DBUS_CALL_FLAGS_NONE,
2007 if (error != NULL) {
2008 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2009 g_clear_error(&error);
2011 BT_ERR("Failed to set Discoverable property");
2012 return BLUETOOTH_ERROR_INTERNAL;
2014 g_variant_unref(result);
2015 result = g_dbus_proxy_call_sync(proxy,
2017 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2018 "DiscoverableTimeout", g_variant_new("u", timeout)),
2019 G_DBUS_CALL_FLAGS_NONE,
2025 if (error != NULL) {
2026 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2027 g_clear_error(&error);
2029 BT_ERR("Failed to set DiscoverableTimeout property");
2030 return BLUETOOTH_ERROR_INTERNAL;
2033 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2036 ret = __bt_set_visible_time(timeout);
2038 g_variant_unref(result);
2043 int _bt_start_discovery(void)
2046 GError *error = NULL;
2049 if (_bt_is_discovering() == TRUE) {
2050 BT_ERR("BT is already in discovering");
2051 return BLUETOOTH_ERROR_IN_PROGRESS;
2052 } else if (_bt_is_device_creating() == TRUE) {
2053 BT_ERR("Bonding device is going on");
2054 return BLUETOOTH_ERROR_DEVICE_BUSY;
2057 proxy = _bt_get_adapter_proxy();
2058 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2060 result = g_dbus_proxy_call_sync(proxy,
2063 G_DBUS_CALL_FLAGS_NONE,
2069 if (error != NULL) {
2070 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2071 g_clear_error(&error);
2073 BT_ERR("StartDiscovery failed");
2074 return BLUETOOTH_ERROR_INTERNAL;
2077 is_discovering = TRUE;
2078 cancel_by_user = FALSE;
2079 /* discovery status will be change in event */
2080 g_variant_unref(result);
2081 return BLUETOOTH_ERROR_NONE;
2084 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2088 GError *error = NULL;
2089 const gchar *disc_type;
2091 if (_bt_is_discovering() == TRUE) {
2092 BT_ERR("BT is already in discovering");
2093 return BLUETOOTH_ERROR_IN_PROGRESS;
2096 proxy = _bt_get_adapter_proxy();
2097 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2099 if (role == DISCOVERY_ROLE_BREDR)
2100 disc_type = "BREDR";
2101 else if (role == DISCOVERY_ROLE_LE)
2103 else if (role == DISCOVERY_ROLE_LE_BREDR)
2104 disc_type = "LE_BREDR";
2106 return BLUETOOTH_ERROR_INVALID_PARAM;
2108 result = g_dbus_proxy_call_sync(proxy,
2109 "StartCustomDiscovery",
2110 g_variant_new("s", disc_type),
2111 G_DBUS_CALL_FLAGS_NONE,
2117 if (error != NULL) {
2118 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2119 g_clear_error(&error);
2121 BT_ERR("StartCustomDiscovery failed");
2122 return BLUETOOTH_ERROR_INTERNAL;
2125 is_discovering = TRUE;
2126 cancel_by_user = FALSE;
2127 /* discovery status will be change in event */
2128 g_variant_unref(result);
2129 return BLUETOOTH_ERROR_NONE;
2132 int _bt_cancel_discovery(void)
2135 GError *error = NULL;
2138 if (_bt_is_discovering() == FALSE) {
2139 BT_ERR("BT is not in discovering");
2140 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2143 proxy = _bt_get_adapter_proxy();
2144 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2146 result = g_dbus_proxy_call_sync(proxy,
2149 G_DBUS_CALL_FLAGS_NONE,
2155 int ret = BLUETOOTH_ERROR_INTERNAL;
2156 if (error != NULL) {
2157 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2159 if (g_strrstr(error->message, "No discovery started"))
2160 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2162 g_clear_error(&error);
2164 BT_ERR("StopDiscovery failed");
2170 cancel_by_user = TRUE;
2171 /* discovery status will be change in event */
2172 g_variant_unref(result);
2173 return BLUETOOTH_ERROR_NONE;
2176 gboolean _bt_is_discovering(void)
2178 return is_discovering;
2181 gboolean _bt_is_connectable(void)
2184 GError *error = NULL;
2185 gboolean is_connectable = FALSE;
2189 proxy = _bt_get_adapter_properties_proxy();
2190 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2192 result = g_dbus_proxy_call_sync(proxy,
2194 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2196 G_DBUS_CALL_FLAGS_NONE,
2202 if (error != NULL) {
2203 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2204 g_clear_error(&error);
2206 BT_ERR("Failed to get connectable property");
2207 return BLUETOOTH_ERROR_INTERNAL;
2210 g_variant_get(result, "(v)", &temp);
2211 is_connectable = g_variant_get_boolean(temp);
2212 BT_DBG("discoverable_v:%d", is_connectable);
2214 g_variant_unref(result);
2215 g_variant_unref(temp);
2217 BT_INFO("Get connectable [%d]", is_connectable);
2218 return is_connectable;
2221 int _bt_set_connectable(gboolean is_connectable)
2224 GError *error = NULL;
2227 if (__bt_is_factory_test_mode()) {
2228 BT_ERR("Unable to set connectable in factory binary !!");
2229 return BLUETOOTH_ERROR_NOT_SUPPORT;
2232 proxy = _bt_get_adapter_properties_proxy();
2234 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2236 result = g_dbus_proxy_call_sync(proxy,
2238 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2239 g_variant_new("b", is_connectable)),
2240 G_DBUS_CALL_FLAGS_NONE,
2246 if (error != NULL) {
2247 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2248 g_clear_error(&error);
2250 BT_ERR("Failed to set connectable property");
2251 return BLUETOOTH_ERROR_INTERNAL;
2254 BT_INFO_C("### Set connectable [%d]", is_connectable);
2255 g_variant_unref(result);
2256 return BLUETOOTH_ERROR_NONE;
2259 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2262 gboolean discovering_v;
2263 GError *error = NULL;
2264 char *discovering_type = NULL;
2268 proxy = _bt_get_adapter_properties_proxy();
2269 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2271 if (discovery_type == DISCOVERY_ROLE_BREDR)
2272 discovering_type = "Discovering";
2273 else if (discovery_type == DISCOVERY_ROLE_LE)
2274 discovering_type = "LEDiscovering";
2276 result = g_dbus_proxy_call_sync(proxy,
2278 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2280 G_DBUS_CALL_FLAGS_NONE,
2286 if (error != NULL) {
2287 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2288 g_clear_error(&error);
2290 BT_ERR("Failed to get discovering property");
2291 return BLUETOOTH_ERROR_INTERNAL;
2294 g_variant_get(result, "(v)", &temp);
2295 discovering_v = g_variant_get_boolean(temp);
2296 BT_DBG("discoverable_v:%d", discovering_v);
2298 g_variant_unref(result);
2299 g_variant_unref(temp);
2301 return discovering_v;
2304 unsigned int _bt_get_discoverable_timeout_property(void)
2307 unsigned int timeout_v;
2308 GError *error = NULL;
2312 proxy = _bt_get_adapter_properties_proxy();
2313 retv_if(proxy == NULL, 0);
2315 result = g_dbus_proxy_call_sync(proxy,
2317 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2318 "DiscoverableTimeout"),
2319 G_DBUS_CALL_FLAGS_NONE,
2325 BT_ERR("Fail to get discoverable timeout");
2326 if (error != NULL) {
2327 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2328 g_clear_error(&error);
2333 g_variant_get(result, "(v)", &temp);
2334 timeout_v = g_variant_get_uint32(temp);
2335 BT_DBG("discoverable_v:%d", timeout_v);
2337 g_variant_unref(result);
2338 g_variant_unref(temp);
2343 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2345 bluetooth_device_info_t *dev_info;
2348 GByteArray *manufacturer_data = NULL;
2350 GVariantIter *char_value_iter;
2352 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2354 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2359 if (!g_strcmp0(key, "Address")) {
2360 const char *address = NULL;
2361 address = g_variant_get_string(value, NULL);
2362 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2364 } else if (!g_strcmp0(key, "Class")) {
2366 cod = g_variant_get_uint32(value);
2367 _bt_divide_device_class(&dev_info->device_class, cod);
2368 } else if (!g_strcmp0(key, "Name")) {
2369 const char *name = NULL;
2370 name = g_variant_get_string(value, NULL);
2371 /* If there is no Alias */
2372 if (strlen(dev_info->device_name.name) == 0) {
2373 g_strlcpy(dev_info->device_name.name, name,
2374 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2376 } else if (!g_strcmp0(key, "Alias")) {
2377 const char *alias = NULL;
2378 alias = g_variant_get_string(value, NULL);
2379 /* Overwrite the name */
2381 memset(dev_info->device_name.name, 0x00,
2382 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2383 g_strlcpy(dev_info->device_name.name, alias,
2384 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2386 } else if (!g_strcmp0(key, "IsAliasSet")) {
2387 dev_info->is_alias_set = g_variant_get_boolean(value);
2388 } else if (!g_strcmp0(key, "Connected")) {
2389 dev_info->connected = g_variant_get_byte(value);
2390 } else if (!g_strcmp0(key, "Paired")) {
2391 dev_info->paired = g_variant_get_boolean(value);
2392 } else if (!g_strcmp0(key, "Trusted")) {
2393 dev_info->trust = g_variant_get_boolean(value);
2394 } else if (!g_strcmp0(key, "RSSI")) {
2395 dev_info->rssi = g_variant_get_int16(value);
2396 } else if (!g_strcmp0(key, "UUIDs")) {
2402 dev_info->service_index = 0;
2403 g_variant_get(value, "as", &iter);
2404 while (g_variant_iter_loop(iter, "s", &uuid)) {
2405 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2406 parts = g_strsplit(uuid, "-", -1);
2408 if (parts == NULL || parts[0] == NULL) {
2413 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2418 dev_info->service_index = i;
2419 g_variant_iter_free(iter);
2420 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2421 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2422 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2423 manufacturer_data = g_byte_array_new();
2424 g_variant_get(value, "ay", &char_value_iter);
2425 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2426 g_byte_array_append(manufacturer_data, &char_value, 1);
2428 if (manufacturer_data) {
2429 if (manufacturer_data->len > 0)
2430 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2432 g_variant_iter_free(char_value_iter);
2433 g_byte_array_free(manufacturer_data, TRUE);
2440 static void __bt_extract_device_info(GVariantIter *iter,
2443 bluetooth_device_info_t *dev_info = NULL;
2444 char *object_path = NULL;
2445 GVariantIter *interface_iter;
2446 GVariantIter *svc_iter;
2447 char *interface_str = NULL;
2449 /* Parse the signature: oa{sa{sv}}} */
2450 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2453 if (object_path == NULL)
2456 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2457 &interface_str, &svc_iter)) {
2458 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2459 BT_DBG("Found a device: %s", object_path);
2460 dev_info = __bt_parse_device_info(svc_iter);
2462 if (dev_info->paired == TRUE) {
2463 g_array_append_vals(*dev_list, dev_info,
2464 sizeof(bluetooth_device_info_t));
2468 g_free(interface_str);
2469 g_variant_iter_free(svc_iter);
2477 int _bt_get_bonded_devices(GArray **dev_list)
2480 GDBusConnection *conn;
2481 GDBusProxy *manager_proxy;
2482 GVariant *result = NULL;
2483 GVariantIter *iter = NULL;
2484 GError *error = NULL;
2486 conn = _bt_gdbus_get_system_gconn();
2487 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2489 manager_proxy = _bt_get_manager_proxy();
2490 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2492 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2494 G_DBUS_CALL_FLAGS_NONE,
2500 if (error != NULL) {
2501 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2502 g_clear_error(&error);
2504 BT_ERR("Failed to Failed to GetManagedObjects");
2505 return BLUETOOTH_ERROR_INTERNAL;
2508 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2509 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2511 __bt_extract_device_info(iter, dev_list);
2512 g_variant_iter_free(iter);
2513 g_variant_unref(result);
2516 return BLUETOOTH_ERROR_NONE;
2519 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2522 GDBusConnection *conn;
2523 GDBusProxy *manager_proxy;
2524 GVariant *result = NULL;
2525 GVariant *result1 = NULL;
2526 GVariantIter *iter = NULL;
2527 GError *error = NULL;
2528 char *object_path = NULL;
2529 GVariantIter *interface_iter;
2530 char *interface_str = NULL;
2531 GDBusProxy *device_proxy = NULL;
2532 gboolean is_connected = FALSE;
2534 conn = _bt_gdbus_get_system_gconn();
2535 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2537 manager_proxy = _bt_get_manager_proxy();
2538 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2540 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2542 G_DBUS_CALL_FLAGS_NONE,
2548 if (error != NULL) {
2549 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2550 g_clear_error(&error);
2553 BT_ERR("Failed to Failed to GetManagedObjects");
2554 return BLUETOOTH_ERROR_INTERNAL;
2557 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2558 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2560 /* Parse the signature: oa{sa{sv}}} */
2561 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2562 if (object_path == NULL)
2565 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2566 &interface_str, NULL)) {
2567 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2568 BT_DBG("Found a device: %s", object_path);
2569 g_free(interface_str);
2571 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2572 NULL, BT_BLUEZ_NAME,
2573 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2575 if (device_proxy == NULL) {
2576 BT_DBG("Device don't have this service");
2580 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2581 g_variant_new("(s)", profile_uuid),
2582 G_DBUS_CALL_FLAGS_NONE,
2587 if (result1 == NULL) {
2588 BT_ERR("Error occured in Proxy call");
2590 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2591 g_error_free(error);
2594 g_object_unref(device_proxy);
2597 g_variant_get(result1, "(b)", &is_connected);
2599 if (is_connected == TRUE) {
2600 char address[BT_ADDRESS_STRING_SIZE];
2601 bluetooth_device_address_t *addr = NULL;
2603 _bt_convert_device_path_to_address(object_path, address);
2605 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2606 _bt_convert_addr_string_to_type(addr->addr, address);
2608 g_array_append_vals(*addr_list, addr,
2609 sizeof(bluetooth_device_address_t));
2612 g_variant_unref(result1);
2613 g_object_unref(device_proxy);
2620 g_variant_unref(result);
2621 g_variant_iter_free(iter);
2624 return BLUETOOTH_ERROR_NONE;
2627 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2628 bluetooth_device_info_t *dev_info)
2630 char *object_path = NULL;
2631 GDBusProxy *adapter_proxy;
2632 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2633 int ret = BLUETOOTH_ERROR_NONE;
2635 BT_CHECK_PARAMETER(device_address, return);
2636 BT_CHECK_PARAMETER(dev_info, return);
2638 adapter_proxy = _bt_get_adapter_proxy();
2639 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2641 _bt_convert_addr_type_to_string(address, device_address->addr);
2643 object_path = _bt_get_device_object_path(address);
2645 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2647 ret = __bt_get_bonded_device_info(object_path, dev_info);
2648 g_free(object_path);
2653 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2655 char *object_path = NULL;
2656 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2657 gboolean alias_set = FALSE;
2659 GDBusConnection *conn;
2660 GDBusProxy *device_proxy;
2661 GError *error = NULL;
2662 GVariant *result = NULL;
2663 GVariant *temp = NULL;
2666 BT_CHECK_PARAMETER(device_address, return);
2667 BT_CHECK_PARAMETER(is_alias_set, return);
2669 _bt_convert_addr_type_to_string(address, device_address->addr);
2671 object_path = _bt_get_device_object_path(address);
2672 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2674 conn = _bt_gdbus_get_system_gconn();
2676 g_free(object_path);
2677 return BLUETOOTH_ERROR_INTERNAL;
2680 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2684 BT_PROPERTIES_INTERFACE,
2686 if (device_proxy == NULL) {
2687 g_free(object_path);
2688 return BLUETOOTH_ERROR_INTERNAL;
2691 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2692 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2693 G_DBUS_CALL_FLAGS_NONE,
2699 BT_ERR("Error occured in Proxy call");
2700 if (error != NULL) {
2701 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2702 g_error_free(error);
2704 g_object_unref(device_proxy);
2705 g_free(object_path);
2706 return BLUETOOTH_ERROR_INTERNAL;
2709 g_variant_get(result, "(v)", &temp);
2710 alias_set = g_variant_get_boolean(temp);
2711 *is_alias_set = alias_set;
2712 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2713 g_variant_unref(temp);
2714 g_variant_unref(result);
2715 g_object_unref(device_proxy);
2717 g_free(object_path);
2719 return BLUETOOTH_ERROR_NONE;
2722 int _bt_get_timeout_value(int *timeout)
2724 time_t current_time;
2727 /* Take current time */
2728 time(¤t_time);
2729 time_diff = difftime(current_time, visible_timer.start_time);
2731 BT_DBG("Time diff = %d\n", time_diff);
2733 *timeout = visible_timer.timeout - time_diff;
2735 return BLUETOOTH_ERROR_NONE;
2738 int _bt_set_le_privacy(gboolean set_privacy)
2741 GError *error = NULL;
2742 GVariant *result = NULL;
2744 if (__bt_is_factory_test_mode()) {
2745 BT_ERR("Unable to set le privacy in factory binary !!");
2746 return BLUETOOTH_ERROR_NOT_SUPPORT;
2749 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2750 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2751 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2754 proxy = _bt_get_adapter_proxy();
2755 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2757 result = g_dbus_proxy_call_sync(proxy,
2759 g_variant_new("(b)", set_privacy),
2760 G_DBUS_CALL_FLAGS_NONE,
2766 if (error != NULL) {
2767 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2768 g_clear_error(&error);
2770 BT_ERR("Failed to SetLePrivacy");
2771 return BLUETOOTH_ERROR_INTERNAL;
2774 g_variant_unref(result);
2775 BT_INFO("SetLePrivacy as %d", set_privacy);
2776 return BLUETOOTH_ERROR_NONE;
2779 int _bt_set_le_static_random_address(gboolean is_enable)
2782 GError *error = NULL;
2783 GVariant *result = NULL;
2785 if (__bt_is_factory_test_mode()) {
2786 BT_ERR("Unable to set le random address in factory binary !!");
2787 return BLUETOOTH_ERROR_NOT_SUPPORT;
2790 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2791 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2792 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2795 proxy = _bt_get_adapter_proxy();
2796 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2798 result = g_dbus_proxy_call_sync(proxy,
2799 "SetLeStaticRandomAddress",
2800 g_variant_new("(b)", is_enable),
2801 G_DBUS_CALL_FLAGS_NONE,
2807 if (error != NULL) {
2808 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2809 g_clear_error(&error);
2811 BT_ERR("Failed to SetLeStaticRandomAddress");
2812 return BLUETOOTH_ERROR_INTERNAL;
2815 g_variant_unref(result);
2816 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2817 return BLUETOOTH_ERROR_NONE;
2820 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2823 GError *error = NULL;
2827 GVariantBuilder *builder;
2829 BT_CHECK_PARAMETER(m_data, return);
2831 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2832 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2833 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2836 proxy = _bt_get_adapter_proxy();
2837 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2839 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2841 for (i = 0; i < (m_data->data_len) + 2; i++)
2842 g_variant_builder_add(builder, "y", m_data->data[i]);
2844 val = g_variant_new("(ay)", builder);
2846 result = g_dbus_proxy_call_sync(proxy,
2847 "SetManufacturerData",
2849 G_DBUS_CALL_FLAGS_NONE,
2853 g_variant_builder_unref(builder);
2855 if (error != NULL) {
2856 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2857 g_clear_error(&error);
2859 BT_ERR("Failed to SetManufacturerData");
2861 return BLUETOOTH_ERROR_INTERNAL;
2863 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2865 for (i = 0; i < (m_data->data_len) + 2; i++)
2866 g_variant_builder_add(builder, "y", m_data->data[i]);
2868 val = g_variant_new("(ay)", builder);
2870 _bt_send_event(BT_ADAPTER_EVENT,
2871 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2874 BT_INFO("Set manufacturer data");
2876 g_variant_builder_unref(builder);
2877 g_variant_unref(result);
2879 return BLUETOOTH_ERROR_NONE;
2883 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2885 int result = BLUETOOTH_ERROR_NONE;
2886 bt_service_alarm_t *alarm = NULL;
2888 if (!call_back || !alarm_id)
2889 return BLUETOOTH_ERROR_INVALID_PARAM;
2891 if (!alarm_mgr.is_alarm_initialized) {
2892 result = alarmmgr_init("bt-service");
2894 BT_ERR("Failed to initialize alarm = %d", result);
2895 result = BLUETOOTH_ERROR_INTERNAL;
2898 result = alarmmgr_set_cb(alarm_cb, NULL);
2900 BT_ERR("Failed to set the callback = %d", result);
2901 result = BLUETOOTH_ERROR_INTERNAL;
2904 alarm_mgr.is_alarm_initialized = TRUE;
2907 alarm = g_malloc0(sizeof(bt_service_alarm_t));
2909 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2911 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
2914 BT_ERR("Failed to create alarm error = %d", result);
2915 result = BLUETOOTH_ERROR_INTERNAL;
2919 alarm->alarm_id = *alarm_id;
2920 alarm->callback = call_back;
2921 alarm->user_data = user_data;
2923 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
2924 result = BLUETOOTH_ERROR_NONE;
2929 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
2932 bt_service_alarm_t *p_data;
2933 bt_set_alarm_cb callback = NULL;
2934 void *user_data = NULL;
2936 node = g_list_find_custom(alarm_mgr.g_alarm_list,
2937 GINT_TO_POINTER(alarm_id), compare_alarm);
2941 p_data = (bt_service_alarm_t *)node->data;
2942 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
2948 callback = p_data->callback;
2949 user_data = p_data->user_data;
2953 callback(alarm_id, user_data);
2958 int _bt_service_remove_alarm(alarm_id_t alarm_id)
2961 bt_service_alarm_t *p_data;
2962 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
2965 alarmmgr_remove_alarm(alarm_id);
2966 p_data = (bt_service_alarm_t *)list->data;
2967 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
2974 gint compare_alarm(gconstpointer list_data, gconstpointer data)
2977 alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
2979 alarm_id_t alarm_id = (alarm_id_t)data;
2981 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
2983 if (p_data->alarm_id == alarm_id)
2989 static void alarm_data_free(void *data)
2991 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
2996 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3000 int function = (int)(uintptr_t)user_data;
3002 int function = (int)user_data;
3006 case BT_ENABLE_ADAPTER:
3007 result = _bt_enable_adapter();
3008 if (result != BLUETOOTH_ERROR_NONE) {
3009 BT_ERR("_bt_enable_adapter is failed");
3010 /* Send enabled event to API */
3011 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3012 g_variant_new("(i)", result));
3015 case BT_DISABLE_ADAPTER:
3016 result = _bt_disable_adapter();
3017 if (result != BLUETOOTH_ERROR_NONE) {
3018 BT_ERR("_bt_disable_adapter is failed");
3019 /* Send disabled event to API */
3020 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3021 g_variant_new("(i)", result));
3025 BT_ERR("function is NOT matched");
3032 int _bt_adapter_request_delayed(int function)
3037 case BT_ENABLE_ADAPTER:
3038 ret = _bt_enable_adapter_check_status();
3039 if (ret == BLUETOOTH_ERROR_NONE)
3040 _bt_adapter_set_status(BT_ACTIVATING);
3045 case BT_DISABLE_ADAPTER:
3046 ret = _bt_disable_adapter_check_status();
3047 if (ret == BLUETOOTH_ERROR_NONE)
3048 _bt_adapter_set_status(BT_DEACTIVATING);
3054 BT_ERR("function is NOT matched");
3055 return BLUETOOTH_ERROR_INTERNAL;
3059 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3061 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3064 return BLUETOOTH_ERROR_NONE;
3067 int _bt_get_enable_timer_id(void)