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 <dbus/dbus-glib.h>
27 #include <dbus/dbus.h>
29 #include <eventsystem.h>
30 #include <bundle_internal.h>
33 #include "bluetooth-api.h"
34 #include "bt-internal-types.h"
35 #include "bt-service-common.h"
36 #include "bt-service-event.h"
37 #include "bt-service-adapter.h"
38 #include "bt-service-util.h"
39 #include "bt-service-network.h"
40 #include "bt-service-obex-server.h"
41 #include "bt-service-opp-client.h"
42 #include "bt-service-agent.h"
43 #include "bt-service-main.h"
44 #include "bt-service-avrcp.h"
45 #include "bt-service-device.h"
46 #include "bt-service-adapter-le.h"
48 #ifdef TIZEN_DPM_ENABLE
49 #include "bt-service-dpm.h"
59 bt_adapter_timer_t visible_timer = {0, };
63 bt_set_alarm_cb callback;
68 gboolean is_alarm_initialized;
70 } bt_service_alarm_mgr_t;
72 static bt_service_alarm_mgr_t alarm_mgr = {0, };
74 static gboolean is_discovering;
75 static gboolean cancel_by_user;
76 static bt_status_t adapter_status = BT_DEACTIVATED;
77 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
78 static gboolean is_le_intended = FALSE;
79 static void *adapter_agent = NULL;
80 static GDBusProxy *core_proxy = NULL;
81 static guint timer_id = 0;
82 static guint le_timer_id = 0;
83 static gboolean is_recovery_mode;
84 static gboolean in_power_off;
86 static guint poweroff_subscribe_id;
87 static uint status_reg_id;
89 #define BT_CORE_NAME "org.projectx.bt_core"
90 #define BT_CORE_PATH "/org/projectx/bt_core"
91 #define BT_CORE_INTERFACE "org.projectx.btcore"
93 #define BT_DISABLE_TIME 500 /* 500 ms */
95 static int alarm_cb(alarm_id_t alarm_id, void* user_param);
96 static void alarm_data_free(void *data);
98 GDBusProxy *_bt_init_core_proxy(void)
101 GDBusConnection *conn;
103 conn = _bt_gdbus_get_system_gconn();
107 proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
122 static GDBusProxy *__bt_get_core_proxy(void)
124 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
127 static gboolean __bt_is_factory_test_mode(void)
131 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
132 BT_ERR("Get the DUT Mode fail");
137 BT_INFO("DUT Test Mode !!");
144 static gboolean __bt_timeout_handler(gpointer user_data)
146 int result = BLUETOOTH_ERROR_NONE;
150 /* Take current time */
152 time_diff = difftime(current_time, visible_timer.start_time);
154 /* Send event to application */
155 _bt_send_event(BT_ADAPTER_EVENT,
156 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
157 g_variant_new("(in)", result, time_diff));
159 if (visible_timer.timeout <= time_diff) {
160 g_source_remove(visible_timer.event_id);
161 visible_timer.event_id = 0;
162 visible_timer.timeout = 0;
164 #ifndef TIZEN_PROFILE_WEARABLE
165 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
166 BT_ERR("Set vconf failed\n");
174 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
177 int result = BLUETOOTH_ERROR_NONE;
180 if (alarm_id != visible_timer.alarm_id)
183 if (visible_timer.event_id) {
184 _bt_send_event(BT_ADAPTER_EVENT,
185 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
186 g_variant_new("(in)", result, timeout));
187 g_source_remove(visible_timer.event_id);
188 visible_timer.event_id = 0;
189 visible_timer.timeout = 0;
191 #ifndef TIZEN_PROFILE_WEARABLE
192 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
193 BT_ERR("Set vconf failed\n");
196 /* Switch Off visibility in Bluez */
197 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
198 visible_timer.alarm_id = 0;
202 static void __bt_visibility_alarm_remove()
204 if (visible_timer.event_id > 0) {
205 g_source_remove(visible_timer.event_id);
206 visible_timer.event_id = 0;
209 if (visible_timer.alarm_id > 0) {
210 _bt_service_remove_alarm(visible_timer.alarm_id);
211 visible_timer.alarm_id = 0;
215 int __bt_set_visible_time(int timeout)
220 __bt_visibility_alarm_remove();
222 visible_timer.timeout = timeout;
224 #ifndef TIZEN_PROFILE_WEARABLE
225 #ifdef TIZEN_DPM_ENABLE
226 if (_bt_dpm_get_bluetooth_limited_discoverable_state() != DPM_RESTRICTED) {
228 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
229 BT_ERR("Set vconf failed");
230 #ifdef TIZEN_DPM_ENABLE
237 return BLUETOOTH_ERROR_NONE;
239 result = _bt_service_set_alarm(visible_timer.timeout,
240 __bt_visibility_alarm_cb, NULL, &alarm_id);
241 if (result != BLUETOOTH_ERROR_NONE)
242 return BLUETOOTH_ERROR_INTERNAL;
243 visible_timer.alarm_id = alarm_id;
244 /* Take start time */
245 time(&(visible_timer.start_time));
246 visible_timer.event_id = g_timeout_add_seconds(1,
247 __bt_timeout_handler, NULL);
249 return BLUETOOTH_ERROR_NONE;
252 static void __bt_get_service_list(GVariant *value, bluetooth_device_info_t *dev)
259 ret_if(value == NULL);
262 dev->service_index = 0;
264 g_variant_get(value, "as", &iter);
265 while (g_variant_iter_loop(iter, "s", &uuid)) {
266 g_strlcpy(dev->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
267 parts = g_strsplit(uuid, "-", -1);
269 if (parts == NULL || parts[0] == NULL) {
274 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
277 dev->service_index++;
280 g_variant_iter_free(iter);
283 static int __bt_get_bonded_device_info(gchar *device_path,
284 bluetooth_device_info_t *dev_info)
286 GError *error = NULL;
287 GDBusProxy *device_proxy;
288 gchar *address = NULL;
291 unsigned int cod = 0;
293 gboolean trust = FALSE;
294 gboolean paired = FALSE;
295 guchar connected = 0;
296 GByteArray *manufacturer_data = NULL;
298 GDBusConnection *conn;
300 GVariantIter *property_iter;
304 GVariantIter *char_value_iter;
306 BT_CHECK_PARAMETER(device_path, return);
307 BT_CHECK_PARAMETER(dev_info, return);
309 conn = _bt_gdbus_get_system_gconn();
310 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
312 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
316 BT_PROPERTIES_INTERFACE,
319 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
321 result = g_dbus_proxy_call_sync(device_proxy,
323 g_variant_new("(s)", BT_DEVICE_INTERFACE),
324 G_DBUS_CALL_FLAGS_NONE,
330 BT_ERR("Error occured in Proxy call");
332 BT_ERR("Error occured in Proxy call (Error: %s)", error->message);
333 g_clear_error(&error);
335 g_object_unref(device_proxy);
336 return BLUETOOTH_ERROR_INTERNAL;
339 g_object_unref(device_proxy);
341 g_variant_get(result, "(a{sv})", &property_iter);
343 while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
344 if (!g_strcmp0(key, "Paired")) {
345 paired = g_variant_get_boolean(value);
346 } else if (!g_strcmp0(key, "Address")) {
347 g_variant_get(value, "s", &address);
348 } else if (!g_strcmp0(key, "Alias")) {
349 g_variant_get(value, "s", &alias);
350 } else if (!g_strcmp0(key, "Name")) {
351 g_variant_get(value, "s", &name);
352 } else if (!g_strcmp0(key, "Class")) {
353 cod = g_variant_get_uint32(value);
354 } else if (!g_strcmp0(key, "Connected")) {
355 connected = g_variant_get_byte(value);
356 } else if (!g_strcmp0(key, "Trusted")) {
357 trust = g_variant_get_boolean(value);
358 } else if (!g_strcmp0(key, "RSSI")) {
359 rssi = g_variant_get_int16(value);
360 } else if (!g_strcmp0(key, "UUIDs")) {
361 __bt_get_service_list(value, dev_info);
362 } else if (!g_strcmp0(key, "LegacyManufacturerDataLen")) {
363 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
364 } else if (!g_strcmp0(key, "LegacyManufacturerData")) {
365 manufacturer_data = g_byte_array_new();
366 g_variant_get(value, "ay", &char_value_iter);
367 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
368 g_byte_array_append(manufacturer_data, &char_value, 1);
370 g_variant_iter_free(char_value_iter);
372 if (manufacturer_data) {
373 if (manufacturer_data->len > 0) {
374 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data,
375 manufacturer_data->len);
378 g_byte_array_free(manufacturer_data, TRUE);
381 g_variant_iter_free(property_iter);
383 BT_DBG("trust: %d, paired: %d", trust, paired);
385 g_variant_unref(result);
387 if ((paired == FALSE) && (trust == FALSE)) {
391 return BLUETOOTH_ERROR_NOT_PAIRED;
394 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
397 _bt_divide_device_class(&dev_info->device_class, cod);
399 g_strlcpy(dev_info->device_name.name, alias ? alias : name,
400 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
402 dev_info->rssi = rssi;
403 dev_info->trust = trust;
404 dev_info->paired = paired;
405 dev_info->connected = connected;
406 ret = BLUETOOTH_ERROR_NONE;
414 void _bt_set_discovery_status(gboolean mode)
416 is_discovering = mode;
419 void _bt_set_cancel_by_user(gboolean value)
421 cancel_by_user = value;
424 gboolean _bt_get_cancel_by_user(void)
426 return cancel_by_user;
429 void _bt_adapter_set_status(bt_status_t status)
431 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
432 adapter_status = status;
435 bt_status_t _bt_adapter_get_status(void)
437 return adapter_status;
440 void _bt_adapter_set_le_status(bt_le_status_t status)
442 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
443 adapter_le_status = status;
446 bt_le_status_t _bt_adapter_get_le_status(void)
448 return adapter_le_status;
452 void _bt_set_le_intended_status(gboolean value)
454 is_le_intended = value;
457 static void __bt_set_in_poweroff(void)
459 BT_INFO("Set in_power_off to TRUE");
463 static gboolean __bt_is_in_poweroff(void)
468 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
470 char *phone_name = NULL;
476 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
477 phone_name = vconf_keynode_get_str(node);
479 if (phone_name && strlen(phone_name) != 0) {
480 if (!g_utf8_validate(phone_name, -1,
481 (const char **)&ptr))
484 BT_INFO("device_name is changed to %s", phone_name);
485 _bt_set_local_name(phone_name);
487 BT_ERR("phone_name is NOT valid");
490 BT_ERR("vconf type is NOT string");
494 static void __bt_set_local_name(void)
496 bluetooth_device_name_t local_name;
497 char *phone_name = NULL;
501 if (_bt_get_local_name(&local_name) != BLUETOOTH_ERROR_NONE ||
502 (temp = strstr(local_name.name, "BlueZ")) != NULL) {
503 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
508 if (strlen(phone_name) != 0) {
509 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
512 _bt_set_local_name(phone_name);
518 static int __bt_set_enabled(void)
520 int adapter_status = BT_ADAPTER_DISABLED;
521 int result = BLUETOOTH_ERROR_NONE;
524 BT_DBG("g_source is removed");
525 g_source_remove(timer_id);
529 _bt_check_adapter(&adapter_status);
531 if (adapter_status == BT_ADAPTER_DISABLED) {
532 BT_ERR("Bluetoothd is not running");
533 return BLUETOOTH_ERROR_INTERNAL;
536 #ifdef TIZEN_PROFILE_MOBILE || defined(TIZEN_PROFILE_IVI)
537 /* BT setting UI will control Mobile's visible mode. So in the FRWK...set the visible mode as off: */
538 if (_bt_set_discoverable_mode(
539 BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0) != BLUETOOTH_ERROR_NONE)
540 BT_ERR("Set connectable mode failed");
543 if (_bt_set_discoverable_mode(
544 BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE, 0) != BLUETOOTH_ERROR_NONE)
545 BT_ERR("Fail to set discoverable mode");
549 /* Update Bluetooth Status to notify other modules */
550 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
551 BT_ERR("Set vconf failed\n");
553 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
554 BT_ERR("Set vconf failed\n");
556 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
557 EVT_VAL_BT_ON) != ES_R_OK)
558 BT_ERR("Fail to set value");
560 /* Send enabled event to API */
561 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
562 g_variant_new("(i)", result));
564 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
565 _bt_audio_start_auto_connect(FALSE);
568 __bt_set_local_name();
569 _bt_set_discovery_status(FALSE);
571 return BLUETOOTH_ERROR_NONE;
574 void _bt_set_disabled(int result)
576 int power_off_status = 0;
579 int pm_ignore_mode = 0;
581 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
582 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
584 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
586 /* Update the vconf BT status in normal Deactivation case only */
587 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
588 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
590 BT_DBG("Update vconf for BT normal Deactivation");
592 if (result == BLUETOOTH_ERROR_TIMEOUT)
593 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0)
594 BT_ERR("Set vconf failed");
596 /* Update Bluetooth Status to notify other modules */
597 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
598 BT_ERR("Set vconf failed");
600 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_STATE,
601 EVT_VAL_BT_OFF) != ES_R_OK)
602 BT_ERR("Fail to set value");
605 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
606 BT_ERR("Set vconf failed\n");
608 _bt_cancel_queued_transfers();
609 _bt_adapter_set_status(BT_DEACTIVATED);
610 _bt_set_discovery_status(FALSE);
612 #ifndef USB_BLUETOOTH
613 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
615 /* Send disabled event */
616 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
617 g_variant_new("(i)", result));
618 #ifndef USB_BLUETOOTH
622 BT_INFO("Adapter disabled");
625 static int __bt_set_le_enabled(void)
628 int result = BLUETOOTH_ERROR_NONE;
631 /* Update Bluetooth Status to notify other modules */
632 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
633 BT_ERR("Set vconf failed");
635 /* set packet length to max size to enable packet length extension */
636 if (BLUETOOTH_ERROR_NONE != _bt_le_set_max_packet_len())
637 BT_ERR("Fail to set max packet length");
639 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
640 EVT_VAL_BT_LE_ON) != ES_R_OK)
641 BT_ERR("Fail to set value");
643 /* Send enabled event to API */
645 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
646 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
648 status = _bt_adapter_get_status();
649 if (status == BT_DEACTIVATED) {
650 BT_INFO("BREDR is off, turn off PSCAN");
651 _bt_set_connectable(FALSE);
653 if (le_timer_id > 0) {
654 g_source_remove(le_timer_id);
658 /* Send enabled event to API */
659 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
660 g_variant_new("(i)", result));
662 __bt_set_local_name();
665 return BLUETOOTH_ERROR_NONE;
668 void _bt_set_le_disabled(int result)
670 int power_off_status;
673 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
674 BT_DBG("ret : %d", ret);
675 BT_DBG("power_off_status : %d", power_off_status);
677 /* Update Bluetooth Status to notify other modules */
678 BT_DBG("Update vconf for BT LE normal Deactivation");
679 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
680 BT_ERR("Set vconf failed\n");
681 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
683 if (_bt_eventsystem_set_value(SYS_EVENT_BT_STATE, EVT_KEY_BT_LE_STATE,
684 EVT_VAL_BT_LE_OFF) != ES_R_OK)
685 BT_ERR("Fail to set value");
687 /* Send disabled event */
688 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
689 g_variant_new("(i)", result));
692 void *_bt_get_adapter_agent(void)
694 return adapter_agent;
697 int _bt_enable_core(void)
701 GError *error = NULL;
703 proxy = __bt_get_core_proxy();
704 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
706 /* Clean up the process */
707 result = g_dbus_proxy_call_sync(proxy,
710 G_DBUS_CALL_FLAGS_NONE,
717 BT_ERR("Bt core call failed(Error: %s)", error->message);
718 g_clear_error(&error);
720 BT_ERR("Bt core call failed");
721 return BLUETOOTH_ERROR_INTERNAL;
724 g_variant_unref(result);
725 return BLUETOOTH_ERROR_NONE;
728 #if defined(TIZEN_FEATURE_FLIGHTMODE_ENABLED) || (!defined(TIZEN_PROFILE_WEARABLE))
729 static void __bt_service_flight_ps_mode_cb(keynode_t *node, void *data)
731 gboolean flight_mode = FALSE;
732 int power_saving_mode = 0;
735 DBG_SECURE("key=%s", vconf_keynode_get_name(node));
736 type = vconf_keynode_get_type(node);
737 if (type == VCONF_TYPE_BOOL) {
738 flight_mode = vconf_keynode_get_bool(node);
739 if (flight_mode != TRUE) {
740 BT_ERR("Ignore the event");
743 } else if (type == VCONF_TYPE_INT) {
744 power_saving_mode = vconf_keynode_get_int(node);
745 if (power_saving_mode != 2) {
746 BT_ERR("Ignore the event");
750 BT_ERR("Invaild vconf key type : %d", type);
758 static void __bt_poweroff_event_filter(GDBusConnection *connection,
759 const gchar *sender_name, const gchar *object_path,
760 const gchar *interface_name, const gchar *signal_name,
761 GVariant *parameters, gpointer user_data)
765 g_variant_get(parameters, "(i)", &state);
767 if (state != BT_DEVICED_POWEROFF_SIGNAL_POWEROFF &&
768 state != BT_DEVICED_POWEROFF_SIGNAL_REBOOT) {
769 BT_DBG("Not interested event : %d", state);
773 if (_bt_adapter_get_status() == BT_ACTIVATING) {
774 BT_INFO("Just update VCONFKEY_BT_STATUS in Power off");
775 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON))
776 BT_ERR("Set VCONFKEY_BT_STATUS failed");
778 __bt_set_in_poweroff();
782 void _bt_service_register_poweroff_event(void)
784 if (poweroff_subscribe_id)
787 poweroff_subscribe_id = g_dbus_connection_signal_subscribe(
788 _bt_gdbus_get_system_gconn(), NULL,
789 BT_DEVICED_POWEROFF_INTERFACE,
790 BT_DEVICED_POWEROFF_SIGNAL,
791 BT_DEVICED_POWEROFF_OBJECT_PATH,
792 NULL, 0, __bt_poweroff_event_filter, NULL, NULL);
795 void _bt_service_unregister_poweroff_event(void)
797 if (poweroff_subscribe_id == 0)
800 g_dbus_connection_signal_unsubscribe(_bt_gdbus_get_system_gconn(),
801 poweroff_subscribe_id);
802 poweroff_subscribe_id = 0;
805 void _bt_service_register_vconf_handler(void)
809 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
810 if (vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
811 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
812 BT_ERR("Unable to register key handler");
814 BT_DBG("Telephony is disabled");
817 #ifndef TIZEN_PROFILE_WEARABLE
818 if (vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
819 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL) < 0)
820 BT_ERR("Unable to register key handler");
824 void _bt_service_unregister_vconf_handler(void)
828 #ifdef TIZEN_FEATURE_FLIGHTMODE_ENABLED
829 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
830 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
833 #ifndef TIZEN_PROFILE_WEARABLE
834 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
835 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
839 static void __bt_state_event_handler(const char *event_name, bundle *data, void *user_data)
841 const char *bt_status = NULL;
842 const char *bt_le_status = NULL;
843 BT_DBG("bt state set event(%s) received", event_name);
845 bt_status = bundle_get_val(data, EVT_KEY_BT_STATE);
846 BT_DBG("bt_state: (%s)", bt_status);
848 bt_le_status = bundle_get_val(data, EVT_KEY_BT_LE_STATE);
849 BT_DBG("bt_state: (%s)", bt_le_status);
852 void _bt_handle_adapter_added(void)
856 bt_le_status_t le_status;
860 BT_DBG("g_source is removed");
861 g_source_remove(timer_id);
866 status = _bt_adapter_get_status();
867 le_status = _bt_adapter_get_le_status();
868 BT_INFO("status : %d", status);
869 BT_INFO("le_status : %d", le_status);
871 #ifndef USB_BLUETOOTH
872 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
873 if (!adapter_agent) {
874 BT_ERR("Fail to register agent");
878 if (adapter_agent == NULL) {
879 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
880 if (!adapter_agent) {
881 BT_ERR("Fail to register agent");
887 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
888 BT_ERR("Fail to register media player");
890 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
891 BT_ERR("Fail to init obex server");
893 #ifdef TIZEN_BT_PAN_NAP_ENABLED
894 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
895 BT_ERR("Fail to activate network");
898 /* add the vconf noti handler */
899 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
900 __bt_phone_name_changed_cb, NULL);
902 BT_ERR("Unable to register key handler");
904 if (le_status == BT_LE_ACTIVATING ||
905 status == BT_ACTIVATING) {
906 __bt_set_le_enabled();
907 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
910 if (status == BT_ACTIVATING) {
912 _bt_adapter_set_status(BT_ACTIVATED);
916 if (eventsystem_register_event(SYS_EVENT_BT_STATE, &status_reg_id,
917 (eventsystem_handler)__bt_state_event_handler, NULL) != ES_R_OK) {
918 BT_ERR("Fail to register system event");
922 void _bt_handle_adapter_removed(void)
926 _bt_adapter_set_status(BT_DEACTIVATED);
928 __bt_visibility_alarm_remove();
930 if (alarm_mgr.is_alarm_initialized == TRUE) {
932 alarm_mgr.is_alarm_initialized = FALSE;
933 g_list_free_full(alarm_mgr.g_alarm_list, alarm_data_free);
934 alarm_mgr.g_alarm_list = NULL;
937 #ifdef TIZEN_BT_A2DP_SINK_AUTO_CONNECT
938 _bt_audio_stop_auto_connect();
941 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
942 (vconf_callback_fn)__bt_phone_name_changed_cb);
944 ERR("vconf_ignore_key_changed failed\n");
946 #ifndef USB_BLUETOOTH
947 _bt_destroy_agent(adapter_agent);
948 adapter_agent = NULL;
950 if (is_recovery_mode == TRUE) {
951 /* Send disabled event */
952 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
954 /* Will recover BT by bt-core, so set the mode as activating */
955 _bt_adapter_set_status(BT_ACTIVATING);
956 is_recovery_mode = FALSE;
958 _bt_reliable_terminate_service(NULL);
961 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
964 if (eventsystem_unregister_event(status_reg_id) != ES_R_OK)
965 BT_ERR("Fail to unregister system event");
968 static gboolean __bt_enable_timeout_cb(gpointer user_data)
972 GError *error = NULL;
976 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
978 BT_ERR("EnableAdapter is failed");
980 proxy = __bt_get_core_proxy();
984 /* Clean up the process */
985 result = g_dbus_proxy_call_sync(proxy,
988 G_DBUS_CALL_FLAGS_NONE,
995 BT_ERR("Bt core call failed(Error: %s)", error->message);
996 g_clear_error(&error);
998 BT_ERR("Bt core call failed");
1003 g_variant_unref(result);
1004 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
1006 #ifndef USB_BLUETOOTH
1007 _bt_terminate_service(NULL);
1013 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
1017 GError *error = NULL;
1021 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
1023 BT_ERR("EnableAdapterLE is failed");
1025 proxy = __bt_get_core_proxy();
1029 /* Clean up the process */
1030 result = g_dbus_proxy_call_sync(proxy,
1033 G_DBUS_CALL_FLAGS_NONE,
1039 if (error != NULL) {
1040 BT_ERR("Bt core call failed(Error: %s)", error->message);
1041 g_clear_error(&error);
1043 BT_ERR("Bt core call failed");
1047 g_variant_unref(result);
1048 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
1050 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
1052 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1053 _bt_terminate_service(NULL);
1058 void _bt_adapter_start_le_enable_timer(void)
1060 if (le_timer_id > 0) {
1061 g_source_remove(le_timer_id);
1065 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1066 __bt_enable_le_timeout_cb, NULL);
1071 void _bt_adapter_start_enable_timer(void)
1074 g_source_remove(timer_id);
1078 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
1079 __bt_enable_timeout_cb, NULL);
1085 static gboolean __bt_adapter_enabled_cb(gpointer user_data)
1090 _bt_adapter_set_status(BT_ACTIVATED);
1096 int _bt_enable_adapter_check_status(void)
1098 bt_status_t status = _bt_adapter_get_status();
1099 bt_le_status_t le_status = _bt_adapter_get_le_status();
1103 if (status == BT_ACTIVATING) {
1104 BT_ERR("Enabling in progress");
1105 return BLUETOOTH_ERROR_IN_PROGRESS;
1108 if (status == BT_ACTIVATED) {
1109 BT_ERR("Already enabled");
1110 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1113 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1114 BT_ERR("Disabling in progress");
1115 return BLUETOOTH_ERROR_DEVICE_BUSY;
1118 return BLUETOOTH_ERROR_NONE;
1121 int _bt_enable_adapter(void)
1124 GError *error = NULL;
1126 GVariant *result = NULL;
1127 bt_status_t status = _bt_adapter_get_status();
1128 bt_le_status_t le_status = _bt_adapter_get_le_status();
1132 if (status == BT_ACTIVATING) {
1133 BT_ERR("Enabling in progress");
1134 return BLUETOOTH_ERROR_IN_PROGRESS;
1137 if (status == BT_ACTIVATED) {
1138 BT_ERR("Already enabled");
1139 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1142 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1143 BT_ERR("Disabling in progress");
1144 return BLUETOOTH_ERROR_DEVICE_BUSY;
1147 _bt_adapter_set_status(BT_ACTIVATING);
1151 int adapter_status = BT_ADAPTER_DISABLED;
1153 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
1154 BT_ERR("Set vconf failed");
1156 _bt_check_adapter(&adapter_status);
1157 if (adapter_status == BT_ADAPTER_ENABLED) {
1158 g_idle_add(__bt_adapter_enabled_cb, NULL);
1159 _bt_adapter_start_enable_timer();
1160 return BLUETOOTH_ERROR_NONE;
1165 if (__bt_is_in_poweroff() == TRUE) {
1166 BT_INFO("Just update VCONFKEY_BT_STATUS in Power off");
1167 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
1168 BT_ERR("Set VCONFKEY_BT_STATUS failed");
1169 return BLUETOOTH_ERROR_NONE;
1172 proxy = __bt_get_core_proxy();
1174 return BLUETOOTH_ERROR_INTERNAL;
1176 if (le_status == BT_LE_ACTIVATED) {
1177 BT_INFO("LE Already enabled. Just turn on PSCAN");
1178 ret = _bt_set_connectable(TRUE);
1179 if (ret == BLUETOOTH_ERROR_NONE)
1180 _bt_adapter_set_status(BT_ACTIVATED);
1182 return BLUETOOTH_ERROR_INTERNAL;
1185 result = g_dbus_proxy_call_sync(proxy, "EnableAdapter",
1187 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1190 BT_ERR("EnableAdapterLe failed: %s", error->message);
1191 _bt_adapter_set_status(BT_DEACTIVATED);
1192 g_clear_error(&error);
1194 result = g_dbus_proxy_call_sync(proxy,
1197 G_DBUS_CALL_FLAGS_NONE,
1202 if (error != NULL) {
1203 BT_ERR("Bt core call failed(Error: %s)", error->message);
1204 g_clear_error(&error);
1206 g_variant_unref(result);
1207 #ifndef USB_BLUETOOTH
1208 /* Terminate myself */
1209 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1211 return BLUETOOTH_ERROR_INTERNAL;
1213 g_variant_unref(result);
1214 if (le_status == BT_LE_ACTIVATED)
1217 _bt_adapter_start_enable_timer();
1219 return BLUETOOTH_ERROR_NONE;
1222 static gboolean __bt_disconnect_all(void)
1225 GDBusConnection *conn;
1226 GDBusProxy *dev_proxy;
1227 gboolean ret = FALSE;
1229 GError *error = NULL;
1230 GArray *device_list;
1231 bluetooth_device_info_t *info;
1233 char *device_path = NULL;
1234 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1239 conn = _bt_gdbus_get_system_gconn();
1241 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1243 if (_bt_get_bonded_devices(&device_list)
1244 != BLUETOOTH_ERROR_NONE) {
1245 g_array_free(device_list, TRUE);
1249 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1251 for (i = 0; i < size; i++) {
1253 info = &g_array_index(device_list,
1254 bluetooth_device_info_t, i);
1256 if (info->connected != BLUETOOTH_CONNECTED_LINK_NONE) {
1257 BT_DBG("Found Connected device");
1258 _bt_convert_addr_type_to_string(address, info->device_address.addr);
1259 device_path = _bt_get_device_object_path(address);
1260 if (device_path == NULL)
1263 BT_DBG("Disconnecting : %s", device_path);
1265 dev_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
1269 BT_DEVICE_INTERFACE,
1272 if (dev_proxy == NULL)
1275 result = g_dbus_proxy_call_sync(dev_proxy,
1278 G_DBUS_CALL_FLAGS_NONE,
1284 if (error != NULL) {
1285 BT_ERR("Disconnect call failed(Error: %s)", error->message);
1286 g_clear_error(&error);
1288 BT_ERR("Disconnect call failed");
1289 g_object_unref(dev_proxy);
1293 g_variant_unref(result);
1294 g_object_unref(dev_proxy);
1298 g_array_free(device_list, TRUE);
1304 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1307 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1313 int _bt_disable_cb(void)
1321 GError *error = NULL;
1323 _bt_adapter_set_status(BT_DEACTIVATING);
1325 bt_le_status_t le_status;
1326 le_status = _bt_adapter_get_le_status();
1327 BT_DBG("le_status : %d", le_status);
1328 if (le_status == BT_LE_ACTIVATED) {
1329 BT_INFO("LE is enabled. Just turn off PSCAN");
1331 if (_bt_is_discovering())
1332 _bt_cancel_discovery();
1334 if (_bt_is_connectable() == FALSE) {
1335 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1337 ret = _bt_set_connectable(FALSE);
1338 if (ret != BLUETOOTH_ERROR_NONE) {
1339 BT_ERR("_bt_set_connectable fail!");
1340 _bt_adapter_set_status(BT_ACTIVATED);
1341 return BLUETOOTH_ERROR_INTERNAL;
1346 proxy = __bt_get_core_proxy();
1347 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1349 result = g_dbus_proxy_call_sync(proxy,
1352 G_DBUS_CALL_FLAGS_NONE,
1358 if (error != NULL) {
1359 BT_ERR("Failed to DisableAdapter (Error: %s)", error->message);
1360 g_clear_error(&error);
1362 BT_ERR("Failed to DisableAdapter");
1363 _bt_adapter_set_status(BT_ACTIVATED);
1364 return BLUETOOTH_ERROR_INTERNAL;
1367 g_variant_unref(result);
1368 return BLUETOOTH_ERROR_NONE;
1371 int _bt_disable_adapter_check_status(void)
1373 bt_status_t status = _bt_adapter_get_status();
1377 if (status == BT_DEACTIVATING) {
1378 BT_DBG("Disabling in progress");
1379 return BLUETOOTH_ERROR_IN_PROGRESS;
1382 if (status == BT_DEACTIVATED) {
1383 BT_DBG("Already disabled");
1384 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1387 return BLUETOOTH_ERROR_NONE;
1390 int _bt_disable_adapter(void)
1395 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1396 BT_DBG("Disabling in progress");
1397 return BLUETOOTH_ERROR_IN_PROGRESS;
1400 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1401 BT_DBG("Already disabled");
1402 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1406 g_source_remove(timer_id);
1410 __bt_disconnect_all();
1411 ret = _bt_disable_cb();
1417 int _bt_recover_adapter(void)
1422 GError *error = NULL;
1424 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1425 BT_ERR("Disabling in progress");
1426 return BLUETOOTH_ERROR_IN_PROGRESS;
1429 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1430 BT_ERR("Already disabled");
1431 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1434 _bt_adapter_set_status(BT_DEACTIVATING);
1436 proxy = __bt_get_core_proxy();
1437 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1439 result = g_dbus_proxy_call_sync(proxy,
1442 G_DBUS_CALL_FLAGS_NONE,
1448 if (error != NULL) {
1449 BT_ERR("Failed to RecoverAdapter (Error: %s)", error->message);
1450 g_clear_error(&error);
1452 BT_ERR("Failed to RecoverAdapter");
1453 return BLUETOOTH_ERROR_INTERNAL;
1456 is_recovery_mode = TRUE;
1458 g_variant_unref(result);
1459 __bt_disconnect_all();
1462 return BLUETOOTH_ERROR_NONE;
1465 int _bt_reset_adapter(void)
1469 GError *error = NULL;
1473 proxy = __bt_get_core_proxy();
1475 return BLUETOOTH_ERROR_INTERNAL;
1477 result = g_dbus_proxy_call_sync(proxy,
1480 G_DBUS_CALL_FLAGS_NONE,
1486 if (error != NULL) {
1487 BT_ERR("Failed to ResetAdapter (Error: %s)", error->message);
1488 g_clear_error(&error);
1490 BT_ERR("Failed to ResetAdapter");
1491 return BLUETOOTH_ERROR_INTERNAL;
1494 g_variant_unref(result);
1495 /* Terminate myself */
1496 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1497 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1499 return BLUETOOTH_ERROR_NONE;
1503 int _bt_check_adapter(int *status)
1506 char *adapter_path = NULL;
1508 BT_CHECK_PARAMETER(status, return);
1510 *status = BT_ADAPTER_DISABLED;
1512 adapter_path = _bt_get_adapter_path();
1515 if (adapter_path != NULL)
1516 *status = BT_ADAPTER_ENABLED;
1518 g_free(adapter_path);
1519 return BLUETOOTH_ERROR_NONE;
1522 int _bt_check_adapter(int *status)
1525 GError *error = NULL;
1528 gboolean powered = FALSE;
1530 BT_CHECK_PARAMETER(status, return);
1532 *status = BT_ADAPTER_DISABLED;
1534 proxy = _bt_get_adapter_properties_proxy();
1535 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1537 result = g_dbus_proxy_call_sync(proxy,
1539 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1541 G_DBUS_CALL_FLAGS_NONE,
1547 BT_ERR("Failed to get local address");
1548 if (error != NULL) {
1549 BT_ERR("Failed to get local address (Error: %s)", error->message);
1550 g_clear_error(&error);
1552 return BLUETOOTH_ERROR_INTERNAL;
1555 g_variant_get(result, "(v)", &temp);
1556 powered = g_variant_get_boolean(temp);
1557 BT_DBG("powered: %d", powered);
1560 *status = BT_ADAPTER_ENABLED;
1562 g_variant_unref(result);
1563 g_variant_unref(temp);
1564 return BLUETOOTH_ERROR_NONE;
1568 int _bt_enable_adapter_le(void)
1572 GError *error = NULL;
1573 bt_status_t status = _bt_adapter_get_status();
1574 bt_le_status_t le_status = _bt_adapter_get_le_status();
1577 if (le_status == BT_LE_ACTIVATING) {
1578 BT_ERR("Enabling in progress");
1579 return BLUETOOTH_ERROR_IN_PROGRESS;
1582 if (le_status == BT_LE_ACTIVATED) {
1583 BT_ERR("Already enabled");
1584 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1587 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1588 BT_ERR("Disabling in progress");
1589 return BLUETOOTH_ERROR_DEVICE_BUSY;
1592 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1594 proxy = __bt_get_core_proxy();
1595 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1597 result = g_dbus_proxy_call_sync(proxy, "EnableAdapterLe",
1599 G_DBUS_CALL_FLAGS_NONE, BT_ENABLE_TIMEOUT,
1602 BT_ERR("EnableAdapterLe failed: %s", error->message);
1603 _bt_adapter_set_le_status(BT_DEACTIVATED);
1604 g_clear_error(&error);
1606 /* Clean up the process */
1607 result = g_dbus_proxy_call_sync(proxy,
1610 G_DBUS_CALL_FLAGS_NONE,
1616 BT_ERR("Bt core call failed");
1618 BT_ERR("EnableAdapterLE Failed %s", error->message);
1619 g_clear_error(&error);
1622 g_variant_unref(result);
1623 /* Terminate myself */
1624 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1625 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1626 return BLUETOOTH_ERROR_INTERNAL;
1630 g_variant_unref(result);
1632 _bt_adapter_start_le_enable_timer();
1634 if (status == BT_ACTIVATED) {
1635 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1636 __bt_set_le_enabled();
1638 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1640 return BLUETOOTH_ERROR_NONE;
1643 int _bt_disable_adapter_le(void)
1647 bt_le_status_t bt_le_state;
1649 GError *error = NULL;
1651 bt_le_state = _bt_adapter_get_le_status();
1652 if (bt_le_state == BT_LE_DEACTIVATING) {
1653 BT_DBG("Disabling in progress");
1654 return BLUETOOTH_ERROR_IN_PROGRESS;
1657 if (bt_le_state == BT_LE_DEACTIVATED) {
1658 BT_DBG("Already disabled");
1659 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1662 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1664 proxy = __bt_get_core_proxy();
1666 return BLUETOOTH_ERROR_INTERNAL;
1668 result = g_dbus_proxy_call_sync(proxy,
1671 G_DBUS_CALL_FLAGS_NONE,
1677 if (error != NULL) {
1678 BT_ERR("Bt core call failed (Error: %s)", error->message);
1679 g_clear_error(&error);
1681 BT_ERR("Bt core call failed");
1682 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1683 return BLUETOOTH_ERROR_INTERNAL;
1686 g_variant_unref(result);
1687 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1688 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1690 return BLUETOOTH_ERROR_NONE;
1693 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1697 GError *error = NULL;
1698 const char *address;
1702 BT_CHECK_PARAMETER(local_address, return);
1704 proxy = _bt_get_adapter_properties_proxy();
1705 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1707 result = g_dbus_proxy_call_sync(proxy,
1709 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1711 G_DBUS_CALL_FLAGS_NONE,
1717 BT_ERR("Failed to get local address");
1718 if (error != NULL) {
1719 BT_ERR("Failed to get local address (Error: %s)", error->message);
1720 g_clear_error(&error);
1722 return BLUETOOTH_ERROR_INTERNAL;
1725 g_variant_get(result, "(v)", &temp);
1726 address = g_variant_get_string(temp, NULL);
1727 BT_DBG("Address:%s", address);
1730 _bt_convert_addr_string_to_type(local_address->addr, address);
1732 return BLUETOOTH_ERROR_INTERNAL;
1734 g_variant_unref(result);
1735 g_variant_unref(temp);
1736 return BLUETOOTH_ERROR_NONE;
1739 int _bt_get_local_version(bluetooth_version_t *local_version)
1742 const char *ver = NULL;
1744 int ret = BLUETOOTH_ERROR_NONE;
1748 BT_CHECK_PARAMETER(local_version, return);
1750 GError *error = NULL;
1752 proxy = _bt_get_adapter_properties_proxy();
1753 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1755 result = g_dbus_proxy_call_sync(proxy,
1757 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1759 G_DBUS_CALL_FLAGS_NONE,
1765 if (error != NULL) {
1766 BT_ERR("Failed to get local version (Error: %s)", error->message);
1767 g_clear_error(&error);
1769 BT_ERR("Failed to get local version");
1770 return BLUETOOTH_ERROR_INTERNAL;
1773 g_variant_get(result, "(v)", &temp);
1774 ver = g_variant_get_string(temp, NULL);
1775 BT_DBG("VERSION: %s", ver);
1777 if (ver && (strlen(ver) > 0)) {
1778 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1779 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1782 g_strlcpy(local_version->version, ver,
1783 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1786 ret = BLUETOOTH_ERROR_INTERNAL;
1789 g_variant_unref(result);
1790 g_variant_unref(temp);
1794 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1797 const char *name = NULL;
1799 int ret = BLUETOOTH_ERROR_NONE;
1802 GError *error = NULL;
1804 BT_CHECK_PARAMETER(local_name, return);
1806 proxy = _bt_get_adapter_properties_proxy();
1807 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1809 result = g_dbus_proxy_call_sync(proxy,
1811 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1813 G_DBUS_CALL_FLAGS_NONE,
1819 if (error != NULL) {
1820 BT_ERR("Failed to get local name (Error: %s)", error->message);
1821 g_clear_error(&error);
1823 BT_ERR("Failed to get local name");
1824 return BLUETOOTH_ERROR_INTERNAL;
1827 g_variant_get(result, "(v)", &temp);
1828 name = g_variant_get_string(temp, NULL);
1829 BT_DBG("LOCAL NAME:%s", name);
1831 if (name && (strlen(name) > 0)) {
1832 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1833 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1836 g_strlcpy(local_name->name, name,
1837 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1839 ret = BLUETOOTH_ERROR_INTERNAL;
1841 g_variant_unref(result);
1842 g_variant_unref(temp);
1846 int _bt_set_local_name(char *local_name)
1849 GError *error = NULL;
1853 BT_CHECK_PARAMETER(local_name, return);
1855 proxy = _bt_get_adapter_properties_proxy();
1857 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1859 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1862 result = g_dbus_proxy_call_sync(proxy,
1864 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
1865 "Alias", g_variant_new("s", local_name)),
1866 G_DBUS_CALL_FLAGS_NONE,
1872 if (error != NULL) {
1873 BT_ERR("Failed to set Alias (Error: %s)", error->message);
1874 g_clear_error(&error);
1876 BT_ERR("Failed to set Alias");
1877 return BLUETOOTH_ERROR_INTERNAL;
1880 g_variant_unref(result);
1881 return BLUETOOTH_ERROR_NONE;
1884 int _bt_is_service_used(char *service_uuid, gboolean *used)
1887 GError *error = NULL;
1888 int ret = BLUETOOTH_ERROR_NONE;
1890 GVariant *temp = NULL;
1891 GVariantIter *iter = NULL;
1895 BT_CHECK_PARAMETER(service_uuid, return);
1896 BT_CHECK_PARAMETER(used, return);
1898 proxy = _bt_get_adapter_properties_proxy();
1899 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1901 result = g_dbus_proxy_call_sync(proxy,
1903 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1905 G_DBUS_CALL_FLAGS_NONE,
1911 if (error != NULL) {
1912 BT_ERR("Failed to get UUIDs (Error: %s)", error->message);
1913 g_clear_error(&error);
1915 BT_ERR("Failed to get UUIDs");
1916 return BLUETOOTH_ERROR_INTERNAL;
1919 g_variant_get(result, "(v)", &temp);
1920 g_variant_get(temp, "as", &iter);
1923 while (g_variant_iter_loop(iter, "&s", &uuid)) {
1924 if (strcasecmp(uuid, service_uuid) == 0) {
1929 g_variant_iter_free(iter);
1930 g_variant_unref(result);
1931 g_variant_unref(temp);
1933 BT_DBG("Service Used? %d", *used);
1938 static gboolean __bt_get_discoverable_property(void)
1941 gboolean discoverable_v;
1942 GError *error = NULL;
1946 proxy = _bt_get_adapter_properties_proxy();
1947 retv_if(proxy == NULL, FALSE);
1949 result = g_dbus_proxy_call_sync(proxy,
1951 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
1953 G_DBUS_CALL_FLAGS_NONE,
1959 if (error != NULL) {
1960 BT_ERR("Failed to get Discoverable property (Error: %s)", error->message);
1961 g_clear_error(&error);
1963 BT_ERR("Failed to get Discoverable property");
1964 return BLUETOOTH_ERROR_INTERNAL;
1967 g_variant_get(result, "(v)", &temp);
1968 discoverable_v = g_variant_get_boolean(temp);
1969 BT_DBG("discoverable_v:%d", discoverable_v);
1971 g_variant_unref(result);
1972 g_variant_unref(temp);
1974 return discoverable_v;
1977 int _bt_get_discoverable_mode(int *mode)
1979 gboolean discoverable;
1980 unsigned int timeout;
1982 BT_CHECK_PARAMETER(mode, return);
1984 discoverable = __bt_get_discoverable_property();
1985 timeout = _bt_get_discoverable_timeout_property();
1987 if (discoverable == TRUE) {
1989 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1991 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1993 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1995 return BLUETOOTH_ERROR_NONE;
1999 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
2001 int ret = BLUETOOTH_ERROR_NONE;
2004 GError *error = NULL;
2008 proxy = _bt_get_adapter_properties_proxy();
2010 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2012 #ifdef TIZEN_DPM_ENABLE
2013 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE &&
2014 _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
2015 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT_HANDSFREE");
2016 return BLUETOOTH_ERROR_ACCESS_DENIED;
2018 if (discoverable_mode != BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE &&
2019 _bt_dpm_get_bluetooth_limited_discoverable_state() == DPM_RESTRICTED) {
2020 _bt_launch_dpm_popup("DPM_POLICY_DISABLE_BT");
2021 return BLUETOOTH_ERROR_ACCESS_DENIED;
2025 switch (discoverable_mode) {
2026 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
2031 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
2036 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
2041 return BLUETOOTH_ERROR_INVALID_PARAM;
2044 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
2045 discoverable_mode, timeout);
2047 result = g_dbus_proxy_call_sync(proxy,
2049 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE,
2050 "Connectable", g_variant_new("b", pg_scan)),
2051 G_DBUS_CALL_FLAGS_NONE,
2057 if (error != NULL) {
2058 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2059 g_clear_error(&error);
2061 BT_ERR("Failed to set connectable property");
2062 return BLUETOOTH_ERROR_INTERNAL;
2064 g_variant_unref(result);
2065 result = g_dbus_proxy_call_sync(proxy,
2067 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Discoverable",
2068 g_variant_new("b", inq_scan)),
2069 G_DBUS_CALL_FLAGS_NONE,
2075 if (error != NULL) {
2076 BT_ERR("Failed to set Discoverable property (Error: %s)", error->message);
2077 g_clear_error(&error);
2079 BT_ERR("Failed to set Discoverable 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,
2086 "DiscoverableTimeout", g_variant_new("u", timeout)),
2087 G_DBUS_CALL_FLAGS_NONE,
2093 if (error != NULL) {
2094 BT_ERR("Failed to set DiscoverableTimeout property (Error: %s)", error->message);
2095 g_clear_error(&error);
2097 BT_ERR("Failed to set DiscoverableTimeout property");
2098 return BLUETOOTH_ERROR_INTERNAL;
2101 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
2104 ret = __bt_set_visible_time(timeout);
2106 g_variant_unref(result);
2111 int _bt_start_discovery(void)
2114 GError *error = NULL;
2117 if (_bt_is_discovering() == TRUE) {
2118 BT_ERR("BT is already in discovering");
2119 return BLUETOOTH_ERROR_IN_PROGRESS;
2120 } else if (_bt_is_device_creating() == TRUE) {
2121 BT_ERR("Bonding device is going on");
2122 return BLUETOOTH_ERROR_DEVICE_BUSY;
2125 proxy = _bt_get_adapter_proxy();
2126 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2128 result = g_dbus_proxy_call_sync(proxy,
2131 G_DBUS_CALL_FLAGS_NONE,
2137 if (error != NULL) {
2138 BT_ERR("StartDiscovery failed (Error: %s)", error->message);
2139 g_clear_error(&error);
2141 BT_ERR("StartDiscovery failed");
2142 return BLUETOOTH_ERROR_INTERNAL;
2145 is_discovering = TRUE;
2146 cancel_by_user = FALSE;
2147 /* discovery status will be change in event */
2148 g_variant_unref(result);
2149 return BLUETOOTH_ERROR_NONE;
2152 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
2156 GError *error = NULL;
2157 const gchar *disc_type;
2159 if (_bt_is_discovering() == TRUE) {
2160 BT_ERR("BT is already in discovering");
2161 return BLUETOOTH_ERROR_IN_PROGRESS;
2164 proxy = _bt_get_adapter_proxy();
2165 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2167 if (role == DISCOVERY_ROLE_BREDR)
2168 disc_type = "BREDR";
2169 else if (role == DISCOVERY_ROLE_LE)
2171 else if (role == DISCOVERY_ROLE_LE_BREDR)
2172 disc_type = "LE_BREDR";
2174 return BLUETOOTH_ERROR_INVALID_PARAM;
2176 result = g_dbus_proxy_call_sync(proxy,
2177 "StartCustomDiscovery",
2178 g_variant_new("s", disc_type),
2179 G_DBUS_CALL_FLAGS_NONE,
2185 if (error != NULL) {
2186 BT_ERR("StartCustomDiscovery failed (Error: %s)", error->message);
2187 g_clear_error(&error);
2189 BT_ERR("StartCustomDiscovery failed");
2190 return BLUETOOTH_ERROR_INTERNAL;
2193 is_discovering = TRUE;
2194 cancel_by_user = FALSE;
2195 /* discovery status will be change in event */
2196 g_variant_unref(result);
2197 return BLUETOOTH_ERROR_NONE;
2200 int _bt_cancel_discovery(void)
2203 GError *error = NULL;
2206 if (_bt_is_discovering() == FALSE) {
2207 BT_ERR("BT is not in discovering");
2208 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
2211 proxy = _bt_get_adapter_proxy();
2212 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2214 result = g_dbus_proxy_call_sync(proxy,
2217 G_DBUS_CALL_FLAGS_NONE,
2223 int ret = BLUETOOTH_ERROR_INTERNAL;
2224 if (error != NULL) {
2225 BT_ERR("StopDiscovery failed (Error: %s)", error->message);
2227 if (g_strrstr(error->message, "No discovery started"))
2228 ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
2230 g_clear_error(&error);
2232 BT_ERR("StopDiscovery failed");
2238 cancel_by_user = TRUE;
2239 /* discovery status will be change in event */
2240 g_variant_unref(result);
2241 return BLUETOOTH_ERROR_NONE;
2244 gboolean _bt_is_discovering(void)
2246 return is_discovering;
2249 gboolean _bt_is_connectable(void)
2252 GError *error = NULL;
2253 gboolean is_connectable = FALSE;
2257 proxy = _bt_get_adapter_properties_proxy();
2258 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2260 result = g_dbus_proxy_call_sync(proxy,
2262 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2264 G_DBUS_CALL_FLAGS_NONE,
2270 if (error != NULL) {
2271 BT_ERR("Failed to get connectable property (Error: %s)", error->message);
2272 g_clear_error(&error);
2274 BT_ERR("Failed to get connectable property");
2275 return BLUETOOTH_ERROR_INTERNAL;
2278 g_variant_get(result, "(v)", &temp);
2279 is_connectable = g_variant_get_boolean(temp);
2280 BT_DBG("discoverable_v:%d", is_connectable);
2282 g_variant_unref(result);
2283 g_variant_unref(temp);
2285 BT_INFO("Get connectable [%d]", is_connectable);
2286 return is_connectable;
2289 int _bt_set_connectable(gboolean is_connectable)
2292 GError *error = NULL;
2295 if (__bt_is_factory_test_mode()) {
2296 BT_ERR("Unable to set connectable in factory binary !!");
2297 return BLUETOOTH_ERROR_NOT_SUPPORT;
2300 proxy = _bt_get_adapter_properties_proxy();
2302 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2304 result = g_dbus_proxy_call_sync(proxy,
2306 g_variant_new("(ssv)", BT_ADAPTER_INTERFACE, "Connectable",
2307 g_variant_new("b", is_connectable)),
2308 G_DBUS_CALL_FLAGS_NONE,
2314 if (error != NULL) {
2315 BT_ERR("Failed to set connectable property (Error: %s)", error->message);
2316 g_clear_error(&error);
2318 BT_ERR("Failed to set connectable property");
2319 return BLUETOOTH_ERROR_INTERNAL;
2322 BT_INFO_C("### Set connectable [%d]", is_connectable);
2323 g_variant_unref(result);
2324 return BLUETOOTH_ERROR_NONE;
2327 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
2330 gboolean discovering_v;
2331 GError *error = NULL;
2332 char *discovering_type = NULL;
2336 proxy = _bt_get_adapter_properties_proxy();
2337 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2339 if (discovery_type == DISCOVERY_ROLE_BREDR)
2340 discovering_type = "Discovering";
2341 else if (discovery_type == DISCOVERY_ROLE_LE)
2342 discovering_type = "LEDiscovering";
2344 result = g_dbus_proxy_call_sync(proxy,
2346 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2348 G_DBUS_CALL_FLAGS_NONE,
2354 if (error != NULL) {
2355 BT_ERR("Failed to get discovering property (Error: %s)", error->message);
2356 g_clear_error(&error);
2358 BT_ERR("Failed to get discovering property");
2359 return BLUETOOTH_ERROR_INTERNAL;
2362 g_variant_get(result, "(v)", &temp);
2363 discovering_v = g_variant_get_boolean(temp);
2364 BT_DBG("discoverable_v:%d", discovering_v);
2366 g_variant_unref(result);
2367 g_variant_unref(temp);
2369 return discovering_v;
2372 unsigned int _bt_get_discoverable_timeout_property(void)
2375 unsigned int timeout_v;
2376 GError *error = NULL;
2380 proxy = _bt_get_adapter_properties_proxy();
2381 retv_if(proxy == NULL, 0);
2383 result = g_dbus_proxy_call_sync(proxy,
2385 g_variant_new("(ss)", BT_ADAPTER_INTERFACE,
2386 "DiscoverableTimeout"),
2387 G_DBUS_CALL_FLAGS_NONE,
2393 BT_ERR("Fail to get discoverable timeout");
2394 if (error != NULL) {
2395 BT_ERR("Fail to get discoverable timeout (Error: %s)", error->message);
2396 g_clear_error(&error);
2401 g_variant_get(result, "(v)", &temp);
2402 timeout_v = g_variant_get_uint32(temp);
2403 BT_DBG("discoverable_v:%d", timeout_v);
2405 g_variant_unref(result);
2406 g_variant_unref(temp);
2411 static bluetooth_device_info_t *__bt_parse_device_info(GVariantIter *item_iter)
2413 bluetooth_device_info_t *dev_info;
2416 GByteArray *manufacturer_data = NULL;
2418 GVariantIter *char_value_iter;
2420 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
2422 while (g_variant_iter_loop(item_iter, "{sv}", &key, &value)) {
2427 if (!g_strcmp0(key, "Address")) {
2428 const char *address = NULL;
2429 address = g_variant_get_string(value, NULL);
2430 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2432 } else if (!g_strcmp0(key, "Class")) {
2434 cod = g_variant_get_uint32(value);
2435 _bt_divide_device_class(&dev_info->device_class, cod);
2436 } else if (!g_strcmp0(key, "Name")) {
2437 const char *name = NULL;
2438 name = g_variant_get_string(value, NULL);
2439 /* If there is no Alias */
2440 if (strlen(dev_info->device_name.name) == 0) {
2441 g_strlcpy(dev_info->device_name.name, name,
2442 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2444 } else if (!g_strcmp0(key, "Alias")) {
2445 const char *alias = NULL;
2446 alias = g_variant_get_string(value, NULL);
2447 /* Overwrite the name */
2449 memset(dev_info->device_name.name, 0x00,
2450 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2451 g_strlcpy(dev_info->device_name.name, alias,
2452 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2454 } else if (!g_strcmp0(key, "IsAliasSet")) {
2455 dev_info->is_alias_set = g_variant_get_boolean(value);
2456 } else if (!g_strcmp0(key, "Connected")) {
2457 dev_info->connected = g_variant_get_byte(value);
2458 } else if (!g_strcmp0(key, "Paired")) {
2459 dev_info->paired = g_variant_get_boolean(value);
2460 } else if (!g_strcmp0(key, "Trusted")) {
2461 dev_info->trust = g_variant_get_boolean(value);
2462 } else if (!g_strcmp0(key, "RSSI")) {
2463 dev_info->rssi = g_variant_get_int16(value);
2464 } else if (!g_strcmp0(key, "UUIDs")) {
2470 dev_info->service_index = 0;
2471 g_variant_get(value, "as", &iter);
2472 while (g_variant_iter_loop(iter, "s", &uuid)) {
2473 g_strlcpy(dev_info->uuids[i], uuid, BLUETOOTH_UUID_STRING_MAX);
2474 parts = g_strsplit(uuid, "-", -1);
2476 if (parts == NULL || parts[0] == NULL) {
2481 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2486 dev_info->service_index = i;
2487 g_variant_iter_free(iter);
2488 } else if (strcasecmp(key, "LegacyManufacturerDataLen") == 0) {
2489 dev_info->manufacturer_data.data_len = g_variant_get_uint16(value);
2490 } else if (strcasecmp(key, "LegacyManufacturerData") == 0) {
2491 manufacturer_data = g_byte_array_new();
2492 g_variant_get(value, "ay", &char_value_iter);
2493 while (g_variant_iter_loop(char_value_iter, "y", &char_value))
2494 g_byte_array_append(manufacturer_data, &char_value, 1);
2496 if (manufacturer_data) {
2497 if (manufacturer_data->len > 0)
2498 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
2500 g_variant_iter_free(char_value_iter);
2501 g_byte_array_free(manufacturer_data, TRUE);
2508 static void __bt_extract_device_info(GVariantIter *iter,
2511 bluetooth_device_info_t *dev_info = NULL;
2512 char *object_path = NULL;
2513 GVariantIter *interface_iter;
2514 GVariantIter *svc_iter;
2515 char *interface_str = NULL;
2517 /* Parse the signature: oa{sa{sv}}} */
2518 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path,
2521 if (object_path == NULL)
2524 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2525 &interface_str, &svc_iter)) {
2526 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2527 BT_DBG("Found a device: %s", object_path);
2528 dev_info = __bt_parse_device_info(svc_iter);
2530 if (dev_info->paired == TRUE) {
2531 g_array_append_vals(*dev_list, dev_info,
2532 sizeof(bluetooth_device_info_t));
2536 g_free(interface_str);
2537 g_variant_iter_free(svc_iter);
2545 int _bt_get_bonded_devices(GArray **dev_list)
2548 GDBusConnection *conn;
2549 GDBusProxy *manager_proxy;
2550 GVariant *result = NULL;
2551 GVariantIter *iter = NULL;
2552 GError *error = NULL;
2554 conn = _bt_gdbus_get_system_gconn();
2555 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2557 manager_proxy = _bt_get_manager_proxy();
2558 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2560 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2562 G_DBUS_CALL_FLAGS_NONE,
2568 if (error != NULL) {
2569 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2570 g_clear_error(&error);
2572 BT_ERR("Failed to Failed to GetManagedObjects");
2573 return BLUETOOTH_ERROR_INTERNAL;
2576 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2577 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2579 __bt_extract_device_info(iter, dev_list);
2580 g_variant_iter_free(iter);
2581 g_variant_unref(result);
2584 return BLUETOOTH_ERROR_NONE;
2587 int _bt_get_profile_connected_devices(char *profile_uuid, GArray **addr_list)
2590 GDBusConnection *conn;
2591 GDBusProxy *manager_proxy;
2592 GVariant *result = NULL;
2593 GVariant *result1 = NULL;
2594 GVariantIter *iter = NULL;
2595 GError *error = NULL;
2596 char *object_path = NULL;
2597 GVariantIter *interface_iter;
2598 char *interface_str = NULL;
2599 GDBusProxy *device_proxy = NULL;
2600 gboolean is_connected = FALSE;
2602 conn = _bt_gdbus_get_system_gconn();
2603 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2605 manager_proxy = _bt_get_manager_proxy();
2606 retv_if(manager_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2608 result = g_dbus_proxy_call_sync(manager_proxy, "GetManagedObjects",
2610 G_DBUS_CALL_FLAGS_NONE,
2616 if (error != NULL) {
2617 BT_ERR("Failed to GetManagedObjects (Error: %s)", error->message);
2618 g_clear_error(&error);
2621 BT_ERR("Failed to Failed to GetManagedObjects");
2622 return BLUETOOTH_ERROR_INTERNAL;
2625 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2626 g_variant_get(result, "(a{oa{sa{sv}}})", &iter);
2628 /* Parse the signature: oa{sa{sv}}} */
2629 while (g_variant_iter_loop(iter, "{&oa{sa{sv}}}", &object_path, &interface_iter)) {
2630 if (object_path == NULL)
2633 while (g_variant_iter_loop(interface_iter, "{sa{sv}}",
2634 &interface_str, NULL)) {
2635 if (g_strcmp0(interface_str, "org.bluez.Device1") == 0) {
2636 BT_DBG("Found a device: %s", object_path);
2637 g_free(interface_str);
2639 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2640 NULL, BT_BLUEZ_NAME,
2641 object_path, BT_DEVICE_INTERFACE, NULL, NULL);
2643 if (device_proxy == NULL) {
2644 BT_DBG("Device don't have this service");
2648 result1 = g_dbus_proxy_call_sync(device_proxy, "IsConnectedProfile",
2649 g_variant_new("(s)", profile_uuid),
2650 G_DBUS_CALL_FLAGS_NONE,
2655 if (result1 == NULL) {
2656 BT_ERR("Error occured in Proxy call");
2658 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
2659 g_error_free(error);
2662 g_object_unref(device_proxy);
2665 g_variant_get(result1, "(b)", &is_connected);
2667 if (is_connected == TRUE) {
2668 char address[BT_ADDRESS_STRING_SIZE];
2669 bluetooth_device_address_t *addr = NULL;
2671 _bt_convert_device_path_to_address(object_path, address);
2673 addr = g_malloc0(sizeof(bluetooth_device_address_t));
2674 _bt_convert_addr_string_to_type(addr->addr, address);
2676 g_array_append_vals(*addr_list, addr,
2677 sizeof(bluetooth_device_address_t));
2680 g_variant_unref(result1);
2681 g_object_unref(device_proxy);
2688 g_variant_unref(result);
2689 g_variant_iter_free(iter);
2692 return BLUETOOTH_ERROR_NONE;
2695 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2696 bluetooth_device_info_t *dev_info)
2698 char *object_path = NULL;
2699 GDBusProxy *adapter_proxy;
2700 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2701 int ret = BLUETOOTH_ERROR_NONE;
2703 BT_CHECK_PARAMETER(device_address, return);
2704 BT_CHECK_PARAMETER(dev_info, return);
2706 adapter_proxy = _bt_get_adapter_proxy();
2707 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2709 _bt_convert_addr_type_to_string(address, device_address->addr);
2711 object_path = _bt_get_device_object_path(address);
2713 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2715 ret = __bt_get_bonded_device_info(object_path, dev_info);
2716 g_free(object_path);
2721 int _bt_is_alias_set(bluetooth_device_address_t *device_address, gboolean *is_alias_set)
2723 char *object_path = NULL;
2724 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2725 gboolean alias_set = FALSE;
2727 GDBusConnection *conn;
2728 GDBusProxy *device_proxy;
2729 GError *error = NULL;
2730 GVariant *result = NULL;
2731 GVariant *temp = NULL;
2734 BT_CHECK_PARAMETER(device_address, return);
2735 BT_CHECK_PARAMETER(is_alias_set, return);
2737 _bt_convert_addr_type_to_string(address, device_address->addr);
2739 object_path = _bt_get_device_object_path(address);
2740 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2742 conn = _bt_gdbus_get_system_gconn();
2744 g_free(object_path);
2745 return BLUETOOTH_ERROR_INTERNAL;
2748 device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
2752 BT_PROPERTIES_INTERFACE,
2754 if (device_proxy == NULL) {
2755 g_free(object_path);
2756 return BLUETOOTH_ERROR_INTERNAL;
2759 result = g_dbus_proxy_call_sync(device_proxy, "Get",
2760 g_variant_new("(ss)", BT_DEVICE_INTERFACE, "IsAliasSet"),
2761 G_DBUS_CALL_FLAGS_NONE,
2767 BT_ERR("Error occured in Proxy call");
2768 if (error != NULL) {
2769 BT_ERR("Getting is_alias_set property failed: [%s]\n", error->message);
2770 g_error_free(error);
2772 g_object_unref(device_proxy);
2773 g_free(object_path);
2774 return BLUETOOTH_ERROR_INTERNAL;
2777 g_variant_get(result, "(v)", &temp);
2778 alias_set = g_variant_get_boolean(temp);
2779 *is_alias_set = alias_set;
2780 BT_DBG("address: [%s] | *is_alias_set: %s", address, *is_alias_set ? "TRUE" : "FALSE");
2781 g_variant_unref(temp);
2782 g_variant_unref(result);
2783 g_object_unref(device_proxy);
2785 g_free(object_path);
2787 return BLUETOOTH_ERROR_NONE;
2790 int _bt_get_timeout_value(int *timeout)
2792 time_t current_time;
2795 /* Take current time */
2796 time(¤t_time);
2797 time_diff = difftime(current_time, visible_timer.start_time);
2799 BT_DBG("Time diff = %d\n", time_diff);
2801 *timeout = visible_timer.timeout - time_diff;
2803 return BLUETOOTH_ERROR_NONE;
2806 int _bt_set_le_privacy(gboolean set_privacy)
2809 GError *error = NULL;
2810 GVariant *result = NULL;
2812 if (__bt_is_factory_test_mode()) {
2813 BT_ERR("Unable to set le privacy in factory binary !!");
2814 return BLUETOOTH_ERROR_NOT_SUPPORT;
2817 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2818 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2819 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2822 proxy = _bt_get_adapter_proxy();
2823 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2825 result = g_dbus_proxy_call_sync(proxy,
2827 g_variant_new("(b)", set_privacy),
2828 G_DBUS_CALL_FLAGS_NONE,
2834 if (error != NULL) {
2835 BT_ERR("Failed to SetLePrivacy (Error: %s)", error->message);
2836 g_clear_error(&error);
2838 BT_ERR("Failed to SetLePrivacy");
2839 return BLUETOOTH_ERROR_INTERNAL;
2842 g_variant_unref(result);
2843 BT_INFO("SetLePrivacy as %d", set_privacy);
2844 return BLUETOOTH_ERROR_NONE;
2847 int _bt_set_le_static_random_address(gboolean is_enable)
2850 GError *error = NULL;
2851 GVariant *result = NULL;
2853 if (__bt_is_factory_test_mode()) {
2854 BT_ERR("Unable to set le random address in factory binary !!");
2855 return BLUETOOTH_ERROR_NOT_SUPPORT;
2858 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2859 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2860 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2863 proxy = _bt_get_adapter_proxy();
2864 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2866 result = g_dbus_proxy_call_sync(proxy,
2867 "SetLeStaticRandomAddress",
2868 g_variant_new("(b)", is_enable),
2869 G_DBUS_CALL_FLAGS_NONE,
2875 if (error != NULL) {
2876 BT_ERR("Failed to SetLeStaticRandomAddress (Error: %s)", error->message);
2877 g_clear_error(&error);
2879 BT_ERR("Failed to SetLeStaticRandomAddress");
2880 return BLUETOOTH_ERROR_INTERNAL;
2883 g_variant_unref(result);
2884 BT_INFO("SetLeStaticRandomAddress as %d", is_enable);
2885 return BLUETOOTH_ERROR_NONE;
2888 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2891 GError *error = NULL;
2895 GVariantBuilder *builder;
2897 BT_CHECK_PARAMETER(m_data, return);
2899 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2900 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2901 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2904 proxy = _bt_get_adapter_proxy();
2905 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2907 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2909 for (i = 0; i < (m_data->data_len) + 2; i++)
2910 g_variant_builder_add(builder, "y", m_data->data[i]);
2912 val = g_variant_new("(ay)", builder);
2914 result = g_dbus_proxy_call_sync(proxy,
2915 "SetManufacturerData",
2917 G_DBUS_CALL_FLAGS_NONE,
2921 g_variant_builder_unref(builder);
2923 if (error != NULL) {
2924 BT_ERR("Failed to SetManufacturerData (Error: %s)", error->message);
2925 g_clear_error(&error);
2927 BT_ERR("Failed to SetManufacturerData");
2929 return BLUETOOTH_ERROR_INTERNAL;
2931 builder = g_variant_builder_new(G_VARIANT_TYPE("ay"));
2933 for (i = 0; i < (m_data->data_len) + 2; i++)
2934 g_variant_builder_add(builder, "y", m_data->data[i]);
2936 val = g_variant_new("(ay)", builder);
2938 _bt_send_event(BT_ADAPTER_EVENT,
2939 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2942 BT_INFO("Set manufacturer data");
2944 g_variant_builder_unref(builder);
2945 g_variant_unref(result);
2947 return BLUETOOTH_ERROR_NONE;
2951 int _bt_service_set_alarm(int timeout, bt_set_alarm_cb call_back, void *user_data, alarm_id_t *alarm_id)
2953 int result = BLUETOOTH_ERROR_NONE;
2954 bt_service_alarm_t *alarm = NULL;
2956 if (!call_back || !alarm_id)
2957 return BLUETOOTH_ERROR_INVALID_PARAM;
2959 if (!alarm_mgr.is_alarm_initialized) {
2960 result = alarmmgr_init("bt-service");
2962 BT_ERR("Failed to initialize alarm = %d", result);
2963 result = BLUETOOTH_ERROR_INTERNAL;
2966 result = alarmmgr_set_cb(alarm_cb, NULL);
2968 BT_ERR("Failed to set the callback = %d", result);
2969 result = BLUETOOTH_ERROR_INTERNAL;
2972 alarm_mgr.is_alarm_initialized = TRUE;
2975 alarm = g_malloc0(sizeof(bt_service_alarm_t));
2977 return BLUETOOTH_ERROR_MEMORY_ALLOCATION;
2979 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, timeout,
2982 BT_ERR("Failed to create alarm error = %d", result);
2983 result = BLUETOOTH_ERROR_INTERNAL;
2987 alarm->alarm_id = *alarm_id;
2988 alarm->callback = call_back;
2989 alarm->user_data = user_data;
2991 alarm_mgr.g_alarm_list = g_list_append(alarm_mgr.g_alarm_list, alarm);
2992 result = BLUETOOTH_ERROR_NONE;
2997 static int alarm_cb(alarm_id_t alarm_id, void* user_param)
3000 bt_service_alarm_t *p_data;
3001 bt_set_alarm_cb callback = NULL;
3002 void *user_data = NULL;
3004 node = g_list_find_custom(alarm_mgr.g_alarm_list,
3005 GINT_TO_POINTER(alarm_id), compare_alarm);
3009 p_data = (bt_service_alarm_t *)node->data;
3010 alarm_mgr.g_alarm_list = g_list_delete_link(alarm_mgr.g_alarm_list,
3016 callback = p_data->callback;
3017 user_data = p_data->user_data;
3021 callback(alarm_id, user_data);
3026 int _bt_service_remove_alarm(alarm_id_t alarm_id)
3029 bt_service_alarm_t *p_data;
3030 list = g_list_find_custom(alarm_mgr.g_alarm_list, GINT_TO_POINTER(alarm_id), compare_alarm);
3033 alarmmgr_remove_alarm(alarm_id);
3034 p_data = (bt_service_alarm_t *)list->data;
3035 alarm_mgr.g_alarm_list = g_list_remove(alarm_mgr.g_alarm_list, list->data);
3042 gint compare_alarm(gconstpointer list_data, gconstpointer data)
3044 alarm_id_t alarm_id = (alarm_id_t)data;
3045 bt_service_alarm_t *p_data = (bt_service_alarm_t *)list_data;
3047 if (p_data->alarm_id == alarm_id)
3053 static void alarm_data_free(void *data)
3055 bt_service_alarm_t *p_data = (bt_service_alarm_t *)data;
3060 static gboolean _bt_adapter_request_delayed_cb(gpointer user_data)
3063 int function = (int)user_data;
3066 case BT_ENABLE_ADAPTER:
3067 result = _bt_enable_adapter();
3068 if (result != BLUETOOTH_ERROR_NONE) {
3069 BT_ERR("_bt_enable_adapter is failed");
3070 /* Send enabled event to API */
3071 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
3072 g_variant_new("(i)", result));
3075 case BT_DISABLE_ADAPTER:
3076 result = _bt_disable_adapter();
3077 if (result != BLUETOOTH_ERROR_NONE) {
3078 BT_ERR("_bt_disable_adapter is failed");
3079 /* Send disabled event to API */
3080 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
3081 g_variant_new("(i)", result));
3085 BT_ERR("function is NOT matched");
3092 int _bt_adapter_request_delayed(int function)
3097 case BT_ENABLE_ADAPTER:
3098 ret = _bt_enable_adapter_check_status();
3099 if (ret == BLUETOOTH_ERROR_NONE)
3100 _bt_adapter_set_status(BT_ACTIVATING);
3105 case BT_DISABLE_ADAPTER:
3106 ret = _bt_disable_adapter_check_status();
3107 if (ret == BLUETOOTH_ERROR_NONE)
3108 _bt_adapter_set_status(BT_DEACTIVATING);
3114 BT_ERR("function is NOT matched");
3115 return BLUETOOTH_ERROR_INTERNAL;
3118 g_idle_add((GSourceFunc)_bt_adapter_request_delayed_cb, (void*)function);
3120 return BLUETOOTH_ERROR_NONE;
3124 int _bt_get_enable_timer_id(void)