1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * BlueZ - Bluetooth protocol stack for Linux
6 * Copyright (C) 2006-2010 Nokia Corporation
7 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
26 #include <dbus/dbus.h>
28 #include "lib/bluetooth.h"
30 #include "lib/sdp_lib.h"
33 #include "gdbus/gdbus.h"
36 #include "src/shared/util.h"
37 #include "src/shared/att.h"
38 #include "src/shared/queue.h"
39 #include "src/shared/gatt-db.h"
40 #include "src/shared/gatt-client.h"
41 #include "src/shared/gatt-server.h"
42 #include "src/shared/ad.h"
43 #include "src/shared/timeout.h"
44 #include "btio/btio.h"
46 #include "attrib/att.h"
49 #include "gatt-database.h"
50 #include "attrib/gattrib.h"
52 #include "gatt-client.h"
55 #include "dbus-common.h"
57 #include "uuid-helper.h"
58 #include "sdp-client.h"
59 #include "attrib/gatt.h"
63 #include "attrib-server.h"
66 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
68 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
69 #include <sys/ioctl.h>
70 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
73 #define DISCONNECT_TIMER 2
74 #define DISCOVERY_TIMER 1
75 #define INVALID_FLAGS 0xff
78 #define MIN(a, b) ((a) < (b) ? (a) : (b))
81 #define RSSI_THRESHOLD 8
83 #define GATT_PRIM_SVC_UUID_STR "2800"
84 #define GATT_SND_SVC_UUID_STR "2801"
85 #define GATT_INCLUDE_UUID_STR "2802"
86 #define GATT_CHARAC_UUID_STR "2803"
88 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
89 #define DEV_MAX_MANUFACTURER_DATA_LEN 248
92 static DBusConnection *dbus_conn = NULL;
93 static unsigned service_state_cb_id;
95 struct btd_disconnect_data {
97 disconnect_watch watch;
99 GDestroyNotify destroy;
105 struct btd_device *device;
108 struct btd_adapter_pin_cb_iter *cb_iter;
111 struct timespec attempt_start_time;
112 long last_attempt_duration_ms;
119 AUTH_TYPE_NOTIFY_PASSKEY,
120 AUTH_TYPE_NOTIFY_PINCODE,
123 struct authentication_req {
126 struct btd_device *device;
140 struct btd_device *device;
143 GSList *profiles_added;
146 int reconnect_attempt;
151 struct included_search {
152 struct browse_req *req;
157 struct svc_callback {
160 struct btd_device *dev;
161 device_svc_cb_t func;
165 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
166 struct le_adv_report_info {
168 char manufacturer_data[DEV_MAX_MANUFACTURER_DATA_LEN];
169 uint8_t manufacturer_data_len;
173 /* Per-bearer (LE or BR/EDR) device state */
174 struct bearer_state {
187 WAKE_FLAG_DEFAULT = 0,
193 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
196 DEV_PAIRED_BREDR = 1,
202 DEV_CONNECTED_NONE = 0,
203 DEV_CONNECTED_BREDR = 1,
205 DEV_CONNECTED_BREDR_LE,
206 } dev_connected_state;
208 struct trusted_profile_t {
220 bdaddr_t conn_bdaddr;
221 uint8_t conn_bdaddr_type;
227 bool pending_paired; /* "Paired" waiting for SDP */
229 bool refresh_discovery;
231 /* Manage whether this device can wake the system from suspend.
232 * - wake_support: Requires a profile that supports wake (i.e. HID)
233 * - wake_allowed: Is wake currently allowed?
234 * - pending_wake_allowed - Wake flag sent via set_device_flags
235 * - wake_override - User configured wake setting
239 bool pending_wake_allowed;
240 uint8_t wake_override;
241 GDBusPendingPropertySet wake_id;
243 uint32_t supported_flags;
244 uint32_t current_flags;
245 GSList *svc_callbacks;
249 char name[MAX_NAME_LENGTH + 1];
258 struct btd_adapter *adapter;
260 GSList *primaries; /* List of primary services */
261 GSList *services; /* List of btd_service */
262 GSList *pending; /* Pending services */
263 GSList *watches; /* List of disconnect_data */
266 unsigned int disconn_timer;
267 unsigned int discov_timer;
268 unsigned int temporary_timer; /* Temporary/disappear timer */
269 struct browse_req *browse; /* service discover request */
270 struct bonding_req *bonding;
271 struct authentication_req *authr; /* authentication request */
272 GSList *disconnects; /* disconnects message */
273 DBusMessage *connect; /* connect message */
274 DBusMessage *disconnect; /* disconnect message */
277 struct bt_att *att; /* The new ATT transport */
278 uint16_t att_mtu; /* The ATT MTU */
279 unsigned int att_disconn_id;
282 * TODO: For now, device creates and owns the client-role gatt_db, but
283 * this needs to be persisted in a more central place so that proper
284 * attribute cache support can be built.
286 struct gatt_db *db; /* GATT db cache */
288 struct bt_gatt_client *client; /* GATT client instance */
289 struct bt_gatt_server *server; /* GATT server instance */
290 unsigned int gatt_ready_id;
292 struct btd_gatt_client *client_dbus;
294 struct bearer_state bredr_state;
295 struct bearer_state le_state;
297 struct csrk_info *local_csrk;
298 struct csrk_info *remote_csrk;
299 uint8_t ltk_enc_size;
301 sdp_list_t *tmp_records;
307 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
308 struct trusted_profile_t trusted_profiles;
311 gboolean auto_connect;
312 gboolean disable_auto_connect;
313 gboolean general_connect;
321 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
323 char *manufacturer_data;
324 int manufacturer_data_len;
325 struct le_adv_report_info le_adv_data;
326 int remote_feature_flags;
328 gboolean gatt_connected;
329 uint16_t auth_payload_timeout;
331 uint8_t last_bdaddr_type;
332 uint8_t auth_bdaddr_type;
333 gboolean ipsp_connected; /* IPSP Connection state */
334 char if_name[16 + 1]; /* BT interface UP after IPSP connection */
335 uint8_t rpa_res_support; /* RPA Resolution capability of device */
336 uint16_t max_tx_octets;
337 uint16_t max_tx_time;
338 uint16_t max_rx_octets;
339 uint16_t max_rx_time;
341 DBusMessage *req_att_mtu; /* Attribute MTU request message */
343 bool pending_conn_update;
348 static const uint16_t uuid_list[] = {
355 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
357 SHOW_AUTHORIZATION = 0x0, /* 0b00 */
358 SUPPORTED_BLOCKED = 0x1, /* 0b01 */
359 SUPPORTED_TRUSTED= 0x2, /* 0b10 */
360 } bt_profile_trusted_states;
362 #define PBAP_SHIFT_OFFSET 0
363 #define MAP_SHIFT_OFFSET 2
364 #define SAP_SHIFT_OFFSET 4
365 #define HFP_HS_SHIFT_OFFSET 6
366 #define A2DP_SHIFT_OFFSET 8
368 #define PROFILE_SUPPORTED 0x3 /* This corresponds to binary 0b11*/
372 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
373 #define OTP_PSM 0x0025
376 #define BT_OTC_SERVICE_NAME "org.otp.client"
377 #define BT_OTC_OBJECT_PATH "/org/otp/client"
378 #define BT_OTC_INTERFACE_NAME "org.otp.otc_channel"
381 #define BT_OTS_SERVICE_NAME "org.projectx.otp"
382 #define BT_OTS_OBJECT_PATH "/org/projectx/otp"
383 #define BT_OTS_INTERFACE_NAME "org.projectx.otp_service"
386 BT_OTP_CLIENT_ROLE = 0x00,
390 struct otc_conn_info {
391 const char *dev_path;
397 GSList *otc_connection_list = NULL;
400 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
401 #define BT_L2CAP_LE_INTERFACE_NAME "org.bluez.l2cap_le"
402 #define BTD_L2CAP_LE_PSM_MAX 0xFFFF
406 BT_L2CAP_LE_CLIENT_ROLE = 0x00,
407 BT_L2CAP_LE_SERVER_ROLE,
408 } bt_l2cap_le_role_e;
410 struct l2cap_le_conn_info {
411 struct l2cap_le_profile_info *profile_info;
415 const char *dev_path;
421 struct l2cap_le_profile_info {
425 bt_l2cap_le_role_e role;
427 BtIOSecLevel sec_level;
430 struct l2cap_le_conn_info *server;
434 GSList *l2cap_le_socket_list = NULL;
438 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg);
439 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg);
441 static struct bearer_state *get_state(struct btd_device *dev,
444 if (bdaddr_type == BDADDR_BREDR)
445 return &dev->bredr_state;
447 return &dev->le_state;
450 static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
454 for (l = list; l != NULL; l = g_slist_next(l)) {
455 struct btd_service *service = l->data;
457 if (btd_service_get_profile(service) == p)
464 static GSList *find_service_with_state(GSList *list,
465 btd_service_state_t state)
469 for (l = list; l != NULL; l = g_slist_next(l)) {
470 struct btd_service *service = l->data;
472 if (btd_service_get_state(service) == state)
479 static GSList *find_service_with_uuid(GSList *list, char *uuid)
483 for (l = list; l != NULL; l = g_slist_next(l)) {
484 struct btd_service *service = l->data;
485 struct btd_profile *profile = btd_service_get_profile(service);
487 if (bt_uuid_strcmp(profile->remote_uuid, uuid) == 0)
494 static void update_technologies(GKeyFile *file, struct btd_device *dev)
500 list[len++] = "BR/EDR";
505 if (dev->bdaddr_type == BDADDR_LE_PUBLIC)
510 g_key_file_set_string(file, "General", "AddressType", type);
515 g_key_file_set_string_list(file, "General", "SupportedTechnologies",
519 static void store_csrk(struct csrk_info *csrk, GKeyFile *key_file,
525 for (i = 0; i < 16; i++)
526 sprintf(key + (i * 2), "%2.2X", csrk->key[i]);
528 g_key_file_set_string(key_file, group, "Key", key);
529 g_key_file_set_integer(key_file, group, "Counter", csrk->counter);
532 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
533 static char *manufacturer_data2str(char *data, int size)
535 char str[DEV_MAX_MANUFACTURER_DATA_LEN * 3 + 1];
540 for(i = 0; i < size; i++) {
541 snprintf(tmp, sizeof(tmp), "%d ", data[i]);
542 g_strlcat(str, tmp, sizeof(str));
545 return g_strdup(str);
548 static void load_manufacturer_data_2digit(char *data, int len, char *buf)
553 split = g_strsplit(data, " ", 0);
555 for (i = 0; i < len; i++) {
556 if (split[i] == NULL)
559 buf[i] = (char)g_ascii_strtoull(split[i], NULL, 10);
568 static gboolean store_device_info_cb(gpointer user_data)
570 struct btd_device *device = user_data;
573 char filename[PATH_MAX];
574 char device_addr[18];
579 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
580 gboolean svc_change_regd = false;
583 device->store_id = 0;
585 ba2str(&device->bdaddr, device_addr);
587 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
589 ba2str(device->rpa, device_addr);
591 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
592 btd_adapter_get_storage_dir(device->adapter),
594 create_file(filename, 0600);
596 key_file = g_key_file_new();
597 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
598 error("Unable to load key file from %s: (%s)", filename,
601 g_key_file_free(key_file);
605 g_key_file_set_string(key_file, "General", "Name", device->name);
607 if (device->alias != NULL)
608 g_key_file_set_string(key_file, "General", "Alias",
611 g_key_file_remove_key(key_file, "General", "Alias", NULL);
614 sprintf(class, "0x%6.6x", device->class & 0xffffff);
615 g_key_file_set_string(key_file, "General", "Class", class);
617 g_key_file_remove_key(key_file, "General", "Class", NULL);
620 if (device->appearance) {
621 sprintf(class, "0x%4.4x", device->appearance);
622 g_key_file_set_string(key_file, "General", "Appearance", class);
624 g_key_file_remove_key(key_file, "General", "Appearance", NULL);
627 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
628 if (device->rpa_res_support) {
629 g_key_file_set_integer(key_file, "General", "RPAResSupport",
630 device->rpa_res_support);
632 g_key_file_remove_key(key_file, "General", "RPAResSupport", NULL);
636 update_technologies(key_file, device);
638 g_key_file_set_boolean(key_file, "General", "Trusted",
640 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
641 struct trusted_profile_t trust_profile = device->trusted_profiles;
642 int trusted_profiles = (trust_profile.pbap << PBAP_SHIFT_OFFSET) |
643 (trust_profile.map << MAP_SHIFT_OFFSET) |
644 (trust_profile.sap << SAP_SHIFT_OFFSET) |
645 (trust_profile.hfp_hs << HFP_HS_SHIFT_OFFSET) |
646 (trust_profile.a2dp << A2DP_SHIFT_OFFSET);
647 DBG("Storing TrustedProfiles %d", trusted_profiles);
648 g_key_file_set_integer(key_file, "General", "TrustedProfiles",
651 g_key_file_set_boolean(key_file, "General", "Blocked",
654 if (device->wake_override != WAKE_FLAG_DEFAULT) {
655 g_key_file_set_boolean(key_file, "General", "WakeAllowed",
656 device->wake_override ==
664 uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
665 for (i = 0, l = device->uuids; l; l = g_slist_next(l), i++)
667 g_key_file_set_string_list(key_file, "General", "Services",
668 (const char **)uuids, i);
670 g_key_file_remove_key(key_file, "General", "Services", NULL);
673 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
674 if (device->le_adv_data.flags) {
675 g_key_file_set_integer(key_file, "General", "Flags",
676 device->le_adv_data.flags);
678 g_key_file_remove_key(key_file, "General", "Flags", NULL);
681 if (device->manufacturer_data) {
682 str = manufacturer_data2str(device->manufacturer_data,
683 device->manufacturer_data_len);
684 g_key_file_set_string(key_file, "General",
685 "LegacyManufacturerData",
688 g_key_file_set_integer(key_file, "General",
689 "LegacyManufacturerDataLen",
690 device->manufacturer_data_len);
692 g_key_file_remove_key(key_file, "General",
693 "LegacyManufacturerData", NULL);
694 g_key_file_remove_key(key_file, "General",
695 "LegacyManufacturerDataLen", NULL);
701 ba2str(&device->bdaddr, irk_addr);
702 g_key_file_set_string(key_file, "General", "IdentityAddress",
705 g_key_file_remove_key(key_file, "General", "IdentityAddress",
710 if (device->vendor_src) {
711 g_key_file_set_integer(key_file, "DeviceID", "Source",
713 g_key_file_set_integer(key_file, "DeviceID", "Vendor",
715 g_key_file_set_integer(key_file, "DeviceID", "Product",
717 g_key_file_set_integer(key_file, "DeviceID", "Version",
720 g_key_file_remove_group(key_file, "DeviceID", NULL);
723 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
724 svc_change_regd = bt_att_get_svc_changed_indication_registered(device->att);
725 g_key_file_set_boolean(key_file, "Att", "SvcChangeRegd",
729 if (device->local_csrk)
730 store_csrk(device->local_csrk, key_file, "LocalSignatureKey");
732 if (device->remote_csrk)
733 store_csrk(device->remote_csrk, key_file, "RemoteSignatureKey");
735 str = g_key_file_to_data(key_file, &length, NULL);
736 if (!g_file_set_contents(filename, str, length, &gerr)) {
737 error("Unable set contents for %s: (%s)", filename,
744 g_key_file_free(key_file);
750 static bool device_address_is_private(struct btd_device *dev)
752 if (dev->bdaddr_type != BDADDR_LE_RANDOM)
755 switch (dev->bdaddr.b[5] >> 6) {
756 case 0x00: /* Private non-resolvable */
757 case 0x01: /* Private resolvable */
764 static void store_device_info(struct btd_device *device)
766 if (device->temporary || device->store_id > 0)
769 if (device_address_is_private(device)) {
770 DBG("Can't store info for private addressed device %s",
775 device->store_id = g_idle_add(store_device_info_cb, device);
778 void device_store_cached_name(struct btd_device *dev, const char *name)
780 char filename[PATH_MAX];
787 gsize length_old = 0;
789 if (device_address_is_private(dev)) {
790 DBG("Can't store name for private addressed device %s",
795 ba2str(&dev->bdaddr, d_addr);
797 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
799 ba2str(dev->rpa, d_addr);
802 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
803 btd_adapter_get_storage_dir(dev->adapter), d_addr);
804 create_file(filename, 0600);
806 key_file = g_key_file_new();
807 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
808 error("Unable to load key file from %s: (%s)", filename,
813 data_old = g_key_file_to_data(key_file, &length_old, NULL);
815 g_key_file_set_string(key_file, "General", "Name", name);
817 data = g_key_file_to_data(key_file, &length, NULL);
819 if ((length != length_old) || (memcmp(data, data_old, length))) {
820 if (!g_file_set_contents(filename, data, length, &gerr)) {
821 error("Unable set contents for %s: (%s)", filename,
829 g_key_file_free(key_file);
832 static void browse_request_free(struct browse_req *req)
834 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
837 struct btd_device *device = req->device;
839 if (device->browse == req)
840 device->browse = NULL;
842 if (req->listener_id)
843 g_dbus_remove_watch(dbus_conn, req->listener_id);
845 dbus_message_unref(req->msg);
846 g_slist_free_full(req->profiles_added, g_free);
848 sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
853 static bool gatt_cache_is_enabled(struct btd_device *device)
855 switch (btd_opts.gatt_cache) {
856 case BT_GATT_CACHE_YES:
857 return device_is_paired(device, device->bdaddr_type);
858 case BT_GATT_CACHE_NO:
860 case BT_GATT_CACHE_ALWAYS:
866 static void gatt_cache_cleanup(struct btd_device *device)
868 if (gatt_cache_is_enabled(device))
871 bt_gatt_client_cancel_all(device->client);
872 gatt_db_clear(device->db);
873 device->le_state.svc_resolved = false;
876 static void gatt_client_cleanup(struct btd_device *device)
881 gatt_cache_cleanup(device);
882 bt_gatt_client_set_service_changed(device->client, NULL, NULL, NULL);
884 if (device->gatt_ready_id > 0) {
885 bt_gatt_client_ready_unregister(device->client,
886 device->gatt_ready_id);
887 device->gatt_ready_id = 0;
890 bt_gatt_client_unref(device->client);
891 device->client = NULL;
894 static void gatt_server_cleanup(struct btd_device *device)
899 btd_gatt_database_att_disconnected(
900 btd_adapter_get_database(device->adapter), device);
902 bt_gatt_server_unref(device->server);
903 device->server = NULL;
906 static void attio_cleanup(struct btd_device *device)
908 if (device->att_disconn_id)
909 bt_att_unregister_disconnect(device->att,
910 device->att_disconn_id);
912 if (device->att_io) {
913 g_io_channel_shutdown(device->att_io, FALSE, NULL);
914 g_io_channel_unref(device->att_io);
915 device->att_io = NULL;
918 gatt_client_cleanup(device);
919 gatt_server_cleanup(device);
922 bt_att_unref(device->att);
926 if (device->attrib) {
927 GAttrib *attrib = device->attrib;
929 device->attrib = NULL;
930 g_attrib_cancel_all(attrib);
931 g_attrib_unref(attrib);
935 static void browse_request_cancel(struct browse_req *req)
937 struct btd_device *device = req->device;
938 struct btd_adapter *adapter = device->adapter;
942 bt_cancel_discovery(btd_adapter_get_address(adapter), &device->bdaddr);
944 attio_cleanup(device);
946 browse_request_free(req);
949 static void svc_dev_remove(gpointer user_data)
951 struct svc_callback *cb = user_data;
954 g_source_remove(cb->idle_id);
956 cb->func(cb->dev, -ENODEV, cb->user_data);
961 static void device_free(gpointer user_data)
963 struct btd_device *device = user_data;
965 btd_gatt_client_destroy(device->client_dbus);
966 device->client_dbus = NULL;
968 g_slist_free_full(device->uuids, g_free);
969 g_slist_free_full(device->primaries, g_free);
970 g_slist_free_full(device->svc_callbacks, svc_dev_remove);
972 /* Reset callbacks since the device is going to be freed */
973 gatt_db_unregister(device->db, device->db_id);
975 attio_cleanup(device);
977 gatt_db_unref(device->db);
979 bt_ad_unref(device->ad);
981 if (device->tmp_records)
982 sdp_list_free(device->tmp_records,
983 (sdp_free_func_t) sdp_record_free);
985 if (device->disconn_timer)
986 timeout_remove(device->disconn_timer);
988 if (device->discov_timer)
989 timeout_remove(device->discov_timer);
991 if (device->temporary_timer)
992 timeout_remove(device->temporary_timer);
995 dbus_message_unref(device->connect);
997 if (device->disconnect)
998 dbus_message_unref(device->disconnect);
1002 if (device->authr) {
1003 if (device->authr->agent)
1004 agent_unref(device->authr->agent);
1005 g_free(device->authr->pincode);
1006 g_free(device->authr);
1009 if (device->eir_uuids)
1010 g_slist_free_full(device->eir_uuids, g_free);
1012 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1013 g_free(device->rpa);
1015 g_free(device->local_csrk);
1016 g_free(device->remote_csrk);
1017 g_free(device->path);
1018 g_free(device->alias);
1019 free(device->modalias);
1023 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1024 void device_set_remote_feature_flag(struct btd_device *device, int flags)
1026 device->remote_feature_flags = flags;
1029 gboolean device_is_bredrle(struct btd_device *device)
1031 return (device->remote_feature_flags & (EIR_CONTROLLER | EIR_SIM_HOST));
1035 bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type)
1037 struct bearer_state *state = get_state(device, bdaddr_type);
1039 return state->paired;
1042 bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type)
1044 struct bearer_state *state = get_state(device, bdaddr_type);
1046 return state->bonded;
1049 gboolean device_is_trusted(struct btd_device *device)
1051 return device->trusted;
1054 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1055 gboolean device_is_profile_trusted(struct btd_device *device,
1058 if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1059 if (device->trusted_profiles.pbap == SUPPORTED_TRUSTED)
1061 } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1062 if (device->trusted_profiles.map == SUPPORTED_TRUSTED)
1064 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1065 if (device->trusted_profiles.sap == SUPPORTED_TRUSTED)
1067 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1068 if (device->trusted_profiles.hfp_hs == SUPPORTED_TRUSTED)
1070 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1071 if (device->trusted_profiles.a2dp == SUPPORTED_TRUSTED)
1077 gboolean device_is_profile_blocked(struct btd_device *device,
1080 if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1081 if (device->trusted_profiles.pbap == SUPPORTED_BLOCKED)
1083 } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1084 if (device->trusted_profiles.map == SUPPORTED_BLOCKED)
1086 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1087 if (device->trusted_profiles.sap == SUPPORTED_BLOCKED)
1089 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1090 if (device->trusted_profiles.hfp_hs == SUPPORTED_BLOCKED)
1092 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1093 if (device->trusted_profiles.a2dp == SUPPORTED_BLOCKED)
1100 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
1101 DBusMessageIter *iter, void *data)
1103 struct btd_device *device = data;
1105 const char *ptr = dstaddr;
1107 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1109 ba2str(device->rpa, dstaddr);
1112 ba2str(&device->bdaddr, dstaddr);
1113 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1118 static gboolean property_get_address_type(const GDBusPropertyTable *property,
1119 DBusMessageIter *iter, void *user_data)
1121 struct btd_device *device = user_data;
1124 if (device->le && device->bdaddr_type == BDADDR_LE_RANDOM)
1129 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
1134 static gboolean dev_property_get_name(const GDBusPropertyTable *property,
1135 DBusMessageIter *iter, void *data)
1137 struct btd_device *device = data;
1138 const char *ptr = device->name;
1140 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1145 static gboolean dev_property_exists_name(const GDBusPropertyTable *property,
1148 struct btd_device *dev = data;
1150 return device_name_known(dev);
1153 static gboolean dev_property_get_alias(const GDBusPropertyTable *property,
1154 DBusMessageIter *iter, void *data)
1156 struct btd_device *device = data;
1160 /* Alias (fallback to name or address) */
1161 if (device->alias != NULL)
1162 ptr = device->alias;
1163 else if (strlen(device->name) > 0) {
1166 ba2str(&device->bdaddr, dstaddr);
1167 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
1168 g_strdelimit(dstaddr, ":", '-');
1173 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1178 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1179 static gboolean dev_property_get_alias_set(const GDBusPropertyTable *property,
1180 DBusMessageIter *iter, void *data)
1182 struct btd_device *device = data;
1185 if (device->alias != NULL)
1190 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1196 static void set_alias(GDBusPendingPropertySet id, const char *alias,
1199 struct btd_device *device = data;
1202 if ((device->alias == NULL && g_str_equal(alias, "")) ||
1203 g_strcmp0(device->alias, alias) == 0) {
1204 g_dbus_pending_property_success(id);
1208 g_free(device->alias);
1209 device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
1211 store_device_info(device);
1213 g_dbus_emit_property_changed(dbus_conn, device->path,
1214 DEVICE_INTERFACE, "Alias");
1216 g_dbus_pending_property_success(id);
1219 static void dev_property_set_alias(const GDBusPropertyTable *property,
1220 DBusMessageIter *value,
1221 GDBusPendingPropertySet id, void *data)
1225 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING) {
1226 g_dbus_pending_property_error(id,
1227 ERROR_INTERFACE ".InvalidArguments",
1228 "Invalid arguments in method call");
1232 dbus_message_iter_get_basic(value, &alias);
1234 set_alias(id, alias, data);
1237 static gboolean dev_property_exists_class(const GDBusPropertyTable *property,
1240 struct btd_device *device = data;
1242 return device->class != 0;
1245 static gboolean dev_property_get_class(const GDBusPropertyTable *property,
1246 DBusMessageIter *iter, void *data)
1248 struct btd_device *device = data;
1250 if (device->class == 0)
1253 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &device->class);
1258 static gboolean get_appearance(const GDBusPropertyTable *property, void *data,
1259 uint16_t *appearance)
1261 struct btd_device *device = data;
1263 if (dev_property_exists_class(property, data))
1266 if (device->appearance) {
1267 *appearance = device->appearance;
1274 static gboolean dev_property_exists_appearance(
1275 const GDBusPropertyTable *property, void *data)
1277 uint16_t appearance;
1279 return get_appearance(property, data, &appearance);
1282 static gboolean dev_property_get_appearance(const GDBusPropertyTable *property,
1283 DBusMessageIter *iter, void *data)
1285 uint16_t appearance;
1287 if (!get_appearance(property, data, &appearance))
1290 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &appearance);
1295 static const char *get_icon(const GDBusPropertyTable *property, void *data)
1297 struct btd_device *device = data;
1298 const char *icon = NULL;
1299 uint16_t appearance;
1301 if (device->class != 0)
1302 icon = class_to_icon(device->class);
1303 else if (get_appearance(property, data, &appearance))
1304 icon = gap_appearance_to_icon(appearance);
1309 static gboolean dev_property_exists_icon(
1310 const GDBusPropertyTable *property, void *data)
1312 return get_icon(property, data) != NULL;
1315 static gboolean dev_property_get_icon(const GDBusPropertyTable *property,
1316 DBusMessageIter *iter, void *data)
1320 icon = get_icon(property, data);
1324 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &icon);
1329 static gboolean dev_property_get_paired(const GDBusPropertyTable *property,
1330 DBusMessageIter *iter, void *data)
1332 struct btd_device *dev = data;
1335 if (dev->bredr_state.paired || dev->le_state.paired)
1340 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1345 static gboolean dev_property_get_legacy(const GDBusPropertyTable *property,
1346 DBusMessageIter *iter, void *data)
1348 struct btd_device *device = data;
1349 dbus_bool_t val = device->legacy;
1351 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1356 static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
1357 DBusMessageIter *iter, void *data)
1359 struct btd_device *dev = data;
1360 dbus_int16_t val = dev->rssi;
1362 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1367 static gboolean dev_property_exists_rssi(const GDBusPropertyTable *property,
1370 struct btd_device *dev = data;
1378 static gboolean dev_property_get_tx_power(const GDBusPropertyTable *property,
1379 DBusMessageIter *iter, void *data)
1381 struct btd_device *dev = data;
1382 dbus_int16_t val = dev->tx_power;
1384 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1389 static gboolean dev_property_exists_tx_power(const GDBusPropertyTable *property,
1392 struct btd_device *dev = data;
1394 if (dev->tx_power == 127)
1401 dev_property_get_svc_resolved(const GDBusPropertyTable *property,
1402 DBusMessageIter *iter, void *data)
1404 struct btd_device *device = data;
1405 gboolean val = device->svc_refreshed;
1407 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1412 static gboolean dev_property_flags_exist(const GDBusPropertyTable *property,
1415 struct btd_device *device = data;
1417 return device->ad_flags[0] != INVALID_FLAGS;
1421 dev_property_get_flags(const GDBusPropertyTable *property,
1422 DBusMessageIter *iter, void *data)
1424 struct btd_device *device = data;
1425 uint8_t *flags = device->ad_flags;
1426 DBusMessageIter array;
1428 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1429 DBUS_TYPE_BYTE_AS_STRING, &array);
1430 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1431 &flags, sizeof(device->ad_flags));
1432 dbus_message_iter_close_container(iter, &array);
1437 static gboolean dev_property_get_trusted(const GDBusPropertyTable *property,
1438 DBusMessageIter *iter, void *data)
1440 struct btd_device *device = data;
1441 gboolean val = device_is_trusted(device);
1443 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1448 static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
1450 struct btd_device *device = data;
1452 btd_device_set_trusted(device, value);
1454 g_dbus_pending_property_success(id);
1457 static void dev_property_set_trusted(const GDBusPropertyTable *property,
1458 DBusMessageIter *value,
1459 GDBusPendingPropertySet id, void *data)
1463 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1464 g_dbus_pending_property_error(id,
1465 ERROR_INTERFACE ".InvalidArguments",
1466 "Invalid arguments in method call");
1470 dbus_message_iter_get_basic(value, &b);
1472 set_trust(id, b, data);
1475 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1476 static gboolean dev_property_get_trusted_profiles(const GDBusPropertyTable *property,
1477 DBusMessageIter *iter, void *data)
1479 struct btd_device *device = data;
1480 uint32_t pbap = device->trusted_profiles.pbap;
1481 uint32_t map = device->trusted_profiles.map;
1482 uint32_t sap = device->trusted_profiles.sap;
1483 uint32_t hfp_hs = device->trusted_profiles.hfp_hs;
1484 uint32_t a2dp = device->trusted_profiles.a2dp;
1486 unsigned int val = (pbap << PBAP_SHIFT_OFFSET) |
1487 (map << MAP_SHIFT_OFFSET) |
1488 (sap << SAP_SHIFT_OFFSET) |
1489 (hfp_hs << HFP_HS_SHIFT_OFFSET) |
1490 (a2dp << A2DP_SHIFT_OFFSET);
1492 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val);
1498 static gboolean dev_property_get_blocked(const GDBusPropertyTable *property,
1499 DBusMessageIter *iter, void *data)
1501 struct btd_device *device = data;
1503 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1509 static void set_blocked(GDBusPendingPropertySet id, gboolean value, void *data)
1511 struct btd_device *device = data;
1515 err = device_block(device, FALSE);
1517 err = device_unblock(device, FALSE, FALSE);
1521 g_dbus_pending_property_success(id);
1524 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1525 "Kernel lacks reject list support");
1528 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1535 static void dev_property_set_blocked(const GDBusPropertyTable *property,
1536 DBusMessageIter *value,
1537 GDBusPendingPropertySet id, void *data)
1541 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1542 g_dbus_pending_property_error(id,
1543 ERROR_INTERFACE ".InvalidArguments",
1544 "Invalid arguments in method call");
1548 dbus_message_iter_get_basic(value, &b);
1550 set_blocked(id, b, data);
1553 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1554 static uint8_t device_get_connected_state(struct btd_device *device)
1556 if (device->bredr_state.connected && device->le_state.connected)
1557 return DEV_CONNECTED_BREDR_LE;
1558 else if (device->bredr_state.connected)
1559 return DEV_CONNECTED_BREDR;
1560 else if (device->le_state.connected)
1561 return DEV_CONNECTED_LE;
1563 return DEV_CONNECTED_NONE;
1566 static gboolean dev_property_get_payload(const GDBusPropertyTable *property,
1567 DBusMessageIter *iter, void *data)
1569 struct btd_device *dev = data;
1570 dbus_uint16_t payload_timeout = dev->auth_payload_timeout;
1572 dbus_message_iter_append_basic(iter,
1573 DBUS_TYPE_UINT16, &payload_timeout);
1578 static gboolean dev_property_get_last_addr_type(const GDBusPropertyTable *property,
1579 DBusMessageIter *iter, void *data)
1581 struct btd_device *dev = data;
1582 uint8_t last_addr_type = dev->last_bdaddr_type;
1584 dbus_message_iter_append_basic(iter,
1585 DBUS_TYPE_BYTE, &last_addr_type);
1590 static gboolean dev_property_get_att_mtu(const GDBusPropertyTable *property,
1591 DBusMessageIter *iter, void *data)
1593 struct btd_device *device = data;
1594 dbus_uint16_t mtu = bt_gatt_client_get_mtu(device->client);
1596 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &mtu);
1601 static gboolean dev_property_get_gatt_connected(const GDBusPropertyTable *property,
1602 DBusMessageIter *iter, void *data)
1604 struct btd_device *device = data;
1605 dbus_bool_t gatt_connected;
1607 if (device->gatt_connected)
1608 gatt_connected = TRUE;
1610 gatt_connected = FALSE;
1612 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1618 static gboolean dev_property_get_ipsp_conn_state(const GDBusPropertyTable *property,
1619 DBusMessageIter *iter, void *data)
1621 struct btd_device *dev = data;
1622 dbus_bool_t ipsp_connected;
1624 if (dev->ipsp_connected)
1625 ipsp_connected = TRUE;
1627 ipsp_connected = FALSE;
1629 dbus_message_iter_append_basic(iter,
1630 DBUS_TYPE_BOOLEAN, &ipsp_connected);
1635 static gboolean dev_property_get_ipsp_conn_bt_iface_name(const GDBusPropertyTable *property,
1636 DBusMessageIter *iter, void *data)
1638 struct btd_device *dev = data;
1639 char *ptr = g_strdup(dev->if_name);
1641 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, (const char **)&ptr);
1649 static gboolean dev_property_get_connected(const GDBusPropertyTable *property,
1650 DBusMessageIter *iter, void *data)
1652 struct btd_device *dev = data;
1654 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1655 uint8_t connected = device_get_connected_state(dev);
1657 dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &connected);
1659 dbus_bool_t connected;
1661 if (dev->bredr_state.connected || dev->le_state.connected)
1666 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
1672 static gboolean dev_property_get_uuids(const GDBusPropertyTable *property,
1673 DBusMessageIter *iter, void *data)
1675 struct btd_device *dev = data;
1676 DBusMessageIter entry;
1679 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1680 DBUS_TYPE_STRING_AS_STRING, &entry);
1682 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
1684 else if (dev->eir_uuids)
1689 for (; l != NULL; l = l->next)
1690 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
1693 dbus_message_iter_close_container(iter, &entry);
1698 static gboolean dev_property_get_modalias(const GDBusPropertyTable *property,
1699 DBusMessageIter *iter, void *data)
1701 struct btd_device *device = data;
1703 if (!device->modalias)
1706 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1712 static gboolean dev_property_exists_modalias(const GDBusPropertyTable *property,
1715 struct btd_device *device = data;
1717 return device->modalias ? TRUE : FALSE;
1720 static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
1721 DBusMessageIter *iter, void *data)
1723 struct btd_device *device = data;
1724 const char *str = adapter_get_path(device->adapter);
1726 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &str);
1731 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1732 static gboolean property_get_manufacturer_data_len(const GDBusPropertyTable *property,
1733 DBusMessageIter *iter, void *user_data)
1735 struct btd_device *device = user_data;
1736 dbus_uint16_t val = device->manufacturer_data_len;
1738 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val);
1743 static gboolean property_get_manufacturer_data(const GDBusPropertyTable *property,
1744 DBusMessageIter *iter, void *user_data)
1746 struct btd_device *device = user_data;
1747 char str[DEV_MAX_MANUFACTURER_DATA_LEN] = {0};
1748 DBusMessageIter array;
1750 memset(str, 0, DEV_MAX_MANUFACTURER_DATA_LEN);
1751 if (device->manufacturer_data_len)
1752 memcpy(str, device->manufacturer_data,
1753 device->manufacturer_data_len);
1755 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1756 DBUS_TYPE_BYTE_AS_STRING, &array);
1758 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1759 &device->manufacturer_data,
1760 device->manufacturer_data_len);
1762 dbus_message_iter_close_container(iter, &array);
1767 gboolean device_get_gatt_connected(const struct btd_device *device)
1769 return device->gatt_connected;
1773 static void append_manufacturer_data(void *data, void *user_data)
1775 struct bt_ad_manufacturer_data *md = data;
1776 DBusMessageIter *dict = user_data;
1778 g_dbus_dict_append_basic_array(dict,
1779 DBUS_TYPE_UINT16, &md->manufacturer_id,
1780 DBUS_TYPE_BYTE, &md->data, md->len);
1784 dev_property_get_manufacturer_data(const GDBusPropertyTable *property,
1785 DBusMessageIter *iter, void *data)
1787 struct btd_device *device = data;
1788 DBusMessageIter dict;
1790 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1791 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1792 DBUS_TYPE_UINT16_AS_STRING
1793 DBUS_TYPE_VARIANT_AS_STRING
1794 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1797 bt_ad_foreach_manufacturer_data(device->ad, append_manufacturer_data,
1800 dbus_message_iter_close_container(iter, &dict);
1806 dev_property_manufacturer_data_exist(const GDBusPropertyTable *property,
1809 struct btd_device *device = data;
1811 return bt_ad_has_manufacturer_data(device->ad, NULL);
1814 static void append_service_data(void *data, void *user_data)
1816 struct bt_ad_service_data *sd = data;
1817 DBusMessageIter *dict = user_data;
1818 char uuid_str[MAX_LEN_UUID_STR];
1820 bt_uuid_to_string(&sd->uuid, uuid_str, sizeof(uuid_str));
1822 dict_append_array(dict, uuid_str, DBUS_TYPE_BYTE, &sd->data, sd->len);
1826 dev_property_get_service_data(const GDBusPropertyTable *property,
1827 DBusMessageIter *iter, void *data)
1829 struct btd_device *device = data;
1830 DBusMessageIter dict;
1832 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1833 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1834 DBUS_TYPE_STRING_AS_STRING
1835 DBUS_TYPE_VARIANT_AS_STRING
1836 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1839 bt_ad_foreach_service_data(device->ad, append_service_data, &dict);
1841 dbus_message_iter_close_container(iter, &dict);
1847 dev_property_service_data_exist(const GDBusPropertyTable *property,
1850 struct btd_device *device = data;
1852 return bt_ad_has_service_data(device->ad, NULL);
1855 static void append_advertising_data(void *data, void *user_data)
1857 struct bt_ad_data *ad = data;
1858 DBusMessageIter *dict = user_data;
1860 g_dbus_dict_append_basic_array(dict,
1861 DBUS_TYPE_BYTE, &ad->type,
1862 DBUS_TYPE_BYTE, &ad->data, ad->len);
1866 dev_property_get_advertising_data(const GDBusPropertyTable *property,
1867 DBusMessageIter *iter, void *data)
1869 struct btd_device *device = data;
1870 DBusMessageIter dict;
1872 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1873 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1874 DBUS_TYPE_BYTE_AS_STRING
1875 DBUS_TYPE_VARIANT_AS_STRING
1876 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1879 bt_ad_foreach_data(device->ad, append_advertising_data, &dict);
1881 dbus_message_iter_close_container(iter, &dict);
1887 dev_property_advertising_data_exist(const GDBusPropertyTable *property,
1890 struct btd_device *device = data;
1892 return bt_ad_has_data(device->ad, NULL);
1895 static bool device_get_wake_support(struct btd_device *device)
1897 return device->wake_support;
1900 void device_set_wake_support(struct btd_device *device, bool wake_support)
1902 device->wake_support = wake_support;
1904 /* If wake configuration has not been made yet, set the initial
1907 if (device->wake_override == WAKE_FLAG_DEFAULT) {
1908 device_set_wake_override(device, wake_support);
1909 device_set_wake_allowed(device, wake_support, -1U);
1913 static bool device_get_wake_allowed(struct btd_device *device)
1915 return device->wake_allowed;
1918 void device_set_wake_override(struct btd_device *device, bool wake_override)
1920 if (wake_override) {
1921 device->wake_override = WAKE_FLAG_ENABLED;
1922 device->current_flags |= DEVICE_FLAG_REMOTE_WAKEUP;
1924 device->wake_override = WAKE_FLAG_DISABLED;
1925 device->current_flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
1929 static void device_set_wake_allowed_complete(struct btd_device *device)
1931 if (device->wake_id != -1U) {
1932 g_dbus_pending_property_success(device->wake_id);
1933 device->wake_id = -1U;
1936 device->wake_allowed = device->pending_wake_allowed;
1937 g_dbus_emit_property_changed(dbus_conn, device->path,
1938 DEVICE_INTERFACE, "WakeAllowed");
1940 store_device_info(device);
1943 static void set_wake_allowed_complete(uint8_t status, uint16_t length,
1944 const void *param, void *user_data)
1946 const struct mgmt_rp_set_device_flags *rp = param;
1947 struct btd_device *dev = user_data;
1949 if (status != MGMT_STATUS_SUCCESS) {
1950 error("Set device flags return status: %s",
1951 mgmt_errstr(status));
1955 if (length < sizeof(*rp)) {
1956 error("Too small Set Device Flags complete event: %d", length);
1960 device_set_wake_allowed_complete(dev);
1963 void device_set_wake_allowed(struct btd_device *device, bool wake_allowed,
1964 GDBusPendingPropertySet id)
1967 /* Pending and current value are the same unless there is a change in
1968 * progress. Only update wake allowed if pending value doesn't match the
1971 if (wake_allowed == device->pending_wake_allowed)
1974 device->wake_id = id;
1975 device->pending_wake_allowed = wake_allowed;
1976 flags = device->current_flags;
1978 flags |= DEVICE_FLAG_REMOTE_WAKEUP;
1980 flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
1982 adapter_set_device_flags(device->adapter, device, flags,
1983 set_wake_allowed_complete, device);
1988 dev_property_get_wake_allowed(const GDBusPropertyTable *property,
1989 DBusMessageIter *iter, void *data)
1991 struct btd_device *device = data;
1992 dbus_bool_t wake_allowed = device_get_wake_allowed(device);
1994 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &wake_allowed);
1999 static void dev_property_set_wake_allowed(const GDBusPropertyTable *property,
2000 DBusMessageIter *value,
2001 GDBusPendingPropertySet id, void *data)
2003 struct btd_device *device = data;
2006 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
2007 g_dbus_pending_property_error(id,
2008 ERROR_INTERFACE ".InvalidArguments",
2009 "Invalid arguments in method call");
2013 if (device->temporary) {
2014 g_dbus_pending_property_error(id,
2015 ERROR_INTERFACE ".Unsupported",
2016 "Cannot set property while temporary");
2020 /* Emit busy or success depending on current value. */
2021 if (b == device->pending_wake_allowed) {
2022 if (device->wake_allowed == device->pending_wake_allowed)
2023 g_dbus_pending_property_success(id);
2025 g_dbus_pending_property_error(
2026 id, ERROR_INTERFACE ".Busy",
2027 "Property change in progress");
2032 dbus_message_iter_get_basic(value, &b);
2033 device_set_wake_override(device, b);
2034 device_set_wake_allowed(device, b, id);
2037 static gboolean dev_property_wake_allowed_exist(
2038 const GDBusPropertyTable *property, void *data)
2040 struct btd_device *device = data;
2042 return device_get_wake_support(device);
2046 static bool disconnect_all(gpointer user_data)
2048 struct btd_device *device = user_data;
2050 device->disconn_timer = 0;
2052 if (device->bredr_state.connected)
2053 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
2056 if (device->le_state.connected)
2057 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
2058 device->bdaddr_type);
2063 int device_block(struct btd_device *device, gboolean update_only)
2067 if (device->blocked)
2070 if (device->disconn_timer > 0)
2071 timeout_remove(device->disconn_timer);
2073 disconnect_all(device);
2075 while (device->services != NULL) {
2076 struct btd_service *service = device->services->data;
2078 device->services = g_slist_remove(device->services, service);
2079 service_remove(service);
2084 err = btd_adapter_block_address(device->adapter,
2086 device->bdaddr_type);
2087 if (!err && device->bredr)
2088 err = btd_adapter_block_address(device->adapter,
2096 device->blocked = TRUE;
2098 store_device_info(device);
2100 btd_device_set_temporary(device, false);
2102 g_dbus_emit_property_changed(dbus_conn, device->path,
2103 DEVICE_INTERFACE, "Blocked");
2108 int device_unblock(struct btd_device *device, gboolean silent,
2109 gboolean update_only)
2113 if (!device->blocked)
2118 err = btd_adapter_unblock_address(device->adapter,
2120 device->bdaddr_type);
2121 if (!err && device->bredr)
2122 err = btd_adapter_unblock_address(device->adapter,
2130 device->blocked = FALSE;
2132 store_device_info(device);
2135 g_dbus_emit_property_changed(dbus_conn, device->path,
2136 DEVICE_INTERFACE, "Blocked");
2137 device_probe_profiles(device, device->uuids);
2143 static void browse_request_exit(DBusConnection *conn, void *user_data)
2145 struct browse_req *req = user_data;
2147 DBG("Requestor exited");
2149 browse_request_cancel(req);
2152 static void bonding_request_cancel(struct bonding_req *bonding)
2154 struct btd_device *device = bonding->device;
2155 struct btd_adapter *adapter = device->adapter;
2157 adapter_cancel_bonding(adapter, &device->bdaddr, device->bdaddr_type);
2160 static void dev_disconn_service(gpointer a, gpointer b)
2162 btd_service_disconnect(a);
2165 void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
2167 if (device->bonding)
2168 bonding_request_cancel(device->bonding);
2171 browse_request_cancel(device->browse);
2173 if (device->att_io) {
2174 g_io_channel_shutdown(device->att_io, FALSE, NULL);
2175 g_io_channel_unref(device->att_io);
2176 device->att_io = NULL;
2179 if (device->connect) {
2180 DBusMessage *reply = btd_error_failed(device->connect,
2181 ERR_BREDR_CONN_CANCELED);
2182 g_dbus_send_message(dbus_conn, reply);
2183 dbus_message_unref(device->connect);
2184 device->connect = NULL;
2187 if (btd_device_is_connected(device) && msg)
2188 device->disconnects = g_slist_append(device->disconnects,
2189 dbus_message_ref(msg));
2191 if (device->disconn_timer)
2194 g_slist_foreach(device->services, dev_disconn_service, NULL);
2196 g_slist_free(device->pending);
2197 device->pending = NULL;
2199 while (device->watches) {
2200 struct btd_disconnect_data *data = device->watches->data;
2203 /* temporary is set if device is going to be removed */
2204 data->watch(device, device->temporary,
2207 /* Check if the watch has been removed by callback function */
2208 if (!g_slist_find(device->watches, data))
2211 device->watches = g_slist_remove(device->watches, data);
2215 if (!btd_device_is_connected(device)) {
2217 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
2221 device->disconn_timer = timeout_add_seconds(DISCONNECT_TIMER,
2226 bool device_is_disconnecting(struct btd_device *device)
2228 return device->disconn_timer > 0;
2231 void device_set_ltk_enc_size(struct btd_device *device, uint8_t enc_size)
2233 device->ltk_enc_size = enc_size;
2234 bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
2237 static void device_set_auto_connect(struct btd_device *device, gboolean enable)
2241 if (!device || !device->le)
2244 ba2str(&device->bdaddr, addr);
2246 DBG("%s auto connect: %d", addr, enable);
2248 if (device->auto_connect == enable)
2251 device->auto_connect = enable;
2253 /* Disabling auto connect */
2254 if (enable == FALSE) {
2255 adapter_connect_list_remove(device->adapter, device);
2256 adapter_auto_connect_remove(device->adapter, device);
2260 /* Enabling auto connect */
2261 adapter_auto_connect_add(device->adapter, device);
2263 if (device->attrib) {
2264 DBG("Already connected");
2268 adapter_connect_list_add(device->adapter, device);
2271 static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
2274 struct btd_device *device = user_data;
2277 * If device is not trusted disable connections through passive
2278 * scanning until Device1.Connect is called
2280 if (device->auto_connect && !device->trusted) {
2281 device->disable_auto_connect = TRUE;
2282 device_set_auto_connect(device, FALSE);
2285 device_request_disconnect(device, msg);
2290 static int connect_next(struct btd_device *dev)
2292 struct btd_service *service;
2295 while (dev->pending) {
2296 service = dev->pending->data;
2298 err = btd_service_connect(service);
2302 dev->pending = g_slist_delete_link(dev->pending, dev->pending);
2308 static void device_profile_connected(struct btd_device *dev,
2309 struct btd_profile *profile, int err)
2311 struct btd_service *pending;
2314 DBG("%s %s (%d)", profile->name, strerror(-err), -err);
2317 btd_device_set_temporary(dev, false);
2319 if (dev->pending == NULL)
2322 if (!btd_device_is_connected(dev)) {
2324 case EHOSTDOWN: /* page timeout */
2325 case EHOSTUNREACH: /* adapter not powered */
2326 case ECONNABORTED: /* adapter powered down */
2331 pending = dev->pending->data;
2332 l = find_service_with_profile(dev->pending, profile);
2334 dev->pending = g_slist_delete_link(dev->pending, l);
2336 /* Only continue connecting the next profile if it matches the first
2337 * pending, otherwise it will trigger another connect to the same
2340 if (profile != btd_service_get_profile(pending))
2343 if (connect_next(dev) == 0)
2347 g_slist_free(dev->pending);
2348 dev->pending = NULL;
2353 if (dbus_message_is_method_call(dev->connect, DEVICE_INTERFACE,
2356 dev->general_connect = TRUE;
2357 else if (find_service_with_state(dev->services,
2358 BTD_SERVICE_STATE_CONNECTED))
2359 /* Reset error if there are services connected */
2363 DBG("returning response to %s", dbus_message_get_sender(dev->connect));
2366 /* Fallback to LE bearer if supported */
2367 if (err == -EHOSTDOWN && dev->le && !dev->le_state.connected) {
2368 err = device_connect_le(dev);
2373 g_dbus_send_message(dbus_conn,
2374 btd_error_failed(dev->connect,
2375 btd_error_bredr_conn_from_errno(err)));
2377 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2378 /* SDP is not required for Samsung TV Power on */
2379 if (g_strcmp0(profile->name, "hid-device") == 0) {
2380 DBG("Skip SDP discovery.");
2383 /* Start passive SDP discovery to update known services */
2384 if (dev->bredr && !dev->svc_refreshed && dev->refresh_discovery)
2385 device_browse_sdp(dev, NULL);
2386 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2390 g_dbus_send_reply(dbus_conn, dev->connect, DBUS_TYPE_INVALID);
2393 dbus_message_unref(dev->connect);
2394 dev->connect = NULL;
2397 void device_add_eir_uuids(struct btd_device *dev, GSList *uuids)
2402 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
2405 for (l = uuids; l != NULL; l = l->next) {
2406 const char *str = l->data;
2407 if (g_slist_find_custom(dev->eir_uuids, str, bt_uuid_strcmp))
2410 dev->eir_uuids = g_slist_append(dev->eir_uuids, g_strdup(str));
2414 g_dbus_emit_property_changed(dbus_conn, dev->path,
2415 DEVICE_INTERFACE, "UUIDs");
2418 static void add_manufacturer_data(void *data, void *user_data)
2420 struct eir_msd *msd = data;
2421 struct btd_device *dev = user_data;
2423 if (!bt_ad_add_manufacturer_data(dev->ad, msd->company, msd->data,
2427 g_dbus_emit_property_changed(dbus_conn, dev->path,
2428 DEVICE_INTERFACE, "ManufacturerData");
2431 void device_set_manufacturer_data(struct btd_device *dev, GSList *list,
2435 bt_ad_clear_manufacturer_data(dev->ad);
2437 g_slist_foreach(list, add_manufacturer_data, dev);
2440 static void add_service_data(void *data, void *user_data)
2442 struct eir_sd *sd = data;
2443 struct btd_device *dev = user_data;
2446 if (bt_string_to_uuid(&uuid, sd->uuid) < 0)
2449 if (!bt_ad_add_service_data(dev->ad, &uuid, sd->data, sd->data_len))
2452 g_dbus_emit_property_changed(dbus_conn, dev->path,
2453 DEVICE_INTERFACE, "ServiceData");
2456 void device_set_service_data(struct btd_device *dev, GSList *list,
2460 bt_ad_clear_service_data(dev->ad);
2462 g_slist_foreach(list, add_service_data, dev);
2465 static void add_data(void *data, void *user_data)
2467 struct eir_ad *ad = data;
2468 struct btd_device *dev = user_data;
2470 if (!bt_ad_add_data(dev->ad, ad->type, ad->data, ad->len))
2473 if (ad->type == EIR_TRANSPORT_DISCOVERY)
2474 g_dbus_emit_property_changed(dbus_conn, dev->path,
2479 void device_set_data(struct btd_device *dev, GSList *list,
2483 bt_ad_clear_data(dev->ad);
2485 g_slist_foreach(list, add_data, dev);
2488 static struct btd_service *find_connectable_service(struct btd_device *dev,
2492 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2493 struct btd_service *s = NULL;
2495 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2496 struct btd_service *service = l->data;
2497 struct btd_profile *p = btd_service_get_profile(service);
2499 if (!p->connect || !p->remote_uuid)
2502 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
2503 if (strcasecmp(uuid, p->remote_uuid) == 0)
2506 if (strcasecmp(uuid, p->remote_uuid) == 0) {
2508 if (ext_profile_is_registered_as_client_role(p) == TRUE) {
2516 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2524 static int service_prio_cmp(gconstpointer a, gconstpointer b)
2526 struct btd_profile *p1 = btd_service_get_profile(a);
2527 struct btd_profile *p2 = btd_service_get_profile(b);
2529 return p2->priority - p1->priority;
2532 bool btd_device_all_services_allowed(struct btd_device *dev)
2535 struct btd_adapter *adapter = dev->adapter;
2536 struct btd_service *service;
2537 struct btd_profile *profile;
2539 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2541 profile = btd_service_get_profile(service);
2543 if (!profile || !profile->auto_connect)
2546 if (!btd_adapter_is_uuid_allowed(adapter, profile->remote_uuid))
2553 void btd_device_update_allowed_services(struct btd_device *dev)
2555 struct btd_adapter *adapter = dev->adapter;
2556 struct btd_service *service;
2557 struct btd_profile *profile;
2562 /* If service discovery is ongoing, let the service discovery complete
2563 * callback call this function.
2566 ba2str(&dev->bdaddr, addr);
2567 DBG("service discovery of %s is ongoing. Skip updating allowed "
2572 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2574 profile = btd_service_get_profile(service);
2576 is_allowed = btd_adapter_is_uuid_allowed(adapter,
2577 profile->remote_uuid);
2578 btd_service_set_allowed(service, is_allowed);
2582 static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
2584 struct btd_service *service;
2585 struct btd_profile *p;
2587 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2588 bool hs_hf_verify = FALSE;
2592 service = find_connectable_service(dev, uuid);
2594 return dev->pending;
2596 if (btd_service_is_allowed(service))
2597 return g_slist_prepend(dev->pending, service);
2599 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2600 else if ((service == NULL) &&
2601 (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2602 DBG("HFP service not found check for HSP service");
2603 service = find_connectable_service(dev, HSP_HS_UUID);
2605 return g_slist_prepend(dev->pending, service);
2606 } else if (g_strcmp0(uuid, HID_UUID) == 0) {
2607 DBG("HID service not found, add HID service");
2608 btd_device_add_uuid(dev, uuid);
2609 service = find_connectable_service(dev, HID_UUID);
2611 return g_slist_prepend(dev->pending, service);
2614 return dev->pending;
2617 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2619 p = btd_service_get_profile(service);
2621 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2622 DBG("profile uuid %s", p->remote_uuid);
2623 if (g_strcmp0(p->remote_uuid, HSP_HS_UUID) == 0) {
2624 DBG("HSP service is found check for HFP service");
2625 struct btd_service *service;
2626 struct btd_profile *p;
2629 for (h = dev->services; h != NULL; h = g_slist_next(h)) {
2631 p = btd_service_get_profile(service);
2633 if (g_strcmp0(p->remote_uuid, HFP_HS_UUID) == 0) {
2634 DBG("HFP found,ignore HSP ");
2635 hs_hf_verify = TRUE;
2643 if (!p->auto_connect)
2646 if (!btd_service_is_allowed(service)) {
2647 info("service %s is blocked", p->remote_uuid);
2651 if (g_slist_find(dev->pending, service))
2654 if (btd_service_get_state(service) !=
2655 BTD_SERVICE_STATE_DISCONNECTED)
2658 dev->pending = g_slist_insert_sorted(dev->pending, service,
2662 return dev->pending;
2665 int btd_device_connect_services(struct btd_device *dev, GSList *services)
2669 if (dev->pending || dev->connect || dev->browse)
2672 if (!btd_adapter_get_powered(dev->adapter))
2675 if (!dev->bredr_state.svc_resolved)
2679 for (l = services; l; l = g_slist_next(l)) {
2680 struct btd_service *service = l->data;
2682 dev->pending = g_slist_append(dev->pending, service);
2685 dev->pending = create_pending_list(dev, NULL);
2688 return connect_next(dev);
2691 static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type,
2692 DBusMessage *msg, const char *uuid)
2694 struct bearer_state *state = get_state(dev, bdaddr_type);
2697 DBG("%s %s, client %s", dev->path, uuid ? uuid : "(all)",
2698 dbus_message_get_sender(msg));
2700 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2701 if (dev->pending || dev->connect)
2702 return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
2704 if (dev->pending || dev->connect || dev->browse)
2705 return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
2708 if (!btd_adapter_get_powered(dev->adapter)) {
2709 return btd_error_not_ready_str(msg,
2710 ERR_BREDR_CONN_ADAPTER_NOT_POWERED);
2713 btd_device_set_temporary(dev, false);
2715 if (!state->svc_resolved)
2716 goto resolve_services;
2718 dev->pending = create_pending_list(dev, uuid);
2719 if (!dev->pending) {
2720 if (dev->svc_refreshed) {
2721 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2722 if (!uuid && dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2724 find_service_with_state(dev->services,
2725 BTD_SERVICE_STATE_CONNECTED)) {
2727 if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2729 find_service_with_state(dev->services,
2730 BTD_SERVICE_STATE_CONNECTED)) {
2732 return dbus_message_new_method_return(msg);
2734 return btd_error_not_available_str(msg,
2735 ERR_BREDR_CONN_PROFILE_UNAVAILABLE);
2739 goto resolve_services;
2742 err = connect_next(dev);
2744 if (err == -EALREADY)
2745 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2746 return btd_error_already_connected(msg);
2748 return dbus_message_new_method_return(msg);
2750 return btd_error_failed(msg,
2751 btd_error_bredr_conn_from_errno(err));
2754 dev->connect = dbus_message_ref(msg);
2759 DBG("Resolving services for %s", dev->path);
2761 if (bdaddr_type == BDADDR_BREDR)
2762 err = device_browse_sdp(dev, msg);
2764 err = device_browse_gatt(dev, msg);
2766 return btd_error_failed(msg, bdaddr_type == BDADDR_BREDR ?
2767 ERR_BREDR_CONN_SDP_SEARCH : ERR_LE_CONN_GATT_BROWSE);
2773 #define NVAL_TIME ((time_t) -1)
2774 #define SEEN_TRESHHOLD 300
2776 static uint8_t select_conn_bearer(struct btd_device *dev)
2778 time_t bredr_last = NVAL_TIME, le_last = NVAL_TIME;
2779 time_t current = time(NULL);
2781 /* Prefer bonded bearer in case only one is bonded */
2782 if (dev->bredr_state.bonded && !dev->le_state.bonded )
2783 return BDADDR_BREDR;
2784 else if (!dev->bredr_state.bonded && dev->le_state.bonded)
2785 return dev->bdaddr_type;
2787 /* If the address is random it can only be connected over LE */
2788 if (dev->bdaddr_type == BDADDR_LE_RANDOM)
2789 return dev->bdaddr_type;
2791 if (dev->bredr_seen) {
2792 bredr_last = current - dev->bredr_seen;
2793 if (bredr_last > SEEN_TRESHHOLD)
2794 bredr_last = NVAL_TIME;
2798 le_last = current - dev->le_seen;
2799 if (le_last > SEEN_TRESHHOLD)
2800 le_last = NVAL_TIME;
2803 if (le_last == NVAL_TIME && bredr_last == NVAL_TIME)
2804 return dev->bdaddr_type;
2806 if (dev->bredr && (!dev->le || le_last == NVAL_TIME))
2807 return BDADDR_BREDR;
2809 if (dev->le && (!dev->bredr || bredr_last == NVAL_TIME))
2810 return dev->bdaddr_type;
2813 * Prefer BR/EDR if time is the same since it might be from an
2814 * advertisement with BR/EDR flag set.
2816 if (bredr_last <= le_last && btd_adapter_get_bredr(dev->adapter))
2817 return BDADDR_BREDR;
2819 return dev->bdaddr_type;
2822 static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
2825 struct btd_device *dev = user_data;
2826 uint8_t bdaddr_type;
2828 if (dev->bredr_state.connected) {
2830 * Check if services have been resolved and there is at least
2831 * one connected before switching to connect LE.
2833 if (dev->bredr_state.svc_resolved &&
2834 find_service_with_state(dev->services,
2835 BTD_SERVICE_STATE_CONNECTED))
2836 bdaddr_type = dev->bdaddr_type;
2838 bdaddr_type = BDADDR_BREDR;
2839 } else if (dev->le_state.connected && dev->bredr)
2840 bdaddr_type = BDADDR_BREDR;
2842 bdaddr_type = select_conn_bearer(dev);
2844 if (bdaddr_type != BDADDR_BREDR) {
2847 if (dev->le_state.connected)
2848 return dbus_message_new_method_return(msg);
2850 btd_device_set_temporary(dev, false);
2852 if (dev->disable_auto_connect) {
2853 dev->disable_auto_connect = FALSE;
2854 device_set_auto_connect(dev, TRUE);
2857 err = device_connect_le(dev);
2859 return btd_error_failed(msg, strerror(-err));
2861 dev->connect = dbus_message_ref(msg);
2866 return connect_profiles(dev, bdaddr_type, msg, NULL);
2869 static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
2872 struct btd_device *dev = user_data;
2873 const char *pattern;
2877 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2878 DBUS_TYPE_INVALID)) {
2879 return btd_error_invalid_args_str(msg,
2880 ERR_BREDR_CONN_INVALID_ARGUMENTS);
2883 uuid = bt_name2string(pattern);
2884 reply = connect_profiles(dev, BDADDR_BREDR, msg, uuid);
2890 static void device_profile_disconnected(struct btd_device *dev,
2891 struct btd_profile *profile, int err)
2893 if (!dev->disconnect)
2897 g_dbus_send_message(dbus_conn,
2898 btd_error_failed(dev->disconnect,
2901 g_dbus_send_reply(dbus_conn, dev->disconnect,
2904 dbus_message_unref(dev->disconnect);
2905 dev->disconnect = NULL;
2908 static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
2911 struct btd_device *dev = user_data;
2912 struct btd_service *service;
2913 const char *pattern;
2917 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2919 return btd_error_invalid_args(msg);
2921 uuid = bt_name2string(pattern);
2923 return btd_error_invalid_args(msg);
2925 service = find_connectable_service(dev, uuid);
2926 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2927 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2928 DBG("HFP service is not found check for HSP service");
2929 service = find_connectable_service(dev, HSP_HS_UUID);
2935 return btd_error_invalid_args(msg);
2937 if (dev->disconnect)
2938 return btd_error_in_progress(msg);
2940 if (btd_service_get_state(service) == BTD_SERVICE_STATE_DISCONNECTED)
2941 return dbus_message_new_method_return(msg);
2943 dev->disconnect = dbus_message_ref(msg);
2945 err = btd_service_disconnect(service);
2949 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2950 if (dev->disconnect)
2952 dbus_message_unref(dev->disconnect);
2953 dev->disconnect = NULL;
2955 if (err == -ENOTSUP)
2956 return btd_error_not_supported(msg);
2957 else if (err == -EALREADY)
2958 return dbus_message_new_method_return(msg);
2960 return btd_error_failed(msg, strerror(-err));
2963 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2964 static DBusMessage *disconnect_ext_profile(DBusConnection *conn,
2965 DBusMessage *msg, void *user_data)
2967 struct btd_device *dev = user_data;
2968 struct btd_profile *profile;
2969 struct btd_service *service;
2970 const char *sender, *path;
2974 sender = dbus_message_get_sender(msg);
2976 DBG("sender %s", sender);
2978 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
2980 return btd_error_invalid_args(msg);
2982 profile = btd_profile_find_ext(sender, path);
2984 return btd_error_invalid_args(msg);
2986 l = find_service_with_profile(dev->services, profile);
2988 return btd_error_invalid_args(msg);
2992 if (dev->disconnect)
2993 return btd_error_in_progress(msg);
2995 dev->disconnect = dbus_message_ref(msg);
2997 err = btd_service_disconnect(service);
3001 if (dev->disconnect)
3002 dbus_message_unref(dev->disconnect);
3003 dev->disconnect = NULL;
3005 if (err == -ENOTSUP)
3006 return btd_error_not_supported(msg);
3008 return btd_error_failed(msg, strerror(-err));
3012 static void store_services(struct btd_device *device)
3014 char filename[PATH_MAX];
3019 GError *gerr = NULL;
3024 if (device_address_is_private(device)) {
3025 DBG("Can't store services for private addressed device %s",
3030 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
3031 prim_uuid = bt_uuid2string(&uuid);
3032 if (prim_uuid == NULL)
3035 ba2str(&device->bdaddr, dst_addr);
3037 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3039 ba2str(device->rpa, dst_addr);
3042 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes",
3043 btd_adapter_get_storage_dir(device->adapter),
3045 key_file = g_key_file_new();
3047 for (l = device->primaries; l; l = l->next) {
3048 struct gatt_primary *primary = l->data;
3049 char handle[6], uuid_str[33];
3052 sprintf(handle, "%hu", primary->range.start);
3054 bt_string2uuid(&uuid, primary->uuid);
3055 sdp_uuid128_to_uuid(&uuid);
3057 switch (uuid.type) {
3059 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
3062 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
3065 for (i = 0; i < 16; i++)
3066 sprintf(uuid_str + (i * 2), "%2.2X",
3067 uuid.value.uuid128.data[i]);
3073 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
3074 g_key_file_set_string(key_file, handle, "Value", uuid_str);
3075 g_key_file_set_integer(key_file, handle, "EndGroupHandle",
3076 primary->range.end);
3079 data = g_key_file_to_data(key_file, &length, NULL);
3081 create_file(filename, 0600);
3082 if (!g_file_set_contents(filename, data, length, &gerr)) {
3083 error("Unable set contents for %s: (%s)", filename,
3091 g_key_file_free(key_file);
3095 struct btd_device *device;
3100 static void db_hash_read_value_cb(struct gatt_db_attribute *attrib,
3101 int err, const uint8_t *value,
3102 size_t length, void *user_data)
3104 const uint8_t **hash = user_data;
3106 if (err || (length != 16))
3112 static void store_desc(struct gatt_db_attribute *attr, void *user_data)
3114 struct gatt_saver *saver = user_data;
3115 GKeyFile *key_file = saver->key_file;
3116 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3117 const bt_uuid_t *uuid;
3119 uint16_t handle_num;
3121 handle_num = gatt_db_attribute_get_handle(attr);
3122 sprintf(handle, "%04hx", handle_num);
3124 uuid = gatt_db_attribute_get_type(attr);
3125 bt_uuid_to_string(uuid, uuid_str, sizeof(uuid_str));
3127 bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
3128 if (!bt_uuid_cmp(uuid, &ext_uuid) && saver->ext_props)
3129 sprintf(value, "%04hx:%s", saver->ext_props, uuid_str);
3131 sprintf(value, "%s", uuid_str);
3133 g_key_file_set_string(key_file, "Attributes", handle, value);
3136 static void store_chrc(struct gatt_db_attribute *attr, void *user_data)
3138 struct gatt_saver *saver = user_data;
3139 GKeyFile *key_file = saver->key_file;
3140 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3141 uint16_t handle_num, value_handle;
3143 bt_uuid_t uuid, hash_uuid;
3145 if (!gatt_db_attribute_get_char_data(attr, &handle_num, &value_handle,
3146 &properties, &saver->ext_props,
3148 warn("Error storing characteristic - can't get data");
3152 sprintf(handle, "%04hx", handle_num);
3153 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3155 /* Store Database Hash value if available */
3156 bt_uuid16_create(&hash_uuid, GATT_CHARAC_DB_HASH);
3157 if (!bt_uuid_cmp(&uuid, &hash_uuid)) {
3158 const uint8_t *hash = NULL;
3160 attr = gatt_db_get_attribute(saver->device->db, value_handle);
3162 gatt_db_attribute_read(attr, 0, BT_ATT_OP_READ_REQ, NULL,
3163 db_hash_read_value_cb, &hash);
3165 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:"
3166 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3167 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3168 "%02hhx%02hhx:%s", value_handle, properties,
3169 hash[0], hash[1], hash[2], hash[3],
3170 hash[4], hash[5], hash[6], hash[7],
3171 hash[8], hash[9], hash[10], hash[11],
3172 hash[12], hash[13], hash[14], hash[15],
3175 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3176 value_handle, properties, uuid_str);
3179 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3180 value_handle, properties, uuid_str);
3182 g_key_file_set_string(key_file, "Attributes", handle, value);
3184 gatt_db_service_foreach_desc(attr, store_desc, saver);
3187 static void store_incl(struct gatt_db_attribute *attr, void *user_data)
3189 struct gatt_saver *saver = user_data;
3190 GKeyFile *key_file = saver->key_file;
3191 struct gatt_db_attribute *service;
3192 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3193 uint16_t handle_num, start, end;
3196 if (!gatt_db_attribute_get_incl_data(attr, &handle_num, &start, &end)) {
3197 warn("Error storing included service - can't get data");
3201 service = gatt_db_get_attribute(saver->device->db, start);
3203 warn("Error storing included service - can't find it");
3207 sprintf(handle, "%04hx", handle_num);
3209 gatt_db_attribute_get_service_uuid(service, &uuid);
3210 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3211 sprintf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", start,
3214 g_key_file_set_string(key_file, "Attributes", handle, value);
3217 static void store_service(struct gatt_db_attribute *attr, void *user_data)
3219 struct gatt_saver *saver = user_data;
3220 GKeyFile *key_file = saver->key_file;
3221 char uuid_str[MAX_LEN_UUID_STR], handle[6], value[256];
3222 uint16_t start, end;
3227 if (!gatt_db_attribute_get_service_data(attr, &start, &end, &primary,
3229 warn("Error storing service - can't get data");
3233 sprintf(handle, "%04hx", start);
3235 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3238 type = GATT_PRIM_SVC_UUID_STR;
3240 type = GATT_SND_SVC_UUID_STR;
3242 sprintf(value, "%s:%04hx:%s", type, end, uuid_str);
3244 g_key_file_set_string(key_file, "Attributes", handle, value);
3246 gatt_db_service_foreach_incl(attr, store_incl, saver);
3247 gatt_db_service_foreach_char(attr, store_chrc, saver);
3250 static void store_gatt_db(struct btd_device *device)
3252 char filename[PATH_MAX];
3255 GError *gerr = NULL;
3258 struct gatt_saver saver;
3260 if (device_address_is_private(device)) {
3261 DBG("Can't store GATT db for private addressed device %s",
3266 if (!gatt_cache_is_enabled(device))
3269 ba2str(&device->bdaddr, dst_addr);
3271 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
3272 btd_adapter_get_storage_dir(device->adapter),
3274 create_file(filename, 0600);
3276 key_file = g_key_file_new();
3277 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
3278 error("Unable to load key file from %s: (%s)", filename,
3283 /* Remove current attributes since it might have changed */
3284 g_key_file_remove_group(key_file, "Attributes", NULL);
3286 saver.key_file = key_file;
3287 saver.device = device;
3289 gatt_db_foreach_service(device->db, NULL, store_service, &saver);
3291 data = g_key_file_to_data(key_file, &length, NULL);
3292 if (!g_file_set_contents(filename, data, length, &gerr)) {
3293 error("Unable set contents for %s: (%s)", filename,
3299 g_key_file_free(key_file);
3303 static void browse_request_complete(struct browse_req *req, uint8_t type,
3304 uint8_t bdaddr_type, int err)
3306 struct btd_device *dev = req->device;
3307 DBusMessage *reply = NULL;
3310 if (req->type != type)
3316 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, "Pair")) {
3317 if (!device_is_paired(dev, bdaddr_type)) {
3318 reply = btd_error_failed(req->msg, "Not paired");
3322 if (dev->pending_paired) {
3323 g_dbus_emit_property_changed(dbus_conn, dev->path,
3324 DEVICE_INTERFACE, "Paired");
3325 dev->pending_paired = false;
3328 /* Disregard browse errors in case of Pair */
3329 reply = g_dbus_create_reply(req->msg, DBUS_TYPE_INVALID);
3334 /* Fallback to LE bearer if supported */
3335 if (err == -EHOSTDOWN && bdaddr_type == BDADDR_BREDR &&
3336 dev->le && !dev->le_state.connected) {
3337 err = device_connect_le(dev);
3341 reply = btd_error_failed(req->msg,
3342 bdaddr_type == BDADDR_BREDR ?
3343 btd_error_bredr_conn_from_errno(err) :
3344 btd_error_le_conn_from_errno(err));
3348 /* if successfully resolved services we need to free browsing request
3349 * before passing message back to connect functions, otherwise
3350 * device->browse is set and "InProgress" error is returned instead
3351 * of actually connecting services
3353 msg = dbus_message_ref(req->msg);
3354 browse_request_free(req);
3357 if (dbus_message_is_method_call(msg, DEVICE_INTERFACE, "Connect"))
3358 reply = dev_connect(dbus_conn, msg, dev);
3359 else if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
3361 reply = connect_profile(dbus_conn, msg, dev);
3363 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
3365 dbus_message_unref(msg);
3369 g_dbus_send_message(dbus_conn, reply);
3372 browse_request_free(req);
3375 void device_set_refresh_discovery(struct btd_device *dev, bool refresh)
3377 dev->refresh_discovery = refresh;
3380 static void device_set_svc_refreshed(struct btd_device *device, bool value)
3382 if (device->svc_refreshed == value)
3385 device->svc_refreshed = value;
3387 g_dbus_emit_property_changed(dbus_conn, device->path,
3388 DEVICE_INTERFACE, "ServicesResolved");
3391 static void device_svc_resolved(struct btd_device *dev, uint8_t browse_type,
3392 uint8_t bdaddr_type, int err)
3394 struct bearer_state *state = get_state(dev, bdaddr_type);
3395 struct browse_req *req = dev->browse;
3397 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3398 DBG("%s bdaddr_type %d err %d", dev->path, bdaddr_type, err);
3400 DBG("%s err %d", dev->path, err);
3403 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3404 state->svc_resolved = true;
3407 state->svc_resolved = true;
3410 /* Disconnection notification can happen before this function
3411 * gets called, so don't set svc_refreshed for a disconnected
3414 if (state->connected)
3415 device_set_svc_refreshed(dev, true);
3417 g_slist_free_full(dev->eir_uuids, g_free);
3418 dev->eir_uuids = NULL;
3420 if (dev->pending_paired) {
3421 g_dbus_emit_property_changed(dbus_conn, dev->path,
3422 DEVICE_INTERFACE, "Paired");
3423 dev->pending_paired = false;
3426 if (!dev->temporary) {
3427 store_device_info(dev);
3429 if (bdaddr_type != BDADDR_BREDR && err == 0)
3430 store_services(dev);
3433 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3435 browse_request_complete(req, browse_type, bdaddr_type, err);
3438 while (dev->svc_callbacks) {
3439 struct svc_callback *cb = dev->svc_callbacks->data;
3441 if (cb->idle_id > 0)
3442 g_source_remove(cb->idle_id);
3444 cb->func(dev, err, cb->user_data);
3446 dev->svc_callbacks = g_slist_delete_link(dev->svc_callbacks,
3447 dev->svc_callbacks);
3451 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3455 /* If bdaddr_type is LE but req is for SDP, don't complete browse req. */
3456 if (bdaddr_type != BDADDR_BREDR && req->search_uuid) {
3457 DBG("Discover comp. is for LE but browse req. is for SDP.");
3461 browse_request_complete(req, browse_type, bdaddr_type, err);
3463 btd_device_update_allowed_services(dev);
3464 device_resolved_drivers(dev->adapter, dev);
3467 static struct bonding_req *bonding_request_new(DBusMessage *msg,
3468 struct btd_device *device,
3469 uint8_t bdaddr_type,
3470 struct agent *agent)
3472 struct bonding_req *bonding;
3475 ba2str(&device->bdaddr, addr);
3476 DBG("Requesting bonding for %s", addr);
3478 bonding = g_new0(struct bonding_req, 1);
3480 bonding->msg = dbus_message_ref(msg);
3481 bonding->bdaddr_type = bdaddr_type;
3483 bonding->cb_iter = btd_adapter_pin_cb_iter_new(device->adapter);
3485 /* Marks the bonding start time for the first attempt on request
3486 * construction. The following attempts will be updated on
3487 * device_bonding_retry. */
3488 clock_gettime(CLOCK_MONOTONIC, &bonding->attempt_start_time);
3491 bonding->agent = agent_ref(agent);
3496 void device_bonding_restart_timer(struct btd_device *device)
3498 if (!device || !device->bonding)
3501 clock_gettime(CLOCK_MONOTONIC, &device->bonding->attempt_start_time);
3504 static void bonding_request_stop_timer(struct bonding_req *bonding)
3506 struct timespec current;
3508 clock_gettime(CLOCK_MONOTONIC, ¤t);
3510 /* Compute the time difference in ms. */
3511 bonding->last_attempt_duration_ms =
3512 (current.tv_sec - bonding->attempt_start_time.tv_sec) * 1000L +
3513 (current.tv_nsec - bonding->attempt_start_time.tv_nsec)
3517 /* Returns the duration of the last bonding attempt in milliseconds. The
3518 * duration is measured starting from the latest of the following three
3519 * events and finishing when the Command complete event is received for the
3520 * authentication request:
3521 * - MGMT_OP_PAIR_DEVICE is sent,
3522 * - MGMT_OP_PIN_CODE_REPLY is sent and
3523 * - Command complete event is received for the sent MGMT_OP_PIN_CODE_REPLY.
3525 long device_bonding_last_duration(struct btd_device *device)
3527 struct bonding_req *bonding = device->bonding;
3532 return bonding->last_attempt_duration_ms;
3535 static void create_bond_req_exit(DBusConnection *conn, void *user_data)
3537 struct btd_device *device = user_data;
3540 ba2str(&device->bdaddr, addr);
3541 DBG("%s: requestor exited before bonding was completed", addr);
3544 device_cancel_authentication(device, FALSE);
3546 if (device->bonding) {
3547 device->bonding->listener_id = 0;
3548 device_request_disconnect(device, NULL);
3552 static void bonding_request_free(struct bonding_req *bonding)
3557 if (bonding->listener_id)
3558 g_dbus_remove_watch(dbus_conn, bonding->listener_id);
3561 dbus_message_unref(bonding->msg);
3563 if (bonding->cb_iter)
3564 g_free(bonding->cb_iter);
3566 if (bonding->agent) {
3567 agent_cancel(bonding->agent);
3568 agent_unref(bonding->agent);
3569 bonding->agent = NULL;
3572 if (bonding->retry_timer)
3573 g_source_remove(bonding->retry_timer);
3575 if (bonding->device)
3576 bonding->device->bonding = NULL;
3581 static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg,
3584 struct btd_device *device = data;
3585 struct btd_adapter *adapter = device->adapter;
3586 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3587 struct bearer_state *state;
3589 uint8_t bdaddr_type;
3591 struct agent *agent;
3592 struct bonding_req *bonding;
3594 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3596 bool connect_le = FALSE;
3597 uint8_t link_type = DEV_CONNECTED_NONE;
3601 btd_device_set_temporary(device, false);
3603 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3604 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &conn_type,
3605 DBUS_TYPE_INVALID) == FALSE)
3607 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
3609 return btd_error_invalid_args(msg);
3611 if (device->bonding)
3612 return btd_error_in_progress(msg);
3614 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3615 if (conn_type == DEV_CONN_DEFAULT) {
3616 link_type = device_get_connected_state(device);
3618 if (link_type == DEV_CONNECTED_BREDR) {
3619 if (device_is_bonded(device, DEV_CONN_BREDR))
3620 return btd_error_already_exists(msg);
3621 conn_type = DEV_CONN_BREDR;
3622 } else if (link_type == DEV_CONNECTED_LE) {
3623 if (device_is_bonded(device, DEV_CONN_LE))
3624 return btd_error_already_exists(msg);
3625 conn_type = DEV_CONN_LE;
3627 if (device_is_bonded(device, DEV_CONN_BREDR))
3628 return btd_error_already_exists(msg);
3629 else if (device_is_bonded(device, DEV_CONN_LE))
3630 return btd_error_already_exists(msg);
3633 conn_type = DEV_CONN_BREDR;
3634 else if (device->le)
3635 conn_type = DEV_CONN_LE;
3637 conn_type = DEV_CONN_BREDR;
3640 if (device_is_bonded(device, conn_type))
3641 return btd_error_already_exists(msg);
3643 bdaddr_type = device->bdaddr_type;
3645 if (device->bredr_state.bonded)
3646 bdaddr_type = device->bdaddr_type;
3647 else if (device->le_state.bonded)
3648 bdaddr_type = BDADDR_BREDR;
3650 bdaddr_type = select_conn_bearer(device);
3652 state = get_state(device, bdaddr_type);
3655 return btd_error_already_exists(msg);
3658 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3659 DBG("conn_type %d, link_type %d, bdaddr_type %d, device->bredr %d",
3660 conn_type, link_type, bdaddr_type, device->bredr);
3661 if (conn_type == DEV_CONN_LE &&
3662 (device_is_bredrle(device) || bdaddr_type != BDADDR_BREDR)) {
3663 DBG("LE Connect request");
3668 sender = dbus_message_get_sender(msg);
3670 agent = agent_get(sender);
3672 io_cap = agent_get_io_capability(agent);
3674 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
3676 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3677 if ((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3679 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3681 bonding = bonding_request_new(msg, device, BDADDR_BREDR, agent);
3683 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3689 bonding->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
3690 sender, create_bond_req_exit,
3693 device->bonding = bonding;
3694 bonding->device = device;
3696 /* Due to a bug in the kernel we might loose out on ATT commands
3697 * that arrive during the SMP procedure, so connect the ATT
3698 * channel first and only then start pairing (there's code for
3699 * this in the ATT connect callback)
3701 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3702 if (((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3703 (connect_le)) && !device->le_state.connected)
3704 err = device_connect_le(device);
3705 else if (connect_le) /* Send bonding request if LE is already connected*/
3706 err = adapter_create_bonding(adapter, &device->bdaddr,
3707 bdaddr_type, io_cap);
3709 err = adapter_create_bonding(adapter, &device->bdaddr,
3710 BDADDR_BREDR, io_cap);
3712 if (bdaddr_type != BDADDR_BREDR) {
3713 if (!state->connected && btd_le_connect_before_pairing())
3714 err = device_connect_le(device);
3716 err = adapter_create_bonding(adapter, &device->bdaddr,
3717 device->bdaddr_type,
3720 err = adapter_create_bonding(adapter, &device->bdaddr,
3721 BDADDR_BREDR, io_cap);
3726 bonding_request_free(device->bonding);
3727 return btd_error_failed(msg, strerror(-err));
3733 static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
3736 case MGMT_STATUS_SUCCESS:
3737 return dbus_message_new_method_return(msg);
3739 case MGMT_STATUS_CONNECT_FAILED:
3740 return dbus_message_new_error(msg,
3741 ERROR_INTERFACE ".ConnectionAttemptFailed",
3743 case MGMT_STATUS_TIMEOUT:
3744 return dbus_message_new_error(msg,
3745 ERROR_INTERFACE ".AuthenticationTimeout",
3746 "Authentication Timeout");
3747 case MGMT_STATUS_BUSY:
3748 case MGMT_STATUS_REJECTED:
3749 return dbus_message_new_error(msg,
3750 ERROR_INTERFACE ".AuthenticationRejected",
3751 "Authentication Rejected");
3752 case MGMT_STATUS_CANCELLED:
3753 case MGMT_STATUS_NO_RESOURCES:
3754 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3755 case MGMT_STATUS_DISCONNECTED:
3757 return dbus_message_new_error(msg,
3758 ERROR_INTERFACE ".AuthenticationCanceled",
3759 "Authentication Canceled");
3760 case MGMT_STATUS_ALREADY_PAIRED:
3761 return dbus_message_new_error(msg,
3762 ERROR_INTERFACE ".AlreadyExists",
3765 return dbus_message_new_error(msg,
3766 ERROR_INTERFACE ".AuthenticationFailed",
3767 "Authentication Failed");
3771 static void device_cancel_bonding(struct btd_device *device, uint8_t status)
3773 struct bonding_req *bonding = device->bonding;
3780 ba2str(&device->bdaddr, addr);
3781 DBG("Canceling bonding request for %s", addr);
3784 device_cancel_authentication(device, FALSE);
3786 reply = new_authentication_return(bonding->msg, status);
3787 g_dbus_send_message(dbus_conn, reply);
3789 bonding_request_cancel(bonding);
3790 bonding_request_free(bonding);
3793 static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
3796 struct btd_device *device = data;
3797 struct bonding_req *req = device->bonding;
3802 return btd_error_does_not_exist(msg);
3804 device_cancel_bonding(device, MGMT_STATUS_CANCELLED);
3806 return dbus_message_new_method_return(msg);
3809 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3810 static DBusMessage *discover_services(DBusConnection *conn,
3811 DBusMessage *msg, void *user_data)
3813 struct btd_device *device = user_data;
3814 const char *pattern;
3818 return btd_error_in_progress(msg);
3820 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
3821 DBUS_TYPE_INVALID) == FALSE)
3822 return btd_error_invalid_args(msg);
3824 err = device_browse_sdp(device, msg);
3831 return btd_error_failed(msg,
3832 "Unable to search the SDP services");
3835 static const char *browse_request_get_requestor(struct browse_req *req)
3840 return dbus_message_get_sender(req->msg);
3843 static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
3846 DBusMessageIter entry;
3848 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
3851 dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
3853 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
3855 dbus_message_iter_close_container(dict, &entry);
3858 static void discover_services_reply(struct browse_req *req, int err,
3862 DBusMessageIter iter, dict;
3871 if (err == -EHOSTDOWN)
3872 err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
3874 err_if = ERROR_INTERFACE ".Failed";
3876 reply = dbus_message_new_error(req->msg, err_if,
3878 g_dbus_send_message(dbus_conn, reply);
3882 reply = dbus_message_new_method_return(req->msg);
3886 dbus_message_iter_init_append(reply, &iter);
3888 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3889 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3890 DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
3891 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
3893 for (seq = recs; seq; seq = seq->next) {
3894 sdp_record_t *rec = (sdp_record_t *) seq->data;
3900 result = g_string_new(NULL);
3902 convert_sdp_record_to_xml(rec, result,
3903 (void *) g_string_append);
3906 if (!g_utf8_validate(result->str, -1, NULL)) {
3909 DBG("UTF8 invalid string, make valid");
3910 ptr = g_utf8_make_valid(result->str, -1);
3911 iter_append_record(&dict, rec->handle, ptr);
3914 iter_append_record(&dict, rec->handle, result->str);
3918 g_string_free(result, TRUE);
3921 dbus_message_iter_close_container(&iter, &dict);
3923 g_dbus_send_message(dbus_conn, reply);
3926 static DBusMessage *cancel_discover(DBusConnection *conn,
3927 DBusMessage *msg, void *user_data)
3929 struct btd_device *device = user_data;
3930 const char *sender = dbus_message_get_sender(msg);
3931 const char *requestor;
3933 if (!device->browse)
3934 return btd_error_does_not_exist(msg);
3936 if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
3937 "DiscoverServices"))
3938 return btd_error_not_authorized(msg);
3940 requestor = browse_request_get_requestor(device->browse);
3942 /* only the discover requestor can cancel the inquiry process */
3943 if (!requestor || !g_str_equal(requestor, sender))
3944 return btd_error_not_authorized(msg);
3946 discover_services_reply(device->browse, -ECANCELED, NULL);
3949 browse_request_cancel(device->browse);
3951 return dbus_message_new_method_return(msg);
3954 void device_set_gatt_connected(struct btd_device *device, gboolean connected)
3956 if (device == NULL) {
3957 error("device is NULL");
3961 if (device->gatt_connected == connected) {
3962 error("same state change for gatt_connected : %d", connected);
3965 DBG("GattConnected %d", connected);
3967 device->gatt_connected = connected;
3968 g_dbus_emit_property_changed(dbus_conn, device->path,
3969 DEVICE_INTERFACE, "GattConnected");
3972 static DBusMessage *connect_le(DBusConnection *conn, DBusMessage *msg,
3975 struct btd_device *dev = user_data;
3976 dbus_bool_t auto_connect = FALSE;
3981 * If a LE connection is requested without device discovery,
3982 * we try to get device object. Here, technology can be updated
3983 * if there is matched device object. Or, a new device object
3986 dev = btd_adapter_get_device(dev->adapter, &dev->bdaddr,
3989 error("Unable to get device object");
3990 return btd_error_not_supported(msg);
3994 if (dev->le_state.connected)
3995 return dbus_message_new_method_return(msg);
3997 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &auto_connect,
3999 return btd_error_invalid_args(msg);
4001 btd_device_set_temporary(dev, false);
4004 DBG("Start BLE auto connection");
4005 dev->disable_auto_connect = FALSE;
4006 device_set_auto_connect(dev, TRUE);
4008 return dbus_message_new_method_return(msg);
4011 err = device_connect_le(dev);
4013 return btd_error_failed(msg, strerror(-err));
4015 dev->connect = dbus_message_ref(msg);
4020 static DBusMessage *disconnect_le(DBusConnection *conn, DBusMessage *msg,
4023 struct btd_device *dev = user_data;
4026 return btd_error_not_supported(msg);
4029 * Disable connections through passive sccanning
4031 if (dev->auto_connect) {
4032 DBG("Stop BLE auto connection");
4033 dev->disable_auto_connect = FALSE;
4034 device_set_auto_connect(dev, FALSE);
4036 if (!dev->le_state.connected) {
4037 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
4042 device_request_disconnect(dev, msg);
4047 static DBusMessage *connect_ipsp(DBusConnection *conn, DBusMessage *msg,
4050 struct btd_device *device = user_data;
4052 DBG("bdaddr_type %d", device->bdaddr_type);
4054 if (device->bdaddr_type == BDADDR_BREDR) {
4056 device->bdaddr_type = BDADDR_LE_PUBLIC;
4058 device = btd_adapter_get_device(device->adapter,
4059 &device->bdaddr, BDADDR_LE_PUBLIC);
4061 return btd_error_no_such_adapter(msg);
4065 if (device->ipsp_connected)
4066 return btd_error_already_connected(msg);
4068 /* Initiate Connection for 6Lowan*/
4069 if (btd_adapter_connect_ipsp(device->adapter, &device->bdaddr,
4070 device->bdaddr_type) != 0)
4071 return btd_error_failed(msg, "ConnectFailed");
4073 return dbus_message_new_method_return(msg);;
4076 static DBusMessage *disconnect_ipsp(DBusConnection *conn, DBusMessage *msg,
4079 struct btd_device *device = user_data;
4080 DBG("bdaddr_type %d", device->bdaddr_type);
4082 if (device->bdaddr_type == BDADDR_BREDR)
4083 return btd_error_not_supported(msg);
4085 if (!device->ipsp_connected)
4086 return btd_error_not_connected(msg);
4088 /* Disconnect the 6Lowpan connection */
4089 if (btd_adapter_disconnect_ipsp(device->adapter, &device->bdaddr,
4090 device->bdaddr_type) != 0)
4091 return btd_error_failed(msg, "DisconnectFailed");
4093 /* TODO: Handle disconnection of GATT connection, If the connection
4094 * is established as part of IPSP connection. */
4096 return dbus_message_new_method_return(msg);;
4099 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4100 static GSList *find_otc_conn_info(GSList *list, const char *path)
4104 for (l = list; l != NULL; l = g_slist_next(l)) {
4105 struct otc_conn_info *info = l->data;
4107 if (g_strcmp0(info->dev_path, path) == 0)
4114 static gboolean otc_disconnected_cb(GIOChannel *chan, GIOCondition cond,
4117 struct otc_conn_info *conn_info;
4118 const char *dev_path = (const char *) user_data;
4121 DBG("OTC Disconnected");
4123 l = find_otc_conn_info(otc_connection_list, dev_path);
4127 conn_info = l->data;
4128 conn_info->otc_connected = false;
4130 g_dbus_emit_signal(dbus_conn, dev_path,
4131 DEVICE_INTERFACE, "OtcDisconnected",
4134 if (conn_info->io) {
4135 g_io_channel_shutdown(conn_info->io, TRUE, NULL);
4136 g_io_channel_unref(conn_info->io);
4139 otc_connection_list = g_slist_remove(otc_connection_list, conn_info);
4145 static void otc_connect_cb(GIOChannel *chan, GError *gerr,
4148 const char *dev_path;
4150 struct otc_conn_info *conn_info = NULL;
4151 DBusMessage *msg = NULL;
4152 DBusMessageIter iter;
4158 dev_path = (const char *) user_data;
4159 l = find_otc_conn_info(otc_connection_list, dev_path);
4164 conn_info = l->data;
4165 conn_info->otc_connected = true;
4167 fd = g_io_channel_unix_get_fd(chan);
4169 DBG("OTC Connected fd [%d], role [%s]",
4170 fd, conn_info->role ? "server" : "client");
4171 DBG("dev_path [%s]", dev_path);
4173 g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4174 otc_disconnected_cb, (gpointer) dev_path);
4176 if (conn_info->role == BT_OTP_CLIENT_ROLE) {
4177 msg = dbus_message_new_method_call(BT_OTC_SERVICE_NAME,
4179 BT_OTC_INTERFACE_NAME,
4181 } else if (conn_info->role == BT_OTP_SERVER_ROLE) {
4182 msg = dbus_message_new_method_call(BT_OTS_SERVICE_NAME,
4184 BT_OTS_INTERFACE_NAME,
4189 error("Unable to create NewConnection call");
4193 dbus_message_iter_init_append(msg, &iter);
4195 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4197 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4199 if (!g_dbus_send_message(dbus_conn, msg)) {
4200 error("sending NewConnection failed");
4201 dbus_message_unref(msg);
4205 int btd_adapter_connect_otc(struct btd_device *device)
4207 struct btd_adapter *adapter = device_get_adapter(device);
4208 const bdaddr_t *src = btd_adapter_get_address(adapter);
4209 uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4210 const bdaddr_t *dest = device_get_address(device);
4211 uint8_t dest_type = device->bdaddr_type;
4212 struct otc_conn_info *conn_info = NULL;
4213 const char *dev_path = device_get_path(device);
4214 GError *gerr = NULL;
4216 conn_info = g_malloc0(sizeof(struct otc_conn_info));
4218 conn_info->io = bt_io_connect(otc_connect_cb,
4219 (gpointer) dev_path, NULL, &gerr,
4220 BT_IO_OPT_SOURCE_BDADDR, src,
4221 BT_IO_OPT_SOURCE_TYPE, src_type,
4222 BT_IO_OPT_DEST_BDADDR, dest,
4223 BT_IO_OPT_DEST_TYPE, dest_type,
4224 BT_IO_OPT_PSM, OTP_PSM,
4225 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4228 if (!conn_info->io) {
4229 error("OTC Connect failed : %s", gerr->message);
4235 conn_info->dev_path = dev_path;
4236 conn_info->role = BT_OTP_CLIENT_ROLE;
4237 conn_info->otc_connected = false;
4238 g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4240 otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4244 static DBusMessage *connect_otc(DBusConnection *conn, DBusMessage *msg,
4247 struct btd_device *device = user_data;
4251 return btd_error_invalid_args(msg);
4253 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4256 struct otc_conn_info *info = l->data;
4257 if (info->otc_connected)
4258 return btd_error_already_connected(msg);
4260 return btd_error_busy(msg);
4263 if (btd_adapter_connect_otc(device) != 0)
4264 return btd_error_failed(msg, "ConnectFailed");
4266 return dbus_message_new_method_return(msg);
4269 static DBusMessage *disconnect_otc(DBusConnection *conn, DBusMessage *msg,
4272 struct btd_device *device = user_data;
4273 struct otc_conn_info *info = NULL;
4277 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4280 return btd_error_does_not_exist(msg);
4284 if (!info->otc_connected)
4285 return btd_error_not_connected(msg);
4287 sock = g_io_channel_unix_get_fd(info->io);
4289 shutdown(sock, SHUT_RDWR);
4291 g_io_channel_shutdown(info->io, FALSE, NULL);
4293 g_io_channel_unref(info->io);
4296 return dbus_message_new_method_return(msg);
4299 int btd_adapter_listen_otc(struct btd_device *device)
4301 struct btd_adapter *adapter = device_get_adapter(device);
4302 const bdaddr_t *src = btd_adapter_get_address(adapter);
4303 uint8_t type = btd_adapter_get_le_address_type(adapter);
4304 struct otc_conn_info *conn_info = NULL;
4305 const char *dev_path = device_get_path(device);
4306 GError *gerr = NULL;
4308 conn_info = g_malloc0(sizeof(struct otc_conn_info));
4310 conn_info->io = bt_io_listen(otc_connect_cb, NULL, (gpointer) dev_path,
4312 BT_IO_OPT_SOURCE_BDADDR, src,
4313 BT_IO_OPT_SOURCE_TYPE, type,
4314 BT_IO_OPT_PSM, OTP_PSM,
4315 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4318 if (!conn_info->io) {
4319 error("OTC Listen failed : %s", gerr->message);
4325 conn_info->dev_path = dev_path;
4326 conn_info->otc_connected = false;
4327 conn_info->role = BT_OTP_SERVER_ROLE;
4328 g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4330 otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4334 static DBusMessage *listen_otc(DBusConnection *conn, DBusMessage *msg,
4337 struct btd_device *device = user_data;
4341 return btd_error_invalid_args(msg);
4343 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4346 struct otc_conn_info *info = l->data;
4347 if (info->otc_connected)
4348 return btd_error_already_connected(msg);
4350 return btd_error_busy(msg);
4353 if (btd_adapter_listen_otc(device) != 0)
4354 return btd_error_failed(msg, "ListenFailed");
4356 return dbus_message_new_method_return(msg);
4360 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4361 /********************* L2CAP LE SOCKET IMPLEMENTATION *************************/
4362 static GSList *find_l2cap_le_profile_info(GSList *list, const char *owner,
4366 for (l = list; l != NULL; l = g_slist_next(l)) {
4367 struct l2cap_le_profile_info *info = l->data;
4372 if (g_strcmp0(info->owner, owner))
4375 if (!g_strcmp0(info->path, path))
4382 static int parse_l2cap_le_opt(struct l2cap_le_profile_info *info,
4383 const char *key, DBusMessageIter *value)
4385 int type = dbus_message_iter_get_arg_type(value);
4388 if (strcasecmp(key, "RequireAuthentication") == 0) {
4389 if (type != DBUS_TYPE_BOOLEAN)
4392 dbus_message_iter_get_basic(value, &b);
4395 info->sec_level = BT_IO_SEC_MEDIUM;
4397 info->sec_level = BT_IO_SEC_LOW;
4398 } else if (strcasecmp(key, "RequireAuthorization") == 0) {
4399 if (type != DBUS_TYPE_BOOLEAN)
4401 dbus_message_iter_get_basic(value, &b);
4402 info->authorize = b;
4408 static struct l2cap_le_profile_info *create_l2cap_le_socket(const char *owner,
4409 const char *path, int psm, DBusMessageIter *opts)
4411 struct l2cap_le_profile_info *info = NULL;
4413 if (psm < 0 || psm > BTD_L2CAP_LE_PSM_MAX)
4416 info = g_malloc0(sizeof(struct l2cap_le_profile_info));
4418 info->owner = g_strdup(owner);
4419 info->path = g_strdup(path);
4422 while (dbus_message_iter_get_arg_type(opts) == DBUS_TYPE_DICT_ENTRY) {
4423 DBusMessageIter value, entry;
4426 dbus_message_iter_recurse(opts, &entry);
4427 dbus_message_iter_get_basic(&entry, &key);
4429 dbus_message_iter_next(&entry);
4430 dbus_message_iter_recurse(&entry, &value);
4432 if (parse_l2cap_le_opt(info, key, &value) < 0)
4433 error("Invalid value for l2cap_le_socket option %s", key);
4435 dbus_message_iter_next(opts);
4439 info->name = g_strdup_printf("%s%s/%d", owner, path, psm);
4444 static void l2cap_le_io_destroy(gpointer p)
4446 struct l2cap_le_conn_info *conn = p;
4448 if (conn->io_id > 0)
4449 g_source_remove(conn->io_id);
4452 g_io_channel_shutdown(conn->io, FALSE, NULL);
4453 g_io_channel_unref(conn->io);
4456 if (conn->auth_id != 0)
4457 btd_cancel_authorization(conn->auth_id);
4459 if (conn->auth_uuid)
4460 free(conn->auth_uuid);
4465 static gboolean l2cap_le_disconnected_cb(GIOChannel *chan,
4466 GIOCondition cond, gpointer user_data)
4468 struct l2cap_le_conn_info *conn = user_data;
4469 struct l2cap_le_profile_info *info = conn->profile_info;
4471 DBG(" L2CAP LE socket disconnected role [%s] ",
4472 info->role == BT_L2CAP_LE_SERVER_ROLE ? "server" : "client");
4474 g_dbus_emit_signal(dbus_conn, conn->dev_path,
4475 DEVICE_INTERFACE, "L2CAPLEDisconnected",
4478 conn->connected = false;
4480 info->conn = g_slist_remove(info->conn, conn);
4481 l2cap_le_io_destroy(conn);
4485 static void l2cap_le_connect_cb(GIOChannel *chan, GError *gerr,
4488 struct l2cap_le_conn_info *conn = (struct l2cap_le_conn_info *) user_data;
4489 struct l2cap_le_profile_info *info = conn->profile_info;
4490 DBusMessage *msg = NULL;
4491 DBusMessageIter iter;
4492 const char *dev_path;
4494 GError *io_err = NULL;
4497 if (!bt_io_get(chan, &io_err,
4498 BT_IO_OPT_DEST, addr,
4499 BT_IO_OPT_INVALID)) {
4501 error("%s failed %s", info->name, gerr->message);
4502 g_error_free(io_err);
4505 error("Unable to get connect data for %s: %s",
4506 info->name, io_err->message);
4513 error("%s failed to connect to %s: %s", info->name, addr,
4518 conn->connected = true;
4520 fd = g_io_channel_unix_get_fd(chan);
4522 if (conn->io_id == 0)
4523 conn->io_id = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4524 l2cap_le_disconnected_cb, conn);
4526 msg = dbus_message_new_method_call(info->owner,
4528 BT_L2CAP_LE_INTERFACE_NAME,
4532 error("Unable to create NewConnection call");
4536 dev_path = conn->dev_path;
4538 dbus_message_iter_init_append(msg, &iter);
4540 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4542 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4544 if (!g_dbus_send_message(dbus_conn, msg)) {
4545 error("sending NewConnection failed");
4546 dbus_message_unref(msg);
4550 DBG("L2CAP_LE Connected fd [%d] addr [%s], role [%s]",fd, addr,
4551 info->role == BT_L2CAP_LE_SERVER_ROLE ? "server" : "client");
4556 g_error_free(io_err);
4558 info->conn = g_slist_remove(info->conn, conn);
4559 l2cap_le_io_destroy(conn);
4562 static struct l2cap_le_conn_info *create_l2cap_le_conn(
4563 struct l2cap_le_conn_info *server, GIOChannel *io,
4564 bdaddr_t *src, bdaddr_t *dst, uint8_t dst_type)
4566 struct l2cap_le_conn_info *conn;
4568 struct btd_device *device;
4569 struct btd_adapter *adapter = adapter_find(src);
4572 error("could not find adapter");
4576 device = btd_adapter_get_device(adapter, dst, dst_type);
4578 error("could not find Device");
4582 conn = g_new0(struct l2cap_le_conn_info, 1);
4583 conn->io = g_io_channel_ref(io);
4584 conn->profile_info = server->profile_info;
4585 conn->dev_path = device_get_path(device);
4587 cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
4588 conn->io_id = g_io_add_watch(io, cond, l2cap_le_disconnected_cb, conn);
4593 static void l2cap_le_auth(DBusError *err, void *user_data)
4595 struct l2cap_le_conn_info *conn = user_data;
4596 struct l2cap_le_profile_info *info = conn->profile_info;
4597 GError *gerr = NULL;
4602 bt_io_get(conn->io, &gerr, BT_IO_OPT_DEST, addr, BT_IO_OPT_INVALID);
4604 error("Unable to get connect data for %s: %s",
4605 info->name, gerr->message);
4610 if (err && dbus_error_is_set(err)) {
4611 error("%s rejected %s: %s", info->name, addr, err->message);
4615 if (!bt_io_accept(conn->io, l2cap_le_connect_cb, conn, NULL, &gerr)) {
4616 error("bt_io_accept: %s", gerr->message);
4621 DBG("%s authorized to connect to %s", addr, info->name);
4625 info->conn = g_slist_remove(info->conn, conn);
4626 l2cap_le_io_destroy(conn);
4629 static void l2cap_le_confirm(GIOChannel *io, gpointer user_data)
4631 struct l2cap_le_conn_info *server = user_data;
4632 struct l2cap_le_profile_info *info = server->profile_info;
4633 struct l2cap_le_conn_info *conn;
4634 GError *gerr = NULL;
4638 char *uuid = g_malloc0(UUID_LEN * sizeof(char));
4640 bt_io_get(io, &gerr,
4641 BT_IO_OPT_SOURCE_BDADDR, &src,
4642 BT_IO_OPT_DEST_BDADDR, &dst,
4643 BT_IO_OPT_DEST_TYPE, &dst_type,
4644 BT_IO_OPT_DEST, addr,
4647 error("%s failed to get connect data: %s", info->name,
4653 DBG("incoming connect from %s for authorization", addr);
4655 conn = create_l2cap_le_conn(server, io, &src, &dst, dst_type);
4659 /* Use custom uuid of the form "FFFFFFFF-FFFF-FFFF-FFFF-<psm in 12 digits>"
4660 * for authorizing l2cap_le socket using existing flow.
4661 * This custom uuid will be used in the BT-OAL layer to identify the
4662 * l2cap_le socket authorization and extracting psm from it.
4664 snprintf(uuid, UUID_LEN, "%s%012d", L2CAP_LE_UUID_SUBSTR, server->psm);
4665 conn->auth_uuid = uuid;
4667 conn->auth_id = btd_request_authorization(&src, &dst,
4668 (const char *)conn->auth_uuid, l2cap_le_auth, conn);
4669 if (conn->auth_id == 0) {
4670 error("%s authorization failure", info->name);
4671 l2cap_le_io_destroy(conn);
4675 info->conn = g_slist_append(info->conn, conn);
4677 DBG("%s authorizing connection from %s", info->name, addr);
4680 static void l2cap_le_direct_connect(GIOChannel *io, GError *err,
4683 struct l2cap_le_conn_info *server = user_data;
4684 struct l2cap_le_profile_info *info = server->profile_info;
4685 struct l2cap_le_conn_info *conn;
4686 GError *gerr = NULL;
4690 bt_io_get(io, &gerr,
4691 BT_IO_OPT_SOURCE_BDADDR, &src,
4692 BT_IO_OPT_DEST_BDADDR, &dst,
4693 BT_IO_OPT_DEST_TYPE, &dst_type,
4696 error("%s failed to get connect data: %s", info->name,
4702 conn = create_l2cap_le_conn(server, io, &src, &dst, dst_type);
4706 info->conn = g_slist_append(info->conn, conn);
4708 l2cap_le_connect_cb(io, err, conn);
4711 static void _remove_l2cap_le_socket(struct l2cap_le_profile_info *info)
4713 l2cap_le_socket_list = g_slist_remove(l2cap_le_socket_list, info);
4715 DBG("Removed \"%s\"", info->name);
4718 l2cap_le_io_destroy((gpointer)info->server);
4719 g_slist_free_full(info->conn, l2cap_le_io_destroy);
4722 g_free(info->owner);
4728 static void l2cap_le_socket_exited(DBusConnection *conn, void *user_data)
4730 struct l2cap_le_profile_info *info = user_data;
4732 DBG("l2cap le server \"%s\" exited", info->name);
4734 _remove_l2cap_le_socket(info);
4737 static int _connect_l2cap_le(struct btd_device *device,
4738 struct l2cap_le_profile_info *info)
4740 struct btd_adapter *adapter = device_get_adapter(device);
4741 const bdaddr_t *src = btd_adapter_get_address(adapter);
4742 uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4743 const bdaddr_t *dest = device_get_address(device);
4744 uint8_t dest_type = device->bdaddr_type;
4745 const char *dev_path = device_get_path(device);
4746 GError *gerr = NULL;
4747 struct l2cap_le_conn_info *conn = NULL;
4749 conn = g_malloc0(sizeof(struct l2cap_le_conn_info));
4750 info->conn = g_slist_append(info->conn, conn);
4752 conn->io = bt_io_connect(l2cap_le_connect_cb,
4754 BT_IO_OPT_SOURCE_BDADDR, src,
4755 BT_IO_OPT_SOURCE_TYPE, src_type,
4756 BT_IO_OPT_DEST_BDADDR, dest,
4757 BT_IO_OPT_DEST_TYPE, dest_type,
4758 BT_IO_OPT_PSM, info->psm,
4759 BT_IO_OPT_SEC_LEVEL, info->sec_level,
4763 error("L2CAP_LE Connect failed : %s", gerr->message);
4765 _remove_l2cap_le_socket(info);
4769 info->role = BT_L2CAP_LE_CLIENT_ROLE;
4770 conn->dev_path = dev_path;
4771 conn->profile_info = info;
4772 conn->connected = false;
4773 g_io_channel_set_close_on_unref(conn->io, FALSE);
4775 l2cap_le_socket_list = g_slist_append(l2cap_le_socket_list, info);
4779 static int _listen_l2cap_le(struct btd_adapter *adapter,
4780 struct l2cap_le_profile_info *info)
4782 const bdaddr_t *src = btd_adapter_get_address(adapter);
4783 uint8_t type = btd_adapter_get_le_address_type(adapter);
4784 GError *gerr = NULL;
4785 struct l2cap_le_conn_info *conn = NULL;
4786 BtIOConfirm confirm;
4787 BtIOConnect connect;
4790 if (info->authorize) {
4791 confirm = l2cap_le_confirm;
4795 connect = l2cap_le_direct_connect;
4798 conn = g_malloc0(sizeof(struct l2cap_le_conn_info));
4799 info->server = conn;
4801 conn->io = bt_io_listen(connect, confirm, (gpointer)conn,
4803 BT_IO_OPT_SOURCE_BDADDR, src,
4804 BT_IO_OPT_SOURCE_TYPE, type,
4805 BT_IO_OPT_PSM, info->psm,
4806 BT_IO_OPT_SEC_LEVEL, info->sec_level,
4810 error("L2cap_LE Listen failed : %s", gerr->message);
4812 _remove_l2cap_le_socket(info);
4816 bt_io_get(conn->io, &gerr, BT_IO_OPT_PSM, &psm, BT_IO_OPT_INVALID);
4818 DBG("L2CAP LE Socket listen to PSM %d successful", psm);
4820 conn->connected = false;
4821 info->role = BT_L2CAP_LE_SERVER_ROLE;
4823 conn->profile_info = info;
4824 g_io_channel_set_close_on_unref(conn->io, FALSE);
4826 l2cap_le_socket_list = g_slist_append(l2cap_le_socket_list, info);
4831 static DBusMessage *connect_l2cap_le_socket(DBusConnection *conn,
4832 DBusMessage *msg, void *user_data)
4834 struct btd_device *device = user_data;
4836 const char *path, *sender;
4838 DBusMessageIter args, opts;
4839 struct l2cap_le_profile_info *info = NULL;
4842 return btd_error_invalid_args(msg);
4844 sender = dbus_message_get_sender(msg);
4846 dbus_message_iter_init(msg, &args);
4847 dbus_message_iter_get_basic(&args, &path);
4848 dbus_message_iter_next(&args);
4850 dbus_message_iter_get_basic(&args, &psm);
4851 dbus_message_iter_next(&args);
4853 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4856 struct l2cap_le_profile_info *info = l->data;
4858 struct l2cap_le_conn_info *conn_info = info->conn->data;
4859 if (conn_info && conn_info->connected)
4860 return btd_error_already_connected(msg);
4862 return btd_error_busy(msg);
4864 error("Something is wrong!!!");
4865 return btd_error_failed(msg, "ConnectFailed due to some internal error");
4869 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
4870 return btd_error_invalid_args(msg);
4872 dbus_message_iter_recurse(&args, &opts);
4874 info = create_l2cap_le_socket(sender, path, psm, &opts);
4876 return btd_error_invalid_args(msg);
4878 info->role = BT_L2CAP_LE_CLIENT_ROLE;
4880 DBG("connect l2cap l2 socket channel %d", (int)psm);
4882 if (_connect_l2cap_le(device, info) != 0)
4883 return btd_error_failed(msg, "ConnectFailed");
4885 info->id = g_dbus_add_disconnect_watch(conn, sender, l2cap_le_socket_exited,
4888 return dbus_message_new_method_return(msg);
4891 DBusMessage *listen_l2cap_le_socket(DBusConnection *conn, DBusMessage *msg,
4894 struct btd_adapter *adapter = user_data;
4896 const char *path, *sender;
4898 DBusMessageIter args, opts;
4899 struct l2cap_le_profile_info *info = NULL;
4901 sender = dbus_message_get_sender(msg);
4903 dbus_message_iter_init(msg, &args);
4904 dbus_message_iter_get_basic(&args, &path);
4905 dbus_message_iter_next(&args);
4907 dbus_message_iter_get_basic(&args, &psm);
4908 dbus_message_iter_next(&args);
4910 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4913 return btd_error_already_exists(msg);
4915 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
4916 return btd_error_invalid_args(msg);
4918 dbus_message_iter_recurse(&args, &opts);
4920 info = create_l2cap_le_socket(sender, path, psm, &opts);
4922 return btd_error_invalid_args(msg);
4924 info->role = BT_L2CAP_LE_SERVER_ROLE;
4926 DBG("listen l2cap_le socket to psm %d", (int)psm);
4928 if (_listen_l2cap_le(adapter, info) != 0)
4929 return btd_error_failed(msg, "ListenFailed");
4931 info->id = g_dbus_add_disconnect_watch(conn, sender, l2cap_le_socket_exited,
4934 return dbus_message_new_method_return(msg);
4937 DBusMessage *get_psm_l2cap_le(DBusConnection *conn, DBusMessage *msg)
4939 const char *path, *sender;
4943 DBusMessageIter args;
4944 struct l2cap_le_profile_info *info;
4946 sender = dbus_message_get_sender(msg);
4948 DBG("sender %s", sender);
4950 dbus_message_iter_init(msg, &args);
4952 dbus_message_iter_get_basic(&args, &path);
4953 dbus_message_iter_next(&args);
4955 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4958 DBG("L2cap LE socket not exist");
4959 return btd_error_does_not_exist(msg);
4965 psm = info->server->psm;
4967 return btd_error_does_not_exist(msg);
4969 reply = dbus_message_new_method_return(msg);
4971 return btd_error_failed(msg,
4972 "Failed to create reply.");
4974 dbus_message_append_args(reply,
4975 DBUS_TYPE_UINT32, &psm,
4981 DBusMessage *remove_l2cap_le_socket(DBusConnection *conn, DBusMessage *msg)
4983 const char *path, *sender;
4984 struct l2cap_le_profile_info *info = NULL;
4987 sender = dbus_message_get_sender(msg);
4989 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
4991 return btd_error_invalid_args(msg);
4993 DBG("remove socket sender %s path %s", sender, path);
4995 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4998 DBG("L2cap LE socket not exist");
4999 return btd_error_does_not_exist(msg);
5004 g_dbus_remove_watch(conn, info->id);
5005 _remove_l2cap_le_socket(info);
5007 return dbus_message_new_method_return(msg);
5011 static DBusMessage *le_set_data_length(
5012 DBusConnection *conn, DBusMessage *msg,
5015 dbus_uint16_t max_tx_octets;
5016 dbus_uint16_t max_tx_time;
5017 struct btd_device *device = user_data;
5021 if (!dbus_message_get_args(msg, NULL,
5022 DBUS_TYPE_UINT16, &max_tx_octets,
5023 DBUS_TYPE_UINT16, &max_tx_time,
5024 DBUS_TYPE_INVALID)) {
5025 DBG("error in retrieving values");
5026 return btd_error_invalid_args(msg);
5029 if (device->bdaddr_type == BDADDR_BREDR)
5030 return btd_error_not_supported(msg);
5032 ba2str(&device->bdaddr, addr);
5034 DBG("Remote device address: %s", addr);
5035 DBG("Max tx octets: %u, Max tx time: %u",
5036 max_tx_octets, max_tx_time);
5038 status = btd_adapter_le_set_data_length(device->adapter,
5039 &device->bdaddr, max_tx_octets,
5043 return btd_error_failed(msg, "Unable to set le data length values");
5045 return dbus_message_new_method_return(msg);
5048 static DBusMessage *set_trusted_profile(DBusConnection *conn,
5049 DBusMessage *msg, void *data)
5051 struct btd_device *dev = data;
5052 dbus_bool_t profile_trusted;
5053 const char *pattern;
5055 uint32_t pbap = dev->trusted_profiles.pbap;
5056 uint32_t map = dev->trusted_profiles.map;
5057 uint32_t sap = dev->trusted_profiles.sap;
5058 uint32_t hfp_hs = dev->trusted_profiles.hfp_hs;
5059 uint32_t a2dp = dev->trusted_profiles.a2dp;
5061 if (!dbus_message_get_args(msg, NULL,
5062 DBUS_TYPE_STRING, &pattern,
5063 DBUS_TYPE_BOOLEAN, &profile_trusted,
5065 return btd_error_invalid_args(msg);
5067 DBG("Pattern : %s", pattern);
5068 uuid = bt_name2string(pattern);
5069 DBG("UUID : %s", uuid);
5070 DBG("profile Trusted : %d %d %d", dev->trusted_profiles.pbap,
5071 dev->trusted_profiles.map, dev->trusted_profiles.sap);
5072 DBG("profile Restricted : %d %d", dev->trusted_profiles.hfp_hs,
5073 dev->trusted_profiles.a2dp);
5074 if (g_strcmp0(uuid, OBEX_PBAP_UUID) == 0) {
5075 if (profile_trusted)
5076 pbap = SUPPORTED_TRUSTED;
5078 pbap = SUPPORTED_BLOCKED;
5079 } else if (g_strcmp0(uuid, OBEX_MAP_UUID) == 0) {
5080 if (profile_trusted)
5081 map = SUPPORTED_TRUSTED;
5083 map = SUPPORTED_BLOCKED;
5084 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
5085 if (profile_trusted)
5086 sap = SUPPORTED_TRUSTED;
5088 sap = SUPPORTED_BLOCKED;
5089 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
5090 if (profile_trusted)
5091 hfp_hs = SUPPORTED_TRUSTED;
5093 hfp_hs = SUPPORTED_BLOCKED;
5094 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
5095 if (profile_trusted)
5096 a2dp = SUPPORTED_TRUSTED;
5098 a2dp = SUPPORTED_BLOCKED;
5101 return btd_error_invalid_args(msg);
5105 btd_device_set_trusted_profiles(dev, pbap, map, sap, hfp_hs, a2dp);
5106 return dbus_message_new_method_return(msg);
5109 static DBusMessage *is_connected_profile(DBusConnection *conn, DBusMessage *msg,
5112 struct btd_device *dev = user_data;
5113 struct btd_service *service;
5114 btd_service_state_t state;
5115 const char *pattern;
5120 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
5122 return btd_error_invalid_args(msg);
5124 reply = dbus_message_new_method_return(msg);
5126 return btd_error_invalid_args(reply);
5128 uuid = bt_name2string(pattern);
5129 DBG("is_connected_profile_uuid : %s", uuid);
5130 service = btd_device_get_service(dev, uuid);
5132 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
5133 DBG("HFP service is not found check for HSP service");
5134 service = btd_device_get_service(dev, HSP_HS_UUID);
5140 return btd_error_not_connected(msg);
5142 state = btd_service_get_state(service);
5143 DBG("Connected State : %d", state);
5145 if (state == BTD_SERVICE_STATE_CONNECTED)
5150 dbus_message_append_args(reply,
5151 DBUS_TYPE_BOOLEAN, &val,
5157 static DBusMessage *update_le_conn_parm(DBusConnection *conn, DBusMessage *msg,
5160 struct btd_device *device = user_data;
5163 struct le_conn_param param = {0, 0, 0, 0};
5164 uint32_t min, max, latency, to_multiplier;
5168 if (device == NULL) {
5169 error("device is NULL");
5170 return btd_error_invalid_args(msg);
5174 error("le is not supported");
5175 return btd_error_not_supported(msg);
5178 if (!device->gatt_connected || !device->attrib)
5179 return btd_error_not_connected(msg);
5181 io = g_attrib_get_channel(device->attrib);
5183 return btd_error_not_connected(msg);
5185 fd = g_io_channel_unix_get_fd(io);
5187 return btd_error_not_connected(msg);
5189 if (device_get_conn_update_state(device))
5190 return btd_error_in_progress(msg);
5192 device_set_conn_update_state(device, true);
5194 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &min,
5195 DBUS_TYPE_UINT32, &max,
5196 DBUS_TYPE_UINT32, &latency,
5197 DBUS_TYPE_UINT32, &to_multiplier,
5198 DBUS_TYPE_INVALID)) {
5199 error("Invalid args");
5200 return btd_error_invalid_args(msg);
5203 if (min > UINT16_MAX || max > UINT16_MAX ||
5204 latency > UINT16_MAX || to_multiplier > UINT16_MAX) {
5205 error("Invalid args");
5206 return btd_error_invalid_args(msg);
5208 param.min = (uint16_t)min;
5209 param.max = (uint16_t)max;
5210 param.latency = (uint16_t)latency;
5211 param.to_multiplier = (uint16_t)to_multiplier;
5213 if (setsockopt(fd, SOL_BLUETOOTH, BT_LE_CONN_PARAM,
5214 ¶m, sizeof(param)) < 0) {
5215 error("Can't Update LE conn param : %s (%d)",
5216 strerror(errno), errno);
5217 return btd_error_failed(msg, strerror(errno));
5220 return dbus_message_new_method_return(msg);
5223 static void device_request_att_mtu_reponse_cb(bool success, uint8_t att_ecode,
5226 struct btd_device *device = user_data;
5228 DBusMessageIter iter;
5231 if (!device->req_att_mtu)
5234 mtu = bt_gatt_client_get_mtu(device->client);
5238 err_if = ERROR_INTERFACE ".Failed";
5240 reply = dbus_message_new_error(device->req_att_mtu, err_if,
5241 "Request Att MTU failed");
5242 g_dbus_send_message(dbus_conn, reply);
5246 DBG("MTU exchange complete, with MTU: %u", mtu);
5248 reply = dbus_message_new_method_return(device->req_att_mtu);
5252 dbus_message_iter_init_append(reply, &iter);
5254 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
5256 dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
5258 g_dbus_send_message(dbus_conn, reply);
5260 dbus_message_unref(device->req_att_mtu);
5261 device->req_att_mtu = NULL;
5264 static DBusMessage *request_att_mtu(DBusConnection *conn, DBusMessage *msg,
5267 struct btd_device *device = user_data;
5272 if (device == NULL) {
5273 error("device is NULL");
5274 return btd_error_invalid_args(msg);
5278 error("le is not supported");
5279 return btd_error_not_supported(msg);
5282 if (!device->gatt_connected || !device->attrib)
5283 return btd_error_not_connected(msg);
5285 if (!dbus_message_get_args(msg, NULL,
5286 DBUS_TYPE_UINT16, &mtu,
5287 DBUS_TYPE_INVALID)) {
5288 error("Invalid args");
5289 return btd_error_invalid_args(msg);
5294 if (!bt_gatt_request_att_mtu(device->client, mtu,
5295 device_request_att_mtu_reponse_cb, device))
5296 return btd_error_failed(msg, "Unable to Request MTU");
5298 device->req_att_mtu = dbus_message_ref(msg);
5302 static DBusMessage *device_get_ida(DBusConnection *conn, DBusMessage *msg,
5305 struct btd_device *device = user_data;
5306 char device_idaddr[18] = { 0 };
5308 const gchar *id_address = device_idaddr;
5313 return btd_error_invalid_args(msg);
5316 error("It doesn't support LE");
5317 return btd_error_not_supported(msg);
5321 // There is the first RPA. So it's paired device.
5323 ba2str(device->rpa, device_idaddr);
5325 ba2str(&device->bdaddr, device_idaddr);
5326 } else if (device->bdaddr_type != BDADDR_LE_RANDOM) {
5327 // device->bdaddr is identity address.
5328 ba2str(&device->bdaddr, device_idaddr);
5329 } else if ((device->bdaddr.b[5] >> 6) == 0x01) {
5330 // RPA but it's not paired
5331 return btd_error_does_not_exist(msg);
5332 } else if ((device->bdaddr.b[5] >> 6) == 0x03) {
5333 // Static Random address
5334 ba2str(&device->bdaddr, device_idaddr);
5337 return btd_error_not_supported(msg);
5340 reply = dbus_message_new_method_return(msg);
5344 dbus_message_append_args(reply, DBUS_TYPE_STRING, &id_address,
5350 void device_set_conn_update_state(struct btd_device *device, bool state)
5355 device->pending_conn_update = state;
5358 bool device_get_conn_update_state(struct btd_device *device)
5360 return device->pending_conn_update;
5364 static const GDBusMethodTable device_methods[] = {
5365 { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) },
5366 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) },
5367 { GDBUS_ASYNC_METHOD("ConnectProfile", GDBUS_ARGS({ "UUID", "s" }),
5368 NULL, connect_profile) },
5369 { GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
5370 NULL, disconnect_profile) },
5371 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5372 { GDBUS_ASYNC_METHOD("DisconnectExtProfile",
5373 GDBUS_ARGS({ "profile", "o" }), NULL,
5374 disconnect_ext_profile) },
5375 { GDBUS_ASYNC_METHOD("Pair", GDBUS_ARGS({ "conn_type", "y" }), NULL,
5378 { GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
5380 { GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
5381 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5382 { GDBUS_ASYNC_METHOD("ConnectLE", GDBUS_ARGS({ "auto_connect", "b"}),
5383 NULL, connect_le) },
5384 { GDBUS_ASYNC_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
5385 { GDBUS_METHOD("IsConnectedProfile", GDBUS_ARGS({ "UUID", "s" }),
5386 GDBUS_ARGS({ "IsConnected", "b" }),
5387 is_connected_profile)},
5388 { GDBUS_METHOD("LeConnUpdate", GDBUS_ARGS({ "interval_min", "u" },
5389 { "interval_max", "u" }, { "latency", "u" },
5390 { "time_out", "u" }), NULL,
5391 update_le_conn_parm) },
5392 { GDBUS_ASYNC_METHOD("DiscoverServices", GDBUS_ARGS({ "pattern", "s" }),
5393 NULL, discover_services) },
5394 { GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
5395 { GDBUS_ASYNC_METHOD("ConnectIpsp", NULL, NULL, connect_ipsp) },
5396 { GDBUS_ASYNC_METHOD("DisconnectIpsp", NULL, NULL, disconnect_ipsp) },
5397 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5398 { GDBUS_METHOD("ConnectOtc", NULL, NULL, connect_otc) },
5399 { GDBUS_METHOD("DisconnectOtc", NULL, NULL, disconnect_otc) },
5400 { GDBUS_METHOD("ListenOtc", NULL, NULL, listen_otc) },
5401 { GDBUS_ASYNC_METHOD("ConnectL2capLESocket",
5402 GDBUS_ARGS({ "path", "o"}, { "psm", "i" }, { "options", "a{sv}" }),
5403 NULL, connect_l2cap_le_socket) },
5405 { GDBUS_ASYNC_METHOD("LESetDataLength",
5406 GDBUS_ARGS({"max_tx_octets", "q" },
5407 { "max_tx_time", "q" }), NULL,
5408 le_set_data_length)},
5409 { GDBUS_ASYNC_METHOD("RequestAttMtu", GDBUS_ARGS({ "mtu", "q" }),
5410 GDBUS_ARGS({ "mtu", "q" }, { "status", "y"}),
5412 { GDBUS_METHOD("GetIDAddress", NULL, GDBUS_ARGS({ "IDAdress", "s" }),
5414 { GDBUS_METHOD("SetTrustedProfile",
5415 GDBUS_ARGS({ "uuid", "s"}, { "trusted", "b"}), NULL,
5416 set_trusted_profile) },
5421 static const GDBusPropertyTable device_properties[] = {
5422 { "Address", "s", dev_property_get_address },
5423 { "AddressType", "s", property_get_address_type },
5424 { "Name", "s", dev_property_get_name, NULL, dev_property_exists_name },
5425 { "Alias", "s", dev_property_get_alias, dev_property_set_alias },
5426 { "Class", "u", dev_property_get_class, NULL,
5427 dev_property_exists_class },
5428 { "Appearance", "q", dev_property_get_appearance, NULL,
5429 dev_property_exists_appearance },
5430 { "Icon", "s", dev_property_get_icon, NULL,
5431 dev_property_exists_icon },
5432 { "Paired", "b", dev_property_get_paired },
5433 { "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted },
5434 { "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
5435 { "LegacyPairing", "b", dev_property_get_legacy },
5436 { "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
5437 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5438 {"IsAliasSet", "b", dev_property_get_alias_set },
5439 { "Connected", "y", dev_property_get_connected },
5441 { "Connected", "b", dev_property_get_connected },
5443 { "UUIDs", "as", dev_property_get_uuids },
5444 { "Modalias", "s", dev_property_get_modalias, NULL,
5445 dev_property_exists_modalias },
5446 { "Adapter", "o", dev_property_get_adapter },
5447 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5448 /* To handle Failed Legacy Pairing when initiated from Remote device*/
5449 { "LegacyPaired", "b", dev_property_get_paired },
5450 { "LegacyManufacturerDataLen", "q", property_get_manufacturer_data_len },
5451 { "LegacyManufacturerData", "ay", property_get_manufacturer_data },
5452 { "GattConnected", "b", dev_property_get_gatt_connected },
5453 { "PayloadTimeout", "q", dev_property_get_payload},
5454 { "LastAddrType", "y", dev_property_get_last_addr_type},
5455 { "IpspConnected", "b", dev_property_get_ipsp_conn_state },
5456 { "IpspBtInterfaceInfo", "s", dev_property_get_ipsp_conn_bt_iface_name },
5457 { "AttMtu", "q", dev_property_get_att_mtu },
5458 { "TrustedProfiles", "u", dev_property_get_trusted_profiles},
5460 { "ManufacturerData", "a{qv}", dev_property_get_manufacturer_data,
5461 NULL, dev_property_manufacturer_data_exist },
5462 { "ServiceData", "a{sv}", dev_property_get_service_data,
5463 NULL, dev_property_service_data_exist },
5464 { "TxPower", "n", dev_property_get_tx_power, NULL,
5465 dev_property_exists_tx_power },
5466 { "ServicesResolved", "b", dev_property_get_svc_resolved, NULL, NULL },
5467 { "AdvertisingFlags", "ay", dev_property_get_flags, NULL,
5468 dev_property_flags_exist,
5469 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
5470 { "AdvertisingData", "a{yv}", dev_property_get_advertising_data,
5471 NULL, dev_property_advertising_data_exist,
5472 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
5473 { "WakeAllowed", "b", dev_property_get_wake_allowed,
5474 dev_property_set_wake_allowed,
5475 dev_property_wake_allowed_exist },
5479 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5480 static const GDBusSignalTable device_signals[] = {
5481 { GDBUS_SIGNAL("Disconnected",
5482 GDBUS_ARGS({ "bdaddr_type", "y" }, { "reason", "y" },
5483 { "name", "s" })) },
5484 { GDBUS_SIGNAL("DeviceConnected", GDBUS_ARGS({ "bdaddr_type", "y"})) },
5485 { GDBUS_SIGNAL("ProfileStateChanged",
5486 GDBUS_ARGS({ "profile", "s"}, {"state", "i"})) },
5487 { GDBUS_SIGNAL("AdvReport",
5488 GDBUS_ARGS({"Address","s"}, { "Address Type", "y" },
5489 { "Adv Type", "y"}, { "RSSI", "i"},
5490 { "AdvDataLen", "i"}, { "AdvData", "ay"})) },
5491 { GDBUS_SIGNAL("LEDataLengthChanged",
5492 GDBUS_ARGS({"max_tx_octets","q"},
5493 { "max_tx_time", "q" },
5494 { "max_rx_octets", "q"},
5495 { "max_rx_time", "q"}))},
5496 { GDBUS_SIGNAL("IpspStateChanged",
5497 GDBUS_ARGS({"connected","b"}, {"if_name","s"}))},
5498 { GDBUS_SIGNAL("OtcDisconnected", NULL)},
5499 { GDBUS_SIGNAL("AttMtuChanged",
5500 GDBUS_ARGS({"mtu", "q"})) },
5505 uint8_t btd_device_get_bdaddr_type(struct btd_device *dev)
5507 return dev->bdaddr_type;
5510 bool btd_device_is_connected(struct btd_device *dev)
5512 return dev->bredr_state.connected || dev->le_state.connected;
5515 static void clear_temporary_timer(struct btd_device *dev)
5517 if (dev->temporary_timer) {
5518 timeout_remove(dev->temporary_timer);
5519 dev->temporary_timer = 0;
5523 void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
5525 struct bearer_state *state = get_state(dev, bdaddr_type);
5527 device_update_last_seen(dev, bdaddr_type);
5529 if (state->connected) {
5531 ba2str(&dev->bdaddr, addr);
5532 error("Device %s is already connected", addr);
5536 bacpy(&dev->conn_bdaddr, &dev->bdaddr);
5537 dev->conn_bdaddr_type = dev->bdaddr_type;
5539 /* If this is the first connection over this bearer */
5540 if (bdaddr_type == BDADDR_BREDR)
5541 device_set_bredr_support(dev);
5543 device_set_le_support(dev, bdaddr_type);
5545 state->connected = true;
5547 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5548 if (dev->le_state.connected && dev->bredr_state.connected)
5551 /* Remove temporary timer while connected */
5552 clear_temporary_timer(dev);
5554 g_dbus_emit_property_changed(dbus_conn, dev->path, DEVICE_INTERFACE,
5557 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
5558 if (bdaddr_type == BDADDR_BREDR &&
5559 get_charging_state(dev->adapter) == WIRELESS_CHARGING) {
5560 int br_pkt_type = ACL_PTYPE_MASK |
5561 HCI_2DH1 | HCI_2DH3 | HCI_2DH5 |
5562 HCI_3DH1 | HCI_3DH3 | HCI_3DH5;
5564 DBG("During wireless charging... Change packet type");
5565 device_change_pkt_type(dev, (gpointer)br_pkt_type);
5567 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
5569 g_dbus_emit_signal(dbus_conn, dev->path,
5570 DEVICE_INTERFACE, "DeviceConnected",
5571 DBUS_TYPE_BYTE, &bdaddr_type,
5576 void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
5578 struct bearer_state *state = get_state(device, bdaddr_type);
5580 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5581 bool remove_device = false;
5583 bool paired_status_updated = false;
5584 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5585 char *dev_name = device->name;
5588 if (!state->connected)
5591 state->connected = false;
5592 device->general_connect = FALSE;
5594 device_set_svc_refreshed(device, false);
5596 if (device->disconn_timer > 0) {
5597 timeout_remove(device->disconn_timer);
5598 device->disconn_timer = 0;
5601 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5602 if (device->browse) {
5603 struct browse_req *req = device->browse;
5605 if ((bdaddr_type == BDADDR_BREDR && req->search_uuid != 0) ||
5606 (bdaddr_type != BDADDR_BREDR && req->search_uuid == 0))
5607 device->browse = NULL;
5609 DBG("device->browse is for other link");
5613 /* This could be executed while the client is waiting for Connect() but
5614 * att_connect_cb has not been invoked.
5615 * In that case reply the client that the connection failed.
5617 if (device->connect) {
5618 DBG("connection removed while Connect() is waiting reply");
5619 reply = btd_error_failed(device->connect,
5620 ERR_BREDR_CONN_CANCELED);
5621 g_dbus_send_message(dbus_conn, reply);
5622 dbus_message_unref(device->connect);
5623 device->connect = NULL;
5626 while (device->disconnects) {
5627 DBusMessage *msg = device->disconnects->data;
5629 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5630 if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
5632 remove_device = true;
5634 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
5635 device->disconnects = g_slist_remove(device->disconnects, msg);
5636 dbus_message_unref(msg);
5639 /* Check paired status of both bearers since it's possible to be
5640 * paired but not connected via link key to LTK conversion.
5642 if (!device->bredr_state.connected && device->bredr_state.paired &&
5643 !device->bredr_state.bonded) {
5644 btd_adapter_remove_bonding(device->adapter,
5647 device->bredr_state.paired = false;
5648 paired_status_updated = true;
5651 if (!device->le_state.connected && device->le_state.paired &&
5652 !device->le_state.bonded) {
5653 btd_adapter_remove_bonding(device->adapter,
5655 device->bdaddr_type);
5656 device->le_state.paired = false;
5657 paired_status_updated = true;
5660 /* report change only if both bearers are unpaired */
5661 if (!device->bredr_state.paired && !device->le_state.paired &&
5662 paired_status_updated)
5663 g_dbus_emit_property_changed(dbus_conn, device->path,
5668 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5669 if (device->bredr_state.connected || device->le_state.connected)
5672 device_update_last_seen(device, bdaddr_type);
5674 g_slist_free_full(device->eir_uuids, g_free);
5675 device->eir_uuids = NULL;
5677 g_dbus_emit_property_changed(dbus_conn, device->path,
5678 DEVICE_INTERFACE, "Connected");
5681 btd_adapter_remove_device(device->adapter, device);
5683 g_dbus_emit_signal(dbus_conn, device->path,
5684 DEVICE_INTERFACE, "Disconnected",
5685 DBUS_TYPE_BYTE, &bdaddr_type,
5686 DBUS_TYPE_BYTE, &device->disc_reason,
5687 DBUS_TYPE_STRING, &dev_name,
5692 guint device_add_disconnect_watch(struct btd_device *device,
5693 disconnect_watch watch, void *user_data,
5694 GDestroyNotify destroy)
5696 struct btd_disconnect_data *data;
5697 static guint id = 0;
5699 data = g_new0(struct btd_disconnect_data, 1);
5701 data->watch = watch;
5702 data->user_data = user_data;
5703 data->destroy = destroy;
5705 device->watches = g_slist_append(device->watches, data);
5710 void device_remove_disconnect_watch(struct btd_device *device, guint id)
5714 for (l = device->watches; l; l = l->next) {
5715 struct btd_disconnect_data *data = l->data;
5717 if (data->id == id) {
5718 device->watches = g_slist_remove(device->watches,
5721 data->destroy(data->user_data);
5728 static char *load_cached_name(struct btd_device *device, const char *local,
5731 char filename[PATH_MAX];
5736 if (device_address_is_private(device))
5739 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
5741 key_file = g_key_file_new();
5743 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
5746 str = g_key_file_get_string(key_file, "General", "Name", NULL);
5749 if (len > HCI_MAX_NAME_LENGTH)
5750 str[HCI_MAX_NAME_LENGTH] = '\0';
5754 g_key_file_free(key_file);
5759 static struct csrk_info *load_csrk(GKeyFile *key_file, const char *group)
5761 struct csrk_info *csrk;
5765 str = g_key_file_get_string(key_file, group, "Key", NULL);
5769 csrk = g_new0(struct csrk_info, 1);
5771 for (i = 0; i < 16; i++) {
5772 if (sscanf(str + (i * 2), "%2hhx", &csrk->key[i]) != 1)
5777 * In case of older storage this will return 0 which is fine since it
5778 * didn't support signing at that point the counter should never have
5781 csrk->counter = g_key_file_get_integer(key_file, group, "Counter",
5793 static void load_services(struct btd_device *device, char **uuids)
5797 for (uuid = uuids; *uuid; uuid++) {
5798 if (g_slist_find_custom(device->uuids, *uuid, bt_uuid_strcmp))
5801 device->uuids = g_slist_insert_sorted(device->uuids,
5809 static void convert_info(struct btd_device *device, GKeyFile *key_file)
5811 char filename[PATH_MAX];
5812 char adapter_addr[18];
5813 char device_addr[18];
5817 GError *gerr = NULL;
5819 /* Load device profile list from legacy properties */
5820 uuids = g_key_file_get_string_list(key_file, "General", "SDPServices",
5823 load_services(device, uuids);
5825 uuids = g_key_file_get_string_list(key_file, "General", "GATTServices",
5828 load_services(device, uuids);
5833 /* Remove old entries so they are not loaded again */
5834 g_key_file_remove_key(key_file, "General", "SDPServices", NULL);
5835 g_key_file_remove_key(key_file, "General", "GATTServices", NULL);
5837 ba2str(btd_adapter_get_address(device->adapter), adapter_addr);
5838 ba2str(&device->bdaddr, device_addr);
5839 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
5842 str = g_key_file_to_data(key_file, &length, NULL);
5843 if (!g_file_set_contents(filename, str, length, &gerr)) {
5844 error("Unable set contents for %s: (%s)", filename,
5850 store_device_info(device);
5853 static void load_info(struct btd_device *device, const char *local,
5854 const char *peer, GKeyFile *key_file)
5856 GError *gerr = NULL;
5858 gboolean store_needed = FALSE;
5860 gboolean wake_allowed;
5862 int source, vendor, product, version;
5864 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5865 gboolean svc_change_regd;
5866 char buf[DEV_MAX_MANUFACTURER_DATA_LEN] = { 0, };
5868 /* Load device name from storage info file, if that fails fall back to
5871 str = g_key_file_get_string(key_file, "General", "Name", NULL);
5873 str = load_cached_name(device, local, peer);
5875 store_needed = TRUE;
5879 strcpy(device->name, str);
5884 device->alias = g_key_file_get_string(key_file, "General", "Alias",
5888 str = g_key_file_get_string(key_file, "General", "Class", NULL);
5892 if (sscanf(str, "%x", &class) == 1)
5893 device->class = class;
5897 /* Load appearance */
5898 str = g_key_file_get_string(key_file, "General", "Appearance", NULL);
5900 device->appearance = strtol(str, NULL, 16);
5904 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5905 /* Load RPA Resolution Support value */
5906 device->rpa_res_support = g_key_file_get_integer(key_file,
5907 "General", "RPAResSupport", NULL);
5909 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerDataLen", NULL);
5911 device->manufacturer_data_len = strtol(str, NULL, 10);
5914 if (0 > device->manufacturer_data_len) {
5915 error("Invalid manufacturer_data_len: %d",
5916 device->manufacturer_data_len);
5917 device->manufacturer_data_len = 0;
5920 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerData", NULL);
5922 if (device->manufacturer_data_len < DEV_MAX_MANUFACTURER_DATA_LEN) {
5923 load_manufacturer_data_2digit(str,
5924 device->manufacturer_data_len, buf);
5925 device->manufacturer_data = g_memdup(buf,
5926 device->manufacturer_data_len);
5932 str = g_key_file_get_string(key_file, "General", "IdentityAddress",
5936 device->rpa = g_malloc0(sizeof(bdaddr_t));
5937 bacpy(device->rpa, &device->bdaddr);
5938 str2ba(str, &device->bdaddr);
5943 /* Load device technology */
5944 techno = g_key_file_get_string_list(key_file, "General",
5945 "SupportedTechnologies", NULL, NULL);
5949 for (t = techno; *t; t++) {
5950 if (g_str_equal(*t, "BR/EDR"))
5951 device->bredr = true;
5952 else if (g_str_equal(*t, "LE"))
5955 error("Unknown device technology");
5959 device->bdaddr_type = BDADDR_BREDR;
5961 str = g_key_file_get_string(key_file, "General",
5962 "AddressType", NULL);
5964 if (str && g_str_equal(str, "public"))
5965 device->bdaddr_type = BDADDR_LE_PUBLIC;
5966 else if (str && g_str_equal(str, "static"))
5967 device->bdaddr_type = BDADDR_LE_RANDOM;
5969 error("Unknown LE device technology");
5973 device->local_csrk = load_csrk(key_file, "LocalSignatureKey");
5974 device->remote_csrk = load_csrk(key_file, "RemoteSignatureKey");
5981 device->trusted = g_key_file_get_boolean(key_file, "General",
5984 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5985 /* Load Trusted Profiles*/
5986 int trusted_profiles = g_key_file_get_integer(key_file, "General",
5987 "TrustedProfiles", NULL);
5988 DBG("Loading TrustedProfiles %d", trusted_profiles);
5989 device->trusted_profiles.pbap = ((trusted_profiles &
5990 (PROFILE_SUPPORTED << PBAP_SHIFT_OFFSET)) >> PBAP_SHIFT_OFFSET);
5991 device->trusted_profiles.map = ((trusted_profiles &
5992 (PROFILE_SUPPORTED << MAP_SHIFT_OFFSET)) >> MAP_SHIFT_OFFSET);
5993 device->trusted_profiles.sap = ((trusted_profiles &
5994 (PROFILE_SUPPORTED << SAP_SHIFT_OFFSET)) >> SAP_SHIFT_OFFSET);
5995 device->trusted_profiles.hfp_hs = ((trusted_profiles &
5996 (PROFILE_SUPPORTED << HFP_HS_SHIFT_OFFSET)) >> HFP_HS_SHIFT_OFFSET);
5997 device->trusted_profiles.a2dp = ((trusted_profiles &
5998 (PROFILE_SUPPORTED << A2DP_SHIFT_OFFSET)) >> A2DP_SHIFT_OFFSET);
6002 /* Load device blocked */
6003 blocked = g_key_file_get_boolean(key_file, "General", "Blocked", NULL);
6005 device_block(device, FALSE);
6007 /* Load device profile list */
6008 uuids = g_key_file_get_string_list(key_file, "General", "Services",
6011 load_services(device, uuids);
6013 /* Discovered services restored from storage */
6014 device->bredr_state.svc_resolved = true;
6017 /* Load device id */
6018 source = g_key_file_get_integer(key_file, "DeviceID", "Source", NULL);
6020 vendor = g_key_file_get_integer(key_file, "DeviceID",
6023 product = g_key_file_get_integer(key_file, "DeviceID",
6026 version = g_key_file_get_integer(key_file, "DeviceID",
6029 btd_device_set_pnpid(device, source, vendor, product, version);
6032 /* Wake allowed is only configured and stored if user changed it.
6033 * Otherwise, we enable if profile supports it.
6035 wake_allowed = g_key_file_get_boolean(key_file, "General",
6036 "WakeAllowed", &gerr);
6038 device_set_wake_override(device, wake_allowed);
6044 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6045 /* Load Service changed Registered flag */
6046 svc_change_regd = g_key_file_get_boolean(key_file, "Att",
6047 "SvcChangeRegd", NULL);
6049 bt_att_set_svc_changed_indication_registered(device->att,
6054 store_device_info(device);
6057 static void load_att_info(struct btd_device *device, const char *local,
6060 char filename[PATH_MAX];
6062 GError *gerr = NULL;
6063 char *prim_uuid, *str;
6064 char **groups, **handle, *service_uuid;
6065 struct gatt_primary *prim;
6070 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
6071 prim_uuid = bt_uuid2string(&uuid);
6073 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", local,
6076 key_file = g_key_file_new();
6077 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
6078 error("Unable to load key file from %s: (%s)", filename,
6082 groups = g_key_file_get_groups(key_file, NULL);
6084 for (handle = groups; *handle; handle++) {
6088 str = g_key_file_get_string(key_file, *handle, "UUID", NULL);
6092 uuid_ok = g_str_equal(str, prim_uuid);
6098 str = g_key_file_get_string(key_file, *handle, "Value", NULL);
6102 end = g_key_file_get_integer(key_file, *handle,
6103 "EndGroupHandle", NULL);
6109 prim = g_new0(struct gatt_primary, 1);
6110 prim->range.start = atoi(*handle);
6111 prim->range.end = end;
6113 switch (strlen(str)) {
6115 uuid.type = SDP_UUID16;
6116 sscanf(str, "%04hx", &uuid.value.uuid16);
6119 uuid.type = SDP_UUID32;
6120 sscanf(str, "%08x", &uuid.value.uuid32);
6123 uuid.type = SDP_UUID128;
6124 memset(tmp, 0, sizeof(tmp));
6125 for (i = 0; i < 16; i++) {
6126 memcpy(tmp, str + (i * 2), 2);
6127 uuid.value.uuid128.data[i] =
6128 (uint8_t) strtol(tmp, NULL, 16);
6137 service_uuid = bt_uuid2string(&uuid);
6138 memcpy(prim->uuid, service_uuid, MAX_LEN_UUID_STR);
6142 device->primaries = g_slist_append(device->primaries, prim);
6146 g_key_file_free(key_file);
6150 static void device_register_primaries(struct btd_device *device,
6151 GSList *prim_list, int psm)
6153 device->primaries = g_slist_concat(device->primaries, prim_list);
6156 static void add_primary(struct gatt_db_attribute *attr, void *user_data)
6158 GSList **new_services = user_data;
6159 struct gatt_primary *prim;
6162 prim = g_new0(struct gatt_primary, 1);
6164 DBG("Failed to allocate gatt_primary structure");
6168 gatt_db_attribute_get_service_handles(attr, &prim->range.start,
6170 gatt_db_attribute_get_service_uuid(attr, &uuid);
6171 bt_uuid_to_string(&uuid, prim->uuid, sizeof(prim->uuid));
6173 *new_services = g_slist_append(*new_services, prim);
6176 static void load_desc_value(struct gatt_db_attribute *attrib,
6177 int err, void *user_data)
6180 warn("loading descriptor value to db failed");
6183 static ssize_t str2val(const char *str, uint8_t *val, size_t len)
6185 const char *pos = str;
6188 for (i = 0; i < len; i++) {
6189 if (sscanf(pos, "%2hhx", &val[i]) != 1)
6197 static int load_desc(char *handle, char *value,
6198 struct gatt_db_attribute *service)
6200 char uuid_str[MAX_LEN_UUID_STR];
6201 struct gatt_db_attribute *att;
6202 uint16_t handle_int;
6204 bt_uuid_t uuid, ext_uuid;
6206 if (sscanf(handle, "%04hx", &handle_int) != 1)
6209 /* Check if there is any value stored, otherwise it is just the UUID */
6210 if (sscanf(value, "%04hx:%s", &val, uuid_str) != 2) {
6211 if (sscanf(value, "%s", uuid_str) != 1)
6216 DBG("loading descriptor handle: 0x%04x, value: 0x%04x, value uuid: %s",
6217 handle_int, val, uuid_str);
6219 bt_string_to_uuid(&uuid, uuid_str);
6220 bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
6222 /* If it is CEP then it must contain the value */
6223 if (!bt_uuid_cmp(&uuid, &ext_uuid) && !val) {
6224 warn("cannot load CEP descriptor without value");
6228 att = gatt_db_service_insert_descriptor(service, handle_int, &uuid,
6229 0, NULL, NULL, NULL);
6230 if (!att || gatt_db_attribute_get_handle(att) != handle_int) {
6231 warn("loading descriptor to db failed");
6236 if (!gatt_db_attribute_write(att, 0, (uint8_t *)&val,
6237 sizeof(val), 0, NULL,
6238 load_desc_value, NULL))
6245 static int load_chrc(char *handle, char *value,
6246 struct gatt_db_attribute *service)
6248 uint16_t properties, value_handle, handle_int;
6249 char uuid_str[MAX_LEN_UUID_STR];
6250 struct gatt_db_attribute *att;
6256 if (sscanf(handle, "%04hx", &handle_int) != 1)
6259 /* Check if there is any value stored */
6260 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%32s:%s",
6261 &value_handle, &properties, val_str, uuid_str) != 4) {
6262 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%s",
6263 &value_handle, &properties, uuid_str) != 3)
6267 val_len = str2val(val_str, val, sizeof(val));
6269 bt_string_to_uuid(&uuid, uuid_str);
6271 /* Log debug message. */
6272 DBG("loading characteristic handle: 0x%04x, value handle: 0x%04x,"
6273 " properties 0x%04x value: %s uuid: %s",
6274 handle_int, value_handle, properties,
6275 val_len ? val_str : "", uuid_str);
6277 att = gatt_db_service_insert_characteristic(service, value_handle,
6278 &uuid, 0, properties,
6280 if (!att || gatt_db_attribute_get_handle(att) != value_handle) {
6281 warn("loading characteristic to db failed");
6286 if (!gatt_db_attribute_write(att, 0, val, val_len, 0, NULL,
6287 load_desc_value, NULL))
6294 static int load_incl(struct gatt_db *db, char *handle, char *value,
6295 struct gatt_db_attribute *service)
6297 char uuid_str[MAX_LEN_UUID_STR];
6298 struct gatt_db_attribute *att;
6299 uint16_t start, end;
6301 if (sscanf(handle, "%04hx", &start) != 1)
6304 if (sscanf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", &start, &end,
6308 /* Log debug message. */
6309 DBG("loading included service: 0x%04x, end: 0x%04x, uuid: %s", start,
6312 att = gatt_db_get_attribute(db, start);
6314 warn("loading included service to db failed - no such service");
6318 att = gatt_db_service_add_included(service, att);
6320 warn("loading included service to db failed");
6327 static int load_service(struct gatt_db *db, char *handle, char *value)
6329 struct gatt_db_attribute *att;
6330 uint16_t start, end;
6331 char type[MAX_LEN_UUID_STR], uuid_str[MAX_LEN_UUID_STR];
6335 if (sscanf(handle, "%04hx", &start) != 1)
6338 if (sscanf(value, "%[^:]:%04hx:%s", type, &end, uuid_str) != 3)
6341 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR))
6343 else if (g_str_equal(type, GATT_SND_SVC_UUID_STR))
6348 bt_string_to_uuid(&uuid, uuid_str);
6350 /* Log debug message. */
6351 DBG("loading service: 0x%04x, end: 0x%04x, uuid: %s",
6352 start, end, uuid_str);
6354 att = gatt_db_insert_service(db, start, &uuid, primary,
6357 error("Unable load service into db!");
6364 static int load_gatt_db_impl(GKeyFile *key_file, char **keys,
6367 struct gatt_db_attribute *current_service;
6368 char **handle, *value, type[MAX_LEN_UUID_STR];
6371 /* first load service definitions */
6372 for (handle = keys; *handle; handle++) {
6373 value = g_key_file_get_string(key_file, "Attributes", *handle,
6376 if (sscanf(value, "%[^:]:", type) != 1) {
6377 warn("Missing Type in attribute definition");
6382 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
6383 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
6384 ret = load_service(db, *handle, value);
6394 current_service = NULL;
6395 /* then fill them with data*/
6396 for (handle = keys; *handle; handle++) {
6397 value = g_key_file_get_string(key_file, "Attributes", *handle,
6400 if (sscanf(value, "%[^:]:", type) != 1) {
6401 warn("Missing Type in attribute definition");
6406 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
6407 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
6409 uint16_t start, end;
6412 char uuid_str[MAX_LEN_UUID_STR];
6414 if (sscanf(*handle, "%04hx", &tmp) != 1) {
6415 warn("Unable to parse attribute handle");
6420 if (current_service)
6421 gatt_db_service_set_active(current_service,
6424 current_service = gatt_db_get_attribute(db, tmp);
6426 gatt_db_attribute_get_service_data(current_service,
6430 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6431 } else if (g_str_equal(type, GATT_INCLUDE_UUID_STR)) {
6432 ret = load_incl(db, *handle, value, current_service);
6433 } else if (g_str_equal(type, GATT_CHARAC_UUID_STR)) {
6434 ret = load_chrc(*handle, value, current_service);
6436 ret = load_desc(*handle, value, current_service);
6446 if (current_service)
6447 gatt_db_service_set_active(current_service, true);
6452 static void load_gatt_db(struct btd_device *device, const char *local,
6455 char **keys, filename[PATH_MAX];
6457 GError *gerr = NULL;
6459 if (!gatt_cache_is_enabled(device))
6462 DBG("Restoring %s gatt database from file", peer);
6464 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
6466 key_file = g_key_file_new();
6467 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
6468 error("Unable to load key file from %s: (%s)", filename,
6472 keys = g_key_file_get_keys(key_file, "Attributes", NULL, NULL);
6475 warn("No cache for %s", peer);
6476 g_key_file_free(key_file);
6480 if (load_gatt_db_impl(key_file, keys, device->db))
6481 warn("Unable to load gatt db from file for %s", peer);
6484 g_key_file_free(key_file);
6486 g_slist_free_full(device->primaries, g_free);
6487 device->primaries = NULL;
6488 gatt_db_foreach_service(device->db, NULL, add_primary,
6489 &device->primaries);
6492 static void device_add_uuids(struct btd_device *device, GSList *uuids)
6495 bool changed = false;
6497 for (l = uuids; l != NULL; l = g_slist_next(l)) {
6498 GSList *match = g_slist_find_custom(device->uuids, l->data,
6504 device->uuids = g_slist_insert_sorted(device->uuids,
6510 g_dbus_emit_property_changed(dbus_conn, device->path,
6511 DEVICE_INTERFACE, "UUIDs");
6514 static bool device_match_profile(struct btd_device *device,
6515 struct btd_profile *profile,
6518 if (profile->remote_uuid == NULL)
6521 if (g_slist_find_custom(uuids, profile->remote_uuid,
6522 bt_uuid_strcmp) == NULL) {
6523 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
6524 if (strcmp(profile->name, "hid-device") == 0)
6533 static void add_gatt_service(struct gatt_db_attribute *attr, void *user_data)
6535 struct btd_device *device = user_data;
6536 struct btd_service *service;
6537 struct btd_profile *profile;
6539 char uuid_str[MAX_LEN_UUID_STR];
6542 gatt_db_attribute_get_service_uuid(attr, &uuid);
6543 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6545 /* Check if service was already probed */
6546 l = find_service_with_uuid(device->services, uuid_str);
6550 /* Add UUID and probe service */
6551 btd_device_add_uuid(device, uuid_str);
6553 /* Check if service was probed */
6554 l = find_service_with_uuid(device->services, uuid_str);
6559 /* Mark service as active to skip discovering it again */
6560 gatt_db_service_set_active(attr, true);
6563 profile = btd_service_get_profile(service);
6565 /* Claim attributes of internal profiles */
6566 if (!profile->external) {
6567 /* Mark the service as claimed by the existing profile. */
6568 gatt_db_service_set_claimed(attr, true);
6571 /* Notify driver about the new connection */
6572 service_accept(service);
6575 static void device_add_gatt_services(struct btd_device *device)
6579 ba2str(&device->bdaddr, addr);
6581 if (device->blocked) {
6582 DBG("Skipping profiles for blocked device %s", addr);
6586 gatt_db_foreach_service(device->db, NULL, add_gatt_service, device);
6589 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6590 static void accept_gatt_service(struct gatt_db_attribute *attr, void *user_data)
6592 struct btd_device *device = user_data;
6595 char uuid_str[MAX_LEN_UUID_STR];
6597 gatt_db_attribute_get_service_uuid(attr, &uuid);
6598 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6600 l = find_service_with_uuid(device->services, uuid_str);
6604 service_accept(l->data);
6608 static void device_accept_gatt_profiles(struct btd_device *device)
6610 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6613 for (l = device->services; l != NULL; l = g_slist_next(l))
6614 service_accept(l->data);
6616 gatt_db_foreach_service(device->db, NULL, accept_gatt_service, device);
6620 static void device_remove_gatt_service(struct btd_device *device,
6621 struct gatt_db_attribute *attr)
6623 struct btd_service *service;
6625 char uuid_str[MAX_LEN_UUID_STR];
6628 gatt_db_attribute_get_service_uuid(attr, &uuid);
6629 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6631 l = find_service_with_uuid(device->services, uuid_str);
6636 device->services = g_slist_delete_link(device->services, l);
6637 device->pending = g_slist_remove(device->pending, service);
6638 service_remove(service);
6641 static gboolean gatt_services_changed(gpointer user_data)
6643 struct btd_device *device = user_data;
6645 store_gatt_db(device);
6650 static void gatt_service_added(struct gatt_db_attribute *attr, void *user_data)
6652 struct btd_device *device = user_data;
6653 GSList *new_service = NULL;
6654 uint16_t start, end;
6656 if (!bt_gatt_client_is_ready(device->client))
6659 gatt_db_attribute_get_service_data(attr, &start, &end, NULL, NULL);
6661 DBG("start: 0x%04x, end: 0x%04x", start, end);
6664 * TODO: Remove the primaries list entirely once all profiles use
6667 add_primary(attr, &new_service);
6671 device_register_primaries(device, new_service, -1);
6673 add_gatt_service(attr, device);
6675 btd_gatt_client_service_added(device->client_dbus, attr);
6677 gatt_services_changed(device);
6680 static gint prim_attr_cmp(gconstpointer a, gconstpointer b)
6682 const struct gatt_primary *prim = a;
6683 const struct gatt_db_attribute *attr = b;
6684 uint16_t start, end;
6686 gatt_db_attribute_get_service_handles(attr, &start, &end);
6688 return !(prim->range.start == start && prim->range.end == end);
6691 static gint prim_uuid_cmp(gconstpointer a, gconstpointer b)
6693 const struct gatt_primary *prim = a;
6694 const char *uuid = b;
6696 return bt_uuid_strcmp(prim->uuid, uuid);
6699 static void gatt_service_removed(struct gatt_db_attribute *attr,
6702 struct btd_device *device = user_data;
6704 struct gatt_primary *prim;
6705 uint16_t start, end;
6708 * NOTE: shared/gatt-client clears the database in case of failure. This
6709 * triggers the service_removed callback for all affected services.
6710 * Hence, this function will be called in the following cases:
6712 * 1. When a GATT service gets removed due to "Service Changed".
6714 * 2. When a GATT service gets removed when the database get cleared
6715 * upon disconnection with a non-bonded device.
6717 * 3. When a GATT service gets removed when the database get cleared
6718 * by shared/gatt-client when its initialization procedure fails,
6719 * e.g. due to an ATT protocol error or an unexpected disconnect.
6720 * In this case the gatt-client will not be ready.
6723 gatt_db_attribute_get_service_handles(attr, &start, &end);
6725 DBG("start: 0x%04x, end: 0x%04x", start, end);
6727 /* Remove the corresponding gatt_primary */
6728 l = g_slist_find_custom(device->primaries, attr, prim_attr_cmp);
6733 device->primaries = g_slist_delete_link(device->primaries, l);
6736 * Remove the corresponding UUIDs entry and profile, only if this is
6737 * the last service with this UUID.
6739 l = g_slist_find_custom(device->uuids, prim->uuid, bt_uuid_strcmp);
6741 if (l && !g_slist_find_custom(device->primaries, prim->uuid,
6744 * If this happend since the db was cleared for a non-bonded
6745 * device, then don't remove the btd_service just yet. We do
6746 * this so that we can avoid re-probing the profile if the same
6747 * GATT service is found on the device on re-connection.
6748 * However, if the device is marked as temporary, then we
6751 if (device->client || device->temporary == TRUE)
6752 device_remove_gatt_service(device, attr);
6755 device->uuids = g_slist_delete_link(device->uuids, l);
6756 g_dbus_emit_property_changed(dbus_conn, device->path,
6757 DEVICE_INTERFACE, "UUIDs");
6762 store_device_info(device);
6764 btd_gatt_client_service_removed(device->client_dbus, attr);
6766 gatt_services_changed(device);
6769 static struct btd_device *device_new(struct btd_adapter *adapter,
6770 const char *address)
6773 struct btd_device *device;
6774 const char *adapter_path = adapter_get_path(adapter);
6776 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6777 DBG("address %s", address);
6780 device = g_try_malloc0(sizeof(struct btd_device));
6784 device->tx_power = 127;
6786 device->db = gatt_db_new();
6792 memset(device->ad_flags, INVALID_FLAGS, sizeof(device->ad_flags));
6794 device->ad = bt_ad_new();
6796 device_free(device);
6800 address_up = g_ascii_strup(address, -1);
6801 device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
6802 g_strdelimit(device->path, ":", '_');
6805 str2ba(address, &device->bdaddr);
6807 device->client_dbus = btd_gatt_client_new(device);
6808 if (!device->client_dbus) {
6809 error("Failed to create btd_gatt_client");
6810 device_free(device);
6814 DBG("Creating device %s", device->path);
6816 if (g_dbus_register_interface(dbus_conn,
6817 device->path, DEVICE_INTERFACE,
6818 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6819 device_methods, device_signals,
6821 device_methods, NULL,
6823 device_properties, device,
6824 device_free) == FALSE) {
6825 error("Unable to register device interface for %s", address);
6826 device_free(device);
6830 device->adapter = adapter;
6831 device->temporary = true;
6833 device->db_id = gatt_db_register(device->db, gatt_service_added,
6834 gatt_service_removed, device, NULL);
6836 device->refresh_discovery = btd_opts.refresh_discovery;
6838 return btd_device_ref(device);
6841 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6842 void device_print_addr(struct btd_device *dev)
6847 ba2str(&dev->bdaddr, ida);
6850 ba2str(dev->rpa, rpa);
6852 DBG("IDA %s [%d] : RPA [%s], BREDR [%d], LE [%d]",
6853 ida, dev->bdaddr_type, rpa,
6854 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
6856 DBG("ADDR %s [%d] : BREDR [%d], LE [%d]",
6857 ida, dev->bdaddr_type,
6858 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
6863 struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
6864 const char *address, GKeyFile *key_file)
6866 struct btd_device *device;
6867 const char *src_dir;
6869 DBG("address %s", address);
6871 device = device_new(adapter, address);
6875 convert_info(device, key_file);
6877 src_dir = btd_adapter_get_storage_dir(adapter);
6879 load_info(device, src_dir, address, key_file);
6880 load_att_info(device, src_dir, address);
6885 struct btd_device *device_create(struct btd_adapter *adapter,
6886 const bdaddr_t *bdaddr, uint8_t bdaddr_type)
6888 struct btd_device *device;
6892 ba2str(bdaddr, dst);
6895 device = device_new(adapter, dst);
6899 device->bdaddr_type = bdaddr_type;
6901 if (bdaddr_type == BDADDR_BREDR)
6902 device->bredr = true;
6906 str = load_cached_name(device, btd_adapter_get_storage_dir(adapter),
6909 strcpy(device->name, str);
6916 char *btd_device_get_storage_path(struct btd_device *device,
6917 const char *filename)
6921 if (device_address_is_private(device)) {
6922 warn("Refusing storage path for private addressed device %s",
6927 ba2str(&device->bdaddr, dstaddr);
6929 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6931 ba2str(device->rpa, dstaddr);
6935 return g_strdup_printf(STORAGEDIR "/%s/%s",
6936 btd_adapter_get_storage_dir(device->adapter),
6939 return g_strdup_printf(STORAGEDIR "/%s/%s/%s",
6940 btd_adapter_get_storage_dir(device->adapter),
6944 void btd_device_device_set_name(struct btd_device *device, const char *name)
6946 if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
6949 DBG("%s %s", device->path, name);
6951 strncpy(device->name, name, MAX_NAME_LENGTH);
6953 store_device_info(device);
6955 g_dbus_emit_property_changed(dbus_conn, device->path,
6956 DEVICE_INTERFACE, "Name");
6958 if (device->alias != NULL)
6961 g_dbus_emit_property_changed(dbus_conn, device->path,
6962 DEVICE_INTERFACE, "Alias");
6965 void device_get_name(struct btd_device *device, char *name, size_t len)
6967 if (name != NULL && len > 0) {
6968 strncpy(name, device->name, len - 1);
6969 name[len - 1] = '\0';
6973 bool device_name_known(struct btd_device *device)
6975 return device->name[0] != '\0';
6978 void device_set_class(struct btd_device *device, uint32_t class)
6980 if (device->class == class)
6983 DBG("%s 0x%06X", device->path, class);
6985 device->class = class;
6987 store_device_info(device);
6989 g_dbus_emit_property_changed(dbus_conn, device->path,
6990 DEVICE_INTERFACE, "Class");
6991 g_dbus_emit_property_changed(dbus_conn, device->path,
6992 DEVICE_INTERFACE, "Icon");
6995 void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr,
6996 uint8_t bdaddr_type)
6998 bool auto_connect = device->auto_connect;
7000 if (!bacmp(bdaddr, &device->bdaddr) &&
7001 bdaddr_type == device->bdaddr_type)
7004 /* Since this function is only used for LE SMP Identity
7005 * Resolving purposes we can now assume LE is supported.
7009 /* Remove old address from accept/auto-connect list since its address
7013 device_set_auto_connect(device, FALSE);
7015 bacpy(&device->bdaddr, bdaddr);
7016 device->bdaddr_type = bdaddr_type;
7018 store_device_info(device);
7020 g_dbus_emit_property_changed(dbus_conn, device->path,
7021 DEVICE_INTERFACE, "Address");
7022 g_dbus_emit_property_changed(dbus_conn, device->path,
7023 DEVICE_INTERFACE, "AddressType");
7026 device_set_auto_connect(device, TRUE);
7029 void device_set_bredr_support(struct btd_device *device)
7031 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7035 ba2str(device->rpa, addr_str);
7036 error("Cannot set bredr support to RPA device [%s]", addr_str);
7040 if (device->bdaddr_type == BDADDR_LE_RANDOM) {
7041 ba2str(&device->bdaddr, addr_str);
7042 error("Cannot set bredr support to LE random device [%s]",
7051 device->bredr = true;
7052 store_device_info(device);
7055 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7056 void device_set_rpa(struct btd_device *device, const bdaddr_t *rpa)
7058 if (device->rpa == NULL) {
7059 device->rpa = g_malloc0(sizeof(bdaddr_t));
7060 bacpy(device->rpa, rpa);
7062 error("RPA is already set");
7065 void device_set_irk_value(struct btd_device *device, const uint8_t *val)
7067 memcpy(&device->irk_val, val, sizeof(device->irk_val));
7071 void device_set_le_support(struct btd_device *device, uint8_t bdaddr_type)
7077 device->bdaddr_type = bdaddr_type;
7079 store_device_info(device);
7082 static bool device_disappeared(gpointer user_data)
7084 struct btd_device *dev = user_data;
7086 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7087 if (dev->le_state.connected) {
7088 DBG("GATT connection exists, don't remove the device");
7093 dev->temporary_timer = 0;
7095 btd_adapter_remove_device(dev->adapter, dev);
7100 static void set_temporary_timer(struct btd_device *dev, unsigned int timeout)
7102 clear_temporary_timer(dev);
7107 dev->temporary_timer = timeout_add_seconds(timeout, device_disappeared,
7111 void device_update_last_seen(struct btd_device *device, uint8_t bdaddr_type)
7113 if (bdaddr_type == BDADDR_BREDR)
7114 device->bredr_seen = time(NULL);
7116 device->le_seen = time(NULL);
7118 if (!device_is_temporary(device))
7121 /* Restart temporary timer */
7122 set_temporary_timer(device, btd_opts.tmpto);
7125 /* It is possible that we have two device objects for the same device in
7126 * case it has first been discovered over BR/EDR and has a private
7127 * address when discovered over LE for the first time. In such a case we
7128 * need to inherit critical values from the duplicate so that we don't
7129 * ovewrite them when writing to storage. The next time bluetoothd
7130 * starts the device will show up as a single instance.
7132 void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup)
7138 dev->bredr = dup->bredr;
7140 dev->trusted = dup->trusted;
7141 dev->blocked = dup->blocked;
7143 for (l = dup->uuids; l; l = g_slist_next(l))
7144 dev->uuids = g_slist_append(dev->uuids, g_strdup(l->data));
7146 if (dev->name[0] == '\0')
7147 strcpy(dev->name, dup->name);
7150 dev->alias = g_strdup(dup->alias);
7152 dev->class = dup->class;
7154 dev->vendor_src = dup->vendor_src;
7155 dev->vendor = dup->vendor;
7156 dev->product = dup->product;
7157 dev->version = dup->version;
7160 uint32_t btd_device_get_class(struct btd_device *device)
7162 return device->class;
7165 uint16_t btd_device_get_vendor(struct btd_device *device)
7167 return device->vendor;
7170 uint16_t btd_device_get_vendor_src(struct btd_device *device)
7172 return device->vendor_src;
7175 uint16_t btd_device_get_product(struct btd_device *device)
7177 return device->product;
7180 uint16_t btd_device_get_version(struct btd_device *device)
7182 return device->version;
7185 static void delete_folder_tree(const char *dirname)
7188 struct dirent *entry;
7189 char filename[PATH_MAX];
7191 dir = opendir(dirname);
7195 while ((entry = readdir(dir)) != NULL) {
7196 if (g_str_equal(entry->d_name, ".") ||
7197 g_str_equal(entry->d_name, ".."))
7200 if (entry->d_type == DT_UNKNOWN)
7201 entry->d_type = util_get_dt(dirname, entry->d_name);
7203 snprintf(filename, PATH_MAX, "%s/%s", dirname, entry->d_name);
7205 if (entry->d_type == DT_DIR)
7206 delete_folder_tree(filename);
7215 void device_remove_bonding(struct btd_device *device, uint8_t bdaddr_type)
7217 if (bdaddr_type == BDADDR_BREDR)
7218 device->bredr_state.bonded = false;
7220 device->le_state.bonded = false;
7222 if (!device->bredr_state.bonded && !device->le_state.bonded)
7223 btd_device_set_temporary(device, true);
7225 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
7229 static void device_remove_stored(struct btd_device *device)
7231 char device_addr[18];
7232 char filename[PATH_MAX];
7234 GError *gerr = NULL;
7238 if (device->bredr_state.bonded)
7239 device_remove_bonding(device, BDADDR_BREDR);
7241 if (device->le_state.bonded)
7242 device_remove_bonding(device, device->bdaddr_type);
7244 device->bredr_state.paired = false;
7245 device->le_state.paired = false;
7247 if (device->blocked)
7248 device_unblock(device, TRUE, FALSE);
7250 ba2str(&device->bdaddr, device_addr);
7252 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7254 ba2str(device->rpa, device_addr);
7257 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s",
7258 btd_adapter_get_storage_dir(device->adapter),
7260 delete_folder_tree(filename);
7262 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
7263 btd_adapter_get_storage_dir(device->adapter),
7266 key_file = g_key_file_new();
7267 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
7269 g_key_file_free(key_file);
7272 g_key_file_remove_group(key_file, "ServiceRecords", NULL);
7273 g_key_file_remove_group(key_file, "Attributes", NULL);
7275 data = g_key_file_to_data(key_file, &length, NULL);
7277 create_file(filename, 0600);
7278 if (!g_file_set_contents(filename, data, length, &gerr)) {
7279 error("Unable set contents for %s: (%s)", filename,
7286 g_key_file_free(key_file);
7289 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7290 void device_unpair(struct btd_device *device, gboolean remove_stored)
7293 DBG("Unpairing device %s", device->path);
7295 if (device->bonding) {
7298 if (device->bredr_state.connected)
7299 status = MGMT_STATUS_DISCONNECTED;
7301 status = MGMT_STATUS_CONNECT_FAILED;
7303 device_cancel_bonding(device, status);
7307 browse_request_cancel(device->browse);
7310 // while (device->services != NULL) {
7311 // struct btd_service *service = device->services->data;
7313 // device->services = g_slist_remove(device->services, service);
7314 // service_remove(service);
7317 g_slist_free(device->pending);
7318 device->pending = NULL;
7320 if (btd_device_is_connected(device))
7321 disconnect_all(device);
7323 if (device->store_id > 0) {
7324 g_source_remove(device->store_id);
7325 device->store_id = 0;
7328 store_device_info_cb(device);
7332 device_remove_stored(device);
7334 gatt_db_clear(device->db);
7337 bacpy(&device->bdaddr, device->rpa);
7338 device->bdaddr_type = BDADDR_LE_RANDOM;
7340 g_free(device->rpa);
7344 device->bredr_state.paired = 0;
7345 device->le_state.paired = 0;
7346 device->bredr_state.svc_resolved = false;
7347 device->trusted = false;
7348 device->trusted_profiles.pbap = SHOW_AUTHORIZATION;
7349 device->trusted_profiles.map = SHOW_AUTHORIZATION;
7350 device->trusted_profiles.sap = SHOW_AUTHORIZATION;
7351 device->trusted_profiles.hfp_hs = SUPPORTED_TRUSTED;
7352 device->trusted_profiles.a2dp = SUPPORTED_TRUSTED;
7353 if (device->alias != NULL) {
7354 /* Remove alias name because
7355 * In UG if we rename and then unpair device and
7356 * initiates connection without scanning then paired
7357 * list will have alias name as first preference is
7358 * given to alias name.
7360 DBG("Freeing device alias name");
7361 g_free(device->alias);
7362 device->alias = NULL;
7364 g_dbus_emit_property_changed(dbus_conn, device->path,
7365 DEVICE_INTERFACE, "Paired");
7366 // btd_device_unref(device);
7370 void device_remove_stored_folder(struct btd_device *device)
7372 const bdaddr_t *src = btd_adapter_get_address(device->adapter);
7373 char adapter_addr[18];
7374 char device_addr[18];
7375 char filename[PATH_MAX];
7377 ba2str(src, adapter_addr);
7378 ba2str(&device->bdaddr, device_addr);
7380 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
7383 delete_folder_tree(filename);
7387 void device_remove(struct btd_device *device, gboolean remove_stored)
7389 DBG("Removing device %s", device->path);
7391 if (device->auto_connect) {
7392 device->disable_auto_connect = TRUE;
7393 device_set_auto_connect(device, FALSE);
7396 if (device->bonding) {
7399 if (device->bredr_state.connected)
7400 status = MGMT_STATUS_DISCONNECTED;
7402 status = MGMT_STATUS_CONNECT_FAILED;
7404 device_cancel_bonding(device, status);
7408 browse_request_cancel(device->browse);
7410 while (device->services != NULL) {
7411 struct btd_service *service = device->services->data;
7413 device->services = g_slist_remove(device->services, service);
7414 service_remove(service);
7417 g_slist_free(device->pending);
7418 device->pending = NULL;
7420 if (btd_device_is_connected(device)) {
7421 if (device->disconn_timer > 0)
7422 timeout_remove(device->disconn_timer);
7423 disconnect_all(device);
7426 clear_temporary_timer(device);
7428 if (device->store_id > 0) {
7429 g_source_remove(device->store_id);
7430 device->store_id = 0;
7433 store_device_info_cb(device);
7437 device_remove_stored(device);
7439 btd_device_unref(device);
7442 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7443 int device_rpa_cmp(gconstpointer a, gconstpointer b)
7445 const struct btd_device *device = a;
7446 const char *address = b;
7452 ba2str(device->rpa, addr);
7454 return strcasecmp(addr, address);
7457 int device_addr_cmp(gconstpointer a, gconstpointer b)
7459 const struct btd_device *device = a;
7460 const bdaddr_t *bdaddr = b;
7462 return bacmp(&device->bdaddr, bdaddr);
7465 int device_rpa_ida_cmp(gconstpointer a, gconstpointer b)
7467 const struct btd_device *device = a;
7468 const char *address = b;
7471 if (!device->rpa || device->le == false)
7474 ba2str(&device->bdaddr, addr);
7475 return strcasecmp(addr, address);
7479 int device_address_cmp(gconstpointer a, gconstpointer b)
7481 const struct btd_device *device = a;
7482 const char *address = b;
7485 ba2str(&device->bdaddr, addr);
7486 return strcasecmp(addr, address);
7489 int device_bdaddr_cmp(gconstpointer a, gconstpointer b)
7491 const struct btd_device *device = a;
7492 const bdaddr_t *bdaddr = b;
7494 return bacmp(&device->bdaddr, bdaddr);
7497 static bool addr_is_public(uint8_t addr_type)
7499 if (addr_type == BDADDR_BREDR || addr_type == BDADDR_LE_PUBLIC)
7505 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7506 int device_addr_type_strict_cmp(gconstpointer a, gconstpointer b)
7508 const struct btd_device *dev = a;
7509 const struct device_addr_type *addr = b;
7512 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
7514 if (addr->bdaddr_type == BDADDR_BREDR) {
7524 if (cmp && dev->rpa && addr->bdaddr_type == BDADDR_LE_RANDOM &&
7525 (addr->bdaddr.b[5] >> 6) == 0x01)
7526 return bacmp(dev->rpa, &addr->bdaddr);
7528 if (addr->bdaddr_type != dev->bdaddr_type)
7535 int device_addr_type_cmp(gconstpointer a, gconstpointer b)
7537 const struct btd_device *dev = a;
7538 const struct device_addr_type *addr = b;
7541 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
7544 * Address matches and both old and new are public addresses
7545 * (doesn't matter whether LE or BR/EDR, then consider this a
7548 if (!cmp && addr_is_public(addr->bdaddr_type) &&
7549 addr_is_public(dev->bdaddr_type))
7550 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7552 if (dev->rpa && addr->bdaddr_type == BDADDR_BREDR) {
7555 ba2str(&dev->bdaddr, addr_str);
7556 DBG("Don't match. LE Only device [%s]", addr_str);
7565 if (addr->bdaddr_type == BDADDR_BREDR) {
7575 if (addr->bdaddr_type != dev->bdaddr_type) {
7576 if (addr->bdaddr_type == dev->conn_bdaddr_type)
7577 return bacmp(&dev->conn_bdaddr, &addr->bdaddr);
7584 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7585 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
7586 void device_change_pkt_type(gpointer data, gpointer user_data)
7588 int pkt_type = (int)user_data;
7589 struct btd_device *device = data;
7590 struct hci_conn_info_req *cr;
7591 set_conn_ptype_cp cp;
7596 /* Change a packet type only for Phone device */
7597 if ((device->class & 0x00001F00) >> 8 != 0x02)
7600 if (!device->bredr_state.connected)
7603 hdev = hci_open_dev(0);
7605 error("Cannot open hdev");
7609 cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
7611 error("Out of memory");
7614 cr->type = ACL_LINK;
7615 bacpy(&cr->bdaddr, &device->bdaddr);
7617 err = ioctl(hdev, HCIGETCONNINFO, cr);
7619 error("Fail to get HCIGETCOINFO");
7621 hci_close_dev(hdev);
7625 cp.handle = cr->conn_info->handle;
7627 cp.pkt_type = cpu_to_le16((uint16_t)pkt_type);
7629 ba2str(&device->bdaddr, addr);
7630 DBG("Handle %d, Addr %s", cp.handle, addr);
7631 DBG("Send Change pkt type request : 0x%X", pkt_type);
7633 if (hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SET_CONN_PTYPE,
7634 SET_CONN_PTYPE_CP_SIZE, &cp) < 0) {
7635 error("hci_send_cmd is failed");
7636 hci_close_dev(hdev);
7640 hci_close_dev(hdev);
7643 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
7646 static gboolean record_has_uuid(const sdp_record_t *rec,
7647 const char *profile_uuid)
7651 for (pat = rec->pattern; pat != NULL; pat = pat->next) {
7655 uuid = bt_uuid2string(pat->data);
7659 ret = strcasecmp(uuid, profile_uuid);
7670 GSList *btd_device_get_uuids(struct btd_device *device)
7672 return device->uuids;
7676 struct btd_device *dev;
7680 static struct btd_service *probe_service(struct btd_device *device,
7681 struct btd_profile *profile,
7685 struct btd_service *service;
7687 if (profile->device_probe == NULL)
7690 if (!device_match_profile(device, profile, uuids))
7693 l = find_service_with_profile(device->services, profile);
7694 /* If the service already exists, return NULL so that it won't be added
7695 * to the device->services.
7700 service = service_create(device, profile);
7702 if (service_probe(service)) {
7703 btd_service_unref(service);
7707 /* Only set auto connect if profile has set the flag and can really
7708 * accept connections.
7710 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
7711 if (profile->auto_connect && profile->accept)
7712 device_set_auto_connect(device, TRUE);
7718 static void dev_probe(struct btd_profile *p, void *user_data)
7720 struct probe_data *d = user_data;
7721 struct btd_service *service;
7723 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7724 if (find_service_with_profile(d->dev->services, p)) {
7725 DBG("%s is already probed.(UUID:%s)", p->name, p->remote_uuid);
7730 service = probe_service(d->dev, p, d->uuids);
7734 d->dev->services = g_slist_append(d->dev->services, service);
7737 void device_probe_profile(gpointer a, gpointer b)
7739 struct btd_device *device = a;
7740 struct btd_profile *profile = b;
7741 struct btd_service *service;
7743 service = probe_service(device, profile, device->uuids);
7747 device->services = g_slist_append(device->services, service);
7749 if (!profile->auto_connect || !device->general_connect)
7752 device->pending = g_slist_append(device->pending, service);
7754 if (g_slist_length(device->pending) == 1)
7755 connect_next(device);
7758 void device_remove_profile(gpointer a, gpointer b)
7760 struct btd_device *device = a;
7761 struct btd_profile *profile = b;
7762 struct btd_service *service;
7765 l = find_service_with_profile(device->services, profile);
7766 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
7768 if (g_strcmp0(profile->local_uuid , HID_DEVICE_UUID) == 0) {
7769 l = find_service_with_uuid(device->services,
7776 if (btd_service_get_state(service) ==
7777 BTD_SERVICE_STATE_CONNECTED) {
7779 err = btd_service_disconnect(service);
7781 error("error: %s", strerror(-err));
7792 device->services = g_slist_delete_link(device->services, l);
7793 device->pending = g_slist_remove(device->pending, service);
7794 service_remove(service);
7797 void device_probe_profiles(struct btd_device *device, GSList *uuids)
7799 struct probe_data d = { device, uuids };
7802 ba2str(&device->bdaddr, addr);
7804 if (device->blocked) {
7805 DBG("Skipping profiles for blocked device %s", addr);
7809 DBG("Probing profiles for device %s", addr);
7811 btd_profile_foreach(dev_probe, &d);
7814 device_add_uuids(device, uuids);
7817 static void store_sdp_record(GKeyFile *key_file, sdp_record_t *rec)
7819 char handle_str[11];
7824 sprintf(handle_str, "0x%8.8X", rec->handle);
7826 if (sdp_gen_record_pdu(rec, &buf) < 0)
7829 size = buf.data_size;
7831 str = g_malloc0(size*2+1);
7833 for (i = 0; i < size; i++)
7834 sprintf(str + (i * 2), "%02X", buf.data[i]);
7836 g_key_file_set_string(key_file, "ServiceRecords", handle_str, str);
7842 static void store_primaries_from_sdp_record(GKeyFile *key_file,
7846 char *att_uuid, *prim_uuid;
7847 uint16_t start = 0, end = 0, psm = 0;
7848 char handle[6], uuid_str[33];
7851 sdp_uuid16_create(&uuid, ATT_UUID);
7852 att_uuid = bt_uuid2string(&uuid);
7854 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
7855 prim_uuid = bt_uuid2string(&uuid);
7857 if (!record_has_uuid(rec, att_uuid))
7860 if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
7863 sprintf(handle, "%hu", start);
7864 switch (uuid.type) {
7866 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
7869 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
7872 for (i = 0; i < 16; i++)
7873 sprintf(uuid_str + (i * 2), "%2.2X",
7874 uuid.value.uuid128.data[i]);
7880 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
7881 g_key_file_set_string(key_file, handle, "Value", uuid_str);
7882 g_key_file_set_integer(key_file, handle, "EndGroupHandle", end);
7889 static int rec_cmp(const void *a, const void *b)
7891 const sdp_record_t *r1 = a;
7892 const sdp_record_t *r2 = b;
7894 return r1->handle - r2->handle;
7897 static int update_record(struct browse_req *req, const char *uuid,
7902 /* Check for duplicates */
7903 if (sdp_list_find(req->records, rec, rec_cmp))
7907 req->records = sdp_list_append(req->records, sdp_copy_record(rec));
7909 /* Check if UUID is duplicated */
7910 l = g_slist_find_custom(req->device->uuids, uuid, bt_uuid_strcmp);
7912 l = g_slist_find_custom(req->profiles_added, uuid,
7916 req->profiles_added = g_slist_append(req->profiles_added,
7923 static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
7925 struct btd_device *device = req->device;
7927 char srcaddr[18], dstaddr[18];
7928 char sdp_file[PATH_MAX];
7929 char att_file[PATH_MAX];
7930 GKeyFile *sdp_key_file;
7931 GKeyFile *att_key_file;
7932 GError *gerr = NULL;
7937 ba2str(btd_adapter_get_address(device->adapter), srcaddr);
7938 ba2str(&device->bdaddr, dstaddr);
7940 snprintf(sdp_file, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr,
7942 create_file(sdp_file, 0600);
7944 sdp_key_file = g_key_file_new();
7945 if (!g_key_file_load_from_file(sdp_key_file, sdp_file, 0, &gerr)) {
7946 error("Unable to load key file from %s: (%s)", sdp_file,
7948 g_clear_error(&gerr);
7949 g_key_file_free(sdp_key_file);
7950 sdp_key_file = NULL;
7953 snprintf(att_file, PATH_MAX, STORAGEDIR "/%s/%s/attributes", srcaddr,
7955 create_file(att_file, 0600);
7957 att_key_file = g_key_file_new();
7958 if (!g_key_file_load_from_file(att_key_file, att_file, 0, &gerr)) {
7959 error("Unable to load key file from %s: (%s)", att_file,
7961 g_clear_error(&gerr);
7962 g_key_file_free(att_key_file);
7963 att_key_file = NULL;
7966 for (seq = recs; seq; seq = seq->next) {
7967 sdp_record_t *rec = (sdp_record_t *) seq->data;
7973 /* If service class attribute is missing, svclass will be all
7974 * zero and the resulting uuid string will be NULL.
7976 profile_uuid = bt_uuid2string(&rec->svclass);
7981 if (bt_uuid_strcmp(profile_uuid, PNP_UUID) == 0) {
7982 uint16_t source, vendor, product, version;
7985 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
7986 source = pdlist ? pdlist->val.uint16 : 0x0000;
7988 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
7989 vendor = pdlist ? pdlist->val.uint16 : 0x0000;
7991 pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
7992 product = pdlist ? pdlist->val.uint16 : 0x0000;
7994 pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
7995 version = pdlist ? pdlist->val.uint16 : 0x0000;
7997 if (source || vendor || product || version)
7998 btd_device_set_pnpid(device, source, vendor,
8002 if (update_record(req, profile_uuid, rec) < 0)
8006 store_sdp_record(sdp_key_file, rec);
8009 store_primaries_from_sdp_record(att_key_file, rec);
8016 data = g_key_file_to_data(sdp_key_file, &length, NULL);
8018 if (!g_file_set_contents(sdp_file, data, length,
8020 error("Unable set contents for %s: (%s)",
8021 sdp_file, gerr->message);
8022 g_clear_error(&gerr);
8027 g_key_file_free(sdp_key_file);
8031 data = g_key_file_to_data(att_key_file, &length, NULL);
8033 if (!g_file_set_contents(att_file, data, length,
8035 error("Unable set contents for %s: (%s)",
8036 att_file, gerr->message);
8037 g_clear_error(&gerr);
8042 g_key_file_free(att_key_file);
8046 static int primary_cmp(gconstpointer a, gconstpointer b)
8048 return memcmp(a, b, sizeof(struct gatt_primary));
8051 static void update_gatt_uuids(struct browse_req *req, GSList *current,
8056 /* Added Profiles */
8057 for (l = found; l; l = g_slist_next(l)) {
8058 struct gatt_primary *prim = l->data;
8061 lmatch = g_slist_find_custom(current, prim, primary_cmp);
8066 req->profiles_added = g_slist_append(req->profiles_added,
8067 g_strdup(prim->uuid));
8069 DBG("UUID Added: %s", prim->uuid);
8073 static GSList *device_services_from_record(struct btd_device *device,
8076 GSList *l, *prim_list = NULL;
8080 sdp_uuid16_create(&proto_uuid, ATT_UUID);
8081 att_uuid = bt_uuid2string(&proto_uuid);
8083 for (l = profiles; l; l = l->next) {
8084 const char *profile_uuid = l->data;
8085 const sdp_record_t *rec;
8086 struct gatt_primary *prim;
8087 uint16_t start = 0, end = 0, psm = 0;
8090 rec = btd_device_get_record(device, profile_uuid);
8094 if (!record_has_uuid(rec, att_uuid))
8097 if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
8100 prim = g_new0(struct gatt_primary, 1);
8101 prim->range.start = start;
8102 prim->range.end = end;
8103 sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
8105 prim_list = g_slist_append(prim_list, prim);
8113 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
8115 struct browse_req *req = user_data;
8116 struct btd_device *device = req->device;
8121 ba2str(&device->bdaddr, addr);
8124 error("%s: error updating services: %s (%d)",
8125 addr, strerror(-err), -err);
8129 update_bredr_services(req, recs);
8131 if (device->tmp_records)
8132 sdp_list_free(device->tmp_records,
8133 (sdp_free_func_t) sdp_record_free);
8135 device->tmp_records = req->records;
8136 req->records = NULL;
8138 if (!req->profiles_added) {
8139 DBG("%s: No service update", addr);
8143 primaries = device_services_from_record(device, req->profiles_added);
8145 device_register_primaries(device, primaries, ATT_PSM);
8148 * TODO: The btd_service instances for GATT services need to be
8149 * initialized with the service handles. Eventually this code should
8150 * perform ATT protocol service discovery over the ATT PSM to obtain
8151 * the full list of services and populate a client-role gatt_db over
8154 device_probe_profiles(device, req->profiles_added);
8156 /* Propagate services changes */
8157 g_dbus_emit_property_changed(dbus_conn, req->device->path,
8158 DEVICE_INTERFACE, "UUIDs");
8161 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8165 /* since no new services are found, UUID signal is not emitted,
8166 ** so send a reply to the framework with the existing services */
8167 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
8168 "DiscoverServices"))
8169 discover_services_reply(req, err, device->tmp_records);
8173 /* If SDP search failed during an ongoing connection request, we should
8174 * reply to D-Bus method call.
8176 if (err < 0 && device->connect) {
8177 DBG("SDP failed during connection");
8178 reply = btd_error_failed(device->connect, strerror(-err));
8179 g_dbus_send_message(dbus_conn, reply);
8180 dbus_message_unref(device->connect);
8181 device->connect = NULL;
8184 device_svc_resolved(device, BROWSE_SDP, BDADDR_BREDR, err);
8187 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
8189 struct browse_req *req = user_data;
8190 struct btd_device *device = req->device;
8191 struct btd_adapter *adapter = device->adapter;
8194 /* If we have a valid response and req->search_uuid == 2, then L2CAP
8195 * UUID & PNP searching was successful -- we are done */
8196 if (err < 0 || (req->search_uuid == 2 && req->records)) {
8197 if (err == -ECONNRESET && req->reconnect_attempt < 1) {
8199 req->reconnect_attempt++;
8204 update_bredr_services(req, recs);
8206 /* Search for mandatory uuids */
8207 if (uuid_list[req->search_uuid]) {
8208 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
8209 bt_search_service(btd_adapter_get_address(adapter),
8210 &device->bdaddr, &uuid,
8211 browse_cb, user_data, NULL,
8217 search_cb(recs, err, user_data);
8220 static bool device_get_auto_connect(struct btd_device *device)
8222 if (device->disable_auto_connect)
8225 return device->auto_connect;
8228 static void disconnect_gatt_service(gpointer data, gpointer user_data)
8230 struct btd_service *service = data;
8231 struct btd_profile *profile = btd_service_get_profile(service);
8233 /* Ignore if profile cannot accept connections */
8234 if (!profile->accept)
8237 btd_service_disconnect(service);
8240 static void att_disconnected_cb(int err, void *user_data)
8242 struct btd_device *device = user_data;
8249 DBG("%s (%d)", strerror(err), err);
8251 g_slist_foreach(device->services, disconnect_gatt_service, NULL);
8253 btd_gatt_client_disconnected(device->client_dbus);
8255 if (!device_get_auto_connect(device)) {
8256 DBG("Automatic connection disabled");
8261 * Keep scanning/re-connection active if disconnection reason
8262 * is connection timeout, remote user terminated connection or local
8263 * initiated disconnection.
8265 if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
8266 adapter_connect_list_add(device->adapter, device);
8269 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8270 device_set_gatt_connected(device, FALSE);
8272 attio_cleanup(device);
8275 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8276 static void att_mtu_changed(uint16_t mtu, void *user_data)
8278 struct btd_device *device = user_data;
8280 DBG("att mtu changed %d", mtu);
8282 g_dbus_emit_signal(dbus_conn, device->path,
8283 DEVICE_INTERFACE, "AttMtuChanged",
8284 DBUS_TYPE_UINT16, &mtu,
8289 static void register_gatt_services(struct btd_device *device)
8291 struct browse_req *req = device->browse;
8292 GSList *services = NULL;
8294 if (!bt_gatt_client_is_ready(device->client))
8298 * TODO: Remove the primaries list entirely once all profiles use
8301 gatt_db_foreach_service(device->db, NULL, add_primary, &services);
8303 btd_device_set_temporary(device, false);
8305 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8307 if (req->search_uuid)
8308 DBG("browse req. is for SDP. Ignore it.");
8310 update_gatt_uuids(req, device->primaries, services);
8314 update_gatt_uuids(req, device->primaries, services);
8317 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8318 /* do not delete existing primary list,
8319 * just append the new primary uuids,
8320 * the list will be modifed when service changed
8321 * indication is received during connection */
8322 g_slist_free_full(device->primaries, g_free);
8323 device->primaries = NULL;
8326 device_register_primaries(device, services, -1);
8328 device_add_gatt_services(device);
8331 static void gatt_client_init(struct btd_device *device);
8333 static void gatt_client_ready_cb(bool success, uint8_t att_ecode,
8336 struct btd_device *device = user_data;
8338 DBG("status: %s, error: %u", success ? "success" : "failed", att_ecode);
8341 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
8346 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8347 /* Register the services after setting the client is ready
8348 * and exporting all the services and characteristics paths.
8350 register_gatt_services(device);
8353 btd_gatt_client_ready(device->client_dbus);
8354 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8355 register_gatt_services(device);
8358 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type, 0);
8360 store_gatt_db(device);
8362 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8363 if (device->name[0] == '\0') {
8365 name = bt_gatt_client_get_gap_device_name(device->client);
8367 strncpy(device->name, name, MAX_NAME_LENGTH);
8372 static void gatt_client_service_changed(uint16_t start_handle,
8373 uint16_t end_handle,
8376 DBG("start 0x%04x, end: 0x%04x", start_handle, end_handle);
8379 static void gatt_debug(const char *str, void *user_data)
8384 static void gatt_client_init(struct btd_device *device)
8386 gatt_client_cleanup(device);
8388 if (!device->connect && !btd_opts.reverse_discovery) {
8389 DBG("Reverse service discovery disabled: skipping GATT client");
8393 device->client = bt_gatt_client_new(device->db, device->att,
8394 device->att_mtu, 0);
8395 if (!device->client) {
8396 DBG("Failed to initialize");
8400 bt_gatt_client_set_debug(device->client, gatt_debug, NULL, NULL);
8403 * Notify notify existing service about the new connection so they can
8404 * react to notifications while discovering services
8406 device_accept_gatt_profiles(device);
8408 device->gatt_ready_id = bt_gatt_client_ready_register(device->client,
8409 gatt_client_ready_cb,
8411 if (!device->gatt_ready_id) {
8412 DBG("Failed to register GATT ready callback");
8413 gatt_client_cleanup(device);
8417 if (!bt_gatt_client_set_service_changed(device->client,
8418 gatt_client_service_changed,
8420 DBG("Failed to set service changed handler");
8421 gatt_client_cleanup(device);
8425 btd_gatt_client_connected(device->client_dbus);
8427 /* Only initiate EATT connection when acting as initiator, as acceptor
8428 * it shall be triggered only when ready to avoid possible clashes where
8429 * both sides attempt to connection at same time.
8431 if (device->connect)
8432 btd_gatt_client_eatt_connect(device->client_dbus);
8435 static void gatt_server_init(struct btd_device *device,
8436 struct btd_gatt_database *database)
8438 struct gatt_db *db = btd_gatt_database_get_db(database);
8441 error("No local GATT database exists for this adapter");
8445 gatt_server_cleanup(device);
8447 device->server = bt_gatt_server_new(db, device->att, device->att_mtu,
8449 if (!device->server) {
8450 error("Failed to initialize bt_gatt_server");
8454 bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
8456 bt_gatt_server_set_debug(device->server, gatt_debug, NULL, NULL);
8458 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8459 if (!bt_gatt_server_set_mtu_changed(device->server,
8462 DBG("Failed to set mtu changed handler");
8468 static bool local_counter(uint32_t *sign_cnt, void *user_data)
8470 struct btd_device *dev = user_data;
8472 if (!dev->local_csrk)
8475 *sign_cnt = dev->local_csrk->counter++;
8477 store_device_info(dev);
8482 static bool remote_counter(uint32_t *sign_cnt, void *user_data)
8484 struct btd_device *dev = user_data;
8486 if (!dev->remote_csrk || *sign_cnt < dev->remote_csrk->counter)
8489 dev->remote_csrk->counter = *sign_cnt;
8491 store_device_info(dev);
8496 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8497 static bool load_svc_change_indication_status(struct btd_device *device, const char *local,
8500 char filename[PATH_MAX];
8502 gboolean svc_change_regd = false;
8503 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
8505 key_file = g_key_file_new();
8506 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
8509 /* Load Service changed Registered flag */
8510 svc_change_regd = g_key_file_get_boolean(key_file, "Att",
8511 "SvcChangeRegd", NULL);
8512 bt_att_set_svc_changed_indication_registered(device->att,
8517 g_key_file_free(key_file);
8519 return svc_change_regd;
8523 bool device_attach_att(struct btd_device *dev, GIOChannel *io)
8525 GError *gerr = NULL;
8527 BtIOSecLevel sec_level;
8530 struct btd_gatt_database *database;
8531 const bdaddr_t *dst;
8533 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8534 uint8_t dst_type = BDADDR_BREDR;
8536 const bdaddr_t *src;
8539 bt_io_get(io, &gerr, BT_IO_OPT_SEC_LEVEL, &sec_level,
8540 BT_IO_OPT_IMTU, &mtu,
8541 BT_IO_OPT_CID, &cid,
8542 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8543 BT_IO_OPT_DEST_TYPE, &dst_type,
8548 error("bt_io_get: %s", gerr->message);
8554 if (btd_opts.gatt_channels == bt_att_get_channels(dev->att)) {
8555 DBG("EATT channel limit reached");
8559 if (!bt_att_attach_fd(dev->att, g_io_channel_unix_get_fd(io))) {
8560 DBG("EATT channel connected");
8561 g_io_channel_set_close_on_unref(io, FALSE);
8565 error("Failed to attach EATT channel");
8569 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8570 if (sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
8571 DBG("Elevating security level since LTK is available");
8573 sec_level = BT_IO_SEC_MEDIUM;
8574 bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level,
8577 error("bt_io_set: %s", gerr->message);
8584 dev->att_mtu = MIN(mtu, btd_opts.gatt_mtu);
8585 attrib = g_attrib_new(io,
8586 cid == ATT_CID ? BT_ATT_DEFAULT_LE_MTU : dev->att_mtu,
8589 error("Unable to create new GAttrib instance");
8593 dev->attrib = attrib;
8594 dev->att = g_attrib_get_att(attrib);
8596 bt_att_ref(dev->att);
8598 bt_att_set_debug(dev->att, BT_ATT_DEBUG, gatt_debug, NULL, NULL);
8600 dev->att_disconn_id = bt_att_register_disconnect(dev->att,
8601 att_disconnected_cb, dev, NULL);
8602 bt_att_set_close_on_unref(dev->att, true);
8604 if (dev->local_csrk)
8605 bt_att_set_local_key(dev->att, dev->local_csrk->key,
8606 local_counter, dev);
8608 if (dev->remote_csrk)
8609 bt_att_set_remote_key(dev->att, dev->remote_csrk->key,
8610 remote_counter, dev);
8612 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8613 if (dst_type != BDADDR_BREDR && device_get_rpa_exist(dev) == true) {
8614 bt_att_set_remote_addr(dev->att,
8615 device_get_rpa(dev), BDADDR_LE_RANDOM);
8617 bt_att_set_remote_addr(dev->att,
8618 &dev->bdaddr, dev->bdaddr_type);
8622 database = btd_adapter_get_database(dev->adapter);
8624 dst = device_get_address(dev);
8625 ba2str(dst, dstaddr);
8627 if (gatt_db_isempty(dev->db))
8628 load_gatt_db(dev, btd_adapter_get_storage_dir(dev->adapter),
8631 gatt_client_init(dev);
8632 gatt_server_init(dev, database);
8635 * Remove the device from the connect_list and give the passive
8636 * scanning another chance to be restarted in case there are
8637 * other devices in the connect_list.
8639 adapter_connect_list_remove(dev->adapter, dev);
8641 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8642 src = btd_adapter_get_address(dev->adapter);
8643 ba2str(src, srcaddr);
8645 /* load the service changed indication status on connection */
8646 load_svc_change_indication_status(dev, srcaddr, dstaddr);
8652 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
8654 struct btd_device *device = user_data;
8659 g_io_channel_unref(device->att_io);
8660 device->att_io = NULL;
8663 DBG("%s", gerr->message);
8665 if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
8668 if (device_get_auto_connect(device)) {
8669 DBG("Enabling automatic connections");
8670 adapter_connect_list_add(device->adapter, device);
8674 browse_request_complete(device->browse,
8676 device->bdaddr_type,
8679 err = -ECONNABORTED;
8683 if (!device_attach_att(device, io))
8686 if (!device->bonding)
8689 if (device->bonding->agent)
8690 io_cap = agent_get_io_capability(device->bonding->agent);
8692 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
8694 err = adapter_create_bonding(device->adapter, &device->bdaddr,
8695 device->bdaddr_type, io_cap);
8697 if (device->bonding && err < 0) {
8698 reply = btd_error_failed(device->bonding->msg, strerror(-err));
8699 g_dbus_send_message(dbus_conn, reply);
8700 bonding_request_cancel(device->bonding);
8701 bonding_request_free(device->bonding);
8705 device_browse_gatt(device, NULL);
8707 if (device->connect) {
8709 reply = btd_error_failed(device->connect,
8710 btd_error_le_conn_from_errno(err));
8712 reply = dbus_message_new_method_return(device->connect);
8714 g_dbus_send_message(dbus_conn, reply);
8715 dbus_message_unref(device->connect);
8716 device->connect = NULL;
8720 int device_connect_le(struct btd_device *dev)
8722 struct btd_adapter *adapter = dev->adapter;
8723 BtIOSecLevel sec_level;
8725 GError *gerr = NULL;
8728 /* There is one connection attempt going on */
8732 ba2str(&dev->bdaddr, addr);
8734 DBG("Connection attempt to: %s", addr);
8736 if (dev->le_state.paired)
8737 sec_level = BT_IO_SEC_MEDIUM;
8739 sec_level = BT_IO_SEC_LOW;
8742 * This connection will help us catch any PDUs that comes before
8745 io = bt_io_connect(att_connect_cb, dev, NULL, &gerr,
8746 BT_IO_OPT_SOURCE_BDADDR,
8747 btd_adapter_get_address(adapter),
8748 BT_IO_OPT_SOURCE_TYPE,
8749 btd_adapter_get_address_type(adapter),
8750 BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
8751 BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
8752 BT_IO_OPT_CID, ATT_CID,
8753 BT_IO_OPT_SEC_LEVEL, sec_level,
8758 DBusMessage *reply = btd_error_failed(
8759 dev->bonding->msg, gerr->message);
8761 g_dbus_send_message(dbus_conn, reply);
8762 bonding_request_cancel(dev->bonding);
8763 bonding_request_free(dev->bonding);
8766 error("ATT bt_io_connect(%s): %s", addr, gerr->message);
8771 /* Keep this, so we can cancel the connection */
8777 static struct browse_req *browse_request_new(struct btd_device *device,
8781 struct browse_req *req;
8786 req = g_new0(struct browse_req, 1);
8787 req->device = device;
8790 device->browse = req;
8795 req->msg = dbus_message_ref(msg);
8798 * Track the request owner to cancel it automatically if the owner
8801 req->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
8802 dbus_message_get_sender(msg),
8803 browse_request_exit,
8809 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg)
8811 struct btd_adapter *adapter = device->adapter;
8812 struct browse_req *req;
8814 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8817 req = browse_request_new(device, BROWSE_GATT, msg);
8821 if (device->client) {
8823 * If discovery has not yet completed, then wait for gatt-client
8826 if (!bt_gatt_client_is_ready(device->client))
8830 * Services have already been discovered, so signal this browse
8831 * request as resolved.
8833 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
8838 device->att_io = bt_io_connect(att_connect_cb,
8840 BT_IO_OPT_SOURCE_BDADDR,
8841 btd_adapter_get_address(adapter),
8842 BT_IO_OPT_SOURCE_TYPE,
8843 btd_adapter_get_address_type(adapter),
8844 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
8845 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
8846 BT_IO_OPT_CID, ATT_CID,
8847 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
8850 if (device->att_io == NULL) {
8851 browse_request_free(req);
8858 static uint16_t get_sdp_flags(struct btd_device *device)
8862 vid = btd_device_get_vendor(device);
8863 pid = btd_device_get_product(device);
8865 /* Sony DualShock 4 is not respecting negotiated L2CAP MTU. This might
8866 * results in SDP response being dropped by kernel. Workaround this by
8867 * forcing SDP code to use bigger MTU while connecting.
8869 if (vid == 0x054c && pid == 0x05c4)
8870 return SDP_LARGE_MTU;
8872 if (btd_adapter_ssp_enabled(device->adapter))
8875 /* if no EIR try matching Sony DualShock 4 with name and class */
8876 if (!strncmp(device->name, "Wireless Controller", MAX_NAME_LENGTH) &&
8877 device->class == 0x2508)
8878 return SDP_LARGE_MTU;
8883 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
8885 struct btd_adapter *adapter = device->adapter;
8886 struct browse_req *req;
8890 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8893 req = browse_request_new(device, BROWSE_SDP, msg);
8897 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
8899 req->sdp_flags = get_sdp_flags(device);
8901 err = bt_search(btd_adapter_get_address(adapter),
8902 &device->bdaddr, &uuid, browse_cb, req, NULL,
8905 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8906 device->browse = NULL;
8908 browse_request_free(req);
8915 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8916 void device_set_last_addr_type(struct btd_device *device, uint8_t type)
8921 //DBG("Last addr type %d", type);
8923 device->last_bdaddr_type = type;
8926 gboolean device_is_ipsp_connected(struct btd_device * device)
8928 return device->ipsp_connected;
8931 void device_set_ipsp_connected(struct btd_device *device, gboolean connected,
8932 const unsigned char *ifname)
8934 char *iface_name = NULL;
8936 if (device == NULL) {
8937 error("device is NULL");
8941 if (device->ipsp_connected == connected)
8944 device->ipsp_connected = connected;
8946 memset(device->if_name, 0, sizeof(device->if_name));
8947 memcpy(device->if_name, ifname, 16);
8948 iface_name = device->if_name;
8950 DBG("ipsp_connected %d", connected);
8951 DBG("ipsp_iface: %s is Up !", iface_name);
8953 g_dbus_emit_signal(dbus_conn, device->path,
8954 DEVICE_INTERFACE, "IpspStateChanged",
8955 DBUS_TYPE_BOOLEAN, &connected,
8956 DBUS_TYPE_STRING, &iface_name,
8959 void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_octets,
8960 uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time)
8962 if (device == NULL) {
8963 error("device is NULL");
8967 device->max_tx_octets = max_tx_octets;
8968 device->max_tx_time = max_tx_time;
8969 device->max_rx_octets = max_rx_octets;
8970 device->max_rx_time = max_rx_time;
8972 DBG("data length changed values :max_tx_octets: %d max_tx_time: %d max_rx_octets: %d max_rx_time: %d",
8973 max_tx_octets, max_tx_time, max_rx_octets, max_rx_time);
8975 g_dbus_emit_signal(dbus_conn, device->path,
8976 DEVICE_INTERFACE, "LEDataLengthChanged",
8977 DBUS_TYPE_UINT16, &max_tx_octets,
8978 DBUS_TYPE_UINT16, &max_tx_time,
8979 DBUS_TYPE_UINT16, &max_rx_octets,
8980 DBUS_TYPE_UINT16, &max_rx_time,
8984 const bdaddr_t *device_get_rpa(struct btd_device *device)
8989 const uint8_t *device_get_irk_value(struct btd_device *device)
8991 return device->irk_val;
8994 bool device_get_rpa_exist(struct btd_device *device)
8996 return device->rpa ? true : false;
8999 void device_set_auth_addr_type(struct btd_device *device, uint8_t type)
9004 DBG("Auth addr type %d", type);
9006 device->auth_bdaddr_type = type;
9009 void device_get_tizen_addr(struct btd_device *device, uint8_t type,
9010 struct device_addr_type *addr)
9012 if (!device || !addr)
9015 if (type == BDADDR_BREDR) {
9016 bacpy(&addr->bdaddr, &device->bdaddr);
9017 addr->bdaddr_type = BDADDR_BREDR;
9022 bacpy(&addr->bdaddr, device->rpa);
9023 addr->bdaddr_type = BDADDR_LE_RANDOM;
9027 bacpy(&addr->bdaddr, &device->bdaddr);
9028 addr->bdaddr_type = device->bdaddr_type;
9032 int device_discover_services(struct btd_device *device)
9037 err = device_browse_sdp(device, NULL);
9039 err = device_browse_gatt(device, NULL);
9041 if (err == 0 && device->discov_timer) {
9042 timeout_remove(device->discov_timer);
9043 device->discov_timer = 0;
9049 struct btd_adapter *device_get_adapter(struct btd_device *device)
9054 return device->adapter;
9057 const bdaddr_t *device_get_address(struct btd_device *device)
9059 return &device->bdaddr;
9061 uint8_t device_get_le_address_type(struct btd_device *device)
9063 return device->bdaddr_type;
9066 const char *device_get_path(const struct btd_device *device)
9071 return device->path;
9074 gboolean device_is_temporary(struct btd_device *device)
9076 return device->temporary;
9079 void btd_device_set_temporary(struct btd_device *device, bool temporary)
9084 if (device->temporary == temporary)
9087 if (device_address_is_private(device))
9090 DBG("temporary %d", temporary);
9092 device->temporary = temporary;
9096 adapter_accept_list_remove(device->adapter, device);
9097 adapter_connect_list_remove(device->adapter, device);
9098 if (device->auto_connect) {
9099 device->disable_auto_connect = TRUE;
9100 device_set_auto_connect(device, FALSE);
9102 set_temporary_timer(device, btd_opts.tmpto);
9105 clear_temporary_timer(device);
9108 adapter_accept_list_add(device->adapter, device);
9110 store_device_info(device);
9112 /* attributes were not stored when resolved if device was temporary */
9113 if (device->bdaddr_type != BDADDR_BREDR &&
9114 device->le_state.svc_resolved &&
9115 g_slist_length(device->primaries) != 0)
9116 store_services(device);
9119 void btd_device_set_trusted(struct btd_device *device, gboolean trusted)
9124 if (device->trusted == trusted)
9127 DBG("trusted %d", trusted);
9129 device->trusted = trusted;
9131 store_device_info(device);
9133 g_dbus_emit_property_changed(dbus_conn, device->path,
9134 DEVICE_INTERFACE, "Trusted");
9137 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9138 void device_disconnect_blocked(struct btd_device *device, char *uuid)
9140 struct btd_service *service;
9143 if (!device || !uuid)
9146 l = find_service_with_uuid(device->services, uuid);
9151 if (btd_service_get_state(service) ==
9152 BTD_SERVICE_STATE_CONNECTED) {
9154 err = btd_service_disconnect(service);
9156 error("error: %s", strerror(-err));
9160 void btd_device_set_trusted_profiles(struct btd_device *device,
9161 uint32_t pbap, uint32_t map, uint32_t sap,
9162 uint32_t hfp_hs, uint32_t a2dp)
9167 DBG("TrustedProfiles Parameters: [PBAP %d] [MAP %d] [SAP %d] [HFP %d] [A2DP %d]",
9168 pbap, map, sap, hfp_hs, a2dp);
9170 if (device->trusted_profiles.pbap == pbap &&
9171 device->trusted_profiles.map == map &&
9172 device->trusted_profiles.sap == sap &&
9173 device->trusted_profiles.hfp_hs == hfp_hs &&
9174 device->trusted_profiles.a2dp == a2dp)
9177 /* Disconnect OBEX based profiles if connected */
9178 if (device->trusted_profiles.pbap != pbap) {
9179 device->trusted_profiles.pbap = pbap;
9180 if (pbap == SUPPORTED_BLOCKED)
9181 device_disconnect_blocked(device, OBEX_PSE_UUID);
9182 } else if (device->trusted_profiles.map != map) {
9183 device->trusted_profiles.map = map;
9184 if (map == SUPPORTED_BLOCKED)
9185 device_disconnect_blocked(device, OBEX_MAP_UUID);
9186 } else if (device->trusted_profiles.sap != sap) {
9187 device->trusted_profiles.sap = sap;
9188 if (sap == SUPPORTED_BLOCKED)
9189 device_disconnect_blocked(device, SAP_UUID);
9190 } else if (device->trusted_profiles.hfp_hs != hfp_hs) {
9191 device->trusted_profiles.hfp_hs = hfp_hs;
9192 } else if (device->trusted_profiles.a2dp != a2dp) {
9193 device->trusted_profiles.a2dp = a2dp;
9196 store_device_info(device);
9197 g_dbus_emit_property_changed(dbus_conn, device->path,
9198 DEVICE_INTERFACE, "TrustedProfiles");
9202 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type)
9209 if (bdaddr_type == BDADDR_BREDR)
9210 device->bredr_state.bonded = true;
9212 device->le_state.bonded = true;
9214 btd_device_set_temporary(device, false);
9217 void device_set_legacy(struct btd_device *device, bool legacy)
9222 DBG("legacy %d", legacy);
9224 if (device->legacy == legacy)
9227 device->legacy = legacy;
9229 g_dbus_emit_property_changed(dbus_conn, device->path,
9230 DEVICE_INTERFACE, "LegacyPairing");
9233 void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type,
9236 char filename[PATH_MAX];
9237 char device_addr[18];
9239 GError *gerr = NULL;
9244 ba2str(&device->bdaddr, device_addr);
9245 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
9246 btd_adapter_get_storage_dir(device->adapter),
9249 key_file = g_key_file_new();
9250 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
9251 error("Unable to load key file from %s: (%s)", filename,
9256 /* for bonded devices this is done on every connection so limit writes
9257 * to storage if no change needed
9259 if (bdaddr_type == BDADDR_BREDR) {
9260 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
9261 "CCC_BR/EDR", NULL);
9262 if (old_value == value)
9265 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_BR/EDR",
9268 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
9270 if (old_value == value)
9273 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_LE",
9277 create_file(filename, 0600);
9279 str = g_key_file_to_data(key_file, &length, NULL);
9280 if (!g_file_set_contents(filename, str, length, &gerr)) {
9281 error("Unable set contents for %s: (%s)", filename,
9288 g_key_file_free(key_file);
9290 void device_load_svc_chng_ccc(struct btd_device *device, uint16_t *ccc_le,
9291 uint16_t *ccc_bredr)
9293 char filename[PATH_MAX];
9294 char device_addr[18];
9296 GError *gerr = NULL;
9298 ba2str(&device->bdaddr, device_addr);
9299 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
9300 btd_adapter_get_storage_dir(device->adapter),
9303 key_file = g_key_file_new();
9304 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
9305 error("Unable to load key file from %s: (%s)", filename,
9310 if (!g_key_file_has_group(key_file, "ServiceChanged")) {
9314 *ccc_bredr = 0x0000;
9315 g_key_file_free(key_file);
9320 *ccc_le = g_key_file_get_integer(key_file, "ServiceChanged",
9324 *ccc_bredr = g_key_file_get_integer(key_file, "ServiceChanged",
9325 "CCC_BR/EDR", NULL);
9327 g_key_file_free(key_file);
9330 void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi,
9331 int8_t delta_threshold)
9336 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9337 if (rssi == 0 || device->rssi == 0) {
9338 if (device->rssi == rssi)
9342 device->rssi = rssi;
9343 DBG("rssi %d", rssi);
9345 if (rssi == 0 || device->rssi == 0) {
9346 if (device->rssi == rssi)
9349 DBG("rssi %d", rssi);
9351 device->rssi = rssi;
9355 if (device->rssi > rssi)
9356 delta = device->rssi - rssi;
9358 delta = rssi - device->rssi;
9360 /* only report changes of delta_threshold dBm or more */
9361 if (delta < delta_threshold)
9364 DBG("rssi %d delta %d", rssi, delta);
9366 device->rssi = rssi;
9370 g_dbus_emit_property_changed(dbus_conn, device->path,
9371 DEVICE_INTERFACE, "RSSI");
9374 void device_set_rssi(struct btd_device *device, int8_t rssi)
9376 device_set_rssi_with_delta(device, rssi, RSSI_THRESHOLD);
9379 void device_set_tx_power(struct btd_device *device, int8_t tx_power)
9384 if (device->tx_power == tx_power)
9387 DBG("tx_power %d", tx_power);
9389 device->tx_power = tx_power;
9391 g_dbus_emit_property_changed(dbus_conn, device->path,
9392 DEVICE_INTERFACE, "TxPower");
9395 void device_set_flags(struct btd_device *device, uint8_t flags)
9400 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
9401 DBG("flags %d", flags);
9404 if (device->ad_flags[0] == flags)
9407 device->ad_flags[0] = flags;
9409 g_dbus_emit_property_changed(dbus_conn, device->path,
9410 DEVICE_INTERFACE, "AdvertisingFlags");
9413 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9414 void device_set_le_connectable(struct btd_device *device, uint8_t adv_type)
9419 if (device->le_connectable)
9422 if (adv_type == ADV_TYPE_IND || adv_type == ADV_TYPE_DIRECT_IND)
9423 device->le_connectable = true;
9427 bool device_is_connectable(struct btd_device *device)
9435 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9436 /* Check the ADV type. Some beacon device can be connectable regardless adv flags */
9437 return device->le_connectable;
9439 /* Check if either Limited or General discoverable are set */
9440 return (device->ad_flags[0] & 0x03);
9444 static bool start_discovery(gpointer user_data)
9446 struct btd_device *device = user_data;
9449 device_browse_sdp(device, NULL);
9451 device_browse_gatt(device, NULL);
9453 device->discov_timer = 0;
9458 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type)
9460 struct bearer_state *state = get_state(dev, bdaddr_type);
9465 state->paired = true;
9467 /* If the other bearer state was already true we don't need to
9468 * send any property signals.
9470 if (dev->bredr_state.paired == dev->le_state.paired)
9473 if (!state->svc_resolved) {
9474 dev->pending_paired = true;
9478 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9479 if (dev->bonding == NULL)
9481 g_dbus_emit_property_changed(dbus_conn, dev->path,
9482 DEVICE_INTERFACE, "Paired");
9485 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type)
9487 struct bearer_state *state = get_state(dev, bdaddr_type);
9492 state->paired = false;
9495 * If the other bearer state is still true we don't need to
9496 * send any property signals or remove device.
9498 if (dev->bredr_state.paired != dev->le_state.paired) {
9499 /* TODO disconnect only unpaired bearer */
9500 if (state->connected)
9501 device_request_disconnect(dev, NULL);
9506 g_dbus_emit_property_changed(dbus_conn, dev->path,
9507 DEVICE_INTERFACE, "Paired");
9509 btd_device_set_temporary(dev, true);
9511 if (btd_device_is_connected(dev))
9512 device_request_disconnect(dev, NULL);
9514 btd_adapter_remove_device(dev->adapter, dev);
9517 static void device_auth_req_free(struct btd_device *device)
9519 struct authentication_req *authr = device->authr;
9525 agent_unref(authr->agent);
9527 g_free(authr->pincode);
9530 device->authr = NULL;
9533 bool device_is_retrying(struct btd_device *device)
9535 struct bonding_req *bonding = device->bonding;
9537 return bonding && bonding->retry_timer > 0;
9540 void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
9543 struct bonding_req *bonding = device->bonding;
9544 struct authentication_req *auth = device->authr;
9545 struct bearer_state *state = get_state(device, bdaddr_type);
9547 DBG("bonding %p status 0x%02x", bonding, status);
9549 if (auth && auth->agent)
9550 agent_cancel(auth->agent);
9553 device_cancel_authentication(device, TRUE);
9555 /* Put the device back to the temporary state so that it will be
9556 * treated as a newly discovered device.
9558 if (!device_is_paired(device, bdaddr_type) &&
9559 !device_is_trusted(device))
9560 btd_device_set_temporary(device, true);
9562 device_bonding_failed(device, status);
9563 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9564 device->legacy_pairing = false;
9568 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9569 device->legacy_pairing = false;
9571 device_auth_req_free(device);
9573 /* If we're already paired nothing more is needed */
9574 if (state->paired) {
9575 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9576 if (bdaddr_type == BDADDR_BREDR && state->svc_resolved) {
9577 DBG("Link key has been changed. Report it");
9579 g_dbus_emit_property_changed(dbus_conn,
9580 device->path, DEVICE_INTERFACE,
9583 DBG("Just overwrite Link key");
9584 } else if (bdaddr_type == BDADDR_LE_RANDOM ||
9585 bdaddr_type == BDADDR_LE_PUBLIC) {
9586 DBG("Long Term Key has been changed. Report it");
9587 g_dbus_emit_property_changed(dbus_conn, device->path,
9588 DEVICE_INTERFACE, "Paired");
9590 #endif /* TIZEN_FEATURE_BLUEZ_MODIFY */
9594 device_set_paired(device, bdaddr_type);
9596 /* If services are already resolved just reply to the pairing
9599 if (state->svc_resolved && bonding) {
9600 /* Attept to store services for this device failed because it
9601 * was not paired. Now that we're paired retry. */
9602 store_gatt_db(device);
9604 g_dbus_send_reply(dbus_conn, bonding->msg, DBUS_TYPE_INVALID);
9605 bonding_request_free(bonding);
9609 /* If we were initiators start service discovery immediately.
9610 * However if the other end was the initator wait a few seconds
9611 * before SDP. This is due to potential IOP issues if the other
9612 * end starts doing SDP at the same time as us */
9614 DBG("Proceeding with service discovery");
9615 /* If we are initiators remove any discovery timer and just
9616 * start discovering services directly */
9617 if (device->discov_timer) {
9618 timeout_remove(device->discov_timer);
9619 device->discov_timer = 0;
9622 if (bdaddr_type == BDADDR_BREDR)
9623 device_browse_sdp(device, bonding->msg);
9625 device_browse_gatt(device, bonding->msg);
9627 bonding_request_free(bonding);
9628 } else if (!state->svc_resolved) {
9629 if (!device->browse && !device->discov_timer &&
9630 btd_opts.reverse_discovery) {
9631 /* If we are not initiators and there is no currently
9632 * active discovery or discovery timer, set discovery
9634 DBG("setting timer for reverse service discovery");
9635 device->discov_timer = timeout_add_seconds(
9643 static gboolean svc_idle_cb(gpointer user_data)
9645 struct svc_callback *cb = user_data;
9646 struct btd_device *dev = cb->dev;
9648 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
9650 cb->func(cb->dev, 0, cb->user_data);
9657 unsigned int device_wait_for_svc_complete(struct btd_device *dev,
9658 device_svc_cb_t func,
9661 /* This API is only used for BR/EDR (for now) */
9662 struct bearer_state *state = &dev->bredr_state;
9663 static unsigned int id = 0;
9664 struct svc_callback *cb;
9666 cb = g_new0(struct svc_callback, 1);
9668 cb->user_data = user_data;
9672 dev->svc_callbacks = g_slist_prepend(dev->svc_callbacks, cb);
9674 if (state->svc_resolved || !btd_opts.reverse_discovery)
9675 cb->idle_id = g_idle_add(svc_idle_cb, cb);
9676 else if (dev->discov_timer >0) {
9677 timeout_remove(dev->discov_timer);
9678 dev->discov_timer = timeout_add_seconds(
9683 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9684 else if (!dev->browse) {
9685 DBG("Service is not going on. Start discovery");
9686 dev->discov_timer = timeout_add_seconds(
9691 DBG("Wait for service discovery");
9697 bool device_remove_svc_complete_callback(struct btd_device *dev,
9702 for (l = dev->svc_callbacks; l != NULL; l = g_slist_next(l)) {
9703 struct svc_callback *cb = l->data;
9708 if (cb->idle_id > 0)
9709 g_source_remove(cb->idle_id);
9711 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
9720 gboolean device_is_bonding(struct btd_device *device, const char *sender)
9722 struct bonding_req *bonding = device->bonding;
9724 if (!device->bonding)
9730 return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
9733 static gboolean device_bonding_retry(gpointer data)
9735 struct btd_device *device = data;
9736 struct btd_adapter *adapter = device_get_adapter(device);
9737 struct bonding_req *bonding = device->bonding;
9744 DBG("retrying bonding");
9745 bonding->retry_timer = 0;
9747 /* Restart the bonding timer to the begining of the pairing. If not
9748 * pincode request/reply occurs during this retry,
9749 * device_bonding_last_duration() will return a consistent value from
9751 device_bonding_restart_timer(device);
9754 io_cap = agent_get_io_capability(bonding->agent);
9756 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
9758 err = adapter_bonding_attempt(adapter, &device->bdaddr,
9759 device->bdaddr_type, io_cap);
9761 device_bonding_complete(device, bonding->bdaddr_type,
9767 int device_bonding_attempt_retry(struct btd_device *device)
9769 struct bonding_req *bonding = device->bonding;
9771 /* Ignore other failure events while retrying */
9772 if (device_is_retrying(device))
9778 /* Mark the end of a bonding attempt to compute the delta for the
9780 bonding_request_stop_timer(bonding);
9782 if (btd_adapter_pin_cb_iter_end(bonding->cb_iter))
9785 DBG("scheduling retry");
9786 bonding->retry_timer = g_timeout_add(3000,
9787 device_bonding_retry, device);
9791 void device_bonding_failed(struct btd_device *device, uint8_t status)
9793 struct bonding_req *bonding = device->bonding;
9796 DBG("status %u", status);
9799 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9800 if (device->legacy_pairing) {
9801 DBG("Emit LegacyPaired");
9802 g_dbus_emit_property_changed(dbus_conn, device->path,
9803 DEVICE_INTERFACE, "LegacyPaired");
9808 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9809 btd_device_set_temporary(device, TRUE);
9813 device_cancel_authentication(device, FALSE);
9815 reply = new_authentication_return(bonding->msg, status);
9816 g_dbus_send_message(dbus_conn, reply);
9818 bonding_request_free(bonding);
9821 struct btd_adapter_pin_cb_iter *device_bonding_iter(struct btd_device *device)
9823 if (device->bonding == NULL)
9826 return device->bonding->cb_iter;
9829 static void pincode_cb(struct agent *agent, DBusError *err, const char *pin,
9832 struct authentication_req *auth = data;
9833 struct btd_device *device = auth->device;
9835 /* No need to reply anything if the authentication already failed */
9836 if (auth->agent == NULL)
9839 btd_adapter_pincode_reply(device->adapter, &device->bdaddr,
9840 pin, pin ? strlen(pin) : 0);
9842 agent_unref(device->authr->agent);
9843 device->authr->agent = NULL;
9846 static void confirm_cb(struct agent *agent, DBusError *err, void *data)
9848 struct authentication_req *auth = data;
9849 struct btd_device *device = auth->device;
9851 /* No need to reply anything if the authentication already failed */
9852 if (auth->agent == NULL)
9855 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9856 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
9858 err ? FALSE : TRUE);
9859 device_set_auth_addr_type(device, BDADDR_BREDR);
9861 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
9863 err ? FALSE : TRUE);
9866 agent_unref(device->authr->agent);
9867 device->authr->agent = NULL;
9870 static void passkey_cb(struct agent *agent, DBusError *err,
9871 uint32_t passkey, void *data)
9873 struct authentication_req *auth = data;
9874 struct btd_device *device = auth->device;
9876 /* No need to reply anything if the authentication already failed */
9877 if (auth->agent == NULL)
9881 passkey = INVALID_PASSKEY;
9883 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9884 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
9885 auth->addr_type, passkey);
9886 device_set_auth_addr_type(device, BDADDR_BREDR);
9888 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
9889 auth->addr_type, passkey);
9892 agent_unref(device->authr->agent);
9893 device->authr->agent = NULL;
9896 static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
9898 struct authentication_req *auth = data;
9899 struct btd_device *device = auth->device;
9901 pincode_cb(agent, err, auth->pincode, auth);
9903 g_free(device->authr->pincode);
9904 device->authr->pincode = NULL;
9907 static struct authentication_req *new_auth(struct btd_device *device,
9912 struct authentication_req *auth;
9913 struct agent *agent;
9916 ba2str(&device->bdaddr, addr);
9917 DBG("Requesting agent authentication for %s", addr);
9919 if (device->authr) {
9920 error("Authentication already requested for %s", addr);
9924 if (device->bonding && device->bonding->agent)
9925 agent = agent_ref(device->bonding->agent);
9927 agent = agent_get(NULL);
9930 error("No agent available for request type %d", type);
9934 auth = g_new0(struct authentication_req, 1);
9935 auth->agent = agent;
9936 auth->device = device;
9938 auth->addr_type = addr_type;
9939 auth->secure = secure;
9940 device->authr = auth;
9945 int device_request_pincode(struct btd_device *device, gboolean secure)
9947 struct authentication_req *auth;
9950 auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_PINCODE, secure);
9954 err = agent_request_pincode(auth->agent, device, pincode_cb, secure,
9957 error("Failed requesting authentication");
9958 device_auth_req_free(device);
9964 int device_request_passkey(struct btd_device *device, uint8_t type)
9966 struct authentication_req *auth;
9969 auth = new_auth(device, type, AUTH_TYPE_PASSKEY, FALSE);
9973 err = agent_request_passkey(auth->agent, device, passkey_cb, auth,
9976 error("Failed requesting authentication");
9977 device_auth_req_free(device);
9983 int device_confirm_passkey(struct btd_device *device, uint8_t type,
9984 int32_t passkey, uint8_t confirm_hint)
9986 struct authentication_req *auth;
9989 /* Just-Works repairing policy */
9990 if (confirm_hint && device_is_paired(device, type)) {
9991 if (btd_opts.jw_repairing == JW_REPAIRING_NEVER) {
9992 btd_adapter_confirm_reply(device->adapter,
9996 } else if (btd_opts.jw_repairing == JW_REPAIRING_ALWAYS) {
9997 btd_adapter_confirm_reply(device->adapter,
10004 auth = new_auth(device, type, AUTH_TYPE_CONFIRM, FALSE);
10008 auth->passkey = passkey;
10010 #ifndef TIZEN_FEATURE_BLUEZ_CONFIRM_ONLY
10011 if (confirm_hint) {
10012 if (device->bonding != NULL) {
10013 /* We know the client has indicated the intent to pair
10014 * with the peer device, so we can auto-accept.
10016 btd_adapter_confirm_reply(device->adapter,
10022 err = agent_request_authorization(auth->agent, device,
10023 confirm_cb, auth, NULL);
10026 err = agent_request_confirmation(auth->agent, device, passkey,
10027 confirm_cb, auth, NULL);
10030 if (err == -EINPROGRESS) {
10031 /* Already in progress */
10032 confirm_cb(auth->agent, NULL, auth);
10036 error("Failed requesting authentication");
10037 device_auth_req_free(device);
10043 int device_notify_passkey(struct btd_device *device, uint8_t type,
10044 uint32_t passkey, uint8_t entered)
10046 struct authentication_req *auth;
10049 if (device->authr) {
10050 auth = device->authr;
10051 if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
10054 auth = new_auth(device, type, AUTH_TYPE_NOTIFY_PASSKEY, FALSE);
10059 err = agent_display_passkey(auth->agent, device, passkey, entered);
10061 error("Failed requesting authentication");
10062 device_auth_req_free(device);
10068 int device_notify_pincode(struct btd_device *device, gboolean secure,
10069 const char *pincode)
10071 struct authentication_req *auth;
10074 auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_NOTIFY_PINCODE, secure);
10078 auth->pincode = g_strdup(pincode);
10080 err = agent_display_pincode(auth->agent, device, pincode,
10081 display_pincode_cb, auth, NULL);
10083 if (err == -EINPROGRESS) {
10084 /* Already in progress */
10085 display_pincode_cb(auth->agent, NULL, auth);
10089 error("Failed requesting authentication");
10090 device_auth_req_free(device);
10096 static void cancel_authentication(struct authentication_req *auth)
10098 struct agent *agent;
10101 if (!auth || !auth->agent)
10104 agent = auth->agent;
10105 auth->agent = NULL;
10107 dbus_error_init(&err);
10108 dbus_set_error_const(&err, ERROR_INTERFACE ".Canceled", NULL);
10110 switch (auth->type) {
10111 case AUTH_TYPE_PINCODE:
10112 pincode_cb(agent, &err, NULL, auth);
10114 case AUTH_TYPE_CONFIRM:
10115 confirm_cb(agent, &err, auth);
10117 case AUTH_TYPE_PASSKEY:
10118 passkey_cb(agent, &err, 0, auth);
10120 case AUTH_TYPE_NOTIFY_PASSKEY:
10121 /* User Notify doesn't require any reply */
10123 case AUTH_TYPE_NOTIFY_PINCODE:
10124 pincode_cb(agent, &err, NULL, auth);
10128 dbus_error_free(&err);
10131 void device_cancel_authentication(struct btd_device *device, gboolean aborted)
10133 struct authentication_req *auth = device->authr;
10139 ba2str(&device->bdaddr, addr);
10140 DBG("Canceling authentication request for %s", addr);
10143 agent_cancel(auth->agent);
10146 cancel_authentication(auth);
10148 device_auth_req_free(device);
10150 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10151 device_set_auth_addr_type(device, BDADDR_BREDR);
10155 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10156 gboolean device_is_authenticating(struct btd_device *dev, uint8_t bdaddr_type)
10158 return (dev->auth_bdaddr_type == bdaddr_type && dev->authr != NULL);
10161 gboolean device_is_authenticating(struct btd_device *device)
10163 return (device->authr != NULL);
10167 struct gatt_primary *btd_device_get_primary(struct btd_device *device,
10172 match = g_slist_find_custom(device->primaries, uuid, bt_uuid_strcmp);
10174 return match->data;
10179 GSList *btd_device_get_primaries(struct btd_device *device)
10181 return device->primaries;
10184 struct gatt_db *btd_device_get_gatt_db(struct btd_device *device)
10192 struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device)
10197 return device->client;
10200 void *btd_device_get_attrib(struct btd_device *device)
10205 return device->attrib;
10208 struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device)
10213 return device->server;
10216 void btd_device_gatt_set_service_changed(struct btd_device *device,
10217 uint16_t start, uint16_t end)
10220 * TODO: Remove this function and handle service changed via
10225 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
10230 if (g_slist_find_custom(device->uuids, uuid, bt_uuid_strcmp))
10233 new_uuid = g_strdup(uuid);
10234 uuid_list = g_slist_append(NULL, new_uuid);
10236 device_probe_profiles(device, uuid_list);
10239 g_slist_free(uuid_list);
10241 store_device_info(device);
10243 g_dbus_emit_property_changed(dbus_conn, device->path,
10244 DEVICE_INTERFACE, "UUIDs");
10247 static sdp_list_t *read_device_records(struct btd_device *device)
10249 char local[18], peer[18];
10250 char filename[PATH_MAX];
10251 GKeyFile *key_file;
10252 GError *gerr = NULL;
10253 char **keys, **handle;
10255 sdp_list_t *recs = NULL;
10258 ba2str(btd_adapter_get_address(device->adapter), local);
10259 ba2str(&device->bdaddr, peer);
10261 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10263 ba2str(device->rpa, peer);
10266 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
10268 key_file = g_key_file_new();
10269 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
10270 error("Unable to load key file from %s: (%s)", filename,
10272 g_error_free(gerr);
10274 keys = g_key_file_get_keys(key_file, "ServiceRecords", NULL, NULL);
10276 for (handle = keys; handle && *handle; handle++) {
10277 str = g_key_file_get_string(key_file, "ServiceRecords",
10282 rec = record_from_string(str);
10283 recs = sdp_list_append(recs, rec);
10288 g_key_file_free(key_file);
10293 void btd_device_set_record(struct btd_device *device, const char *uuid,
10294 const char *record)
10296 /* This API is only used for BR/EDR */
10297 struct bearer_state *state = &device->bredr_state;
10298 struct browse_req *req;
10299 sdp_list_t *recs = NULL;
10305 req = browse_request_new(device, BROWSE_SDP, NULL);
10309 rec = record_from_string(record);
10310 recs = sdp_list_append(recs, rec);
10311 update_bredr_services(req, recs);
10312 sdp_list_free(recs, NULL);
10314 device->svc_refreshed = true;
10315 state->svc_resolved = true;
10317 device_probe_profiles(device, req->profiles_added);
10319 /* Propagate services changes */
10320 g_dbus_emit_property_changed(dbus_conn, req->device->path,
10321 DEVICE_INTERFACE, "UUIDs");
10323 device_svc_resolved(device, BROWSE_SDP, device->bdaddr_type, 0);
10326 const sdp_record_t *btd_device_get_record(struct btd_device *device,
10329 /* Load records from storage if there is nothing in cache */
10330 if (!device->tmp_records) {
10331 device->tmp_records = read_device_records(device);
10332 if (!device->tmp_records)
10336 return find_record_in_list(device->tmp_records, uuid);
10339 struct btd_device *btd_device_ref(struct btd_device *device)
10341 __sync_fetch_and_add(&device->ref_count, 1);
10346 void btd_device_unref(struct btd_device *device)
10348 if (__sync_sub_and_fetch(&device->ref_count, 1))
10351 if (!device->path) {
10352 error("freeing device without an object path");
10356 DBG("Freeing device %s", device->path);
10358 g_dbus_unregister_interface(dbus_conn, device->path, DEVICE_INTERFACE);
10361 int device_get_appearance(struct btd_device *device, uint16_t *value)
10363 if (device->appearance == 0)
10367 *value = device->appearance;
10372 void device_set_appearance(struct btd_device *device, uint16_t value)
10374 const char *icon = gap_appearance_to_icon(value);
10376 if (device->appearance == value)
10379 g_dbus_emit_property_changed(dbus_conn, device->path,
10380 DEVICE_INTERFACE, "Appearance");
10383 g_dbus_emit_property_changed(dbus_conn, device->path,
10384 DEVICE_INTERFACE, "Icon");
10386 device->appearance = value;
10387 store_device_info(device);
10390 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10391 int device_get_rpa_res_char_value(struct btd_device *device)
10393 return device->rpa_res_support;
10396 /* Store the RPA Resolution Characteristic Value of remote device.
10397 * This value would be checked before start directed advertising using RPA.
10399 void device_set_rpa_res_char_value(struct btd_device *device, uint8_t value)
10401 if (device->rpa_res_support == value)
10404 device->rpa_res_support = value;
10405 store_device_info(device);
10408 void device_set_manufacturer_info(struct btd_device *device, struct eir_data *eir)
10413 if (eir->manufacturer_data_len == 0)
10416 device->manufacturer_data = g_memdup(eir->manufacturer_data,
10417 eir->manufacturer_data_len);
10418 device->manufacturer_data_len = eir->manufacturer_data_len;
10420 store_device_info(device);
10422 g_dbus_emit_property_changed(dbus_conn, device->path,
10423 DEVICE_INTERFACE, "LegacyManufacturerDataLen");
10425 g_dbus_emit_property_changed(dbus_conn, device->path,
10426 DEVICE_INTERFACE, "LegacyManufacturerData");
10430 void device_set_adv_report_info(struct btd_device *device, void *data, uint8_t data_len,
10431 uint8_t adv_type, int8_t rssi)
10436 char peer_addr[18];
10437 const char *paddr = peer_addr;
10438 dbus_int32_t rssi_val = rssi;
10439 int adv_len = data_len;
10442 ba2str(&device->bdaddr, peer_addr);
10444 /* Replace address type for paired RPA device since IDA passed from controller */
10446 ba2str(device->rpa, peer_addr);
10447 addr_type = BDADDR_LE_RANDOM;
10449 addr_type = device->bdaddr_type;
10451 g_dbus_emit_signal(dbus_conn, device->path,
10452 DEVICE_INTERFACE, "AdvReport",
10453 DBUS_TYPE_STRING, &paddr,
10454 DBUS_TYPE_BYTE, &addr_type,
10455 DBUS_TYPE_BYTE, &adv_type,
10456 DBUS_TYPE_INT32, &rssi_val,
10457 DBUS_TYPE_INT32, &adv_len,
10458 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_len,
10459 DBUS_TYPE_INVALID);
10462 void device_set_payload_timeout(struct btd_device *device,
10463 uint16_t payload_timeout)
10467 if (device->auth_payload_timeout == payload_timeout)
10470 DBG("Payload timeout %d", payload_timeout);
10472 device->auth_payload_timeout = payload_timeout;
10473 g_dbus_emit_property_changed(dbus_conn, device->path,
10474 DEVICE_INTERFACE, "PayloadTimeout");
10477 void device_set_disconnect_reason(struct btd_device *device, uint8_t reason)
10479 device->disc_reason = reason;
10482 void btd_device_disconnect(struct btd_device *device)
10485 struct btd_service *service;
10486 btd_service_state_t state;
10488 ba2str(&device->bdaddr, dst);
10491 if (device->bredr_state.connected == false)
10494 service = btd_device_get_service(device, HFP_HS_UUID);
10498 state = btd_service_get_state(service);
10499 DBG("Connected State : %d", state);
10501 if (state == BTD_SERVICE_STATE_DISCONNECTED) {
10502 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
10511 void btd_device_set_pnpid(struct btd_device *device, uint16_t source,
10512 uint16_t vendor, uint16_t product, uint16_t version)
10514 if (device->vendor_src == source && device->version == version &&
10515 device->vendor == vendor && device->product == product)
10518 device->vendor_src = source;
10519 device->vendor = vendor;
10520 device->product = product;
10521 device->version = version;
10523 free(device->modalias);
10524 device->modalias = bt_modalias(source, vendor, product, version);
10526 g_dbus_emit_property_changed(dbus_conn, device->path,
10527 DEVICE_INTERFACE, "Modalias");
10529 store_device_info(device);
10532 uint32_t btd_device_get_current_flags(struct btd_device *dev)
10534 return dev->current_flags;
10537 /* This event is sent immediately after add device on all mgmt sockets.
10538 * Afterwards, it is only sent to mgmt sockets other than the one which called
10539 * set_device_flags.
10541 void btd_device_flags_changed(struct btd_device *dev, uint32_t supported_flags,
10542 uint32_t current_flags)
10544 const uint32_t changed_flags = dev->current_flags ^ current_flags;
10547 dev->supported_flags = supported_flags;
10548 dev->current_flags = current_flags;
10550 if (!changed_flags)
10553 if (changed_flags & DEVICE_FLAG_REMOTE_WAKEUP) {
10554 flag_value = !!(current_flags & DEVICE_FLAG_REMOTE_WAKEUP);
10555 dev->pending_wake_allowed = flag_value;
10557 /* If an override exists and doesn't match the current state,
10558 * apply it. This logic will run after Add Device only and will
10559 * enable wake for previously paired devices.
10561 if (dev->wake_override != WAKE_FLAG_DEFAULT) {
10562 bool wake_allowed =
10563 dev->wake_override == WAKE_FLAG_ENABLED;
10564 if (flag_value != wake_allowed)
10565 device_set_wake_allowed(dev, wake_allowed, -1U);
10567 device_set_wake_allowed_complete(dev);
10569 device_set_wake_allowed_complete(dev);
10574 static void service_state_changed(struct btd_service *service,
10575 btd_service_state_t old_state,
10576 btd_service_state_t new_state,
10579 struct btd_profile *profile = btd_service_get_profile(service);
10580 struct btd_device *device = btd_service_get_device(service);
10581 int err = btd_service_get_error(service);
10583 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10585 if (old_state == BTD_SERVICE_STATE_UNAVAILABLE ||
10586 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
10587 DBG("Skip status updating ([%d] -> [%d])", old_state, new_state);
10589 g_dbus_emit_signal(dbus_conn, device->path,
10590 DEVICE_INTERFACE, "ProfileStateChanged",
10591 DBUS_TYPE_STRING, &profile->remote_uuid,
10592 DBUS_TYPE_INT32, &new_state,
10593 DBUS_TYPE_INVALID);
10596 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
10597 new_state == BTD_SERVICE_STATE_DISCONNECTING ||
10598 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
10600 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
10601 new_state == BTD_SERVICE_STATE_DISCONNECTING)
10605 if (old_state == BTD_SERVICE_STATE_CONNECTING)
10606 device_profile_connected(device, profile, err);
10607 else if (old_state == BTD_SERVICE_STATE_DISCONNECTING)
10608 device_profile_disconnected(device, profile, err);
10611 struct btd_service *btd_device_get_service(struct btd_device *dev,
10612 const char *remote_uuid)
10616 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
10617 struct btd_service *service = l->data;
10618 struct btd_profile *p = btd_service_get_profile(service);
10620 if (g_str_equal(p->remote_uuid, remote_uuid))
10623 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
10624 if (g_str_equal(HID_UUID, remote_uuid)) {
10625 if (strcmp(p->name, "hid-device") == 0)
10634 void btd_device_init(void)
10636 dbus_conn = btd_get_dbus_connection();
10637 service_state_cb_id = btd_service_add_state_cb(
10638 service_state_changed, NULL);
10641 void btd_device_cleanup(void)
10643 btd_service_remove_state_cb(service_state_cb_id);
10646 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10647 void btd_device_set_legacy_pairing(struct btd_device *dev, bool legacy_pairing)
10649 dev->legacy_pairing = legacy_pairing;
10652 void btd_device_set_svc_changed_indication(struct btd_device *dev, bool value)
10654 bt_att_set_svc_changed_indication_registered(dev->att, value);
10655 store_device_info(dev);
10658 bool btd_device_get_svc_changed_indication(struct btd_device *dev)
10660 return bt_att_get_svc_changed_indication_registered(dev->att);