4 * Copyright (c) 2013-2014 Intel Corporation.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <dbus/dbus.h>
24 #include <gio/gunixfdlist.h>
28 #include "bluetooth-service.h"
30 #include "bluetooth.h"
32 #define ERROR_INTERFACE "org.tizen.comms.Error"
33 #define SPP_PROFILE_PATH "/bluetooth/profile/spp"
35 #define DEVICE_SERVICE_CLASS_DISCOVERABLE_MODE 0x002000
37 #define BT_STOP_DISCOVERY_TIMEOUT (1000*15)
39 #define BT_SPP_BUFFER_MAX 1024
40 #define BLUETOOTH_IDENT_LEN 6
41 #define CONNMAN_DBUS_NAME "net.connman"
42 #define CONNMAN_BLUETOOTH_SERVICE_PREFIX "/net/connman/service/bluetooth_"
43 #define CONNMAN_BLUETOOTH_TECHNOLOGY_PATH "/net/connman/technology/bluetooth"
44 #define CONNMAN_BLUETOTOH_TECHNOLOGY_INTERFACE "net.connman.Technology"
46 #define BLUEZ_AGENT_SERVICE "org.bluezlib.agent"
47 #define AGENT_INTERFACE "org.bluez.Agent1"
48 #define AGENT_OBJECT_PATH "/org/bluezlib/agent"
50 static bool initialized;
51 static bool bt_service_init;
53 static guint bluetooth_agent_id;
54 static guint profile_id;
55 static GDBusConnection *conn;
57 static bluez_adapter_t *default_adapter;
59 static guint event_id;
61 static void profile_connect_callback(bluez_device_t *device,
62 enum device_profile_state state);
64 static void profile_disconnect_callback(bluez_device_t *device,
65 enum device_profile_state state);
67 static int request_name_on_dbus(const char *name);
68 static void release_name_on_dbus(const char *name);
70 struct device_connect_cb_node {
71 bt_device_gatt_state_changed_cb cb;
75 struct device_disconnect_cb_node {
76 bt_device_gatt_state_changed_cb cb;
80 struct device_created_cb_node {
81 bt_adapter_device_discovery_state_changed_cb cb;
85 struct adapter_discovering_cb_node {
86 bt_adapter_device_discovery_state_changed_cb cb;
90 struct adapter_visibility_duration_cb_node {
91 bt_adapter_visibility_duration_changed_cb cb;
95 struct adapter_visibility_mode_cb_node {
96 bt_adapter_visibility_mode_changed_cb cb;
100 struct device_destroy_unpaired_cb_node {
101 bt_adapter_device_discovery_state_changed_cb cb;
105 struct adapter_state_cb_node {
106 bt_adapter_state_changed_cb cb;
110 struct device_bond_cb_node {
111 bt_device_bond_created_cb cb;
115 struct device_destroy_paired_cb_node {
116 bt_device_bond_destroyed_cb cb;
120 struct device_auth_cb_node {
121 bt_device_authorization_changed_cb cb;
125 struct adapter_name_cb_node {
126 bt_adapter_name_changed_cb cb;
130 struct device_connected_state_cb_node {
131 bt_device_connection_state_changed_cb cb;
135 struct device_service_search_cb_node {
136 bt_device_service_searched_cb cb;
140 struct spp_connection_requested_cb_node {
141 bt_spp_connection_requested_cb cb;
145 struct spp_data_received_cb_node {
146 bt_spp_data_received_cb cb;
150 struct avrcp_repeat_mode_changed_node {
151 bt_avrcp_repeat_mode_changed_cb cb;
155 struct avrcp_set_shuffle_mode_changed_node {
156 bt_avrcp_shuffle_mode_changed_cb cb;
160 struct avrcp_target_connection_state_changed_node {
161 bt_avrcp_target_connection_state_changed_cb cb;
165 struct audio_connection_state_changed_cb_node {
166 bt_audio_connection_state_changed_cb cb;
170 struct panu_connection_state_changed_cb_node {
171 bt_panu_connection_state_changed_cb cb;
175 struct hdp_connection_changed_cb_node {
176 bt_hdp_connected_cb conn_cb;
177 bt_hdp_disconnected_cb disconn_cb;
181 struct hdp_set_data_received_cb_node {
182 bt_hdp_data_received_cb cb;
186 struct socket_connection_requested_cb_node {
187 bt_socket_connection_requested_cb cb;
191 struct socket_connection_state_changed_cb_node {
192 bt_socket_connection_state_changed_cb cb;
196 struct hid_host_connection_state_changed_cb_node {
197 bt_hid_host_connection_state_changed_cb cb;
201 struct nap_connection_state_changed_cb_node {
202 bt_nap_connection_state_changed_cb cb;
206 static struct device_connect_cb_node *device_connect_node;
207 static struct device_disconnect_cb_node *device_disconnect_node;
208 static struct avrcp_repeat_mode_changed_node *avrcp_repeat_node;
209 static struct avrcp_set_shuffle_mode_changed_node *avrcp_shuffle_node;
210 static struct adapter_name_cb_node *adapter_name_node;
211 static struct device_created_cb_node *device_created_node;
212 static struct adapter_state_cb_node *adapter_state_node;
213 static struct adapter_discovering_cb_node *adapter_discovering_node;
214 static struct adapter_visibility_duration_cb_node
215 *adapter_visibility_duration_node;
216 static struct adapter_visibility_mode_cb_node *adapter_visibility_mode_node;
217 static struct device_destroy_unpaired_cb_node *unpaired_device_removed_node;
218 static struct device_bond_cb_node *device_bond_node;
219 static struct device_auth_cb_node *device_auth_node;
220 static struct device_destroy_paired_cb_node *paired_device_removed_node;
221 static struct device_connected_state_cb_node *device_connected_state_node;
222 static struct device_service_search_cb_node *device_service_search_node;
223 static struct spp_connection_requested_cb_node *spp_connection_requested_node;
224 static struct spp_data_received_cb_node *spp_data_received_node;
225 static struct avrcp_target_connection_state_changed_node
226 *avrcp_target_state_node;
227 static struct audio_connection_state_changed_cb_node *audio_state_node;
228 static struct panu_connection_state_changed_cb_node *panu_state_node;
229 static struct hdp_connection_changed_cb_node *hdp_state_node;
230 static struct hdp_set_data_received_cb_node *hdp_set_data_received_node;
232 static struct socket_connection_requested_cb_node
233 *socket_connection_requested_node;
234 static struct socket_connection_state_changed_cb_node
235 *socket_connection_state_node;
236 static struct hid_host_connection_state_changed_cb_node *hid_host_state_node;
237 static struct nap_connection_state_changed_cb_node
238 *nap_connection_state_changed_node;
240 static gboolean generic_device_removed_set;
242 static void divide_device_class(bt_class_s *bt_class, unsigned int class)
244 bt_class->major_device_class =
245 (unsigned short)(class & 0x00001F00) >> 8;
246 bt_class->minor_device_class =
247 (unsigned short)((class & 0x000000FC));
248 bt_class->major_service_class_mask =
249 (unsigned long)((class & 0x00FF0000));
251 if (class & 0x002000) {
252 bt_class->major_service_class_mask |=
253 DEVICE_SERVICE_CLASS_DISCOVERABLE_MODE;
257 static bt_adapter_device_discovery_info_s *get_discovery_device_info(
258 bluez_device_t *device)
263 char *alias, *address;
266 bt_adapter_device_discovery_info_s *device_info;
271 device_info = g_new0(bt_adapter_device_discovery_info_s, 1);
272 if (device_info == NULL) {
277 address = bluez_device_get_property_address(device);
278 alias = bluez_device_get_property_alias(device);
279 uuids = bluez_device_get_property_uuids(device);
280 bluez_device_get_property_class(device, &class);
281 bluez_device_get_property_rssi(device, &rssi);
282 bluez_device_get_property_paired(device, &paired);
284 len = g_strv_length(uuids);
286 device_info->service_count = len;
287 device_info->remote_address = address;
288 device_info->remote_name = alias;
289 device_info->rssi = rssi;
290 device_info->is_bonded = paired;
291 device_info->service_uuid = uuids;
293 divide_device_class(&device_info->bt_class, class);
298 static void free_discovery_device_info(
299 bt_adapter_device_discovery_info_s *discovery_device_info)
303 if (discovery_device_info == NULL)
306 g_free(discovery_device_info->remote_address);
307 g_free(discovery_device_info->remote_name);
309 for (i = 0; i < discovery_device_info->service_count; ++i)
310 g_free(discovery_device_info->service_uuid[i]);
312 g_free(discovery_device_info->service_uuid);
313 g_free(discovery_device_info);
316 static bt_device_info_s *get_device_info(bluez_device_t *device)
319 int paired, connected, trusted;
320 char *alias, *address;
323 bt_device_info_s *device_info;
325 if (device == NULL) {
326 ERROR("device is NULL");
330 device_info = g_new0(bt_device_info_s, 1);
331 if (device_info == NULL) {
336 address = bluez_device_get_property_address(device);
337 alias = bluez_device_get_property_alias(device);
338 uuids = bluez_device_get_property_uuids(device);
339 bluez_device_get_property_class(device, &class);
340 bluez_device_get_property_paired(device, &paired);
341 bluez_device_get_property_connected(device, &connected);
342 bluez_device_get_property_trusted(device, &trusted);
344 len = g_strv_length(uuids);
346 device_info->service_count = len;
347 device_info->remote_address = address;
348 device_info->remote_name = alias;
349 device_info->is_bonded = paired;
350 device_info->is_connected = connected;
351 device_info->is_authorized = trusted;
352 device_info->service_uuid = uuids;
354 divide_device_class(&device_info->bt_class, class);
359 static void free_device_info(bt_device_info_s *device_info)
363 if (device_info == NULL)
366 g_free(device_info->remote_address);
367 g_free(device_info->remote_name);
368 for (i = 0; i < device_info->service_count; ++i)
369 g_free(device_info->service_uuid[i]);
371 g_free(device_info->service_uuid);
375 void adapter_powered_changed(bluez_adapter_t *adater,
379 struct adapter_state_cb_node *data =
380 (struct adapter_state_cb_node *)user_data;
382 DBG("Powered: %d", powered);
385 data->cb(BT_ERROR_NONE, BT_ADAPTER_ENABLED, data->user_data);
387 data->cb(BT_ERROR_NONE, BT_ADAPTER_DISABLED, data->user_data);
390 static void bluez_paired_device_removed(bluez_device_t *device,
396 struct device_destroy_paired_cb_node *data = user_data;
403 address = bluez_device_get_property_address(device);
404 bluez_device_get_property_paired(device, &paired);
406 device_addr = address;
408 /* CAPI function bt_device_bond_destroyed_cb
409 * parameter 2 is char *, not the const char *
410 * so device_addr should free by user
413 data->cb(BT_SUCCESS, device_addr, data->user_data);
416 static void bluez_unpaired_device_removed(bluez_device_t *device,
419 bt_adapter_device_discovery_info_s *discovery_device_info;
420 struct device_destroy_unpaired_cb_node *node = user_data;
425 discovery_device_info = get_discovery_device_info(device);
428 node->cb(BT_SUCCESS, BT_ADAPTER_DEVICE_DISCOVERY_REMOVED,
429 discovery_device_info, node->user_data);
431 free_discovery_device_info(discovery_device_info);
434 static void handle_generic_device_removed(bluez_device_t *device, void *user_data)
441 bluez_device_get_property_paired(device, &paired);
443 bluez_unpaired_device_removed(device, unpaired_device_removed_node);
445 bluez_paired_device_removed(device, paired_device_removed_node);
448 static void set_device_removed_generic_callback(bluez_adapter_t *adapter)
450 bluez_adapter_set_device_removed_cb(adapter,
451 handle_generic_device_removed, NULL);
453 generic_device_removed_set = TRUE;
456 static bt_avrcp_repeat_mode_e loopstatus_to_enum(const gchar *repeat)
458 DBG("repeat = %s", repeat);
460 if (g_strcmp0(repeat, "None") == 0)
461 return BT_AVRCP_REPEAT_MODE_OFF;
462 else if (g_strcmp0(repeat, "Track") == 0)
463 return BT_AVRCP_REPEAT_MODE_SINGLE_TRACK;
464 else if (g_strcmp0(repeat, "Playlist") == 0)
465 return BT_AVRCP_REPEAT_MODE_ALL_TRACK;
469 static void bluez_avrcp_repeat_changed(const gchar *repeat,
472 bt_avrcp_repeat_mode_e repeat_mode;
473 struct avrcp_repeat_mode_changed_node *data = user_data;
475 repeat_mode = loopstatus_to_enum(repeat);
478 data->cb(repeat_mode, data->user_data);
481 static bt_avrcp_repeat_mode_e shuffle_to_enum(gboolean shuffle)
484 DBG("shuffle is true");
485 return BT_AVRCP_SHUFFLE_MODE_ALL_TRACK;
487 DBG("shuffle is false");
488 return BT_AVRCP_SHUFFLE_MODE_OFF;
492 static void bluez_avrcp_shuffle_changed(gboolean shuffle,
495 bt_avrcp_shuffle_mode_e shuffle_mode;
496 struct avrcp_set_shuffle_mode_changed_node *data =
499 shuffle_mode = shuffle_to_enum(shuffle);
502 data->cb(shuffle_mode, data->user_data);
505 static void bluez_nap_connection_changed(bool connected,
506 const char *remote_address,
507 const char *interface_name,
510 struct nap_connection_state_changed_cb_node *data =
514 data->cb(connected, remote_address,
515 interface_name, data->user_data);
518 static void bluez_set_data_received_changed(
519 unsigned int channel,
524 struct hdp_set_data_received_cb_node *data_node =
528 data_node->cb(channel, data, size,
529 data_node->user_data);
533 static void bluez_hdp_state_changed(int result,
534 const char *remote_address,
536 bt_hdp_channel_type_e type,
537 unsigned int channel,
540 struct hdp_connection_changed_cb_node *data =
543 if (app_id != NULL) {
545 data->conn_cb(result, remote_address,
546 app_id, type, channel,
548 else if (data->disconn_cb)
549 data->disconn_cb(result, remote_address,
550 channel, data->user_data);
554 static void bluez_avrcp_target_state_changed(const char *remote_address,
558 struct avrcp_target_connection_state_changed_node *data =
564 (data->cb)(connected, remote_address,
568 static void bluez_audio_state_changed(int result,
570 const char *remote_address,
571 bt_audio_profile_type_e type,
574 struct audio_connection_state_changed_cb_node *data =
580 (data->cb)(result, connected, remote_address, type,
584 static void device_paired_changed(bluez_device_t *device,
588 bt_device_info_s *device_bond_info;
589 struct device_bond_cb_node *data = user_data;
593 device_bond_info = get_device_info(device);
595 data->cb(BT_SUCCESS, device_bond_info, data->user_data);
597 free_device_info(device_bond_info);
600 static void device_connected_changed(bluez_device_t *device,
601 int connected, void *user_data)
603 struct device_connected_state_cb_node *node = user_data;
604 char *device_address;
608 device_address = bluez_device_get_property_address(device);
610 node->cb(connected, device_address, node->user_data);
612 g_free(device_address);
615 static void device_auth_changed(bluez_device_t *device,
616 int trusted, void *user_data)
618 struct device_auth_cb_node *node = user_data;
619 bt_device_authorization_e authorization;
620 char *device_address;
624 authorization = trusted ? BT_DEVICE_UNAUTHORIZED:
625 BT_DEVICE_AUTHORIZED;
627 device_address = bluez_device_get_property_address(device);
629 node->cb(authorization, device_address, node->user_data);
631 g_free(device_address);
634 static void device_panu_connected_changed(bluez_device_t *device,
635 int connected, void *user_data)
637 struct panu_connection_state_changed_cb_node *node = user_data;
638 char *device_address;
642 device_address = bluez_device_get_property_address(device);
644 node->cb(BT_SUCCESS, connected, device_address,
645 BT_PANU_SERVICE_TYPE_NAP, node->user_data);
647 g_free(device_address);
650 static void device_hid_connected_changed(bluez_device_t *device,
651 int connected, void *user_data)
653 struct hid_host_connection_state_changed_cb_node *node = user_data;
654 char *device_address;
658 device_address = bluez_device_get_property_address(device);
660 node->cb(BT_SUCCESS, connected, device_address, node->user_data);
662 g_free(device_address);
665 static unsigned int dev_property_callback_flags;
667 enum bluez_device_property_callback_flag {
668 DEV_PROP_FLAG_PAIR = 0x01,
669 DEV_PROP_FLAG_CONNECT = 0x02,
670 DEV_PROP_FLAG_AUTH = 0x04,
671 DEV_PROP_FLAG_PANU_CONNECT = 0x08,
672 DEV_PROP_FLAG_HDP_CONNECT = 0x10,
673 DEV_PROP_FLAG_HDP_DATA = 0x20,
674 DEV_PROP_FLAG_HID_CONNECT = 0x40
677 static void set_device_property_changed_callback(bluez_device_t *device)
681 if (dev_property_callback_flags & DEV_PROP_FLAG_PAIR)
682 bluez_device_set_paired_changed_cb(device,
683 device_paired_changed,
686 if (dev_property_callback_flags & DEV_PROP_FLAG_CONNECT)
687 bluez_device_set_connected_changed_cb(device,
688 device_connected_changed,
689 device_connected_state_node);
691 if (dev_property_callback_flags & DEV_PROP_FLAG_AUTH)
692 bluez_device_set_trusted_changed_cb(device,
696 if (dev_property_callback_flags & DEV_PROP_FLAG_PANU_CONNECT)
697 bluez_device_network_set_connected_changed_cb(device,
698 device_panu_connected_changed,
701 if (dev_property_callback_flags & DEV_PROP_FLAG_HDP_CONNECT)
702 bluez_set_hdp_state_changed_cb(device,
703 bluez_hdp_state_changed,
706 if (dev_property_callback_flags & DEV_PROP_FLAG_HDP_DATA)
707 bluez_set_data_received_changed_cb(device,
708 bluez_set_data_received_changed,
709 hdp_set_data_received_node);
711 if (dev_property_callback_flags & DEV_PROP_FLAG_HID_CONNECT)
712 bluez_device_input_set_connected_changed_cb(device,
713 device_hid_connected_changed,
714 hid_host_state_node);
718 static void unset_device_property_changed_callback(bluez_device_t *device)
722 if (!(dev_property_callback_flags & DEV_PROP_FLAG_PAIR))
723 bluez_device_unset_paired_changed_cb(device);
725 if (!(dev_property_callback_flags & DEV_PROP_FLAG_CONNECT))
726 bluez_device_unset_connected_changed_cb(device);
728 if (!(dev_property_callback_flags & DEV_PROP_FLAG_AUTH))
729 bluez_device_unset_trusted_changed_cb(device);
731 if (!(dev_property_callback_flags & DEV_PROP_FLAG_PANU_CONNECT))
732 bluez_device_network_unset_connected_changed_cb(device);
734 if (!(dev_property_callback_flags & DEV_PROP_FLAG_HDP_CONNECT))
735 bluez_unset_hdp_state_changed_cb(device);
737 if (!(dev_property_callback_flags & DEV_PROP_FLAG_HDP_DATA))
738 bluez_unset_data_received_changed_cb(device);
740 if (!(dev_property_callback_flags & DEV_PROP_FLAG_HID_CONNECT))
741 bluez_device_input_unset_connected_changed_cb(device);
744 static void foreach_device_property_callback(GList *list, unsigned int flag)
746 bluez_device_t *device;
751 for (iter = g_list_first(list); iter; iter = next) {
752 next = g_list_next(iter);
756 if (dev_property_callback_flags & flag)
757 set_device_property_changed_callback(device);
759 unset_device_property_changed_callback(device);
763 static void bluez_device_created(bluez_device_t *device, void *user_data)
765 bt_adapter_device_discovery_info_s *discovery_device_info;
766 struct device_created_cb_node *node = user_data;
769 discovery_device_info = get_discovery_device_info(device);
771 DBG("name: %s, uuid: %p, uuid_count: %d", discovery_device_info->remote_name,
772 discovery_device_info->service_uuid,
773 discovery_device_info->service_count);
775 if (node && node->cb)
776 node->cb(BT_SUCCESS, BT_ADAPTER_DEVICE_DISCOVERY_FOUND,
777 discovery_device_info, node->user_data);
779 set_device_property_changed_callback(device);
781 free_discovery_device_info(discovery_device_info);
784 static void bluez_adapter_discovering_changed(bluez_adapter_t *adapter,
788 bt_adapter_device_discovery_state_e state;
789 struct adapter_discovering_cb_node *node = user_data;
790 bt_adapter_device_discovery_info_s *discovery_device_info;
791 GList *device_list, *list, *next;
792 bluez_device_t *device;
796 state = discovering ? BT_ADAPTER_DEVICE_DISCOVERY_STARTED :
797 BT_ADAPTER_DEVICE_DISCOVERY_FINISHED;
799 if (!node || !node->cb)
802 node->cb(BT_SUCCESS, state, NULL, node->user_data);
805 * BlueZ 5.x may contain some discovering device a short time.
806 * When UI start discovery, the last discovering device may
807 * not dispear, also notify tham.
809 if (state != BT_ADAPTER_DEVICE_DISCOVERY_STARTED)
812 device_list = bluez_adapter_get_devices(default_adapter);
813 for (list = g_list_first(device_list); list; list = next) {
814 next = g_list_next(list);
818 discovery_device_info = get_discovery_device_info(device);
820 node->cb(BT_SUCCESS, BT_ADAPTER_DEVICE_DISCOVERY_FOUND,
821 discovery_device_info, node->user_data);
823 set_device_property_changed_callback(device);
825 free_discovery_device_info(discovery_device_info);
829 void adapter_name_changed(bluez_adapter_t *adapter,
833 struct adapter_name_cb_node *data =
834 (struct adapter_name_cb_node *)user_data;
835 gchar *adapter_name = g_strdup(name);
837 data->cb(adapter_name, data->user_data);
839 g_free(adapter_name);
842 static void discoverable_timeout_changed(bluez_adapter_t *adapter,
843 guint32 timeout, void *user_data)
845 struct adapter_visibility_duration_cb_node *node = user_data;
847 node->cb(timeout, node->user_data);
850 static void adapter_discoverable_changed(bluez_adapter_t *adapter,
851 gboolean discoverable, void *user_data)
853 struct adapter_visibility_mode_cb_node *node = user_data;
854 bt_adapter_visibility_mode_e discoverable_mode;
855 unsigned int discoverable_timeout;
859 BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
863 discoverable_timeout = comms_manager_get_bt_adapter_visibale_time();
864 if (discoverable_timeout == -1) {
865 node->cb(BT_ERROR_OPERATION_FAILED, 0, node->user_data);
869 discoverable_mode = (discoverable_timeout == 0) ?
870 BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE :
871 BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE;
874 node->cb(BT_SUCCESS, discoverable_mode, node->user_data);
877 static void bluez_device_connect_changed(bluez_device_t *device,
878 enum device_state state,
881 struct device_connect_cb_node *data = user_data;
884 case DEVICE_CONNECT_SUCCESS:
885 DBG("Connect device: %s", "DEVICE_CONNECT_SUCCESS");
887 case DEVICE_NOT_READY:
888 DBG("Connect device: %s", "DEVICE_NOT_READY");
890 case DEVICE_ALREADY_CONNECTED:
891 DBG("Connect device: %s", "DEVICE_ALREADY_CONNECTED");
893 case DEVICE_CONNECT_FAILED:
894 DBG("Connect device: %s", "DEVICE_CONNECT_FAILED");
896 case DEVICE_CONNECT_INPROGRESS:
897 DBG("Connect device: %s", "DEVICE_CONNECT_INPROGRESS");
900 ERROR("Unknown error code");
905 data->cb(state, data->user_data);
909 static void bluez_device_disconnect_changed(bluez_device_t *device,
910 enum device_state state,
913 struct device_disconnect_cb_node *data = user_data;
916 case DEVICE_DISCONNECT_SUCCESS:
917 DBG("Disconnect device: %s", "DEVICE_DISCONNECT_SUCCESS");
919 case DEVICE_NOT_CONNECTED:
920 DBG("Disconnect device: %s", "DEVICE_NOT_CONNECTED");
923 ERROR("Unknown error code");
928 data->cb(state, data->user_data);
931 static void _bt_update_bluetooth_callbacks(void)
933 DBG("default_adpater: %p", default_adapter);
935 if (default_adapter == NULL)
938 if (adapter_state_node)
939 bluez_adapter_set_powered_changed_cb(default_adapter,
940 adapter_powered_changed,
943 if (adapter_name_node)
944 bluez_adapter_set_alias_changed_cb(default_adapter,
945 adapter_name_changed,
948 if (device_created_node)
949 bluez_adapter_set_device_created_cb(default_adapter,
950 bluez_device_created,
951 device_created_node);
953 if (adapter_discovering_node)
954 bluez_adapter_set_device_discovering_cb(default_adapter,
955 bluez_adapter_discovering_changed,
956 adapter_discovering_node);
958 if (adapter_visibility_duration_node)
959 bluez_adapter_set_discoverable_timeout_changed_cb(
961 discoverable_timeout_changed,
962 adapter_visibility_duration_node);
964 if (adapter_visibility_mode_node)
965 bluez_adapter_set_discoverable_changed_cb(default_adapter,
966 adapter_discoverable_changed,
967 adapter_visibility_mode_node);
969 if (generic_device_removed_set == FALSE)
970 set_device_removed_generic_callback(default_adapter);
972 if (audio_state_node)
973 bluez_set_audio_state_cb(
974 bluez_audio_state_changed,
977 if (avrcp_target_state_node)
978 bluez_set_avrcp_target_cb(
979 bluez_avrcp_target_state_changed,
980 avrcp_target_state_node);
982 if (device_connect_node)
983 bluez_set_device_connect_changed_cb(
984 bluez_device_connect_changed,
985 device_connect_node);
987 if (device_disconnect_node)
988 bluez_set_device_disconnect_changed_cb(
989 bluez_device_disconnect_changed,
990 device_disconnect_node);
992 if (nap_connection_state_changed_node)
993 bluez_set_nap_connection_state_cb(
994 bluez_nap_connection_changed,
995 nap_connection_state_changed_node);
998 static void setup_bluez_lib(void)
1005 err = bluez_lib_init();
1007 ERROR("Bluz-lib init error");
1011 default_adapter = bluez_adapter_get_adapter(DEFAULT_ADAPTER_NAME);
1012 if (default_adapter == NULL) {
1013 ERROR("Can't find adapter %s", DEFAULT_ADAPTER_NAME);
1018 _bt_update_bluetooth_callbacks();
1022 DBG("Set bluetooth powered state");
1023 if (adapter_state_node == NULL)
1026 bluez_adapter_get_property_powered(default_adapter, &powered);
1028 adapter_powered_changed(default_adapter, powered,
1029 adapter_state_node);
1033 static void destroy_bluez_lib(void)
1037 default_adapter = NULL;
1039 initialized = false;
1042 void _bt_service_bt_in_service_watch(uint in_service, void *user_data)
1044 DBG("%d", in_service);
1047 int bt_initialize(void)
1049 if (bt_service_init)
1054 comms_manager_set_bt_in_service_watch(
1055 _bt_service_bt_in_service_watch, NULL);
1057 bt_service_init = TRUE;
1064 int bt_deinitialize(void)
1066 if (bt_service_init == false)
1069 destroy_bluez_lib();
1071 comms_manager_remove_bt_in_service_watch();
1073 bt_service_init = FALSE;
1078 int bt_adapter_enable(void)
1082 if (bt_service_init == false)
1083 return BT_ERROR_NOT_INITIALIZED;
1085 comms_manager_enable_bluetooth();
1090 int bt_adapter_disable(void)
1094 if (bt_service_init == false)
1095 return BT_ERROR_NOT_INITIALIZED;
1097 comms_manager_disable_bluetooth();
1102 int bt_adapter_get_state(bt_adapter_state_e *adapter_state)
1108 if (initialized == false)
1109 return BT_ERROR_NOT_INITIALIZED;
1111 if (default_adapter == NULL)
1112 return BT_ERROR_ADAPTER_NOT_FOUND;
1114 if (adapter_state == NULL)
1115 return BT_ERROR_INVALID_PARAMETER;
1117 bluez_adapter_get_property_powered(default_adapter, &powered);
1118 if (powered == true)
1119 *adapter_state = BT_ADAPTER_ENABLED;
1121 *adapter_state = BT_ADAPTER_DISABLED;
1126 int bt_adapter_get_address(char **local_address)
1132 if (initialized == false)
1133 return BT_ERROR_NOT_INITIALIZED;
1135 if (default_adapter == NULL)
1136 return BT_ERROR_ADAPTER_NOT_FOUND;
1138 if (local_address == NULL)
1139 return BT_ERROR_INVALID_PARAMETER;
1141 address = bluez_adapter_get_property_address(default_adapter);
1142 if (address == NULL)
1143 return BT_ERROR_OPERATION_FAILED;
1145 *local_address = address;
1150 int bt_adapter_get_name(char **local_name)
1156 if (initialized == false)
1157 return BT_ERROR_NOT_INITIALIZED;
1159 if (default_adapter == NULL)
1160 return BT_ERROR_ADAPTER_NOT_FOUND;
1162 if (local_name == NULL)
1163 return BT_ERROR_INVALID_PARAMETER;
1165 name = bluez_adapter_get_property_alias(default_adapter);
1167 return BT_ERROR_OPERATION_FAILED;
1174 int bt_adapter_set_name(const char *local_name)
1178 if (initialized == false)
1179 return BT_ERROR_NOT_INITIALIZED;
1181 if (default_adapter == NULL)
1182 return BT_ERROR_ADAPTER_NOT_FOUND;
1184 if (local_name == NULL)
1185 return BT_ERROR_INVALID_PARAMETER;
1187 bluez_adapter_set_alias(default_adapter, local_name);
1192 int bt_adapter_set_name_changed_cb(bt_adapter_name_changed_cb callback,
1195 struct adapter_name_cb_node *node_data;
1197 if (callback == NULL)
1198 return BT_ERROR_INVALID_PARAMETER;
1200 if (adapter_name_node) {
1201 DBG("Powered state changed callback already set.");
1202 return BT_ERROR_ALREADY_DONE;
1205 node_data = g_new0(struct adapter_name_cb_node, 1);
1206 if (node_data == NULL) {
1208 return BT_ERROR_OUT_OF_MEMORY;
1211 node_data->cb = callback;
1212 node_data->user_data = user_data;
1214 adapter_name_node = node_data;
1216 _bt_update_bluetooth_callbacks();
1221 int bt_adapter_unset_name_changed_cb(void)
1225 if (initialized == false)
1226 return BT_ERROR_NOT_INITIALIZED;
1228 if (default_adapter == NULL)
1229 return BT_ERROR_ADAPTER_NOT_FOUND;
1231 if (!adapter_name_node)
1234 bluez_adapter_unset_alias_changed_cb(default_adapter);
1236 g_free(adapter_name_node);
1237 adapter_name_node = NULL;
1242 int bt_adapter_get_visibility(bt_adapter_visibility_mode_e *mode,
1246 unsigned int timeout;
1251 if (initialized == false)
1252 return BT_ERROR_NOT_INITIALIZED;
1254 if (default_adapter == NULL)
1255 return BT_ERROR_ADAPTER_NOT_FOUND;
1258 return BT_ERROR_INVALID_PARAMETER;
1260 err = bluez_adapter_get_property_discoverable(default_adapter,
1263 return BT_ERROR_OPERATION_FAILED;
1265 timeout = comms_manager_get_bt_adapter_visibale_time();
1267 return BT_ERROR_OPERATION_FAILED;
1273 *mode = BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE;
1277 *mode = (timeout == 0) ?
1278 BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE :
1279 BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE;
1281 if (*mode == BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE)
1282 *duration = timeout;
1287 int bt_adapter_set_visibility(bt_adapter_visibility_mode_e discoverable_mode,
1294 if (initialized == false)
1295 return BT_ERROR_NOT_INITIALIZED;
1297 if (default_adapter == NULL)
1298 return BT_ERROR_ADAPTER_NOT_FOUND;
1300 switch (discoverable_mode) {
1301 case BT_ADAPTER_VISIBILITY_MODE_NON_DISCOVERABLE:
1302 discoverable = false;
1305 case BT_ADAPTER_VISIBILITY_MODE_LIMITED_DISCOVERABLE:
1306 discoverable = true;
1308 case BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE:
1309 discoverable = true;
1313 return BT_ERROR_INVALID_PARAMETER;
1316 bluez_adapter_set_discoverable(default_adapter, discoverable);
1318 bluez_adapter_set_discoverable_timeout(default_adapter, duration);
1323 static gboolean bt_stop_discovery_timeout_cb(gpointer user_data)
1327 bt_adapter_stop_device_discovery();
1332 static void bt_stop_discovery_timeout(void)
1337 event_id = g_timeout_add(BT_STOP_DISCOVERY_TIMEOUT,
1338 (GSourceFunc)bt_stop_discovery_timeout_cb, NULL);
1341 int bt_adapter_start_device_discovery(void)
1345 if (initialized == false)
1346 return BT_ERROR_NOT_INITIALIZED;
1348 if (default_adapter == NULL)
1349 return BT_ERROR_ADAPTER_NOT_FOUND;
1351 bluez_adapter_start_discovery(default_adapter);
1353 bt_stop_discovery_timeout();
1358 int bt_adapter_stop_device_discovery(void)
1362 if (initialized == false)
1363 return BT_ERROR_NOT_INITIALIZED;
1365 if (default_adapter == NULL)
1366 return BT_ERROR_ADAPTER_NOT_FOUND;
1368 bluez_adapter_stop_discovery(default_adapter);
1373 int bt_adapter_is_discovering(bool *is_discovering)
1379 if (initialized == false)
1380 return BT_ERROR_NOT_INITIALIZED;
1382 if (default_adapter == NULL)
1383 return BT_ERROR_ADAPTER_NOT_FOUND;
1385 if (is_discovering == NULL)
1386 return BT_ERROR_INVALID_PARAMETER;
1388 bluez_adapter_get_property_discovering(default_adapter, &discovering);
1390 *is_discovering = discovering;
1395 int bt_adapter_is_service_used(const char *service_uuid, bool *used)
1397 guint length, index;
1402 if (initialized == false)
1403 return BT_ERROR_NOT_INITIALIZED;
1405 if (default_adapter == NULL)
1406 return BT_ERROR_ADAPTER_NOT_FOUND;
1409 return BT_ERROR_INVALID_PARAMETER;
1411 uuids = bluez_adapter_get_property_uuids(default_adapter);
1412 length = g_strv_length(uuids);
1415 for (index = 0; index < length; ++index) {
1416 if (strcasecmp(uuids[index], service_uuid) == 0) {
1427 int bt_adapter_set_device_discovery_state_changed_cb(
1428 bt_adapter_device_discovery_state_changed_cb callback,
1431 struct device_created_cb_node *created_node;
1432 struct adapter_discovering_cb_node *discovering_node;
1433 struct device_destroy_unpaired_cb_node *removed_node;
1437 if (callback == NULL)
1438 return BT_ERROR_INVALID_PARAMETER;
1440 if (device_created_node) {
1441 DBG("Discovery state changed callback already set.");
1442 return BT_ERROR_ALREADY_DONE;
1445 created_node = g_new0(struct device_created_cb_node, 1);
1446 if (created_node == NULL) {
1447 ERROR("no memory.");
1448 return BT_ERROR_OUT_OF_MEMORY;
1451 created_node->cb = callback;
1452 created_node->user_data = user_data;
1454 device_created_node = created_node;
1456 if (adapter_discovering_node) {
1457 DBG("Device discovering changed callback already set.");
1458 return BT_ERROR_ALREADY_DONE;
1461 discovering_node = g_new0(struct adapter_discovering_cb_node, 1);
1462 if (discovering_node == NULL) {
1463 ERROR("no memory.");
1464 return BT_ERROR_OUT_OF_MEMORY;
1467 discovering_node->cb = callback;
1468 discovering_node->user_data = user_data;
1470 adapter_discovering_node = discovering_node;
1472 if (unpaired_device_removed_node) {
1473 DBG("Device removed changed callback already set");
1474 return BT_ERROR_ALREADY_DONE;
1477 removed_node = g_new0(struct device_destroy_unpaired_cb_node, 1);
1478 if (removed_node == NULL) {
1480 return BT_ERROR_OUT_OF_MEMORY;
1483 removed_node->cb = callback;
1484 removed_node->user_data = user_data;
1486 unpaired_device_removed_node = removed_node;
1488 _bt_update_bluetooth_callbacks();
1493 int bt_adapter_set_state_changed_cb(bt_adapter_state_changed_cb callback,
1496 struct adapter_state_cb_node *node_data;
1500 if (callback == NULL)
1501 return BT_ERROR_INVALID_PARAMETER;
1503 if (adapter_state_node) {
1504 DBG("Powered state changed callback already set.");
1505 return BT_ERROR_ALREADY_DONE;
1508 node_data = g_new0(struct adapter_state_cb_node, 1);
1509 if (node_data == NULL) {
1511 return BT_ERROR_OUT_OF_MEMORY;
1514 node_data->cb = callback;
1515 node_data->user_data = user_data;
1517 adapter_state_node = node_data;
1519 _bt_update_bluetooth_callbacks();
1524 int bt_adapter_set_visibility_duration_changed_cb(
1525 bt_adapter_visibility_duration_changed_cb callback,
1528 struct adapter_visibility_duration_cb_node *node_data;
1532 if (callback == NULL)
1533 return BT_ERROR_INVALID_PARAMETER;
1535 if (adapter_visibility_duration_node) {
1536 DBG("duration changed callback already set.");
1537 return BT_ERROR_ALREADY_DONE;
1540 node_data = g_new0(struct adapter_visibility_duration_cb_node, 1);
1541 if (node_data == NULL) {
1543 return BT_ERROR_OUT_OF_MEMORY;
1546 node_data->cb = callback;
1547 node_data->user_data = user_data;
1549 adapter_visibility_duration_node = node_data;
1551 _bt_update_bluetooth_callbacks();
1555 int bt_adapter_set_visibility_mode_changed_cb(
1556 bt_adapter_visibility_mode_changed_cb callback,
1559 struct adapter_visibility_mode_cb_node *node_data;
1563 if (callback == NULL)
1564 return BT_ERROR_INVALID_PARAMETER;
1566 if (adapter_visibility_mode_node) {
1567 DBG("visibility mode changed callback already set.");
1568 return BT_ERROR_ALREADY_DONE;
1571 node_data = g_new0(struct adapter_visibility_mode_cb_node, 1);
1572 if (node_data == NULL) {
1574 return BT_ERROR_OUT_OF_MEMORY;
1577 node_data->cb = callback;
1578 node_data->user_data = user_data;
1580 adapter_visibility_mode_node = node_data;
1582 _bt_update_bluetooth_callbacks();
1587 int bt_adapter_unset_state_changed_cb(void)
1591 if (initialized == false)
1592 return BT_ERROR_NOT_INITIALIZED;
1594 if (default_adapter == NULL)
1595 return BT_ERROR_ADAPTER_NOT_FOUND;
1597 if (!adapter_state_node)
1600 bluez_adapter_unset_powered_changed_cb(default_adapter);
1602 g_free(adapter_state_node);
1603 adapter_state_node = NULL;
1608 int bt_adapter_unset_device_discovery_state_changed_cb(void)
1612 if (initialized == false)
1613 return BT_ERROR_NOT_INITIALIZED;
1615 if (default_adapter == NULL)
1616 return BT_ERROR_ADAPTER_NOT_FOUND;
1618 if (device_created_node) {
1619 bluez_adapter_unset_device_created_cb(default_adapter);
1621 g_free(device_created_node);
1622 device_created_node = NULL;
1625 if (adapter_discovering_node) {
1626 bluez_adapter_unset_device_discovering_cb(default_adapter);
1628 g_free(adapter_discovering_node);
1629 adapter_discovering_node = NULL;
1632 if (unpaired_device_removed_node) {
1633 g_free(unpaired_device_removed_node);
1634 unpaired_device_removed_node = NULL;
1637 if (paired_device_removed_node == NULL &&
1638 generic_device_removed_set == TRUE) {
1639 bluez_adapter_unset_device_removed_cb(default_adapter);
1641 generic_device_removed_set = FALSE;
1647 int bt_adapter_unset_visibility_duration_changed_cb(void)
1651 if (initialized == false)
1652 return BT_ERROR_NOT_INITIALIZED;
1654 if (default_adapter == NULL)
1655 return BT_ERROR_ADAPTER_NOT_FOUND;
1657 if (!adapter_visibility_duration_node)
1660 bluez_adapter_unset_discoverable_timeout_changed_cb(default_adapter);
1662 g_free(adapter_visibility_duration_node);
1663 adapter_visibility_duration_node = NULL;
1668 int bt_adapter_unset_visibility_mode_changed_cb(void)
1672 if (initialized == false)
1673 return BT_ERROR_NOT_INITIALIZED;
1675 if (default_adapter == NULL)
1676 return BT_ERROR_ADAPTER_NOT_FOUND;
1678 if (!adapter_visibility_mode_node)
1681 bluez_adapter_unset_discoverable_changed_cb(default_adapter);
1683 g_free(adapter_visibility_mode_node);
1684 adapter_visibility_mode_node = NULL;
1689 int bt_adapter_reset(void)
1691 DBG("Not implement");
1696 int bt_adapter_foreach_bonded_device(bt_adapter_bonded_device_cb callback,
1700 bluez_device_t *device;
1701 bt_device_info_s *device_bond_info;
1707 if (initialized == false)
1708 return BT_ERROR_NOT_INITIALIZED;
1710 if (default_adapter == NULL)
1711 return BT_ERROR_ADAPTER_NOT_FOUND;
1713 if (callback == NULL)
1714 return BT_ERROR_INVALID_PARAMETER;
1716 list = bluez_adapter_get_devices(default_adapter);
1717 for (iter = g_list_first(list); iter; iter = next) {
1718 device = iter->data;
1720 next = g_list_next(iter);
1725 bluez_device_get_property_paired(device, &paired);
1726 if (paired == false)
1729 device_bond_info = get_device_info(device);
1730 DBG("device name: %s", device_bond_info->remote_name);
1732 callback(device_bond_info, user_data);
1734 free_device_info(device_bond_info);
1742 int bt_adapter_get_bonded_device_info(const char *remote_address,
1743 bt_device_info_s **device_info)
1745 bluez_device_t *device;
1750 if (initialized == false)
1751 return BT_ERROR_NOT_INITIALIZED;
1753 if (default_adapter == NULL)
1754 return BT_ERROR_ADAPTER_NOT_FOUND;
1756 if (!remote_address || !device_info)
1757 return BT_ERROR_INVALID_PARAMETER;
1759 device = bluez_adapter_get_device_by_address(default_adapter,
1762 return BT_ERROR_OPERATION_FAILED;
1764 bluez_device_get_property_paired(device, &paired);
1765 if (paired == false)
1766 return BT_ERROR_REMOTE_DEVICE_NOT_BONDED;
1768 *device_info = get_device_info(device);
1773 int bt_adapter_free_device_info(bt_device_info_s *device_info)
1776 return BT_ERROR_INVALID_PARAMETER;
1778 free_device_info(device_info);
1783 /* Device Function */
1785 static void bt_device_paired_cb(enum bluez_error_type error,
1788 bt_error_e capi_error = BT_SUCCESS;
1789 char *remote_address = user_data;
1790 bt_device_info_s *device_info;
1791 bluez_device_t *device;
1793 device = bluez_adapter_get_device_by_address(default_adapter,
1796 ERROR("no %s device", remote_address);
1800 if (!device_bond_node)
1803 /* Pair a device success, will report through DISCOVERY EVENT */
1804 if (error == ERROR_NONE)
1808 case ERROR_INVALID_ARGUMENTS:
1809 capi_error = BT_ERROR_INVALID_PARAMETER;
1812 capi_error = BT_ERROR_OPERATION_FAILED;
1814 case ERROR_AUTH_CANCELED:
1815 case ERROR_AUTH_FAILED:
1816 capi_error = BT_ERROR_AUTH_FAILED;
1818 case ERROR_AUTH_REJECT:
1819 capi_error = BT_ERROR_AUTH_REJECTED;
1821 case ERROR_AUTH_TIMEOUT:
1822 capi_error = BT_ERROR_TIMED_OUT;
1824 case ERROR_AUTH_ATTEMPT_FAILED:
1825 capi_error = BT_ERROR_AUTH_FAILED;
1828 WARN("Unknown error type with device pair");
1831 device_info = get_device_info(device);
1833 device_bond_node->cb(capi_error, device_info,
1834 device_bond_node->user_data);
1836 free_device_info(device_info);
1839 int bt_device_create_bond(const char *remote_address)
1841 comms_bluetooth_device_pair(remote_address,
1842 bt_device_paired_cb, strdup(remote_address));
1847 int bt_device_cancel_bonding(void)
1849 enum bluez_error_type error_type;
1854 if (initialized == false)
1855 return BT_ERROR_NOT_INITIALIZED;
1857 if (default_adapter == NULL)
1858 return BT_ERROR_ADAPTER_NOT_FOUND;
1860 bluez_adapter_get_property_powered(default_adapter, &powered);
1861 if (powered == FALSE)
1862 return BT_ERROR_NOT_ENABLED;
1864 error_type = comms_bluetooth_device_cancel_pairing_sync();
1865 if (error_type == ERROR_NONE)
1867 else if (error_type == ERROR_DOES_NOT_EXIST)
1868 return BT_ERROR_NOT_IN_PROGRESS;
1870 return BT_ERROR_OPERATION_FAILED;
1873 int bt_device_destroy_bond(const char *remote_address)
1875 bluez_device_t *device;
1879 if (initialized == false)
1880 return BT_ERROR_NOT_INITIALIZED;
1882 if (default_adapter == NULL)
1883 return BT_ERROR_ADAPTER_NOT_FOUND;
1885 device = bluez_adapter_get_device_by_address(default_adapter,
1888 return BT_ERROR_OPERATION_FAILED;
1890 bluez_adapter_remove_device(default_adapter, device);
1895 int bt_device_set_alias(const char *remote_address, const char *alias)
1897 bluez_device_t *device;
1901 if (initialized == false)
1902 return BT_ERROR_NOT_INITIALIZED;
1904 if (default_adapter == NULL)
1905 return BT_ERROR_ADAPTER_NOT_FOUND;
1907 if (!remote_address || !alias)
1908 return BT_ERROR_INVALID_PARAMETER;
1910 device = bluez_adapter_get_device_by_address(default_adapter,
1913 return BT_ERROR_OPERATION_FAILED;
1915 bluez_device_set_alias(device, alias);
1920 int bt_device_set_authorization(const char *remote_address,
1921 bt_device_authorization_e authorization_state)
1924 bluez_device_t *device;
1928 if (initialized == false)
1929 return BT_ERROR_NOT_INITIALIZED;
1931 if (default_adapter == NULL)
1932 return BT_ERROR_ADAPTER_NOT_FOUND;
1934 if (!remote_address)
1935 return BT_ERROR_INVALID_PARAMETER;
1937 device = bluez_adapter_get_device_by_address(default_adapter,
1940 return BT_ERROR_OPERATION_FAILED;
1942 trusted = (authorization_state == BT_DEVICE_AUTHORIZED) ?
1945 bluez_device_set_trusted(device, trusted);
1950 static bt_device_sdp_info_s *get_device_sdp_info(bluez_device_t *device)
1952 bt_device_sdp_info_s *sdp_info;
1957 sdp_info = g_new0(bt_device_sdp_info_s, 1);
1958 if (sdp_info == NULL) {
1959 ERROR("no memeory");
1963 address = bluez_device_get_property_address(device);
1964 uuids = bluez_device_get_property_uuids(device);
1966 len = g_strv_length(uuids);
1968 sdp_info->remote_address = address;
1969 sdp_info->service_uuid = uuids;
1970 sdp_info->service_count = len;
1975 static void free_device_sdp_info(bt_device_sdp_info_s *sdp_info)
1979 if (sdp_info == NULL)
1982 g_free(sdp_info->remote_address);
1983 for (i = 0; i < sdp_info->service_count; ++i)
1984 g_free(sdp_info->service_uuid[i]);
1986 g_free(sdp_info->service_uuid);
1990 int bt_device_start_service_search(const char *remote_address)
1992 bluez_device_t *device = NULL;
1993 bt_device_sdp_info_s *sdp_info;
1994 int powered, paired;
1996 GList *list, *iter, *next;
1998 if (initialized == false)
1999 return BT_ERROR_NOT_INITIALIZED;
2001 if (default_adapter == NULL)
2002 return BT_ERROR_ADAPTER_NOT_FOUND;
2004 if (!remote_address)
2005 return BT_ERROR_INVALID_PARAMETER;
2007 bluez_adapter_get_property_powered(default_adapter, &powered);
2008 if (powered == FALSE)
2009 return BT_ERROR_NOT_ENABLED;
2011 if (!device_service_search_node)
2014 list = bluez_adapter_get_devices(default_adapter);
2015 for (iter = g_list_first(list); iter; iter = next) {
2016 bluez_device_t *dev;
2019 next = g_list_next(iter);
2024 address = bluez_device_get_property_address(dev);
2025 if (!g_strcmp0(remote_address, address)) {
2037 return BT_ERROR_SERVICE_SEARCH_FAILED;
2039 bluez_device_get_property_paired(device, &paired);
2040 if (paired == FALSE)
2041 return BT_ERROR_REMOTE_DEVICE_NOT_BONDED;
2043 sdp_info = get_device_sdp_info(device);
2045 device_service_search_node->cb(BT_SUCCESS, sdp_info,
2046 device_service_search_node->user_data);
2048 free_device_sdp_info(sdp_info);
2053 int bt_device_cancel_service_search(void)
2056 * BlueZ 5.x don't support cancel device service search
2057 * So only return SUCCESS.
2063 int bt_device_set_bond_created_cb(bt_device_bond_created_cb callback,
2066 struct device_bond_cb_node *node;
2071 if (callback == NULL)
2072 return BT_ERROR_INVALID_PARAMETER;
2074 if (device_bond_node) {
2075 DBG("Device bond callback already set.");
2079 node = g_new0(struct device_bond_cb_node, 1);
2081 ERROR("no memeroy");
2082 return BT_ERROR_OPERATION_FAILED;
2085 node->cb = callback;
2086 node->user_data = user_data;
2088 device_bond_node = node;
2090 dev_property_callback_flags |= DEV_PROP_FLAG_PAIR;
2092 if (!default_adapter)
2095 list = bluez_adapter_get_devices(default_adapter);
2096 foreach_device_property_callback(list, DEV_PROP_FLAG_PAIR);
2101 int bt_device_unset_bond_created_cb(void)
2106 if (initialized == false)
2107 return BT_ERROR_NOT_INITIALIZED;
2109 if (default_adapter == NULL)
2110 return BT_ERROR_ADAPTER_NOT_FOUND;
2112 if (!device_bond_node)
2115 dev_property_callback_flags &= ~DEV_PROP_FLAG_PAIR;
2117 list = bluez_adapter_get_devices(default_adapter);
2118 foreach_device_property_callback(list, DEV_PROP_FLAG_PAIR);
2120 g_free(device_bond_node);
2121 device_bond_node = NULL;
2126 int bt_device_set_bond_destroyed_cb(bt_device_bond_destroyed_cb callback,
2129 struct device_destroy_paired_cb_node *node;
2133 if (callback == NULL)
2134 return BT_ERROR_INVALID_PARAMETER;
2136 if (paired_device_removed_node) {
2137 DBG("Device bonded-destroy callback already set");
2138 return BT_ERROR_ALREADY_DONE;
2141 node = g_new0(struct device_destroy_paired_cb_node, 1);
2143 ERROR("no memeroy");
2144 return BT_ERROR_OUT_OF_MEMORY;
2147 node->cb = callback;
2148 node->user_data = user_data;
2150 paired_device_removed_node = node;
2152 _bt_update_bluetooth_callbacks();
2157 int bt_device_unset_bond_destroyed_cb(void)
2161 if (initialized == false)
2162 return BT_ERROR_NOT_INITIALIZED;
2164 if (default_adapter == NULL)
2165 return BT_ERROR_ADAPTER_NOT_FOUND;
2167 if (paired_device_removed_node) {
2168 g_free(paired_device_removed_node);
2169 paired_device_removed_node = NULL;
2172 if (unpaired_device_removed_node == NULL &&
2173 generic_device_removed_set == TRUE) {
2174 bluez_adapter_unset_device_removed_cb(default_adapter);
2176 generic_device_removed_set = FALSE;
2182 int bt_device_set_authorization_changed_cb(
2183 bt_device_authorization_changed_cb callback,
2186 struct device_auth_cb_node *node;
2191 if (callback == NULL)
2192 return BT_ERROR_INVALID_PARAMETER;
2194 if (device_auth_node) {
2195 DBG("Device bond callback already set.");
2199 node = g_new0(struct device_auth_cb_node, 1);
2201 ERROR("no memeroy");
2202 return BT_ERROR_OPERATION_FAILED;
2205 node->cb = callback;
2206 node->user_data = user_data;
2208 device_auth_node = node;
2210 dev_property_callback_flags |= DEV_PROP_FLAG_AUTH;
2212 if (!default_adapter)
2215 list = bluez_adapter_get_devices(default_adapter);
2216 foreach_device_property_callback(list, DEV_PROP_FLAG_AUTH);
2221 int bt_device_unset_authorization_changed_cb(void)
2226 if (initialized == false)
2227 return BT_ERROR_NOT_INITIALIZED;
2229 if (default_adapter == NULL)
2230 return BT_ERROR_ADAPTER_NOT_FOUND;
2232 if (!device_auth_node)
2235 dev_property_callback_flags &= ~DEV_PROP_FLAG_AUTH;
2237 list = bluez_adapter_get_devices(default_adapter);
2238 foreach_device_property_callback(list, DEV_PROP_FLAG_AUTH);
2240 g_free(device_auth_node);
2241 device_auth_node = NULL;
2246 int bt_device_set_service_searched_cb(bt_device_service_searched_cb callback,
2249 struct device_service_search_cb_node *node;
2253 if (callback == NULL)
2254 return BT_ERROR_INVALID_PARAMETER;
2256 if (device_service_search_node) {
2257 DBG("Device service serach callback already set.");
2261 node = g_new0(struct device_service_search_cb_node, 1);
2263 ERROR("no memeroy");
2264 return BT_ERROR_OUT_OF_MEMORY;
2267 node->cb = callback;
2268 node->user_data = user_data;
2270 device_service_search_node = node;
2275 int bt_device_unset_service_searched_cb(void)
2279 if (initialized == false)
2280 return BT_ERROR_NOT_INITIALIZED;
2282 if (!device_service_search_node)
2285 g_free(device_service_search_node);
2286 device_service_search_node = NULL;
2291 int bt_device_set_connection_state_changed_cb(
2292 bt_device_connection_state_changed_cb callback,
2295 struct device_connected_state_cb_node *node_data;
2300 if (callback == NULL)
2301 return BT_ERROR_INVALID_PARAMETER;
2303 if (device_connected_state_node) {
2304 DBG("Device connected state changed callback already set.");
2305 return BT_ERROR_ALREADY_DONE;
2308 node_data = g_new0(struct device_connected_state_cb_node, 1);
2309 if (node_data == NULL) {
2311 return BT_ERROR_OUT_OF_MEMORY;
2314 node_data->cb = callback;
2315 node_data->user_data = user_data;
2317 device_connected_state_node = node_data;
2319 dev_property_callback_flags |= DEV_PROP_FLAG_CONNECT;
2321 if (!default_adapter)
2324 list = bluez_adapter_get_devices(default_adapter);
2325 foreach_device_property_callback(list, DEV_PROP_FLAG_CONNECT);
2330 int bt_device_unset_connection_state_changed_cb(void)
2335 if (initialized == false)
2336 return BT_ERROR_NOT_INITIALIZED;
2338 if (default_adapter == NULL)
2339 return BT_ERROR_ADAPTER_NOT_FOUND;
2341 if (!device_connected_state_node)
2344 dev_property_callback_flags &= ~DEV_PROP_FLAG_CONNECT;
2346 list = bluez_adapter_get_devices(default_adapter);
2347 foreach_device_property_callback(list, DEV_PROP_FLAG_CONNECT);
2349 g_free(device_connected_state_node);
2350 device_connected_state_node = NULL;
2355 /* Audio Function */
2357 int bt_audio_initialize(void)
2359 DBG("Not implement");
2364 int bt_audio_deinitialize(void)
2366 DBG("Not implement");
2371 int bt_audio_connect(const char *remote_address,
2372 bt_audio_profile_type_e type)
2374 bluez_device_t *device;
2379 if (initialized == false)
2380 return BT_ERROR_NOT_INITIALIZED;
2382 if (default_adapter == NULL)
2383 return BT_ERROR_ADAPTER_NOT_FOUND;
2386 case BT_AUDIO_PROFILE_TYPE_HSP_HFP:
2387 uuid = BT_HFP_HS_UUID;
2389 case BT_AUDIO_PROFILE_TYPE_A2DP:
2390 uuid = BT_A2DP_SINK_UUID;
2392 case BT_AUDIO_PROFILE_TYPE_ALL:
2393 uuid = BT_GENERIC_AUDIO_UUID;
2396 DBG("Unknown role");
2397 return BT_ERROR_INVALID_PARAMETER;
2400 device = bluez_adapter_get_device_by_address(default_adapter,
2403 return BT_ERROR_OPERATION_FAILED;
2405 bluez_device_connect_profile(device, uuid,
2406 profile_connect_callback);
2411 int bt_audio_disconnect(const char *remote_address,
2412 bt_audio_profile_type_e type)
2414 bluez_device_t *device;
2419 if (initialized == false)
2420 return BT_ERROR_NOT_INITIALIZED;
2422 if (default_adapter == NULL)
2423 return BT_ERROR_ADAPTER_NOT_FOUND;
2426 case BT_AUDIO_PROFILE_TYPE_HSP_HFP:
2427 uuid = BT_HFP_HS_UUID;
2429 case BT_AUDIO_PROFILE_TYPE_A2DP:
2430 uuid = BT_A2DP_SINK_UUID;
2432 case BT_AUDIO_PROFILE_TYPE_ALL:
2433 uuid = BT_GENERIC_AUDIO_UUID;
2436 DBG("Unknown role");
2437 return BT_ERROR_INVALID_PARAMETER;
2440 device = bluez_adapter_get_device_by_address(default_adapter,
2443 return BT_ERROR_OPERATION_FAILED;
2445 bluez_device_disconnect_profile(device, uuid,
2446 profile_disconnect_callback);
2451 int bt_audio_set_connection_state_changed_cb(
2452 bt_audio_connection_state_changed_cb callback,
2455 struct audio_connection_state_changed_cb_node *node_data = NULL;
2457 if (callback == NULL)
2458 return BT_ERROR_INVALID_PARAMETER;
2460 if (audio_state_node) {
2461 DBG("audio state callback already set.");
2462 return BT_ERROR_ALREADY_DONE;
2465 node_data = g_new0(struct audio_connection_state_changed_cb_node, 1);
2466 if (node_data == NULL) {
2468 return BT_ERROR_OUT_OF_MEMORY;
2471 node_data->cb = callback;
2472 node_data->user_data = user_data;
2474 audio_state_node = node_data;
2476 _bt_update_bluetooth_callbacks();
2481 int bt_audio_unset_connection_state_changed_cb(void)
2485 if (initialized == false)
2486 return BT_ERROR_NOT_INITIALIZED;
2488 if (!audio_state_node)
2491 bluez_unset_audio_state_cb();
2493 g_free(audio_state_node);
2494 audio_state_node = NULL;
2499 static gboolean media_handle_set_property(GDBusConnection *connection,
2500 const gchar *sender,
2501 const gchar *object_path,
2502 const gchar *interface_name,
2503 const gchar *property_name,
2508 DBG("property_name = %s", property_name);
2510 if (g_strcmp0(property_name, "LoopStatus") == 0) {
2511 const gchar *loopstatus = g_variant_get_string(value, NULL);
2512 DBG("loopstatus = %s", loopstatus);
2514 if (avrcp_repeat_node)
2515 bluez_avrcp_repeat_changed(loopstatus,
2517 } else if (g_strcmp0(property_name, "Shuffle") == 0) {
2518 gboolean shuffle_mode = g_variant_get_boolean(value);
2519 if (shuffle_mode == TRUE)
2520 DBG("shuffle_mode TRUE");
2522 DBG("shuffle_mode FALSE");
2524 if (avrcp_shuffle_node)
2525 bluez_avrcp_shuffle_changed(shuffle_mode,
2526 avrcp_shuffle_node);
2529 return *error == NULL;
2532 static const gchar media_xml[] =
2534 " <interface name='org.mpris.MediaPlayer2.Player'>"
2535 " <property type='b' name='Shuffle' access='readwrite'/>"
2536 " <property type='s' name='LoopStatus' access='readwrite'/>"
2540 static const GDBusInterfaceVTable media_handle = {
2543 media_handle_set_property
2546 static GDBusNodeInfo *media_data;
2547 static int bluetooth_media_agent_id;
2549 static int destory_media_agent(void)
2551 if (bluetooth_media_agent_id > 0) {
2552 comms_bluetooth_unregister_media_agent(AGENT_OBJECT_PATH,
2555 g_dbus_connection_unregister_object(conn,
2556 bluetooth_media_agent_id);
2558 bluetooth_media_agent_id = 0;
2560 release_name_on_dbus(BLUEZ_AGENT_SERVICE);
2566 static int create_media_agent(void)
2570 if (bluetooth_media_agent_id)
2571 return BT_ERROR_ALREADY_DONE;
2574 g_dbus_node_info_new_for_xml(media_xml, NULL);
2576 ret = request_name_on_dbus(BLUEZ_AGENT_SERVICE);
2580 DBG("%s requested success", BLUEZ_AGENT_SERVICE);
2582 bluetooth_media_agent_id = g_dbus_connection_register_object(
2592 if (bluetooth_media_agent_id == 0)
2593 return BT_ERROR_OPERATION_FAILED;
2595 ret = comms_bluetooth_register_media_agent_sync(AGENT_OBJECT_PATH,
2598 DBG("ret = %d", ret);
2600 if (ret != BT_SUCCESS) {
2601 destory_media_agent();
2602 return BT_ERROR_OPERATION_FAILED;
2608 int bt_avrcp_target_initialize(
2609 bt_avrcp_target_connection_state_changed_cb callback,
2612 struct avrcp_target_connection_state_changed_node *node_data = NULL;
2615 DBG("default_adpater: %p", default_adapter);
2617 if (default_adapter == NULL)
2618 return BT_ERROR_ADAPTER_NOT_FOUND;
2620 if (callback == NULL)
2621 return BT_ERROR_INVALID_PARAMETER;
2623 if (avrcp_target_state_node) {
2624 DBG("avrcp target callback already set.");
2625 return BT_ERROR_ALREADY_DONE;
2628 ret = create_media_agent();
2630 if (ret != BT_SUCCESS)
2634 g_new0(struct avrcp_target_connection_state_changed_node, 1);
2635 if (node_data == NULL) {
2637 return BT_ERROR_OUT_OF_MEMORY;
2640 node_data->cb = callback;
2641 node_data->user_data = user_data;
2643 avrcp_target_state_node = node_data;
2645 _bt_update_bluetooth_callbacks();
2650 int bt_avrcp_target_deinitialize(void)
2654 if (initialized == false)
2655 return BT_ERROR_NOT_INITIALIZED;
2657 if (!avrcp_target_state_node)
2660 bluez_unset_avrcp_target_cb();
2662 g_free(avrcp_target_state_node);
2663 avrcp_target_state_node = NULL;
2665 destory_media_agent();
2670 int bt_avrcp_set_repeat_mode_changed_cb(
2671 bt_avrcp_repeat_mode_changed_cb callback,
2674 static struct avrcp_repeat_mode_changed_node *node_data;
2676 DBG("default_adpater: %p", default_adapter);
2678 if (default_adapter == NULL)
2679 return BT_ERROR_ADAPTER_NOT_FOUND;
2681 if (callback == NULL)
2682 return BT_ERROR_INVALID_PARAMETER;
2684 if (avrcp_repeat_node) {
2685 DBG("repeat mode callback already set.");
2686 return BT_ERROR_ALREADY_DONE;
2689 node_data = g_new0(struct avrcp_repeat_mode_changed_node, 1);
2690 if (node_data == NULL) {
2692 return BT_ERROR_OUT_OF_MEMORY;
2695 node_data->cb = callback;
2696 node_data->user_data = user_data;
2698 avrcp_repeat_node = node_data;
2703 int bt_avrcp_unset_repeat_mode_changed_cb(void)
2707 if (initialized == false)
2708 return BT_ERROR_NOT_INITIALIZED;
2710 if (!avrcp_repeat_node)
2713 g_free(avrcp_repeat_node);
2714 avrcp_repeat_node = NULL;
2719 int bt_avrcp_set_shuffle_mode_changed_cb(
2720 bt_avrcp_shuffle_mode_changed_cb callback,
2723 struct avrcp_set_shuffle_mode_changed_node *node_data = NULL;
2725 DBG("default_adpater: %p", default_adapter);
2727 if (default_adapter == NULL)
2728 return BT_ERROR_ADAPTER_NOT_FOUND;
2730 if (callback == NULL)
2731 return BT_ERROR_INVALID_PARAMETER;
2733 if (avrcp_shuffle_node) {
2734 DBG("repeat mode callback already set.");
2735 return BT_ERROR_ALREADY_DONE;
2738 node_data = g_new0(struct avrcp_set_shuffle_mode_changed_node, 1);
2739 if (node_data == NULL) {
2741 return BT_ERROR_OUT_OF_MEMORY;
2744 node_data->cb = callback;
2745 node_data->user_data = user_data;
2747 avrcp_shuffle_node = node_data;
2752 int bt_avrcp_unset_shuffle_mode_changed_cb(void)
2756 if (initialized == false)
2757 return BT_ERROR_NOT_INITIALIZED;
2759 if (!avrcp_shuffle_node)
2762 g_free(avrcp_shuffle_node);
2763 avrcp_shuffle_node = NULL;
2768 int bt_avrcp_target_notify_repeat_mode(bt_avrcp_repeat_mode_e mode)
2772 if (default_adapter == NULL) {
2774 return BT_ERROR_ADAPTER_NOT_FOUND;
2777 return comms_bluetooth_avrcp_change_property(LOOPSTATUS,
2781 int bt_avrcp_target_notify_shuffle_mode(bt_avrcp_shuffle_mode_e mode)
2785 if (default_adapter == NULL) {
2787 return BT_ERROR_ADAPTER_NOT_FOUND;
2790 return comms_bluetooth_avrcp_change_property(SHUFFLE, mode,
2794 int bt_avrcp_target_notify_player_state(bt_avrcp_player_state_e state)
2798 if (default_adapter == NULL) {
2800 return BT_ERROR_ADAPTER_NOT_FOUND;
2803 return comms_bluetooth_avrcp_change_property(PLAYBACKSTATUS,
2807 int bt_avrcp_target_notify_position(unsigned int position)
2811 if (default_adapter == NULL) {
2813 return BT_ERROR_ADAPTER_NOT_FOUND;
2816 return comms_bluetooth_avrcp_change_property(POSITION,
2817 position, NULL, NULL);
2820 int bt_avrcp_target_notify_track(const char *title, const char *artist,
2821 const char *album, const char *genre, unsigned int track_num,
2822 unsigned int total_tracks, unsigned int duration)
2824 GVariantBuilder *builder;
2829 if (default_adapter == NULL) {
2831 return BT_ERROR_ADAPTER_NOT_FOUND;
2834 builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
2836 val = g_variant_new("s", title);
2837 g_variant_builder_add(builder, "{sv}", "xesam:title", val);
2839 val = g_variant_new("s", artist);
2840 g_variant_builder_add(builder, "{sv}", "xesam:artist", val);
2842 val = g_variant_new("s", genre);
2843 g_variant_builder_add(builder, "{sv}", "xesam:genre", val);
2845 val = g_variant_new("s", album);
2846 g_variant_builder_add(builder, "{sv}", "xesam:album", val);
2848 val = g_variant_new("i", track_num);
2849 g_variant_builder_add(builder, "{sv}", "xesam:trackNumber", val);
2851 val = g_variant_new("x", duration);
2852 g_variant_builder_add(builder, "{sv}", "mpris:length", val);
2854 return comms_bluetooth_avrcp_change_track((void *)builder,
2858 int bt_avrcp_target_notify_equalizer_state(bt_avrcp_equalizer_state_e state)
2860 /*bluez-5.X doesn't provide the property*/
2864 int bt_avrcp_target_notify_scan_mode(bt_avrcp_scan_mode_e mode)
2866 /*bluez-5.X doesn't provide the property*/
2870 int bt_avrcp_set_equalizer_state_changed_cb(
2871 bt_avrcp_equalizer_state_changed_cb callback,
2874 /*bluez-5.X doesn't provide the property*/
2878 int bt_avrcp_unset_equalizer_state_changed_cb(void)
2880 /*bluez-5.X doesn't provide the property*/
2884 int bt_avrcp_set_scan_mode_changed_cb(bt_avrcp_scan_mode_changed_cb callback,
2887 /*bluez-5.X doesn't provide the property*/
2891 int bt_avrcp_unset_scan_mode_changed_cb(void)
2893 /*bluez-5.X doesn't provide the property*/
2898 int bt_hid_host_initialize(
2899 bt_hid_host_connection_state_changed_cb connection_cb,
2902 struct hid_host_connection_state_changed_cb_node *node_data;
2907 if (connection_cb == NULL)
2908 return BT_ERROR_INVALID_PARAMETER;
2910 if (hid_host_state_node) {
2911 DBG("hid host connected state changed callback already set.");
2912 return BT_ERROR_ALREADY_DONE;
2915 node_data = g_new0(struct hid_host_connection_state_changed_cb_node, 1);
2916 if (node_data == NULL) {
2918 return BT_ERROR_OUT_OF_MEMORY;
2921 node_data->cb = connection_cb;
2922 node_data->user_data = user_data;
2924 hid_host_state_node = node_data;
2926 dev_property_callback_flags |= DEV_PROP_FLAG_HID_CONNECT;
2928 if (!default_adapter)
2931 list = bluez_adapter_get_devices(default_adapter);
2932 foreach_device_property_callback(list, DEV_PROP_FLAG_HID_CONNECT);
2939 int bt_hid_host_deinitialize(void)
2944 if (initialized == false)
2945 return BT_ERROR_NOT_INITIALIZED;
2947 if (default_adapter == NULL)
2948 return BT_ERROR_ADAPTER_NOT_FOUND;
2950 if (!hid_host_state_node)
2953 dev_property_callback_flags &= ~DEV_PROP_FLAG_HID_CONNECT;
2955 list = bluez_adapter_get_devices(default_adapter);
2956 foreach_device_property_callback(list, DEV_PROP_FLAG_HID_CONNECT);
2958 g_free(hid_host_state_node);
2959 hid_host_state_node = NULL;
2964 static void profile_connect_callback(bluez_device_t *device,
2965 enum device_profile_state state)
2968 case PROFILE_CONNECT_SUCCESS:
2969 DBG("Connect profile: %s", "PROFILE_CONNECT_SUCCESS");
2971 case PROFILE_NOT_EXIST:
2972 DBG("Connect profile: %s", "PROFILE_NOT_EXIST");
2974 case PROFILE_ALREADY_CONNECTED:
2975 DBG("Connect profile: %s", "PROFILE_ALREADY_CONNECTED");
2977 case PROFILE_CONNECT_FAILED:
2978 DBG("Connect profile: %s", "PROFILE_CONNECT_FAILED");
2981 ERROR("Unknown error code");
2986 int bt_hid_host_connect(const char *remote_address)
2988 bluez_device_t *device;
2992 if (initialized == false)
2993 return BT_ERROR_NOT_INITIALIZED;
2995 if (default_adapter == NULL)
2996 return BT_ERROR_ADAPTER_NOT_FOUND;
2998 device = bluez_adapter_get_device_by_address(default_adapter,
3001 return BT_ERROR_OPERATION_FAILED;
3003 bluez_device_connect_profile(device, BT_HID_UUID,
3004 profile_connect_callback);
3009 static void profile_disconnect_callback(bluez_device_t *device,
3010 enum device_profile_state state)
3013 case PROFILE_DISCONNECT_SUCCESS:
3014 DBG("Connect profile: %s", "PROFILE_DISCONNECT_SUCCESS");
3016 case PROFILE_NOT_EXIST:
3017 DBG("Connect profile: %s", "PROFILE_NOT_EXIST");
3019 case PROFILE_NOT_CONNECTED:
3020 DBG("Connect profile: %s", "PROFILE_NOT_CONNECTED");
3022 case PROFILE_NOT_SUPPORTED:
3023 DBG("Connect profile: %s", "PROFILE_NOT_SUPPORTED");
3025 case PROFILE_DISCONNECT_FAILED:
3026 DBG("Connect profile: %s", "PROFILE_DISCONNECT_FAILED");
3029 ERROR("Unknown error code");
3034 int bt_hid_host_disconnect(const char *remote_address)
3036 bluez_device_t *device;
3040 if (initialized == false)
3041 return BT_ERROR_NOT_INITIALIZED;
3043 if (default_adapter == NULL)
3044 return BT_ERROR_ADAPTER_NOT_FOUND;
3046 device = bluez_adapter_get_device_by_address(default_adapter,
3049 return BT_ERROR_OPERATION_FAILED;
3051 bluez_device_disconnect_profile(device, BT_HID_UUID,
3052 profile_disconnect_callback);
3057 struct spp_context {
3059 gchar *remote_address;
3062 GIOChannel *channel;
3063 bt_spp_new_connection_cb new_connection;
3064 void *new_connection_data;
3069 bt_socket_role_e role;
3072 GList *spp_ctx_list;
3074 static GDBusNodeInfo *profile_xml_data;
3076 static struct spp_context *create_spp_context(void)
3078 struct spp_context *spp_ctx, *spp_last;
3081 spp_ctx = g_try_new0(struct spp_context, 1);
3082 if (spp_ctx == NULL) {
3087 if (g_list_length(spp_ctx_list) != 0) {
3088 list = g_list_last(spp_ctx_list);
3089 spp_last = list->data;
3090 spp_ctx->fd = spp_last->fd + 1;
3097 static void free_spp_context(struct spp_context *spp_ctx)
3099 if (spp_ctx == NULL)
3103 g_free(spp_ctx->uuid);
3105 if (spp_ctx->spp_path)
3106 g_free(spp_ctx->spp_path);
3108 if (spp_ctx->remote_address)
3109 g_free(spp_ctx->remote_address);
3114 static struct spp_context *find_spp_context_from_uuid(const char *uuid)
3116 struct spp_context *spp_ctx;
3119 for (list = g_list_first(spp_ctx_list); list; list = next) {
3120 next = g_list_next(list);
3122 spp_ctx = list->data;
3124 if (spp_ctx && !g_strcmp0(spp_ctx->uuid, uuid))
3131 static struct spp_context *find_spp_context_from_socketfd(int socket_fd)
3133 struct spp_context *spp_ctx;
3136 for (list = g_list_first(spp_ctx_list); list; list = next) {
3137 next = g_list_next(list);
3139 spp_ctx = list->data;
3141 if (spp_ctx && (spp_ctx->fd == socket_fd))
3148 static struct spp_context *find_spp_context_from_fd(int fd)
3150 struct spp_context *spp_ctx;
3154 for (list = g_list_first(spp_ctx_list); list; list = next) {
3155 next = g_list_next(list);
3157 spp_ctx = list->data;
3159 spp_fd = g_io_channel_unix_get_fd(spp_ctx->channel);
3161 if (spp_ctx && spp_fd == fd)
3168 /* Agent Function */
3170 static bt_agent *this_agent;
3172 static GDBusNodeInfo *introspection_data;
3174 static const gchar introspection_xml[] =
3176 " <interface name='org.bluez.Agent1'>"
3177 " <method name='Release'>"
3179 " <method name='RequestPinCode'>"
3180 " <arg type='o' name='device' direction='in'/>"
3181 " <arg type='s' direction='out'/>"
3183 " <method name='DisplayPinCode'>"
3184 " <arg type='o' name='device' direction='in'/>"
3185 " <arg type='s' name='pincode' direction='in'/>"
3187 " <method name='RequestPasskey'>"
3188 " <arg type='o' name='device' direction='in'/>"
3189 " <arg type='u' direction='out'/>"
3191 " <method name='RequestConfirmation'>"
3192 " <arg type='o' name='device' direction='in'/>"
3193 " <arg type='u' name='passkey' direction='in'/>"
3195 " <method name='RequestAuthorization'>"
3196 " <arg type='o' name='device' direction='in'/>"
3198 " <method name='AuthorizeService'>"
3199 " <arg type='o' name='device' direction='in'/>"
3200 " <arg type='s' name='uuid' direction='in'/>"
3201 " <arg type='h' name='fd' direction='in'/>"
3203 " <method name='Cancel'>"
3208 static void handle_release(GDBusMethodInvocation *invocation)
3212 g_dbus_method_invocation_return_value(invocation, NULL);
3215 static void handle_display_pincode(const gchar *device_path,
3216 const char *pincode,
3217 GDBusMethodInvocation *invocation)
3220 bluez_device_t *device;
3224 if (default_adapter == NULL) {
3225 ERROR("No default adapter");
3229 device = bluez_adapter_get_device_by_path(default_adapter,
3231 if (device == NULL) {
3232 ERROR("Can't find device %s", device_path);
3236 device_name = bluez_device_get_property_alias(device);
3238 if (this_agent && this_agent->display_pincode)
3239 this_agent->display_pincode(device_name, pincode, invocation);
3241 g_dbus_method_invocation_return_value(invocation, NULL);
3244 static void request_pincode_handler(const gchar *device_path,
3245 GDBusMethodInvocation *invocation)
3248 bluez_device_t *device;
3252 if (default_adapter == NULL) {
3253 ERROR("No default adapter");
3257 device = bluez_adapter_get_device_by_path(default_adapter,
3259 if (device == NULL) {
3260 ERROR("Can't find device %s", device_path);
3264 device_name = bluez_device_get_property_alias(device);
3266 if (this_agent && this_agent->request_pincode)
3267 this_agent->request_pincode(device_name, invocation);
3270 static void request_passkey_handler(const gchar *device_path,
3271 GDBusMethodInvocation *invocation)
3274 bluez_device_t *device;
3278 if (default_adapter == NULL) {
3279 ERROR("No default adapter");
3283 device = bluez_adapter_get_device_by_path(default_adapter,
3285 if (device == NULL) {
3286 ERROR("Can't find device %s", device_path);
3290 device_name = bluez_device_get_property_alias(device);
3292 if (this_agent && this_agent->request_passkey)
3293 this_agent->request_passkey(device_name, invocation);
3296 static void request_confirmation_handler(const gchar *device_path,
3298 GDBusMethodInvocation *invocation)
3301 bluez_device_t *device;
3305 if (default_adapter == NULL) {
3306 ERROR("No default adapter");
3310 device = bluez_adapter_get_device_by_path(default_adapter,
3312 if (device == NULL) {
3313 ERROR("Can't find device %s", device_path);
3317 device_name = bluez_device_get_property_alias(device);
3319 if (this_agent && this_agent->request_confirm)
3320 this_agent->request_confirm(device_name, passkey, invocation);
3323 static void handle_spp_authorize_request(bluez_device_t *device,
3324 struct spp_context *spp_ctx,
3325 GDBusMethodInvocation *invocation)
3327 char *device_name, *device_address;
3329 GUnixFDList *fd_list;
3332 if (spp_ctx->max_pending == 0) {
3333 bt_spp_reject(invocation);
3337 msg = g_dbus_method_invocation_get_message(invocation);
3339 fd_list = g_dbus_message_get_unix_fd_list(msg);
3341 fd = g_unix_fd_list_get(fd_list, (gint)0, NULL);
3343 spp_ctx->channel = g_io_channel_unix_new(fd);
3345 device_name = bluez_device_get_property_alias(device);
3346 device_address = bluez_device_get_property_address(device);
3348 /* New API handler */
3349 if (spp_connection_requested_node)
3350 spp_connection_requested_node->cb(
3351 spp_ctx->uuid, device_name, invocation,
3352 spp_connection_requested_node->user_data);
3354 /* Old API handler */
3355 if (spp_ctx->max_pending <=0) {
3356 bt_spp_reject(invocation);
3360 if (spp_ctx->is_accept) {
3361 bt_spp_accept(invocation);
3365 spp_ctx->requestion = invocation;
3366 spp_ctx->role = BT_SOCKET_SERVER;
3367 spp_ctx->remote_address = g_strdup(device_address);
3369 if (socket_connection_requested_node)
3370 socket_connection_requested_node->cb(
3371 spp_ctx->fd, (const char *)device_address,
3372 socket_connection_requested_node->user_data);
3376 g_free(device_name);
3379 g_free(device_address);
3382 static void request_authorize_service_handler(const gchar *device_path,
3384 GDBusMethodInvocation *invocation)
3386 struct spp_context *spp_ctx;
3388 bluez_device_t *device;
3392 if (default_adapter == NULL) {
3393 ERROR("No default adapter");
3397 device = bluez_adapter_get_device_by_path(default_adapter,
3399 if (device == NULL) {
3400 ERROR("Can't find device %s", device_path);
3404 spp_ctx = find_spp_context_from_uuid(uuid);
3405 if (spp_ctx != NULL) {
3406 handle_spp_authorize_request(device, spp_ctx, invocation);
3410 /* Other profile Authorize request */
3411 if (!this_agent || !this_agent->authorize_service)
3414 device_name = bluez_device_get_property_alias(device);
3416 this_agent->authorize_service(device_name, uuid, invocation);
3418 g_free(device_name);
3421 static void request_authorization_handler(const gchar *device_path,
3422 GDBusMethodInvocation *invocation)
3427 if (!this_agent->cancel)
3430 g_dbus_method_invocation_return_value(invocation, NULL);
3433 static void cancel_handler(GDBusMethodInvocation *invocation)
3438 if (!this_agent->cancel)
3441 this_agent->cancel();
3443 g_dbus_method_invocation_return_value(invocation, NULL);
3446 static void handle_method_call(GDBusConnection *connection,
3447 const gchar *sender,
3448 const gchar *object_path,
3449 const gchar *interface_name,
3450 const gchar *method_name,
3451 GVariant *parameters,
3452 GDBusMethodInvocation *invocation,
3455 if (g_strcmp0(method_name, "Release") == 0) {
3456 handle_release(invocation);
3461 if (g_strcmp0(method_name, "DisplayPinCode") == 0) {
3462 gchar *device_path = NULL, *pincode = NULL;
3463 g_variant_get(parameters, "(os)", &device_path, &pincode);
3465 handle_display_pincode(device_path, pincode, invocation);
3467 g_free(device_path);
3473 if (g_strcmp0(method_name, "RequestPinCode") == 0) {
3474 gchar *device_path = NULL;
3475 g_variant_get(parameters, "(o)", &device_path);
3477 request_pincode_handler(device_path, invocation);
3479 g_free(device_path);
3484 if (g_strcmp0(method_name, "RequestPasskey") == 0) {
3485 gchar *device_path = NULL;
3486 g_variant_get(parameters, "(o)", &device_path);
3488 request_passkey_handler(device_path, invocation);
3490 g_free(device_path);
3495 if (g_strcmp0(method_name, "RequestConfirmation") == 0) {
3496 gchar *device_path = NULL;
3497 guint32 passkey = 0;
3498 g_variant_get(parameters, "(ou)", &device_path, &passkey);
3500 request_confirmation_handler(device_path, passkey, invocation);
3502 g_free(device_path);
3507 if (g_strcmp0(method_name, "AuthorizeService") == 0) {
3508 gchar *device_path, *uuid;
3511 g_variant_get(parameters, "(osh)", &device_path,
3514 request_authorize_service_handler(device_path,
3517 g_free(device_path);
3523 if (g_strcmp0(method_name, "RequestAuthorization") == 0) {
3525 g_variant_get(parameters, "(o)", &device_path);
3527 request_authorization_handler(device_path, invocation);
3529 g_free(device_path);
3534 if (g_strcmp0(method_name, "Cancel") == 0) {
3535 cancel_handler(invocation);
3541 static const GDBusInterfaceVTable interface_handle = {
3548 static void release_dbus_connection(void)
3550 g_object_unref(conn);
3554 static void release_name_on_dbus(const char *name)
3557 guint32 request_name_reply;
3558 GError *error = NULL;
3560 if (bluetooth_agent_id || profile_id)
3563 ret = g_dbus_connection_call_sync(conn,
3564 "org.freedesktop.DBus",
3565 "/org/freedesktop/DBus",
3566 "org.freedesktop.DBus",
3568 g_variant_new("(s)", name),
3569 G_VARIANT_TYPE("(u)"),
3570 G_DBUS_CALL_FLAGS_NONE,
3573 WARN("%s", error->message);
3577 g_variant_get(ret, "(u)", &request_name_reply);
3578 g_variant_unref(ret);
3580 if (request_name_reply != 1) {
3581 WARN("Unexpected reply");
3585 release_dbus_connection();
3590 static GDBusConnection *get_system_dbus_connect(void)
3592 GError *error = NULL;
3597 conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
3599 DBG("%s", error->message);
3601 g_error_free(error);
3607 static int request_name_on_dbus(const char *name)
3609 GDBusConnection *connection;
3611 guint32 request_name_reply;
3612 GError *error = NULL;
3614 if (bluetooth_agent_id || profile_id)
3617 connection = get_system_dbus_connect();
3618 if (connection == NULL)
3621 ret = g_dbus_connection_call_sync(connection,
3622 "org.freedesktop.DBus",
3623 "/org/freedesktop/DBus",
3624 "org.freedesktop.DBus",
3626 g_variant_new("(su)",
3628 G_BUS_NAME_OWNER_FLAGS_NONE),
3629 G_VARIANT_TYPE("(u)"),
3630 G_DBUS_CALL_FLAGS_NONE,
3633 WARN("%s", error->message);
3634 g_error_free(error);
3639 g_variant_get(ret, "(u)", &request_name_reply);
3640 g_variant_unref(ret);
3642 /* RequestName will return the uint32 value:
3643 * 1: DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
3644 * 2: BUS_REQUEST_NAME_REPLY_IN_QUEUE
3645 * 3: DBUS_REQUEST_NAME_REPLY_EXISTS
3646 * 4: DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER
3649 if (request_name_reply != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
3652 release_name_on_dbus(name);
3660 g_object_unref(connection);
3665 static int destory_agent(void)
3667 if (bluetooth_agent_id > 0) {
3668 comms_bluetooth_unregister_pairing_agent(AGENT_OBJECT_PATH,
3671 g_dbus_connection_unregister_object(conn, bluetooth_agent_id);
3673 bluetooth_agent_id = 0;
3675 release_name_on_dbus(BLUEZ_AGENT_SERVICE);
3681 static int create_agent(void)
3685 if (bluetooth_agent_id)
3686 return BT_ERROR_ALREADY_DONE;
3688 introspection_data =
3689 g_dbus_node_info_new_for_xml(introspection_xml, NULL);
3691 ret = request_name_on_dbus(BLUEZ_AGENT_SERVICE);
3695 DBG("%s requested success", BLUEZ_AGENT_SERVICE);
3697 bluetooth_agent_id = g_dbus_connection_register_object(conn,
3699 introspection_data->interfaces[0],
3700 &interface_handle, NULL, NULL, NULL);
3701 if (bluetooth_agent_id == 0)
3704 ret = comms_bluetooth_register_pairing_agent_sync(
3705 AGENT_OBJECT_PATH, NULL);
3706 if (ret != BT_SUCCESS)
3707 return BT_ERROR_OPERATION_FAILED;
3712 int bt_agent_register(bt_agent *agent)
3716 if (initialized == false)
3717 return BT_ERROR_NOT_INITIALIZED;
3720 return BT_ERROR_INVALID_PARAMETER;
3722 if (bluetooth_agent_id > 0)
3723 return BT_ERROR_ALREADY_DONE;
3725 if (this_agent != NULL)
3726 return BT_ERROR_ALREADY_DONE;
3728 ret = create_agent();
3729 if (ret != BT_SUCCESS)
3737 int bt_agent_unregister(void)
3739 if (initialized == false)
3740 return BT_ERROR_NOT_INITIALIZED;
3749 static void bt_agent_simple_accept(GDBusMethodInvocation *invocation)
3751 g_dbus_method_invocation_return_value(invocation, NULL);
3754 static void bt_agent_simple_reject(GDBusMethodInvocation *invocation)
3756 g_dbus_method_invocation_return_dbus_error(invocation,
3757 ERROR_INTERFACE ".Rejected",
3761 void bt_agent_confirm_accept(bt_req_t *requestion)
3763 GDBusMethodInvocation *invocation = requestion;
3765 bt_agent_simple_accept(invocation);
3768 void bt_agent_confirm_reject(bt_req_t *requestion)
3770 GDBusMethodInvocation *invocation = requestion;
3772 bt_agent_simple_reject(invocation);
3775 void bt_agent_pincode_reply(const char *pin_code, bt_req_t *requestion)
3777 GDBusMethodInvocation *invocation = requestion;
3779 g_dbus_method_invocation_return_value(invocation,
3780 g_variant_new("(s)", pin_code));
3783 void bt_agent_pincode_cancel(bt_req_t *requestion)
3785 GDBusMethodInvocation *invocation = requestion;
3787 g_dbus_method_invocation_return_dbus_error(invocation,
3788 ERROR_INTERFACE ".Canceled",
3792 static const gchar profile_xml[] =
3794 " <interface name='org.bluez.Profile1'>"
3795 " <method name='Release'>"
3797 " <method name='NewConnection'>"
3798 " <arg type='o' name='device' direction='in'/>"
3799 " <arg type='h' name='fd' direction='in'/>"
3800 " <arg type='a{sv}' name='opts' direction='in'/>"
3802 " <method name='RequestDisconnection'>"
3803 " <arg type='o' name='device' direction='in'/>"
3808 static gboolean received_data(GIOChannel *channel, GIOCondition con,
3811 bt_spp_received_data spp_data;
3812 struct spp_context *spp_ctx;
3816 spp_ctx = user_data;
3817 if (spp_ctx == NULL) {
3818 WARN("no spp find");
3822 if (!spp_data_received_node)
3825 spp_data.socket_fd = g_io_channel_unix_get_fd(channel);
3826 spp_data.data = g_try_new0(gchar, BT_SPP_BUFFER_MAX);
3828 status = g_io_channel_read_chars(channel, spp_data.data,
3829 BT_SPP_BUFFER_MAX - 1, &rbytes, NULL);
3830 if (status == G_IO_STATUS_ERROR) {
3831 DBG("read channel error");
3835 spp_data.data_size = rbytes;
3837 if (spp_data_received_node->cb)
3838 spp_data_received_node->cb(&spp_data,
3839 spp_data_received_node->user_data);
3841 g_free(spp_data.data);
3847 static void notify_connection_state(gchar *device_path,
3848 bt_socket_connection_state_e state,
3849 struct spp_context *spp_ctx)
3851 bluez_device_t *device;
3852 gchar *device_name, *address;
3855 device = bluez_adapter_get_device_by_path(default_adapter,
3857 if (device == NULL) {
3858 ERROR("Can't find device %s", device_path);
3862 device_name = bluez_device_get_property_alias(device);
3863 address = bluez_device_get_property_address(device);
3865 fd = g_io_channel_unix_get_fd(spp_ctx->channel);
3867 if (spp_ctx->new_connection)
3868 spp_ctx->new_connection(spp_ctx->uuid, device_name,
3869 fd, spp_ctx->new_connection_data);
3871 if (socket_connection_state_node) {
3872 bt_socket_connection_s connection;
3874 connection.socket_fd = fd;
3875 connection.remote_address = address;
3876 connection.service_uuid = spp_ctx->uuid;
3877 connection.local_role = spp_ctx->role;
3879 socket_connection_state_node->cb(
3880 BT_SUCCESS, state, &connection,
3881 socket_connection_state_node->user_data);
3884 g_free(device_name);
3888 static void handle_new_connection(gchar *device_path, gint fd,
3889 GDBusMethodInvocation *invocation,
3892 struct spp_context *spp_ctx;
3893 GIOChannel *channel;
3895 spp_ctx = user_data;
3896 if (spp_ctx == NULL) {
3897 DBG("no spp context");
3901 if (!(spp_ctx->channel)) {
3902 channel = g_io_channel_unix_new(fd);
3903 if (channel == NULL) {
3904 ERROR("Create connection channel error");
3905 g_dbus_method_invocation_return_value(invocation, NULL);
3909 spp_ctx->channel = channel;
3911 channel = spp_ctx->channel;
3913 g_io_channel_set_close_on_unref(channel, TRUE);
3914 g_io_channel_set_encoding(channel, NULL, NULL);
3915 g_io_channel_set_buffered(channel, FALSE);
3917 g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
3918 received_data, user_data);
3921 notify_connection_state(device_path, BT_SOCKET_CONNECTED, spp_ctx);
3923 g_dbus_method_invocation_return_value(invocation, NULL);
3926 static void handle_request_disconnection(gchar *device_path,
3927 GDBusMethodInvocation *invocation,
3930 struct spp_context *spp_ctx = user_data;
3932 DBG("device path %s", device_path);
3934 g_io_channel_unref(spp_ctx->channel);
3935 spp_ctx->channel = NULL;
3937 notify_connection_state(device_path, BT_SOCKET_DISCONNECTED, spp_ctx);
3939 g_dbus_method_invocation_return_value(invocation, NULL);
3942 static void handle_profile_method_call(GDBusConnection *connection,
3943 const gchar *sender,
3944 const gchar *object_path,
3945 const gchar *interface_name,
3946 const gchar *method_name,
3947 GVariant *parameters,
3948 GDBusMethodInvocation *invocation,
3951 if (g_strcmp0(method_name, "Release") == 0)
3952 handle_release(invocation);
3953 else if (g_strcmp0(method_name, "NewConnection") == 0) {
3955 GUnixFDList *fd_list;
3961 g_variant_get(parameters, "(oha{sv})",
3962 &device_path, &fd_index, &opts);
3964 msg = g_dbus_method_invocation_get_message(invocation);
3966 fd_list = g_dbus_message_get_unix_fd_list(msg);
3968 fd = g_unix_fd_list_get(fd_list, fd_index, NULL);
3970 handle_new_connection(device_path, fd, invocation, user_data);
3972 g_free(device_path);
3973 g_variant_iter_free(opts);
3974 } else if (g_strcmp0(method_name, "RequestDisconnection") == 0) {
3977 g_variant_get(parameters, "(o)", &device_path);
3979 handle_request_disconnection(device_path,
3980 invocation, user_data);
3982 g_free(device_path);
3984 DBG("Unknown method name %s", method_name);
3987 static const GDBusInterfaceVTable profile_interface = {
3988 handle_profile_method_call,
3993 static int register_profile_agent(const gchar *path,
3994 struct spp_context *spp_ctx)
4001 ret = request_name_on_dbus(BLUEZ_AGENT_SERVICE);
4005 profile_xml_data = g_dbus_node_info_new_for_xml(profile_xml, NULL);
4007 profile_id = g_dbus_connection_register_object(conn, spp_ctx->spp_path,
4008 profile_xml_data->interfaces[0],
4010 spp_ctx, NULL, NULL);
4012 if (profile_id == 0)
4018 return BT_ERROR_OPERATION_FAILED;
4021 static void unregister_profile_agent(void)
4023 g_dbus_connection_unregister_object(conn, profile_id);
4025 g_dbus_node_info_unref(profile_xml_data);
4030 gchar *generate_object_path_from_uuid(const gchar *prefix, const gchar *uuid)
4034 path = g_strdup_printf("%s/%s", prefix, uuid);
4048 int bt_spp_create_rfcomm(const char *uuid,
4049 bt_spp_new_connection_cb new_connection_cb,
4052 enum bluez_error_type err_type;
4053 struct spp_context *spp_ctx;
4054 GVariantBuilder *opts;
4059 return BT_ERROR_INVALID_PARAMETER;
4061 spp_ctx = create_spp_context();
4062 if (spp_ctx == NULL)
4063 return BT_ERROR_OUT_OF_MEMORY;
4065 path = generate_object_path_from_uuid(SPP_PROFILE_PATH, uuid);
4067 spp_ctx->spp_path = path;
4068 spp_ctx->uuid = g_strdup(uuid);
4069 spp_ctx->new_connection = new_connection_cb;
4070 spp_ctx->new_connection_data = user_data;
4072 ret = register_profile_agent(path, spp_ctx);
4073 if (ret != BT_SUCCESS) {
4074 free_spp_context(spp_ctx);
4078 opts = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
4079 g_variant_builder_add(opts, "{sv}", "Name",
4080 g_variant_new("s", "spp"));
4081 g_variant_builder_add(opts, "{sv}", "Version",
4082 g_variant_new("q", 1));
4084 err_type = bluez_profile_register_profile_sync(path, uuid, opts);
4086 if (err_type == ERROR_INVALID_ARGUMENTS) {
4087 unregister_profile_agent();
4089 release_name_on_dbus(BLUEZ_AGENT_SERVICE);
4091 free_spp_context(spp_ctx);
4093 return BT_ERROR_OPERATION_FAILED;
4096 spp_ctx_list = g_list_append(spp_ctx_list, spp_ctx);
4101 int bt_spp_destroy_rfcomm(const char *uuid)
4103 struct spp_context *spp_ctx;
4106 return BT_ERROR_INVALID_PARAMETER;
4108 spp_ctx = find_spp_context_from_uuid(uuid);
4109 if (spp_ctx == NULL) {
4110 WARN("no specified uuid");
4111 return BT_ERROR_OPERATION_FAILED;
4114 bluez_profile_unregister_profile(spp_ctx->spp_path, NULL, NULL);
4116 unregister_profile_agent();
4118 release_name_on_dbus(BLUEZ_AGENT_SERVICE);
4120 spp_ctx_list = g_list_remove(spp_ctx_list, spp_ctx);
4122 g_io_channel_shutdown(spp_ctx->channel, TRUE, NULL);
4124 g_io_channel_unref(spp_ctx->channel);
4126 free_spp_context(spp_ctx);
4131 int bt_spp_connect_rfcomm(const char *remote_address,
4132 const char *service_uuid)
4134 bluez_device_t *device;
4138 if (!remote_address || !service_uuid)
4139 return BT_ERROR_INVALID_PARAMETER;
4141 if (initialized == false)
4142 return BT_ERROR_NOT_INITIALIZED;
4144 if (default_adapter == NULL)
4145 return BT_ERROR_ADAPTER_NOT_FOUND;
4147 device = bluez_adapter_get_device_by_address(default_adapter,
4150 return BT_ERROR_OPERATION_FAILED;
4152 bluez_device_connect_profile(device, service_uuid,
4153 profile_connect_callback);
4158 int bt_spp_disconnect_rfcomm(const char *remote_address,
4159 const char *service_uuid)
4161 bluez_device_t *device;
4165 if (!remote_address || !service_uuid)
4166 return BT_ERROR_INVALID_PARAMETER;
4168 if (initialized == false)
4169 return BT_ERROR_NOT_INITIALIZED;
4171 if (default_adapter == NULL)
4172 return BT_ERROR_ADAPTER_NOT_FOUND;
4174 device = bluez_adapter_get_device_by_address(default_adapter,
4177 return BT_ERROR_OPERATION_FAILED;
4179 bluez_device_disconnect_profile(device, service_uuid,
4180 profile_disconnect_callback);
4185 int bt_spp_accept(bt_req_t *requestion)
4187 GDBusMethodInvocation *invocation = requestion;
4189 bt_agent_simple_accept(invocation);
4194 int bt_spp_reject(bt_req_t *requestion)
4196 GDBusMethodInvocation *invocation = requestion;
4198 bt_agent_simple_reject(invocation);
4203 int bt_spp_set_connection_requested_cb(bt_spp_connection_requested_cb callback,
4206 struct spp_connection_requested_cb_node *node_data;
4208 if (callback == NULL)
4209 return BT_ERROR_INVALID_PARAMETER;
4211 if (spp_connection_requested_node) {
4212 DBG("spp connection requested callback already set.");
4213 return BT_ERROR_ALREADY_DONE;
4216 node_data = g_new0(struct spp_connection_requested_cb_node, 1);
4217 if (node_data == NULL) {
4219 return BT_ERROR_OUT_OF_MEMORY;
4222 node_data->cb = callback;
4223 node_data->user_data = user_data;
4225 spp_connection_requested_node = node_data;
4230 int bt_spp_unset_connection_requested_cb(void)
4234 if (initialized == false)
4235 return BT_ERROR_NOT_INITIALIZED;
4237 if (default_adapter == NULL)
4238 return BT_ERROR_ADAPTER_NOT_FOUND;
4240 if (!spp_connection_requested_node)
4243 g_free(spp_connection_requested_node);
4244 spp_connection_requested_node = NULL;
4249 int bt_spp_send_data(int fd, const char *data, int length)
4251 struct spp_context *spp_ctx;
4252 gsize written = 0, count = 0;
4256 return BT_ERROR_INVALID_PARAMETER;
4258 spp_ctx = find_spp_context_from_fd(fd);
4259 if (spp_ctx == NULL) {
4260 WARN("no specified fd");
4261 return BT_ERROR_OPERATION_FAILED;
4265 status = g_io_channel_write_chars(spp_ctx->channel, data,
4266 length, &count, NULL);
4270 } while (status != G_IO_STATUS_ERROR && written < length);
4272 if (status == G_IO_STATUS_ERROR)
4273 return BT_ERROR_OPERATION_FAILED;
4278 int bt_spp_set_data_received_cb(bt_spp_data_received_cb callback,
4281 struct spp_data_received_cb_node *node_data;
4283 if (initialized == false)
4284 return BT_ERROR_NOT_INITIALIZED;
4286 if (callback == NULL)
4287 return BT_ERROR_INVALID_PARAMETER;
4289 if (spp_data_received_node) {
4290 DBG("SPP data received callback already set.");
4291 return BT_ERROR_ALREADY_DONE;
4294 node_data = g_new0(struct spp_data_received_cb_node, 1);
4295 if (node_data == NULL) {
4297 return BT_ERROR_OUT_OF_MEMORY;
4300 node_data->cb = callback;
4301 node_data->user_data = user_data;
4303 spp_data_received_node = node_data;
4308 int bt_spp_unset_data_received_cb(void)
4312 if (initialized == false)
4313 return BT_ERROR_NOT_INITIALIZED;
4315 if (!spp_data_received_node)
4318 g_free(spp_data_received_node);
4319 spp_data_received_node = NULL;
4324 int bt_socket_create_rfcomm(const char *service_uuid, int *socket_fd)
4326 struct spp_context *spp_ctx;
4329 if (!service_uuid || !socket_fd)
4330 return BT_ERROR_INVALID_PARAMETER;
4332 ret = bt_spp_create_rfcomm(service_uuid, NULL, NULL);
4333 if (ret != BT_SUCCESS)
4336 spp_ctx = find_spp_context_from_uuid(service_uuid);
4337 if (spp_ctx == NULL)
4338 return BT_ERROR_OPERATION_FAILED;
4340 *socket_fd = spp_ctx->fd;
4345 int bt_socket_destroy_rfcomm(int socket_fd)
4347 struct spp_context *spp_ctx;
4349 spp_ctx = find_spp_context_from_socketfd(socket_fd);
4351 return BT_ERROR_OPERATION_FAILED;
4353 return bt_spp_destroy_rfcomm(spp_ctx->uuid);
4356 int bt_socket_connect_rfcomm(const char *remote_address,
4357 const char *service_uuid)
4359 struct spp_context *spp_ctx;
4362 if (!remote_address || !service_uuid)
4363 return BT_ERROR_INVALID_PARAMETER;
4365 spp_ctx = find_spp_context_from_uuid(service_uuid);
4369 /* BlueZ 5.x should create_rfcomm using a specify UUID,
4370 * then it can connect remote device.
4372 ret = bt_spp_create_rfcomm(service_uuid, NULL, NULL);
4373 if (ret != BT_SUCCESS)
4376 spp_ctx = find_spp_context_from_uuid(service_uuid);
4378 return BT_ERROR_OPERATION_FAILED;
4381 if (!spp_ctx->remote_address) {
4382 spp_ctx->remote_address = g_strdup(remote_address);
4383 spp_ctx->role = BT_SOCKET_CLIENT;
4386 return bt_spp_connect_rfcomm(remote_address, service_uuid);
4389 int bt_socket_disconnect_rfcomm(int socket_fd)
4391 struct spp_context *spp_ctx;
4393 spp_ctx = find_spp_context_from_fd(socket_fd);
4395 return BT_ERROR_OPERATION_FAILED;
4397 return bt_spp_disconnect_rfcomm(spp_ctx->remote_address,
4401 int bt_socket_listen(int socket_fd, int max_pending_connections)
4403 struct spp_context *spp_ctx;
4405 spp_ctx = find_spp_context_from_socketfd(socket_fd);
4406 if (spp_ctx == NULL)
4407 return BT_ERROR_OPERATION_FAILED;
4409 if (max_pending_connections > 0)
4410 spp_ctx->max_pending = max_pending_connections;
4412 spp_ctx->max_pending = -1;
4417 int bt_socket_listen_and_accept_rfcomm(int socket_fd,
4418 int max_pending_connections)
4420 struct spp_context *spp_ctx;
4422 spp_ctx = find_spp_context_from_socketfd(socket_fd);
4423 if (spp_ctx == NULL)
4424 return BT_ERROR_OPERATION_FAILED;
4426 if (max_pending_connections > 0)
4427 spp_ctx->max_pending = max_pending_connections;
4429 spp_ctx->max_pending = -1;
4431 spp_ctx->is_accept = true;
4436 int bt_socket_accept(int requested_socket_fd, int *connected_socket_fd)
4438 struct spp_context *spp_ctx;
4440 if (connected_socket_fd == NULL)
4441 return BT_ERROR_INVALID_PARAMETER;
4443 spp_ctx = find_spp_context_from_socketfd(requested_socket_fd);
4444 if (spp_ctx == NULL)
4445 return BT_ERROR_OPERATION_FAILED;
4447 bt_spp_accept(spp_ctx->requestion);
4449 if (spp_ctx->max_pending > 0)
4450 spp_ctx->max_pending--;
4453 * Note: this connected_socket_fd maybe invalid, because
4454 * connected_socket_fd should return by connection_state_changed,
4456 if (spp_ctx->channel == NULL)
4457 *connected_socket_fd = -1;
4459 *connected_socket_fd =
4460 g_io_channel_unix_get_fd(spp_ctx->channel);
4465 int bt_socket_reject(int socket_fd)
4467 struct spp_context *spp_ctx;
4469 spp_ctx = find_spp_context_from_socketfd(socket_fd);
4470 if (spp_ctx == NULL)
4471 return BT_ERROR_OPERATION_FAILED;
4473 bt_spp_reject(spp_ctx->requestion);
4475 if (spp_ctx->max_pending >= 0)
4476 spp_ctx->max_pending++;
4481 int bt_socket_send_data(int socket_fd, const char *data, int length)
4483 return bt_spp_send_data(socket_fd, data, length);
4486 int bt_socket_set_data_received_cb(bt_socket_data_received_cb callback,
4489 return bt_spp_set_data_received_cb(
4490 (bt_spp_data_received_cb)callback, user_data);
4493 int bt_socket_set_connection_requested_cb(
4494 bt_socket_connection_requested_cb callback,
4497 struct socket_connection_requested_cb_node *node_data;
4499 if (initialized == false)
4500 return BT_ERROR_NOT_INITIALIZED;
4502 if (callback == NULL)
4503 return BT_ERROR_INVALID_PARAMETER;
4505 if (spp_connection_requested_node) {
4506 DBG("socket connection requested callback already set.");
4507 return BT_ERROR_ALREADY_DONE;
4510 node_data = g_new0(struct socket_connection_requested_cb_node, 1);
4511 if (node_data == NULL) {
4513 return BT_ERROR_OUT_OF_MEMORY;
4516 node_data->cb = callback;
4517 node_data->user_data = user_data;
4519 socket_connection_requested_node = node_data;
4524 int bt_socket_set_connection_state_changed_cb(
4525 bt_socket_connection_state_changed_cb callback,
4528 struct socket_connection_state_changed_cb_node *node_data;
4530 if (initialized == false)
4531 return BT_ERROR_NOT_INITIALIZED;
4533 if (callback == NULL)
4534 return BT_ERROR_INVALID_PARAMETER;
4536 if (socket_connection_state_node) {
4537 DBG("socket connection state changed callback already set.");
4538 return BT_ERROR_ALREADY_DONE;
4541 node_data = g_new0(struct socket_connection_state_changed_cb_node, 1);
4542 if (node_data == NULL) {
4544 return BT_ERROR_OUT_OF_MEMORY;
4547 node_data->cb = callback;
4548 node_data->user_data = user_data;
4550 socket_connection_state_node = node_data;
4557 int bt_socket_unset_connection_requested_cb(void)
4559 if (initialized == false)
4560 return BT_ERROR_NOT_INITIALIZED;
4562 if (!socket_connection_requested_node)
4565 g_free(socket_connection_requested_node);
4566 socket_connection_requested_node = NULL;
4571 int bt_socket_unset_data_received_cb(void)
4573 return bt_spp_unset_data_received_cb();
4576 int bt_socket_unset_connection_state_changed_cb(void)
4578 if (initialized == false)
4579 return BT_ERROR_NOT_INITIALIZED;
4581 if (!socket_connection_state_node)
4584 g_free(socket_connection_state_node);
4585 socket_connection_state_node = NULL;
4590 static void address2ident(const char *name, char *ident)
4594 for (index = 0; index < BLUETOOTH_IDENT_LEN; ++index) {
4595 ident[index * 2] = name[index * 3];
4596 ident[index * 2 + 1] = name[index * 3 + 1];
4599 ident[BLUETOOTH_IDENT_LEN * 2] = '\0';
4602 char *get_connman_service_path(const char *adapter_name,
4603 const char *remote_name)
4605 char adapter_ident[BLUETOOTH_IDENT_LEN * 2 + 1] = { 0 };
4606 char remote_ident[BLUETOOTH_IDENT_LEN * 2 + 1] = { 0 };
4610 len = strlen(CONNMAN_BLUETOOTH_SERVICE_PREFIX) +
4611 BLUETOOTH_IDENT_LEN * 4 + 2;
4613 path = calloc(len, sizeof(char));
4617 address2ident(adapter_name, adapter_ident);
4618 address2ident(remote_name, remote_ident);
4620 sprintf(path, "%s%s%s%s", CONNMAN_BLUETOOTH_SERVICE_PREFIX,
4621 adapter_ident, "_", remote_ident);
4626 int bt_panu_connect(const char *remote_address, bt_panu_service_type_e type)
4628 GDBusConnection *connection;
4629 bt_device_info_s *device_bond_info;
4630 char *path, *adapter_address;
4631 bluez_device_t *device;
4633 GError *error = NULL;
4638 if (initialized == false)
4639 return BT_ERROR_NOT_INITIALIZED;
4641 if (default_adapter == NULL)
4642 return BT_ERROR_ADAPTER_NOT_FOUND;
4644 if (!remote_address)
4645 return BT_ERROR_INVALID_PARAMETER;
4647 device = bluez_adapter_get_device_by_address(default_adapter,
4651 return BT_ERROR_OPERATION_FAILED;
4653 device_bond_info = get_device_info(device);
4654 is_bonded = device_bond_info->is_bonded;
4655 free_device_info(device_bond_info);
4657 if (is_bonded == FALSE)
4658 return BT_ERROR_REMOTE_DEVICE_NOT_BONDED;
4660 adapter_address = bluez_adapter_get_property_address(default_adapter);
4661 if (adapter_address == NULL)
4662 return BT_ERROR_OPERATION_FAILED;
4664 path = get_connman_service_path(adapter_address, remote_address);
4666 free(adapter_address);
4667 return BT_ERROR_OPERATION_FAILED;
4670 DBG("path %s", path);
4672 connection = get_system_dbus_connect();
4673 if (connection == NULL) {
4674 ret = BT_ERROR_OPERATION_FAILED;
4678 g_dbus_connection_call_sync(connection, CONNMAN_DBUS_NAME, path,
4679 "net.connman.Service", "Connect",
4680 NULL, NULL, 0, -1, NULL, &error);
4683 DBG("error %s", error->message);
4684 g_error_free(error);
4685 ret = BT_ERROR_OPERATION_FAILED;
4694 free(adapter_address);
4699 int bt_panu_disconnect(const char *remote_address)
4701 GDBusConnection *connection;
4702 char *path, *adapter_address;
4703 bluez_device_t *device;
4705 GError *error = NULL;
4709 if (initialized == false)
4710 return BT_ERROR_NOT_INITIALIZED;
4712 if (default_adapter == NULL)
4713 return BT_ERROR_ADAPTER_NOT_FOUND;
4715 if (!remote_address)
4716 return BT_ERROR_INVALID_PARAMETER;
4718 device = bluez_adapter_get_device_by_address(default_adapter,
4722 return BT_ERROR_OPERATION_FAILED;
4724 bluez_device_network_get_property_connected(device, &connected);
4725 if (connected == FALSE)
4726 return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED;
4728 adapter_address = bluez_adapter_get_property_address(default_adapter);
4729 if (adapter_address == NULL)
4730 return BT_ERROR_OPERATION_FAILED;
4732 path = get_connman_service_path(adapter_address, remote_address);
4734 free(adapter_address);
4735 return BT_ERROR_OPERATION_FAILED;
4738 DBG("path %s", path);
4740 connection = get_system_dbus_connect();
4741 if (connection == NULL) {
4742 ret = BT_ERROR_OPERATION_FAILED;
4746 g_dbus_connection_call_sync(connection, CONNMAN_DBUS_NAME, path,
4747 "net.connman.Service", "Disconnect",
4748 NULL, NULL, 0, -1, NULL, &error);
4751 DBG("error %s", error->message);
4752 g_error_free(error);
4753 ret = BT_ERROR_OPERATION_FAILED;
4762 free(adapter_address);
4767 int bt_panu_set_connection_state_changed_cb(
4768 bt_panu_connection_state_changed_cb callback,
4771 struct panu_connection_state_changed_cb_node *node_data;
4776 if (callback == NULL)
4777 return BT_ERROR_INVALID_PARAMETER;
4779 if (panu_state_node) {
4780 DBG("network connected state changed callback already set.");
4781 return BT_ERROR_ALREADY_DONE;
4784 node_data = g_new0(struct panu_connection_state_changed_cb_node, 1);
4785 if (node_data == NULL) {
4787 return BT_ERROR_OUT_OF_MEMORY;
4790 node_data->cb = callback;
4791 node_data->user_data = user_data;
4793 panu_state_node = node_data;
4795 dev_property_callback_flags |= DEV_PROP_FLAG_PANU_CONNECT;
4797 if (!default_adapter)
4800 list = bluez_adapter_get_devices(default_adapter);
4801 foreach_device_property_callback(list, DEV_PROP_FLAG_PANU_CONNECT);
4808 int bt_panu_unset_connection_state_changed_cb(void)
4813 if (initialized == false)
4814 return BT_ERROR_NOT_INITIALIZED;
4816 if (default_adapter == NULL)
4817 return BT_ERROR_ADAPTER_NOT_FOUND;
4819 if (!panu_state_node)
4822 dev_property_callback_flags &= ~DEV_PROP_FLAG_PANU_CONNECT;
4824 list = bluez_adapter_get_devices(default_adapter);
4825 foreach_device_property_callback(list, DEV_PROP_FLAG_PANU_CONNECT);
4827 g_free(panu_state_node);
4828 panu_state_node = NULL;
4833 static int connman_set_tethering(bool tethering)
4835 GDBusConnection *connection;
4836 GVariant *tethering_val;
4837 GError *error = NULL;
4839 if (initialized == false)
4840 return BT_ERROR_NOT_INITIALIZED;
4842 if (default_adapter == NULL)
4843 return BT_ERROR_ADAPTER_NOT_FOUND;
4845 connection = get_system_dbus_connect();
4846 if (connection == NULL)
4847 return BT_ERROR_OPERATION_FAILED;
4849 tethering_val = g_variant_new("b", tethering);
4851 g_dbus_connection_call_sync(connection, CONNMAN_DBUS_NAME,
4852 CONNMAN_BLUETOOTH_TECHNOLOGY_PATH,
4853 CONNMAN_BLUETOTOH_TECHNOLOGY_INTERFACE,
4855 g_variant_new("(sv)",
4856 "Tethering", tethering_val),
4857 NULL, 0, -1, NULL, &error);
4860 DBG("error %s", error->message);
4861 g_error_free(error);
4862 return BT_ERROR_OPERATION_FAILED;
4868 int bt_nap_activate(void)
4870 return connman_set_tethering(true);
4873 int bt_nap_deactivate(void)
4875 return connman_set_tethering(false);
4878 int bt_hdp_register_sink_app(unsigned short data_type, char **app_id)
4880 int result = BT_ERROR_NONE;
4884 if (initialized == false)
4885 return BT_ERROR_NOT_INITIALIZED;
4887 if (default_adapter == NULL)
4888 return BT_ERROR_ADAPTER_NOT_FOUND;
4890 result = bluetooth_hdp_activate(data_type,
4891 HDP_ROLE_SINK, HDP_QOS_ANY, app_id);
4895 int bt_hdp_unregister_sink_app(const char *app_id)
4897 int result = BT_ERROR_NONE;
4901 if (initialized == false)
4902 return BT_ERROR_NOT_INITIALIZED;
4904 if (default_adapter == NULL)
4905 return BT_ERROR_ADAPTER_NOT_FOUND;
4907 result = bluetooth_hdp_deactivate(app_id);
4912 int bt_hdp_send_data(unsigned int channel, const char *data,
4915 int result = BT_ERROR_NONE;
4919 if (initialized == false)
4920 return BT_ERROR_NOT_INITIALIZED;
4922 if (default_adapter == NULL)
4923 return BT_ERROR_ADAPTER_NOT_FOUND;
4925 result = bluetooth_hdp_send_data(channel, data, size);
4930 int bt_hdp_connect_to_source(const char *remote_address,
4933 int result = BT_ERROR_NONE;
4934 bluetooth_device_address_t addr_hex = { {0,} };
4938 if (initialized == false)
4939 return BT_ERROR_NOT_INITIALIZED;
4941 if (default_adapter == NULL)
4942 return BT_ERROR_ADAPTER_NOT_FOUND;
4944 if (remote_address == NULL)
4945 return BT_ERROR_INVALID_PARAMETER;
4947 convert_address_to_hex(&addr_hex, remote_address);
4949 result = bluetooth_hdp_connect(app_id, HDP_QOS_ANY, &addr_hex);
4954 int bt_hdp_disconnect(const char *remote_address, unsigned int channel)
4956 int result = BT_ERROR_NONE;
4957 bluetooth_device_address_t addr_hex = { {0,} };
4961 if (initialized == false)
4962 return BT_ERROR_NOT_INITIALIZED;
4964 if (default_adapter == NULL)
4965 return BT_ERROR_ADAPTER_NOT_FOUND;
4967 if (remote_address == NULL)
4968 return BT_ERROR_INVALID_PARAMETER;
4970 convert_address_to_hex(&addr_hex, remote_address);
4972 result = bluetooth_hdp_disconnect(channel, &addr_hex);
4977 int bt_hdp_set_connection_state_changed_cb(bt_hdp_connected_cb connected_cb,
4978 bt_hdp_disconnected_cb disconnected_cb, void *user_data)
4980 struct hdp_connection_changed_cb_node *node_data = NULL;
4983 if (connected_cb == NULL || disconnected_cb == NULL)
4984 return BT_ERROR_INVALID_PARAMETER;
4986 if (hdp_state_node) {
4987 DBG("hdp state callback already set.");
4988 return BT_ERROR_ALREADY_DONE;
4991 node_data = g_new0(struct hdp_connection_changed_cb_node, 1);
4992 if (node_data == NULL) {
4994 return BT_ERROR_OUT_OF_MEMORY;
4997 node_data->conn_cb = connected_cb;
4998 node_data->disconn_cb = disconnected_cb;
4999 node_data->user_data = user_data;
5001 hdp_state_node = node_data;
5003 dev_property_callback_flags |= DEV_PROP_FLAG_HDP_CONNECT;
5005 if (!default_adapter)
5008 list = bluez_adapter_get_devices(default_adapter);
5009 foreach_device_property_callback(list, DEV_PROP_FLAG_HDP_CONNECT);
5016 int bt_hdp_unset_connection_state_changed_cb(void)
5022 if (initialized == false)
5023 return BT_ERROR_NOT_INITIALIZED;
5025 if (!hdp_state_node)
5028 dev_property_callback_flags &= ~DEV_PROP_FLAG_HDP_CONNECT;
5030 list = bluez_adapter_get_devices(default_adapter);
5031 foreach_device_property_callback(list, DEV_PROP_FLAG_HDP_CONNECT);
5033 g_free(hdp_state_node);
5034 hdp_state_node = NULL;
5039 int bt_hdp_set_data_received_cb(bt_hdp_data_received_cb callback,
5042 struct hdp_set_data_received_cb_node *node_data = NULL;
5047 if (callback == NULL)
5048 return BT_ERROR_INVALID_PARAMETER;
5050 if (hdp_set_data_received_node) {
5051 DBG("hdp set data receive dnode callback already set.");
5052 return BT_ERROR_ALREADY_DONE;
5055 node_data = g_new0(struct hdp_set_data_received_cb_node, 1);
5056 if (node_data == NULL) {
5058 return BT_ERROR_OUT_OF_MEMORY;
5061 node_data->cb = callback;
5062 node_data->user_data = user_data;
5064 hdp_set_data_received_node = node_data;
5066 dev_property_callback_flags |= DEV_PROP_FLAG_HDP_DATA;
5068 if (!default_adapter)
5071 list = bluez_adapter_get_devices(default_adapter);
5072 foreach_device_property_callback(list, DEV_PROP_FLAG_HDP_DATA);
5079 int bt_hdp_unset_data_received_cb(void)
5085 if (initialized == false)
5086 return BT_ERROR_NOT_INITIALIZED;
5088 if (!hdp_set_data_received_node)
5091 dev_property_callback_flags &= ~DEV_PROP_FLAG_HDP_DATA;
5093 list = bluez_adapter_get_devices(default_adapter);
5094 foreach_device_property_callback(list, DEV_PROP_FLAG_HDP_DATA);
5096 g_free(hdp_set_data_received_node);
5097 hdp_set_data_received_node = NULL;
5102 int bt_device_connect_le(bt_device_gatt_state_changed_cb callback,
5103 const char *remote_address)
5105 bluez_device_t *device;
5107 struct device_connect_cb_node *node_data = NULL;
5111 if (initialized == false)
5112 return BT_ERROR_NOT_INITIALIZED;
5114 if (default_adapter == NULL)
5115 return BT_ERROR_ADAPTER_NOT_FOUND;
5117 if (callback == NULL)
5118 return BT_ERROR_INVALID_PARAMETER;
5120 device = bluez_adapter_get_device_by_address(default_adapter,
5123 return BT_ERROR_OPERATION_FAILED;
5125 if (device_connect_node) {
5126 DBG("device disconnect callback already set.");
5127 return BT_ERROR_ALREADY_DONE;
5131 g_new0(struct device_connect_cb_node, 1);
5132 if (node_data == NULL) {
5134 return BT_ERROR_OUT_OF_MEMORY;
5137 node_data->cb = callback;
5138 node_data->user_data = NULL;
5140 device_connect_node = node_data;
5142 _bt_update_bluetooth_callbacks();
5144 bluez_device_connect_le(device);
5149 int bt_device_disconnect_le(bt_device_gatt_state_changed_cb callback,
5150 const char *remote_address)
5152 bluez_device_t *device;
5154 struct device_disconnect_cb_node *node_data = NULL;
5158 if (initialized == false)
5159 return BT_ERROR_NOT_INITIALIZED;
5161 if (default_adapter == NULL)
5162 return BT_ERROR_ADAPTER_NOT_FOUND;
5164 if (callback == NULL)
5165 return BT_ERROR_INVALID_PARAMETER;
5167 device = bluez_adapter_get_device_by_address(default_adapter,
5170 return BT_ERROR_OPERATION_FAILED;
5172 if (device_disconnect_node) {
5173 DBG("device disconnect callback already set.");
5174 return BT_ERROR_ALREADY_DONE;
5178 g_new0(struct device_disconnect_cb_node, 1);
5179 if (node_data == NULL) {
5181 return BT_ERROR_OUT_OF_MEMORY;
5184 node_data->cb = callback;
5185 node_data->user_data = NULL;
5187 device_disconnect_node = node_data;
5189 _bt_update_bluetooth_callbacks();
5191 bluez_device_disconnect_le(device);
5196 int bt_nap_set_connection_state_changed_cb(
5197 bt_nap_connection_state_changed_cb callback,
5200 struct nap_connection_state_changed_cb_node *node_data;
5204 if (callback == NULL)
5205 return BT_ERROR_INVALID_PARAMETER;
5207 if (nap_connection_state_changed_node) {
5208 DBG("Powered state changed callback already set.");
5209 return BT_ERROR_ALREADY_DONE;
5212 node_data = g_new0(struct nap_connection_state_changed_cb_node, 1);
5213 if (node_data == NULL) {
5215 return BT_ERROR_OUT_OF_MEMORY;
5218 node_data->cb = callback;
5219 node_data->user_data = user_data;
5221 nap_connection_state_changed_node = node_data;
5223 _bt_update_bluetooth_callbacks();
5228 int bt_nap_unset_connection_state_changed_cb(void)
5232 if (initialized == false)
5233 return BT_ERROR_NOT_INITIALIZED;
5235 if (default_adapter == NULL)
5236 return BT_ERROR_ADAPTER_NOT_FOUND;
5238 if (!adapter_name_node)
5241 bluez_unset_nap_connection_state_cb();
5243 g_free(nap_connection_state_changed_node);
5244 nap_connection_state_changed_node = NULL;
5249 static gboolean spp_is_device_connected(const char *address)
5251 struct spp_context *spp_ctx;
5256 for (list = g_list_first(spp_ctx_list); list; list = next) {
5257 next = g_list_next(list);
5259 spp_ctx = list->data;
5261 if (spp_ctx->channel &&
5262 g_strcmp0(spp_ctx->remote_address,
5270 int bt_device_foreach_connected_profiles(
5271 const char *remote_address,
5272 bt_device_connected_profile callback,
5275 bluez_device_t *device;
5276 bt_device_info_s *device_info;
5277 gboolean rfcomm_connected;
5279 gboolean hid_connected = false;
5283 if (initialized == false)
5284 return BT_ERROR_NOT_INITIALIZED;
5286 if (default_adapter == NULL)
5287 return BT_ERROR_ADAPTER_NOT_FOUND;
5289 if (!remote_address || !callback)
5290 return BT_ERROR_INVALID_PARAMETER;
5292 device = bluez_adapter_get_device_by_address(default_adapter,
5295 return BT_ERROR_OPERATION_FAILED;
5297 device_info = get_device_info(device);
5299 if (device_info->is_connected == false)
5300 return BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED;
5302 rfcomm_connected = spp_is_device_connected(remote_address);
5303 if (rfcomm_connected)
5304 callback(BT_PROFILE_RFCOMM, user_data);
5306 is_type = bluez_get_media_type(remote_address);
5308 /*not check hfp and hsp connected, hfp is not ready*/
5309 /*todo hfp and hsp checking*/
5312 callback(BT_PROFILE_A2DP, user_data);
5314 if (!(bluez_device_input_get_property_connected(device,
5317 callback(BT_PROFILE_HID, user_data);
5320 free_device_info(device_info);