4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
7 * Girishashok Joshi <girish.joshi@samsung.com>
8 * Chanyeol Park <chanyeol.park@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
25 #include <dbus/dbus-glib.h>
26 #include <dbus/dbus.h>
31 #include <syspopup_caller.h>
33 #include <notification.h>
34 //#include <journal/device.h>
38 #include "bluetooth-api.h"
39 #include "bt-internal-types.h"
41 #include "bt-service-common.h"
42 #include "bt-service-event.h"
43 #include "bt-service-adapter.h"
44 #include "bt-service-util.h"
45 #include "bt-service-network.h"
46 #include "bt-service-obex-server.h"
47 #include "bt-service-agent.h"
48 #include "bt-service-main.h"
49 #include "bt-service-avrcp.h"
59 bt_adapter_timer_t visible_timer = {0, };
61 static gboolean is_discovering;
62 static gboolean is_le_discovering;
63 static bt_le_discovery_type_t le_discovery_type = BT_LE_PASSIVE_SCAN;
64 static gboolean cancel_by_user;
65 static bt_status_t adapter_status = BT_DEACTIVATED;
66 static bt_le_status_t adapter_le_status = BT_LE_DEACTIVATED;
67 static void *adapter_agent = NULL;
68 static DBusGProxy *core_proxy = NULL;
69 static guint timer_id = 0;
70 static guint le_timer_id = 0;
72 #define BT_CORE_NAME "org.projectx.bt_core"
73 #define BT_CORE_PATH "/org/projectx/bt_core"
74 #define BT_CORE_INTERFACE "org.projectx.btcore"
76 #define BT_DISABLE_TIME 500 /* 500 ms */
78 DBusGProxy *_bt_init_core_proxy(void)
81 DBusGConnection *conn;
83 conn = _bt_get_system_gconn();
87 proxy = dbus_g_proxy_new_for_name(conn, BT_CORE_NAME,
88 BT_CORE_PATH, BT_CORE_INTERFACE);
97 static DBusGProxy *__bt_get_core_proxy(void)
99 return (core_proxy) ? core_proxy : _bt_init_core_proxy();
102 static gboolean __bt_is_factory_test_mode(void)
106 #ifdef ENABLE_TIZEN_2_4
107 if (vconf_get_bool(VCONFKEY_BT_DUT_MODE, &mode)) {
108 BT_ERR("Get the DUT Mode fail");
114 BT_INFO("DUT Test Mode !!");
121 static gboolean __bt_timeout_handler(gpointer user_data)
123 int result = BLUETOOTH_ERROR_NONE;
127 /* Take current time */
129 time_diff = difftime(current_time, visible_timer.start_time);
131 /* Send event to application */
132 _bt_send_event(BT_ADAPTER_EVENT,
133 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
134 DBUS_TYPE_INT32, &result,
135 DBUS_TYPE_INT16, &time_diff,
138 if (visible_timer.timeout <= time_diff) {
139 g_source_remove(visible_timer.event_id);
140 visible_timer.event_id = 0;
141 visible_timer.timeout = 0;
143 #ifndef TIZEN_WEARABLE
144 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
145 BT_ERR("Set vconf failed\n");
153 static int __bt_visibility_alarm_cb(alarm_id_t alarm_id, void* user_param)
155 BT_DBG("__bt_visibility_alarm_cb - alram id = [%d] \n", alarm_id);
157 int result = BLUETOOTH_ERROR_NONE;
160 if (alarm_id != visible_timer.alarm_id)
163 if (visible_timer.event_id) {
164 _bt_send_event(BT_ADAPTER_EVENT,
165 BLUETOOTH_EVENT_DISCOVERABLE_TIMEOUT_CHANGED,
166 DBUS_TYPE_INT32, &result,
167 DBUS_TYPE_INT16, &timeout,
169 g_source_remove(visible_timer.event_id);
170 visible_timer.event_id = 0;
171 visible_timer.timeout = 0;
173 #ifndef TIZEN_WEARABLE
174 if (vconf_set_int(BT_FILE_VISIBLE_TIME, 0) != 0)
175 BT_ERR("Set vconf failed\n");
178 /* Switch Off visibility in Bluez */
179 _bt_set_discoverable_mode(BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE, 0);
180 visible_timer.alarm_id = 0;
184 static void __bt_visibility_alarm_create()
189 result = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, visible_timer.timeout,
192 BT_ERR("Failed to create alarm error = %d\n", result);
194 BT_DBG("Alarm created = %d\n", alarm_id);
195 visible_timer.alarm_id = alarm_id;
199 static void __bt_visibility_alarm_remove()
201 if (visible_timer.event_id > 0) {
202 g_source_remove(visible_timer.event_id);
203 visible_timer.event_id = 0;
206 if (visible_timer.alarm_id > 0) {
207 alarmmgr_remove_alarm(visible_timer.alarm_id);
208 visible_timer.alarm_id = 0;
212 int __bt_set_visible_time(int timeout)
216 __bt_visibility_alarm_remove();
218 visible_timer.timeout = timeout;
220 #ifndef TIZEN_WEARABLE
221 if (vconf_set_int(BT_FILE_VISIBLE_TIME, timeout) != 0)
222 BT_ERR("Set vconf failed");
225 return BLUETOOTH_ERROR_NONE;
227 if (!visible_timer.alarm_init) {
228 /* Set Alarm timer to switch off BT */
229 result = alarmmgr_init("bt-service");
231 return BLUETOOTH_ERROR_INTERNAL;
233 visible_timer.alarm_init = TRUE;
236 result = alarmmgr_set_cb(__bt_visibility_alarm_cb, NULL);
238 return BLUETOOTH_ERROR_INTERNAL;
240 /* Take start time */
241 time(&(visible_timer.start_time));
242 visible_timer.event_id = g_timeout_add_seconds(1,
243 __bt_timeout_handler, NULL);
245 __bt_visibility_alarm_create();
247 return BLUETOOTH_ERROR_NONE;
250 static void __bt_get_service_list(GValue *value, bluetooth_device_info_t *dev)
256 ret_if(value == NULL);
259 uuids = g_value_get_boxed(value);
260 ret_if(uuids == NULL);
262 dev->service_index = 0;
264 for (i = 0; uuids[i] != NULL; i++) {
265 g_strlcpy(dev->uuids[i], uuids[i], BLUETOOTH_UUID_STRING_MAX);
267 parts = g_strsplit(uuids[i], "-", -1);
269 if (parts == NULL || parts[0] == NULL)
272 dev->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
275 dev->service_index++;
279 static int __bt_get_bonded_device_info(gchar *device_path,
280 bluetooth_device_info_t *dev_info)
282 GValue *value = { 0 };
284 DBusGProxy *device_proxy;
285 const gchar *address;
292 GByteArray *manufacturer_data = NULL;
293 GHashTable *hash = NULL;
295 DBusGConnection *conn;
297 BT_CHECK_PARAMETER(device_path, return);
298 BT_CHECK_PARAMETER(dev_info, return);
300 conn = _bt_get_system_gconn();
301 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
303 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
304 device_path, BT_PROPERTIES_INTERFACE);
306 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
308 dbus_g_proxy_call(device_proxy, "GetAll", &err,
309 G_TYPE_STRING, BT_DEVICE_INTERFACE,
311 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
312 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
314 g_object_unref(device_proxy);
317 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
319 return BLUETOOTH_ERROR_INTERNAL;
323 value = g_hash_table_lookup(hash, "Paired");
324 paired = g_value_get_boolean(value);
326 value = g_hash_table_lookup(hash, "Address");
327 address = value ? g_value_get_string(value) : NULL;
329 value = g_hash_table_lookup(hash, "Alias");
330 name = value ? g_value_get_string(value) : NULL;
333 BT_DBG("Alias Name [%s]", name);
335 value = g_hash_table_lookup(hash, "Name");
336 name = value ? g_value_get_string(value) : NULL;
339 value = g_hash_table_lookup(hash, "Class");
340 cod = value ? g_value_get_uint(value) : 0;
342 value = g_hash_table_lookup(hash, "Connected");
343 connected = value ? g_value_get_boolean(value) : FALSE;
345 value = g_hash_table_lookup(hash, "Trusted");
346 trust = value ? g_value_get_boolean(value) : FALSE;
348 BT_DBG("paired: %d", paired);
349 BT_DBG("trust: %d", trust);
351 if ((paired == FALSE) && (trust == FALSE)) {
352 return BLUETOOTH_ERROR_NOT_PAIRED;
355 value = g_hash_table_lookup(hash, "RSSI");
356 rssi = value ? g_value_get_int(value) : 0;
358 value = g_hash_table_lookup(hash, "UUIDs");
359 __bt_get_service_list(value, dev_info);
361 value = g_hash_table_lookup(hash, "ManufacturerDataLen");
362 dev_info->manufacturer_data.data_len = value ? g_value_get_uint(value) : 0;
364 value = g_hash_table_lookup(hash, "ManufacturerData");
365 manufacturer_data = value ? g_value_get_boxed(value) : NULL;
366 if (manufacturer_data) {
367 if (manufacturer_data->len > 0) {
368 BT_DBG("manufacturer_data->len = %d", manufacturer_data->len);
369 memcpy(dev_info->manufacturer_data.data, manufacturer_data->data, manufacturer_data->len);
373 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
376 _bt_divide_device_class(&dev_info->device_class, cod);
378 g_strlcpy(dev_info->device_name.name, name,
379 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
381 dev_info->rssi = rssi;
382 dev_info->trust = trust;
383 dev_info->paired = paired;
384 dev_info->connected = connected;
385 g_hash_table_destroy(hash);
386 ret = BLUETOOTH_ERROR_NONE;
388 BT_ERR("Hash is NULL\n");
389 ret = BLUETOOTH_ERROR_INTERNAL;
395 void _bt_set_discovery_status(gboolean mode)
397 is_discovering = mode;
400 void _bt_set_le_discovery_status(gboolean mode)
402 is_le_discovering = mode;
405 void _bt_set_le_discovery_type(bt_le_discovery_type_t type)
407 le_discovery_type = type;
410 bt_le_discovery_type_t _bt_get_le_discovery_type(void)
412 return le_discovery_type;
415 void _bt_set_cancel_by_user(gboolean value)
417 cancel_by_user = value;
420 gboolean _bt_get_cancel_by_user(void)
422 return cancel_by_user;
425 void _bt_adapter_set_status(bt_status_t status)
427 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_status, status);
428 adapter_status = status;
431 bt_status_t _bt_adapter_get_status(void)
433 return adapter_status;
436 void _bt_adapter_set_le_status(bt_le_status_t status)
438 BT_INFO("adapter_le_status changed [%d] -> [%d]", adapter_le_status, status);
439 adapter_le_status = status;
442 bt_le_status_t _bt_adapter_get_le_status(void)
444 return adapter_le_status;
447 static void __bt_phone_name_changed_cb(keynode_t *node, void *data)
449 char *phone_name = NULL;
455 if (vconf_keynode_get_type(node) == VCONF_TYPE_STRING) {
456 phone_name = vconf_keynode_get_str(node);
458 if (phone_name && strlen(phone_name) != 0) {
459 if (!g_utf8_validate(phone_name, -1,
460 (const char **)&ptr))
463 _bt_set_local_name(phone_name);
468 #ifdef TIZEN_WEARABLE
469 static char * __bt_change_dev_name(const char *default_name)
476 if ((fp = fopen("/csa/bluetooth/.bd_addr", "r")) == NULL) {
477 BT_ERR("Unable to open bd_addr");
481 result = fseek(fp, -4, SEEK_END);
483 BT_ERR("fseek is failed");
488 buf = (char *)malloc(sizeof(char) * 5);
490 BT_ERR("malloc is failed");
496 result = fread(buf, 1, 4, fp);
498 BT_DBG("Size Read: [%d]", result);
500 BT_ERR("Error reading file: code[%d]", result);
502 name = g_strdup_printf("%s (%s)", default_name, buf);
512 static void __bt_set_visible_mode(void)
516 if (vconf_get_int(BT_FILE_VISIBLE_TIME, &timeout) != 0)
517 BT_ERR("Fail to get the timeout value");
523 static void __bt_set_local_name(void)
525 char *phone_name = NULL;
528 phone_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
533 if (strlen(phone_name) != 0) {
534 if (!g_utf8_validate(phone_name, -1, (const char **)&ptr))
537 #ifdef TIZEN_WEARABLE
538 if (strstr(phone_name, "(") == NULL) {
539 char *tmp = __bt_change_dev_name(phone_name);
546 _bt_set_local_name(phone_name);
551 static int __bt_set_enabled(void)
553 int adapter_status = BT_ADAPTER_DISABLED;
554 int result = BLUETOOTH_ERROR_NONE;
556 _bt_check_adapter(&adapter_status);
558 if (adapter_status == BT_ADAPTER_DISABLED) {
559 BT_ERR("Bluetoothd is not running");
560 return BLUETOOTH_ERROR_INTERNAL;
563 #ifndef TIZEN_WEARABLE
564 __bt_set_visible_mode();
567 __bt_set_local_name();
569 /* Update Bluetooth Status to notify other modules */
570 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
571 BT_ERR("Set vconf failed\n");
573 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
574 BT_ERR("Set vconf failed\n");
576 /* Send enabled event to API */
577 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
578 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
580 return BLUETOOTH_ERROR_NONE;
583 void _bt_set_disabled(int result)
585 int power_off_status = 0;
588 int pm_ignore_mode = 0;
590 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
591 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
593 ret_pm_ignore = vconf_get_int(VCONFKEY_PM_KEY_IGNORE, &pm_ignore_mode);
595 /* Update the vconf BT status in normal Deactivation case only */
596 if (ret == 0 && power_off_status == VCONFKEY_SYSMAN_POWER_OFF_NONE &&
597 ret_pm_ignore == 0 && pm_ignore_mode != VCONFKEY_PM_KEY_LOCK) {
599 BT_DBG("Update vconf for BT normal Deactivation");
601 if (result == BLUETOOTH_ERROR_TIMEOUT)
602 if (vconf_set_int(BT_OFF_DUE_TO_TIMEOUT, 1) != 0 )
603 BT_ERR("Set vconf failed");
605 /* Update Bluetooth Status to notify other modules */
606 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_OFF) != 0)
607 BT_ERR("Set vconf failed");
610 if (vconf_set_int(VCONFKEY_BT_DEVICE, VCONFKEY_BT_DEVICE_NONE) != 0)
611 BT_ERR("Set vconf failed\n");
613 _bt_adapter_set_status(BT_DEACTIVATED);
615 if (_bt_adapter_get_le_status() != BT_LE_DEACTIVATED) {
616 /* Send disabled event */
617 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
618 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
621 BT_INFO("Adapter disabled");
624 static int __bt_set_le_enabled(void)
627 int result = BLUETOOTH_ERROR_NONE;
630 __bt_set_local_name();
632 #ifdef ENABLE_TIZEN_2_4
633 /* Update Bluetooth Status to notify other modules */
634 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_ON) != 0)
635 BT_ERR("Set vconf failed\n");
637 /* Send enabled event to API */
639 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
640 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
642 status = _bt_adapter_get_status();
643 if (status == BT_DEACTIVATED) {
644 BT_INFO("BREDR is off, turn off PSCAN");
645 _bt_set_connectable(FALSE);
647 if (le_timer_id > 0) {
648 g_source_remove(le_timer_id);
652 /* Send enabled event to API */
653 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_ENABLED,
654 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
657 return BLUETOOTH_ERROR_NONE;
660 void _bt_set_le_disabled(int result)
662 int power_off_status;
665 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
666 BT_DBG("ret : %d", ret);
667 BT_DBG("power_off_status : %d", power_off_status);
669 /* Update Bluetooth Status to notify other modules */
670 BT_DBG("Update vconf for BT LE normal Deactivation");
671 #ifdef ENABLE_TIZEN_2_4
672 if (vconf_set_int(VCONFKEY_BT_LE_STATUS, VCONFKEY_BT_LE_STATUS_OFF) != 0)
673 BT_ERR("Set vconf failed\n");
674 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
677 if (_bt_adapter_get_status() != BT_DEACTIVATED) {
678 /* Send disabled event */
679 _bt_send_event(BT_LE_ADAPTER_EVENT, BLUETOOTH_EVENT_LE_DISABLED,
680 DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
684 void *_bt_get_adapter_agent(void)
686 return adapter_agent;
689 int _bt_enable_core(void)
693 proxy = __bt_get_core_proxy();
694 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
696 if (dbus_g_proxy_call(proxy, "EnableCore", NULL,
697 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
698 BT_ERR("Bt core call failed");
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)
737 #ifdef TIZEN_TELEPHONY_ENABLED
738 ret = vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
739 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL);
741 BT_ERR("Unable to register key handler");
743 BT_DBG("Telephony is disabled");
746 #ifndef TIZEN_WEARABLE
747 #ifdef ENABLE_TIZEN_2_4
748 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_PSMODE,
749 (vconf_callback_fn)__bt_service_flight_ps_mode_cb, NULL);
751 BT_ERR("Unable to register key handler");
756 void _bt_service_unregister_vconf_handler(void)
760 #ifdef TIZEN_TELEPHONY_ENABLED
761 vconf_ignore_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE,
762 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
765 #ifndef TIZEN_WEARABLE
766 #ifdef ENABLE_TIZEN_2_4
767 vconf_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE,
768 (vconf_callback_fn)__bt_service_flight_ps_mode_cb);
773 void _bt_handle_adapter_added(void)
777 bt_le_status_t le_status;
781 BT_DBG("g_source is removed");
782 g_source_remove(timer_id);
786 status = _bt_adapter_get_status();
787 le_status = _bt_adapter_get_le_status();
788 BT_DBG("status : %d", status);
789 BT_DBG("le_status : %d", le_status);
791 adapter_agent = _bt_create_agent(BT_ADAPTER_AGENT_PATH, TRUE);
792 if (!adapter_agent) {
793 BT_ERR("Fail to register agent");
797 if (_bt_register_media_player() != BLUETOOTH_ERROR_NONE)
798 BT_ERR("Fail to register media player");
800 if (_bt_register_obex_server() != BLUETOOTH_ERROR_NONE)
801 BT_ERR("Fail to init obex server");
803 #ifndef TIZEN_WEARABLE
804 if (_bt_network_activate() != BLUETOOTH_ERROR_NONE)
805 BT_ERR("Fail to activate network");
808 /* add the vconf noti handler */
809 ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
810 __bt_phone_name_changed_cb, NULL);
812 BT_ERR("Unable to register key handler");
814 if (le_status == BT_LE_ACTIVATING) {
815 __bt_set_le_enabled();
816 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
818 if (status == BT_ACTIVATING) {
820 _bt_adapter_set_status(BT_ACTIVATED);
824 _bt_service_register_vconf_handler();
827 void _bt_handle_adapter_removed(void)
831 _bt_adapter_set_status(BT_DEACTIVATED);
834 __bt_visibility_alarm_remove();
836 if (visible_timer.alarm_init) {
838 visible_timer.alarm_init = FALSE;
841 ret = vconf_ignore_key_changed(VCONFKEY_SETAPPL_DEVICE_NAME_STR,
842 (vconf_callback_fn)__bt_phone_name_changed_cb);
844 ERR("vconf_ignore_key_changed failed\n");
847 _bt_destroy_agent(adapter_agent);
848 adapter_agent = NULL;
850 _bt_reliable_terminate_service(NULL);
853 static gboolean __bt_enable_timeout_cb(gpointer user_data)
859 retv_if(_bt_adapter_get_status() == BT_ACTIVATED, FALSE);
861 BT_ERR("EnableAdapter is failed");
863 proxy = __bt_get_core_proxy();
867 /* Clean up the process */
868 if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
869 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
870 BT_ERR("Bt core call failed");
873 _bt_set_disabled(BLUETOOTH_ERROR_TIMEOUT);
875 /* Display notification */
876 notification_status_message_post(BT_STR_NOT_SUPPORT);
878 _bt_terminate_service(NULL);
883 static gboolean __bt_enable_le_timeout_cb(gpointer user_data)
889 retv_if(_bt_adapter_get_le_status() == BT_LE_ACTIVATED, FALSE);
891 BT_ERR("EnableAdapterLE is failed");
893 proxy = __bt_get_core_proxy();
897 /* Clean up the process */
898 if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
899 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
900 BT_ERR("Bt core call failed");
903 _bt_adapter_set_le_status(BT_LE_DEACTIVATED);
905 _bt_set_le_disabled(BLUETOOTH_ERROR_TIMEOUT);
907 /* Display notification */
908 notification_status_message_post(BT_STR_NOT_SUPPORT);
910 if (_bt_adapter_get_status() == BT_DEACTIVATED)
911 _bt_terminate_service(NULL);
916 void _bt_adapter_start_le_enable_timer(void)
918 if (le_timer_id > 0) {
919 g_source_remove(le_timer_id);
923 le_timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
924 __bt_enable_le_timeout_cb, NULL);
929 void _bt_adapter_start_enable_timer(void)
932 g_source_remove(timer_id);
936 timer_id = g_timeout_add(BT_ENABLE_TIMEOUT,
937 __bt_enable_timeout_cb, NULL);
942 int _bt_enable_adapter(void)
947 bt_status_t status = _bt_adapter_get_status();
948 bt_le_status_t le_status = _bt_adapter_get_le_status();
951 if (status == BT_ACTIVATING) {
952 BT_ERR("Enabling in progress");
953 return BLUETOOTH_ERROR_IN_PROGRESS;
956 if (status == BT_ACTIVATED) {
957 BT_ERR("Already enabled");
958 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
961 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
962 BT_ERR("Disabling in progress");
963 return BLUETOOTH_ERROR_DEVICE_BUSY;
966 _bt_adapter_set_status(BT_ACTIVATING);
968 proxy = __bt_get_core_proxy();
970 return BLUETOOTH_ERROR_INTERNAL;
972 if (le_status == BT_LE_ACTIVATED) {
973 BT_INFO("LE Already enabled. Just turn on PSCAN");
974 ret = _bt_set_connectable(TRUE);
975 if (ret == BLUETOOTH_ERROR_NONE) {
976 _bt_adapter_set_status(BT_ACTIVATED);
978 return BLUETOOTH_ERROR_INTERNAL;
982 if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapter",
983 BT_ENABLE_TIMEOUT, &err,
985 G_TYPE_INVALID) == FALSE) {
987 _bt_adapter_set_status(BT_DEACTIVATED);
990 BT_ERR("Bt core call failed: [%s]", err->message);
994 /* Clean up the process */
995 if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
996 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
997 BT_ERR("Bt core call failed");
1000 /* Display notification */
1001 notification_status_message_post(BT_STR_NOT_SUPPORT);
1003 /* Terminate myself */
1004 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1005 return BLUETOOTH_ERROR_INTERNAL;
1008 if (le_status == BT_LE_ACTIVATED) {
1011 _bt_adapter_start_enable_timer();
1014 return BLUETOOTH_ERROR_NONE;
1017 static gboolean __bt_disconnect_all(void)
1020 DBusGConnection *conn;
1021 DBusGProxy *dev_proxy;
1022 gboolean ret = FALSE;
1024 GArray *device_list;
1025 bluetooth_device_info_t info;
1027 char *device_path = NULL;
1028 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1033 conn = _bt_get_system_gconn();
1035 device_list = g_array_new(FALSE, FALSE, sizeof(gchar));
1037 if (_bt_get_bonded_devices(&device_list)
1038 != BLUETOOTH_ERROR_NONE) {
1039 g_array_free(device_list, TRUE);
1043 size = (device_list->len) / sizeof(bluetooth_device_info_t);
1045 for (i = 0; i < size; i++) {
1047 info = g_array_index(device_list,
1048 bluetooth_device_info_t, i);
1050 if (info.connected == TRUE) {
1051 BT_DBG("Found Connected device");
1052 _bt_convert_addr_type_to_string(address, info.device_address.addr);
1053 device_path = _bt_get_device_object_path(address);
1054 if (device_path == NULL)
1057 BT_DBG("Disconnecting : %s", device_path);
1059 dev_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1060 device_path, BT_DEVICE_INTERFACE);
1061 if (dev_proxy == NULL)
1064 if(!dbus_g_proxy_call(dev_proxy, "Disconnect",
1065 NULL, G_TYPE_INVALID, G_TYPE_INVALID)) {
1066 BT_ERR("Disconnect fail error.");
1067 g_object_unref(dev_proxy);
1073 g_array_free(device_list, TRUE);
1078 static gboolean __bt_set_disabled_timeout_cb(gpointer user_data)
1081 _bt_set_disabled(BLUETOOTH_ERROR_NONE);
1086 int __bt_disable_cb(void)
1090 bt_le_status_t le_status;
1093 _bt_adapter_set_status(BT_DEACTIVATING);
1094 le_status = _bt_adapter_get_le_status();
1095 BT_DBG("le_status : %d", le_status);
1096 if (le_status == BT_LE_ACTIVATED) {
1097 BT_INFO("LE is enabled. Just turn off PSCAN");
1099 if (_bt_is_discovering())
1100 _bt_cancel_discovery();
1102 if (_bt_is_connectable() == FALSE) {
1103 g_timeout_add(100, (GSourceFunc)__bt_set_disabled_timeout_cb, NULL);
1105 ret = _bt_set_connectable(FALSE);
1106 if (ret != BLUETOOTH_ERROR_NONE) {
1107 BT_ERR("_bt_set_connectable fail!");
1108 _bt_adapter_set_status(BT_ACTIVATED);
1109 return BLUETOOTH_ERROR_INTERNAL;
1114 proxy = __bt_get_core_proxy();
1115 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1117 if (dbus_g_proxy_call(proxy, "DisableAdapter", NULL,
1118 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1119 BT_ERR("Bt core call failed");
1120 _bt_adapter_set_status(BT_ACTIVATED);
1121 return BLUETOOTH_ERROR_INTERNAL;
1124 return BLUETOOTH_ERROR_NONE;
1127 int _bt_disable_adapter(void)
1132 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1133 BT_DBG("Disabling in progress");
1134 return BLUETOOTH_ERROR_IN_PROGRESS;
1137 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1138 BT_DBG("Already disabled");
1139 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1143 g_source_remove(timer_id);
1147 __bt_disconnect_all();
1148 ret = __bt_disable_cb();
1154 int _bt_recover_adapter(void)
1159 if (_bt_adapter_get_status() == BT_DEACTIVATING) {
1160 BT_DBG("Disabling in progress");
1161 return BLUETOOTH_ERROR_IN_PROGRESS;
1164 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1165 BT_DBG("Already disabled");
1166 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1169 _bt_adapter_set_status(BT_DEACTIVATING);
1171 proxy = __bt_get_core_proxy();
1172 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1174 if (dbus_g_proxy_call(proxy, "RecoverAdapter", NULL,
1175 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1176 BT_ERR("Bt core call failed");
1177 return BLUETOOTH_ERROR_INTERNAL;
1180 __bt_disconnect_all();
1183 return BLUETOOTH_ERROR_NONE;
1186 int _bt_reset_adapter(void)
1192 proxy = __bt_get_core_proxy();
1194 return BLUETOOTH_ERROR_INTERNAL;
1196 if (dbus_g_proxy_call(proxy, "ResetAdapter", NULL,
1197 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1198 BT_ERR("Bt core call failed");
1199 return BLUETOOTH_ERROR_INTERNAL;
1202 /* Terminate myself */
1203 if (_bt_adapter_get_status() == BT_DEACTIVATED) {
1204 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1207 return BLUETOOTH_ERROR_NONE;
1210 int _bt_check_adapter(int *status)
1213 char *adapter_path = NULL;
1215 BT_CHECK_PARAMETER(status, return);
1217 *status = BT_ADAPTER_DISABLED;
1219 adapter_path = _bt_get_adapter_path();
1222 if (adapter_path != NULL)
1223 *status = BT_ADAPTER_ENABLED;
1225 g_free(adapter_path);
1226 return BLUETOOTH_ERROR_NONE;
1229 int _bt_enable_adapter_le(void)
1234 bt_status_t status = _bt_adapter_get_status();
1235 bt_le_status_t le_status = _bt_adapter_get_le_status();
1237 if (le_status == BT_LE_ACTIVATING) {
1238 BT_ERR("Enabling in progress");
1239 return BLUETOOTH_ERROR_IN_PROGRESS;
1242 if (le_status == BT_LE_ACTIVATED) {
1243 BT_ERR("Already enabled");
1244 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
1247 if (status == BT_DEACTIVATING || le_status == BT_LE_DEACTIVATING) {
1248 BT_ERR("Disabling in progress");
1249 return BLUETOOTH_ERROR_DEVICE_BUSY;
1252 _bt_adapter_set_le_status(BT_LE_ACTIVATING);
1254 proxy = __bt_get_core_proxy();
1255 retv_if(!proxy, BLUETOOTH_ERROR_INTERNAL);
1257 if (dbus_g_proxy_call_with_timeout(proxy, "EnableAdapterLe",
1258 BT_ENABLE_TIMEOUT, &err,
1260 G_TYPE_INVALID) == FALSE) {
1262 _bt_adapter_set_le_status(BT_DEACTIVATED);
1265 BT_ERR("Bt core call failed: [%s]", err->message);
1269 /* Clean up the process */
1270 if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
1271 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1272 BT_ERR("Bt core call failed");
1275 /* Display notification */
1276 notification_status_message_post(BT_STR_NOT_SUPPORT);
1278 /* Terminate myself */
1279 if (_bt_adapter_get_status() == BT_DEACTIVATED)
1280 g_idle_add((GSourceFunc)_bt_terminate_service, NULL);
1281 return BLUETOOTH_ERROR_INTERNAL;
1284 _bt_adapter_start_le_enable_timer();
1286 if (status == BT_ACTIVATED) {
1287 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1288 __bt_set_le_enabled();
1290 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1292 return BLUETOOTH_ERROR_NONE;
1295 int _bt_disable_adapter_le(void)
1299 bt_le_status_t bt_le_state;
1301 bt_le_state = _bt_adapter_get_le_status();
1302 if (bt_le_state == BT_LE_DEACTIVATING) {
1303 BT_DBG("Disabling in progress");
1304 return BLUETOOTH_ERROR_IN_PROGRESS;
1307 if (bt_le_state == BT_LE_DEACTIVATED) {
1308 BT_DBG("Already disabled");
1309 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
1312 _bt_adapter_set_le_status(BT_LE_DEACTIVATING);
1314 proxy = __bt_get_core_proxy();
1316 return BLUETOOTH_ERROR_INTERNAL;
1318 if (dbus_g_proxy_call(proxy, "DisableAdapterLe", NULL,
1319 G_TYPE_INVALID, G_TYPE_INVALID) == FALSE) {
1320 BT_ERR("Bt core call failed");
1321 _bt_adapter_set_le_status(BT_LE_ACTIVATED);
1322 return BLUETOOTH_ERROR_INTERNAL;
1325 _bt_set_le_disabled(BLUETOOTH_ERROR_NONE);
1326 BT_DBG("le status : %d", _bt_adapter_get_le_status());
1328 return BLUETOOTH_ERROR_NONE;
1331 int _bt_get_local_address(bluetooth_device_address_t *local_address)
1337 GValue address_v = { 0 };
1339 BT_CHECK_PARAMETER(local_address, return);
1341 proxy = _bt_get_adapter_properties_proxy();
1342 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1344 if (!dbus_g_proxy_call(proxy, "Get", &err,
1345 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1346 G_TYPE_STRING, "Address",
1348 G_TYPE_VALUE, &address_v,
1351 BT_ERR("Getting property failed: [%s]\n", err->message);
1354 return BLUETOOTH_ERROR_INTERNAL;
1357 address = (char *)g_value_get_string(&address_v);
1360 _bt_convert_addr_string_to_type(local_address->addr, address);
1362 return BLUETOOTH_ERROR_INTERNAL;
1365 return BLUETOOTH_ERROR_NONE;
1368 int _bt_get_local_version(bluetooth_version_t *local_version)
1371 GHashTable *hash = NULL;
1374 int ret = BLUETOOTH_ERROR_NONE;
1376 BT_CHECK_PARAMETER(local_version, return);
1379 GValue version_v = { 0 };
1381 proxy = _bt_get_adapter_properties_proxy();
1382 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1384 if (!dbus_g_proxy_call(proxy, "Get", &err,
1385 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1386 G_TYPE_STRING, "Version",
1388 G_TYPE_VALUE, &version_v,
1391 BT_ERR("Getting property failed: [%s]\n", err->message);
1394 return BLUETOOTH_ERROR_INTERNAL;
1397 ver = (char *)g_value_get_string(&version_v);
1400 if (ver && (strlen(ver) > 0)) {
1401 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1402 if (!g_utf8_validate(ver, -1, (const char **)&ptr))
1405 g_strlcpy(local_version->version, ver,
1406 BLUETOOTH_VERSION_LENGTH_MAX + 1);
1409 ret = BLUETOOTH_ERROR_INTERNAL;
1412 g_hash_table_destroy(hash);
1416 int _bt_get_local_name(bluetooth_device_name_t *local_name)
1419 GHashTable *hash = NULL;
1422 int ret = BLUETOOTH_ERROR_NONE;
1425 GValue name_v = { 0 };
1427 BT_CHECK_PARAMETER(local_name, return);
1429 proxy = _bt_get_adapter_properties_proxy();
1430 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1432 if (!dbus_g_proxy_call(proxy, "Get", &err,
1433 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1434 G_TYPE_STRING, "Alias",
1436 G_TYPE_VALUE, &name_v,
1439 BT_ERR("Getting property failed: [%s]\n", err->message);
1442 return BLUETOOTH_ERROR_INTERNAL;
1445 name = (char *)g_value_get_string(&name_v);
1447 if (name && (strlen(name) > 0)) {
1448 /* Check the utf8 valitation & Fill the NULL in the invalid location*/
1449 if (!g_utf8_validate(name, -1, (const char **)&ptr))
1452 g_strlcpy(local_name->name, name,
1453 BLUETOOTH_DEVICE_NAME_LENGTH_MAX + 1);
1455 ret = BLUETOOTH_ERROR_INTERNAL;
1458 g_hash_table_destroy(hash);
1462 int _bt_set_local_name(char *local_name)
1464 GValue name = { 0 };
1466 GError *error = NULL;
1469 BT_CHECK_PARAMETER(local_name, return);
1471 proxy = _bt_get_adapter_properties_proxy();
1473 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1475 if (!g_utf8_validate(local_name, -1, (const char **)&ptr))
1478 g_value_init(&name, G_TYPE_STRING);
1479 g_value_set_string(&name, local_name);
1481 dbus_g_proxy_call(proxy, "Set", &error,
1482 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1483 G_TYPE_STRING, "Alias",
1484 G_TYPE_VALUE, &name,
1485 G_TYPE_INVALID, G_TYPE_INVALID);
1487 g_value_unset(&name);
1490 BT_ERR("SetProperty Fail: %s", error->message);
1491 g_error_free(error);
1492 return BLUETOOTH_ERROR_INTERNAL;
1495 return BLUETOOTH_ERROR_NONE;
1498 int _bt_is_service_used(char *service_uuid, gboolean *used)
1504 GValue uuids_v = { 0 };
1505 int ret = BLUETOOTH_ERROR_NONE;
1508 BT_CHECK_PARAMETER(service_uuid, return);
1509 BT_CHECK_PARAMETER(used, return);
1511 proxy = _bt_get_adapter_properties_proxy();
1512 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1514 if (!dbus_g_proxy_call(proxy, "Get", &err,
1515 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1516 G_TYPE_STRING, "UUIDs",
1518 G_TYPE_VALUE, &uuids_v,
1521 BT_ERR("Getting property failed: [%s]\n", err->message);
1524 return BLUETOOTH_ERROR_INTERNAL;
1527 uuids = g_value_get_boxed(&uuids_v);
1529 if (uuids == NULL) {
1535 for (i = 0; uuids[i] != NULL; i++) {
1536 if (strcasecmp(uuids[i], service_uuid) == 0) {
1544 BT_DBG("Service Used? %d", *used);
1549 static gboolean __bt_get_discoverable_property(void)
1552 GValue discoverable_v = { 0 };
1555 proxy = _bt_get_adapter_properties_proxy();
1556 retv_if(proxy == NULL, FALSE);
1558 if (!dbus_g_proxy_call(proxy, "Get", &err,
1559 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1560 G_TYPE_STRING, "Discoverable",
1562 G_TYPE_VALUE, &discoverable_v,
1565 BT_ERR("Getting property failed: [%s]\n", err->message);
1571 return g_value_get_boolean(&discoverable_v);
1574 int _bt_get_discoverable_mode(int *mode)
1576 gboolean discoverable;
1577 unsigned int timeout;
1579 BT_CHECK_PARAMETER(mode, return);
1581 discoverable = __bt_get_discoverable_property();
1582 timeout = _bt_get_discoverable_timeout_property();
1584 if (discoverable == TRUE) {
1586 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
1588 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
1590 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
1592 return BLUETOOTH_ERROR_NONE;
1596 int _bt_set_discoverable_mode(int discoverable_mode, int timeout)
1598 int ret = BLUETOOTH_ERROR_NONE;
1601 GError *error = NULL;
1602 GValue connectable = { 0 };
1603 GValue discoverable = { 0 };
1604 GValue val_timeout = { 0 };
1607 proxy = _bt_get_adapter_properties_proxy();
1609 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1611 g_value_init(&connectable, G_TYPE_BOOLEAN);
1612 g_value_init(&discoverable, G_TYPE_BOOLEAN);
1613 g_value_init(&val_timeout, G_TYPE_UINT);
1615 switch (discoverable_mode) {
1616 case BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE:
1621 case BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE:
1626 case BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE:
1631 return BLUETOOTH_ERROR_INVALID_PARAM;
1634 BT_INFO("Req. discoverable_mode : %d, timeout : %d",
1635 discoverable_mode, timeout);
1637 g_value_set_boolean(&connectable, pg_scan);
1638 g_value_set_boolean(&discoverable, inq_scan);
1639 g_value_set_uint(&val_timeout, timeout);
1641 dbus_g_proxy_call(proxy, "Set", &error,
1642 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1643 G_TYPE_STRING, "Connectable",
1644 G_TYPE_VALUE, &connectable,
1645 G_TYPE_INVALID, G_TYPE_INVALID);
1647 if (error != NULL) {
1648 BT_ERR("Connectable set err:[%s]", error->message);
1649 g_error_free(error);
1650 ret = BLUETOOTH_ERROR_INTERNAL;
1654 dbus_g_proxy_call(proxy, "Set", &error,
1655 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1656 G_TYPE_STRING, "Discoverable",
1657 G_TYPE_VALUE, &discoverable,
1658 G_TYPE_INVALID, G_TYPE_INVALID);
1661 if (error != NULL) {
1662 BT_ERR("Discoverable set err:[%s]", error->message);
1663 g_error_free(error);
1664 ret = BLUETOOTH_ERROR_INTERNAL;
1668 dbus_g_proxy_call(proxy, "Set", &error,
1669 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1670 G_TYPE_STRING, "DiscoverableTimeout",
1671 G_TYPE_VALUE, &val_timeout,
1672 G_TYPE_INVALID, G_TYPE_INVALID);
1674 if (error != NULL) {
1675 BT_ERR("Timeout set err:[%s]", error->message);
1676 g_error_free(error);
1677 ret = BLUETOOTH_ERROR_INTERNAL;
1681 if (discoverable_mode == BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE)
1684 ret = __bt_set_visible_time(timeout);
1687 g_value_unset(&val_timeout);
1688 g_value_unset(&connectable);
1689 g_value_unset(&discoverable);
1694 int _bt_start_discovery(void)
1699 if (_bt_is_discovering() == TRUE) {
1700 BT_ERR("BT is already in discovering");
1701 return BLUETOOTH_ERROR_IN_PROGRESS;
1702 } else if (_bt_is_device_creating() == TRUE) {
1703 BT_ERR("Bonding device is going on");
1704 return BLUETOOTH_ERROR_DEVICE_BUSY;
1707 proxy = _bt_get_adapter_proxy();
1708 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1710 if (!dbus_g_proxy_call(proxy, "StartDiscovery", &err,
1711 G_TYPE_INVALID, G_TYPE_INVALID)) {
1713 BT_ERR("StartDiscovery failed: [%s]\n", err->message);
1716 BT_ERR("Discover start failed");
1717 return BLUETOOTH_ERROR_INTERNAL;
1720 is_discovering = TRUE;
1721 cancel_by_user = FALSE;
1722 /* discovery status will be change in event */
1724 return BLUETOOTH_ERROR_NONE;
1727 int _bt_start_custom_discovery(bt_discovery_role_type_t role)
1731 const gchar *disc_type;
1733 if (_bt_is_discovering() == TRUE) {
1734 BT_ERR("BT is already in discovering");
1735 return BLUETOOTH_ERROR_IN_PROGRESS;
1738 proxy = _bt_get_adapter_proxy();
1739 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1741 if (role == DISCOVERY_ROLE_BREDR)
1742 disc_type = "BREDR";
1743 else if (role == DISCOVERY_ROLE_LE)
1745 else if (role == DISCOVERY_ROLE_LE_BREDR)
1746 disc_type = "LE_BREDR";
1748 return BLUETOOTH_ERROR_INVALID_PARAM;
1750 if (!dbus_g_proxy_call(proxy, "StartCustomDiscovery", NULL,
1751 G_TYPE_STRING, disc_type,
1752 G_TYPE_INVALID, G_TYPE_INVALID)) {
1753 BT_ERR("StartCustomDiscovery failed");
1754 return BLUETOOTH_ERROR_INTERNAL;
1757 is_discovering = TRUE;
1758 cancel_by_user = FALSE;
1759 /* discovery status will be change in event */
1761 return BLUETOOTH_ERROR_NONE;
1764 int _bt_cancel_discovery(void)
1769 if (_bt_is_discovering() == FALSE) {
1770 BT_ERR("BT is not in discovering");
1771 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1774 proxy = _bt_get_adapter_proxy();
1775 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1777 if (!dbus_g_proxy_call(proxy, "StopDiscovery", &err,
1778 G_TYPE_INVALID, G_TYPE_INVALID)) {
1780 BT_ERR("StopDiscovery failed: [%s]\n", err->message);
1783 return BLUETOOTH_ERROR_INTERNAL;
1786 cancel_by_user = TRUE;
1787 /* discovery status will be change in event */
1789 return BLUETOOTH_ERROR_NONE;
1792 int _bt_start_le_discovery(void)
1796 if (_bt_is_le_discovering() == TRUE) {
1797 BT_ERR("BT is already in LE discovering");
1798 return BLUETOOTH_ERROR_IN_PROGRESS;
1801 proxy = _bt_get_adapter_proxy();
1802 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1804 if (!dbus_g_proxy_call(proxy, "StartLEDiscovery", NULL,
1805 G_TYPE_INVALID, G_TYPE_INVALID)) {
1806 BT_ERR("LE Discover start failed");
1807 return BLUETOOTH_ERROR_INTERNAL;
1810 is_le_discovering = TRUE;
1812 return BLUETOOTH_ERROR_NONE;
1815 int _bt_stop_le_discovery(void)
1819 if (_bt_is_le_discovering() == FALSE) {
1820 BT_ERR("BT is not in LE discovering");
1821 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1824 proxy = _bt_get_adapter_proxy();
1825 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1827 if (!dbus_g_proxy_call(proxy, "StopLEDiscovery", NULL,
1828 G_TYPE_INVALID, G_TYPE_INVALID)) {
1829 BT_ERR("LE Discover stop failed");
1830 return BLUETOOTH_ERROR_INTERNAL;
1833 return BLUETOOTH_ERROR_NONE;
1836 gboolean _bt_is_discovering(void)
1838 return is_discovering;
1841 gboolean _bt_is_le_discovering(void)
1843 return is_le_discovering;
1846 gboolean _bt_is_connectable(void)
1849 GValue connectable_v = { 0 };
1851 gboolean is_connectable = FALSE;
1853 proxy = _bt_get_adapter_properties_proxy();
1854 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1856 if (!dbus_g_proxy_call(proxy, "Get", &err,
1857 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1858 G_TYPE_STRING, "Connectable",
1860 G_TYPE_VALUE, &connectable_v,
1863 BT_ERR("Getting property failed: [%s]\n", err->message);
1866 return BLUETOOTH_ERROR_INTERNAL;
1869 is_connectable = g_value_get_boolean(&connectable_v);
1870 BT_INFO("Get connectable [%d]", is_connectable);
1872 return is_connectable;
1875 int _bt_set_connectable(gboolean is_connectable)
1878 GValue connectable = { 0 };
1879 GError *error = NULL;
1881 if (__bt_is_factory_test_mode()) {
1882 BT_ERR("Unable to set connectable in factory binary !!");
1883 return BLUETOOTH_ERROR_NOT_SUPPORT;
1886 proxy = _bt_get_adapter_properties_proxy();
1888 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1890 g_value_init(&connectable, G_TYPE_BOOLEAN);
1891 g_value_set_boolean(&connectable, is_connectable);
1893 dbus_g_proxy_call(proxy, "Set", &error,
1894 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1895 G_TYPE_STRING, "Connectable",
1896 G_TYPE_VALUE, &connectable,
1897 G_TYPE_INVALID, G_TYPE_INVALID);
1899 g_value_unset(&connectable);
1900 if (error != NULL) {
1901 BT_ERR("Connectable set err:[%s]", error->message);
1902 g_error_free(error);
1903 return BLUETOOTH_ERROR_INTERNAL;
1906 BT_INFO("Set connectable [%d]", is_connectable);
1907 return BLUETOOTH_ERROR_NONE;
1910 gboolean _bt_get_discovering_property(bt_discovery_role_type_t discovery_type)
1914 GValue discovering_v = { 0 };
1916 char *discovering_type = NULL;
1918 proxy = _bt_get_adapter_properties_proxy();
1919 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1921 if (discovery_type == DISCOVERY_ROLE_BREDR)
1922 discovering_type = "Discovering";
1923 else if (discovery_type == DISCOVERY_ROLE_LE)
1924 discovering_type = "LEDiscovering";
1926 if (!dbus_g_proxy_call(proxy, "Get", &err,
1927 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1928 G_TYPE_STRING, discovering_type,
1930 G_TYPE_VALUE, &discovering_v,
1933 BT_ERR("Getting property failed: [%s]\n", err->message);
1936 return BLUETOOTH_ERROR_INTERNAL;
1939 return g_value_get_boolean(&discovering_v);
1943 unsigned int _bt_get_discoverable_timeout_property(void)
1946 GValue timeout_v = { 0 };
1949 proxy = _bt_get_adapter_properties_proxy();
1950 retv_if(proxy == NULL, 0);
1952 if (!dbus_g_proxy_call(proxy, "Get", &err,
1953 G_TYPE_STRING, BT_ADAPTER_INTERFACE,
1954 G_TYPE_STRING, "DiscoverableTimeout",
1956 G_TYPE_VALUE, &timeout_v,
1959 BT_ERR("Getting property failed: [%s]\n", err->message);
1965 return g_value_get_uint(&timeout_v);
1968 static bluetooth_device_info_t *__bt_parse_device_info(DBusMessageIter *item_iter)
1970 DBusMessageIter value_iter;
1971 bluetooth_device_info_t *dev_info;
1973 dbus_message_iter_recurse(item_iter, &value_iter);
1975 if (dbus_message_iter_get_arg_type(&value_iter) != DBUS_TYPE_DICT_ENTRY) {
1980 dev_info = g_malloc0(sizeof(bluetooth_device_info_t));
1982 while (dbus_message_iter_get_arg_type(&value_iter) ==
1983 DBUS_TYPE_DICT_ENTRY) {
1986 DBusMessageIter dict_entry;
1987 DBusMessageIter iter_dict_val;
1989 dbus_message_iter_recurse(&value_iter, &dict_entry);
1991 dbus_message_iter_get_basic(&dict_entry, &key);
1994 dbus_message_iter_next(&value_iter);
1998 if (!dbus_message_iter_next(&dict_entry)) {
1999 dbus_message_iter_next(&value_iter);
2002 dbus_message_iter_recurse(&dict_entry, &iter_dict_val);
2004 if (strcasecmp(key, "Address") == 0) {
2005 const char *address = NULL;
2006 dbus_message_iter_get_basic(&iter_dict_val, &address);
2007 _bt_convert_addr_string_to_type(dev_info->device_address.addr,
2010 } else if (strcasecmp(key, "Class") == 0) {
2012 dbus_message_iter_get_basic(&iter_dict_val, &cod);
2013 _bt_divide_device_class(&dev_info->device_class, cod);
2014 } else if (strcasecmp(key, "Name") == 0) {
2015 dbus_message_iter_get_basic(&iter_dict_val, &value);
2017 /* If there is no Alias */
2018 if (strlen(dev_info->device_name.name) == 0) {
2019 g_strlcpy(dev_info->device_name.name, value,
2020 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2022 } else if (strcasecmp(key, "Alias") == 0) {
2023 dbus_message_iter_get_basic(&iter_dict_val, &value);
2025 /* Overwrite the name */
2027 memset(dev_info->device_name.name, 0x00,
2028 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2029 g_strlcpy(dev_info->device_name.name, value,
2030 BLUETOOTH_DEVICE_NAME_LENGTH_MAX+1);
2032 } else if (strcasecmp(key, "Connected") == 0) {
2033 dbus_message_iter_get_basic(&iter_dict_val,
2034 &dev_info->connected);
2035 } else if (strcasecmp(key, "Paired") == 0) {
2036 dbus_message_iter_get_basic(&iter_dict_val,
2038 } else if (strcasecmp(key, "Trusted") == 0) {
2039 dbus_message_iter_get_basic(&iter_dict_val,
2041 } else if (strcasecmp(key, "RSSI") == 0) {
2042 dbus_message_iter_get_basic(&iter_dict_val,
2044 } else if (strcasecmp(key, "UUIDs") == 0) {
2045 DBusMessageIter uuid_iter;
2049 dbus_message_iter_recurse(&iter_dict_val, &uuid_iter);
2051 while (dbus_message_iter_get_arg_type(&uuid_iter) != DBUS_TYPE_INVALID) {
2052 dbus_message_iter_get_basic(&uuid_iter,
2055 g_strlcpy(dev_info->uuids[i], value,
2056 BLUETOOTH_UUID_STRING_MAX);
2058 parts = g_strsplit(value, "-", -1);
2060 if (parts == NULL || parts[0] == NULL)
2063 dev_info->service_list_array[i] = g_ascii_strtoull(parts[0], NULL, 16);
2067 if (!dbus_message_iter_next(&uuid_iter)) {
2072 dev_info->service_index = i;
2073 } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
2074 dbus_message_iter_get_basic(&iter_dict_val,
2075 &dev_info->manufacturer_data.data_len);
2076 } else if (strcasecmp(key, "ManufacturerData") == 0) {
2077 DBusMessageIter manufacturer_iter;
2081 dbus_message_iter_recurse(&iter_dict_val, &manufacturer_iter);
2083 while (dbus_message_iter_get_arg_type(&manufacturer_iter) == DBUS_TYPE_BYTE) {
2084 dbus_message_iter_get_basic(&manufacturer_iter, &byte);
2085 dev_info->manufacturer_data.data[i] = byte;
2087 dbus_message_iter_next(&manufacturer_iter);
2091 dbus_message_iter_next(&value_iter);
2097 static void __bt_extract_device_info(DBusMessageIter *msg_iter,
2100 bluetooth_device_info_t *dev_info = NULL;
2101 char *object_path = NULL;
2102 DBusMessageIter value_iter;
2104 /* Parse the signature: oa{sa{sv}}} */
2105 ret_if(dbus_message_iter_get_arg_type(msg_iter) !=
2106 DBUS_TYPE_OBJECT_PATH);
2108 dbus_message_iter_get_basic(msg_iter, &object_path);
2109 ret_if(object_path == NULL);
2111 /* object array (oa) */
2112 ret_if(dbus_message_iter_next(msg_iter) == FALSE);
2113 ret_if(dbus_message_iter_get_arg_type(msg_iter) != DBUS_TYPE_ARRAY);
2115 dbus_message_iter_recurse(msg_iter, &value_iter);
2117 /* string array (sa) */
2118 while (dbus_message_iter_get_arg_type(&value_iter) ==
2119 DBUS_TYPE_DICT_ENTRY) {
2120 char *interface_name = NULL;
2121 DBusMessageIter interface_iter;
2123 dbus_message_iter_recurse(&value_iter, &interface_iter);
2125 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
2128 dbus_message_iter_get_basic(&interface_iter, &interface_name);
2130 ret_if(dbus_message_iter_next(&interface_iter) == FALSE);
2132 ret_if(dbus_message_iter_get_arg_type(&interface_iter) !=
2135 if (g_strcmp0(interface_name, "org.bluez.Device1") == 0) {
2136 BT_DBG("Found a device: %s", object_path);
2137 dev_info = __bt_parse_device_info(&interface_iter);
2140 if (dev_info->paired == FALSE)
2143 g_array_append_vals(*dev_list, dev_info,
2144 sizeof(bluetooth_device_info_t));
2152 dbus_message_iter_next(&value_iter);
2155 BT_DBG("There is no device interface");
2158 BT_DBG("Not paired");
2162 int _bt_get_bonded_devices(GArray **dev_list)
2167 DBusMessageIter reply_iter;
2168 DBusMessageIter value_iter;
2170 DBusConnection *conn;
2172 conn = _bt_get_system_conn();
2173 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
2175 msg = dbus_message_new_method_call(BT_BLUEZ_NAME, BT_MANAGER_PATH,
2176 BT_MANAGER_INTERFACE,
2177 "GetManagedObjects");
2179 retv_if(msg == NULL, BLUETOOTH_ERROR_INTERNAL);
2181 /* Synchronous call */
2182 dbus_error_init(&err);
2183 reply = dbus_connection_send_with_reply_and_block(
2186 dbus_message_unref(msg);
2189 BT_ERR("Can't get managed objects");
2191 if (dbus_error_is_set(&err)) {
2192 BT_ERR("%s", err.message);
2193 dbus_error_free(&err);
2195 return BLUETOOTH_ERROR_INTERNAL;
2198 if (dbus_message_iter_init(reply, &reply_iter) == FALSE) {
2199 BT_ERR("Fail to iterate the reply");
2200 dbus_message_unref(reply);
2201 return BLUETOOTH_ERROR_INTERNAL;
2204 dbus_message_iter_recurse(&reply_iter, &value_iter);
2206 /* signature of GetManagedObjects: a{oa{sa{sv}}} */
2207 while (dbus_message_iter_get_arg_type(&value_iter) ==
2208 DBUS_TYPE_DICT_ENTRY) {
2209 DBusMessageIter msg_iter;
2211 dbus_message_iter_recurse(&value_iter, &msg_iter);
2213 __bt_extract_device_info(&msg_iter, dev_list);
2215 dbus_message_iter_next(&value_iter);
2217 dbus_message_unref(reply);
2219 return BLUETOOTH_ERROR_NONE;
2222 int _bt_get_bonded_device_info(bluetooth_device_address_t *device_address,
2223 bluetooth_device_info_t *dev_info)
2225 char *object_path = NULL;
2226 DBusGProxy *adapter_proxy;
2227 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
2228 int ret = BLUETOOTH_ERROR_NONE;
2230 BT_CHECK_PARAMETER(device_address, return);
2231 BT_CHECK_PARAMETER(dev_info, return);
2233 adapter_proxy = _bt_get_adapter_proxy();
2234 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2236 _bt_convert_addr_type_to_string(address, device_address->addr);
2238 object_path = _bt_get_device_object_path(address);
2240 retv_if(object_path == NULL, BLUETOOTH_ERROR_NOT_PAIRED);
2242 ret = __bt_get_bonded_device_info(object_path, dev_info);
2243 g_free(object_path);
2248 int _bt_get_timeout_value(int *timeout)
2250 time_t current_time;
2253 /* Take current time */
2254 time(¤t_time);
2255 time_diff = difftime(current_time, visible_timer.start_time);
2257 BT_DBG("Time diff = %d\n", time_diff);
2259 *timeout = visible_timer.timeout - time_diff;
2261 return BLUETOOTH_ERROR_NONE;
2264 int _bt_set_le_privacy(gboolean set_privacy)
2267 GError *error = NULL;
2268 int ret = BLUETOOTH_ERROR_NONE;
2270 if (__bt_is_factory_test_mode()) {
2271 BT_ERR("Unable to set le privacy in factory binary !!");
2272 return BLUETOOTH_ERROR_NOT_SUPPORT;
2275 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2276 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2277 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2280 proxy = _bt_get_adapter_proxy();
2281 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2283 dbus_g_proxy_call(proxy, "SetLePrivacy", &error,
2284 G_TYPE_BOOLEAN, set_privacy,
2285 G_TYPE_INVALID, G_TYPE_INVALID);
2288 BT_ERR("SetLePrivacy Failed :[%s]", error->message);
2289 if (g_strrstr(error->message, BT_SERVICE_ERR_MSG_NOT_SUPPORTED))
2290 ret = BLUETOOTH_ERROR_NOT_SUPPORT;
2292 ret = BLUETOOTH_ERROR_INTERNAL;
2293 g_error_free(error);
2297 BT_INFO("SetLePrivacy as %d", set_privacy);
2299 return BLUETOOTH_ERROR_NONE;
2302 int _bt_set_manufacturer_data(bluetooth_manufacturer_data_t *m_data)
2305 GError *error = NULL;
2309 BT_CHECK_PARAMETER(m_data, return);
2311 if (_bt_adapter_get_status() != BT_ACTIVATED &&
2312 _bt_adapter_get_le_status() != BT_LE_ACTIVATED) {
2313 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
2316 proxy = _bt_get_adapter_proxy();
2317 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
2319 arr = g_array_new(TRUE, TRUE, sizeof(guint8));
2321 for (i = 0; i < (m_data->data_len) + 2; i++)
2322 g_array_append_vals(arr, &(m_data->data[i]), sizeof(guint8));
2324 dbus_g_proxy_call(proxy, "SetManufacturerData", &error,
2325 DBUS_TYPE_G_UCHAR_ARRAY, arr,
2326 G_TYPE_INVALID, G_TYPE_INVALID);
2328 g_array_free(arr, TRUE);
2331 BT_ERR("SetManufacturerData Fail: %s", error->message);
2332 g_error_free(error);
2333 return BLUETOOTH_ERROR_INTERNAL;
2336 _bt_send_event(BT_ADAPTER_EVENT,
2337 BLUETOOTH_EVENT_MANUFACTURER_DATA_CHANGED,
2338 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
2339 &m_data, m_data->data_len,
2342 BT_INFO("Set manufacturer data");
2344 return BLUETOOTH_ERROR_NONE;