2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <syspopup_caller.h>
26 #include <eventsystem.h>
27 #include <bundle_internal.h>
30 #include "bluetooth-api.h"
31 #include "bt-internal-types.h"
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
34 #include "bt-service-adapter.h"
35 #include "bt-service-util.h"
36 #include "bt-service-network.h"
37 #include "bt-service-obex-server.h"
38 #include "bt-service-opp-client.h"
39 #include "bt-service-map-client.h"
40 #include "bt-service-agent.h"
41 #include "bt-service-main.h"
42 #include "bt-service-avrcp.h"
43 #include "bt-service-device.h"
44 #ifdef TIZEN_FEATURE_BT_DPM
45 #include "bt-service-dpm.h"
55 bt_adapter_timer_t visible_timer = {0, };
59 bt_set_alarm_cb callback;
64 gboolean is_alarm_initialized;
66 } bt_service_alarm_mgr_t;
68 #define BT_RECOVERY_MAX_COUNT 3
70 static bt_service_alarm_mgr_t alarm_mgr = {0, };
72 static gboolean is_discovering;
73 static gboolean discovery_req;
74 static gboolean cancel_by_user;
75 static bt_status_t adapter_status = BT_DEACTIVATED;
76 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
77 static gboolean is_le_intended = FALSE;
78 static void *adapter_agent = NULL;
79 static GDBusProxy *core_proxy = NULL;
80 static guint timer_id = 0;
81 static guint le_timer_id = 0;
82 static int recovery_cnt = BT_RECOVERY_MAX_COUNT;
83 static guint recovery_timer = 0;
85 static uint status_reg_id;
87 #define BT_CORE_NAME "org.projectx.bt_core"
88 #define BT_CORE_PATH "/org/projectx/bt_core"
89 #define BT_CORE_INTERFACE "org.projectx.btcore"
91 #define BT_DISABLE_TIME 500 /* 500 ms */
93 #define BT_RECOVERY_TIME_W 2000 /*2 sec*/
94 #define BT_RECOVERY_TIME 5000 /*5 sec*/
96 static int alarm_cb(alarm_id_t alarm_id, void* user_param);
97 static void alarm_data_free(void *data);
99 GDBusProxy *_bt_init_core_proxy(void)
102 GDBusConnection *conn;
104 conn = _bt_gdbus_get_system_gconn();
108 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
123 static GDBusProxy *__bt_get_core_proxy(void)
125 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
128 static gboolean __bt_is_factory_test_mode(void)
132 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
133 BT_ERR("Get the DUT Mode fail");
138 BT_INFO("DUT Test Mode !!");
145 static gboolean __bt_timeout_handler(gpointer user_data)
147 int result = BLUETOOTH_ERROR_NONE;
151 /* Take current time */
153 time_diff = difftime(current_time, visible_timer.start_time);
155 /* Send event to application */
156 _bt_send_event(BT_ADAPTER_EVENT,
157 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
158 g_variant_new("(in)", result, time_diff));
160 if (visible_timer.timeout <= time_diff) {
161 g_source_remove(visible_timer.event_id);
162 visible_timer.event_id = 0;
163 visible_timer.timeout = 0;
165 if (!TIZEN_PROFILE_WEARABLE) {
166 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
167 BT_ERR("Set vconf failed\n");
175 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
178 int result = BLUETOOTH_ERROR_NONE;
181 if (alarm_id != visible_timer.alarm_id)
184 if (visible_timer.event_id) {
185 _bt_send_event(BT_ADAPTER_EVENT,
186 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
187 g_variant_new("(in)", result, timeout));
188 g_source_remove(visible_timer.event_id);
189 visible_timer.event_id = 0;
190 visible_timer.timeout = 0;
192 if (!TIZEN_PROFILE_WEARABLE) {
193 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
194 BT_ERR("Set vconf failed\n");
197 /* Switch Off visibility in Bluez */
198 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
199 visible_timer.alarm_id = 0;
203 static void __bt_visibility_alarm_remove()
205 if (visible_timer.event_id > 0) {
206 g_source_remove(visible_timer.event_id);
207 visible_timer.event_id = 0;
210 if (visible_timer.alarm_id > 0) {
211 _bt_service_remove_alarm(visible_timer.alarm_id);
212 visible_timer.alarm_id = 0;
216 int __bt_set_visible_time(int timeout)
220 #ifdef TIZEN_FEATURE_BT_DPM
221 int discoverable_state = DPM_BT_ERROR;
224 __bt_visibility_alarm_remove();
226 visible_timer.timeout = timeout;
228 if (!TIZEN_PROFILE_WEARABLE) {
229 #ifdef TIZEN_FEATURE_BT_DPM
230 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
231 if (discoverable_state != DPM_RESTRICTED) {
233 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
234 BT_ERR("Set vconf failed");
235 #ifdef TIZEN_FEATURE_BT_DPM
242 return BLUETOOTH_ERROR_NONE;
244 result = _bt_service_set_alarm(visible_timer.timeout,
245 __bt_visibility_alarm_cb, NULL, &alarm_id);
246 if (result != BLUETOOTH_ERROR_NONE)
247 return BLUETOOTH_ERROR_INTERNAL;
248 visible_timer.alarm_id = alarm_id;
249 /* Take start time */
250 time(&(visible_timer.start_time));
251 visible_timer.event_id = g_timeout_add_seconds(1,
252 __bt_timeout_handler, NULL);
254 return BLUETOOTH_ERROR_NONE;
257 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
264 ret_if(value == NULL);
267 dev->service_index = 0;
269 g_variant_get(value, "as", &iter);
270 while (g_variant_iter_loop(iter, "s", &uuid)) {
271 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
272 parts = g_strsplit(uuid, "-", -1);
274 if (parts == NULL || parts[0] == NULL) {
279 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
282 dev->service_index++;
285 g_variant_iter_free(iter);
288 static int __bt_get_bonded_device_info(gchar *device_path,
289 bluetooth_device_info_t *dev_info)
291 GError *error = NULL;
292 GDBusProxy *device_proxy;
293 gchar *address = NULL;
295 unsigned int cod = 0;
297 gboolean trust = FALSE;
298 gboolean paired = FALSE;
299 guchar connected = 0;
300 GByteArray *manufacturer_data = NULL;
302 GDBusConnection *conn;
304 GVariantIter *property_iter;
308 GVariantIter *char_value_iter;
310 BT_CHECK_PARAMETER(device_path, return);
311 BT_CHECK_PARAMETER(dev_info, return);
313 conn = _bt_gdbus_get_system_gconn();
314 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
316 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
320 BT_PROPERTIES_INTERFACE,
323 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
325 result = g_dbus_proxy_call_sync(device_proxy,
327 g_variant_new("(s)", BT_DEVICE_INTERFACE),
328 G_DBUS_CALL_FLAGS_NONE,
334 BT_ERR("Error occured in Proxy call");
336 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
337 g_clear_error(&error);
339 g_object_unref(device_proxy);
340 return BLUETOOTH_ERROR_INTERNAL;
343 g_object_unref(device_proxy);
345 g_variant_get(result, "(a{sv})", &property_iter);
347 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
348 if (!g_strcmp0(key, "Paired")) {
349 paired = g_variant_get_boolean(value);
350 } else if (!g_strcmp0(key, "Address")) {
351 g_variant_get(value, "s", &address);
352 } else if (!g_strcmp0(key, "Alias")) {
353 g_variant_get(value, "s", &name);
354 } else if (!g_strcmp0(key, "Name")) {
356 g_variant_get(value, "s", &name);
357 } else if (!g_strcmp0(key, "Class")) {
358 cod = g_variant_get_uint32(value);
359 } else if (!g_strcmp0(key, "Connected")) {
360 connected = g_variant_get_byte(value);
361 } else if (!g_strcmp0(key, "Trusted")) {
362 trust = g_variant_get_boolean(value);
363 } else if (!g_strcmp0(key, "RSSI")) {
364 rssi = g_variant_get_int16(value);
365 } else if (!g_strcmp0(key, "UUIDs")) {
366 __bt_get_service_list(value, dev_info);
367 } else if (!g_strcmp0(key, "ManufacturerDataLen")) {
368 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
369 } else if (!g_strcmp0(key, "ManufacturerData")) {
370 manufacturer_data = g_byte_array_new();
371 g_variant_get(value, "ay", &char_value_iter);
372 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
373 g_byte_array_append(manufacturer_data, &char_value, 1);
375 g_variant_iter_free(char_value_iter);
377 if (manufacturer_data) {
378 if (manufacturer_data->len > 0) {
379 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
380 manufacturer_data->len);
383 g_byte_array_free(manufacturer_data, TRUE);
386 g_variant_iter_free(property_iter);
388 BT_DBG("trust: %d, paired: %d", trust, paired);
390 g_variant_unref(result);
392 if ((paired == FALSE) && (trust == FALSE)) {
395 return BLUETOOTH_ERROR_NOT_PAIRED;
398 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
401 _bt_divide_device_class(&dev_info->device_class, cod);
403 g_strlcpy(dev_info->device_name.name, name,
404 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
406 dev_info->rssi = rssi;
407 dev_info->trust = trust;
408 dev_info->paired = paired;
409 dev_info->connected = connected;
410 ret = BLUETOOTH_ERROR_NONE;
417 void _bt_set_discovery_status(gboolean mode)
419 is_discovering = mode;
420 discovery_req = FALSE;
423 void _bt_set_cancel_by_user(gboolean value)
425 cancel_by_user = value;
428 gboolean _bt_get_cancel_by_user(void)
430 return cancel_by_user;
433 void _bt_adapter_set_status(bt_status_t status)
435 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
436 adapter_status = status;
439 bt_status_t _bt_adapter_get_status(void)
441 return adapter_status;
444 void _bt_adapter_set_le_status(bt_le_status_t status)
446 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
447 adapter_le_status = status;
450 bt_le_status_t _bt_adapter_get_le_status(void)
452 return adapter_le_status;
456 void _bt_set_le_intended_status(gboolean value)
458 is_le_intended = value;
461 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
463 char *phone_name = NULL;
466 ret_if(node == NULL);
468 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
469 phone_name = vconf_keynode_get_str(node);
471 if (phone_name && strlen(phone_name) != 0) {
472 if (!g_utf8_validate(phone_name, -1,
473 (const char **)&ptr))
476 BT_INFO("device_name is changed to %s", phone_name);
477 _bt_set_local_name(phone_name);
479 BT_ERR("phone_name is NOT valid");
482 BT_ERR("vconf type is NOT string");
486 static void __bt_set_local_name(void)
488 bluetooth_device_name_t local_name;
489 char *phone_name = NULL;
493 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
494 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
495 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
500 if (strlen(phone_name) != 0) {
501 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
504 _bt_set_local_name(phone_name);
510 static int __bt_set_enabled(void)
512 int adapter_status = BT_ADAPTER_DISABLED;
513 int result = BLUETOOTH_ERROR_NONE;
516 BT_DBG("g_source is removed");
517 g_source_remove(timer_id);
521 _bt_check_adapter(&adapter_status);
523 if (adapter_status == BT_ADAPTER_DISABLED) {
524 BT_ERR("Bluetoothd is not running");
525 return BLUETOOTH_ERROR_INTERNAL;
528 if (TIZEN_PROFILE_MOBILE || TIZEN_PROFILE_IVI) {
529 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
530 if (_bt_set_discoverable_mode(
531 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
532 BT_ERR("Set connectable mode failed");
533 } else if (TIZEN_PROFILE_TV) {
534 if (_bt_set_discoverable_mode(
535 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
536 BT_ERR("Fail to set discoverable mode");
539 /* Update Bluetooth Status to notify other modules */
540 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
541 BT_ERR("Set vconf failed\n");
543 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
544 BT_ERR("Set vconf failed\n");
546 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
547 EVT_VAL_BT_ON) != ES_R_OK)
548 BT_ERR("Fail to set value");
550 /* Send enabled event to API */
551 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
552 g_variant_new("(i)", result));
554 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
555 _bt_audio_start_auto_connect(FALSE);
558 __bt_set_local_name();
559 _bt_set_discovery_status(FALSE);
561 return BLUETOOTH_ERROR_NONE;
564 void _bt_set_disabled(int result)
566 int power_off_status = 0;
569 int pm_ignore_mode = 0;
571 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
572 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
574 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
576 /* Update the vconf BT status in normal Deactivation case only */
577 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
578 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
580 BT_DBG("Update vconf for BT normal Deactivation");
582 if (result == BLUETOOTH_ERROR_TIMEOUT)
583 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
584 BT_ERR("Set vconf failed");
586 /* Update Bluetooth Status to notify other modules */
587 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
588 BT_ERR("Set vconf failed");
590 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
591 EVT_VAL_BT_OFF) != ES_R_OK)
592 BT_ERR("Fail to set value");
595 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
596 BT_ERR("Set vconf failed\n");
598 _bt_cancel_queued_transfers();
599 _bt_adapter_set_status(BT_DEACTIVATED);
600 _bt_set_discovery_status(FALSE);
602 BT_INFO("Adapter disabled");
605 static int __bt_set_le_enabled(void)
608 int result = BLUETOOTH_ERROR_NONE;
611 /* Update Bluetooth Status to notify other modules */
612 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
613 BT_ERR("Set vconf failed\n");
615 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
616 EVT_VAL_BT_LE_ON) != ES_R_OK)
617 BT_ERR("Fail to set value");
619 /* Send enabled event to API */
621 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
622 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
624 status = _bt_adapter_get_status();
625 if (status == BT_DEACTIVATED) {
626 BT_INFO("BREDR is off, turn off PSCAN");
627 _bt_set_connectable(FALSE);
629 if (le_timer_id > 0) {
630 g_source_remove(le_timer_id);
634 /* Send enabled event to API */
635 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
636 g_variant_new("(i)", result));
638 __bt_set_local_name();
641 return BLUETOOTH_ERROR_NONE;
644 void _bt_set_le_disabled(int result)
646 int power_off_status;
649 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
650 BT_DBG("ret : %d", ret);
651 BT_DBG("power_off_status : %d", power_off_status);
653 /* Update Bluetooth Status to notify other modules */
654 BT_DBG("Update vconf for BT LE normal Deactivation");
655 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
656 BT_ERR("Set vconf failed\n");
657 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
659 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
660 EVT_VAL_BT_LE_OFF) != ES_R_OK)
661 BT_ERR("Fail to set value");
663 /* Send disabled event */
664 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
665 g_variant_new("(i)", result));
668 void *_bt_get_adapter_agent(void)
670 return adapter_agent;
673 int _bt_enable_core(void)
677 GError *error = NULL;
679 proxy = __bt_get_core_proxy();
680 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
682 /* Clean up the process */
683 result = g_dbus_proxy_call_sync(proxy,
686 G_DBUS_CALL_FLAGS_NONE,
693 BT_ERR("Bt core call failed(Error: %s)", error->message);
694 g_clear_error(&error);
696 BT_ERR("Bt core call failed");
697 return BLUETOOTH_ERROR_INTERNAL;
700 g_variant_unref(result);
701 return BLUETOOTH_ERROR_NONE;
704 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
706 gboolean flight_mode = FALSE;
707 int power_saving_mode = 0;
710 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
711 type = vconf_keynode_get_type(node);
712 if (type == VCONF_TYPE_BOOL) {
713 flight_mode = vconf_keynode_get_bool(node);
714 if (flight_mode != TRUE) {
715 BT_ERR("Ignore the event");
718 } else if (type == VCONF_TYPE_INT) {
719 power_saving_mode = vconf_keynode_get_int(node);
720 if (power_saving_mode != 2) {
721 BT_ERR("Ignore the event");
725 BT_ERR("Invaild vconf key type : %d", type);
732 void _bt_service_register_vconf_handler(void)
736 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
737 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
738 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
739 BT_ERR("Unable to register key handler");
741 BT_DBG("Telephony is disabled");
744 if (!TIZEN_PROFILE_WEARABLE) {
745 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
746 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
747 BT_ERR("Unable to register key handler");
751 void _bt_service_unregister_vconf_handler(void)
755 if (TIZEN_FEATURE_FLIGHTMODE_ENABLED) {
756 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
757 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
760 if (!TIZEN_PROFILE_WEARABLE) {
761 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
762 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
766 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
768 const char *bt_status = NULL;
769 const char *bt_le_status = NULL;
770 BT_DBG("bt state set event(%s) received", event_name);
772 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
773 BT_DBG("bt_state: (%s)", bt_status);
775 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
776 BT_DBG("bt_state: (%s)", bt_le_status);
779 static gboolean __bt_adapter_recovery_cb(gpointer data)
787 _bt_service_initialize();
789 ret = _bt_enable_adapter_check_status();
790 if (ret == BLUETOOTH_ERROR_NONE) {
791 ret = _bt_enable_adapter();
793 BT_ERR("_bt_enable_adapter() failed");
795 ret = _bt_enable_adapter_le();
797 BT_ERR("_bt_enable_adapter_le() failed");
807 void _bt_handle_adapter_added(void)
811 bt_le_status_t le_status;
815 BT_DBG("g_source is removed");
816 g_source_remove(timer_id);
823 status = _bt_adapter_get_status();
824 le_status = _bt_adapter_get_le_status();
825 BT_INFO("status : %d", status);
826 BT_INFO("le_status : %d", le_status);
827 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
828 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
829 if (!adapter_agent) {
830 BT_ERR("Fail to register agent");
834 if (adapter_agent == NULL) {
835 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
836 if (!adapter_agent) {
837 BT_ERR("Fail to register agent");
843 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
844 BT_ERR("Fail to register media player");
846 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
847 BT_ERR("Fail to init obex server");
849 #ifdef TIZEN_BT_PAN_NAP_ENABLED
850 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
851 BT_ERR("Fail to activate network");
854 /* add the vconf noti handler */
855 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
856 __bt_phone_name_changed_cb, NULL);
858 BT_ERR("Unable to register key handler");
860 if (le_status == BT_LE_ACTIVATING ||
861 status == BT_ACTIVATING) {
862 __bt_set_le_enabled();
863 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
866 if (status == BT_ACTIVATING) {
868 _bt_adapter_set_status(BT_ACTIVATED);
872 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
873 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
874 BT_ERR("Fail to register system event");
878 void _bt_handle_adapter_removed(void)
882 _bt_adapter_set_status(BT_DEACTIVATED);
884 __bt_visibility_alarm_remove();
886 if (alarm_mgr.is_alarm_initialized == TRUE) {
888 alarm_mgr.is_alarm_initialized = FALSE;
889 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
890 alarm_mgr.g_alarm_list = NULL;
893 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
894 _bt_audio_stop_auto_connect();
897 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
898 (vconf_callback_fn)__bt_phone_name_changed_cb);
900 ERR("vconf_ignore_key_changed failed\n");
902 /* unregister all the services/servers/profiles registered on bluez-adapter
903 once adapter is removed, reinitializing of the state-varaibles becomes
905 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
906 BT_ERR("Fail to unregister obex server");
908 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
909 BT_ERR("Fail to unregister media player");
911 /* Other unregister APIs should be placed here */
913 if (!TIZEN_FEATURE_BT_USB_DONGLE) {
914 _bt_destroy_agent(adapter_agent);
915 adapter_agent = NULL;
917 if (recovery_cnt > 0) {
918 /* Send disabled event */
919 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
920 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
921 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
923 if (recovery_timer > 0)
924 g_source_remove(recovery_timer);
926 if (TIZEN_PROFILE_WEARABLE) {
927 recovery_timer = g_timeout_add(BT_RECOVERY_TIME_W,
928 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
930 recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
931 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
934 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
935 BT_ERR("Fail to unregister system event");
939 if (recovery_timer == 0)
940 _bt_reliable_terminate_service(NULL);
942 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
943 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
944 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
947 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
948 BT_ERR("Fail to unregister system event");
951 static gboolean __bt_enable_timeout_cb(gpointer user_data)
955 GError *error = NULL;
959 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
961 BT_ERR("EnableAdapter is failed");
963 proxy = __bt_get_core_proxy();
967 /* Clean up the process */
968 result = g_dbus_proxy_call_sync(proxy,
971 G_DBUS_CALL_FLAGS_NONE,
978 BT_ERR("Bt core call failed(Error: %s)", error->message);
979 g_clear_error(&error);
981 BT_ERR("Bt core call failed");
986 g_variant_unref(result);
987 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
989 if (recovery_cnt > 0) {
990 BT_ERR("Try recovery again(remain:%d)", recovery_cnt);
991 if (recovery_timer > 0)
992 g_source_remove(recovery_timer);
994 if (TIZEN_PROFILE_WEARABLE) {
995 recovery_timer = g_timeout_add(BT_RECOVERY_TIME_W,
996 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
998 recovery_timer = g_timeout_add(BT_RECOVERY_TIME,
999 (GSourceFunc)__bt_adapter_recovery_cb, NULL);
1005 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1006 _bt_terminate_service(NULL);
1011 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
1015 GError *error = NULL;
1019 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
1021 BT_ERR("EnableAdapterLE is failed");
1023 proxy = __bt_get_core_proxy();
1027 /* Clean up the process */
1028 result = g_dbus_proxy_call_sync(proxy,
1031 G_DBUS_CALL_FLAGS_NONE,
1037 if (error != NULL) {
1038 BT_ERR("Bt core call failed(Error: %s)", error->message);
1039 g_clear_error(&error);
1041 BT_ERR("Bt core call failed");
1045 g_variant_unref(result);
1047 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED)
1048 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
1050 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1051 _bt_terminate_service(NULL);
1056 void _bt_adapter_start_le_enable_timer(void)
1058 if (le_timer_id > 0) {
1059 g_source_remove(le_timer_id);
1063 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1064 __bt_enable_le_timeout_cb, NULL);
1069 void _bt_adapter_start_enable_timer(void)
1072 g_source_remove(timer_id);
1076 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1077 __bt_enable_timeout_cb, NULL);
1082 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1087 _bt_adapter_set_status(BT_ACTIVATED);
1092 int _bt_enable_adapter_check_status(void)
1094 bt_status_t status = _bt_adapter_get_status();
1095 bt_le_status_t le_status = _bt_adapter_get_le_status();
1099 if (status == BT_ACTIVATING) {
1100 BT_ERR("Enabling in progress");
1101 return BLUETOOTH_ERROR_IN_PROGRESS;
1104 if (status == BT_ACTIVATED) {
1105 BT_ERR("Already enabled");
1106 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1109 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1110 BT_ERR("Disabling in progress");
1111 return BLUETOOTH_ERROR_DEVICE_BUSY;
1114 return BLUETOOTH_ERROR_NONE;
1117 int _bt_enable_adapter(void)
1120 GError *error = NULL;
1122 GVariant *result = NULL;
1123 bt_status_t status = _bt_adapter_get_status();
1124 bt_le_status_t le_status = _bt_adapter_get_le_status();
1128 if (status == BT_ACTIVATING) {
1129 BT_ERR("Enabling in progress");
1130 return BLUETOOTH_ERROR_IN_PROGRESS;
1133 if (status == BT_ACTIVATED) {
1134 BT_ERR("Already enabled");
1135 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1138 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1139 BT_ERR("Disabling in progress");
1140 return BLUETOOTH_ERROR_DEVICE_BUSY;
1143 _bt_adapter_set_status(BT_ACTIVATING);
1145 if (TIZEN_PROFILE_TV) {
1146 int adapter_status = BT_ADAPTER_DISABLED;
1148 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1149 BT_ERR("Set vconf failed");
1151 _bt_check_adapter(&adapter_status);
1152 if (adapter_status == BT_ADAPTER_ENABLED) {
1153 g_idle_add(__bt_adapter_enabled_cb, NULL);
1154 _bt_adapter_start_enable_timer();
1155 return BLUETOOTH_ERROR_NONE;
1159 proxy = __bt_get_core_proxy();
1161 return BLUETOOTH_ERROR_INTERNAL;
1163 if (le_status == BT_LE_ACTIVATED) {
1164 BT_INFO("LE Already enabled. Just turn on PSCAN");
1165 ret = _bt_set_connectable(TRUE);
1166 if (ret == BLUETOOTH_ERROR_NONE)
1167 _bt_adapter_set_status(BT_ACTIVATED);
1169 return BLUETOOTH_ERROR_INTERNAL;
1172 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1174 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1177 BT_ERR("EnableAdapterLe failed: %s", error->message);
1178 _bt_adapter_set_status(BT_DEACTIVATED);
1179 g_clear_error(&error);
1181 result = g_dbus_proxy_call_sync(proxy,
1184 G_DBUS_CALL_FLAGS_NONE,
1189 if (error != NULL) {
1190 BT_ERR("Bt core call failed(Error: %s)", error->message);
1191 g_clear_error(&error);
1193 g_variant_unref(result);
1194 /* Terminate myself */
1195 if (!TIZEN_FEATURE_BT_USB_DONGLE)
1196 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1197 return BLUETOOTH_ERROR_INTERNAL;
1199 g_variant_unref(result);
1200 if (le_status == BT_LE_ACTIVATED)
1203 _bt_adapter_start_enable_timer();
1205 return BLUETOOTH_ERROR_NONE;
1208 static gboolean __bt_set_powered(gboolean powered)
1211 GError *error = NULL;
1216 proxy = _bt_get_adapter_properties_proxy();
1217 retv_if(proxy == NULL, FALSE);
1219 result = g_dbus_proxy_call_sync(proxy, "Set",
1220 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Powered",
1221 g_variant_new("b", powered)),
1222 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
1224 if (error != NULL) {
1225 BT_ERR("Failed to set powered property (Error: %s)",
1227 g_clear_error(&error);
1229 BT_ERR("Failed to set powered property");
1234 BT_INFO("Set powered [%d]", powered);
1235 g_variant_unref(result);
1239 static gboolean __bt_disconnect_all(void)
1242 GDBusConnection *conn;
1243 GDBusProxy *dev_proxy;
1244 gboolean ret = FALSE;
1246 GError *error = NULL;
1247 GArray *device_list;
1248 bluetooth_device_info_t info;
1250 char *device_path = NULL;
1251 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1256 conn = _bt_gdbus_get_system_gconn();
1258 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1260 if (_bt_get_bonded_devices(&device_list)
1261 != BLUETOOTH_ERROR_NONE) {
1262 g_array_free(device_list, TRUE);
1266 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1268 for (i = 0; i < size; i++) {
1270 info = g_array_index(device_list,
1271 bluetooth_device_info_t, i);
1273 if (info.connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1274 BT_DBG("Found Connected device");
1275 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1276 device_path = _bt_get_device_object_path(address);
1277 if (device_path == NULL)
1280 BT_DBG("Disconnecting : %s", device_path);
1282 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1286 BT_DEVICE_INTERFACE,
1289 if (dev_proxy == NULL)
1292 result = g_dbus_proxy_call_sync(dev_proxy,
1295 G_DBUS_CALL_FLAGS_NONE,
1301 if (error != NULL) {
1302 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1303 g_clear_error(&error);
1305 BT_ERR("Disconnect call failed");
1306 g_object_unref(dev_proxy);
1310 g_variant_unref(result);
1311 g_object_unref(dev_proxy);
1315 g_array_free(device_list, TRUE);
1321 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1324 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1325 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
1326 g_variant_new("(i)", BLUETOOTH_ERROR_NONE));
1332 int _bt_disable_cb(void)
1340 GError *error = NULL;
1342 _bt_adapter_set_status(BT_DEACTIVATING);
1344 bt_le_status_t le_status;
1345 le_status = _bt_adapter_get_le_status();
1346 BT_DBG("le_status : %d", le_status);
1347 if (le_status == BT_LE_ACTIVATED) {
1348 BT_INFO("LE is enabled. Just turn off PSCAN");
1350 if (_bt_is_discovering())
1351 _bt_cancel_discovery();
1353 if (_bt_is_connectable() == FALSE) {
1354 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1356 ret = _bt_set_connectable(FALSE);
1357 if (ret != BLUETOOTH_ERROR_NONE) {
1358 BT_ERR("_bt_set_connectable fail!");
1359 _bt_adapter_set_status(BT_ACTIVATED);
1360 return BLUETOOTH_ERROR_INTERNAL;
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 DisableAdapter (Error: %s)", error->message);
1379 g_clear_error(&error);
1381 BT_ERR("Failed to DisableAdapter");
1382 _bt_adapter_set_status(BT_ACTIVATED);
1383 return BLUETOOTH_ERROR_INTERNAL;
1386 g_variant_unref(result);
1387 return BLUETOOTH_ERROR_NONE;
1390 int _bt_disable_adapter_check_status(void)
1392 bt_status_t status = _bt_adapter_get_status();
1396 if (status == BT_DEACTIVATING) {
1397 BT_DBG("Disabling in progress");
1398 return BLUETOOTH_ERROR_IN_PROGRESS;
1401 if (status == BT_DEACTIVATED) {
1402 BT_DBG("Already disabled");
1403 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1406 return BLUETOOTH_ERROR_NONE;
1409 int _bt_disable_adapter(void)
1413 bt_le_status_t le_status;
1415 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1416 BT_DBG("Disabling in progress");
1417 return BLUETOOTH_ERROR_IN_PROGRESS;
1420 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1421 BT_DBG("Already disabled");
1422 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1426 g_source_remove(timer_id);
1430 /* unregister all the services/servers/profiles registered on bluez-adapter
1431 once adapter is removed, reinitializing of the state-varaibles becomes
1433 if (_bt_unregister_obex_server() != BLUETOOTH_ERROR_NONE)
1434 BT_ERR("Fail to unregister obex server");
1436 if (_bt_unregister_media_player() != BLUETOOTH_ERROR_NONE)
1437 BT_ERR("Fail to unregister media player");
1438 /* Other unregister APIs should be placed here */
1440 le_status = _bt_adapter_get_le_status();
1441 if (le_status == BT_LE_ACTIVATED && is_le_intended == TRUE) {
1442 __bt_disconnect_all();
1444 if (le_status == BT_LE_ACTIVATED)
1445 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1447 __bt_set_powered(FALSE);
1450 ret = _bt_disable_cb();
1456 int _bt_recover_adapter(void)
1460 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1461 BT_DBG("Disabling in progress");
1462 return BLUETOOTH_ERROR_IN_PROGRESS;
1465 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1466 BT_DBG("Already disabled");
1467 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1470 recovery_cnt = BT_RECOVERY_MAX_COUNT;
1472 _bt_disable_adapter();
1473 _bt_disable_adapter_le();
1476 return BLUETOOTH_ERROR_NONE;
1479 int _bt_reset_adapter(void)
1483 GError *error = NULL;
1487 proxy = __bt_get_core_proxy();
1489 return BLUETOOTH_ERROR_INTERNAL;
1491 result = g_dbus_proxy_call_sync(proxy,
1494 G_DBUS_CALL_FLAGS_NONE,
1500 if (error != NULL) {
1501 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1502 g_clear_error(&error);
1504 BT_ERR("Failed to ResetAdapter");
1505 return BLUETOOTH_ERROR_INTERNAL;
1508 g_variant_unref(result);
1509 /* Terminate myself */
1510 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1511 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1513 return BLUETOOTH_ERROR_NONE;
1516 int _bt_check_adapter(int *status)
1518 if (!TIZEN_PROFILE_TV) {
1519 char *adapter_path = NULL;
1521 BT_CHECK_PARAMETER(status, return);
1523 *status = BT_ADAPTER_DISABLED;
1525 adapter_path = _bt_get_adapter_path();
1528 if (adapter_path != NULL)
1529 *status = BT_ADAPTER_ENABLED;
1531 g_free(adapter_path);
1532 return BLUETOOTH_ERROR_NONE;
1535 GError *error = NULL;
1538 gboolean powered = FALSE;
1540 BT_CHECK_PARAMETER(status, return);
1542 *status = BT_ADAPTER_DISABLED;
1544 proxy = _bt_get_adapter_properties_proxy();
1545 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1547 result = g_dbus_proxy_call_sync(proxy,
1549 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1551 G_DBUS_CALL_FLAGS_NONE,
1557 BT_ERR("Failed to get local address");
1558 if (error != NULL) {
1559 BT_ERR("Failed to get local address (Error: %s)", error->message);
1560 g_clear_error(&error);
1562 return BLUETOOTH_ERROR_INTERNAL;
1565 g_variant_get(result, "(v)", &temp);
1566 powered = g_variant_get_boolean(temp);
1567 BT_DBG("powered: %d", powered);
1570 *status = BT_ADAPTER_ENABLED;
1572 g_variant_unref(result);
1573 g_variant_unref(temp);
1574 return BLUETOOTH_ERROR_NONE;
1578 int _bt_enable_adapter_le(void)
1582 GError *error = NULL;
1583 bt_status_t status = _bt_adapter_get_status();
1584 bt_le_status_t le_status = _bt_adapter_get_le_status();
1587 if (le_status == BT_LE_ACTIVATING) {
1588 BT_ERR("Enabling in progress");
1589 return BLUETOOTH_ERROR_IN_PROGRESS;
1592 if (le_status == BT_LE_ACTIVATED) {
1593 BT_ERR("Already enabled");
1594 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1597 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1598 BT_ERR("Disabling in progress");
1599 _bt_set_le_intended_status(FALSE);
1600 return BLUETOOTH_ERROR_DEVICE_BUSY;
1603 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1605 proxy = __bt_get_core_proxy();
1606 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1608 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1610 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1613 BT_ERR("EnableAdapterLe failed: %s", error->message);
1614 _bt_adapter_set_le_status(BT_DEACTIVATED);
1615 g_clear_error(&error);
1617 /* Clean up the process */
1618 result = g_dbus_proxy_call_sync(proxy,
1621 G_DBUS_CALL_FLAGS_NONE,
1627 BT_ERR("Bt core call failed");
1629 BT_ERR("EnableAdapterLE Failed %s", error->message);
1630 g_clear_error(&error);
1633 g_variant_unref(result);
1634 /* Terminate myself */
1635 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1636 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1637 return BLUETOOTH_ERROR_INTERNAL;
1641 g_variant_unref(result);
1643 _bt_adapter_start_le_enable_timer();
1645 if (status == BT_ACTIVATED) {
1646 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1647 __bt_set_le_enabled();
1649 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1651 return BLUETOOTH_ERROR_NONE;
1654 int _bt_disable_adapter_le(void)
1658 bt_le_status_t bt_le_state;
1660 GError *error = NULL;
1662 bt_le_state = _bt_adapter_get_le_status();
1663 if (bt_le_state == BT_LE_DEACTIVATING) {
1664 BT_DBG("Disabling in progress");
1665 return BLUETOOTH_ERROR_IN_PROGRESS;
1668 if (bt_le_state == BT_LE_DEACTIVATED) {
1669 BT_DBG("Already disabled");
1670 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1673 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1675 proxy = __bt_get_core_proxy();
1677 return BLUETOOTH_ERROR_INTERNAL;
1679 result = g_dbus_proxy_call_sync(proxy,
1682 G_DBUS_CALL_FLAGS_NONE,
1688 if (error != NULL) {
1689 BT_ERR("Bt core call failed (Error: %s)", error->message);
1690 g_clear_error(&error);
1692 BT_ERR("Bt core call failed");
1693 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1694 return BLUETOOTH_ERROR_INTERNAL;
1697 g_variant_unref(result);
1698 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1699 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1701 return BLUETOOTH_ERROR_NONE;
1704 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1708 GError *error = NULL;
1709 const char *address;
1713 BT_CHECK_PARAMETER(local_address, return);
1715 proxy = _bt_get_adapter_properties_proxy();
1716 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1718 result = g_dbus_proxy_call_sync(proxy,
1720 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1722 G_DBUS_CALL_FLAGS_NONE,
1728 BT_ERR("Failed to get local address");
1729 if (error != NULL) {
1730 BT_ERR("Failed to get local address (Error: %s)", error->message);
1731 g_clear_error(&error);
1733 return BLUETOOTH_ERROR_INTERNAL;
1736 g_variant_get(result, "(v)", &temp);
1737 address = g_variant_get_string(temp, NULL);
1738 BT_DBG("Address:%s", address);
1741 _bt_convert_addr_string_to_type(local_address->addr, address);
1743 return BLUETOOTH_ERROR_INTERNAL;
1745 g_variant_unref(result);
1746 g_variant_unref(temp);
1747 return BLUETOOTH_ERROR_NONE;
1750 int _bt_get_local_version(bluetooth_version_t *local_version)
1753 const char *ver = NULL;
1755 int ret = BLUETOOTH_ERROR_NONE;
1759 BT_CHECK_PARAMETER(local_version, return);
1761 GError *error = NULL;
1763 proxy = _bt_get_adapter_properties_proxy();
1764 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1766 result = g_dbus_proxy_call_sync(proxy,
1768 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1770 G_DBUS_CALL_FLAGS_NONE,
1776 if (error != NULL) {
1777 BT_ERR("Failed to get local version (Error: %s)", error->message);
1778 g_clear_error(&error);
1780 BT_ERR("Failed to get local version");
1781 return BLUETOOTH_ERROR_INTERNAL;
1784 g_variant_get(result, "(v)", &temp);
1785 ver = g_variant_get_string(temp, NULL);
1786 BT_DBG("VERSION: %s", ver);
1788 if (ver && (strlen(ver) > 0)) {
1789 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1790 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1793 g_strlcpy(local_version->version, ver,
1794 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1797 ret = BLUETOOTH_ERROR_INTERNAL;
1800 g_variant_unref(result);
1801 g_variant_unref(temp);
1805 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1808 const char *name = NULL;
1810 int ret = BLUETOOTH_ERROR_NONE;
1813 GError *error = NULL;
1815 BT_CHECK_PARAMETER(local_name, return);
1817 proxy = _bt_get_adapter_properties_proxy();
1818 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1820 result = g_dbus_proxy_call_sync(proxy,
1822 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1824 G_DBUS_CALL_FLAGS_NONE,
1830 if (error != NULL) {
1831 BT_ERR("Failed to get local name (Error: %s)", error->message);
1832 g_clear_error(&error);
1834 BT_ERR("Failed to get local name");
1835 return BLUETOOTH_ERROR_INTERNAL;
1838 g_variant_get(result, "(v)", &temp);
1839 name = g_variant_get_string(temp, NULL);
1840 BT_DBG("LOCAL NAME:%s", name);
1842 if (name && (strlen(name) > 0)) {
1843 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1844 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1847 g_strlcpy(local_name->name, name,
1848 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1850 ret = BLUETOOTH_ERROR_INTERNAL;
1852 g_variant_unref(result);
1853 g_variant_unref(temp);
1857 int _bt_set_local_name(char *local_name)
1860 GError *error = NULL;
1864 BT_CHECK_PARAMETER(local_name, return);
1866 proxy = _bt_get_adapter_properties_proxy();
1868 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1870 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1873 result = g_dbus_proxy_call_sync(proxy,
1875 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1876 "Alias", g_variant_new("s", local_name)),
1877 G_DBUS_CALL_FLAGS_NONE,
1883 if (error != NULL) {
1884 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1885 g_clear_error(&error);
1887 BT_ERR("Failed to set Alias");
1888 return BLUETOOTH_ERROR_INTERNAL;
1891 g_variant_unref(result);
1892 return BLUETOOTH_ERROR_NONE;
1895 int _bt_is_service_used(char *service_uuid, gboolean *used)
1898 GError *error = NULL;
1899 int ret = BLUETOOTH_ERROR_NONE;
1901 GVariant *temp = NULL;
1902 GVariantIter *iter = NULL;
1906 BT_CHECK_PARAMETER(service_uuid, return);
1907 BT_CHECK_PARAMETER(used, return);
1909 proxy = _bt_get_adapter_properties_proxy();
1910 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1912 result = g_dbus_proxy_call_sync(proxy,
1914 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1916 G_DBUS_CALL_FLAGS_NONE,
1922 if (error != NULL) {
1923 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1924 g_clear_error(&error);
1926 BT_ERR("Failed to get UUIDs");
1927 return BLUETOOTH_ERROR_INTERNAL;
1930 g_variant_get(result, "(v)", &temp);
1931 g_variant_get(temp, "as", &iter);
1934 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1935 if (strcasecmp(uuid, service_uuid) == 0) {
1940 g_variant_iter_free(iter);
1941 g_variant_unref(result);
1943 BT_DBG("Service Used? %d", *used);
1948 static gboolean __bt_get_discoverable_property(void)
1951 gboolean discoverable_v;
1952 GError *error = NULL;
1956 proxy = _bt_get_adapter_properties_proxy();
1957 retv_if(proxy == NULL, FALSE);
1959 result = g_dbus_proxy_call_sync(proxy,
1961 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1963 G_DBUS_CALL_FLAGS_NONE,
1969 if (error != NULL) {
1970 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1971 g_clear_error(&error);
1973 BT_ERR("Failed to get Discoverable property");
1974 return BLUETOOTH_ERROR_INTERNAL;
1977 g_variant_get(result, "(v)", &temp);
1978 discoverable_v = g_variant_get_boolean(temp);
1979 BT_DBG("discoverable_v:%d", discoverable_v);
1981 g_variant_unref(result);
1982 g_variant_unref(temp);
1984 return discoverable_v;
1987 int _bt_get_discoverable_mode(int *mode)
1989 gboolean discoverable;
1990 unsigned int timeout;
1992 BT_CHECK_PARAMETER(mode, return);
1994 discoverable = __bt_get_discoverable_property();
1995 timeout = _bt_get_discoverable_timeout_property();
1997 if (discoverable == TRUE) {
1999 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
2001 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
2003 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
2005 return BLUETOOTH_ERROR_NONE;
2009 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
2011 int ret = BLUETOOTH_ERROR_NONE;
2014 GError *error = NULL;
2017 #ifdef TIZEN_FEATURE_BT_DPM
2018 int discoverable_state = DPM_BT_ERROR;
2021 proxy = _bt_get_adapter_properties_proxy();
2023 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2025 #ifdef TIZEN_FEATURE_BT_DPM
2026 _bt_dpm_get_bluetooth_limited_discoverable_state(&discoverable_state);
2027 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
2028 discoverable_state == DPM_RESTRICTED) {
2029 if (headed_plugin_info->plugin_headed_enabled)
2030 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT_HANDSFREE");
2032 return BLUETOOTH_ERROR_ACCESS_DENIED;
2034 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
2035 discoverable_state == DPM_RESTRICTED) {
2036 if (headed_plugin_info->plugin_headed_enabled)
2037 headed_plugin_info->headed_plugin->bt_launch_dpmpopup("DPM_POLICY_DISABLE_BT");
2039 return BLUETOOTH_ERROR_ACCESS_DENIED;
2043 switch (discoverable_mode) {
2044 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
2049 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
2054 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
2059 return BLUETOOTH_ERROR_INVALID_PARAM;
2062 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
2063 discoverable_mode, timeout);
2065 result = g_dbus_proxy_call_sync(proxy,
2067 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2068 "Connectable", g_variant_new("b", pg_scan)),
2069 G_DBUS_CALL_FLAGS_NONE,
2075 if (error != NULL) {
2076 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2077 g_clear_error(&error);
2079 BT_ERR("Failed to set connectable property");
2080 return BLUETOOTH_ERROR_INTERNAL;
2082 g_variant_unref(result);
2083 result = g_dbus_proxy_call_sync(proxy,
2085 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2086 g_variant_new("b", inq_scan)),
2087 G_DBUS_CALL_FLAGS_NONE,
2093 if (error != NULL) {
2094 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2095 g_clear_error(&error);
2097 BT_ERR("Failed to set Discoverable property");
2098 return BLUETOOTH_ERROR_INTERNAL;
2100 g_variant_unref(result);
2101 result = g_dbus_proxy_call_sync(proxy,
2103 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2104 "DiscoverableTimeout", g_variant_new("u", timeout)),
2105 G_DBUS_CALL_FLAGS_NONE,
2111 if (error != NULL) {
2112 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2113 g_clear_error(&error);
2115 BT_ERR("Failed to set DiscoverableTimeout property");
2116 return BLUETOOTH_ERROR_INTERNAL;
2119 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2122 ret = __bt_set_visible_time(timeout);
2124 g_variant_unref(result);
2129 int _bt_start_discovery(void)
2132 GError *error = NULL;
2135 if (_bt_is_discovering() == TRUE) {
2136 BT_ERR("BT is already in discovering");
2137 return BLUETOOTH_ERROR_IN_PROGRESS;
2138 } else if (_bt_is_device_creating() == TRUE) {
2139 BT_ERR("Bonding device is going on");
2140 return BLUETOOTH_ERROR_DEVICE_BUSY;
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 if (error != NULL) {
2156 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2157 g_clear_error(&error);
2159 BT_ERR("StartDiscovery failed");
2160 return BLUETOOTH_ERROR_INTERNAL;
2163 discovery_req = TRUE;
2164 cancel_by_user = FALSE;
2165 /* discovery status will be change in event */
2166 g_variant_unref(result);
2167 return BLUETOOTH_ERROR_NONE;
2170 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2174 GError *error = NULL;
2175 const gchar *disc_type;
2177 if (_bt_is_discovering() == TRUE) {
2178 BT_ERR("BT is already in discovering");
2179 return BLUETOOTH_ERROR_IN_PROGRESS;
2182 proxy = _bt_get_adapter_proxy();
2183 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2185 if (role == DISCOVERY_ROLE_BREDR)
2186 disc_type = "BREDR";
2187 else if (role == DISCOVERY_ROLE_LE)
2189 else if (role == DISCOVERY_ROLE_LE_BREDR)
2190 disc_type = "LE_BREDR";
2192 return BLUETOOTH_ERROR_INVALID_PARAM;
2194 result = g_dbus_proxy_call_sync(proxy,
2195 "StartCustomDiscovery",
2196 g_variant_new("s", disc_type),
2197 G_DBUS_CALL_FLAGS_NONE,
2203 if (error != NULL) {
2204 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2205 g_clear_error(&error);
2207 BT_ERR("StartCustomDiscovery failed");
2208 return BLUETOOTH_ERROR_INTERNAL;
2211 discovery_req = TRUE;
2212 cancel_by_user = FALSE;
2213 /* discovery status will be change in event */
2214 g_variant_unref(result);
2215 return BLUETOOTH_ERROR_NONE;
2218 int _bt_cancel_discovery(void)
2221 GError *error = NULL;
2224 if (_bt_is_discovering() == FALSE) {
2225 BT_ERR("BT is not in discovering");
2226 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2229 proxy = _bt_get_adapter_proxy();
2230 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2232 result = g_dbus_proxy_call_sync(proxy,
2235 G_DBUS_CALL_FLAGS_NONE,
2241 int ret = BLUETOOTH_ERROR_INTERNAL;
2242 if (error != NULL) {
2243 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2245 if (g_strrstr(error->message, "No discovery started"))
2246 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2248 g_clear_error(&error);
2250 BT_ERR("StopDiscovery failed");
2256 discovery_req = FALSE;
2257 cancel_by_user = TRUE;
2258 /* discovery status will be change in event */
2259 g_variant_unref(result);
2260 return BLUETOOTH_ERROR_NONE;
2263 gboolean _bt_is_discovering(void)
2265 return (is_discovering || discovery_req);
2268 gboolean _bt_is_connectable(void)
2271 GError *error = NULL;
2272 gboolean is_connectable = FALSE;
2276 proxy = _bt_get_adapter_properties_proxy();
2277 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2279 result = g_dbus_proxy_call_sync(proxy,
2281 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2283 G_DBUS_CALL_FLAGS_NONE,
2289 if (error != NULL) {
2290 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2291 g_clear_error(&error);
2293 BT_ERR("Failed to get connectable property");
2294 return BLUETOOTH_ERROR_INTERNAL;
2297 g_variant_get(result, "(v)", &temp);
2298 is_connectable = g_variant_get_boolean(temp);
2299 BT_DBG("discoverable_v:%d", is_connectable);
2301 g_variant_unref(result);
2302 g_variant_unref(temp);
2304 BT_INFO("Get connectable [%d]", is_connectable);
2305 return is_connectable;
2308 int _bt_set_connectable(gboolean is_connectable)
2311 GError *error = NULL;
2314 if (__bt_is_factory_test_mode()) {
2315 BT_ERR("Unable to set connectable in factory binary !!");
2316 return BLUETOOTH_ERROR_NOT_SUPPORT;
2319 proxy = _bt_get_adapter_properties_proxy();
2321 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2323 result = g_dbus_proxy_call_sync(proxy,
2325 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2326 g_variant_new("b", is_connectable)),
2327 G_DBUS_CALL_FLAGS_NONE,
2333 if (error != NULL) {
2334 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2335 g_clear_error(&error);
2337 BT_ERR("Failed to set connectable property");
2338 return BLUETOOTH_ERROR_INTERNAL;
2341 BT_INFO_C("### Set connectable [%d]", is_connectable);
2342 g_variant_unref(result);
2343 return BLUETOOTH_ERROR_NONE;
2346 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2349 gboolean discovering_v;
2350 GError *error = NULL;
2351 char *discovering_type = NULL;
2355 proxy = _bt_get_adapter_properties_proxy();
2356 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2358 if (discovery_type == DISCOVERY_ROLE_BREDR)
2359 discovering_type = "Discovering";
2360 else if (discovery_type == DISCOVERY_ROLE_LE)
2361 discovering_type = "LEDiscovering";
2363 result = g_dbus_proxy_call_sync(proxy,
2365 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2367 G_DBUS_CALL_FLAGS_NONE,
2373 if (error != NULL) {
2374 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2375 g_clear_error(&error);
2377 BT_ERR("Failed to get discovering property");
2378 return BLUETOOTH_ERROR_INTERNAL;
2381 g_variant_get(result, "(v)", &temp);
2382 discovering_v = g_variant_get_boolean(temp);
2383 BT_DBG("discoverable_v:%d", discovering_v);
2385 g_variant_unref(result);
2386 g_variant_unref(temp);
2388 return discovering_v;
2391 unsigned int _bt_get_discoverable_timeout_property(void)
2394 unsigned int timeout_v;
2395 GError *error = NULL;
2399 proxy = _bt_get_adapter_properties_proxy();
2400 retv_if(proxy == NULL, 0);
2402 result = g_dbus_proxy_call_sync(proxy,
2404 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2405 "DiscoverableTimeout"),
2406 G_DBUS_CALL_FLAGS_NONE,
2412 BT_ERR("Fail to get discoverable timeout");
2413 if (error != NULL) {
2414 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2415 g_clear_error(&error);
2420 g_variant_get(result, "(v)", &temp);
2421 timeout_v = g_variant_get_uint32(temp);
2422 BT_DBG("discoverable_v:%d", timeout_v);
2424 g_variant_unref(result);
2425 g_variant_unref(temp);
2430 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2432 bluetooth_device_info_t *dev_info;
2435 GByteArray *manufacturer_data = NULL;
2437 GVariantIter *char_value_iter;
2439 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2441 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2446 if (!g_strcmp0(key, "Address")) {
2447 const char *address = NULL;
2448 address = g_variant_get_string(value, NULL);
2449 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2451 } else if (!g_strcmp0(key, "Class")) {
2453 cod = g_variant_get_uint32(value);
2454 _bt_divide_device_class(&dev_info->device_class, cod);
2455 } else if (!g_strcmp0(key, "Name")) {
2456 const char *name = NULL;
2457 name = g_variant_get_string(value, NULL);
2458 /* If there is no Alias */
2459 if (strlen(dev_info->device_name.name) == 0) {
2460 g_strlcpy(dev_info->device_name.name, name,
2461 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2463 } else if (!g_strcmp0(key, "Alias")) {
2464 const char *alias = NULL;
2465 alias = g_variant_get_string(value, NULL);
2466 /* Overwrite the name */
2468 memset(dev_info->device_name.name, 0x00,
2469 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2470 g_strlcpy(dev_info->device_name.name, alias,
2471 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2473 } else if (!g_strcmp0(key, "IsAliasSet")) {
2474 dev_info->is_alias_set = g_variant_get_boolean(value);
2475 } else if (!g_strcmp0(key, "Connected")) {
2476 dev_info->connected = g_variant_get_byte(value);
2477 } else if (!g_strcmp0(key, "Paired")) {
2478 dev_info->paired = g_variant_get_boolean(value);
2479 } else if (!g_strcmp0(key, "Trusted")) {
2480 dev_info->trust = g_variant_get_boolean(value);
2481 } else if (!g_strcmp0(key, "RSSI")) {
2482 dev_info->rssi = g_variant_get_int16(value);
2483 } else if (!g_strcmp0(key, "UUIDs")) {
2489 dev_info->service_index = 0;
2490 g_variant_get(value, "as", &iter);
2491 while (g_variant_iter_loop(iter, "s", &uuid)) {
2492 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2493 parts = g_strsplit(uuid, "-", -1);
2495 if (parts == NULL || parts[0] == NULL) {
2500 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2505 dev_info->service_index = i;
2506 g_variant_iter_free(iter);
2507 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2508 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2509 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2510 manufacturer_data = g_byte_array_new();
2511 g_variant_get(value, "ay", &char_value_iter);
2512 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2513 g_byte_array_append(manufacturer_data, &char_value, 1);
2515 if (manufacturer_data) {
2516 if (manufacturer_data->len > 0)
2517 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2519 g_variant_iter_free(char_value_iter);
2520 g_byte_array_free(manufacturer_data, TRUE);
2527 static void __bt_extract_device_info(GVariantIter *iter,
2530 bluetooth_device_info_t *dev_info = NULL;
2531 char *object_path = NULL;
2532 GVariantIter *interface_iter;
2533 GVariantIter *svc_iter;
2534 char *interface_str = NULL;
2536 /* Parse the signature: oa{sa{sv}}} */
2537 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2540 if (object_path == NULL)
2543 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2544 &interface_str, &svc_iter)) {
2545 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2546 BT_DBG("Found a device: %s", object_path);
2547 dev_info = __bt_parse_device_info(svc_iter);
2549 if (dev_info->paired == TRUE) {
2550 g_array_append_vals(*dev_list, dev_info,
2551 sizeof(bluetooth_device_info_t));
2555 g_free(interface_str);
2556 g_variant_iter_free(svc_iter);
2564 int _bt_get_bonded_devices(GArray **dev_list)
2567 GDBusConnection *conn;
2568 GDBusProxy *manager_proxy;
2569 GVariant *result = NULL;
2570 GVariantIter *iter = NULL;
2571 GError *error = NULL;
2573 conn = _bt_gdbus_get_system_gconn();
2574 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2576 manager_proxy = _bt_get_manager_proxy();
2577 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2579 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2581 G_DBUS_CALL_FLAGS_NONE,
2587 if (error != NULL) {
2588 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2589 g_clear_error(&error);
2591 BT_ERR("Failed to Failed to GetManagedObjects");
2592 return BLUETOOTH_ERROR_INTERNAL;
2595 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2596 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2598 __bt_extract_device_info(iter, dev_list);
2599 g_variant_iter_free(iter);
2600 g_variant_unref(result);
2603 return BLUETOOTH_ERROR_NONE;
2606 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2609 GDBusConnection *conn;
2610 GDBusProxy *manager_proxy;
2611 GVariant *result = NULL;
2612 GVariant *result1 = NULL;
2613 GVariantIter *iter = NULL;
2614 GError *error = NULL;
2615 char *object_path = NULL;
2616 GVariantIter *interface_iter;
2617 char *interface_str = NULL;
2618 GDBusProxy *device_proxy = NULL;
2619 gboolean is_connected = FALSE;
2621 conn = _bt_gdbus_get_system_gconn();
2622 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2624 manager_proxy = _bt_get_manager_proxy();
2625 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2627 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2629 G_DBUS_CALL_FLAGS_NONE,
2635 if (error != NULL) {
2636 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2637 g_clear_error(&error);
2640 BT_ERR("Failed to Failed to GetManagedObjects");
2641 return BLUETOOTH_ERROR_INTERNAL;
2644 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2645 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2647 /* Parse the signature: oa{sa{sv}}} */
2648 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2649 if (object_path == NULL)
2652 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2653 &interface_str, NULL)) {
2654 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2655 BT_DBG("Found a device: %s", object_path);
2656 g_free(interface_str);
2658 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2659 NULL, BT_BLUEZ_NAME,
2660 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2662 if (device_proxy == NULL) {
2663 BT_DBG("Device don't have this service");
2667 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2668 g_variant_new("(s)", profile_uuid),
2669 G_DBUS_CALL_FLAGS_NONE,
2674 if (result1 == NULL) {
2675 BT_ERR("Error occured in Proxy call");
2677 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2678 g_error_free(error);
2681 g_object_unref(device_proxy);
2684 g_variant_get(result1, "(b)", &is_connected);
2686 if (is_connected == TRUE) {
2687 char address[BT_ADDRESS_STRING_SIZE];
2688 bluetooth_device_address_t *addr = NULL;
2690 _bt_convert_device_path_to_address(object_path, address);
2692 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2693 _bt_convert_addr_string_to_type(addr->addr, address);
2695 g_array_append_vals(*addr_list, addr,
2696 sizeof(bluetooth_device_address_t));
2699 g_variant_unref(result1);
2700 g_object_unref(device_proxy);
2707 g_variant_unref(result);
2708 g_variant_iter_free(iter);
2711 return BLUETOOTH_ERROR_NONE;
2714 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2715 bluetooth_device_info_t *dev_info)
2717 char *object_path = NULL;
2718 GDBusProxy *adapter_proxy;
2719 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2720 int ret = BLUETOOTH_ERROR_NONE;
2722 BT_CHECK_PARAMETER(device_address, return);
2723 BT_CHECK_PARAMETER(dev_info, return);
2725 adapter_proxy = _bt_get_adapter_proxy();
2726 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2728 _bt_convert_addr_type_to_string(address, device_address->addr);
2730 object_path = _bt_get_device_object_path(address);
2732 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2734 ret = __bt_get_bonded_device_info(object_path, dev_info);
2735 g_free(object_path);
2740 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2742 char *object_path = NULL;
2743 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2744 gboolean alias_set = FALSE;
2746 GDBusConnection *conn;
2747 GDBusProxy *device_proxy;
2748 GError *error = NULL;
2749 GVariant *result = NULL;
2750 GVariant *temp = NULL;
2753 BT_CHECK_PARAMETER(device_address, return);
2754 BT_CHECK_PARAMETER(is_alias_set, return);
2756 _bt_convert_addr_type_to_string(address, device_address->addr);
2758 object_path = _bt_get_device_object_path(address);
2759 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2761 conn = _bt_gdbus_get_system_gconn();
2763 g_free(object_path);
2764 return BLUETOOTH_ERROR_INTERNAL;
2767 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2771 BT_PROPERTIES_INTERFACE,
2773 if (device_proxy == NULL) {
2774 g_free(object_path);
2775 return BLUETOOTH_ERROR_INTERNAL;
2778 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2779 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2780 G_DBUS_CALL_FLAGS_NONE,
2786 BT_ERR("Error occured in Proxy call");
2787 if (error != NULL) {
2788 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2789 g_error_free(error);
2791 g_object_unref(device_proxy);
2792 g_free(object_path);
2793 return BLUETOOTH_ERROR_INTERNAL;
2796 g_variant_get(result, "(v)", &temp);
2797 alias_set = g_variant_get_boolean(temp);
2798 *is_alias_set = alias_set;
2799 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2800 g_variant_unref(temp);
2801 g_variant_unref(result);
2802 g_object_unref(device_proxy);
2804 g_free(object_path);
2806 return BLUETOOTH_ERROR_NONE;
2809 int _bt_get_timeout_value(int *timeout)
2811 time_t current_time;
2814 /* Take current time */
2815 time(¤t_time);
2816 time_diff = difftime(current_time, visible_timer.start_time);
2818 BT_DBG("Time diff = %d\n", time_diff);
2820 *timeout = visible_timer.timeout - time_diff;
2822 return BLUETOOTH_ERROR_NONE;
2825 int _bt_set_le_privacy(gboolean set_privacy)
2828 GError *error = NULL;
2829 GVariant *result = NULL;
2831 if (__bt_is_factory_test_mode()) {
2832 BT_ERR("Unable to set le privacy in factory binary !!");
2833 return BLUETOOTH_ERROR_NOT_SUPPORT;
2836 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2837 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2838 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2841 proxy = _bt_get_adapter_proxy();
2842 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2844 result = g_dbus_proxy_call_sync(proxy,
2846 g_variant_new("(b)", set_privacy),
2847 G_DBUS_CALL_FLAGS_NONE,
2853 if (error != NULL) {
2854 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2855 g_clear_error(&error);
2857 BT_ERR("Failed to SetLePrivacy");
2858 return BLUETOOTH_ERROR_INTERNAL;
2861 g_variant_unref(result);
2862 BT_INFO("SetLePrivacy as %d", set_privacy);
2863 return BLUETOOTH_ERROR_NONE;
2866 int _bt_set_le_static_random_address(gboolean is_enable)
2869 GError *error = NULL;
2870 GVariant *result = NULL;
2872 if (__bt_is_factory_test_mode()) {
2873 BT_ERR("Unable to set le random address in factory binary !!");
2874 return BLUETOOTH_ERROR_NOT_SUPPORT;
2877 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2878 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2879 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2882 proxy = _bt_get_adapter_proxy();
2883 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2885 result = g_dbus_proxy_call_sync(proxy,
2886 "SetLeStaticRandomAddress",
2887 g_variant_new("(b)", is_enable),
2888 G_DBUS_CALL_FLAGS_NONE,
2894 if (error != NULL) {
2895 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2896 g_clear_error(&error);
2898 BT_ERR("Failed to SetLeStaticRandomAddress");
2899 return BLUETOOTH_ERROR_INTERNAL;
2902 g_variant_unref(result);
2903 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2904 return BLUETOOTH_ERROR_NONE;
2907 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2910 GError *error = NULL;
2914 GVariantBuilder *builder;
2916 BT_CHECK_PARAMETER(m_data, return);
2918 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2919 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2920 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2923 proxy = _bt_get_adapter_proxy();
2924 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2926 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2928 for (i = 0; i < (m_data->data_len) + 2; i++)
2929 g_variant_builder_add(builder, "y", m_data->data[i]);
2931 val = g_variant_new("(ay)", builder);
2933 result = g_dbus_proxy_call_sync(proxy,
2934 "SetManufacturerData",
2936 G_DBUS_CALL_FLAGS_NONE,
2940 g_variant_builder_unref(builder);
2942 if (error != NULL) {
2943 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2944 g_clear_error(&error);
2946 BT_ERR("Failed to SetManufacturerData");
2948 return BLUETOOTH_ERROR_INTERNAL;
2950 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2952 for (i = 0; i < (m_data->data_len) + 2; i++)
2953 g_variant_builder_add(builder, "y", m_data->data[i]);
2955 val = g_variant_new("(ay)", builder);
2957 _bt_send_event(BT_ADAPTER_EVENT,
2958 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2961 BT_INFO("Set manufacturer data");
2963 g_variant_builder_unref(builder);
2964 g_variant_unref(result);
2966 return BLUETOOTH_ERROR_NONE;
2970 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2972 int result = BLUETOOTH_ERROR_NONE;
2973 bt_service_alarm_t *alarm = NULL;
2975 if (!call_back || !alarm_id)
2976 return BLUETOOTH_ERROR_INVALID_PARAM;
2978 if (!alarm_mgr.is_alarm_initialized) {
2979 result = alarmmgr_init("bt-service");
2981 BT_ERR("Failed to initialize alarm = %d", result);
2982 result = BLUETOOTH_ERROR_INTERNAL;
2985 result = alarmmgr_set_cb(alarm_cb, NULL);
2987 BT_ERR("Failed to set the callback = %d", result);
2988 result = BLUETOOTH_ERROR_INTERNAL;
2991 alarm_mgr.is_alarm_initialized = TRUE;
2994 alarm = g_malloc0(sizeof(bt_service_alarm_t));
2996 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2998 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
3001 BT_ERR("Failed to create alarm error = %d", result);
3002 result = BLUETOOTH_ERROR_INTERNAL;
3006 alarm->alarm_id = *alarm_id;
3007 alarm->callback = call_back;
3008 alarm->user_data = user_data;
3010 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
3011 result = BLUETOOTH_ERROR_NONE;
3016 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
3019 bt_service_alarm_t *p_data;
3020 bt_set_alarm_cb callback = NULL;
3021 void *user_data = NULL;
3023 node = g_list_find_custom(alarm_mgr.g_alarm_list,
3024 GINT_TO_POINTER(alarm_id), compare_alarm);
3028 p_data = (bt_service_alarm_t *)node->data;
3029 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
3035 callback = p_data->callback;
3036 user_data = p_data->user_data;
3040 callback(alarm_id, user_data);
3045 int _bt_service_remove_alarm(alarm_id_t alarm_id)
3048 bt_service_alarm_t *p_data;
3049 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
3052 alarmmgr_remove_alarm(alarm_id);
3053 p_data = (bt_service_alarm_t *)list->data;
3054 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
3061 gint compare_alarm(gconstpointer list_data, gconstpointer data)
3064 alarm_id_t alarm_id = (alarm_id_t)(uintptr_t)data;
3066 alarm_id_t alarm_id = (alarm_id_t)data;
3068 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
3070 if (p_data->alarm_id == alarm_id)
3076 static void alarm_data_free(void *data)
3078 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
3083 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3087 int function = (int)(uintptr_t)user_data;
3089 int function = (int)user_data;
3093 case BT_ENABLE_ADAPTER:
3094 result = _bt_enable_adapter();
3095 if (result != BLUETOOTH_ERROR_NONE) {
3096 BT_ERR("_bt_enable_adapter is failed");
3097 /* Send enabled event to API */
3098 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3099 g_variant_new("(i)", result));
3102 case BT_DISABLE_ADAPTER:
3103 result = _bt_disable_adapter();
3104 if (result != BLUETOOTH_ERROR_NONE) {
3105 BT_ERR("_bt_disable_adapter is failed");
3106 /* Send disabled event to API */
3107 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3108 g_variant_new("(i)", result));
3112 BT_ERR("function is NOT matched");
3119 int _bt_adapter_request_delayed(int function)
3124 case BT_ENABLE_ADAPTER:
3125 ret = _bt_enable_adapter_check_status();
3126 if (ret == BLUETOOTH_ERROR_NONE)
3127 _bt_adapter_set_status(BT_ACTIVATING);
3132 case BT_DISABLE_ADAPTER:
3133 ret = _bt_disable_adapter_check_status();
3134 if (ret == BLUETOOTH_ERROR_NONE)
3135 _bt_adapter_set_status(BT_DEACTIVATING);
3141 BT_ERR("function is NOT matched");
3142 return BLUETOOTH_ERROR_INTERNAL;
3146 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)(uintptr_t)function);
3148 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void *)function);
3151 return BLUETOOTH_ERROR_NONE;
3154 int _bt_get_enable_timer_id(void)