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>
27 #include <dbus/dbus.h>
29 #include "lib/bluetooth.h"
31 #include "lib/sdp_lib.h"
34 #include "gdbus/gdbus.h"
37 #include "src/shared/util.h"
38 #include "src/shared/att.h"
39 #include "src/shared/queue.h"
40 #include "src/shared/gatt-db.h"
41 #include "src/shared/gatt-client.h"
42 #include "src/shared/gatt-server.h"
43 #include "src/shared/ad.h"
44 #include "src/shared/timeout.h"
45 #include "btio/btio.h"
47 #include "attrib/att.h"
50 #include "gatt-database.h"
51 #include "attrib/gattrib.h"
53 #include "gatt-client.h"
56 #include "dbus-common.h"
58 #include "uuid-helper.h"
59 #include "sdp-client.h"
60 #include "attrib/gatt.h"
64 #include "attrib-server.h"
67 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
69 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
70 #include <sys/ioctl.h>
71 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
74 #define DISCONNECT_TIMER 2
75 #define DISCOVERY_TIMER 1
76 #define INVALID_FLAGS 0xff
79 #define MIN(a, b) ((a) < (b) ? (a) : (b))
82 #define RSSI_THRESHOLD 8
84 #define GATT_PRIM_SVC_UUID_STR "2800"
85 #define GATT_SND_SVC_UUID_STR "2801"
86 #define GATT_INCLUDE_UUID_STR "2802"
87 #define GATT_CHARAC_UUID_STR "2803"
89 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
90 #define DEV_MAX_MANUFACTURER_DATA_LEN 248
93 static DBusConnection *dbus_conn = NULL;
94 static unsigned service_state_cb_id;
96 struct btd_disconnect_data {
98 disconnect_watch watch;
100 GDestroyNotify destroy;
106 struct btd_device *device;
109 struct btd_adapter_pin_cb_iter *cb_iter;
112 struct timespec attempt_start_time;
113 long last_attempt_duration_ms;
120 AUTH_TYPE_NOTIFY_PASSKEY,
121 AUTH_TYPE_NOTIFY_PINCODE,
124 struct authentication_req {
127 struct btd_device *device;
141 struct btd_device *device;
144 GSList *profiles_added;
147 int reconnect_attempt;
152 struct included_search {
153 struct browse_req *req;
158 struct svc_callback {
161 struct btd_device *dev;
162 device_svc_cb_t func;
166 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
167 struct le_adv_report_info {
169 char manufacturer_data[DEV_MAX_MANUFACTURER_DATA_LEN];
170 uint8_t manufacturer_data_len;
174 /* Per-bearer (LE or BR/EDR) device state */
175 struct bearer_state {
188 WAKE_FLAG_DEFAULT = 0,
194 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
197 DEV_PAIRED_BREDR = 1,
203 DEV_CONNECTED_NONE = 0,
204 DEV_CONNECTED_BREDR = 1,
206 DEV_CONNECTED_BREDR_LE,
207 } dev_connected_state;
209 struct trusted_profile_t {
221 bdaddr_t conn_bdaddr;
222 uint8_t conn_bdaddr_type;
228 bool pending_paired; /* "Paired" waiting for SDP */
230 bool refresh_discovery;
232 /* Manage whether this device can wake the system from suspend.
233 * - wake_support: Requires a profile that supports wake (i.e. HID)
234 * - wake_allowed: Is wake currently allowed?
235 * - pending_wake_allowed - Wake flag sent via set_device_flags
236 * - wake_override - User configured wake setting
240 bool pending_wake_allowed;
241 uint8_t wake_override;
242 GDBusPendingPropertySet wake_id;
244 uint32_t supported_flags;
245 uint32_t current_flags;
246 GSList *svc_callbacks;
250 char name[MAX_NAME_LENGTH + 1];
259 struct btd_adapter *adapter;
261 GSList *primaries; /* List of primary services */
262 GSList *services; /* List of btd_service */
263 GSList *pending; /* Pending services */
264 GSList *watches; /* List of disconnect_data */
267 unsigned int disconn_timer;
268 unsigned int discov_timer;
269 unsigned int temporary_timer; /* Temporary/disappear timer */
270 struct browse_req *browse; /* service discover request */
271 struct bonding_req *bonding;
272 struct authentication_req *authr; /* authentication request */
273 GSList *disconnects; /* disconnects message */
274 DBusMessage *connect; /* connect message */
275 DBusMessage *disconnect; /* disconnect message */
278 struct bt_att *att; /* The new ATT transport */
279 uint16_t att_mtu; /* The ATT MTU */
280 unsigned int att_disconn_id;
283 * TODO: For now, device creates and owns the client-role gatt_db, but
284 * this needs to be persisted in a more central place so that proper
285 * attribute cache support can be built.
287 struct gatt_db *db; /* GATT db cache */
289 struct bt_gatt_client *client; /* GATT client instance */
290 struct bt_gatt_server *server; /* GATT server instance */
291 unsigned int gatt_ready_id;
293 struct btd_gatt_client *client_dbus;
295 struct bearer_state bredr_state;
296 struct bearer_state le_state;
298 struct csrk_info *local_csrk;
299 struct csrk_info *remote_csrk;
300 uint8_t ltk_enc_size;
302 sdp_list_t *tmp_records;
308 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
309 struct trusted_profile_t trusted_profiles;
312 gboolean auto_connect;
313 gboolean disable_auto_connect;
314 gboolean general_connect;
323 time_t name_resolve_failed_time;
324 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
326 char *manufacturer_data;
327 int manufacturer_data_len;
328 struct le_adv_report_info le_adv_data;
329 int remote_feature_flags;
331 gboolean gatt_connected;
332 uint16_t auth_payload_timeout;
334 uint8_t last_bdaddr_type;
335 uint8_t auth_bdaddr_type;
336 gboolean ipsp_connected; /* IPSP Connection state */
337 char if_name[16 + 1]; /* BT interface UP after IPSP connection */
338 uint8_t rpa_res_support; /* RPA Resolution capability of device */
339 uint16_t max_tx_octets;
340 uint16_t max_tx_time;
341 uint16_t max_rx_octets;
342 uint16_t max_rx_time;
344 DBusMessage *req_att_mtu; /* Attribute MTU request message */
346 bool pending_conn_update;
351 static const uint16_t uuid_list[] = {
358 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
360 SHOW_AUTHORIZATION = 0x0, /* 0b00 */
361 SUPPORTED_BLOCKED = 0x1, /* 0b01 */
362 SUPPORTED_TRUSTED= 0x2, /* 0b10 */
363 } bt_profile_trusted_states;
365 #define PBAP_SHIFT_OFFSET 0
366 #define MAP_SHIFT_OFFSET 2
367 #define SAP_SHIFT_OFFSET 4
368 #define HFP_HS_SHIFT_OFFSET 6
369 #define A2DP_SHIFT_OFFSET 8
371 #define PROFILE_SUPPORTED 0x3 /* This corresponds to binary 0b11*/
375 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
376 #define OTP_PSM 0x0025
379 #define BT_OTC_SERVICE_NAME "org.otp.client"
380 #define BT_OTC_OBJECT_PATH "/org/otp/client"
381 #define BT_OTC_INTERFACE_NAME "org.otp.otc_channel"
384 #define BT_OTS_SERVICE_NAME "org.projectx.otp"
385 #define BT_OTS_OBJECT_PATH "/org/projectx/otp"
386 #define BT_OTS_INTERFACE_NAME "org.projectx.otp_service"
389 BT_OTP_CLIENT_ROLE = 0x00,
393 struct otc_conn_info {
394 const char *dev_path;
400 GSList *otc_connection_list = NULL;
403 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
404 #define BT_L2CAP_LE_INTERFACE_NAME "org.bluez.l2cap_le"
405 #define BTD_L2CAP_LE_PSM_MAX 0xFFFF
409 BT_L2CAP_LE_CLIENT_ROLE = 0x00,
410 BT_L2CAP_LE_SERVER_ROLE,
411 } bt_l2cap_le_role_e;
413 struct l2cap_le_conn_info {
414 struct l2cap_le_profile_info *profile_info;
418 const char *dev_path;
424 struct l2cap_le_profile_info {
428 bt_l2cap_le_role_e role;
430 BtIOSecLevel sec_level;
433 struct l2cap_le_conn_info *server;
437 GSList *l2cap_le_socket_list = NULL;
441 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg);
442 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg);
444 static struct bearer_state *get_state(struct btd_device *dev,
447 if (bdaddr_type == BDADDR_BREDR)
448 return &dev->bredr_state;
450 return &dev->le_state;
453 static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
457 for (l = list; l != NULL; l = g_slist_next(l)) {
458 struct btd_service *service = l->data;
460 if (btd_service_get_profile(service) == p)
467 static GSList *find_service_with_state(GSList *list,
468 btd_service_state_t state)
472 for (l = list; l != NULL; l = g_slist_next(l)) {
473 struct btd_service *service = l->data;
475 if (btd_service_get_state(service) == state)
482 static GSList *find_service_with_uuid(GSList *list, char *uuid)
486 for (l = list; l != NULL; l = g_slist_next(l)) {
487 struct btd_service *service = l->data;
488 struct btd_profile *profile = btd_service_get_profile(service);
490 if (bt_uuid_strcmp(profile->remote_uuid, uuid) == 0)
497 static void update_technologies(GKeyFile *file, struct btd_device *dev)
503 list[len++] = "BR/EDR";
508 if (dev->bdaddr_type == BDADDR_LE_PUBLIC)
513 g_key_file_set_string(file, "General", "AddressType", type);
518 g_key_file_set_string_list(file, "General", "SupportedTechnologies",
522 static void store_csrk(struct csrk_info *csrk, GKeyFile *key_file,
528 for (i = 0; i < 16; i++)
529 sprintf(key + (i * 2), "%2.2X", csrk->key[i]);
531 g_key_file_set_string(key_file, group, "Key", key);
532 g_key_file_set_integer(key_file, group, "Counter", csrk->counter);
535 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
536 static char *manufacturer_data2str(char *data, int size)
538 char str[DEV_MAX_MANUFACTURER_DATA_LEN * 3 + 1];
543 for(i = 0; i < size; i++) {
544 snprintf(tmp, sizeof(tmp), "%d ", data[i]);
545 g_strlcat(str, tmp, sizeof(str));
548 return g_strdup(str);
551 static void load_manufacturer_data_2digit(char *data, int len, char *buf)
556 split = g_strsplit(data, " ", 0);
558 for (i = 0; i < len; i++) {
559 if (split[i] == NULL)
562 buf[i] = (char)g_ascii_strtoull(split[i], NULL, 10);
571 static gboolean store_device_info_cb(gpointer user_data)
573 struct btd_device *device = user_data;
576 char filename[PATH_MAX];
577 char device_addr[18];
582 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
583 gboolean svc_change_regd = false;
586 device->store_id = 0;
588 ba2str(&device->bdaddr, device_addr);
590 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
592 ba2str(device->rpa, device_addr);
594 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
595 btd_adapter_get_storage_dir(device->adapter),
597 create_file(filename, 0600);
599 key_file = g_key_file_new();
600 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
601 error("Unable to load key file from %s: (%s)", filename,
604 g_key_file_free(key_file);
608 g_key_file_set_string(key_file, "General", "Name", device->name);
610 if (device->alias != NULL)
611 g_key_file_set_string(key_file, "General", "Alias",
614 g_key_file_remove_key(key_file, "General", "Alias", NULL);
617 sprintf(class, "0x%6.6x", device->class & 0xffffff);
618 g_key_file_set_string(key_file, "General", "Class", class);
620 g_key_file_remove_key(key_file, "General", "Class", NULL);
623 if (device->appearance) {
624 sprintf(class, "0x%4.4x", device->appearance);
625 g_key_file_set_string(key_file, "General", "Appearance", class);
627 g_key_file_remove_key(key_file, "General", "Appearance", NULL);
630 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
631 if (device->rpa_res_support) {
632 g_key_file_set_integer(key_file, "General", "RPAResSupport",
633 device->rpa_res_support);
635 g_key_file_remove_key(key_file, "General", "RPAResSupport", NULL);
639 update_technologies(key_file, device);
641 g_key_file_set_boolean(key_file, "General", "Trusted",
643 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
644 struct trusted_profile_t trust_profile = device->trusted_profiles;
645 int trusted_profiles = (trust_profile.pbap << PBAP_SHIFT_OFFSET) |
646 (trust_profile.map << MAP_SHIFT_OFFSET) |
647 (trust_profile.sap << SAP_SHIFT_OFFSET) |
648 (trust_profile.hfp_hs << HFP_HS_SHIFT_OFFSET) |
649 (trust_profile.a2dp << A2DP_SHIFT_OFFSET);
650 DBG("Storing TrustedProfiles %d", trusted_profiles);
651 g_key_file_set_integer(key_file, "General", "TrustedProfiles",
654 g_key_file_set_boolean(key_file, "General", "Blocked",
657 if (device->wake_override != WAKE_FLAG_DEFAULT) {
658 g_key_file_set_boolean(key_file, "General", "WakeAllowed",
659 device->wake_override ==
667 uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
668 for (i = 0, l = device->uuids; l; l = g_slist_next(l), i++)
670 g_key_file_set_string_list(key_file, "General", "Services",
671 (const char **)uuids, i);
673 g_key_file_remove_key(key_file, "General", "Services", NULL);
676 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
677 if (device->le_adv_data.flags) {
678 g_key_file_set_integer(key_file, "General", "Flags",
679 device->le_adv_data.flags);
681 g_key_file_remove_key(key_file, "General", "Flags", NULL);
684 if (device->manufacturer_data) {
685 str = manufacturer_data2str(device->manufacturer_data,
686 device->manufacturer_data_len);
687 g_key_file_set_string(key_file, "General",
688 "LegacyManufacturerData",
691 g_key_file_set_integer(key_file, "General",
692 "LegacyManufacturerDataLen",
693 device->manufacturer_data_len);
695 g_key_file_remove_key(key_file, "General",
696 "LegacyManufacturerData", NULL);
697 g_key_file_remove_key(key_file, "General",
698 "LegacyManufacturerDataLen", NULL);
704 ba2str(&device->bdaddr, irk_addr);
705 g_key_file_set_string(key_file, "General", "IdentityAddress",
708 g_key_file_remove_key(key_file, "General", "IdentityAddress",
713 if (device->vendor_src) {
714 g_key_file_set_integer(key_file, "DeviceID", "Source",
716 g_key_file_set_integer(key_file, "DeviceID", "Vendor",
718 g_key_file_set_integer(key_file, "DeviceID", "Product",
720 g_key_file_set_integer(key_file, "DeviceID", "Version",
723 g_key_file_remove_group(key_file, "DeviceID", NULL);
726 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
727 svc_change_regd = bt_att_get_svc_changed_indication_registered(device->att);
728 g_key_file_set_boolean(key_file, "Att", "SvcChangeRegd",
732 if (device->local_csrk)
733 store_csrk(device->local_csrk, key_file, "LocalSignatureKey");
735 if (device->remote_csrk)
736 store_csrk(device->remote_csrk, key_file, "RemoteSignatureKey");
738 str = g_key_file_to_data(key_file, &length, NULL);
739 if (!g_file_set_contents(filename, str, length, &gerr)) {
740 error("Unable set contents for %s: (%s)", filename,
747 g_key_file_free(key_file);
753 static bool device_address_is_private(struct btd_device *dev)
755 if (dev->bdaddr_type != BDADDR_LE_RANDOM)
758 switch (dev->bdaddr.b[5] >> 6) {
759 case 0x00: /* Private non-resolvable */
760 case 0x01: /* Private resolvable */
767 static void store_device_info(struct btd_device *device)
769 if (device->temporary || device->store_id > 0)
772 if (device_address_is_private(device)) {
773 DBG("Can't store info for private addressed device %s",
778 device->store_id = g_idle_add(store_device_info_cb, device);
781 void device_store_cached_name(struct btd_device *dev, const char *name)
783 char filename[PATH_MAX];
790 gsize length_old = 0;
792 if (device_address_is_private(dev)) {
793 DBG("Can't store name for private addressed device %s",
798 ba2str(&dev->bdaddr, d_addr);
800 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
802 ba2str(dev->rpa, d_addr);
805 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
806 btd_adapter_get_storage_dir(dev->adapter), d_addr);
807 create_file(filename, 0600);
809 key_file = g_key_file_new();
810 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
811 error("Unable to load key file from %s: (%s)", filename,
816 data_old = g_key_file_to_data(key_file, &length_old, NULL);
818 g_key_file_set_string(key_file, "General", "Name", name);
820 data = g_key_file_to_data(key_file, &length, NULL);
822 if ((length != length_old) || (memcmp(data, data_old, length))) {
823 if (!g_file_set_contents(filename, data, length, &gerr)) {
824 error("Unable set contents for %s: (%s)", filename,
832 g_key_file_free(key_file);
835 static void device_store_cached_name_resolve(struct btd_device *dev)
837 char filename[PATH_MAX];
844 gsize length_old = 0;
845 uint64_t failed_time;
847 if (device_address_is_private(dev)) {
848 DBG("Can't store name resolve for private addressed device %s",
853 ba2str(&dev->bdaddr, d_addr);
854 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
855 btd_adapter_get_storage_dir(dev->adapter), d_addr);
856 create_file(filename, 0600);
858 key_file = g_key_file_new();
859 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
860 error("Unable to load key file from %s: (%s)", filename,
865 failed_time = (uint64_t) dev->name_resolve_failed_time;
867 data_old = g_key_file_to_data(key_file, &length_old, NULL);
869 g_key_file_set_uint64(key_file, "NameResolving", "FailedTime",
872 data = g_key_file_to_data(key_file, &length, NULL);
874 if ((length != length_old) || (memcmp(data, data_old, length))) {
875 if (!g_file_set_contents(filename, data, length, &gerr)) {
876 error("Unable set contents for %s: (%s)", filename,
885 g_key_file_free(key_file);
888 static void browse_request_free(struct browse_req *req)
890 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
893 struct btd_device *device = req->device;
895 if (device->browse == req)
896 device->browse = NULL;
898 if (req->listener_id)
899 g_dbus_remove_watch(dbus_conn, req->listener_id);
901 dbus_message_unref(req->msg);
902 g_slist_free_full(req->profiles_added, g_free);
904 sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
909 static bool gatt_cache_is_enabled(struct btd_device *device)
911 switch (btd_opts.gatt_cache) {
912 case BT_GATT_CACHE_YES:
913 return device_is_paired(device, device->bdaddr_type);
914 case BT_GATT_CACHE_NO:
916 case BT_GATT_CACHE_ALWAYS:
922 static void gatt_cache_cleanup(struct btd_device *device)
924 if (gatt_cache_is_enabled(device))
927 bt_gatt_client_cancel_all(device->client);
928 gatt_db_clear(device->db);
929 device->le_state.svc_resolved = false;
932 static void gatt_client_cleanup(struct btd_device *device)
937 gatt_cache_cleanup(device);
938 bt_gatt_client_set_service_changed(device->client, NULL, NULL, NULL);
940 if (device->gatt_ready_id > 0) {
941 bt_gatt_client_ready_unregister(device->client,
942 device->gatt_ready_id);
943 device->gatt_ready_id = 0;
946 bt_gatt_client_unref(device->client);
947 device->client = NULL;
950 static void gatt_server_cleanup(struct btd_device *device)
955 btd_gatt_database_att_disconnected(
956 btd_adapter_get_database(device->adapter), device);
958 bt_gatt_server_unref(device->server);
959 device->server = NULL;
962 static void attio_cleanup(struct btd_device *device)
964 if (device->att_disconn_id)
965 bt_att_unregister_disconnect(device->att,
966 device->att_disconn_id);
968 if (device->att_io) {
969 g_io_channel_shutdown(device->att_io, FALSE, NULL);
970 g_io_channel_unref(device->att_io);
971 device->att_io = NULL;
974 gatt_client_cleanup(device);
975 gatt_server_cleanup(device);
978 bt_att_unref(device->att);
982 if (device->attrib) {
983 GAttrib *attrib = device->attrib;
985 device->attrib = NULL;
986 g_attrib_cancel_all(attrib);
987 g_attrib_unref(attrib);
991 static void browse_request_cancel(struct browse_req *req)
993 struct btd_device *device = req->device;
994 struct btd_adapter *adapter = device->adapter;
998 bt_cancel_discovery(btd_adapter_get_address(adapter), &device->bdaddr);
1000 attio_cleanup(device);
1002 browse_request_free(req);
1005 static void svc_dev_remove(gpointer user_data)
1007 struct svc_callback *cb = user_data;
1009 if (cb->idle_id > 0)
1010 g_source_remove(cb->idle_id);
1012 cb->func(cb->dev, -ENODEV, cb->user_data);
1017 static void device_free(gpointer user_data)
1019 struct btd_device *device = user_data;
1021 btd_gatt_client_destroy(device->client_dbus);
1022 device->client_dbus = NULL;
1024 g_slist_free_full(device->uuids, g_free);
1025 g_slist_free_full(device->primaries, g_free);
1026 g_slist_free_full(device->svc_callbacks, svc_dev_remove);
1028 /* Reset callbacks since the device is going to be freed */
1029 gatt_db_unregister(device->db, device->db_id);
1031 attio_cleanup(device);
1033 gatt_db_unref(device->db);
1035 bt_ad_unref(device->ad);
1037 if (device->tmp_records)
1038 sdp_list_free(device->tmp_records,
1039 (sdp_free_func_t) sdp_record_free);
1041 if (device->disconn_timer)
1042 timeout_remove(device->disconn_timer);
1044 if (device->discov_timer)
1045 timeout_remove(device->discov_timer);
1047 if (device->temporary_timer)
1048 timeout_remove(device->temporary_timer);
1050 if (device->connect)
1051 dbus_message_unref(device->connect);
1053 if (device->disconnect)
1054 dbus_message_unref(device->disconnect);
1058 if (device->authr) {
1059 if (device->authr->agent)
1060 agent_unref(device->authr->agent);
1061 g_free(device->authr->pincode);
1062 g_free(device->authr);
1065 if (device->eir_uuids)
1066 g_slist_free_full(device->eir_uuids, g_free);
1068 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1069 g_free(device->rpa);
1071 g_free(device->local_csrk);
1072 g_free(device->remote_csrk);
1073 g_free(device->path);
1074 g_free(device->alias);
1075 free(device->modalias);
1079 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1080 void device_set_remote_feature_flag(struct btd_device *device, int flags)
1082 device->remote_feature_flags = flags;
1085 gboolean device_is_bredrle(struct btd_device *device)
1087 return (device->remote_feature_flags & (EIR_CONTROLLER | EIR_SIM_HOST));
1091 bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type)
1093 struct bearer_state *state = get_state(device, bdaddr_type);
1095 return state->paired;
1098 bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type)
1100 struct bearer_state *state = get_state(device, bdaddr_type);
1102 return state->bonded;
1105 gboolean device_is_trusted(struct btd_device *device)
1107 return device->trusted;
1110 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1111 gboolean device_is_profile_trusted(struct btd_device *device,
1114 if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1115 if (device->trusted_profiles.pbap == SUPPORTED_TRUSTED)
1117 } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1118 if (device->trusted_profiles.map == SUPPORTED_TRUSTED)
1120 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1121 if (device->trusted_profiles.sap == SUPPORTED_TRUSTED)
1123 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1124 if (device->trusted_profiles.hfp_hs == SUPPORTED_TRUSTED)
1126 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1127 if (device->trusted_profiles.a2dp == SUPPORTED_TRUSTED)
1133 gboolean device_is_profile_blocked(struct btd_device *device,
1136 if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1137 if (device->trusted_profiles.pbap == SUPPORTED_BLOCKED)
1139 } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1140 if (device->trusted_profiles.map == SUPPORTED_BLOCKED)
1142 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1143 if (device->trusted_profiles.sap == SUPPORTED_BLOCKED)
1145 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1146 if (device->trusted_profiles.hfp_hs == SUPPORTED_BLOCKED)
1148 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1149 if (device->trusted_profiles.a2dp == SUPPORTED_BLOCKED)
1156 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
1157 DBusMessageIter *iter, void *data)
1159 struct btd_device *device = data;
1161 const char *ptr = dstaddr;
1163 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1165 ba2str(device->rpa, dstaddr);
1168 ba2str(&device->bdaddr, dstaddr);
1169 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1174 static gboolean property_get_address_type(const GDBusPropertyTable *property,
1175 DBusMessageIter *iter, void *user_data)
1177 struct btd_device *device = user_data;
1180 if (device->le && device->bdaddr_type == BDADDR_LE_RANDOM)
1185 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
1190 static gboolean dev_property_get_name(const GDBusPropertyTable *property,
1191 DBusMessageIter *iter, void *data)
1193 struct btd_device *device = data;
1194 const char *ptr = device->name;
1196 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1201 static gboolean dev_property_exists_name(const GDBusPropertyTable *property,
1204 struct btd_device *dev = data;
1206 return device_name_known(dev);
1209 static gboolean dev_property_get_alias(const GDBusPropertyTable *property,
1210 DBusMessageIter *iter, void *data)
1212 struct btd_device *device = data;
1216 /* Alias (fallback to name or address) */
1217 if (device->alias != NULL)
1218 ptr = device->alias;
1219 else if (strlen(device->name) > 0) {
1222 ba2str(&device->bdaddr, dstaddr);
1223 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
1224 g_strdelimit(dstaddr, ":", '-');
1229 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1234 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1235 static gboolean dev_property_get_alias_set(const GDBusPropertyTable *property,
1236 DBusMessageIter *iter, void *data)
1238 struct btd_device *device = data;
1241 if (device->alias != NULL)
1246 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1252 static void set_alias(GDBusPendingPropertySet id, const char *alias,
1255 struct btd_device *device = data;
1258 if ((device->alias == NULL && g_str_equal(alias, "")) ||
1259 g_strcmp0(device->alias, alias) == 0) {
1260 g_dbus_pending_property_success(id);
1264 g_free(device->alias);
1265 device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
1267 store_device_info(device);
1269 g_dbus_emit_property_changed(dbus_conn, device->path,
1270 DEVICE_INTERFACE, "Alias");
1272 g_dbus_pending_property_success(id);
1275 static void dev_property_set_alias(const GDBusPropertyTable *property,
1276 DBusMessageIter *value,
1277 GDBusPendingPropertySet id, void *data)
1281 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING) {
1282 g_dbus_pending_property_error(id,
1283 ERROR_INTERFACE ".InvalidArguments",
1284 "Invalid arguments in method call");
1288 dbus_message_iter_get_basic(value, &alias);
1290 set_alias(id, alias, data);
1293 static gboolean dev_property_exists_class(const GDBusPropertyTable *property,
1296 struct btd_device *device = data;
1298 return device->class != 0;
1301 static gboolean dev_property_get_class(const GDBusPropertyTable *property,
1302 DBusMessageIter *iter, void *data)
1304 struct btd_device *device = data;
1306 if (device->class == 0)
1309 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &device->class);
1314 static gboolean get_appearance(const GDBusPropertyTable *property, void *data,
1315 uint16_t *appearance)
1317 struct btd_device *device = data;
1319 if (dev_property_exists_class(property, data))
1322 if (device->appearance) {
1323 *appearance = device->appearance;
1330 static gboolean dev_property_exists_appearance(
1331 const GDBusPropertyTable *property, void *data)
1333 uint16_t appearance;
1335 return get_appearance(property, data, &appearance);
1338 static gboolean dev_property_get_appearance(const GDBusPropertyTable *property,
1339 DBusMessageIter *iter, void *data)
1341 uint16_t appearance;
1343 if (!get_appearance(property, data, &appearance))
1346 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &appearance);
1351 static const char *get_icon(const GDBusPropertyTable *property, void *data)
1353 struct btd_device *device = data;
1354 const char *icon = NULL;
1355 uint16_t appearance;
1357 if (device->class != 0)
1358 icon = class_to_icon(device->class);
1359 else if (get_appearance(property, data, &appearance))
1360 icon = gap_appearance_to_icon(appearance);
1365 static gboolean dev_property_exists_icon(
1366 const GDBusPropertyTable *property, void *data)
1368 return get_icon(property, data) != NULL;
1371 static gboolean dev_property_get_icon(const GDBusPropertyTable *property,
1372 DBusMessageIter *iter, void *data)
1376 icon = get_icon(property, data);
1380 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &icon);
1385 static gboolean dev_property_get_paired(const GDBusPropertyTable *property,
1386 DBusMessageIter *iter, void *data)
1388 struct btd_device *dev = data;
1391 if (dev->bredr_state.paired || dev->le_state.paired)
1396 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1401 static gboolean dev_property_get_legacy(const GDBusPropertyTable *property,
1402 DBusMessageIter *iter, void *data)
1404 struct btd_device *device = data;
1405 dbus_bool_t val = device->legacy;
1407 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1412 static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
1413 DBusMessageIter *iter, void *data)
1415 struct btd_device *dev = data;
1416 dbus_int16_t val = dev->rssi;
1418 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1423 static gboolean dev_property_exists_rssi(const GDBusPropertyTable *property,
1426 struct btd_device *dev = data;
1434 static gboolean dev_property_get_tx_power(const GDBusPropertyTable *property,
1435 DBusMessageIter *iter, void *data)
1437 struct btd_device *dev = data;
1438 dbus_int16_t val = dev->tx_power;
1440 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1445 static gboolean dev_property_exists_tx_power(const GDBusPropertyTable *property,
1448 struct btd_device *dev = data;
1450 if (dev->tx_power == 127)
1457 dev_property_get_svc_resolved(const GDBusPropertyTable *property,
1458 DBusMessageIter *iter, void *data)
1460 struct btd_device *device = data;
1461 gboolean val = device->svc_refreshed;
1463 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1468 static gboolean dev_property_flags_exist(const GDBusPropertyTable *property,
1471 struct btd_device *device = data;
1473 return device->ad_flags[0] != INVALID_FLAGS;
1477 dev_property_get_flags(const GDBusPropertyTable *property,
1478 DBusMessageIter *iter, void *data)
1480 struct btd_device *device = data;
1481 uint8_t *flags = device->ad_flags;
1482 DBusMessageIter array;
1484 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1485 DBUS_TYPE_BYTE_AS_STRING, &array);
1486 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1487 &flags, sizeof(device->ad_flags));
1488 dbus_message_iter_close_container(iter, &array);
1493 static gboolean dev_property_get_trusted(const GDBusPropertyTable *property,
1494 DBusMessageIter *iter, void *data)
1496 struct btd_device *device = data;
1497 gboolean val = device_is_trusted(device);
1499 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1504 static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
1506 struct btd_device *device = data;
1508 btd_device_set_trusted(device, value);
1510 g_dbus_pending_property_success(id);
1513 static void dev_property_set_trusted(const GDBusPropertyTable *property,
1514 DBusMessageIter *value,
1515 GDBusPendingPropertySet id, void *data)
1519 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1520 g_dbus_pending_property_error(id,
1521 ERROR_INTERFACE ".InvalidArguments",
1522 "Invalid arguments in method call");
1526 dbus_message_iter_get_basic(value, &b);
1528 set_trust(id, b, data);
1531 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1532 static gboolean dev_property_get_trusted_profiles(const GDBusPropertyTable *property,
1533 DBusMessageIter *iter, void *data)
1535 struct btd_device *device = data;
1536 uint32_t pbap = device->trusted_profiles.pbap;
1537 uint32_t map = device->trusted_profiles.map;
1538 uint32_t sap = device->trusted_profiles.sap;
1539 uint32_t hfp_hs = device->trusted_profiles.hfp_hs;
1540 uint32_t a2dp = device->trusted_profiles.a2dp;
1542 unsigned int val = (pbap << PBAP_SHIFT_OFFSET) |
1543 (map << MAP_SHIFT_OFFSET) |
1544 (sap << SAP_SHIFT_OFFSET) |
1545 (hfp_hs << HFP_HS_SHIFT_OFFSET) |
1546 (a2dp << A2DP_SHIFT_OFFSET);
1548 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val);
1554 static gboolean dev_property_get_blocked(const GDBusPropertyTable *property,
1555 DBusMessageIter *iter, void *data)
1557 struct btd_device *device = data;
1559 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1565 static void set_blocked(GDBusPendingPropertySet id, gboolean value, void *data)
1567 struct btd_device *device = data;
1571 err = device_block(device, FALSE);
1573 err = device_unblock(device, FALSE, FALSE);
1577 g_dbus_pending_property_success(id);
1580 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1581 "Kernel lacks reject list support");
1584 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1591 static void dev_property_set_blocked(const GDBusPropertyTable *property,
1592 DBusMessageIter *value,
1593 GDBusPendingPropertySet id, void *data)
1597 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1598 g_dbus_pending_property_error(id,
1599 ERROR_INTERFACE ".InvalidArguments",
1600 "Invalid arguments in method call");
1604 dbus_message_iter_get_basic(value, &b);
1606 set_blocked(id, b, data);
1609 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1610 static uint8_t device_get_connected_state(struct btd_device *device)
1612 if (device->bredr_state.connected && device->le_state.connected)
1613 return DEV_CONNECTED_BREDR_LE;
1614 else if (device->bredr_state.connected)
1615 return DEV_CONNECTED_BREDR;
1616 else if (device->le_state.connected)
1617 return DEV_CONNECTED_LE;
1619 return DEV_CONNECTED_NONE;
1622 static gboolean dev_property_get_payload(const GDBusPropertyTable *property,
1623 DBusMessageIter *iter, void *data)
1625 struct btd_device *dev = data;
1626 dbus_uint16_t payload_timeout = dev->auth_payload_timeout;
1628 dbus_message_iter_append_basic(iter,
1629 DBUS_TYPE_UINT16, &payload_timeout);
1634 static gboolean dev_property_get_last_addr_type(const GDBusPropertyTable *property,
1635 DBusMessageIter *iter, void *data)
1637 struct btd_device *dev = data;
1638 uint8_t last_addr_type = dev->last_bdaddr_type;
1640 dbus_message_iter_append_basic(iter,
1641 DBUS_TYPE_BYTE, &last_addr_type);
1646 static gboolean dev_property_get_att_mtu(const GDBusPropertyTable *property,
1647 DBusMessageIter *iter, void *data)
1649 struct btd_device *device = data;
1650 dbus_uint16_t mtu = bt_gatt_client_get_mtu(device->client);
1652 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &mtu);
1657 static gboolean dev_property_get_gatt_connected(const GDBusPropertyTable *property,
1658 DBusMessageIter *iter, void *data)
1660 struct btd_device *device = data;
1661 dbus_bool_t gatt_connected;
1663 if (device->gatt_connected)
1664 gatt_connected = TRUE;
1666 gatt_connected = FALSE;
1668 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1674 static gboolean dev_property_get_ipsp_conn_state(const GDBusPropertyTable *property,
1675 DBusMessageIter *iter, void *data)
1677 struct btd_device *dev = data;
1678 dbus_bool_t ipsp_connected;
1680 if (dev->ipsp_connected)
1681 ipsp_connected = TRUE;
1683 ipsp_connected = FALSE;
1685 dbus_message_iter_append_basic(iter,
1686 DBUS_TYPE_BOOLEAN, &ipsp_connected);
1691 static gboolean dev_property_get_ipsp_conn_bt_iface_name(const GDBusPropertyTable *property,
1692 DBusMessageIter *iter, void *data)
1694 struct btd_device *dev = data;
1695 char *ptr = g_strdup(dev->if_name);
1697 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, (const char **)&ptr);
1705 static gboolean dev_property_get_connected(const GDBusPropertyTable *property,
1706 DBusMessageIter *iter, void *data)
1708 struct btd_device *dev = data;
1710 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1711 uint8_t connected = device_get_connected_state(dev);
1713 dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &connected);
1715 dbus_bool_t connected;
1717 if (dev->bredr_state.connected || dev->le_state.connected)
1722 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
1728 static gboolean dev_property_get_uuids(const GDBusPropertyTable *property,
1729 DBusMessageIter *iter, void *data)
1731 struct btd_device *dev = data;
1732 DBusMessageIter entry;
1735 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1736 DBUS_TYPE_STRING_AS_STRING, &entry);
1738 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
1740 else if (dev->eir_uuids)
1745 for (; l != NULL; l = l->next)
1746 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
1749 dbus_message_iter_close_container(iter, &entry);
1754 static gboolean dev_property_get_modalias(const GDBusPropertyTable *property,
1755 DBusMessageIter *iter, void *data)
1757 struct btd_device *device = data;
1759 if (!device->modalias)
1762 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1768 static gboolean dev_property_exists_modalias(const GDBusPropertyTable *property,
1771 struct btd_device *device = data;
1773 return device->modalias ? TRUE : FALSE;
1776 static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
1777 DBusMessageIter *iter, void *data)
1779 struct btd_device *device = data;
1780 const char *str = adapter_get_path(device->adapter);
1782 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &str);
1787 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1788 static gboolean property_get_manufacturer_data_len(const GDBusPropertyTable *property,
1789 DBusMessageIter *iter, void *user_data)
1791 struct btd_device *device = user_data;
1792 dbus_uint16_t val = device->manufacturer_data_len;
1794 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val);
1799 static gboolean property_get_manufacturer_data(const GDBusPropertyTable *property,
1800 DBusMessageIter *iter, void *user_data)
1802 struct btd_device *device = user_data;
1803 char str[DEV_MAX_MANUFACTURER_DATA_LEN] = {0};
1804 DBusMessageIter array;
1806 memset(str, 0, DEV_MAX_MANUFACTURER_DATA_LEN);
1807 if (device->manufacturer_data_len)
1808 memcpy(str, device->manufacturer_data,
1809 device->manufacturer_data_len);
1811 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1812 DBUS_TYPE_BYTE_AS_STRING, &array);
1814 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1815 &device->manufacturer_data,
1816 device->manufacturer_data_len);
1818 dbus_message_iter_close_container(iter, &array);
1823 gboolean device_get_gatt_connected(const struct btd_device *device)
1825 return device->gatt_connected;
1829 static void append_manufacturer_data(void *data, void *user_data)
1831 struct bt_ad_manufacturer_data *md = data;
1832 DBusMessageIter *dict = user_data;
1834 g_dbus_dict_append_basic_array(dict,
1835 DBUS_TYPE_UINT16, &md->manufacturer_id,
1836 DBUS_TYPE_BYTE, &md->data, md->len);
1840 dev_property_get_manufacturer_data(const GDBusPropertyTable *property,
1841 DBusMessageIter *iter, void *data)
1843 struct btd_device *device = data;
1844 DBusMessageIter dict;
1846 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1847 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1848 DBUS_TYPE_UINT16_AS_STRING
1849 DBUS_TYPE_VARIANT_AS_STRING
1850 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1853 bt_ad_foreach_manufacturer_data(device->ad, append_manufacturer_data,
1856 dbus_message_iter_close_container(iter, &dict);
1862 dev_property_manufacturer_data_exist(const GDBusPropertyTable *property,
1865 struct btd_device *device = data;
1867 return bt_ad_has_manufacturer_data(device->ad, NULL);
1870 static void append_service_data(void *data, void *user_data)
1872 struct bt_ad_service_data *sd = data;
1873 DBusMessageIter *dict = user_data;
1874 char uuid_str[MAX_LEN_UUID_STR];
1876 bt_uuid_to_string(&sd->uuid, uuid_str, sizeof(uuid_str));
1878 dict_append_array(dict, uuid_str, DBUS_TYPE_BYTE, &sd->data, sd->len);
1882 dev_property_get_service_data(const GDBusPropertyTable *property,
1883 DBusMessageIter *iter, void *data)
1885 struct btd_device *device = data;
1886 DBusMessageIter dict;
1888 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1889 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1890 DBUS_TYPE_STRING_AS_STRING
1891 DBUS_TYPE_VARIANT_AS_STRING
1892 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1895 bt_ad_foreach_service_data(device->ad, append_service_data, &dict);
1897 dbus_message_iter_close_container(iter, &dict);
1903 dev_property_service_data_exist(const GDBusPropertyTable *property,
1906 struct btd_device *device = data;
1908 return bt_ad_has_service_data(device->ad, NULL);
1911 static void append_advertising_data(void *data, void *user_data)
1913 struct bt_ad_data *ad = data;
1914 DBusMessageIter *dict = user_data;
1916 g_dbus_dict_append_basic_array(dict,
1917 DBUS_TYPE_BYTE, &ad->type,
1918 DBUS_TYPE_BYTE, &ad->data, ad->len);
1922 dev_property_get_advertising_data(const GDBusPropertyTable *property,
1923 DBusMessageIter *iter, void *data)
1925 struct btd_device *device = data;
1926 DBusMessageIter dict;
1928 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1929 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1930 DBUS_TYPE_BYTE_AS_STRING
1931 DBUS_TYPE_VARIANT_AS_STRING
1932 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1935 bt_ad_foreach_data(device->ad, append_advertising_data, &dict);
1937 dbus_message_iter_close_container(iter, &dict);
1943 dev_property_advertising_data_exist(const GDBusPropertyTable *property,
1946 struct btd_device *device = data;
1948 return bt_ad_has_data(device->ad, NULL);
1951 static bool device_get_wake_support(struct btd_device *device)
1953 return device->wake_support;
1956 void device_set_wake_support(struct btd_device *device, bool wake_support)
1958 device->wake_support = wake_support;
1960 /* If wake configuration has not been made yet, set the initial
1963 if (device->wake_override == WAKE_FLAG_DEFAULT) {
1964 device_set_wake_override(device, wake_support);
1965 device_set_wake_allowed(device, wake_support, -1U);
1969 static bool device_get_wake_allowed(struct btd_device *device)
1971 return device->wake_allowed;
1974 void device_set_wake_override(struct btd_device *device, bool wake_override)
1976 if (wake_override) {
1977 device->wake_override = WAKE_FLAG_ENABLED;
1978 device->current_flags |= DEVICE_FLAG_REMOTE_WAKEUP;
1980 device->wake_override = WAKE_FLAG_DISABLED;
1981 device->current_flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
1985 static void device_set_wake_allowed_complete(struct btd_device *device)
1987 if (device->wake_id != -1U) {
1988 g_dbus_pending_property_success(device->wake_id);
1989 device->wake_id = -1U;
1992 device->wake_allowed = device->pending_wake_allowed;
1993 g_dbus_emit_property_changed(dbus_conn, device->path,
1994 DEVICE_INTERFACE, "WakeAllowed");
1996 store_device_info(device);
1999 static void set_wake_allowed_complete(uint8_t status, uint16_t length,
2000 const void *param, void *user_data)
2002 const struct mgmt_rp_set_device_flags *rp = param;
2003 struct btd_device *dev = user_data;
2005 if (status != MGMT_STATUS_SUCCESS) {
2006 error("Set device flags return status: %s",
2007 mgmt_errstr(status));
2011 if (length < sizeof(*rp)) {
2012 error("Too small Set Device Flags complete event: %d", length);
2016 device_set_wake_allowed_complete(dev);
2019 void device_set_wake_allowed(struct btd_device *device, bool wake_allowed,
2020 GDBusPendingPropertySet id)
2023 /* Pending and current value are the same unless there is a change in
2024 * progress. Only update wake allowed if pending value doesn't match the
2027 if (wake_allowed == device->pending_wake_allowed)
2030 device->wake_id = id;
2031 device->pending_wake_allowed = wake_allowed;
2032 flags = device->current_flags;
2034 flags |= DEVICE_FLAG_REMOTE_WAKEUP;
2036 flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
2038 adapter_set_device_flags(device->adapter, device, flags,
2039 set_wake_allowed_complete, device);
2044 dev_property_get_wake_allowed(const GDBusPropertyTable *property,
2045 DBusMessageIter *iter, void *data)
2047 struct btd_device *device = data;
2048 dbus_bool_t wake_allowed = device_get_wake_allowed(device);
2050 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &wake_allowed);
2055 static void dev_property_set_wake_allowed(const GDBusPropertyTable *property,
2056 DBusMessageIter *value,
2057 GDBusPendingPropertySet id, void *data)
2059 struct btd_device *device = data;
2062 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
2063 g_dbus_pending_property_error(id,
2064 ERROR_INTERFACE ".InvalidArguments",
2065 "Invalid arguments in method call");
2069 if (device->temporary) {
2070 g_dbus_pending_property_error(id,
2071 ERROR_INTERFACE ".Unsupported",
2072 "Cannot set property while temporary");
2076 /* Emit busy or success depending on current value. */
2077 if (b == device->pending_wake_allowed) {
2078 if (device->wake_allowed == device->pending_wake_allowed)
2079 g_dbus_pending_property_success(id);
2081 g_dbus_pending_property_error(
2082 id, ERROR_INTERFACE ".Busy",
2083 "Property change in progress");
2088 dbus_message_iter_get_basic(value, &b);
2089 device_set_wake_override(device, b);
2090 device_set_wake_allowed(device, b, id);
2093 static gboolean dev_property_wake_allowed_exist(
2094 const GDBusPropertyTable *property, void *data)
2096 struct btd_device *device = data;
2098 return device_get_wake_support(device);
2102 static bool disconnect_all(gpointer user_data)
2104 struct btd_device *device = user_data;
2106 device->disconn_timer = 0;
2108 if (device->bredr_state.connected)
2109 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
2112 if (device->le_state.connected)
2113 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
2114 device->bdaddr_type);
2119 int device_block(struct btd_device *device, gboolean update_only)
2123 if (device->blocked)
2126 if (device->disconn_timer > 0)
2127 timeout_remove(device->disconn_timer);
2129 disconnect_all(device);
2131 while (device->services != NULL) {
2132 struct btd_service *service = device->services->data;
2134 device->services = g_slist_remove(device->services, service);
2135 service_remove(service);
2140 err = btd_adapter_block_address(device->adapter,
2142 device->bdaddr_type);
2143 if (!err && device->bredr)
2144 err = btd_adapter_block_address(device->adapter,
2152 device->blocked = TRUE;
2154 store_device_info(device);
2156 btd_device_set_temporary(device, false);
2158 g_dbus_emit_property_changed(dbus_conn, device->path,
2159 DEVICE_INTERFACE, "Blocked");
2164 int device_unblock(struct btd_device *device, gboolean silent,
2165 gboolean update_only)
2169 if (!device->blocked)
2174 err = btd_adapter_unblock_address(device->adapter,
2176 device->bdaddr_type);
2177 if (!err && device->bredr)
2178 err = btd_adapter_unblock_address(device->adapter,
2186 device->blocked = FALSE;
2188 store_device_info(device);
2191 g_dbus_emit_property_changed(dbus_conn, device->path,
2192 DEVICE_INTERFACE, "Blocked");
2193 device_probe_profiles(device, device->uuids);
2199 static void browse_request_exit(DBusConnection *conn, void *user_data)
2201 struct browse_req *req = user_data;
2203 DBG("Requestor exited");
2205 browse_request_cancel(req);
2208 static void bonding_request_cancel(struct bonding_req *bonding)
2210 struct btd_device *device = bonding->device;
2211 struct btd_adapter *adapter = device->adapter;
2213 adapter_cancel_bonding(adapter, &device->bdaddr, device->bdaddr_type);
2216 static void dev_disconn_service(gpointer a, gpointer b)
2218 btd_service_disconnect(a);
2221 void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
2223 if (device->bonding)
2224 bonding_request_cancel(device->bonding);
2227 browse_request_cancel(device->browse);
2229 if (device->att_io) {
2230 g_io_channel_shutdown(device->att_io, FALSE, NULL);
2231 g_io_channel_unref(device->att_io);
2232 device->att_io = NULL;
2235 if (device->connect) {
2236 DBusMessage *reply = btd_error_failed(device->connect,
2237 ERR_BREDR_CONN_CANCELED);
2238 g_dbus_send_message(dbus_conn, reply);
2239 dbus_message_unref(device->connect);
2240 device->connect = NULL;
2243 if (btd_device_is_connected(device) && msg)
2244 device->disconnects = g_slist_append(device->disconnects,
2245 dbus_message_ref(msg));
2247 if (device->disconn_timer)
2250 g_slist_foreach(device->services, dev_disconn_service, NULL);
2252 g_slist_free(device->pending);
2253 device->pending = NULL;
2255 while (device->watches) {
2256 struct btd_disconnect_data *data = device->watches->data;
2259 /* temporary is set if device is going to be removed */
2260 data->watch(device, device->temporary,
2263 /* Check if the watch has been removed by callback function */
2264 if (!g_slist_find(device->watches, data))
2267 device->watches = g_slist_remove(device->watches, data);
2271 if (!btd_device_is_connected(device)) {
2273 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
2277 device->disconn_timer = timeout_add_seconds(DISCONNECT_TIMER,
2282 bool device_is_disconnecting(struct btd_device *device)
2284 return device->disconn_timer > 0;
2287 void device_set_ltk_enc_size(struct btd_device *device, uint8_t enc_size)
2289 device->ltk_enc_size = enc_size;
2290 bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
2293 static void device_set_auto_connect(struct btd_device *device, gboolean enable)
2297 if (!device || !device->le)
2300 ba2str(&device->bdaddr, addr);
2302 DBG("%s auto connect: %d", addr, enable);
2304 if (device->auto_connect == enable)
2307 device->auto_connect = enable;
2309 /* Disabling auto connect */
2310 if (enable == FALSE) {
2311 adapter_connect_list_remove(device->adapter, device);
2312 adapter_auto_connect_remove(device->adapter, device);
2316 /* Enabling auto connect */
2317 adapter_auto_connect_add(device->adapter, device);
2319 if (device->attrib) {
2320 DBG("Already connected");
2324 adapter_connect_list_add(device->adapter, device);
2327 static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
2330 struct btd_device *device = user_data;
2333 * If device is not trusted disable connections through passive
2334 * scanning until Device1.Connect is called
2336 if (device->auto_connect && !device->trusted) {
2337 device->disable_auto_connect = TRUE;
2338 device_set_auto_connect(device, FALSE);
2341 device_request_disconnect(device, msg);
2346 static int connect_next(struct btd_device *dev)
2348 struct btd_service *service;
2351 while (dev->pending) {
2352 service = dev->pending->data;
2354 err = btd_service_connect(service);
2358 dev->pending = g_slist_delete_link(dev->pending, dev->pending);
2364 static void device_profile_connected(struct btd_device *dev,
2365 struct btd_profile *profile, int err)
2367 struct btd_service *pending;
2370 DBG("%s %s (%d)", profile->name, strerror(-err), -err);
2373 btd_device_set_temporary(dev, false);
2375 if (dev->pending == NULL)
2378 if (!btd_device_is_connected(dev)) {
2380 case EHOSTDOWN: /* page timeout */
2381 case EHOSTUNREACH: /* adapter not powered */
2382 case ECONNABORTED: /* adapter powered down */
2387 pending = dev->pending->data;
2388 l = find_service_with_profile(dev->pending, profile);
2390 dev->pending = g_slist_delete_link(dev->pending, l);
2392 /* Only continue connecting the next profile if it matches the first
2393 * pending, otherwise it will trigger another connect to the same
2396 if (profile != btd_service_get_profile(pending))
2399 if (connect_next(dev) == 0)
2403 g_slist_free(dev->pending);
2404 dev->pending = NULL;
2409 if (dbus_message_is_method_call(dev->connect, DEVICE_INTERFACE,
2412 dev->general_connect = TRUE;
2413 else if (find_service_with_state(dev->services,
2414 BTD_SERVICE_STATE_CONNECTED))
2415 /* Reset error if there are services connected */
2419 DBG("returning response to %s", dbus_message_get_sender(dev->connect));
2422 /* Fallback to LE bearer if supported */
2423 if (err == -EHOSTDOWN && dev->le && !dev->le_state.connected) {
2424 err = device_connect_le(dev);
2429 g_dbus_send_message(dbus_conn,
2430 btd_error_failed(dev->connect,
2431 btd_error_bredr_conn_from_errno(err)));
2433 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2434 /* SDP is not required for Samsung TV Power on */
2435 if (g_strcmp0(profile->name, "hid-device") == 0) {
2436 DBG("Skip SDP discovery.");
2439 /* Start passive SDP discovery to update known services */
2440 if (dev->bredr && !dev->svc_refreshed && dev->refresh_discovery)
2441 device_browse_sdp(dev, NULL);
2442 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2446 g_dbus_send_reply(dbus_conn, dev->connect, DBUS_TYPE_INVALID);
2449 dbus_message_unref(dev->connect);
2450 dev->connect = NULL;
2453 void device_add_eir_uuids(struct btd_device *dev, GSList *uuids)
2458 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
2461 for (l = uuids; l != NULL; l = l->next) {
2462 const char *str = l->data;
2463 if (g_slist_find_custom(dev->eir_uuids, str, bt_uuid_strcmp))
2466 dev->eir_uuids = g_slist_append(dev->eir_uuids, g_strdup(str));
2470 g_dbus_emit_property_changed(dbus_conn, dev->path,
2471 DEVICE_INTERFACE, "UUIDs");
2474 static void add_manufacturer_data(void *data, void *user_data)
2476 struct eir_msd *msd = data;
2477 struct btd_device *dev = user_data;
2479 if (!bt_ad_add_manufacturer_data(dev->ad, msd->company, msd->data,
2483 g_dbus_emit_property_changed(dbus_conn, dev->path,
2484 DEVICE_INTERFACE, "ManufacturerData");
2487 void device_set_manufacturer_data(struct btd_device *dev, GSList *list,
2491 bt_ad_clear_manufacturer_data(dev->ad);
2493 g_slist_foreach(list, add_manufacturer_data, dev);
2496 static void add_service_data(void *data, void *user_data)
2498 struct eir_sd *sd = data;
2499 struct btd_device *dev = user_data;
2502 if (bt_string_to_uuid(&uuid, sd->uuid) < 0)
2505 if (!bt_ad_add_service_data(dev->ad, &uuid, sd->data, sd->data_len))
2508 g_dbus_emit_property_changed(dbus_conn, dev->path,
2509 DEVICE_INTERFACE, "ServiceData");
2512 void device_set_service_data(struct btd_device *dev, GSList *list,
2516 bt_ad_clear_service_data(dev->ad);
2518 g_slist_foreach(list, add_service_data, dev);
2521 static void add_data(void *data, void *user_data)
2523 struct eir_ad *ad = data;
2524 struct btd_device *dev = user_data;
2526 if (!bt_ad_add_data(dev->ad, ad->type, ad->data, ad->len))
2529 if (ad->type == EIR_TRANSPORT_DISCOVERY)
2530 g_dbus_emit_property_changed(dbus_conn, dev->path,
2535 void device_set_data(struct btd_device *dev, GSList *list,
2539 bt_ad_clear_data(dev->ad);
2541 g_slist_foreach(list, add_data, dev);
2544 static struct btd_service *find_connectable_service(struct btd_device *dev,
2548 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2549 struct btd_service *s = NULL;
2551 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2552 struct btd_service *service = l->data;
2553 struct btd_profile *p = btd_service_get_profile(service);
2555 if (!p->connect || !p->remote_uuid)
2558 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
2559 if (strcasecmp(uuid, p->remote_uuid) == 0)
2562 if (strcasecmp(uuid, p->remote_uuid) == 0) {
2564 if (ext_profile_is_registered_as_client_role(p) == TRUE) {
2572 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2580 static int service_prio_cmp(gconstpointer a, gconstpointer b)
2582 struct btd_profile *p1 = btd_service_get_profile(a);
2583 struct btd_profile *p2 = btd_service_get_profile(b);
2585 return p2->priority - p1->priority;
2588 bool btd_device_all_services_allowed(struct btd_device *dev)
2591 struct btd_adapter *adapter = dev->adapter;
2592 struct btd_service *service;
2593 struct btd_profile *profile;
2595 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2597 profile = btd_service_get_profile(service);
2599 if (!profile || !profile->auto_connect)
2602 if (!btd_adapter_is_uuid_allowed(adapter, profile->remote_uuid))
2609 void btd_device_update_allowed_services(struct btd_device *dev)
2611 struct btd_adapter *adapter = dev->adapter;
2612 struct btd_service *service;
2613 struct btd_profile *profile;
2618 /* If service discovery is ongoing, let the service discovery complete
2619 * callback call this function.
2622 ba2str(&dev->bdaddr, addr);
2623 DBG("service discovery of %s is ongoing. Skip updating allowed "
2628 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2630 profile = btd_service_get_profile(service);
2632 is_allowed = btd_adapter_is_uuid_allowed(adapter,
2633 profile->remote_uuid);
2634 btd_service_set_allowed(service, is_allowed);
2638 static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
2640 struct btd_service *service;
2641 struct btd_profile *p;
2643 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2644 bool hs_hf_verify = FALSE;
2648 service = find_connectable_service(dev, uuid);
2650 return dev->pending;
2652 if (btd_service_is_allowed(service))
2653 return g_slist_prepend(dev->pending, service);
2655 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2656 else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
2657 DBG("HFP service not found check for HSP service");
2658 service = find_connectable_service(dev, HSP_HS_UUID);
2660 return g_slist_prepend(dev->pending, service);
2661 } else if (g_strcmp0(uuid, HID_UUID) == 0) {
2662 DBG("HID service not found, add HID service");
2663 btd_device_add_uuid(dev, uuid);
2664 service = find_connectable_service(dev, HID_UUID);
2666 return g_slist_prepend(dev->pending, service);
2669 return dev->pending;
2672 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2674 p = btd_service_get_profile(service);
2676 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2677 DBG("profile uuid %s", p->remote_uuid);
2678 if (g_strcmp0(p->remote_uuid, HSP_HS_UUID) == 0) {
2679 DBG("HSP service is found check for HFP service");
2680 struct btd_service *service;
2681 struct btd_profile *p;
2684 for (h = dev->services; h != NULL; h = g_slist_next(h)) {
2686 p = btd_service_get_profile(service);
2688 if (g_strcmp0(p->remote_uuid, HFP_HS_UUID) == 0) {
2689 DBG("HFP found,ignore HSP ");
2690 hs_hf_verify = TRUE;
2698 if (!p->auto_connect)
2701 if (!btd_service_is_allowed(service)) {
2702 info("service %s is blocked", p->remote_uuid);
2706 if (g_slist_find(dev->pending, service))
2709 if (btd_service_get_state(service) !=
2710 BTD_SERVICE_STATE_DISCONNECTED)
2713 dev->pending = g_slist_insert_sorted(dev->pending, service,
2717 return dev->pending;
2720 int btd_device_connect_services(struct btd_device *dev, GSList *services)
2724 if (dev->pending || dev->connect || dev->browse)
2727 if (!btd_adapter_get_powered(dev->adapter))
2730 if (!dev->bredr_state.svc_resolved)
2734 for (l = services; l; l = g_slist_next(l)) {
2735 struct btd_service *service = l->data;
2737 dev->pending = g_slist_append(dev->pending, service);
2740 dev->pending = create_pending_list(dev, NULL);
2743 return connect_next(dev);
2746 static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type,
2747 DBusMessage *msg, const char *uuid)
2749 struct bearer_state *state = get_state(dev, bdaddr_type);
2752 DBG("%s %s, client %s", dev->path, uuid ? uuid : "(all)",
2753 dbus_message_get_sender(msg));
2755 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2756 if (dev->pending || dev->connect)
2757 return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
2759 if (dev->pending || dev->connect || dev->browse)
2760 return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
2763 if (!btd_adapter_get_powered(dev->adapter)) {
2764 return btd_error_not_ready_str(msg,
2765 ERR_BREDR_CONN_ADAPTER_NOT_POWERED);
2768 btd_device_set_temporary(dev, false);
2770 if (!state->svc_resolved)
2771 goto resolve_services;
2773 dev->pending = create_pending_list(dev, uuid);
2774 if (!dev->pending) {
2775 if (dev->svc_refreshed) {
2776 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2777 if (!uuid && dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2779 find_service_with_state(dev->services,
2780 BTD_SERVICE_STATE_CONNECTED)) {
2782 if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2784 find_service_with_state(dev->services,
2785 BTD_SERVICE_STATE_CONNECTED)) {
2787 return dbus_message_new_method_return(msg);
2789 return btd_error_not_available_str(msg,
2790 ERR_BREDR_CONN_PROFILE_UNAVAILABLE);
2794 goto resolve_services;
2797 err = connect_next(dev);
2799 if (err == -EALREADY)
2800 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2801 return btd_error_already_connected(msg);
2803 return dbus_message_new_method_return(msg);
2805 return btd_error_failed(msg,
2806 btd_error_bredr_conn_from_errno(err));
2809 dev->connect = dbus_message_ref(msg);
2814 DBG("Resolving services for %s", dev->path);
2816 if (bdaddr_type == BDADDR_BREDR)
2817 err = device_browse_sdp(dev, msg);
2819 err = device_browse_gatt(dev, msg);
2821 return btd_error_failed(msg, bdaddr_type == BDADDR_BREDR ?
2822 ERR_BREDR_CONN_SDP_SEARCH : ERR_LE_CONN_GATT_BROWSE);
2828 #define NVAL_TIME ((time_t) -1)
2829 #define SEEN_TRESHHOLD 300
2831 static uint8_t select_conn_bearer(struct btd_device *dev)
2833 time_t bredr_last = NVAL_TIME, le_last = NVAL_TIME;
2834 time_t current = time(NULL);
2836 /* Prefer bonded bearer in case only one is bonded */
2837 if (dev->bredr_state.bonded && !dev->le_state.bonded )
2838 return BDADDR_BREDR;
2839 else if (!dev->bredr_state.bonded && dev->le_state.bonded)
2840 return dev->bdaddr_type;
2842 /* If the address is random it can only be connected over LE */
2843 if (dev->bdaddr_type == BDADDR_LE_RANDOM)
2844 return dev->bdaddr_type;
2846 if (dev->bredr_seen) {
2847 bredr_last = current - dev->bredr_seen;
2848 if (bredr_last > SEEN_TRESHHOLD)
2849 bredr_last = NVAL_TIME;
2853 le_last = current - dev->le_seen;
2854 if (le_last > SEEN_TRESHHOLD)
2855 le_last = NVAL_TIME;
2858 if (le_last == NVAL_TIME && bredr_last == NVAL_TIME)
2859 return dev->bdaddr_type;
2861 if (dev->bredr && (!dev->le || le_last == NVAL_TIME))
2862 return BDADDR_BREDR;
2864 if (dev->le && (!dev->bredr || bredr_last == NVAL_TIME))
2865 return dev->bdaddr_type;
2868 * Prefer BR/EDR if time is the same since it might be from an
2869 * advertisement with BR/EDR flag set.
2871 if (bredr_last <= le_last && btd_adapter_get_bredr(dev->adapter))
2872 return BDADDR_BREDR;
2874 return dev->bdaddr_type;
2877 static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
2880 struct btd_device *dev = user_data;
2881 uint8_t bdaddr_type;
2883 if (dev->bredr_state.connected) {
2885 * Check if services have been resolved and there is at least
2886 * one connected before switching to connect LE.
2888 if (dev->bredr_state.svc_resolved &&
2889 find_service_with_state(dev->services,
2890 BTD_SERVICE_STATE_CONNECTED))
2891 bdaddr_type = dev->bdaddr_type;
2893 bdaddr_type = BDADDR_BREDR;
2894 } else if (dev->le_state.connected && dev->bredr)
2895 bdaddr_type = BDADDR_BREDR;
2897 bdaddr_type = select_conn_bearer(dev);
2899 if (bdaddr_type != BDADDR_BREDR) {
2902 if (dev->le_state.connected)
2903 return dbus_message_new_method_return(msg);
2905 btd_device_set_temporary(dev, false);
2907 if (dev->disable_auto_connect) {
2908 dev->disable_auto_connect = FALSE;
2909 device_set_auto_connect(dev, TRUE);
2912 err = device_connect_le(dev);
2914 return btd_error_failed(msg, strerror(-err));
2916 dev->connect = dbus_message_ref(msg);
2921 return connect_profiles(dev, bdaddr_type, msg, NULL);
2924 static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
2927 struct btd_device *dev = user_data;
2928 const char *pattern;
2932 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2933 DBUS_TYPE_INVALID)) {
2934 return btd_error_invalid_args_str(msg,
2935 ERR_BREDR_CONN_INVALID_ARGUMENTS);
2938 uuid = bt_name2string(pattern);
2939 reply = connect_profiles(dev, BDADDR_BREDR, msg, uuid);
2945 static void device_profile_disconnected(struct btd_device *dev,
2946 struct btd_profile *profile, int err)
2948 if (!dev->disconnect)
2952 g_dbus_send_message(dbus_conn,
2953 btd_error_failed(dev->disconnect,
2956 g_dbus_send_reply(dbus_conn, dev->disconnect,
2959 dbus_message_unref(dev->disconnect);
2960 dev->disconnect = NULL;
2963 static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
2966 struct btd_device *dev = user_data;
2967 struct btd_service *service;
2968 const char *pattern;
2972 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2974 return btd_error_invalid_args(msg);
2976 uuid = bt_name2string(pattern);
2978 return btd_error_invalid_args(msg);
2980 service = find_connectable_service(dev, uuid);
2981 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2982 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2983 DBG("HFP service is not found check for HSP service");
2984 service = find_connectable_service(dev, HSP_HS_UUID);
2990 return btd_error_invalid_args(msg);
2992 if (dev->disconnect)
2993 return btd_error_in_progress(msg);
2995 if (btd_service_get_state(service) == BTD_SERVICE_STATE_DISCONNECTED)
2996 return dbus_message_new_method_return(msg);
2998 dev->disconnect = dbus_message_ref(msg);
3000 err = btd_service_disconnect(service);
3004 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3005 if (dev->disconnect)
3007 dbus_message_unref(dev->disconnect);
3008 dev->disconnect = NULL;
3010 if (err == -ENOTSUP)
3011 return btd_error_not_supported(msg);
3012 else if (err == -EALREADY)
3013 return dbus_message_new_method_return(msg);
3015 return btd_error_failed(msg, strerror(-err));
3018 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3019 static DBusMessage *disconnect_ext_profile(DBusConnection *conn,
3020 DBusMessage *msg, void *user_data)
3022 struct btd_device *dev = user_data;
3023 struct btd_profile *profile;
3024 struct btd_service *service;
3025 const char *sender, *path;
3029 sender = dbus_message_get_sender(msg);
3031 DBG("sender %s", sender);
3033 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
3035 return btd_error_invalid_args(msg);
3037 profile = btd_profile_find_ext(sender, path);
3039 return btd_error_invalid_args(msg);
3041 l = find_service_with_profile(dev->services, profile);
3043 return btd_error_invalid_args(msg);
3047 if (dev->disconnect)
3048 return btd_error_in_progress(msg);
3050 dev->disconnect = dbus_message_ref(msg);
3052 err = btd_service_disconnect(service);
3056 if (dev->disconnect)
3057 dbus_message_unref(dev->disconnect);
3058 dev->disconnect = NULL;
3060 if (err == -ENOTSUP)
3061 return btd_error_not_supported(msg);
3063 return btd_error_failed(msg, strerror(-err));
3067 static void store_services(struct btd_device *device)
3069 char filename[PATH_MAX];
3074 GError *gerr = NULL;
3079 if (device_address_is_private(device)) {
3080 DBG("Can't store services for private addressed device %s",
3085 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
3086 prim_uuid = bt_uuid2string(&uuid);
3087 if (prim_uuid == NULL)
3090 ba2str(&device->bdaddr, dst_addr);
3092 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3094 ba2str(device->rpa, dst_addr);
3097 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes",
3098 btd_adapter_get_storage_dir(device->adapter),
3100 key_file = g_key_file_new();
3102 for (l = device->primaries; l; l = l->next) {
3103 struct gatt_primary *primary = l->data;
3104 char handle[6], uuid_str[33];
3107 sprintf(handle, "%hu", primary->range.start);
3109 bt_string2uuid(&uuid, primary->uuid);
3110 sdp_uuid128_to_uuid(&uuid);
3112 switch (uuid.type) {
3114 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
3117 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
3120 for (i = 0; i < 16; i++)
3121 sprintf(uuid_str + (i * 2), "%2.2X",
3122 uuid.value.uuid128.data[i]);
3128 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
3129 g_key_file_set_string(key_file, handle, "Value", uuid_str);
3130 g_key_file_set_integer(key_file, handle, "EndGroupHandle",
3131 primary->range.end);
3134 data = g_key_file_to_data(key_file, &length, NULL);
3136 create_file(filename, 0600);
3137 if (!g_file_set_contents(filename, data, length, &gerr)) {
3138 error("Unable set contents for %s: (%s)", filename,
3146 g_key_file_free(key_file);
3150 struct btd_device *device;
3155 static void db_hash_read_value_cb(struct gatt_db_attribute *attrib,
3156 int err, const uint8_t *value,
3157 size_t length, void *user_data)
3159 const uint8_t **hash = user_data;
3161 if (err || (length != 16))
3167 static void store_desc(struct gatt_db_attribute *attr, void *user_data)
3169 struct gatt_saver *saver = user_data;
3170 GKeyFile *key_file = saver->key_file;
3171 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3172 const bt_uuid_t *uuid;
3174 uint16_t handle_num;
3176 handle_num = gatt_db_attribute_get_handle(attr);
3177 sprintf(handle, "%04hx", handle_num);
3179 uuid = gatt_db_attribute_get_type(attr);
3180 bt_uuid_to_string(uuid, uuid_str, sizeof(uuid_str));
3182 bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
3183 if (!bt_uuid_cmp(uuid, &ext_uuid) && saver->ext_props)
3184 sprintf(value, "%04hx:%s", saver->ext_props, uuid_str);
3186 sprintf(value, "%s", uuid_str);
3188 g_key_file_set_string(key_file, "Attributes", handle, value);
3191 static void store_chrc(struct gatt_db_attribute *attr, void *user_data)
3193 struct gatt_saver *saver = user_data;
3194 GKeyFile *key_file = saver->key_file;
3195 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3196 uint16_t handle_num, value_handle;
3198 bt_uuid_t uuid, hash_uuid;
3200 if (!gatt_db_attribute_get_char_data(attr, &handle_num, &value_handle,
3201 &properties, &saver->ext_props,
3203 warn("Error storing characteristic - can't get data");
3207 sprintf(handle, "%04hx", handle_num);
3208 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3210 /* Store Database Hash value if available */
3211 bt_uuid16_create(&hash_uuid, GATT_CHARAC_DB_HASH);
3212 if (!bt_uuid_cmp(&uuid, &hash_uuid)) {
3213 const uint8_t *hash = NULL;
3215 attr = gatt_db_get_attribute(saver->device->db, value_handle);
3217 gatt_db_attribute_read(attr, 0, BT_ATT_OP_READ_REQ, NULL,
3218 db_hash_read_value_cb, &hash);
3220 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:"
3221 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3222 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3223 "%02hhx%02hhx:%s", value_handle, properties,
3224 hash[0], hash[1], hash[2], hash[3],
3225 hash[4], hash[5], hash[6], hash[7],
3226 hash[8], hash[9], hash[10], hash[11],
3227 hash[12], hash[13], hash[14], hash[15],
3230 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3231 value_handle, properties, uuid_str);
3234 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3235 value_handle, properties, uuid_str);
3237 g_key_file_set_string(key_file, "Attributes", handle, value);
3239 gatt_db_service_foreach_desc(attr, store_desc, saver);
3242 static void store_incl(struct gatt_db_attribute *attr, void *user_data)
3244 struct gatt_saver *saver = user_data;
3245 GKeyFile *key_file = saver->key_file;
3246 struct gatt_db_attribute *service;
3247 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3248 uint16_t handle_num, start, end;
3251 if (!gatt_db_attribute_get_incl_data(attr, &handle_num, &start, &end)) {
3252 warn("Error storing included service - can't get data");
3256 service = gatt_db_get_attribute(saver->device->db, start);
3258 warn("Error storing included service - can't find it");
3262 sprintf(handle, "%04hx", handle_num);
3264 gatt_db_attribute_get_service_uuid(service, &uuid);
3265 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3266 sprintf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", start,
3269 g_key_file_set_string(key_file, "Attributes", handle, value);
3272 static void store_service(struct gatt_db_attribute *attr, void *user_data)
3274 struct gatt_saver *saver = user_data;
3275 GKeyFile *key_file = saver->key_file;
3276 char uuid_str[MAX_LEN_UUID_STR], handle[6], value[256];
3277 uint16_t start, end;
3282 if (!gatt_db_attribute_get_service_data(attr, &start, &end, &primary,
3284 warn("Error storing service - can't get data");
3288 sprintf(handle, "%04hx", start);
3290 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3293 type = GATT_PRIM_SVC_UUID_STR;
3295 type = GATT_SND_SVC_UUID_STR;
3297 sprintf(value, "%s:%04hx:%s", type, end, uuid_str);
3299 g_key_file_set_string(key_file, "Attributes", handle, value);
3301 gatt_db_service_foreach_incl(attr, store_incl, saver);
3302 gatt_db_service_foreach_char(attr, store_chrc, saver);
3305 static void store_gatt_db(struct btd_device *device)
3307 char filename[PATH_MAX];
3310 GError *gerr = NULL;
3313 struct gatt_saver saver;
3315 if (device_address_is_private(device)) {
3316 DBG("Can't store GATT db for private addressed device %s",
3321 if (!gatt_cache_is_enabled(device))
3324 ba2str(&device->bdaddr, dst_addr);
3326 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
3327 btd_adapter_get_storage_dir(device->adapter),
3329 create_file(filename, 0600);
3331 key_file = g_key_file_new();
3332 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
3333 error("Unable to load key file from %s: (%s)", filename,
3338 /* Remove current attributes since it might have changed */
3339 g_key_file_remove_group(key_file, "Attributes", NULL);
3341 saver.key_file = key_file;
3342 saver.device = device;
3344 gatt_db_foreach_service(device->db, NULL, store_service, &saver);
3346 data = g_key_file_to_data(key_file, &length, NULL);
3347 if (!g_file_set_contents(filename, data, length, &gerr)) {
3348 error("Unable set contents for %s: (%s)", filename,
3354 g_key_file_free(key_file);
3358 static void browse_request_complete(struct browse_req *req, uint8_t type,
3359 uint8_t bdaddr_type, int err)
3361 struct btd_device *dev = req->device;
3362 DBusMessage *reply = NULL;
3365 if (req->type != type)
3371 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, "Pair")) {
3372 if (!device_is_paired(dev, bdaddr_type)) {
3373 reply = btd_error_failed(req->msg, "Not paired");
3377 if (dev->pending_paired) {
3378 g_dbus_emit_property_changed(dbus_conn, dev->path,
3379 DEVICE_INTERFACE, "Paired");
3380 dev->pending_paired = false;
3383 /* Disregard browse errors in case of Pair */
3384 reply = g_dbus_create_reply(req->msg, DBUS_TYPE_INVALID);
3389 /* Fallback to LE bearer if supported */
3390 if (err == -EHOSTDOWN && bdaddr_type == BDADDR_BREDR &&
3391 dev->le && !dev->le_state.connected) {
3392 err = device_connect_le(dev);
3396 reply = btd_error_failed(req->msg,
3397 bdaddr_type == BDADDR_BREDR ?
3398 btd_error_bredr_conn_from_errno(err) :
3399 btd_error_le_conn_from_errno(err));
3403 /* if successfully resolved services we need to free browsing request
3404 * before passing message back to connect functions, otherwise
3405 * device->browse is set and "InProgress" error is returned instead
3406 * of actually connecting services
3408 msg = dbus_message_ref(req->msg);
3409 browse_request_free(req);
3412 if (dbus_message_is_method_call(msg, DEVICE_INTERFACE, "Connect"))
3413 reply = dev_connect(dbus_conn, msg, dev);
3414 else if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
3416 reply = connect_profile(dbus_conn, msg, dev);
3418 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
3420 dbus_message_unref(msg);
3424 g_dbus_send_message(dbus_conn, reply);
3427 browse_request_free(req);
3430 void device_set_refresh_discovery(struct btd_device *dev, bool refresh)
3432 dev->refresh_discovery = refresh;
3435 static void device_set_svc_refreshed(struct btd_device *device, bool value)
3437 if (device->svc_refreshed == value)
3440 device->svc_refreshed = value;
3442 g_dbus_emit_property_changed(dbus_conn, device->path,
3443 DEVICE_INTERFACE, "ServicesResolved");
3446 static void device_svc_resolved(struct btd_device *dev, uint8_t browse_type,
3447 uint8_t bdaddr_type, int err)
3449 struct bearer_state *state = get_state(dev, bdaddr_type);
3450 struct browse_req *req = dev->browse;
3452 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3453 DBG("%s bdaddr_type %d err %d", dev->path, bdaddr_type, err);
3455 DBG("%s err %d", dev->path, err);
3458 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3459 state->svc_resolved = true;
3462 state->svc_resolved = true;
3465 /* Disconnection notification can happen before this function
3466 * gets called, so don't set svc_refreshed for a disconnected
3469 if (state->connected)
3470 device_set_svc_refreshed(dev, true);
3472 g_slist_free_full(dev->eir_uuids, g_free);
3473 dev->eir_uuids = NULL;
3475 if (dev->pending_paired) {
3476 g_dbus_emit_property_changed(dbus_conn, dev->path,
3477 DEVICE_INTERFACE, "Paired");
3478 dev->pending_paired = false;
3481 if (!dev->temporary) {
3482 store_device_info(dev);
3484 if (bdaddr_type != BDADDR_BREDR && err == 0)
3485 store_services(dev);
3488 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3490 browse_request_complete(req, browse_type, bdaddr_type, err);
3493 while (dev->svc_callbacks) {
3494 struct svc_callback *cb = dev->svc_callbacks->data;
3496 if (cb->idle_id > 0)
3497 g_source_remove(cb->idle_id);
3499 cb->func(dev, err, cb->user_data);
3501 dev->svc_callbacks = g_slist_delete_link(dev->svc_callbacks,
3502 dev->svc_callbacks);
3506 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3510 /* If bdaddr_type is LE but req is for SDP, don't complete browse req. */
3511 if (bdaddr_type != BDADDR_BREDR && req->search_uuid) {
3512 DBG("Discover comp. is for LE but browse req. is for SDP.");
3516 browse_request_complete(req, browse_type, bdaddr_type, err);
3518 btd_device_update_allowed_services(dev);
3519 device_resolved_drivers(dev->adapter, dev);
3522 static struct bonding_req *bonding_request_new(DBusMessage *msg,
3523 struct btd_device *device,
3524 uint8_t bdaddr_type,
3525 struct agent *agent)
3527 struct bonding_req *bonding;
3530 ba2str(&device->bdaddr, addr);
3531 DBG("Requesting bonding for %s", addr);
3533 bonding = g_new0(struct bonding_req, 1);
3535 bonding->msg = dbus_message_ref(msg);
3536 bonding->bdaddr_type = bdaddr_type;
3538 bonding->cb_iter = btd_adapter_pin_cb_iter_new(device->adapter);
3540 /* Marks the bonding start time for the first attempt on request
3541 * construction. The following attempts will be updated on
3542 * device_bonding_retry. */
3543 clock_gettime(CLOCK_MONOTONIC, &bonding->attempt_start_time);
3546 bonding->agent = agent_ref(agent);
3551 void device_bonding_restart_timer(struct btd_device *device)
3553 if (!device || !device->bonding)
3556 clock_gettime(CLOCK_MONOTONIC, &device->bonding->attempt_start_time);
3559 static void bonding_request_stop_timer(struct bonding_req *bonding)
3561 struct timespec current;
3563 clock_gettime(CLOCK_MONOTONIC, ¤t);
3565 /* Compute the time difference in ms. */
3566 bonding->last_attempt_duration_ms =
3567 (current.tv_sec - bonding->attempt_start_time.tv_sec) * 1000L +
3568 (current.tv_nsec - bonding->attempt_start_time.tv_nsec)
3572 /* Returns the duration of the last bonding attempt in milliseconds. The
3573 * duration is measured starting from the latest of the following three
3574 * events and finishing when the Command complete event is received for the
3575 * authentication request:
3576 * - MGMT_OP_PAIR_DEVICE is sent,
3577 * - MGMT_OP_PIN_CODE_REPLY is sent and
3578 * - Command complete event is received for the sent MGMT_OP_PIN_CODE_REPLY.
3580 long device_bonding_last_duration(struct btd_device *device)
3582 struct bonding_req *bonding = device->bonding;
3587 return bonding->last_attempt_duration_ms;
3590 static void create_bond_req_exit(DBusConnection *conn, void *user_data)
3592 struct btd_device *device = user_data;
3595 ba2str(&device->bdaddr, addr);
3596 DBG("%s: requestor exited before bonding was completed", addr);
3599 device_cancel_authentication(device, FALSE);
3601 if (device->bonding) {
3602 device->bonding->listener_id = 0;
3603 device_request_disconnect(device, NULL);
3607 static void bonding_request_free(struct bonding_req *bonding)
3612 if (bonding->listener_id)
3613 g_dbus_remove_watch(dbus_conn, bonding->listener_id);
3616 dbus_message_unref(bonding->msg);
3618 if (bonding->cb_iter)
3619 g_free(bonding->cb_iter);
3621 if (bonding->agent) {
3622 agent_cancel(bonding->agent);
3623 agent_unref(bonding->agent);
3624 bonding->agent = NULL;
3627 if (bonding->retry_timer)
3628 g_source_remove(bonding->retry_timer);
3630 if (bonding->device)
3631 bonding->device->bonding = NULL;
3636 static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg,
3639 struct btd_device *device = data;
3640 struct btd_adapter *adapter = device->adapter;
3641 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3642 struct bearer_state *state;
3644 uint8_t bdaddr_type;
3646 struct agent *agent;
3647 struct bonding_req *bonding;
3649 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3651 bool connect_le = FALSE;
3652 uint8_t link_type = DEV_CONNECTED_NONE;
3656 btd_device_set_temporary(device, false);
3658 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3659 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &conn_type,
3660 DBUS_TYPE_INVALID) == FALSE)
3662 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
3664 return btd_error_invalid_args(msg);
3666 if (device->bonding)
3667 return btd_error_in_progress(msg);
3669 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3670 if (conn_type == DEV_CONN_DEFAULT) {
3671 link_type = device_get_connected_state(device);
3673 if (link_type == DEV_CONNECTED_BREDR) {
3674 if (device_is_bonded(device, DEV_CONN_BREDR))
3675 return btd_error_already_exists(msg);
3676 conn_type = DEV_CONN_BREDR;
3677 } else if (link_type == DEV_CONNECTED_LE) {
3678 if (device_is_bonded(device, DEV_CONN_LE))
3679 return btd_error_already_exists(msg);
3680 conn_type = DEV_CONN_LE;
3682 if (device_is_bonded(device, DEV_CONN_BREDR))
3683 return btd_error_already_exists(msg);
3684 else if (device_is_bonded(device, DEV_CONN_LE))
3685 return btd_error_already_exists(msg);
3688 conn_type = DEV_CONN_BREDR;
3689 else if (device->le)
3690 conn_type = DEV_CONN_LE;
3692 conn_type = DEV_CONN_BREDR;
3695 if (device_is_bonded(device, conn_type))
3696 return btd_error_already_exists(msg);
3698 bdaddr_type = device->bdaddr_type;
3700 if (device->bredr_state.bonded)
3701 bdaddr_type = device->bdaddr_type;
3702 else if (device->le_state.bonded)
3703 bdaddr_type = BDADDR_BREDR;
3705 bdaddr_type = select_conn_bearer(device);
3707 state = get_state(device, bdaddr_type);
3710 return btd_error_already_exists(msg);
3713 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3714 DBG("conn_type %d, link_type %d, bdaddr_type %d, device->bredr %d",
3715 conn_type, link_type, bdaddr_type, device->bredr);
3716 if (conn_type == DEV_CONN_LE &&
3717 (device_is_bredrle(device) || bdaddr_type != BDADDR_BREDR)) {
3718 DBG("LE Connect request");
3723 sender = dbus_message_get_sender(msg);
3725 agent = agent_get(sender);
3727 io_cap = agent_get_io_capability(agent);
3729 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
3731 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3732 if ((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3734 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3736 bonding = bonding_request_new(msg, device, BDADDR_BREDR, agent);
3738 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3744 bonding->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
3745 sender, create_bond_req_exit,
3748 device->bonding = bonding;
3749 bonding->device = device;
3751 /* Due to a bug in the kernel we might loose out on ATT commands
3752 * that arrive during the SMP procedure, so connect the ATT
3753 * channel first and only then start pairing (there's code for
3754 * this in the ATT connect callback)
3756 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3757 if (((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3758 (connect_le)) && !device->le_state.connected)
3759 err = device_connect_le(device);
3760 else if (connect_le) /* Send bonding request if LE is already connected*/
3761 err = adapter_create_bonding(adapter, &device->bdaddr,
3762 bdaddr_type, io_cap);
3764 err = adapter_create_bonding(adapter, &device->bdaddr,
3765 BDADDR_BREDR, io_cap);
3767 if (bdaddr_type != BDADDR_BREDR) {
3768 if (!state->connected && btd_le_connect_before_pairing())
3769 err = device_connect_le(device);
3771 err = adapter_create_bonding(adapter, &device->bdaddr,
3772 device->bdaddr_type,
3775 err = adapter_create_bonding(adapter, &device->bdaddr,
3776 BDADDR_BREDR, io_cap);
3781 bonding_request_free(device->bonding);
3782 return btd_error_failed(msg, strerror(-err));
3788 static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
3791 case MGMT_STATUS_SUCCESS:
3792 return dbus_message_new_method_return(msg);
3794 case MGMT_STATUS_CONNECT_FAILED:
3795 return dbus_message_new_error(msg,
3796 ERROR_INTERFACE ".ConnectionAttemptFailed",
3798 case MGMT_STATUS_TIMEOUT:
3799 return dbus_message_new_error(msg,
3800 ERROR_INTERFACE ".AuthenticationTimeout",
3801 "Authentication Timeout");
3802 case MGMT_STATUS_BUSY:
3803 case MGMT_STATUS_REJECTED:
3804 return dbus_message_new_error(msg,
3805 ERROR_INTERFACE ".AuthenticationRejected",
3806 "Authentication Rejected");
3807 case MGMT_STATUS_CANCELLED:
3808 case MGMT_STATUS_NO_RESOURCES:
3809 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3810 case MGMT_STATUS_DISCONNECTED:
3812 return dbus_message_new_error(msg,
3813 ERROR_INTERFACE ".AuthenticationCanceled",
3814 "Authentication Canceled");
3815 case MGMT_STATUS_ALREADY_PAIRED:
3816 return dbus_message_new_error(msg,
3817 ERROR_INTERFACE ".AlreadyExists",
3820 return dbus_message_new_error(msg,
3821 ERROR_INTERFACE ".AuthenticationFailed",
3822 "Authentication Failed");
3826 static void device_cancel_bonding(struct btd_device *device, uint8_t status)
3828 struct bonding_req *bonding = device->bonding;
3835 ba2str(&device->bdaddr, addr);
3836 DBG("Canceling bonding request for %s", addr);
3839 device_cancel_authentication(device, FALSE);
3841 reply = new_authentication_return(bonding->msg, status);
3842 g_dbus_send_message(dbus_conn, reply);
3844 bonding_request_cancel(bonding);
3845 bonding_request_free(bonding);
3848 static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
3851 struct btd_device *device = data;
3852 struct bonding_req *req = device->bonding;
3857 return btd_error_does_not_exist(msg);
3859 device_cancel_bonding(device, MGMT_STATUS_CANCELLED);
3861 return dbus_message_new_method_return(msg);
3864 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3865 static DBusMessage *discover_services(DBusConnection *conn,
3866 DBusMessage *msg, void *user_data)
3868 struct btd_device *device = user_data;
3869 const char *pattern;
3873 return btd_error_in_progress(msg);
3875 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
3876 DBUS_TYPE_INVALID) == FALSE)
3877 return btd_error_invalid_args(msg);
3879 err = device_browse_sdp(device, msg);
3886 return btd_error_failed(msg,
3887 "Unable to search the SDP services");
3890 static const char *browse_request_get_requestor(struct browse_req *req)
3895 return dbus_message_get_sender(req->msg);
3898 static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
3901 DBusMessageIter entry;
3903 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
3906 dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
3908 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
3910 dbus_message_iter_close_container(dict, &entry);
3913 static void discover_services_reply(struct browse_req *req, int err,
3917 DBusMessageIter iter, dict;
3926 if (err == -EHOSTDOWN)
3927 err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
3929 err_if = ERROR_INTERFACE ".Failed";
3931 reply = dbus_message_new_error(req->msg, err_if,
3933 g_dbus_send_message(dbus_conn, reply);
3937 reply = dbus_message_new_method_return(req->msg);
3941 dbus_message_iter_init_append(reply, &iter);
3943 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3944 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3945 DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
3946 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
3948 for (seq = recs; seq; seq = seq->next) {
3949 sdp_record_t *rec = (sdp_record_t *) seq->data;
3955 result = g_string_new(NULL);
3957 convert_sdp_record_to_xml(rec, result,
3958 (void *) g_string_append);
3961 if (!g_utf8_validate(result->str, -1, NULL)) {
3964 DBG("UTF8 invalid string, make valid");
3965 ptr = g_utf8_make_valid(result->str, -1);
3966 iter_append_record(&dict, rec->handle, ptr);
3969 iter_append_record(&dict, rec->handle, result->str);
3973 g_string_free(result, TRUE);
3976 dbus_message_iter_close_container(&iter, &dict);
3978 g_dbus_send_message(dbus_conn, reply);
3981 static DBusMessage *cancel_discover(DBusConnection *conn,
3982 DBusMessage *msg, void *user_data)
3984 struct btd_device *device = user_data;
3985 const char *sender = dbus_message_get_sender(msg);
3986 const char *requestor;
3988 if (!device->browse)
3989 return btd_error_does_not_exist(msg);
3991 if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
3992 "DiscoverServices"))
3993 return btd_error_not_authorized(msg);
3995 requestor = browse_request_get_requestor(device->browse);
3997 /* only the discover requestor can cancel the inquiry process */
3998 if (!requestor || !g_str_equal(requestor, sender))
3999 return btd_error_not_authorized(msg);
4001 discover_services_reply(device->browse, -ECANCELED, NULL);
4004 browse_request_cancel(device->browse);
4006 return dbus_message_new_method_return(msg);
4009 void device_set_gatt_connected(struct btd_device *device, gboolean connected)
4011 if (device == NULL) {
4012 error("device is NULL");
4016 if (device->gatt_connected == connected) {
4017 error("same state change for gatt_connected : %d", connected);
4020 DBG("GattConnected %d", connected);
4022 device->gatt_connected = connected;
4023 g_dbus_emit_property_changed(dbus_conn, device->path,
4024 DEVICE_INTERFACE, "GattConnected");
4027 static DBusMessage *connect_le(DBusConnection *conn, DBusMessage *msg,
4030 struct btd_device *dev = user_data;
4031 dbus_bool_t auto_connect = FALSE;
4036 * If a LE connection is requested without device discovery,
4037 * we try to get device object. Here, technology can be updated
4038 * if there is matched device object. Or, a new device object
4041 dev = btd_adapter_get_device(dev->adapter, &dev->bdaddr,
4044 error("Unable to get device object");
4045 return btd_error_not_supported(msg);
4049 if (dev->le_state.connected)
4050 return dbus_message_new_method_return(msg);
4052 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &auto_connect,
4054 return btd_error_invalid_args(msg);
4056 btd_device_set_temporary(dev, false);
4059 DBG("Start BLE auto connection");
4060 dev->disable_auto_connect = FALSE;
4061 device_set_auto_connect(dev, TRUE);
4063 return dbus_message_new_method_return(msg);
4066 err = device_connect_le(dev);
4068 return btd_error_failed(msg, strerror(-err));
4070 dev->connect = dbus_message_ref(msg);
4075 static DBusMessage *disconnect_le(DBusConnection *conn, DBusMessage *msg,
4078 struct btd_device *dev = user_data;
4081 return btd_error_not_supported(msg);
4084 * Disable connections through passive sccanning
4086 if (dev->auto_connect) {
4087 DBG("Stop BLE auto connection");
4088 dev->disable_auto_connect = FALSE;
4089 device_set_auto_connect(dev, FALSE);
4091 if (!dev->le_state.connected) {
4092 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
4097 device_request_disconnect(dev, msg);
4102 static DBusMessage *connect_ipsp(DBusConnection *conn, DBusMessage *msg,
4105 struct btd_device *device = user_data;
4107 DBG("bdaddr_type %d", device->bdaddr_type);
4109 if (device->bdaddr_type == BDADDR_BREDR) {
4111 device->bdaddr_type = BDADDR_LE_PUBLIC;
4113 device = btd_adapter_get_device(device->adapter,
4114 &device->bdaddr, BDADDR_LE_PUBLIC);
4116 return btd_error_no_such_adapter(msg);
4120 if (device->ipsp_connected)
4121 return btd_error_already_connected(msg);
4123 /* Initiate Connection for 6Lowan*/
4124 if (btd_adapter_connect_ipsp(device->adapter, &device->bdaddr,
4125 device->bdaddr_type) != 0)
4126 return btd_error_failed(msg, "ConnectFailed");
4128 return dbus_message_new_method_return(msg);;
4131 static DBusMessage *disconnect_ipsp(DBusConnection *conn, DBusMessage *msg,
4134 struct btd_device *device = user_data;
4135 DBG("bdaddr_type %d", device->bdaddr_type);
4137 if (device->bdaddr_type == BDADDR_BREDR)
4138 return btd_error_not_supported(msg);
4140 if (!device->ipsp_connected)
4141 return btd_error_not_connected(msg);
4143 /* Disconnect the 6Lowpan connection */
4144 if (btd_adapter_disconnect_ipsp(device->adapter, &device->bdaddr,
4145 device->bdaddr_type) != 0)
4146 return btd_error_failed(msg, "DisconnectFailed");
4148 /* TODO: Handle disconnection of GATT connection, If the connection
4149 * is established as part of IPSP connection. */
4151 return dbus_message_new_method_return(msg);;
4154 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4155 static GSList *find_otc_conn_info(GSList *list, const char *path)
4159 for (l = list; l != NULL; l = g_slist_next(l)) {
4160 struct otc_conn_info *info = l->data;
4162 if (g_strcmp0(info->dev_path, path) == 0)
4169 static gboolean otc_disconnected_cb(GIOChannel *chan, GIOCondition cond,
4172 struct otc_conn_info *conn_info;
4173 const char *dev_path = (const char *) user_data;
4176 DBG("OTC Disconnected");
4178 l = find_otc_conn_info(otc_connection_list, dev_path);
4182 conn_info = l->data;
4183 conn_info->otc_connected = false;
4185 g_dbus_emit_signal(dbus_conn, dev_path,
4186 DEVICE_INTERFACE, "OtcDisconnected",
4189 if (conn_info->io) {
4190 g_io_channel_shutdown(conn_info->io, TRUE, NULL);
4191 g_io_channel_unref(conn_info->io);
4194 otc_connection_list = g_slist_remove(otc_connection_list, conn_info);
4200 static void otc_connect_cb(GIOChannel *chan, GError *gerr,
4203 const char *dev_path;
4205 struct otc_conn_info *conn_info = NULL;
4206 DBusMessage *msg = NULL;
4207 DBusMessageIter iter;
4213 dev_path = (const char *) user_data;
4214 l = find_otc_conn_info(otc_connection_list, dev_path);
4219 conn_info = l->data;
4220 conn_info->otc_connected = true;
4222 fd = g_io_channel_unix_get_fd(chan);
4224 DBG("OTC Connected fd [%d], role [%s]",
4225 fd, conn_info->role ? "server" : "client");
4226 DBG("dev_path [%s]", dev_path);
4228 g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4229 otc_disconnected_cb, (gpointer) dev_path);
4231 if (conn_info->role == BT_OTP_CLIENT_ROLE) {
4232 msg = dbus_message_new_method_call(BT_OTC_SERVICE_NAME,
4234 BT_OTC_INTERFACE_NAME,
4236 } else if (conn_info->role == BT_OTP_SERVER_ROLE) {
4237 msg = dbus_message_new_method_call(BT_OTS_SERVICE_NAME,
4239 BT_OTS_INTERFACE_NAME,
4244 error("Unable to create NewConnection call");
4248 dbus_message_iter_init_append(msg, &iter);
4250 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4252 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4254 if (!g_dbus_send_message(dbus_conn, msg)) {
4255 error("sending NewConnection failed");
4256 dbus_message_unref(msg);
4260 int btd_adapter_connect_otc(struct btd_device *device)
4262 struct btd_adapter *adapter = device_get_adapter(device);
4263 const bdaddr_t *src = btd_adapter_get_address(adapter);
4264 uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4265 const bdaddr_t *dest = device_get_address(device);
4266 uint8_t dest_type = device->bdaddr_type;
4267 struct otc_conn_info *conn_info = NULL;
4268 const char *dev_path = device_get_path(device);
4269 GError *gerr = NULL;
4271 conn_info = g_malloc0(sizeof(struct otc_conn_info));
4273 conn_info->io = bt_io_connect(otc_connect_cb,
4274 (gpointer) dev_path, NULL, &gerr,
4275 BT_IO_OPT_SOURCE_BDADDR, src,
4276 BT_IO_OPT_SOURCE_TYPE, src_type,
4277 BT_IO_OPT_DEST_BDADDR, dest,
4278 BT_IO_OPT_DEST_TYPE, dest_type,
4279 BT_IO_OPT_PSM, OTP_PSM,
4280 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4283 if (!conn_info->io) {
4284 error("OTC Connect failed : %s", gerr->message);
4290 conn_info->dev_path = dev_path;
4291 conn_info->role = BT_OTP_CLIENT_ROLE;
4292 conn_info->otc_connected = false;
4293 g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4295 otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4299 static DBusMessage *connect_otc(DBusConnection *conn, DBusMessage *msg,
4302 struct btd_device *device = user_data;
4306 return btd_error_invalid_args(msg);
4308 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4311 struct otc_conn_info *info = l->data;
4312 if (info->otc_connected)
4313 return btd_error_already_connected(msg);
4315 return btd_error_busy(msg);
4318 if (btd_adapter_connect_otc(device) != 0)
4319 return btd_error_failed(msg, "ConnectFailed");
4321 return dbus_message_new_method_return(msg);
4324 static DBusMessage *disconnect_otc(DBusConnection *conn, DBusMessage *msg,
4327 struct btd_device *device = user_data;
4328 struct otc_conn_info *info = NULL;
4332 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4335 return btd_error_does_not_exist(msg);
4339 if (!info->otc_connected)
4340 return btd_error_not_connected(msg);
4342 sock = g_io_channel_unix_get_fd(info->io);
4344 shutdown(sock, SHUT_RDWR);
4346 g_io_channel_shutdown(info->io, FALSE, NULL);
4348 g_io_channel_unref(info->io);
4351 return dbus_message_new_method_return(msg);
4354 int btd_adapter_listen_otc(struct btd_device *device)
4356 struct btd_adapter *adapter = device_get_adapter(device);
4357 const bdaddr_t *src = btd_adapter_get_address(adapter);
4358 uint8_t type = btd_adapter_get_le_address_type(adapter);
4359 struct otc_conn_info *conn_info = NULL;
4360 const char *dev_path = device_get_path(device);
4361 GError *gerr = NULL;
4363 conn_info = g_malloc0(sizeof(struct otc_conn_info));
4365 conn_info->io = bt_io_listen(otc_connect_cb, NULL, (gpointer) dev_path,
4367 BT_IO_OPT_SOURCE_BDADDR, src,
4368 BT_IO_OPT_SOURCE_TYPE, type,
4369 BT_IO_OPT_PSM, OTP_PSM,
4370 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4373 if (!conn_info->io) {
4374 error("OTC Listen failed : %s", gerr->message);
4380 conn_info->dev_path = dev_path;
4381 conn_info->otc_connected = false;
4382 conn_info->role = BT_OTP_SERVER_ROLE;
4383 g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4385 otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4389 static DBusMessage *listen_otc(DBusConnection *conn, DBusMessage *msg,
4392 struct btd_device *device = user_data;
4396 return btd_error_invalid_args(msg);
4398 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4401 struct otc_conn_info *info = l->data;
4402 if (info->otc_connected)
4403 return btd_error_already_connected(msg);
4405 return btd_error_busy(msg);
4408 if (btd_adapter_listen_otc(device) != 0)
4409 return btd_error_failed(msg, "ListenFailed");
4411 return dbus_message_new_method_return(msg);
4415 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4416 /********************* L2CAP LE SOCKET IMPLEMENTATION *************************/
4417 static GSList *find_l2cap_le_profile_info(GSList *list, const char *owner,
4421 for (l = list; l != NULL; l = g_slist_next(l)) {
4422 struct l2cap_le_profile_info *info = l->data;
4427 if (g_strcmp0(info->owner, owner))
4430 if (!g_strcmp0(info->path, path))
4437 static int parse_l2cap_le_opt(struct l2cap_le_profile_info *info,
4438 const char *key, DBusMessageIter *value)
4440 int type = dbus_message_iter_get_arg_type(value);
4443 if (strcasecmp(key, "RequireAuthentication") == 0) {
4444 if (type != DBUS_TYPE_BOOLEAN)
4447 dbus_message_iter_get_basic(value, &b);
4450 info->sec_level = BT_IO_SEC_MEDIUM;
4452 info->sec_level = BT_IO_SEC_LOW;
4453 } else if (strcasecmp(key, "RequireAuthorization") == 0) {
4454 if (type != DBUS_TYPE_BOOLEAN)
4456 dbus_message_iter_get_basic(value, &b);
4457 info->authorize = b;
4463 static struct l2cap_le_profile_info *create_l2cap_le_socket(const char *owner,
4464 const char *path, int psm, DBusMessageIter *opts)
4466 struct l2cap_le_profile_info *info = NULL;
4468 if (psm < 0 || psm > BTD_L2CAP_LE_PSM_MAX)
4471 info = g_malloc0(sizeof(struct l2cap_le_profile_info));
4473 info->owner = g_strdup(owner);
4474 info->path = g_strdup(path);
4477 while (dbus_message_iter_get_arg_type(opts) == DBUS_TYPE_DICT_ENTRY) {
4478 DBusMessageIter value, entry;
4481 dbus_message_iter_recurse(opts, &entry);
4482 dbus_message_iter_get_basic(&entry, &key);
4484 dbus_message_iter_next(&entry);
4485 dbus_message_iter_recurse(&entry, &value);
4487 if (parse_l2cap_le_opt(info, key, &value) < 0)
4488 error("Invalid value for l2cap_le_socket option %s", key);
4490 dbus_message_iter_next(opts);
4494 info->name = g_strdup_printf("%s%s/%d", owner, path, psm);
4499 static void l2cap_le_io_destroy(gpointer p)
4501 struct l2cap_le_conn_info *conn = p;
4503 if (conn->io_id > 0)
4504 g_source_remove(conn->io_id);
4507 g_io_channel_shutdown(conn->io, FALSE, NULL);
4508 g_io_channel_unref(conn->io);
4511 if (conn->auth_id != 0)
4512 btd_cancel_authorization(conn->auth_id);
4514 if (conn->auth_uuid)
4515 free(conn->auth_uuid);
4520 static gboolean l2cap_le_disconnected_cb(GIOChannel *chan,
4521 GIOCondition cond, gpointer user_data)
4523 struct l2cap_le_conn_info *conn = user_data;
4524 struct l2cap_le_profile_info *info = conn->profile_info;
4526 DBG(" L2CAP LE socket disconnected role [%s] ",
4527 info->role == BT_L2CAP_LE_SERVER_ROLE ? "server" : "client");
4529 g_dbus_emit_signal(dbus_conn, conn->dev_path,
4530 DEVICE_INTERFACE, "L2CAPLEDisconnected",
4533 conn->connected = false;
4535 info->conn = g_slist_remove(info->conn, conn);
4536 l2cap_le_io_destroy(conn);
4540 static void l2cap_le_connect_cb(GIOChannel *chan, GError *gerr,
4543 struct l2cap_le_conn_info *conn = (struct l2cap_le_conn_info *) user_data;
4544 struct l2cap_le_profile_info *info = conn->profile_info;
4545 DBusMessage *msg = NULL;
4546 DBusMessageIter iter;
4547 const char *dev_path;
4549 GError *io_err = NULL;
4552 if (!bt_io_get(chan, &io_err,
4553 BT_IO_OPT_DEST, addr,
4554 BT_IO_OPT_INVALID)) {
4556 error("%s failed %s", info->name, gerr->message);
4557 g_error_free(io_err);
4560 error("Unable to get connect data for %s: %s",
4561 info->name, io_err->message);
4568 error("%s failed to connect to %s: %s", info->name, addr,
4573 conn->connected = true;
4575 fd = g_io_channel_unix_get_fd(chan);
4577 if (conn->io_id == 0)
4578 conn->io_id = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4579 l2cap_le_disconnected_cb, conn);
4581 msg = dbus_message_new_method_call(info->owner,
4583 BT_L2CAP_LE_INTERFACE_NAME,
4587 error("Unable to create NewConnection call");
4591 dev_path = conn->dev_path;
4593 dbus_message_iter_init_append(msg, &iter);
4595 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4597 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4599 if (!g_dbus_send_message(dbus_conn, msg)) {
4600 error("sending NewConnection failed");
4601 dbus_message_unref(msg);
4605 DBG("L2CAP_LE Connected fd [%d] addr [%s], role [%s]",fd, addr,
4606 info->role == BT_L2CAP_LE_SERVER_ROLE ? "server" : "client");
4611 g_error_free(io_err);
4613 info->conn = g_slist_remove(info->conn, conn);
4614 l2cap_le_io_destroy(conn);
4617 static struct l2cap_le_conn_info *create_l2cap_le_conn(
4618 struct l2cap_le_conn_info *server, GIOChannel *io,
4619 bdaddr_t *src, bdaddr_t *dst, uint8_t dst_type)
4621 struct l2cap_le_conn_info *conn;
4623 struct btd_device *device;
4624 struct btd_adapter *adapter = adapter_find(src);
4627 error("could not find adapter");
4631 device = btd_adapter_get_device(adapter, dst, dst_type);
4633 error("could not find Device");
4637 conn = g_new0(struct l2cap_le_conn_info, 1);
4638 conn->io = g_io_channel_ref(io);
4639 conn->profile_info = server->profile_info;
4640 conn->dev_path = device_get_path(device);
4642 cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
4643 conn->io_id = g_io_add_watch(io, cond, l2cap_le_disconnected_cb, conn);
4648 static void l2cap_le_auth(DBusError *err, void *user_data)
4650 struct l2cap_le_conn_info *conn = user_data;
4651 struct l2cap_le_profile_info *info = conn->profile_info;
4652 GError *gerr = NULL;
4657 bt_io_get(conn->io, &gerr, BT_IO_OPT_DEST, addr, BT_IO_OPT_INVALID);
4659 error("Unable to get connect data for %s: %s",
4660 info->name, gerr->message);
4665 if (err && dbus_error_is_set(err)) {
4666 error("%s rejected %s: %s", info->name, addr, err->message);
4670 if (!bt_io_accept(conn->io, l2cap_le_connect_cb, conn, NULL, &gerr)) {
4671 error("bt_io_accept: %s", gerr->message);
4676 DBG("%s authorized to connect to %s", addr, info->name);
4680 info->conn = g_slist_remove(info->conn, conn);
4681 l2cap_le_io_destroy(conn);
4684 static void l2cap_le_confirm(GIOChannel *io, gpointer user_data)
4686 struct l2cap_le_conn_info *server = user_data;
4687 struct l2cap_le_profile_info *info = server->profile_info;
4688 struct l2cap_le_conn_info *conn;
4689 GError *gerr = NULL;
4693 char *uuid = g_malloc0(UUID_LEN * sizeof(char));
4695 bt_io_get(io, &gerr,
4696 BT_IO_OPT_SOURCE_BDADDR, &src,
4697 BT_IO_OPT_DEST_BDADDR, &dst,
4698 BT_IO_OPT_DEST_TYPE, &dst_type,
4699 BT_IO_OPT_DEST, addr,
4702 error("%s failed to get connect data: %s", info->name,
4708 DBG("incoming connect from %s for authorization", addr);
4710 conn = create_l2cap_le_conn(server, io, &src, &dst, dst_type);
4714 /* Use custom uuid of the form "FFFFFFFF-FFFF-FFFF-FFFF-<psm in 12 digits>"
4715 * for authorizing l2cap_le socket using existing flow.
4716 * This custom uuid will be used in the BT-OAL layer to identify the
4717 * l2cap_le socket authorization and extracting psm from it.
4719 snprintf(uuid, UUID_LEN, "%s%012d", L2CAP_LE_UUID_SUBSTR, server->psm);
4720 conn->auth_uuid = uuid;
4722 conn->auth_id = btd_request_authorization(&src, &dst,
4723 (const char *)conn->auth_uuid, l2cap_le_auth, conn);
4724 if (conn->auth_id == 0) {
4725 error("%s authorization failure", info->name);
4726 l2cap_le_io_destroy(conn);
4730 info->conn = g_slist_append(info->conn, conn);
4732 DBG("%s authorizing connection from %s", info->name, addr);
4735 static void l2cap_le_direct_connect(GIOChannel *io, GError *err,
4738 struct l2cap_le_conn_info *server = user_data;
4739 struct l2cap_le_profile_info *info = server->profile_info;
4740 struct l2cap_le_conn_info *conn;
4741 GError *gerr = NULL;
4745 bt_io_get(io, &gerr,
4746 BT_IO_OPT_SOURCE_BDADDR, &src,
4747 BT_IO_OPT_DEST_BDADDR, &dst,
4748 BT_IO_OPT_DEST_TYPE, &dst_type,
4751 error("%s failed to get connect data: %s", info->name,
4757 conn = create_l2cap_le_conn(server, io, &src, &dst, dst_type);
4761 info->conn = g_slist_append(info->conn, conn);
4763 l2cap_le_connect_cb(io, err, conn);
4766 static void _remove_l2cap_le_socket(struct l2cap_le_profile_info *info)
4768 l2cap_le_socket_list = g_slist_remove(l2cap_le_socket_list, info);
4770 DBG("Removed \"%s\"", info->name);
4773 l2cap_le_io_destroy((gpointer)info->server);
4774 g_slist_free_full(info->conn, l2cap_le_io_destroy);
4777 g_free(info->owner);
4783 static void l2cap_le_socket_exited(DBusConnection *conn, void *user_data)
4785 struct l2cap_le_profile_info *info = user_data;
4787 DBG("l2cap le server \"%s\" exited", info->name);
4789 _remove_l2cap_le_socket(info);
4792 static int _connect_l2cap_le(struct btd_device *device,
4793 struct l2cap_le_profile_info *info)
4795 struct btd_adapter *adapter = device_get_adapter(device);
4796 const bdaddr_t *src = btd_adapter_get_address(adapter);
4797 uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4798 const bdaddr_t *dest = device_get_address(device);
4799 uint8_t dest_type = device->bdaddr_type;
4800 const char *dev_path = device_get_path(device);
4801 GError *gerr = NULL;
4802 struct l2cap_le_conn_info *conn = NULL;
4804 conn = g_malloc0(sizeof(struct l2cap_le_conn_info));
4805 info->conn = g_slist_append(info->conn, conn);
4807 conn->io = bt_io_connect(l2cap_le_connect_cb,
4809 BT_IO_OPT_SOURCE_BDADDR, src,
4810 BT_IO_OPT_SOURCE_TYPE, src_type,
4811 BT_IO_OPT_DEST_BDADDR, dest,
4812 BT_IO_OPT_DEST_TYPE, dest_type,
4813 BT_IO_OPT_PSM, info->psm,
4814 BT_IO_OPT_SEC_LEVEL, info->sec_level,
4818 error("L2CAP_LE Connect failed : %s", gerr->message);
4820 _remove_l2cap_le_socket(info);
4824 info->role = BT_L2CAP_LE_CLIENT_ROLE;
4825 conn->dev_path = dev_path;
4826 conn->profile_info = info;
4827 conn->connected = false;
4828 g_io_channel_set_close_on_unref(conn->io, FALSE);
4830 l2cap_le_socket_list = g_slist_append(l2cap_le_socket_list, info);
4834 static int _listen_l2cap_le(struct btd_adapter *adapter,
4835 struct l2cap_le_profile_info *info)
4837 const bdaddr_t *src = btd_adapter_get_address(adapter);
4838 uint8_t type = btd_adapter_get_le_address_type(adapter);
4839 GError *gerr = NULL;
4840 struct l2cap_le_conn_info *conn = NULL;
4841 BtIOConfirm confirm;
4842 BtIOConnect connect;
4845 if (info->authorize) {
4846 confirm = l2cap_le_confirm;
4850 connect = l2cap_le_direct_connect;
4853 conn = g_malloc0(sizeof(struct l2cap_le_conn_info));
4854 info->server = conn;
4856 conn->io = bt_io_listen(connect, confirm, (gpointer)conn,
4858 BT_IO_OPT_SOURCE_BDADDR, src,
4859 BT_IO_OPT_SOURCE_TYPE, type,
4860 BT_IO_OPT_PSM, info->psm,
4861 BT_IO_OPT_SEC_LEVEL, info->sec_level,
4865 error("L2cap_LE Listen failed : %s", gerr->message);
4867 _remove_l2cap_le_socket(info);
4871 bt_io_get(conn->io, &gerr, BT_IO_OPT_PSM, &psm, BT_IO_OPT_INVALID);
4873 DBG("L2CAP LE Socket listen to PSM %d successful", psm);
4875 conn->connected = false;
4876 info->role = BT_L2CAP_LE_SERVER_ROLE;
4878 conn->profile_info = info;
4879 g_io_channel_set_close_on_unref(conn->io, FALSE);
4881 l2cap_le_socket_list = g_slist_append(l2cap_le_socket_list, info);
4886 static DBusMessage *connect_l2cap_le_socket(DBusConnection *conn,
4887 DBusMessage *msg, void *user_data)
4889 struct btd_device *device = user_data;
4891 const char *path, *sender;
4893 DBusMessageIter args, opts;
4894 struct l2cap_le_profile_info *info = NULL;
4897 return btd_error_invalid_args(msg);
4899 sender = dbus_message_get_sender(msg);
4901 dbus_message_iter_init(msg, &args);
4902 dbus_message_iter_get_basic(&args, &path);
4903 dbus_message_iter_next(&args);
4905 dbus_message_iter_get_basic(&args, &psm);
4906 dbus_message_iter_next(&args);
4908 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4911 struct l2cap_le_profile_info *info = l->data;
4913 struct l2cap_le_conn_info *conn_info = info->conn->data;
4914 if (conn_info && conn_info->connected)
4915 return btd_error_already_connected(msg);
4917 return btd_error_busy(msg);
4919 error("Something is wrong!!!");
4920 return btd_error_failed(msg, "ConnectFailed due to some internal error");
4924 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
4925 return btd_error_invalid_args(msg);
4927 dbus_message_iter_recurse(&args, &opts);
4929 info = create_l2cap_le_socket(sender, path, psm, &opts);
4931 return btd_error_invalid_args(msg);
4933 info->role = BT_L2CAP_LE_CLIENT_ROLE;
4935 DBG("connect l2cap l2 socket channel %d", (int)psm);
4937 if (_connect_l2cap_le(device, info) != 0)
4938 return btd_error_failed(msg, "ConnectFailed");
4940 info->id = g_dbus_add_disconnect_watch(conn, sender, l2cap_le_socket_exited,
4943 return dbus_message_new_method_return(msg);
4946 DBusMessage *listen_l2cap_le_socket(DBusConnection *conn, DBusMessage *msg,
4949 struct btd_adapter *adapter = user_data;
4951 const char *path, *sender;
4953 DBusMessageIter args, opts;
4954 struct l2cap_le_profile_info *info = NULL;
4956 sender = dbus_message_get_sender(msg);
4958 dbus_message_iter_init(msg, &args);
4959 dbus_message_iter_get_basic(&args, &path);
4960 dbus_message_iter_next(&args);
4962 dbus_message_iter_get_basic(&args, &psm);
4963 dbus_message_iter_next(&args);
4965 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4968 return btd_error_already_exists(msg);
4970 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
4971 return btd_error_invalid_args(msg);
4973 dbus_message_iter_recurse(&args, &opts);
4975 info = create_l2cap_le_socket(sender, path, psm, &opts);
4977 return btd_error_invalid_args(msg);
4979 info->role = BT_L2CAP_LE_SERVER_ROLE;
4981 DBG("listen l2cap_le socket to psm %d", (int)psm);
4983 if (_listen_l2cap_le(adapter, info) != 0)
4984 return btd_error_failed(msg, "ListenFailed");
4986 info->id = g_dbus_add_disconnect_watch(conn, sender, l2cap_le_socket_exited,
4989 return dbus_message_new_method_return(msg);
4992 DBusMessage *get_psm_l2cap_le(DBusConnection *conn, DBusMessage *msg)
4994 const char *path, *sender;
4998 DBusMessageIter args;
4999 struct l2cap_le_profile_info *info;
5001 sender = dbus_message_get_sender(msg);
5003 DBG("sender %s", sender);
5005 dbus_message_iter_init(msg, &args);
5007 dbus_message_iter_get_basic(&args, &path);
5008 dbus_message_iter_next(&args);
5010 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
5013 DBG("L2cap LE socket not exist");
5014 return btd_error_does_not_exist(msg);
5020 psm = info->server->psm;
5022 return btd_error_does_not_exist(msg);
5024 reply = dbus_message_new_method_return(msg);
5026 return btd_error_failed(msg,
5027 "Failed to create reply.");
5029 dbus_message_append_args(reply,
5030 DBUS_TYPE_UINT32, &psm,
5036 DBusMessage *remove_l2cap_le_socket(DBusConnection *conn, DBusMessage *msg)
5038 const char *path, *sender;
5039 struct l2cap_le_profile_info *info = NULL;
5042 sender = dbus_message_get_sender(msg);
5044 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
5046 return btd_error_invalid_args(msg);
5048 DBG("remove socket sender %s path %s", sender, path);
5050 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
5053 DBG("L2cap LE socket not exist");
5054 return btd_error_does_not_exist(msg);
5059 g_dbus_remove_watch(conn, info->id);
5060 _remove_l2cap_le_socket(info);
5062 return dbus_message_new_method_return(msg);
5066 static DBusMessage *le_set_data_length(
5067 DBusConnection *conn, DBusMessage *msg,
5070 dbus_uint16_t max_tx_octets;
5071 dbus_uint16_t max_tx_time;
5072 struct btd_device *device = user_data;
5076 if (!dbus_message_get_args(msg, NULL,
5077 DBUS_TYPE_UINT16, &max_tx_octets,
5078 DBUS_TYPE_UINT16, &max_tx_time,
5079 DBUS_TYPE_INVALID)) {
5080 DBG("error in retrieving values");
5081 return btd_error_invalid_args(msg);
5084 if (device->bdaddr_type == BDADDR_BREDR)
5085 return btd_error_not_supported(msg);
5087 ba2str(&device->bdaddr, addr);
5089 DBG("Remote device address: %s", addr);
5090 DBG("Max tx octets: %u, Max tx time: %u",
5091 max_tx_octets, max_tx_time);
5093 status = btd_adapter_le_set_data_length(device->adapter,
5094 &device->bdaddr, max_tx_octets,
5098 return btd_error_failed(msg, "Unable to set le data length values");
5100 return dbus_message_new_method_return(msg);
5103 static DBusMessage *set_trusted_profile(DBusConnection *conn,
5104 DBusMessage *msg, void *data)
5106 struct btd_device *dev = data;
5107 dbus_bool_t profile_trusted;
5108 const char *pattern;
5110 uint32_t pbap = dev->trusted_profiles.pbap;
5111 uint32_t map = dev->trusted_profiles.map;
5112 uint32_t sap = dev->trusted_profiles.sap;
5113 uint32_t hfp_hs = dev->trusted_profiles.hfp_hs;
5114 uint32_t a2dp = dev->trusted_profiles.a2dp;
5116 if (!dbus_message_get_args(msg, NULL,
5117 DBUS_TYPE_STRING, &pattern,
5118 DBUS_TYPE_BOOLEAN, &profile_trusted,
5120 return btd_error_invalid_args(msg);
5122 DBG("Pattern : %s", pattern);
5123 uuid = bt_name2string(pattern);
5124 DBG("UUID : %s", uuid);
5125 DBG("profile Trusted : %d %d %d", dev->trusted_profiles.pbap,
5126 dev->trusted_profiles.map, dev->trusted_profiles.sap);
5127 DBG("profile Restricted : %d %d", dev->trusted_profiles.hfp_hs,
5128 dev->trusted_profiles.a2dp);
5129 if (g_strcmp0(uuid, OBEX_PBAP_UUID) == 0) {
5130 if (profile_trusted)
5131 pbap = SUPPORTED_TRUSTED;
5133 pbap = SUPPORTED_BLOCKED;
5134 } else if (g_strcmp0(uuid, OBEX_MAP_UUID) == 0) {
5135 if (profile_trusted)
5136 map = SUPPORTED_TRUSTED;
5138 map = SUPPORTED_BLOCKED;
5139 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
5140 if (profile_trusted)
5141 sap = SUPPORTED_TRUSTED;
5143 sap = SUPPORTED_BLOCKED;
5144 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
5145 if (profile_trusted)
5146 hfp_hs = SUPPORTED_TRUSTED;
5148 hfp_hs = SUPPORTED_BLOCKED;
5149 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
5150 if (profile_trusted)
5151 a2dp = SUPPORTED_TRUSTED;
5153 a2dp = SUPPORTED_BLOCKED;
5156 return btd_error_invalid_args(msg);
5160 btd_device_set_trusted_profiles(dev, pbap, map, sap, hfp_hs, a2dp);
5161 return dbus_message_new_method_return(msg);
5164 static DBusMessage *is_connected_profile(DBusConnection *conn, DBusMessage *msg,
5167 struct btd_device *dev = user_data;
5168 struct btd_service *service;
5169 btd_service_state_t state;
5170 const char *pattern;
5175 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
5177 return btd_error_invalid_args(msg);
5179 reply = dbus_message_new_method_return(msg);
5181 return btd_error_invalid_args(reply);
5183 uuid = bt_name2string(pattern);
5184 DBG("is_connected_profile_uuid : %s", uuid);
5185 service = btd_device_get_service(dev, uuid);
5187 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
5188 DBG("HFP service is not found check for HSP service");
5189 service = btd_device_get_service(dev, HSP_HS_UUID);
5195 return btd_error_not_connected(msg);
5197 state = btd_service_get_state(service);
5198 DBG("Connected State : %d", state);
5200 if (state == BTD_SERVICE_STATE_CONNECTED)
5205 dbus_message_append_args(reply,
5206 DBUS_TYPE_BOOLEAN, &val,
5212 static DBusMessage *update_le_conn_parm(DBusConnection *conn, DBusMessage *msg,
5215 struct btd_device *device = user_data;
5218 struct le_conn_param param = {0, 0, 0, 0};
5219 uint32_t min, max, latency, to_multiplier;
5223 if (device == NULL) {
5224 error("device is NULL");
5225 return btd_error_invalid_args(msg);
5229 error("le is not supported");
5230 return btd_error_not_supported(msg);
5233 if (!device->gatt_connected || !device->attrib)
5234 return btd_error_not_connected(msg);
5236 io = g_attrib_get_channel(device->attrib);
5238 return btd_error_not_connected(msg);
5240 fd = g_io_channel_unix_get_fd(io);
5242 return btd_error_not_connected(msg);
5244 if (device_get_conn_update_state(device))
5245 return btd_error_in_progress(msg);
5247 device_set_conn_update_state(device, true);
5249 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &min,
5250 DBUS_TYPE_UINT32, &max,
5251 DBUS_TYPE_UINT32, &latency,
5252 DBUS_TYPE_UINT32, &to_multiplier,
5253 DBUS_TYPE_INVALID)) {
5254 error("Invalid args");
5255 return btd_error_invalid_args(msg);
5258 if (min > UINT16_MAX || max > UINT16_MAX ||
5259 latency > UINT16_MAX || to_multiplier > UINT16_MAX) {
5260 error("Invalid args");
5261 return btd_error_invalid_args(msg);
5263 param.min = (uint16_t)min;
5264 param.max = (uint16_t)max;
5265 param.latency = (uint16_t)latency;
5266 param.to_multiplier = (uint16_t)to_multiplier;
5268 if (setsockopt(fd, SOL_BLUETOOTH, BT_LE_CONN_PARAM,
5269 ¶m, sizeof(param)) < 0) {
5270 error("Can't Update LE conn param : %s (%d)",
5271 strerror(errno), errno);
5272 return btd_error_failed(msg, strerror(errno));
5275 return dbus_message_new_method_return(msg);
5278 static void device_request_att_mtu_reponse_cb(bool success, uint8_t att_ecode,
5281 struct btd_device *device = user_data;
5283 DBusMessageIter iter;
5286 if (!device->req_att_mtu)
5289 mtu = bt_gatt_client_get_mtu(device->client);
5293 err_if = ERROR_INTERFACE ".Failed";
5295 reply = dbus_message_new_error(device->req_att_mtu, err_if,
5296 "Request Att MTU failed");
5297 g_dbus_send_message(dbus_conn, reply);
5301 DBG("MTU exchange complete, with MTU: %u", mtu);
5303 reply = dbus_message_new_method_return(device->req_att_mtu);
5307 dbus_message_iter_init_append(reply, &iter);
5309 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
5311 dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
5313 g_dbus_send_message(dbus_conn, reply);
5315 dbus_message_unref(device->req_att_mtu);
5316 device->req_att_mtu = NULL;
5319 static DBusMessage *request_att_mtu(DBusConnection *conn, DBusMessage *msg,
5322 struct btd_device *device = user_data;
5327 if (device == NULL) {
5328 error("device is NULL");
5329 return btd_error_invalid_args(msg);
5333 error("le is not supported");
5334 return btd_error_not_supported(msg);
5337 if (!device->gatt_connected || !device->attrib)
5338 return btd_error_not_connected(msg);
5340 if (!dbus_message_get_args(msg, NULL,
5341 DBUS_TYPE_UINT16, &mtu,
5342 DBUS_TYPE_INVALID)) {
5343 error("Invalid args");
5344 return btd_error_invalid_args(msg);
5349 if (!bt_gatt_request_att_mtu(device->client, mtu,
5350 device_request_att_mtu_reponse_cb, device))
5351 return btd_error_failed(msg, "Unable to Request MTU");
5353 device->req_att_mtu = dbus_message_ref(msg);
5357 static DBusMessage *device_get_ida(DBusConnection *conn, DBusMessage *msg,
5360 struct btd_device *device = user_data;
5361 char device_idaddr[18] = { 0 };
5363 const gchar *id_address = device_idaddr;
5368 return btd_error_invalid_args(msg);
5371 error("It doesn't support LE");
5372 return btd_error_not_supported(msg);
5376 // There is the first RPA. So it's paired device.
5378 ba2str(device->rpa, device_idaddr);
5380 ba2str(&device->bdaddr, device_idaddr);
5381 } else if (device->bdaddr_type != BDADDR_LE_RANDOM) {
5382 // device->bdaddr is identity address.
5383 ba2str(&device->bdaddr, device_idaddr);
5384 } else if ((device->bdaddr.b[5] >> 6) == 0x01) {
5385 // RPA but it's not paired
5386 return btd_error_does_not_exist(msg);
5387 } else if ((device->bdaddr.b[5] >> 6) == 0x03) {
5388 // Static Random address
5389 ba2str(&device->bdaddr, device_idaddr);
5392 return btd_error_not_supported(msg);
5395 reply = dbus_message_new_method_return(msg);
5399 dbus_message_append_args(reply, DBUS_TYPE_STRING, &id_address,
5405 void device_set_conn_update_state(struct btd_device *device, bool state)
5410 device->pending_conn_update = state;
5413 bool device_get_conn_update_state(struct btd_device *device)
5415 return device->pending_conn_update;
5419 static const GDBusMethodTable device_methods[] = {
5420 { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) },
5421 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) },
5422 { GDBUS_ASYNC_METHOD("ConnectProfile", GDBUS_ARGS({ "UUID", "s" }),
5423 NULL, connect_profile) },
5424 { GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
5425 NULL, disconnect_profile) },
5426 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5427 { GDBUS_ASYNC_METHOD("DisconnectExtProfile",
5428 GDBUS_ARGS({ "profile", "o" }), NULL,
5429 disconnect_ext_profile) },
5430 { GDBUS_ASYNC_METHOD("Pair", GDBUS_ARGS({ "conn_type", "y" }), NULL,
5433 { GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
5435 { GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
5436 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5437 { GDBUS_ASYNC_METHOD("ConnectLE", GDBUS_ARGS({ "auto_connect", "b"}),
5438 NULL, connect_le) },
5439 { GDBUS_ASYNC_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
5440 { GDBUS_METHOD("IsConnectedProfile", GDBUS_ARGS({ "UUID", "s" }),
5441 GDBUS_ARGS({ "IsConnected", "b" }),
5442 is_connected_profile)},
5443 { GDBUS_METHOD("LeConnUpdate", GDBUS_ARGS({ "interval_min", "u" },
5444 { "interval_max", "u" }, { "latency", "u" },
5445 { "time_out", "u" }), NULL,
5446 update_le_conn_parm) },
5447 { GDBUS_ASYNC_METHOD("DiscoverServices", GDBUS_ARGS({ "pattern", "s" }),
5448 NULL, discover_services) },
5449 { GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
5450 { GDBUS_ASYNC_METHOD("ConnectIpsp", NULL, NULL, connect_ipsp) },
5451 { GDBUS_ASYNC_METHOD("DisconnectIpsp", NULL, NULL, disconnect_ipsp) },
5452 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5453 { GDBUS_METHOD("ConnectOtc", NULL, NULL, connect_otc) },
5454 { GDBUS_METHOD("DisconnectOtc", NULL, NULL, disconnect_otc) },
5455 { GDBUS_METHOD("ListenOtc", NULL, NULL, listen_otc) },
5456 { GDBUS_ASYNC_METHOD("ConnectL2capLESocket",
5457 GDBUS_ARGS({ "path", "o"}, { "psm", "i" }, { "options", "a{sv}" }),
5458 NULL, connect_l2cap_le_socket) },
5460 { GDBUS_ASYNC_METHOD("LESetDataLength",
5461 GDBUS_ARGS({"max_tx_octets", "q" },
5462 { "max_tx_time", "q" }), NULL,
5463 le_set_data_length)},
5464 { GDBUS_ASYNC_METHOD("RequestAttMtu", GDBUS_ARGS({ "mtu", "q" }),
5465 GDBUS_ARGS({ "mtu", "q" }, { "status", "y"}),
5467 { GDBUS_METHOD("GetIDAddress", NULL, GDBUS_ARGS({ "IDAdress", "s" }),
5469 { GDBUS_METHOD("SetTrustedProfile",
5470 GDBUS_ARGS({ "uuid", "s"}, { "trusted", "b"}), NULL,
5471 set_trusted_profile) },
5476 static const GDBusPropertyTable device_properties[] = {
5477 { "Address", "s", dev_property_get_address },
5478 { "AddressType", "s", property_get_address_type },
5479 { "Name", "s", dev_property_get_name, NULL, dev_property_exists_name },
5480 { "Alias", "s", dev_property_get_alias, dev_property_set_alias },
5481 { "Class", "u", dev_property_get_class, NULL,
5482 dev_property_exists_class },
5483 { "Appearance", "q", dev_property_get_appearance, NULL,
5484 dev_property_exists_appearance },
5485 { "Icon", "s", dev_property_get_icon, NULL,
5486 dev_property_exists_icon },
5487 { "Paired", "b", dev_property_get_paired },
5488 { "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted },
5489 { "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
5490 { "LegacyPairing", "b", dev_property_get_legacy },
5491 { "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
5492 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5493 {"IsAliasSet", "b", dev_property_get_alias_set },
5494 { "Connected", "y", dev_property_get_connected },
5496 { "Connected", "b", dev_property_get_connected },
5498 { "UUIDs", "as", dev_property_get_uuids },
5499 { "Modalias", "s", dev_property_get_modalias, NULL,
5500 dev_property_exists_modalias },
5501 { "Adapter", "o", dev_property_get_adapter },
5502 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5503 /* To handle Failed Legacy Pairing when initiated from Remote device*/
5504 { "LegacyPaired", "b", dev_property_get_paired },
5505 { "LegacyManufacturerDataLen", "q", property_get_manufacturer_data_len },
5506 { "LegacyManufacturerData", "ay", property_get_manufacturer_data },
5507 { "GattConnected", "b", dev_property_get_gatt_connected },
5508 { "PayloadTimeout", "q", dev_property_get_payload},
5509 { "LastAddrType", "y", dev_property_get_last_addr_type},
5510 { "IpspConnected", "b", dev_property_get_ipsp_conn_state },
5511 { "IpspBtInterfaceInfo", "s", dev_property_get_ipsp_conn_bt_iface_name },
5512 { "AttMtu", "q", dev_property_get_att_mtu },
5513 { "TrustedProfiles", "u", dev_property_get_trusted_profiles},
5515 { "ManufacturerData", "a{qv}", dev_property_get_manufacturer_data,
5516 NULL, dev_property_manufacturer_data_exist },
5517 { "ServiceData", "a{sv}", dev_property_get_service_data,
5518 NULL, dev_property_service_data_exist },
5519 { "TxPower", "n", dev_property_get_tx_power, NULL,
5520 dev_property_exists_tx_power },
5521 { "ServicesResolved", "b", dev_property_get_svc_resolved, NULL, NULL },
5522 { "AdvertisingFlags", "ay", dev_property_get_flags, NULL,
5523 dev_property_flags_exist,
5524 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
5525 { "AdvertisingData", "a{yv}", dev_property_get_advertising_data,
5526 NULL, dev_property_advertising_data_exist,
5527 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
5528 { "WakeAllowed", "b", dev_property_get_wake_allowed,
5529 dev_property_set_wake_allowed,
5530 dev_property_wake_allowed_exist },
5534 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5535 static const GDBusSignalTable device_signals[] = {
5536 { GDBUS_SIGNAL("Disconnected",
5537 GDBUS_ARGS({ "bdaddr_type", "y" }, { "reason", "y" },
5538 { "name", "s" })) },
5539 { GDBUS_SIGNAL("DeviceConnected", GDBUS_ARGS({ "bdaddr_type", "y"})) },
5540 { GDBUS_SIGNAL("ProfileStateChanged",
5541 GDBUS_ARGS({ "profile", "s"}, {"state", "i"})) },
5542 { GDBUS_SIGNAL("AdvReport",
5543 GDBUS_ARGS({"Address","s"}, { "Address Type", "y" },
5544 { "Adv Type", "y"}, { "RSSI", "i"},
5545 { "AdvDataLen", "i"}, { "AdvData", "ay"})) },
5546 { GDBUS_SIGNAL("LEDataLengthChanged",
5547 GDBUS_ARGS({"max_tx_octets","q"},
5548 { "max_tx_time", "q" },
5549 { "max_rx_octets", "q"},
5550 { "max_rx_time", "q"}))},
5551 { GDBUS_SIGNAL("IpspStateChanged",
5552 GDBUS_ARGS({"connected","b"}, {"if_name","s"}))},
5553 { GDBUS_SIGNAL("OtcDisconnected", NULL)},
5554 { GDBUS_SIGNAL("AttMtuChanged",
5555 GDBUS_ARGS({"mtu", "q"})) },
5560 uint8_t btd_device_get_bdaddr_type(struct btd_device *dev)
5562 return dev->bdaddr_type;
5565 bool btd_device_is_connected(struct btd_device *dev)
5567 return dev->bredr_state.connected || dev->le_state.connected;
5570 static void clear_temporary_timer(struct btd_device *dev)
5572 if (dev->temporary_timer) {
5573 timeout_remove(dev->temporary_timer);
5574 dev->temporary_timer = 0;
5578 void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
5580 struct bearer_state *state = get_state(dev, bdaddr_type);
5582 device_update_last_seen(dev, bdaddr_type);
5584 if (state->connected) {
5586 ba2str(&dev->bdaddr, addr);
5587 error("Device %s is already connected", addr);
5591 bacpy(&dev->conn_bdaddr, &dev->bdaddr);
5592 dev->conn_bdaddr_type = dev->bdaddr_type;
5594 /* If this is the first connection over this bearer */
5595 if (bdaddr_type == BDADDR_BREDR)
5596 device_set_bredr_support(dev);
5598 device_set_le_support(dev, bdaddr_type);
5600 state->connected = true;
5602 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5603 if (dev->le_state.connected && dev->bredr_state.connected)
5606 /* Remove temporary timer while connected */
5607 clear_temporary_timer(dev);
5609 g_dbus_emit_property_changed(dbus_conn, dev->path, DEVICE_INTERFACE,
5612 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
5613 if (bdaddr_type == BDADDR_BREDR &&
5614 get_charging_state(dev->adapter) == WIRELESS_CHARGING) {
5615 int br_pkt_type = ACL_PTYPE_MASK |
5616 HCI_2DH1 | HCI_2DH3 | HCI_2DH5 |
5617 HCI_3DH1 | HCI_3DH3 | HCI_3DH5;
5619 DBG("During wireless charging... Change packet type");
5620 device_change_pkt_type(dev, (gpointer)br_pkt_type);
5622 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
5624 g_dbus_emit_signal(dbus_conn, dev->path,
5625 DEVICE_INTERFACE, "DeviceConnected",
5626 DBUS_TYPE_BYTE, &bdaddr_type,
5631 void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
5633 struct bearer_state *state = get_state(device, bdaddr_type);
5635 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5636 bool remove_device = false;
5638 bool paired_status_updated = false;
5639 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5640 char *dev_name = device->name;
5643 if (!state->connected)
5646 state->connected = false;
5647 device->general_connect = FALSE;
5649 device_set_svc_refreshed(device, false);
5651 if (device->disconn_timer > 0) {
5652 timeout_remove(device->disconn_timer);
5653 device->disconn_timer = 0;
5656 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5657 if (device->browse) {
5658 struct browse_req *req = device->browse;
5660 if ((bdaddr_type == BDADDR_BREDR && req->search_uuid != 0) ||
5661 (bdaddr_type != BDADDR_BREDR && req->search_uuid == 0))
5662 device->browse = NULL;
5664 DBG("device->browse is for other link");
5668 /* This could be executed while the client is waiting for Connect() but
5669 * att_connect_cb has not been invoked.
5670 * In that case reply the client that the connection failed.
5672 if (device->connect) {
5673 DBG("connection removed while Connect() is waiting reply");
5674 reply = btd_error_failed(device->connect,
5675 ERR_BREDR_CONN_CANCELED);
5676 g_dbus_send_message(dbus_conn, reply);
5677 dbus_message_unref(device->connect);
5678 device->connect = NULL;
5681 while (device->disconnects) {
5682 DBusMessage *msg = device->disconnects->data;
5684 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5685 if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
5687 remove_device = true;
5689 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
5690 device->disconnects = g_slist_remove(device->disconnects, msg);
5691 dbus_message_unref(msg);
5694 /* Check paired status of both bearers since it's possible to be
5695 * paired but not connected via link key to LTK conversion.
5697 if (!device->bredr_state.connected && device->bredr_state.paired &&
5698 !device->bredr_state.bonded) {
5699 btd_adapter_remove_bonding(device->adapter,
5702 device->bredr_state.paired = false;
5703 paired_status_updated = true;
5706 if (!device->le_state.connected && device->le_state.paired &&
5707 !device->le_state.bonded) {
5708 btd_adapter_remove_bonding(device->adapter,
5710 device->bdaddr_type);
5711 device->le_state.paired = false;
5712 paired_status_updated = true;
5715 /* report change only if both bearers are unpaired */
5716 if (!device->bredr_state.paired && !device->le_state.paired &&
5717 paired_status_updated)
5718 g_dbus_emit_property_changed(dbus_conn, device->path,
5723 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5724 if (device->bredr_state.connected || device->le_state.connected)
5727 device_update_last_seen(device, bdaddr_type);
5729 g_slist_free_full(device->eir_uuids, g_free);
5730 device->eir_uuids = NULL;
5732 g_dbus_emit_property_changed(dbus_conn, device->path,
5733 DEVICE_INTERFACE, "Connected");
5736 btd_adapter_remove_device(device->adapter, device);
5738 g_dbus_emit_signal(dbus_conn, device->path,
5739 DEVICE_INTERFACE, "Disconnected",
5740 DBUS_TYPE_BYTE, &bdaddr_type,
5741 DBUS_TYPE_BYTE, &device->disc_reason,
5742 DBUS_TYPE_STRING, &dev_name,
5747 guint device_add_disconnect_watch(struct btd_device *device,
5748 disconnect_watch watch, void *user_data,
5749 GDestroyNotify destroy)
5751 struct btd_disconnect_data *data;
5752 static guint id = 0;
5754 data = g_new0(struct btd_disconnect_data, 1);
5756 data->watch = watch;
5757 data->user_data = user_data;
5758 data->destroy = destroy;
5760 device->watches = g_slist_append(device->watches, data);
5765 void device_remove_disconnect_watch(struct btd_device *device, guint id)
5769 for (l = device->watches; l; l = l->next) {
5770 struct btd_disconnect_data *data = l->data;
5772 if (data->id == id) {
5773 device->watches = g_slist_remove(device->watches,
5776 data->destroy(data->user_data);
5783 static char *load_cached_name(struct btd_device *device, const char *local,
5786 char filename[PATH_MAX];
5791 if (device_address_is_private(device))
5794 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
5796 key_file = g_key_file_new();
5798 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
5801 str = g_key_file_get_string(key_file, "General", "Name", NULL);
5804 if (len > HCI_MAX_NAME_LENGTH)
5805 str[HCI_MAX_NAME_LENGTH] = '\0';
5809 g_key_file_free(key_file);
5814 static void load_cached_name_resolve(struct btd_device *device,
5815 const char *local, const char *peer)
5817 char filename[PATH_MAX];
5819 uint64_t failed_time;
5821 if (device_address_is_private(device))
5824 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
5826 key_file = g_key_file_new();
5828 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
5831 failed_time = g_key_file_get_uint64(key_file, "NameResolving",
5832 "FailedTime", NULL);
5834 device->name_resolve_failed_time = failed_time;
5837 g_key_file_free(key_file);
5840 static struct csrk_info *load_csrk(GKeyFile *key_file, const char *group)
5842 struct csrk_info *csrk;
5846 str = g_key_file_get_string(key_file, group, "Key", NULL);
5850 csrk = g_new0(struct csrk_info, 1);
5852 for (i = 0; i < 16; i++) {
5853 if (sscanf(str + (i * 2), "%2hhx", &csrk->key[i]) != 1)
5858 * In case of older storage this will return 0 which is fine since it
5859 * didn't support signing at that point the counter should never have
5862 csrk->counter = g_key_file_get_integer(key_file, group, "Counter",
5874 static void load_services(struct btd_device *device, char **uuids)
5878 for (uuid = uuids; *uuid; uuid++) {
5879 if (g_slist_find_custom(device->uuids, *uuid, bt_uuid_strcmp))
5882 device->uuids = g_slist_insert_sorted(device->uuids,
5890 static void convert_info(struct btd_device *device, GKeyFile *key_file)
5892 char filename[PATH_MAX];
5893 char adapter_addr[18];
5894 char device_addr[18];
5898 GError *gerr = NULL;
5900 /* Load device profile list from legacy properties */
5901 uuids = g_key_file_get_string_list(key_file, "General", "SDPServices",
5904 load_services(device, uuids);
5906 uuids = g_key_file_get_string_list(key_file, "General", "GATTServices",
5909 load_services(device, uuids);
5914 /* Remove old entries so they are not loaded again */
5915 g_key_file_remove_key(key_file, "General", "SDPServices", NULL);
5916 g_key_file_remove_key(key_file, "General", "GATTServices", NULL);
5918 ba2str(btd_adapter_get_address(device->adapter), adapter_addr);
5919 ba2str(&device->bdaddr, device_addr);
5920 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
5923 str = g_key_file_to_data(key_file, &length, NULL);
5924 if (!g_file_set_contents(filename, str, length, &gerr)) {
5925 error("Unable set contents for %s: (%s)", filename,
5931 store_device_info(device);
5934 static void load_info(struct btd_device *device, const char *local,
5935 const char *peer, GKeyFile *key_file)
5937 GError *gerr = NULL;
5939 gboolean store_needed = FALSE;
5941 gboolean wake_allowed;
5943 int source, vendor, product, version;
5945 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5946 gboolean svc_change_regd;
5947 char buf[DEV_MAX_MANUFACTURER_DATA_LEN] = { 0, };
5949 /* Load device name from storage info file, if that fails fall back to
5952 str = g_key_file_get_string(key_file, "General", "Name", NULL);
5954 str = load_cached_name(device, local, peer);
5956 store_needed = TRUE;
5960 strcpy(device->name, str);
5965 device->alias = g_key_file_get_string(key_file, "General", "Alias",
5969 str = g_key_file_get_string(key_file, "General", "Class", NULL);
5973 if (sscanf(str, "%x", &class) == 1)
5974 device->class = class;
5978 /* Load appearance */
5979 str = g_key_file_get_string(key_file, "General", "Appearance", NULL);
5981 device->appearance = strtol(str, NULL, 16);
5985 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5986 /* Load RPA Resolution Support value */
5987 device->rpa_res_support = g_key_file_get_integer(key_file,
5988 "General", "RPAResSupport", NULL);
5990 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerDataLen", NULL);
5992 device->manufacturer_data_len = strtol(str, NULL, 10);
5995 if (0 > device->manufacturer_data_len) {
5996 error("Invalid manufacturer_data_len: %d",
5997 device->manufacturer_data_len);
5998 device->manufacturer_data_len = 0;
6001 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerData", NULL);
6003 if (device->manufacturer_data_len < DEV_MAX_MANUFACTURER_DATA_LEN) {
6004 load_manufacturer_data_2digit(str,
6005 device->manufacturer_data_len, buf);
6006 device->manufacturer_data = g_memdup(buf,
6007 device->manufacturer_data_len);
6013 str = g_key_file_get_string(key_file, "General", "IdentityAddress",
6017 device->rpa = g_malloc0(sizeof(bdaddr_t));
6018 bacpy(device->rpa, &device->bdaddr);
6019 str2ba(str, &device->bdaddr);
6024 /* Load device technology */
6025 techno = g_key_file_get_string_list(key_file, "General",
6026 "SupportedTechnologies", NULL, NULL);
6030 for (t = techno; *t; t++) {
6031 if (g_str_equal(*t, "BR/EDR"))
6032 device->bredr = true;
6033 else if (g_str_equal(*t, "LE"))
6036 error("Unknown device technology");
6040 device->bdaddr_type = BDADDR_BREDR;
6042 str = g_key_file_get_string(key_file, "General",
6043 "AddressType", NULL);
6045 if (str && g_str_equal(str, "public"))
6046 device->bdaddr_type = BDADDR_LE_PUBLIC;
6047 else if (str && g_str_equal(str, "static"))
6048 device->bdaddr_type = BDADDR_LE_RANDOM;
6050 error("Unknown LE device technology");
6054 device->local_csrk = load_csrk(key_file, "LocalSignatureKey");
6055 device->remote_csrk = load_csrk(key_file, "RemoteSignatureKey");
6062 device->trusted = g_key_file_get_boolean(key_file, "General",
6065 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6066 /* Load Trusted Profiles*/
6067 int trusted_profiles = g_key_file_get_integer(key_file, "General",
6068 "TrustedProfiles", NULL);
6069 DBG("Loading TrustedProfiles %d", trusted_profiles);
6070 device->trusted_profiles.pbap = ((trusted_profiles &
6071 (PROFILE_SUPPORTED << PBAP_SHIFT_OFFSET)) >> PBAP_SHIFT_OFFSET);
6072 device->trusted_profiles.map = ((trusted_profiles &
6073 (PROFILE_SUPPORTED << MAP_SHIFT_OFFSET)) >> MAP_SHIFT_OFFSET);
6074 device->trusted_profiles.sap = ((trusted_profiles &
6075 (PROFILE_SUPPORTED << SAP_SHIFT_OFFSET)) >> SAP_SHIFT_OFFSET);
6076 device->trusted_profiles.hfp_hs = ((trusted_profiles &
6077 (PROFILE_SUPPORTED << HFP_HS_SHIFT_OFFSET)) >> HFP_HS_SHIFT_OFFSET);
6078 device->trusted_profiles.a2dp = ((trusted_profiles &
6079 (PROFILE_SUPPORTED << A2DP_SHIFT_OFFSET)) >> A2DP_SHIFT_OFFSET);
6083 /* Load device blocked */
6084 blocked = g_key_file_get_boolean(key_file, "General", "Blocked", NULL);
6086 device_block(device, FALSE);
6088 /* Load device profile list */
6089 uuids = g_key_file_get_string_list(key_file, "General", "Services",
6092 load_services(device, uuids);
6094 /* Discovered services restored from storage */
6095 device->bredr_state.svc_resolved = true;
6098 /* Load device id */
6099 source = g_key_file_get_integer(key_file, "DeviceID", "Source", NULL);
6101 vendor = g_key_file_get_integer(key_file, "DeviceID",
6104 product = g_key_file_get_integer(key_file, "DeviceID",
6107 version = g_key_file_get_integer(key_file, "DeviceID",
6110 btd_device_set_pnpid(device, source, vendor, product, version);
6113 /* Wake allowed is only configured and stored if user changed it.
6114 * Otherwise, we enable if profile supports it.
6116 wake_allowed = g_key_file_get_boolean(key_file, "General",
6117 "WakeAllowed", &gerr);
6119 device_set_wake_override(device, wake_allowed);
6125 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6126 /* Load Service changed Registered flag */
6127 svc_change_regd = g_key_file_get_boolean(key_file, "Att",
6128 "SvcChangeRegd", NULL);
6130 bt_att_set_svc_changed_indication_registered(device->att,
6135 store_device_info(device);
6138 static void load_att_info(struct btd_device *device, const char *local,
6141 char filename[PATH_MAX];
6144 GError *gerr = NULL;
6145 char *prim_uuid, *str;
6146 char **groups, **handle, *service_uuid;
6147 struct gatt_primary *prim;
6152 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", local,
6155 /* Check if attributes file exists */
6156 if (stat(filename, &st) < 0)
6159 key_file = g_key_file_new();
6160 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
6161 error("Unable to load key file from %s: (%s)", filename,
6165 groups = g_key_file_get_groups(key_file, NULL);
6167 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
6168 prim_uuid = bt_uuid2string(&uuid);
6170 for (handle = groups; *handle; handle++) {
6174 str = g_key_file_get_string(key_file, *handle, "UUID", NULL);
6178 uuid_ok = g_str_equal(str, prim_uuid);
6184 str = g_key_file_get_string(key_file, *handle, "Value", NULL);
6188 end = g_key_file_get_integer(key_file, *handle,
6189 "EndGroupHandle", NULL);
6195 prim = g_new0(struct gatt_primary, 1);
6196 prim->range.start = atoi(*handle);
6197 prim->range.end = end;
6199 switch (strlen(str)) {
6201 uuid.type = SDP_UUID16;
6202 sscanf(str, "%04hx", &uuid.value.uuid16);
6205 uuid.type = SDP_UUID32;
6206 sscanf(str, "%08x", &uuid.value.uuid32);
6209 uuid.type = SDP_UUID128;
6210 memset(tmp, 0, sizeof(tmp));
6211 for (i = 0; i < 16; i++) {
6212 memcpy(tmp, str + (i * 2), 2);
6213 uuid.value.uuid128.data[i] =
6214 (uint8_t) strtol(tmp, NULL, 16);
6223 service_uuid = bt_uuid2string(&uuid);
6224 memcpy(prim->uuid, service_uuid, MAX_LEN_UUID_STR);
6228 device->primaries = g_slist_append(device->primaries, prim);
6232 g_key_file_free(key_file);
6236 static void device_register_primaries(struct btd_device *device,
6237 GSList *prim_list, int psm)
6239 device->primaries = g_slist_concat(device->primaries, prim_list);
6242 static void add_primary(struct gatt_db_attribute *attr, void *user_data)
6244 GSList **new_services = user_data;
6245 struct gatt_primary *prim;
6248 prim = g_new0(struct gatt_primary, 1);
6250 DBG("Failed to allocate gatt_primary structure");
6254 gatt_db_attribute_get_service_handles(attr, &prim->range.start,
6256 gatt_db_attribute_get_service_uuid(attr, &uuid);
6257 bt_uuid_to_string(&uuid, prim->uuid, sizeof(prim->uuid));
6259 *new_services = g_slist_append(*new_services, prim);
6262 static void load_desc_value(struct gatt_db_attribute *attrib,
6263 int err, void *user_data)
6266 warn("loading descriptor value to db failed");
6269 static ssize_t str2val(const char *str, uint8_t *val, size_t len)
6271 const char *pos = str;
6274 for (i = 0; i < len; i++) {
6275 if (sscanf(pos, "%2hhx", &val[i]) != 1)
6283 static int load_desc(char *handle, char *value,
6284 struct gatt_db_attribute *service)
6286 char uuid_str[MAX_LEN_UUID_STR];
6287 struct gatt_db_attribute *att;
6288 uint16_t handle_int;
6290 bt_uuid_t uuid, ext_uuid;
6292 if (sscanf(handle, "%04hx", &handle_int) != 1)
6295 /* Check if there is any value stored, otherwise it is just the UUID */
6296 if (sscanf(value, "%04hx:%s", &val, uuid_str) != 2) {
6297 if (sscanf(value, "%s", uuid_str) != 1)
6302 DBG("loading descriptor handle: 0x%04x, value: 0x%04x, value uuid: %s",
6303 handle_int, val, uuid_str);
6305 bt_string_to_uuid(&uuid, uuid_str);
6306 bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
6308 /* If it is CEP then it must contain the value */
6309 if (!bt_uuid_cmp(&uuid, &ext_uuid) && !val) {
6310 warn("cannot load CEP descriptor without value");
6314 att = gatt_db_service_insert_descriptor(service, handle_int, &uuid,
6315 0, NULL, NULL, NULL);
6316 if (!att || gatt_db_attribute_get_handle(att) != handle_int) {
6317 warn("loading descriptor to db failed");
6322 if (!gatt_db_attribute_write(att, 0, (uint8_t *)&val,
6323 sizeof(val), 0, NULL,
6324 load_desc_value, NULL))
6331 static int load_chrc(char *handle, char *value,
6332 struct gatt_db_attribute *service)
6334 uint16_t properties, value_handle, handle_int;
6335 char uuid_str[MAX_LEN_UUID_STR];
6336 struct gatt_db_attribute *att;
6342 if (sscanf(handle, "%04hx", &handle_int) != 1)
6345 /* Check if there is any value stored */
6346 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%32s:%s",
6347 &value_handle, &properties, val_str, uuid_str) != 4) {
6348 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%s",
6349 &value_handle, &properties, uuid_str) != 3)
6353 val_len = str2val(val_str, val, sizeof(val));
6355 bt_string_to_uuid(&uuid, uuid_str);
6357 /* Log debug message. */
6358 DBG("loading characteristic handle: 0x%04x, value handle: 0x%04x,"
6359 " properties 0x%04x value: %s uuid: %s",
6360 handle_int, value_handle, properties,
6361 val_len ? val_str : "", uuid_str);
6363 att = gatt_db_service_insert_characteristic(service, value_handle,
6364 &uuid, 0, properties,
6366 if (!att || gatt_db_attribute_get_handle(att) != value_handle) {
6367 warn("loading characteristic to db failed");
6372 if (!gatt_db_attribute_write(att, 0, val, val_len, 0, NULL,
6373 load_desc_value, NULL))
6380 static int load_incl(struct gatt_db *db, char *handle, char *value,
6381 struct gatt_db_attribute *service)
6383 char uuid_str[MAX_LEN_UUID_STR];
6384 struct gatt_db_attribute *att;
6385 uint16_t start, end;
6387 if (sscanf(handle, "%04hx", &start) != 1)
6390 if (sscanf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", &start, &end,
6394 /* Log debug message. */
6395 DBG("loading included service: 0x%04x, end: 0x%04x, uuid: %s", start,
6398 att = gatt_db_get_attribute(db, start);
6400 warn("loading included service to db failed - no such service");
6404 att = gatt_db_service_add_included(service, att);
6406 warn("loading included service to db failed");
6413 static int load_service(struct gatt_db *db, char *handle, char *value)
6415 struct gatt_db_attribute *att;
6416 uint16_t start, end;
6417 char type[MAX_LEN_UUID_STR], uuid_str[MAX_LEN_UUID_STR];
6421 if (sscanf(handle, "%04hx", &start) != 1)
6424 if (sscanf(value, "%[^:]:%04hx:%s", type, &end, uuid_str) != 3)
6427 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR))
6429 else if (g_str_equal(type, GATT_SND_SVC_UUID_STR))
6434 bt_string_to_uuid(&uuid, uuid_str);
6436 /* Log debug message. */
6437 DBG("loading service: 0x%04x, end: 0x%04x, uuid: %s",
6438 start, end, uuid_str);
6440 att = gatt_db_insert_service(db, start, &uuid, primary,
6443 error("Unable load service into db!");
6450 static int load_gatt_db_impl(GKeyFile *key_file, char **keys,
6453 struct gatt_db_attribute *current_service;
6454 char **handle, *value, type[MAX_LEN_UUID_STR];
6457 /* first load service definitions */
6458 for (handle = keys; *handle; handle++) {
6459 value = g_key_file_get_string(key_file, "Attributes", *handle,
6462 if (sscanf(value, "%[^:]:", type) != 1) {
6463 warn("Missing Type in attribute definition");
6468 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
6469 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
6470 ret = load_service(db, *handle, value);
6480 current_service = NULL;
6481 /* then fill them with data*/
6482 for (handle = keys; *handle; handle++) {
6483 value = g_key_file_get_string(key_file, "Attributes", *handle,
6486 if (sscanf(value, "%[^:]:", type) != 1) {
6487 warn("Missing Type in attribute definition");
6492 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
6493 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
6495 uint16_t start, end;
6498 char uuid_str[MAX_LEN_UUID_STR];
6500 if (sscanf(*handle, "%04hx", &tmp) != 1) {
6501 warn("Unable to parse attribute handle");
6506 if (current_service)
6507 gatt_db_service_set_active(current_service,
6510 current_service = gatt_db_get_attribute(db, tmp);
6512 gatt_db_attribute_get_service_data(current_service,
6516 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6517 } else if (g_str_equal(type, GATT_INCLUDE_UUID_STR)) {
6518 ret = load_incl(db, *handle, value, current_service);
6519 } else if (g_str_equal(type, GATT_CHARAC_UUID_STR)) {
6520 ret = load_chrc(*handle, value, current_service);
6522 ret = load_desc(*handle, value, current_service);
6532 if (current_service)
6533 gatt_db_service_set_active(current_service, true);
6538 static void load_gatt_db(struct btd_device *device, const char *local,
6541 char **keys, filename[PATH_MAX];
6543 GError *gerr = NULL;
6545 if (!gatt_cache_is_enabled(device))
6548 DBG("Restoring %s gatt database from file", peer);
6550 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
6552 key_file = g_key_file_new();
6553 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
6554 error("Unable to load key file from %s: (%s)", filename,
6558 keys = g_key_file_get_keys(key_file, "Attributes", NULL, NULL);
6561 warn("No cache for %s", peer);
6562 g_key_file_free(key_file);
6566 if (load_gatt_db_impl(key_file, keys, device->db))
6567 warn("Unable to load gatt db from file for %s", peer);
6570 g_key_file_free(key_file);
6572 g_slist_free_full(device->primaries, g_free);
6573 device->primaries = NULL;
6574 gatt_db_foreach_service(device->db, NULL, add_primary,
6575 &device->primaries);
6578 static void device_add_uuids(struct btd_device *device, GSList *uuids)
6581 bool changed = false;
6583 for (l = uuids; l != NULL; l = g_slist_next(l)) {
6584 GSList *match = g_slist_find_custom(device->uuids, l->data,
6590 device->uuids = g_slist_insert_sorted(device->uuids,
6596 g_dbus_emit_property_changed(dbus_conn, device->path,
6597 DEVICE_INTERFACE, "UUIDs");
6600 static bool device_match_profile(struct btd_device *device,
6601 struct btd_profile *profile,
6604 if (profile->remote_uuid == NULL)
6607 if (g_slist_find_custom(uuids, profile->remote_uuid,
6608 bt_uuid_strcmp) == NULL) {
6609 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
6610 if (strcmp(profile->name, "hid-device") == 0)
6619 static void add_gatt_service(struct gatt_db_attribute *attr, void *user_data)
6621 struct btd_device *device = user_data;
6622 struct btd_service *service;
6623 struct btd_profile *profile;
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 /* Check if service was already probed */
6632 l = find_service_with_uuid(device->services, uuid_str);
6636 /* Add UUID and probe service */
6637 btd_device_add_uuid(device, uuid_str);
6639 /* Check if service was probed */
6640 l = find_service_with_uuid(device->services, uuid_str);
6645 /* Mark service as active to skip discovering it again */
6646 gatt_db_service_set_active(attr, true);
6649 profile = btd_service_get_profile(service);
6651 /* Claim attributes of internal profiles */
6652 if (!profile->external) {
6653 /* Mark the service as claimed by the existing profile. */
6654 gatt_db_service_set_claimed(attr, true);
6657 /* Notify driver about the new connection */
6658 service_accept(service);
6661 static void device_add_gatt_services(struct btd_device *device)
6665 ba2str(&device->bdaddr, addr);
6667 if (device->blocked) {
6668 DBG("Skipping profiles for blocked device %s", addr);
6672 gatt_db_foreach_service(device->db, NULL, add_gatt_service, device);
6675 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6676 static void accept_gatt_service(struct gatt_db_attribute *attr, void *user_data)
6678 struct btd_device *device = user_data;
6681 char uuid_str[MAX_LEN_UUID_STR];
6683 gatt_db_attribute_get_service_uuid(attr, &uuid);
6684 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6686 l = find_service_with_uuid(device->services, uuid_str);
6690 service_accept(l->data);
6694 static void device_accept_gatt_profiles(struct btd_device *device)
6696 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6699 for (l = device->services; l != NULL; l = g_slist_next(l))
6700 service_accept(l->data);
6702 gatt_db_foreach_service(device->db, NULL, accept_gatt_service, device);
6706 static void device_remove_gatt_service(struct btd_device *device,
6707 struct gatt_db_attribute *attr)
6709 struct btd_service *service;
6711 char uuid_str[MAX_LEN_UUID_STR];
6714 gatt_db_attribute_get_service_uuid(attr, &uuid);
6715 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6717 l = find_service_with_uuid(device->services, uuid_str);
6722 device->services = g_slist_delete_link(device->services, l);
6723 device->pending = g_slist_remove(device->pending, service);
6724 service_remove(service);
6727 static gboolean gatt_services_changed(gpointer user_data)
6729 struct btd_device *device = user_data;
6731 store_gatt_db(device);
6736 static void gatt_service_added(struct gatt_db_attribute *attr, void *user_data)
6738 struct btd_device *device = user_data;
6739 GSList *new_service = NULL;
6740 uint16_t start, end;
6742 if (!bt_gatt_client_is_ready(device->client))
6745 gatt_db_attribute_get_service_data(attr, &start, &end, NULL, NULL);
6747 DBG("start: 0x%04x, end: 0x%04x", start, end);
6750 * TODO: Remove the primaries list entirely once all profiles use
6753 add_primary(attr, &new_service);
6757 device_register_primaries(device, new_service, -1);
6759 add_gatt_service(attr, device);
6761 btd_gatt_client_service_added(device->client_dbus, attr);
6763 gatt_services_changed(device);
6766 static gint prim_attr_cmp(gconstpointer a, gconstpointer b)
6768 const struct gatt_primary *prim = a;
6769 const struct gatt_db_attribute *attr = b;
6770 uint16_t start, end;
6772 gatt_db_attribute_get_service_handles(attr, &start, &end);
6774 return !(prim->range.start == start && prim->range.end == end);
6777 static gint prim_uuid_cmp(gconstpointer a, gconstpointer b)
6779 const struct gatt_primary *prim = a;
6780 const char *uuid = b;
6782 return bt_uuid_strcmp(prim->uuid, uuid);
6785 static void gatt_service_removed(struct gatt_db_attribute *attr,
6788 struct btd_device *device = user_data;
6790 struct gatt_primary *prim;
6791 uint16_t start, end;
6794 * NOTE: shared/gatt-client clears the database in case of failure. This
6795 * triggers the service_removed callback for all affected services.
6796 * Hence, this function will be called in the following cases:
6798 * 1. When a GATT service gets removed due to "Service Changed".
6800 * 2. When a GATT service gets removed when the database get cleared
6801 * upon disconnection with a non-bonded device.
6803 * 3. When a GATT service gets removed when the database get cleared
6804 * by shared/gatt-client when its initialization procedure fails,
6805 * e.g. due to an ATT protocol error or an unexpected disconnect.
6806 * In this case the gatt-client will not be ready.
6809 gatt_db_attribute_get_service_handles(attr, &start, &end);
6811 DBG("start: 0x%04x, end: 0x%04x", start, end);
6813 /* Remove the corresponding gatt_primary */
6814 l = g_slist_find_custom(device->primaries, attr, prim_attr_cmp);
6819 device->primaries = g_slist_delete_link(device->primaries, l);
6822 * Remove the corresponding UUIDs entry and profile, only if this is
6823 * the last service with this UUID.
6825 l = g_slist_find_custom(device->uuids, prim->uuid, bt_uuid_strcmp);
6827 if (l && !g_slist_find_custom(device->primaries, prim->uuid,
6830 * If this happend since the db was cleared for a non-bonded
6831 * device, then don't remove the btd_service just yet. We do
6832 * this so that we can avoid re-probing the profile if the same
6833 * GATT service is found on the device on re-connection.
6834 * However, if the device is marked as temporary, then we
6837 if (device->client || device->temporary == TRUE)
6838 device_remove_gatt_service(device, attr);
6841 device->uuids = g_slist_delete_link(device->uuids, l);
6842 g_dbus_emit_property_changed(dbus_conn, device->path,
6843 DEVICE_INTERFACE, "UUIDs");
6848 store_device_info(device);
6850 btd_gatt_client_service_removed(device->client_dbus, attr);
6852 gatt_services_changed(device);
6855 static struct btd_device *device_new(struct btd_adapter *adapter,
6856 const char *address)
6859 struct btd_device *device;
6860 const char *adapter_path = adapter_get_path(adapter);
6862 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6863 DBG("address %s", address);
6866 device = g_try_malloc0(sizeof(struct btd_device));
6870 device->tx_power = 127;
6872 device->db = gatt_db_new();
6878 memset(device->ad_flags, INVALID_FLAGS, sizeof(device->ad_flags));
6880 device->ad = bt_ad_new();
6882 device_free(device);
6886 address_up = g_ascii_strup(address, -1);
6887 device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
6888 g_strdelimit(device->path, ":", '_');
6891 str2ba(address, &device->bdaddr);
6893 device->client_dbus = btd_gatt_client_new(device);
6894 if (!device->client_dbus) {
6895 error("Failed to create btd_gatt_client");
6896 device_free(device);
6900 DBG("Creating device %s", device->path);
6902 if (g_dbus_register_interface(dbus_conn,
6903 device->path, DEVICE_INTERFACE,
6904 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6905 device_methods, device_signals,
6907 device_methods, NULL,
6909 device_properties, device,
6910 device_free) == FALSE) {
6911 error("Unable to register device interface for %s", address);
6912 device_free(device);
6916 device->adapter = adapter;
6917 device->temporary = true;
6919 device->db_id = gatt_db_register(device->db, gatt_service_added,
6920 gatt_service_removed, device, NULL);
6922 device->refresh_discovery = btd_opts.refresh_discovery;
6924 return btd_device_ref(device);
6927 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6928 void device_print_addr(struct btd_device *dev)
6933 ba2str(&dev->bdaddr, ida);
6936 ba2str(dev->rpa, rpa);
6938 DBG("IDA %s [%d] : RPA [%s], BREDR [%d], LE [%d]",
6939 ida, dev->bdaddr_type, rpa,
6940 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
6942 DBG("ADDR %s [%d] : BREDR [%d], LE [%d]",
6943 ida, dev->bdaddr_type,
6944 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
6949 struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
6950 const char *address, GKeyFile *key_file)
6952 struct btd_device *device;
6953 const char *src_dir;
6955 DBG("address %s", address);
6957 device = device_new(adapter, address);
6961 convert_info(device, key_file);
6963 src_dir = btd_adapter_get_storage_dir(adapter);
6965 load_info(device, src_dir, address, key_file);
6966 load_att_info(device, src_dir, address);
6971 struct btd_device *device_create(struct btd_adapter *adapter,
6972 const bdaddr_t *bdaddr, uint8_t bdaddr_type)
6974 struct btd_device *device;
6977 const char *storage_dir;
6979 ba2str(bdaddr, dst);
6982 device = device_new(adapter, dst);
6986 device->bdaddr_type = bdaddr_type;
6988 if (bdaddr_type == BDADDR_BREDR)
6989 device->bredr = true;
6993 storage_dir = btd_adapter_get_storage_dir(adapter);
6994 str = load_cached_name(device, storage_dir, dst);
6996 strcpy(device->name, str);
7000 load_cached_name_resolve(device, storage_dir, dst);
7005 char *btd_device_get_storage_path(struct btd_device *device,
7006 const char *filename)
7010 if (device_address_is_private(device)) {
7011 warn("Refusing storage path for private addressed device %s",
7016 ba2str(&device->bdaddr, dstaddr);
7018 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7020 ba2str(device->rpa, dstaddr);
7024 return g_strdup_printf(STORAGEDIR "/%s/%s",
7025 btd_adapter_get_storage_dir(device->adapter),
7028 return g_strdup_printf(STORAGEDIR "/%s/%s/%s",
7029 btd_adapter_get_storage_dir(device->adapter),
7033 void btd_device_device_set_name(struct btd_device *device, const char *name)
7035 if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
7038 DBG("%s %s", device->path, name);
7040 strncpy(device->name, name, MAX_NAME_LENGTH);
7042 store_device_info(device);
7044 g_dbus_emit_property_changed(dbus_conn, device->path,
7045 DEVICE_INTERFACE, "Name");
7047 if (device->alias != NULL)
7050 g_dbus_emit_property_changed(dbus_conn, device->path,
7051 DEVICE_INTERFACE, "Alias");
7054 void device_get_name(struct btd_device *device, char *name, size_t len)
7056 if (name != NULL && len > 0) {
7057 strncpy(name, device->name, len - 1);
7058 name[len - 1] = '\0';
7062 bool device_name_known(struct btd_device *device)
7064 return device->name[0] != '\0';
7067 bool device_is_name_resolve_allowed(struct btd_device *device)
7069 struct timespec now;
7074 clock_gettime(CLOCK_MONOTONIC, &now);
7076 /* If now < failed_time, it means the clock has somehow turned back,
7077 * possibly because of system restart. Allow name request in this case.
7079 return now.tv_sec < device->name_resolve_failed_time ||
7080 now.tv_sec >= device->name_resolve_failed_time +
7081 btd_opts.name_request_retry_delay;
7084 void device_name_resolve_fail(struct btd_device *device)
7086 struct timespec now;
7091 clock_gettime(CLOCK_MONOTONIC, &now);
7092 device->name_resolve_failed_time = now.tv_sec;
7093 device_store_cached_name_resolve(device);
7096 void device_set_class(struct btd_device *device, uint32_t class)
7098 if (device->class == class)
7101 DBG("%s 0x%06X", device->path, class);
7103 device->class = class;
7105 store_device_info(device);
7107 g_dbus_emit_property_changed(dbus_conn, device->path,
7108 DEVICE_INTERFACE, "Class");
7109 g_dbus_emit_property_changed(dbus_conn, device->path,
7110 DEVICE_INTERFACE, "Icon");
7113 void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr,
7114 uint8_t bdaddr_type)
7116 bool auto_connect = device->auto_connect;
7118 if (!bacmp(bdaddr, &device->bdaddr) &&
7119 bdaddr_type == device->bdaddr_type)
7122 /* Since this function is only used for LE SMP Identity
7123 * Resolving purposes we can now assume LE is supported.
7127 /* Remove old address from accept/auto-connect list since its address
7131 device_set_auto_connect(device, FALSE);
7133 bacpy(&device->bdaddr, bdaddr);
7134 device->bdaddr_type = bdaddr_type;
7136 store_device_info(device);
7138 g_dbus_emit_property_changed(dbus_conn, device->path,
7139 DEVICE_INTERFACE, "Address");
7140 g_dbus_emit_property_changed(dbus_conn, device->path,
7141 DEVICE_INTERFACE, "AddressType");
7144 device_set_auto_connect(device, TRUE);
7147 void device_set_bredr_support(struct btd_device *device)
7149 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7153 ba2str(device->rpa, addr_str);
7154 error("Cannot set bredr support to RPA device [%s]", addr_str);
7158 if (device->bdaddr_type == BDADDR_LE_RANDOM) {
7159 ba2str(&device->bdaddr, addr_str);
7160 error("Cannot set bredr support to LE random device [%s]",
7169 device->bredr = true;
7170 store_device_info(device);
7173 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7174 void device_set_rpa(struct btd_device *device, const bdaddr_t *rpa)
7176 if (device->rpa == NULL) {
7177 device->rpa = g_malloc0(sizeof(bdaddr_t));
7178 bacpy(device->rpa, rpa);
7180 error("RPA is already set");
7183 void device_set_irk_value(struct btd_device *device, const uint8_t *val)
7185 memcpy(&device->irk_val, val, sizeof(device->irk_val));
7189 void device_set_le_support(struct btd_device *device, uint8_t bdaddr_type)
7195 device->bdaddr_type = bdaddr_type;
7197 store_device_info(device);
7200 static bool device_disappeared(gpointer user_data)
7202 struct btd_device *dev = user_data;
7204 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7205 if (dev->le_state.connected) {
7206 DBG("GATT connection exists, don't remove the device");
7211 dev->temporary_timer = 0;
7213 btd_adapter_remove_device(dev->adapter, dev);
7218 static void set_temporary_timer(struct btd_device *dev, unsigned int timeout)
7220 clear_temporary_timer(dev);
7225 dev->temporary_timer = timeout_add_seconds(timeout, device_disappeared,
7229 void device_update_last_seen(struct btd_device *device, uint8_t bdaddr_type)
7231 if (bdaddr_type == BDADDR_BREDR)
7232 device->bredr_seen = time(NULL);
7234 device->le_seen = time(NULL);
7236 if (!device_is_temporary(device))
7239 /* Restart temporary timer */
7240 set_temporary_timer(device, btd_opts.tmpto);
7243 /* It is possible that we have two device objects for the same device in
7244 * case it has first been discovered over BR/EDR and has a private
7245 * address when discovered over LE for the first time. In such a case we
7246 * need to inherit critical values from the duplicate so that we don't
7247 * ovewrite them when writing to storage. The next time bluetoothd
7248 * starts the device will show up as a single instance.
7250 void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup)
7256 dev->bredr = dup->bredr;
7258 dev->trusted = dup->trusted;
7259 dev->blocked = dup->blocked;
7261 for (l = dup->uuids; l; l = g_slist_next(l))
7262 dev->uuids = g_slist_append(dev->uuids, g_strdup(l->data));
7264 if (dev->name[0] == '\0')
7265 strcpy(dev->name, dup->name);
7268 dev->alias = g_strdup(dup->alias);
7270 dev->class = dup->class;
7272 dev->vendor_src = dup->vendor_src;
7273 dev->vendor = dup->vendor;
7274 dev->product = dup->product;
7275 dev->version = dup->version;
7278 uint32_t btd_device_get_class(struct btd_device *device)
7280 return device->class;
7283 uint16_t btd_device_get_vendor(struct btd_device *device)
7285 return device->vendor;
7288 uint16_t btd_device_get_vendor_src(struct btd_device *device)
7290 return device->vendor_src;
7293 uint16_t btd_device_get_product(struct btd_device *device)
7295 return device->product;
7298 uint16_t btd_device_get_version(struct btd_device *device)
7300 return device->version;
7303 static void delete_folder_tree(const char *dirname)
7306 struct dirent *entry;
7307 char filename[PATH_MAX];
7309 dir = opendir(dirname);
7313 while ((entry = readdir(dir)) != NULL) {
7314 if (g_str_equal(entry->d_name, ".") ||
7315 g_str_equal(entry->d_name, ".."))
7318 if (entry->d_type == DT_UNKNOWN)
7319 entry->d_type = util_get_dt(dirname, entry->d_name);
7321 snprintf(filename, PATH_MAX, "%s/%s", dirname, entry->d_name);
7323 if (entry->d_type == DT_DIR)
7324 delete_folder_tree(filename);
7333 void device_remove_bonding(struct btd_device *device, uint8_t bdaddr_type)
7335 if (bdaddr_type == BDADDR_BREDR)
7336 device->bredr_state.bonded = false;
7338 device->le_state.bonded = false;
7340 if (!device->bredr_state.bonded && !device->le_state.bonded)
7341 btd_device_set_temporary(device, true);
7343 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
7347 static void device_remove_stored(struct btd_device *device)
7349 char device_addr[18];
7350 char filename[PATH_MAX];
7352 GError *gerr = NULL;
7356 if (device->bredr_state.bonded)
7357 device_remove_bonding(device, BDADDR_BREDR);
7359 if (device->le_state.bonded)
7360 device_remove_bonding(device, device->bdaddr_type);
7362 device->bredr_state.paired = false;
7363 device->le_state.paired = false;
7365 if (device->blocked)
7366 device_unblock(device, TRUE, FALSE);
7368 ba2str(&device->bdaddr, device_addr);
7370 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7372 ba2str(device->rpa, device_addr);
7375 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s",
7376 btd_adapter_get_storage_dir(device->adapter),
7378 delete_folder_tree(filename);
7380 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
7381 btd_adapter_get_storage_dir(device->adapter),
7384 key_file = g_key_file_new();
7385 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
7387 g_key_file_free(key_file);
7390 g_key_file_remove_group(key_file, "ServiceRecords", NULL);
7391 g_key_file_remove_group(key_file, "Attributes", NULL);
7393 data = g_key_file_to_data(key_file, &length, NULL);
7395 create_file(filename, 0600);
7396 if (!g_file_set_contents(filename, data, length, &gerr)) {
7397 error("Unable set contents for %s: (%s)", filename,
7404 g_key_file_free(key_file);
7407 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7408 void device_unpair(struct btd_device *device, gboolean remove_stored)
7411 DBG("Unpairing device %s", device->path);
7413 if (device->bonding) {
7416 if (device->bredr_state.connected)
7417 status = MGMT_STATUS_DISCONNECTED;
7419 status = MGMT_STATUS_CONNECT_FAILED;
7421 device_cancel_bonding(device, status);
7425 browse_request_cancel(device->browse);
7428 // while (device->services != NULL) {
7429 // struct btd_service *service = device->services->data;
7431 // device->services = g_slist_remove(device->services, service);
7432 // service_remove(service);
7435 g_slist_free(device->pending);
7436 device->pending = NULL;
7438 if (btd_device_is_connected(device))
7439 disconnect_all(device);
7441 if (device->store_id > 0) {
7442 g_source_remove(device->store_id);
7443 device->store_id = 0;
7446 store_device_info_cb(device);
7450 device_remove_stored(device);
7452 gatt_db_clear(device->db);
7455 bacpy(&device->bdaddr, device->rpa);
7456 device->bdaddr_type = BDADDR_LE_RANDOM;
7458 g_free(device->rpa);
7462 device->bredr_state.paired = 0;
7463 device->le_state.paired = 0;
7464 device->bredr_state.svc_resolved = false;
7465 device->trusted = false;
7466 device->trusted_profiles.pbap = SHOW_AUTHORIZATION;
7467 device->trusted_profiles.map = SHOW_AUTHORIZATION;
7468 device->trusted_profiles.sap = SHOW_AUTHORIZATION;
7469 if (TIZEN_MODEL_DA) {
7470 device->trusted_profiles.hfp_hs = SHOW_AUTHORIZATION;
7471 device->trusted_profiles.a2dp = SHOW_AUTHORIZATION;
7473 device->trusted_profiles.hfp_hs = SUPPORTED_TRUSTED;
7474 device->trusted_profiles.a2dp = SUPPORTED_TRUSTED;
7476 if (device->alias != NULL) {
7477 /* Remove alias name because
7478 * In UG if we rename and then unpair device and
7479 * initiates connection without scanning then paired
7480 * list will have alias name as first preference is
7481 * given to alias name.
7483 DBG("Freeing device alias name");
7484 g_free(device->alias);
7485 device->alias = NULL;
7487 g_dbus_emit_property_changed(dbus_conn, device->path,
7488 DEVICE_INTERFACE, "Paired");
7489 // btd_device_unref(device);
7493 void device_remove_stored_folder(struct btd_device *device)
7495 const bdaddr_t *src = btd_adapter_get_address(device->adapter);
7496 char adapter_addr[18];
7497 char device_addr[18];
7498 char filename[PATH_MAX];
7500 ba2str(src, adapter_addr);
7501 ba2str(&device->bdaddr, device_addr);
7503 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
7506 delete_folder_tree(filename);
7510 void device_remove(struct btd_device *device, gboolean remove_stored)
7512 DBG("Removing device %s", device->path);
7514 if (device->auto_connect) {
7515 device->disable_auto_connect = TRUE;
7516 device_set_auto_connect(device, FALSE);
7519 if (device->bonding) {
7522 if (device->bredr_state.connected)
7523 status = MGMT_STATUS_DISCONNECTED;
7525 status = MGMT_STATUS_CONNECT_FAILED;
7527 device_cancel_bonding(device, status);
7531 browse_request_cancel(device->browse);
7533 while (device->services != NULL) {
7534 struct btd_service *service = device->services->data;
7536 device->services = g_slist_remove(device->services, service);
7537 service_remove(service);
7540 g_slist_free(device->pending);
7541 device->pending = NULL;
7543 if (btd_device_is_connected(device)) {
7544 if (device->disconn_timer > 0)
7545 timeout_remove(device->disconn_timer);
7546 disconnect_all(device);
7549 clear_temporary_timer(device);
7551 if (device->store_id > 0) {
7552 g_source_remove(device->store_id);
7553 device->store_id = 0;
7556 store_device_info_cb(device);
7560 device_remove_stored(device);
7562 btd_device_unref(device);
7565 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7566 int device_rpa_cmp(gconstpointer a, gconstpointer b)
7568 const struct btd_device *device = a;
7569 const char *address = b;
7575 ba2str(device->rpa, addr);
7577 return strcasecmp(addr, address);
7580 int device_addr_cmp(gconstpointer a, gconstpointer b)
7582 const struct btd_device *device = a;
7583 const bdaddr_t *bdaddr = b;
7585 return bacmp(&device->bdaddr, bdaddr);
7588 int device_rpa_ida_cmp(gconstpointer a, gconstpointer b)
7590 const struct btd_device *device = a;
7591 const char *address = b;
7594 if (!device->rpa || device->le == false)
7597 ba2str(&device->bdaddr, addr);
7598 return strcasecmp(addr, address);
7602 int device_address_cmp(gconstpointer a, gconstpointer b)
7604 const struct btd_device *device = a;
7605 const char *address = b;
7608 ba2str(&device->bdaddr, addr);
7609 return strcasecmp(addr, address);
7612 int device_bdaddr_cmp(gconstpointer a, gconstpointer b)
7614 const struct btd_device *device = a;
7615 const bdaddr_t *bdaddr = b;
7617 return bacmp(&device->bdaddr, bdaddr);
7620 static bool addr_is_public(uint8_t addr_type)
7622 if (addr_type == BDADDR_BREDR || addr_type == BDADDR_LE_PUBLIC)
7628 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7629 int device_addr_type_strict_cmp(gconstpointer a, gconstpointer b)
7631 const struct btd_device *dev = a;
7632 const struct device_addr_type *addr = b;
7635 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
7637 if (addr->bdaddr_type == BDADDR_BREDR) {
7647 if (cmp && dev->rpa && addr->bdaddr_type == BDADDR_LE_RANDOM &&
7648 (addr->bdaddr.b[5] >> 6) == 0x01)
7649 return bacmp(dev->rpa, &addr->bdaddr);
7651 if (addr->bdaddr_type != dev->bdaddr_type)
7658 int device_addr_type_cmp(gconstpointer a, gconstpointer b)
7660 const struct btd_device *dev = a;
7661 const struct device_addr_type *addr = b;
7664 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
7667 * Address matches and both old and new are public addresses
7668 * (doesn't matter whether LE or BR/EDR, then consider this a
7671 if (!cmp && addr_is_public(addr->bdaddr_type) &&
7672 addr_is_public(dev->bdaddr_type))
7673 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7675 if (dev->rpa && addr->bdaddr_type == BDADDR_BREDR) {
7678 ba2str(&dev->bdaddr, addr_str);
7679 DBG("Don't match. LE Only device [%s]", addr_str);
7688 if (addr->bdaddr_type == BDADDR_BREDR) {
7698 if (addr->bdaddr_type != dev->bdaddr_type) {
7699 if (addr->bdaddr_type == dev->conn_bdaddr_type)
7700 return bacmp(&dev->conn_bdaddr, &addr->bdaddr);
7707 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7708 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
7709 void device_change_pkt_type(gpointer data, gpointer user_data)
7711 int pkt_type = (int)user_data;
7712 struct btd_device *device = data;
7713 struct hci_conn_info_req *cr;
7714 set_conn_ptype_cp cp;
7719 /* Change a packet type only for Phone device */
7720 if ((device->class & 0x00001F00) >> 8 != 0x02)
7723 if (!device->bredr_state.connected)
7726 hdev = hci_open_dev(0);
7728 error("Cannot open hdev");
7732 cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
7734 error("Out of memory");
7737 cr->type = ACL_LINK;
7738 bacpy(&cr->bdaddr, &device->bdaddr);
7740 err = ioctl(hdev, HCIGETCONNINFO, cr);
7742 error("Fail to get HCIGETCOINFO");
7744 hci_close_dev(hdev);
7748 cp.handle = cr->conn_info->handle;
7750 cp.pkt_type = cpu_to_le16((uint16_t)pkt_type);
7752 ba2str(&device->bdaddr, addr);
7753 DBG("Handle %d, Addr %s", cp.handle, addr);
7754 DBG("Send Change pkt type request : 0x%X", pkt_type);
7756 if (hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SET_CONN_PTYPE,
7757 SET_CONN_PTYPE_CP_SIZE, &cp) < 0) {
7758 error("hci_send_cmd is failed");
7759 hci_close_dev(hdev);
7763 hci_close_dev(hdev);
7766 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
7769 static gboolean record_has_uuid(const sdp_record_t *rec,
7770 const char *profile_uuid)
7774 for (pat = rec->pattern; pat != NULL; pat = pat->next) {
7778 uuid = bt_uuid2string(pat->data);
7782 ret = strcasecmp(uuid, profile_uuid);
7793 GSList *btd_device_get_uuids(struct btd_device *device)
7795 return device->uuids;
7799 struct btd_device *dev;
7803 static struct btd_service *probe_service(struct btd_device *device,
7804 struct btd_profile *profile,
7808 struct btd_service *service;
7810 if (profile->device_probe == NULL)
7813 if (!device_match_profile(device, profile, uuids))
7816 l = find_service_with_profile(device->services, profile);
7817 /* If the service already exists, return NULL so that it won't be added
7818 * to the device->services.
7823 service = service_create(device, profile);
7825 if (service_probe(service)) {
7826 btd_service_unref(service);
7830 /* Only set auto connect if profile has set the flag and can really
7831 * accept connections.
7833 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
7834 if (profile->auto_connect && profile->accept)
7835 device_set_auto_connect(device, TRUE);
7841 static void dev_probe(struct btd_profile *p, void *user_data)
7843 struct probe_data *d = user_data;
7844 struct btd_service *service;
7846 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7847 if (find_service_with_profile(d->dev->services, p)) {
7848 DBG("%s is already probed.(UUID:%s)", p->name, p->remote_uuid);
7853 service = probe_service(d->dev, p, d->uuids);
7857 d->dev->services = g_slist_append(d->dev->services, service);
7860 void device_probe_profile(gpointer a, gpointer b)
7862 struct btd_device *device = a;
7863 struct btd_profile *profile = b;
7864 struct btd_service *service;
7866 service = probe_service(device, profile, device->uuids);
7870 device->services = g_slist_append(device->services, service);
7872 if (!profile->auto_connect || !device->general_connect)
7875 device->pending = g_slist_append(device->pending, service);
7877 if (g_slist_length(device->pending) == 1)
7878 connect_next(device);
7881 void device_remove_profile(gpointer a, gpointer b)
7883 struct btd_device *device = a;
7884 struct btd_profile *profile = b;
7885 struct btd_service *service;
7888 l = find_service_with_profile(device->services, profile);
7889 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
7891 if (g_strcmp0(profile->local_uuid , HID_DEVICE_UUID) == 0) {
7892 l = find_service_with_uuid(device->services,
7899 if (btd_service_get_state(service) ==
7900 BTD_SERVICE_STATE_CONNECTED) {
7902 err = btd_service_disconnect(service);
7904 error("error: %s", strerror(-err));
7915 device->services = g_slist_delete_link(device->services, l);
7916 device->pending = g_slist_remove(device->pending, service);
7917 service_remove(service);
7920 void device_probe_profiles(struct btd_device *device, GSList *uuids)
7922 struct probe_data d = { device, uuids };
7925 ba2str(&device->bdaddr, addr);
7927 if (device->blocked) {
7928 DBG("Skipping profiles for blocked device %s", addr);
7932 DBG("Probing profiles for device %s", addr);
7934 btd_profile_foreach(dev_probe, &d);
7937 device_add_uuids(device, uuids);
7940 static void store_sdp_record(GKeyFile *key_file, sdp_record_t *rec)
7942 char handle_str[11];
7947 sprintf(handle_str, "0x%8.8X", rec->handle);
7949 if (sdp_gen_record_pdu(rec, &buf) < 0)
7952 size = buf.data_size;
7954 str = g_malloc0(size*2+1);
7956 for (i = 0; i < size; i++)
7957 sprintf(str + (i * 2), "%02X", buf.data[i]);
7959 g_key_file_set_string(key_file, "ServiceRecords", handle_str, str);
7965 static void store_primaries_from_sdp_record(GKeyFile *key_file,
7969 char *att_uuid, *prim_uuid;
7970 uint16_t start = 0, end = 0, psm = 0;
7971 char handle[6], uuid_str[33];
7974 sdp_uuid16_create(&uuid, ATT_UUID);
7975 att_uuid = bt_uuid2string(&uuid);
7977 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
7978 prim_uuid = bt_uuid2string(&uuid);
7980 if (!record_has_uuid(rec, att_uuid))
7983 if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
7986 sprintf(handle, "%hu", start);
7987 switch (uuid.type) {
7989 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
7992 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
7995 for (i = 0; i < 16; i++)
7996 sprintf(uuid_str + (i * 2), "%2.2X",
7997 uuid.value.uuid128.data[i]);
8003 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
8004 g_key_file_set_string(key_file, handle, "Value", uuid_str);
8005 g_key_file_set_integer(key_file, handle, "EndGroupHandle", end);
8012 static int rec_cmp(const void *a, const void *b)
8014 const sdp_record_t *r1 = a;
8015 const sdp_record_t *r2 = b;
8017 return r1->handle - r2->handle;
8020 static int update_record(struct browse_req *req, const char *uuid,
8025 /* Check for duplicates */
8026 if (sdp_list_find(req->records, rec, rec_cmp))
8030 req->records = sdp_list_append(req->records, sdp_copy_record(rec));
8032 /* Check if UUID is duplicated */
8033 l = g_slist_find_custom(req->device->uuids, uuid, bt_uuid_strcmp);
8035 l = g_slist_find_custom(req->profiles_added, uuid,
8039 req->profiles_added = g_slist_append(req->profiles_added,
8046 static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
8048 struct btd_device *device = req->device;
8050 char srcaddr[18], dstaddr[18];
8051 char sdp_file[PATH_MAX];
8052 char att_file[PATH_MAX];
8053 GKeyFile *sdp_key_file;
8054 GKeyFile *att_key_file;
8055 GError *gerr = NULL;
8060 ba2str(btd_adapter_get_address(device->adapter), srcaddr);
8061 ba2str(&device->bdaddr, dstaddr);
8063 snprintf(sdp_file, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr,
8065 create_file(sdp_file, 0600);
8067 sdp_key_file = g_key_file_new();
8068 if (!g_key_file_load_from_file(sdp_key_file, sdp_file, 0, &gerr)) {
8069 error("Unable to load key file from %s: (%s)", sdp_file,
8071 g_clear_error(&gerr);
8072 g_key_file_free(sdp_key_file);
8073 sdp_key_file = NULL;
8076 snprintf(att_file, PATH_MAX, STORAGEDIR "/%s/%s/attributes", srcaddr,
8078 create_file(att_file, 0600);
8080 att_key_file = g_key_file_new();
8081 if (!g_key_file_load_from_file(att_key_file, att_file, 0, &gerr)) {
8082 error("Unable to load key file from %s: (%s)", att_file,
8084 g_clear_error(&gerr);
8085 g_key_file_free(att_key_file);
8086 att_key_file = NULL;
8089 for (seq = recs; seq; seq = seq->next) {
8090 sdp_record_t *rec = (sdp_record_t *) seq->data;
8096 /* If service class attribute is missing, svclass will be all
8097 * zero and the resulting uuid string will be NULL.
8099 profile_uuid = bt_uuid2string(&rec->svclass);
8104 if (bt_uuid_strcmp(profile_uuid, PNP_UUID) == 0) {
8105 uint16_t source, vendor, product, version;
8108 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
8109 source = pdlist ? pdlist->val.uint16 : 0x0000;
8111 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
8112 vendor = pdlist ? pdlist->val.uint16 : 0x0000;
8114 pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
8115 product = pdlist ? pdlist->val.uint16 : 0x0000;
8117 pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
8118 version = pdlist ? pdlist->val.uint16 : 0x0000;
8120 if (source || vendor || product || version)
8121 btd_device_set_pnpid(device, source, vendor,
8125 if (update_record(req, profile_uuid, rec) < 0)
8129 store_sdp_record(sdp_key_file, rec);
8132 store_primaries_from_sdp_record(att_key_file, rec);
8139 data = g_key_file_to_data(sdp_key_file, &length, NULL);
8141 if (!g_file_set_contents(sdp_file, data, length,
8143 error("Unable set contents for %s: (%s)",
8144 sdp_file, gerr->message);
8145 g_clear_error(&gerr);
8150 g_key_file_free(sdp_key_file);
8154 data = g_key_file_to_data(att_key_file, &length, NULL);
8156 if (!g_file_set_contents(att_file, data, length,
8158 error("Unable set contents for %s: (%s)",
8159 att_file, gerr->message);
8160 g_clear_error(&gerr);
8165 g_key_file_free(att_key_file);
8169 static int primary_cmp(gconstpointer a, gconstpointer b)
8171 return memcmp(a, b, sizeof(struct gatt_primary));
8174 static void update_gatt_uuids(struct browse_req *req, GSList *current,
8179 /* Added Profiles */
8180 for (l = found; l; l = g_slist_next(l)) {
8181 struct gatt_primary *prim = l->data;
8184 lmatch = g_slist_find_custom(current, prim, primary_cmp);
8189 req->profiles_added = g_slist_append(req->profiles_added,
8190 g_strdup(prim->uuid));
8192 DBG("UUID Added: %s", prim->uuid);
8196 static GSList *device_services_from_record(struct btd_device *device,
8199 GSList *l, *prim_list = NULL;
8203 sdp_uuid16_create(&proto_uuid, ATT_UUID);
8204 att_uuid = bt_uuid2string(&proto_uuid);
8206 for (l = profiles; l; l = l->next) {
8207 const char *profile_uuid = l->data;
8208 const sdp_record_t *rec;
8209 struct gatt_primary *prim;
8210 uint16_t start = 0, end = 0, psm = 0;
8213 rec = btd_device_get_record(device, profile_uuid);
8217 if (!record_has_uuid(rec, att_uuid))
8220 if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
8223 prim = g_new0(struct gatt_primary, 1);
8224 prim->range.start = start;
8225 prim->range.end = end;
8226 sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
8228 prim_list = g_slist_append(prim_list, prim);
8236 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
8238 struct browse_req *req = user_data;
8239 struct btd_device *device = req->device;
8244 ba2str(&device->bdaddr, addr);
8247 error("%s: error updating services: %s (%d)",
8248 addr, strerror(-err), -err);
8252 update_bredr_services(req, recs);
8254 if (device->tmp_records)
8255 sdp_list_free(device->tmp_records,
8256 (sdp_free_func_t) sdp_record_free);
8258 device->tmp_records = req->records;
8259 req->records = NULL;
8261 if (!req->profiles_added) {
8262 DBG("%s: No service update", addr);
8266 primaries = device_services_from_record(device, req->profiles_added);
8268 device_register_primaries(device, primaries, ATT_PSM);
8271 * TODO: The btd_service instances for GATT services need to be
8272 * initialized with the service handles. Eventually this code should
8273 * perform ATT protocol service discovery over the ATT PSM to obtain
8274 * the full list of services and populate a client-role gatt_db over
8277 device_probe_profiles(device, req->profiles_added);
8279 /* Propagate services changes */
8280 g_dbus_emit_property_changed(dbus_conn, req->device->path,
8281 DEVICE_INTERFACE, "UUIDs");
8284 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8288 /* since no new services are found, UUID signal is not emitted,
8289 ** so send a reply to the framework with the existing services */
8290 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
8291 "DiscoverServices"))
8292 discover_services_reply(req, err, device->tmp_records);
8296 /* If SDP search failed during an ongoing connection request, we should
8297 * reply to D-Bus method call.
8299 if (err < 0 && device->connect) {
8300 DBG("SDP failed during connection");
8301 reply = btd_error_failed(device->connect, strerror(-err));
8302 g_dbus_send_message(dbus_conn, reply);
8303 dbus_message_unref(device->connect);
8304 device->connect = NULL;
8307 device_svc_resolved(device, BROWSE_SDP, BDADDR_BREDR, err);
8310 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
8312 struct browse_req *req = user_data;
8313 struct btd_device *device = req->device;
8314 struct btd_adapter *adapter = device->adapter;
8317 /* If we have a valid response and req->search_uuid == 2, then L2CAP
8318 * UUID & PNP searching was successful -- we are done */
8319 if (err < 0 || (req->search_uuid == 2 && req->records)) {
8320 if (err == -ECONNRESET && req->reconnect_attempt < 1) {
8322 req->reconnect_attempt++;
8327 update_bredr_services(req, recs);
8329 /* Search for mandatory uuids */
8330 if (uuid_list[req->search_uuid]) {
8331 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
8332 bt_search_service(btd_adapter_get_address(adapter),
8333 &device->bdaddr, &uuid,
8334 browse_cb, user_data, NULL,
8340 search_cb(recs, err, user_data);
8343 static bool device_get_auto_connect(struct btd_device *device)
8345 if (device->disable_auto_connect)
8348 return device->auto_connect;
8351 static void disconnect_gatt_service(gpointer data, gpointer user_data)
8353 struct btd_service *service = data;
8354 struct btd_profile *profile = btd_service_get_profile(service);
8356 /* Ignore if profile cannot accept connections */
8357 if (!profile->accept)
8360 btd_service_disconnect(service);
8363 static void att_disconnected_cb(int err, void *user_data)
8365 struct btd_device *device = user_data;
8372 DBG("%s (%d)", strerror(err), err);
8374 g_slist_foreach(device->services, disconnect_gatt_service, NULL);
8376 btd_gatt_client_disconnected(device->client_dbus);
8378 if (!device_get_auto_connect(device)) {
8379 DBG("Automatic connection disabled");
8384 * Keep scanning/re-connection active if disconnection reason
8385 * is connection timeout, remote user terminated connection or local
8386 * initiated disconnection.
8388 if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
8389 adapter_connect_list_add(device->adapter, device);
8392 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8393 device_set_gatt_connected(device, FALSE);
8395 attio_cleanup(device);
8398 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8399 static void att_mtu_changed(uint16_t mtu, void *user_data)
8401 struct btd_device *device = user_data;
8403 DBG("att mtu changed %d", mtu);
8405 g_dbus_emit_signal(dbus_conn, device->path,
8406 DEVICE_INTERFACE, "AttMtuChanged",
8407 DBUS_TYPE_UINT16, &mtu,
8412 static void register_gatt_services(struct btd_device *device)
8414 struct browse_req *req = device->browse;
8415 GSList *services = NULL;
8417 if (!bt_gatt_client_is_ready(device->client))
8421 * TODO: Remove the primaries list entirely once all profiles use
8424 gatt_db_foreach_service(device->db, NULL, add_primary, &services);
8426 btd_device_set_temporary(device, false);
8428 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8430 if (req->search_uuid)
8431 DBG("browse req. is for SDP. Ignore it.");
8433 update_gatt_uuids(req, device->primaries, services);
8437 update_gatt_uuids(req, device->primaries, services);
8440 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8441 /* do not delete existing primary list,
8442 * just append the new primary uuids,
8443 * the list will be modifed when service changed
8444 * indication is received during connection */
8445 g_slist_free_full(device->primaries, g_free);
8446 device->primaries = NULL;
8449 device_register_primaries(device, services, -1);
8451 device_add_gatt_services(device);
8454 static void gatt_client_init(struct btd_device *device);
8456 static void gatt_client_ready_cb(bool success, uint8_t att_ecode,
8459 struct btd_device *device = user_data;
8461 DBG("status: %s, error: %u", success ? "success" : "failed", att_ecode);
8464 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
8469 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8470 /* Register the services after setting the client is ready
8471 * and exporting all the services and characteristics paths.
8473 register_gatt_services(device);
8476 btd_gatt_client_ready(device->client_dbus);
8477 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8478 register_gatt_services(device);
8481 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type, 0);
8483 store_gatt_db(device);
8485 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8486 if (device->name[0] == '\0') {
8488 name = bt_gatt_client_get_gap_device_name(device->client);
8490 strncpy(device->name, name, MAX_NAME_LENGTH);
8495 static void gatt_client_service_changed(uint16_t start_handle,
8496 uint16_t end_handle,
8499 DBG("start 0x%04x, end: 0x%04x", start_handle, end_handle);
8502 static void gatt_debug(const char *str, void *user_data)
8507 static void gatt_client_init(struct btd_device *device)
8509 gatt_client_cleanup(device);
8511 if (!device->connect && !btd_opts.reverse_discovery) {
8512 DBG("Reverse service discovery disabled: skipping GATT client");
8516 device->client = bt_gatt_client_new(device->db, device->att,
8517 device->att_mtu, 0);
8518 if (!device->client) {
8519 DBG("Failed to initialize");
8523 bt_gatt_client_set_debug(device->client, gatt_debug, NULL, NULL);
8526 * Notify notify existing service about the new connection so they can
8527 * react to notifications while discovering services
8529 device_accept_gatt_profiles(device);
8531 device->gatt_ready_id = bt_gatt_client_ready_register(device->client,
8532 gatt_client_ready_cb,
8534 if (!device->gatt_ready_id) {
8535 DBG("Failed to register GATT ready callback");
8536 gatt_client_cleanup(device);
8540 if (!bt_gatt_client_set_service_changed(device->client,
8541 gatt_client_service_changed,
8543 DBG("Failed to set service changed handler");
8544 gatt_client_cleanup(device);
8548 btd_gatt_client_connected(device->client_dbus);
8550 /* Only initiate EATT connection when acting as initiator, as acceptor
8551 * it shall be triggered only when ready to avoid possible clashes where
8552 * both sides attempt to connection at same time.
8554 if (device->connect)
8555 btd_gatt_client_eatt_connect(device->client_dbus);
8558 static void gatt_server_init(struct btd_device *device,
8559 struct btd_gatt_database *database)
8561 struct gatt_db *db = btd_gatt_database_get_db(database);
8564 error("No local GATT database exists for this adapter");
8568 gatt_server_cleanup(device);
8570 device->server = bt_gatt_server_new(db, device->att, device->att_mtu,
8572 if (!device->server) {
8573 error("Failed to initialize bt_gatt_server");
8577 bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
8579 bt_gatt_server_set_debug(device->server, gatt_debug, NULL, NULL);
8581 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8582 if (!bt_gatt_server_set_mtu_changed(device->server,
8585 DBG("Failed to set mtu changed handler");
8591 static bool local_counter(uint32_t *sign_cnt, void *user_data)
8593 struct btd_device *dev = user_data;
8595 if (!dev->local_csrk)
8598 *sign_cnt = dev->local_csrk->counter++;
8600 store_device_info(dev);
8605 static bool remote_counter(uint32_t *sign_cnt, void *user_data)
8607 struct btd_device *dev = user_data;
8609 if (!dev->remote_csrk || *sign_cnt < dev->remote_csrk->counter)
8612 dev->remote_csrk->counter = *sign_cnt;
8614 store_device_info(dev);
8619 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8620 static bool load_svc_change_indication_status(struct btd_device *device, const char *local,
8623 char filename[PATH_MAX];
8625 gboolean svc_change_regd = false;
8626 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
8628 key_file = g_key_file_new();
8629 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
8632 /* Load Service changed Registered flag */
8633 svc_change_regd = g_key_file_get_boolean(key_file, "Att",
8634 "SvcChangeRegd", NULL);
8635 bt_att_set_svc_changed_indication_registered(device->att,
8640 g_key_file_free(key_file);
8642 return svc_change_regd;
8646 bool device_attach_att(struct btd_device *dev, GIOChannel *io)
8648 GError *gerr = NULL;
8650 BtIOSecLevel sec_level;
8653 struct btd_gatt_database *database;
8654 const bdaddr_t *dst;
8656 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8657 uint8_t dst_type = BDADDR_BREDR;
8659 const bdaddr_t *src;
8662 bt_io_get(io, &gerr, BT_IO_OPT_SEC_LEVEL, &sec_level,
8663 BT_IO_OPT_IMTU, &mtu,
8664 BT_IO_OPT_CID, &cid,
8665 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8666 BT_IO_OPT_DEST_TYPE, &dst_type,
8671 error("bt_io_get: %s", gerr->message);
8677 if (btd_opts.gatt_channels == bt_att_get_channels(dev->att)) {
8678 DBG("EATT channel limit reached");
8682 if (!bt_att_attach_fd(dev->att, g_io_channel_unix_get_fd(io))) {
8683 DBG("EATT channel connected");
8684 g_io_channel_set_close_on_unref(io, FALSE);
8688 error("Failed to attach EATT channel");
8692 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8693 if (sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
8694 DBG("Elevating security level since LTK is available");
8696 sec_level = BT_IO_SEC_MEDIUM;
8697 bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level,
8700 error("bt_io_set: %s", gerr->message);
8707 dev->att_mtu = MIN(mtu, btd_opts.gatt_mtu);
8708 attrib = g_attrib_new(io,
8709 cid == ATT_CID ? BT_ATT_DEFAULT_LE_MTU : dev->att_mtu,
8712 error("Unable to create new GAttrib instance");
8716 dev->attrib = attrib;
8717 dev->att = g_attrib_get_att(attrib);
8719 bt_att_ref(dev->att);
8721 bt_att_set_debug(dev->att, BT_ATT_DEBUG, gatt_debug, NULL, NULL);
8723 dev->att_disconn_id = bt_att_register_disconnect(dev->att,
8724 att_disconnected_cb, dev, NULL);
8725 bt_att_set_close_on_unref(dev->att, true);
8727 if (dev->local_csrk)
8728 bt_att_set_local_key(dev->att, dev->local_csrk->key,
8729 local_counter, dev);
8731 if (dev->remote_csrk)
8732 bt_att_set_remote_key(dev->att, dev->remote_csrk->key,
8733 remote_counter, dev);
8735 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8736 if (dst_type != BDADDR_BREDR && device_get_rpa_exist(dev) == true) {
8737 bt_att_set_remote_addr(dev->att,
8738 device_get_rpa(dev), BDADDR_LE_RANDOM);
8740 bt_att_set_remote_addr(dev->att,
8741 &dev->bdaddr, dev->bdaddr_type);
8745 database = btd_adapter_get_database(dev->adapter);
8747 dst = device_get_address(dev);
8748 ba2str(dst, dstaddr);
8750 if (gatt_db_isempty(dev->db))
8751 load_gatt_db(dev, btd_adapter_get_storage_dir(dev->adapter),
8754 gatt_client_init(dev);
8755 gatt_server_init(dev, database);
8758 * Remove the device from the connect_list and give the passive
8759 * scanning another chance to be restarted in case there are
8760 * other devices in the connect_list.
8762 adapter_connect_list_remove(dev->adapter, dev);
8764 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8765 src = btd_adapter_get_address(dev->adapter);
8766 ba2str(src, srcaddr);
8768 /* load the service changed indication status on connection */
8769 load_svc_change_indication_status(dev, srcaddr, dstaddr);
8775 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
8777 struct btd_device *device = user_data;
8782 g_io_channel_unref(device->att_io);
8783 device->att_io = NULL;
8786 DBG("%s", gerr->message);
8788 if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
8791 if (device_get_auto_connect(device)) {
8792 DBG("Enabling automatic connections");
8793 adapter_connect_list_add(device->adapter, device);
8797 browse_request_complete(device->browse,
8799 device->bdaddr_type,
8802 err = -ECONNABORTED;
8806 if (!device_attach_att(device, io))
8809 if (!device->bonding)
8812 if (device->bonding->agent)
8813 io_cap = agent_get_io_capability(device->bonding->agent);
8815 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
8817 err = adapter_create_bonding(device->adapter, &device->bdaddr,
8818 device->bdaddr_type, io_cap);
8820 if (device->bonding && err < 0) {
8821 reply = btd_error_failed(device->bonding->msg, strerror(-err));
8822 g_dbus_send_message(dbus_conn, reply);
8823 bonding_request_cancel(device->bonding);
8824 bonding_request_free(device->bonding);
8828 device_browse_gatt(device, NULL);
8830 if (device->connect) {
8832 reply = btd_error_failed(device->connect,
8833 btd_error_le_conn_from_errno(err));
8835 reply = dbus_message_new_method_return(device->connect);
8837 g_dbus_send_message(dbus_conn, reply);
8838 dbus_message_unref(device->connect);
8839 device->connect = NULL;
8843 int device_connect_le(struct btd_device *dev)
8845 struct btd_adapter *adapter = dev->adapter;
8846 BtIOSecLevel sec_level;
8848 GError *gerr = NULL;
8851 /* There is one connection attempt going on */
8855 ba2str(&dev->bdaddr, addr);
8857 DBG("Connection attempt to: %s", addr);
8859 if (dev->le_state.paired)
8860 sec_level = BT_IO_SEC_MEDIUM;
8862 sec_level = BT_IO_SEC_LOW;
8865 * This connection will help us catch any PDUs that comes before
8868 io = bt_io_connect(att_connect_cb, dev, NULL, &gerr,
8869 BT_IO_OPT_SOURCE_BDADDR,
8870 btd_adapter_get_address(adapter),
8871 BT_IO_OPT_SOURCE_TYPE,
8872 btd_adapter_get_address_type(adapter),
8873 BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
8874 BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
8875 BT_IO_OPT_CID, ATT_CID,
8876 BT_IO_OPT_SEC_LEVEL, sec_level,
8881 DBusMessage *reply = btd_error_failed(
8882 dev->bonding->msg, gerr->message);
8884 g_dbus_send_message(dbus_conn, reply);
8885 bonding_request_cancel(dev->bonding);
8886 bonding_request_free(dev->bonding);
8889 error("ATT bt_io_connect(%s): %s", addr, gerr->message);
8894 /* Keep this, so we can cancel the connection */
8900 static struct browse_req *browse_request_new(struct btd_device *device,
8904 struct browse_req *req;
8909 req = g_new0(struct browse_req, 1);
8910 req->device = device;
8913 device->browse = req;
8918 req->msg = dbus_message_ref(msg);
8921 * Track the request owner to cancel it automatically if the owner
8924 req->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
8925 dbus_message_get_sender(msg),
8926 browse_request_exit,
8932 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg)
8934 struct btd_adapter *adapter = device->adapter;
8935 struct browse_req *req;
8937 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8940 req = browse_request_new(device, BROWSE_GATT, msg);
8944 if (device->client) {
8946 * If discovery has not yet completed, then wait for gatt-client
8949 if (!bt_gatt_client_is_ready(device->client))
8953 * Services have already been discovered, so signal this browse
8954 * request as resolved.
8956 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
8961 device->att_io = bt_io_connect(att_connect_cb,
8963 BT_IO_OPT_SOURCE_BDADDR,
8964 btd_adapter_get_address(adapter),
8965 BT_IO_OPT_SOURCE_TYPE,
8966 btd_adapter_get_address_type(adapter),
8967 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
8968 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
8969 BT_IO_OPT_CID, ATT_CID,
8970 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
8973 if (device->att_io == NULL) {
8974 browse_request_free(req);
8981 static uint16_t get_sdp_flags(struct btd_device *device)
8985 vid = btd_device_get_vendor(device);
8986 pid = btd_device_get_product(device);
8988 /* Sony DualShock 4 is not respecting negotiated L2CAP MTU. This might
8989 * results in SDP response being dropped by kernel. Workaround this by
8990 * forcing SDP code to use bigger MTU while connecting.
8992 if (vid == 0x054c && pid == 0x05c4)
8993 return SDP_LARGE_MTU;
8995 if (btd_adapter_ssp_enabled(device->adapter))
8998 /* if no EIR try matching Sony DualShock 4 with name and class */
8999 if (!strncmp(device->name, "Wireless Controller", MAX_NAME_LENGTH) &&
9000 device->class == 0x2508)
9001 return SDP_LARGE_MTU;
9006 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
9008 struct btd_adapter *adapter = device->adapter;
9009 struct browse_req *req;
9013 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9016 req = browse_request_new(device, BROWSE_SDP, msg);
9020 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
9022 req->sdp_flags = get_sdp_flags(device);
9024 err = bt_search(btd_adapter_get_address(adapter),
9025 &device->bdaddr, &uuid, browse_cb, req, NULL,
9028 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9029 device->browse = NULL;
9031 browse_request_free(req);
9038 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9039 void device_set_last_addr_type(struct btd_device *device, uint8_t type)
9044 //DBG("Last addr type %d", type);
9046 device->last_bdaddr_type = type;
9049 gboolean device_is_ipsp_connected(struct btd_device * device)
9051 return device->ipsp_connected;
9054 void device_set_ipsp_connected(struct btd_device *device, gboolean connected,
9055 const unsigned char *ifname)
9057 char *iface_name = NULL;
9059 if (device == NULL) {
9060 error("device is NULL");
9064 if (device->ipsp_connected == connected)
9067 device->ipsp_connected = connected;
9069 memset(device->if_name, 0, sizeof(device->if_name));
9070 memcpy(device->if_name, ifname, 16);
9071 iface_name = device->if_name;
9073 DBG("ipsp_connected %d", connected);
9074 DBG("ipsp_iface: %s is Up !", iface_name);
9076 g_dbus_emit_signal(dbus_conn, device->path,
9077 DEVICE_INTERFACE, "IpspStateChanged",
9078 DBUS_TYPE_BOOLEAN, &connected,
9079 DBUS_TYPE_STRING, &iface_name,
9082 void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_octets,
9083 uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time)
9085 if (device == NULL) {
9086 error("device is NULL");
9090 device->max_tx_octets = max_tx_octets;
9091 device->max_tx_time = max_tx_time;
9092 device->max_rx_octets = max_rx_octets;
9093 device->max_rx_time = max_rx_time;
9095 DBG("data length changed values :max_tx_octets: %d max_tx_time: %d max_rx_octets: %d max_rx_time: %d",
9096 max_tx_octets, max_tx_time, max_rx_octets, max_rx_time);
9098 g_dbus_emit_signal(dbus_conn, device->path,
9099 DEVICE_INTERFACE, "LEDataLengthChanged",
9100 DBUS_TYPE_UINT16, &max_tx_octets,
9101 DBUS_TYPE_UINT16, &max_tx_time,
9102 DBUS_TYPE_UINT16, &max_rx_octets,
9103 DBUS_TYPE_UINT16, &max_rx_time,
9107 const bdaddr_t *device_get_rpa(struct btd_device *device)
9112 const uint8_t *device_get_irk_value(struct btd_device *device)
9114 return device->irk_val;
9117 bool device_get_rpa_exist(struct btd_device *device)
9119 return device->rpa ? true : false;
9122 void device_set_auth_addr_type(struct btd_device *device, uint8_t type)
9127 DBG("Auth addr type %d", type);
9129 device->auth_bdaddr_type = type;
9132 void device_get_tizen_addr(struct btd_device *device, uint8_t type,
9133 struct device_addr_type *addr)
9135 if (!device || !addr)
9138 if (type == BDADDR_BREDR) {
9139 bacpy(&addr->bdaddr, &device->bdaddr);
9140 addr->bdaddr_type = BDADDR_BREDR;
9145 bacpy(&addr->bdaddr, device->rpa);
9146 addr->bdaddr_type = BDADDR_LE_RANDOM;
9150 bacpy(&addr->bdaddr, &device->bdaddr);
9151 addr->bdaddr_type = device->bdaddr_type;
9155 int device_discover_services(struct btd_device *device)
9160 err = device_browse_sdp(device, NULL);
9162 err = device_browse_gatt(device, NULL);
9164 if (err == 0 && device->discov_timer) {
9165 timeout_remove(device->discov_timer);
9166 device->discov_timer = 0;
9172 struct btd_adapter *device_get_adapter(struct btd_device *device)
9177 return device->adapter;
9180 const bdaddr_t *device_get_address(struct btd_device *device)
9182 return &device->bdaddr;
9184 uint8_t device_get_le_address_type(struct btd_device *device)
9186 return device->bdaddr_type;
9189 const char *device_get_path(const struct btd_device *device)
9194 return device->path;
9197 gboolean device_is_temporary(struct btd_device *device)
9199 return device->temporary;
9202 void btd_device_set_temporary(struct btd_device *device, bool temporary)
9207 if (device->temporary == temporary)
9210 if (device_address_is_private(device))
9213 DBG("temporary %d", temporary);
9215 device->temporary = temporary;
9219 adapter_accept_list_remove(device->adapter, device);
9220 adapter_connect_list_remove(device->adapter, device);
9221 if (device->auto_connect) {
9222 device->disable_auto_connect = TRUE;
9223 device_set_auto_connect(device, FALSE);
9225 set_temporary_timer(device, btd_opts.tmpto);
9228 clear_temporary_timer(device);
9231 adapter_accept_list_add(device->adapter, device);
9233 store_device_info(device);
9235 /* attributes were not stored when resolved if device was temporary */
9236 if (device->bdaddr_type != BDADDR_BREDR &&
9237 device->le_state.svc_resolved &&
9238 g_slist_length(device->primaries) != 0)
9239 store_services(device);
9242 void btd_device_set_trusted(struct btd_device *device, gboolean trusted)
9247 if (device->trusted == trusted)
9250 DBG("trusted %d", trusted);
9252 device->trusted = trusted;
9254 store_device_info(device);
9256 g_dbus_emit_property_changed(dbus_conn, device->path,
9257 DEVICE_INTERFACE, "Trusted");
9260 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9261 void device_disconnect_blocked(struct btd_device *device, char *uuid)
9263 struct btd_service *service;
9266 if (!device || !uuid)
9269 l = find_service_with_uuid(device->services, uuid);
9274 if (btd_service_get_state(service) ==
9275 BTD_SERVICE_STATE_CONNECTED) {
9277 err = btd_service_disconnect(service);
9279 error("error: %s", strerror(-err));
9283 void btd_device_set_trusted_profiles(struct btd_device *device,
9284 uint32_t pbap, uint32_t map, uint32_t sap,
9285 uint32_t hfp_hs, uint32_t a2dp)
9290 DBG("TrustedProfiles Parameters: [PBAP %d] [MAP %d] [SAP %d] [HFP %d] [A2DP %d]",
9291 pbap, map, sap, hfp_hs, a2dp);
9293 if (device->trusted_profiles.pbap == pbap &&
9294 device->trusted_profiles.map == map &&
9295 device->trusted_profiles.sap == sap &&
9296 device->trusted_profiles.hfp_hs == hfp_hs &&
9297 device->trusted_profiles.a2dp == a2dp)
9300 /* Disconnect OBEX based profiles if connected */
9301 if (device->trusted_profiles.pbap != pbap) {
9302 device->trusted_profiles.pbap = pbap;
9303 if (pbap == SUPPORTED_BLOCKED)
9304 device_disconnect_blocked(device, OBEX_PSE_UUID);
9305 } else if (device->trusted_profiles.map != map) {
9306 device->trusted_profiles.map = map;
9307 if (map == SUPPORTED_BLOCKED)
9308 device_disconnect_blocked(device, OBEX_MAP_UUID);
9309 } else if (device->trusted_profiles.sap != sap) {
9310 device->trusted_profiles.sap = sap;
9311 if (sap == SUPPORTED_BLOCKED)
9312 device_disconnect_blocked(device, SAP_UUID);
9313 } else if (device->trusted_profiles.hfp_hs != hfp_hs) {
9314 device->trusted_profiles.hfp_hs = hfp_hs;
9315 } else if (device->trusted_profiles.a2dp != a2dp) {
9316 device->trusted_profiles.a2dp = a2dp;
9319 store_device_info(device);
9320 g_dbus_emit_property_changed(dbus_conn, device->path,
9321 DEVICE_INTERFACE, "TrustedProfiles");
9325 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type)
9332 if (bdaddr_type == BDADDR_BREDR)
9333 device->bredr_state.bonded = true;
9335 device->le_state.bonded = true;
9337 btd_device_set_temporary(device, false);
9340 void device_set_legacy(struct btd_device *device, bool legacy)
9345 DBG("legacy %d", legacy);
9347 if (device->legacy == legacy)
9350 device->legacy = legacy;
9352 g_dbus_emit_property_changed(dbus_conn, device->path,
9353 DEVICE_INTERFACE, "LegacyPairing");
9356 void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type,
9359 char filename[PATH_MAX];
9360 char device_addr[18];
9362 GError *gerr = NULL;
9367 ba2str(&device->bdaddr, device_addr);
9368 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
9369 btd_adapter_get_storage_dir(device->adapter),
9372 key_file = g_key_file_new();
9373 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
9374 error("Unable to load key file from %s: (%s)", filename,
9379 /* for bonded devices this is done on every connection so limit writes
9380 * to storage if no change needed
9382 if (bdaddr_type == BDADDR_BREDR) {
9383 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
9384 "CCC_BR/EDR", NULL);
9385 if (old_value == value)
9388 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_BR/EDR",
9391 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
9393 if (old_value == value)
9396 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_LE",
9400 create_file(filename, 0600);
9402 str = g_key_file_to_data(key_file, &length, NULL);
9403 if (!g_file_set_contents(filename, str, length, &gerr)) {
9404 error("Unable set contents for %s: (%s)", filename,
9411 g_key_file_free(key_file);
9413 void device_load_svc_chng_ccc(struct btd_device *device, uint16_t *ccc_le,
9414 uint16_t *ccc_bredr)
9416 char filename[PATH_MAX];
9417 char device_addr[18];
9419 GError *gerr = NULL;
9421 ba2str(&device->bdaddr, device_addr);
9422 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
9423 btd_adapter_get_storage_dir(device->adapter),
9426 key_file = g_key_file_new();
9427 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
9428 error("Unable to load key file from %s: (%s)", filename,
9433 if (!g_key_file_has_group(key_file, "ServiceChanged")) {
9437 *ccc_bredr = 0x0000;
9438 g_key_file_free(key_file);
9443 *ccc_le = g_key_file_get_integer(key_file, "ServiceChanged",
9447 *ccc_bredr = g_key_file_get_integer(key_file, "ServiceChanged",
9448 "CCC_BR/EDR", NULL);
9450 g_key_file_free(key_file);
9453 void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi,
9454 int8_t delta_threshold)
9459 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9460 if (rssi == 0 || device->rssi == 0) {
9461 if (device->rssi == rssi)
9465 device->rssi = rssi;
9466 DBG("rssi %d", rssi);
9468 if (rssi == 0 || device->rssi == 0) {
9469 if (device->rssi == rssi)
9472 DBG("rssi %d", rssi);
9474 device->rssi = rssi;
9478 if (device->rssi > rssi)
9479 delta = device->rssi - rssi;
9481 delta = rssi - device->rssi;
9483 /* only report changes of delta_threshold dBm or more */
9484 if (delta < delta_threshold)
9487 DBG("rssi %d delta %d", rssi, delta);
9489 device->rssi = rssi;
9493 g_dbus_emit_property_changed(dbus_conn, device->path,
9494 DEVICE_INTERFACE, "RSSI");
9497 void device_set_rssi(struct btd_device *device, int8_t rssi)
9499 device_set_rssi_with_delta(device, rssi, RSSI_THRESHOLD);
9502 void device_set_tx_power(struct btd_device *device, int8_t tx_power)
9507 if (device->tx_power == tx_power)
9510 DBG("tx_power %d", tx_power);
9512 device->tx_power = tx_power;
9514 g_dbus_emit_property_changed(dbus_conn, device->path,
9515 DEVICE_INTERFACE, "TxPower");
9518 void device_set_flags(struct btd_device *device, uint8_t flags)
9523 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
9524 DBG("flags %d", flags);
9527 if (device->ad_flags[0] == flags)
9530 device->ad_flags[0] = flags;
9532 g_dbus_emit_property_changed(dbus_conn, device->path,
9533 DEVICE_INTERFACE, "AdvertisingFlags");
9536 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9537 void device_set_le_connectable(struct btd_device *device, uint8_t adv_type)
9542 if (device->le_connectable)
9545 if (adv_type == ADV_TYPE_IND || adv_type == ADV_TYPE_DIRECT_IND)
9546 device->le_connectable = true;
9550 bool device_is_connectable(struct btd_device *device)
9558 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9559 /* Check the ADV type. Some beacon device can be connectable regardless adv flags */
9560 return device->le_connectable;
9562 /* Check if either Limited or General discoverable are set */
9563 return (device->ad_flags[0] & 0x03);
9567 static bool start_discovery(gpointer user_data)
9569 struct btd_device *device = user_data;
9572 device_browse_sdp(device, NULL);
9574 device_browse_gatt(device, NULL);
9576 device->discov_timer = 0;
9581 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type)
9583 struct bearer_state *state = get_state(dev, bdaddr_type);
9588 state->paired = true;
9590 /* If the other bearer state was already true we don't need to
9591 * send any property signals.
9593 if (dev->bredr_state.paired == dev->le_state.paired)
9596 if (!state->svc_resolved) {
9597 dev->pending_paired = true;
9601 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9602 if (dev->bonding == NULL)
9604 g_dbus_emit_property_changed(dbus_conn, dev->path,
9605 DEVICE_INTERFACE, "Paired");
9608 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type)
9610 struct bearer_state *state = get_state(dev, bdaddr_type);
9615 state->paired = false;
9618 * If the other bearer state is still true we don't need to
9619 * send any property signals or remove device.
9621 if (dev->bredr_state.paired != dev->le_state.paired) {
9622 /* TODO disconnect only unpaired bearer */
9623 if (state->connected)
9624 device_request_disconnect(dev, NULL);
9629 g_dbus_emit_property_changed(dbus_conn, dev->path,
9630 DEVICE_INTERFACE, "Paired");
9632 btd_device_set_temporary(dev, true);
9634 if (btd_device_is_connected(dev))
9635 device_request_disconnect(dev, NULL);
9637 btd_adapter_remove_device(dev->adapter, dev);
9640 static void device_auth_req_free(struct btd_device *device)
9642 struct authentication_req *authr = device->authr;
9648 agent_unref(authr->agent);
9650 g_free(authr->pincode);
9653 device->authr = NULL;
9656 bool device_is_retrying(struct btd_device *device)
9658 struct bonding_req *bonding = device->bonding;
9660 return bonding && bonding->retry_timer > 0;
9663 void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
9666 struct bonding_req *bonding = device->bonding;
9667 struct authentication_req *auth = device->authr;
9668 struct bearer_state *state = get_state(device, bdaddr_type);
9670 DBG("bonding %p status 0x%02x", bonding, status);
9672 if (auth && auth->agent)
9673 agent_cancel(auth->agent);
9676 device_cancel_authentication(device, TRUE);
9678 /* Put the device back to the temporary state so that it will be
9679 * treated as a newly discovered device.
9681 if (!device_is_paired(device, bdaddr_type) &&
9682 !device_is_trusted(device))
9683 btd_device_set_temporary(device, true);
9685 device_bonding_failed(device, status);
9686 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9687 device->legacy_pairing = false;
9691 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9692 device->legacy_pairing = false;
9694 device_auth_req_free(device);
9696 /* If we're already paired nothing more is needed */
9697 if (state->paired) {
9698 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9699 if (bdaddr_type == BDADDR_BREDR && state->svc_resolved) {
9700 DBG("Link key has been changed. Report it");
9702 g_dbus_emit_property_changed(dbus_conn,
9703 device->path, DEVICE_INTERFACE,
9706 DBG("Just overwrite Link key");
9707 } else if (bdaddr_type == BDADDR_LE_RANDOM ||
9708 bdaddr_type == BDADDR_LE_PUBLIC) {
9709 DBG("Long Term Key has been changed. Report it");
9710 g_dbus_emit_property_changed(dbus_conn, device->path,
9711 DEVICE_INTERFACE, "Paired");
9713 #endif /* TIZEN_FEATURE_BLUEZ_MODIFY */
9717 device_set_paired(device, bdaddr_type);
9719 /* If services are already resolved just reply to the pairing
9722 if (state->svc_resolved && bonding) {
9723 /* Attept to store services for this device failed because it
9724 * was not paired. Now that we're paired retry. */
9725 store_gatt_db(device);
9727 g_dbus_send_reply(dbus_conn, bonding->msg, DBUS_TYPE_INVALID);
9728 bonding_request_free(bonding);
9732 /* If we were initiators start service discovery immediately.
9733 * However if the other end was the initator wait a few seconds
9734 * before SDP. This is due to potential IOP issues if the other
9735 * end starts doing SDP at the same time as us */
9737 DBG("Proceeding with service discovery");
9738 /* If we are initiators remove any discovery timer and just
9739 * start discovering services directly */
9740 if (device->discov_timer) {
9741 timeout_remove(device->discov_timer);
9742 device->discov_timer = 0;
9745 if (bdaddr_type == BDADDR_BREDR)
9746 device_browse_sdp(device, bonding->msg);
9748 device_browse_gatt(device, bonding->msg);
9750 bonding_request_free(bonding);
9751 } else if (!state->svc_resolved) {
9752 if (!device->browse && !device->discov_timer &&
9753 btd_opts.reverse_discovery) {
9754 /* If we are not initiators and there is no currently
9755 * active discovery or discovery timer, set discovery
9757 DBG("setting timer for reverse service discovery");
9758 device->discov_timer = timeout_add_seconds(
9766 static gboolean svc_idle_cb(gpointer user_data)
9768 struct svc_callback *cb = user_data;
9769 struct btd_device *dev = cb->dev;
9771 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
9773 cb->func(cb->dev, 0, cb->user_data);
9780 unsigned int device_wait_for_svc_complete(struct btd_device *dev,
9781 device_svc_cb_t func,
9784 /* This API is only used for BR/EDR (for now) */
9785 struct bearer_state *state = &dev->bredr_state;
9786 static unsigned int id = 0;
9787 struct svc_callback *cb;
9789 cb = g_new0(struct svc_callback, 1);
9791 cb->user_data = user_data;
9795 dev->svc_callbacks = g_slist_prepend(dev->svc_callbacks, cb);
9797 if (state->svc_resolved || !btd_opts.reverse_discovery)
9798 cb->idle_id = g_idle_add(svc_idle_cb, cb);
9799 else if (dev->discov_timer >0) {
9800 timeout_remove(dev->discov_timer);
9801 dev->discov_timer = timeout_add_seconds(
9806 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9807 else if (!dev->browse) {
9808 DBG("Service is not going on. Start discovery");
9809 dev->discov_timer = timeout_add_seconds(
9814 DBG("Wait for service discovery");
9820 bool device_remove_svc_complete_callback(struct btd_device *dev,
9825 for (l = dev->svc_callbacks; l != NULL; l = g_slist_next(l)) {
9826 struct svc_callback *cb = l->data;
9831 if (cb->idle_id > 0)
9832 g_source_remove(cb->idle_id);
9834 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
9843 gboolean device_is_bonding(struct btd_device *device, const char *sender)
9845 struct bonding_req *bonding = device->bonding;
9847 if (!device->bonding)
9853 return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
9856 static gboolean device_bonding_retry(gpointer data)
9858 struct btd_device *device = data;
9859 struct btd_adapter *adapter = device_get_adapter(device);
9860 struct bonding_req *bonding = device->bonding;
9867 DBG("retrying bonding");
9868 bonding->retry_timer = 0;
9870 /* Restart the bonding timer to the begining of the pairing. If not
9871 * pincode request/reply occurs during this retry,
9872 * device_bonding_last_duration() will return a consistent value from
9874 device_bonding_restart_timer(device);
9877 io_cap = agent_get_io_capability(bonding->agent);
9879 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
9881 err = adapter_bonding_attempt(adapter, &device->bdaddr,
9882 device->bdaddr_type, io_cap);
9884 device_bonding_complete(device, bonding->bdaddr_type,
9890 int device_bonding_attempt_retry(struct btd_device *device)
9892 struct bonding_req *bonding = device->bonding;
9894 /* Ignore other failure events while retrying */
9895 if (device_is_retrying(device))
9901 /* Mark the end of a bonding attempt to compute the delta for the
9903 bonding_request_stop_timer(bonding);
9905 if (btd_adapter_pin_cb_iter_end(bonding->cb_iter))
9908 DBG("scheduling retry");
9909 bonding->retry_timer = g_timeout_add(3000,
9910 device_bonding_retry, device);
9914 void device_bonding_failed(struct btd_device *device, uint8_t status)
9916 struct bonding_req *bonding = device->bonding;
9919 DBG("status %u", status);
9922 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9923 if (device->legacy_pairing) {
9924 DBG("Emit LegacyPaired");
9925 g_dbus_emit_property_changed(dbus_conn, device->path,
9926 DEVICE_INTERFACE, "LegacyPaired");
9931 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9932 btd_device_set_temporary(device, TRUE);
9936 device_cancel_authentication(device, FALSE);
9938 reply = new_authentication_return(bonding->msg, status);
9939 g_dbus_send_message(dbus_conn, reply);
9941 bonding_request_free(bonding);
9944 struct btd_adapter_pin_cb_iter *device_bonding_iter(struct btd_device *device)
9946 if (device->bonding == NULL)
9949 return device->bonding->cb_iter;
9952 static void pincode_cb(struct agent *agent, DBusError *err, const char *pin,
9955 struct authentication_req *auth = data;
9956 struct btd_device *device = auth->device;
9958 /* No need to reply anything if the authentication already failed */
9959 if (auth->agent == NULL)
9962 btd_adapter_pincode_reply(device->adapter, &device->bdaddr,
9963 pin, pin ? strlen(pin) : 0);
9965 agent_unref(device->authr->agent);
9966 device->authr->agent = NULL;
9969 static void confirm_cb(struct agent *agent, DBusError *err, void *data)
9971 struct authentication_req *auth = data;
9972 struct btd_device *device = auth->device;
9974 /* No need to reply anything if the authentication already failed */
9975 if (auth->agent == NULL)
9978 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9979 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
9981 err ? FALSE : TRUE);
9982 device_set_auth_addr_type(device, BDADDR_BREDR);
9984 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
9986 err ? FALSE : TRUE);
9989 agent_unref(device->authr->agent);
9990 device->authr->agent = NULL;
9993 static void passkey_cb(struct agent *agent, DBusError *err,
9994 uint32_t passkey, void *data)
9996 struct authentication_req *auth = data;
9997 struct btd_device *device = auth->device;
9999 /* No need to reply anything if the authentication already failed */
10000 if (auth->agent == NULL)
10004 passkey = INVALID_PASSKEY;
10006 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10007 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
10008 auth->addr_type, passkey);
10009 device_set_auth_addr_type(device, BDADDR_BREDR);
10011 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
10012 auth->addr_type, passkey);
10015 agent_unref(device->authr->agent);
10016 device->authr->agent = NULL;
10019 static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
10021 struct authentication_req *auth = data;
10022 struct btd_device *device = auth->device;
10024 pincode_cb(agent, err, auth->pincode, auth);
10026 g_free(device->authr->pincode);
10027 device->authr->pincode = NULL;
10030 static struct authentication_req *new_auth(struct btd_device *device,
10035 struct authentication_req *auth;
10036 struct agent *agent;
10039 ba2str(&device->bdaddr, addr);
10040 DBG("Requesting agent authentication for %s", addr);
10042 if (device->authr) {
10043 error("Authentication already requested for %s", addr);
10047 if (device->bonding && device->bonding->agent)
10048 agent = agent_ref(device->bonding->agent);
10050 agent = agent_get(NULL);
10053 error("No agent available for request type %d", type);
10057 auth = g_new0(struct authentication_req, 1);
10058 auth->agent = agent;
10059 auth->device = device;
10061 auth->addr_type = addr_type;
10062 auth->secure = secure;
10063 device->authr = auth;
10068 int device_request_pincode(struct btd_device *device, gboolean secure)
10070 struct authentication_req *auth;
10073 auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_PINCODE, secure);
10077 err = agent_request_pincode(auth->agent, device, pincode_cb, secure,
10080 error("Failed requesting authentication");
10081 device_auth_req_free(device);
10087 int device_request_passkey(struct btd_device *device, uint8_t type)
10089 struct authentication_req *auth;
10092 auth = new_auth(device, type, AUTH_TYPE_PASSKEY, FALSE);
10096 err = agent_request_passkey(auth->agent, device, passkey_cb, auth,
10099 error("Failed requesting authentication");
10100 device_auth_req_free(device);
10106 int device_confirm_passkey(struct btd_device *device, uint8_t type,
10107 int32_t passkey, uint8_t confirm_hint)
10109 struct authentication_req *auth;
10112 /* Just-Works repairing policy */
10113 if (confirm_hint && device_is_paired(device, type)) {
10114 if (btd_opts.jw_repairing == JW_REPAIRING_NEVER) {
10115 btd_adapter_confirm_reply(device->adapter,
10119 } else if (btd_opts.jw_repairing == JW_REPAIRING_ALWAYS) {
10120 btd_adapter_confirm_reply(device->adapter,
10127 auth = new_auth(device, type, AUTH_TYPE_CONFIRM, FALSE);
10131 auth->passkey = passkey;
10133 #ifndef TIZEN_FEATURE_BLUEZ_CONFIRM_ONLY
10134 if (confirm_hint) {
10135 if (device->bonding != NULL) {
10136 /* We know the client has indicated the intent to pair
10137 * with the peer device, so we can auto-accept.
10139 btd_adapter_confirm_reply(device->adapter,
10145 err = agent_request_authorization(auth->agent, device,
10146 confirm_cb, auth, NULL);
10149 err = agent_request_confirmation(auth->agent, device, passkey,
10150 confirm_cb, auth, NULL);
10153 if (err == -EINPROGRESS) {
10154 /* Already in progress */
10155 confirm_cb(auth->agent, NULL, auth);
10159 error("Failed requesting authentication");
10160 device_auth_req_free(device);
10166 int device_notify_passkey(struct btd_device *device, uint8_t type,
10167 uint32_t passkey, uint8_t entered)
10169 struct authentication_req *auth;
10172 if (device->authr) {
10173 auth = device->authr;
10174 if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
10177 auth = new_auth(device, type, AUTH_TYPE_NOTIFY_PASSKEY, FALSE);
10182 err = agent_display_passkey(auth->agent, device, passkey, entered);
10184 error("Failed requesting authentication");
10185 device_auth_req_free(device);
10191 int device_notify_pincode(struct btd_device *device, gboolean secure,
10192 const char *pincode)
10194 struct authentication_req *auth;
10197 auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_NOTIFY_PINCODE, secure);
10201 auth->pincode = g_strdup(pincode);
10203 err = agent_display_pincode(auth->agent, device, pincode,
10204 display_pincode_cb, auth, NULL);
10206 if (err == -EINPROGRESS) {
10207 /* Already in progress */
10208 display_pincode_cb(auth->agent, NULL, auth);
10212 error("Failed requesting authentication");
10213 device_auth_req_free(device);
10219 static void cancel_authentication(struct authentication_req *auth)
10221 struct agent *agent;
10224 if (!auth || !auth->agent)
10227 agent = auth->agent;
10228 auth->agent = NULL;
10230 dbus_error_init(&err);
10231 dbus_set_error_const(&err, ERROR_INTERFACE ".Canceled", NULL);
10233 switch (auth->type) {
10234 case AUTH_TYPE_PINCODE:
10235 pincode_cb(agent, &err, NULL, auth);
10237 case AUTH_TYPE_CONFIRM:
10238 confirm_cb(agent, &err, auth);
10240 case AUTH_TYPE_PASSKEY:
10241 passkey_cb(agent, &err, 0, auth);
10243 case AUTH_TYPE_NOTIFY_PASSKEY:
10244 /* User Notify doesn't require any reply */
10246 case AUTH_TYPE_NOTIFY_PINCODE:
10247 pincode_cb(agent, &err, NULL, auth);
10251 dbus_error_free(&err);
10254 void device_cancel_authentication(struct btd_device *device, gboolean aborted)
10256 struct authentication_req *auth = device->authr;
10262 ba2str(&device->bdaddr, addr);
10263 DBG("Canceling authentication request for %s", addr);
10266 agent_cancel(auth->agent);
10269 cancel_authentication(auth);
10271 device_auth_req_free(device);
10273 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10274 device_set_auth_addr_type(device, BDADDR_BREDR);
10278 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10279 gboolean device_is_authenticating(struct btd_device *dev, uint8_t bdaddr_type)
10281 return (dev->auth_bdaddr_type == bdaddr_type && dev->authr != NULL);
10284 gboolean device_is_authenticating(struct btd_device *device)
10286 return (device->authr != NULL);
10290 struct gatt_primary *btd_device_get_primary(struct btd_device *device,
10295 match = g_slist_find_custom(device->primaries, uuid, bt_uuid_strcmp);
10297 return match->data;
10302 GSList *btd_device_get_primaries(struct btd_device *device)
10304 return device->primaries;
10307 struct gatt_db *btd_device_get_gatt_db(struct btd_device *device)
10315 struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device)
10320 return device->client;
10323 void *btd_device_get_attrib(struct btd_device *device)
10328 return device->attrib;
10331 struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device)
10336 return device->server;
10339 void btd_device_gatt_set_service_changed(struct btd_device *device,
10340 uint16_t start, uint16_t end)
10343 * TODO: Remove this function and handle service changed via
10348 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
10353 if (g_slist_find_custom(device->uuids, uuid, bt_uuid_strcmp))
10356 new_uuid = g_strdup(uuid);
10357 uuid_list = g_slist_append(NULL, new_uuid);
10359 device_probe_profiles(device, uuid_list);
10362 g_slist_free(uuid_list);
10364 store_device_info(device);
10366 g_dbus_emit_property_changed(dbus_conn, device->path,
10367 DEVICE_INTERFACE, "UUIDs");
10370 static sdp_list_t *read_device_records(struct btd_device *device)
10372 char local[18], peer[18];
10373 char filename[PATH_MAX];
10374 GKeyFile *key_file;
10375 GError *gerr = NULL;
10376 char **keys, **handle;
10378 sdp_list_t *recs = NULL;
10381 ba2str(btd_adapter_get_address(device->adapter), local);
10382 ba2str(&device->bdaddr, peer);
10384 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10386 ba2str(device->rpa, peer);
10389 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
10391 key_file = g_key_file_new();
10392 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
10393 error("Unable to load key file from %s: (%s)", filename,
10395 g_error_free(gerr);
10397 keys = g_key_file_get_keys(key_file, "ServiceRecords", NULL, NULL);
10399 for (handle = keys; handle && *handle; handle++) {
10400 str = g_key_file_get_string(key_file, "ServiceRecords",
10405 rec = record_from_string(str);
10406 recs = sdp_list_append(recs, rec);
10411 g_key_file_free(key_file);
10416 void btd_device_set_record(struct btd_device *device, const char *uuid,
10417 const char *record)
10419 /* This API is only used for BR/EDR */
10420 struct bearer_state *state = &device->bredr_state;
10421 struct browse_req *req;
10422 sdp_list_t *recs = NULL;
10428 req = browse_request_new(device, BROWSE_SDP, NULL);
10432 rec = record_from_string(record);
10433 recs = sdp_list_append(recs, rec);
10434 update_bredr_services(req, recs);
10435 sdp_list_free(recs, NULL);
10437 device->svc_refreshed = true;
10438 state->svc_resolved = true;
10440 device_probe_profiles(device, req->profiles_added);
10442 /* Propagate services changes */
10443 g_dbus_emit_property_changed(dbus_conn, req->device->path,
10444 DEVICE_INTERFACE, "UUIDs");
10446 device_svc_resolved(device, BROWSE_SDP, device->bdaddr_type, 0);
10449 const sdp_record_t *btd_device_get_record(struct btd_device *device,
10452 /* Load records from storage if there is nothing in cache */
10453 if (!device->tmp_records) {
10454 device->tmp_records = read_device_records(device);
10455 if (!device->tmp_records)
10459 return find_record_in_list(device->tmp_records, uuid);
10462 struct btd_device *btd_device_ref(struct btd_device *device)
10464 __sync_fetch_and_add(&device->ref_count, 1);
10469 void btd_device_unref(struct btd_device *device)
10471 if (__sync_sub_and_fetch(&device->ref_count, 1))
10474 if (!device->path) {
10475 error("freeing device without an object path");
10479 DBG("Freeing device %s", device->path);
10481 g_dbus_unregister_interface(dbus_conn, device->path, DEVICE_INTERFACE);
10484 int device_get_appearance(struct btd_device *device, uint16_t *value)
10486 if (device->appearance == 0)
10490 *value = device->appearance;
10495 void device_set_appearance(struct btd_device *device, uint16_t value)
10497 const char *icon = gap_appearance_to_icon(value);
10499 if (device->appearance == value)
10502 g_dbus_emit_property_changed(dbus_conn, device->path,
10503 DEVICE_INTERFACE, "Appearance");
10506 g_dbus_emit_property_changed(dbus_conn, device->path,
10507 DEVICE_INTERFACE, "Icon");
10509 device->appearance = value;
10510 store_device_info(device);
10513 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10514 int device_get_rpa_res_char_value(struct btd_device *device)
10516 return device->rpa_res_support;
10519 /* Store the RPA Resolution Characteristic Value of remote device.
10520 * This value would be checked before start directed advertising using RPA.
10522 void device_set_rpa_res_char_value(struct btd_device *device, uint8_t value)
10524 if (device->rpa_res_support == value)
10527 device->rpa_res_support = value;
10528 store_device_info(device);
10531 void device_set_manufacturer_info(struct btd_device *device, struct eir_data *eir)
10536 if (eir->manufacturer_data_len == 0)
10539 device->manufacturer_data = g_memdup(eir->manufacturer_data,
10540 eir->manufacturer_data_len);
10541 device->manufacturer_data_len = eir->manufacturer_data_len;
10543 store_device_info(device);
10545 g_dbus_emit_property_changed(dbus_conn, device->path,
10546 DEVICE_INTERFACE, "LegacyManufacturerDataLen");
10548 g_dbus_emit_property_changed(dbus_conn, device->path,
10549 DEVICE_INTERFACE, "LegacyManufacturerData");
10553 void device_set_adv_report_info(struct btd_device *device, void *data, uint8_t data_len,
10554 uint8_t adv_type, int8_t rssi)
10559 char peer_addr[18];
10560 const char *paddr = peer_addr;
10561 dbus_int32_t rssi_val = rssi;
10562 int adv_len = data_len;
10565 ba2str(&device->bdaddr, peer_addr);
10567 /* Replace address type for paired RPA device since IDA passed from controller */
10569 ba2str(device->rpa, peer_addr);
10570 addr_type = BDADDR_LE_RANDOM;
10572 addr_type = device->bdaddr_type;
10574 g_dbus_emit_signal(dbus_conn, device->path,
10575 DEVICE_INTERFACE, "AdvReport",
10576 DBUS_TYPE_STRING, &paddr,
10577 DBUS_TYPE_BYTE, &addr_type,
10578 DBUS_TYPE_BYTE, &adv_type,
10579 DBUS_TYPE_INT32, &rssi_val,
10580 DBUS_TYPE_INT32, &adv_len,
10581 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_len,
10582 DBUS_TYPE_INVALID);
10585 void device_set_payload_timeout(struct btd_device *device,
10586 uint16_t payload_timeout)
10590 if (device->auth_payload_timeout == payload_timeout)
10593 DBG("Payload timeout %d", payload_timeout);
10595 device->auth_payload_timeout = payload_timeout;
10596 g_dbus_emit_property_changed(dbus_conn, device->path,
10597 DEVICE_INTERFACE, "PayloadTimeout");
10600 void device_set_disconnect_reason(struct btd_device *device, uint8_t reason)
10602 device->disc_reason = reason;
10605 void btd_device_disconnect(struct btd_device *device)
10608 struct btd_service *service;
10609 btd_service_state_t state;
10611 ba2str(&device->bdaddr, dst);
10614 if (device->bredr_state.connected == false)
10617 service = btd_device_get_service(device, HFP_HS_UUID);
10621 state = btd_service_get_state(service);
10622 DBG("Connected State : %d", state);
10624 if (state == BTD_SERVICE_STATE_DISCONNECTED) {
10625 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
10634 void btd_device_set_pnpid(struct btd_device *device, uint16_t source,
10635 uint16_t vendor, uint16_t product, uint16_t version)
10637 if (device->vendor_src == source && device->version == version &&
10638 device->vendor == vendor && device->product == product)
10641 device->vendor_src = source;
10642 device->vendor = vendor;
10643 device->product = product;
10644 device->version = version;
10646 free(device->modalias);
10647 device->modalias = bt_modalias(source, vendor, product, version);
10649 g_dbus_emit_property_changed(dbus_conn, device->path,
10650 DEVICE_INTERFACE, "Modalias");
10652 store_device_info(device);
10655 uint32_t btd_device_get_current_flags(struct btd_device *dev)
10657 return dev->current_flags;
10660 /* This event is sent immediately after add device on all mgmt sockets.
10661 * Afterwards, it is only sent to mgmt sockets other than the one which called
10662 * set_device_flags.
10664 void btd_device_flags_changed(struct btd_device *dev, uint32_t supported_flags,
10665 uint32_t current_flags)
10667 const uint32_t changed_flags = dev->current_flags ^ current_flags;
10670 dev->supported_flags = supported_flags;
10671 dev->current_flags = current_flags;
10673 if (!changed_flags)
10676 if (changed_flags & DEVICE_FLAG_REMOTE_WAKEUP) {
10677 flag_value = !!(current_flags & DEVICE_FLAG_REMOTE_WAKEUP);
10678 dev->pending_wake_allowed = flag_value;
10680 /* If an override exists and doesn't match the current state,
10681 * apply it. This logic will run after Add Device only and will
10682 * enable wake for previously paired devices.
10684 if (dev->wake_override != WAKE_FLAG_DEFAULT) {
10685 bool wake_allowed =
10686 dev->wake_override == WAKE_FLAG_ENABLED;
10687 if (flag_value != wake_allowed)
10688 device_set_wake_allowed(dev, wake_allowed, -1U);
10690 device_set_wake_allowed_complete(dev);
10692 device_set_wake_allowed_complete(dev);
10697 static void service_state_changed(struct btd_service *service,
10698 btd_service_state_t old_state,
10699 btd_service_state_t new_state,
10702 struct btd_profile *profile = btd_service_get_profile(service);
10703 struct btd_device *device = btd_service_get_device(service);
10704 int err = btd_service_get_error(service);
10706 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10708 if (old_state == BTD_SERVICE_STATE_UNAVAILABLE ||
10709 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
10710 DBG("Skip status updating ([%d] -> [%d])", old_state, new_state);
10712 g_dbus_emit_signal(dbus_conn, device->path,
10713 DEVICE_INTERFACE, "ProfileStateChanged",
10714 DBUS_TYPE_STRING, &profile->remote_uuid,
10715 DBUS_TYPE_INT32, &new_state,
10716 DBUS_TYPE_INVALID);
10719 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
10720 new_state == BTD_SERVICE_STATE_DISCONNECTING ||
10721 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
10723 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
10724 new_state == BTD_SERVICE_STATE_DISCONNECTING)
10728 if (old_state == BTD_SERVICE_STATE_CONNECTING)
10729 device_profile_connected(device, profile, err);
10730 else if (old_state == BTD_SERVICE_STATE_DISCONNECTING)
10731 device_profile_disconnected(device, profile, err);
10734 struct btd_service *btd_device_get_service(struct btd_device *dev,
10735 const char *remote_uuid)
10739 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
10740 struct btd_service *service = l->data;
10741 struct btd_profile *p = btd_service_get_profile(service);
10743 if (g_str_equal(p->remote_uuid, remote_uuid))
10746 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
10747 if (g_str_equal(HID_UUID, remote_uuid)) {
10748 if (strcmp(p->name, "hid-device") == 0)
10757 void btd_device_init(void)
10759 dbus_conn = btd_get_dbus_connection();
10760 service_state_cb_id = btd_service_add_state_cb(
10761 service_state_changed, NULL);
10764 void btd_device_cleanup(void)
10766 btd_service_remove_state_cb(service_state_cb_id);
10769 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10770 void btd_device_set_legacy_pairing(struct btd_device *dev, bool legacy_pairing)
10772 dev->legacy_pairing = legacy_pairing;
10775 void btd_device_set_svc_changed_indication(struct btd_device *dev, bool value)
10777 bt_att_set_svc_changed_indication_registered(dev->att, value);
10778 store_device_info(dev);
10781 bool btd_device_get_svc_changed_indication(struct btd_device *dev)
10783 return bt_att_get_svc_changed_indication_registered(dev->att);