Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: Add support for LE ping feature

Changes made to add HCI Write Authenticated Payload timeout
command for LE Ping feature.

As per the Core Specification 5.0 Volume 2 Part E Section 7.3.94,
the following code changes implements
HCI Write Authenticated Payload timeout command for LE Ping feature.

Signed-off-by: Spoorthi Ravishankar Koppad <spoorthix.k@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Spoorthi Ravishankar Koppad and committed by
Marcel Holtmann
302975cb 28261da8

+131
+20
include/net/bluetooth/hci.h
··· 1143 1143 __u8 support; 1144 1144 } __packed; 1145 1145 1146 + #define HCI_OP_READ_AUTH_PAYLOAD_TO 0x0c7b 1147 + struct hci_cp_read_auth_payload_to { 1148 + __le16 handle; 1149 + } __packed; 1150 + struct hci_rp_read_auth_payload_to { 1151 + __u8 status; 1152 + __le16 handle; 1153 + __le16 timeout; 1154 + } __packed; 1155 + 1156 + #define HCI_OP_WRITE_AUTH_PAYLOAD_TO 0x0c7c 1157 + struct hci_cp_write_auth_payload_to { 1158 + __le16 handle; 1159 + __le16 timeout; 1160 + } __packed; 1161 + struct hci_rp_write_auth_payload_to { 1162 + __u8 status; 1163 + __le16 handle; 1164 + } __packed; 1165 + 1146 1166 #define HCI_OP_READ_LOCAL_OOB_EXT_DATA 0x0c7d 1147 1167 struct hci_rp_read_local_oob_ext_data { 1148 1168 __u8 status;
+4
include/net/bluetooth/hci_core.h
··· 199 199 /* Default min/max age of connection information (1s/3s) */ 200 200 #define DEFAULT_CONN_INFO_MIN_AGE 1000 201 201 #define DEFAULT_CONN_INFO_MAX_AGE 3000 202 + /* Default authenticated payload timeout 30s */ 203 + #define DEFAULT_AUTH_PAYLOAD_TIMEOUT 0x0bb8 202 204 203 205 struct amp_assoc { 204 206 __u16 len; ··· 277 275 __u16 discov_interleaved_timeout; 278 276 __u16 conn_info_min_age; 279 277 __u16 conn_info_max_age; 278 + __u16 auth_payload_timeout; 280 279 __u8 ssp_debug_mode; 281 280 __u8 hw_error_code; 282 281 __u32 clock; ··· 484 481 __u16 disc_timeout; 485 482 __u16 conn_timeout; 486 483 __u16 setting; 484 + __u16 auth_payload_timeout; 487 485 __u16 le_conn_min_interval; 488 486 __u16 le_conn_max_interval; 489 487 __u16 le_conn_interval;
+3
net/bluetooth/hci_conn.c
··· 520 520 set_bit(HCI_CONN_POWER_SAVE, &conn->flags); 521 521 conn->disc_timeout = HCI_DISCONN_TIMEOUT; 522 522 523 + /* Set Default Authenticated payload timeout to 30s */ 524 + conn->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT; 525 + 523 526 if (conn->role == HCI_ROLE_MASTER) 524 527 conn->out = true; 525 528
+1
net/bluetooth/hci_core.c
··· 3200 3200 hdev->discov_interleaved_timeout = DISCOV_INTERLEAVED_TIMEOUT; 3201 3201 hdev->conn_info_min_age = DEFAULT_CONN_INFO_MIN_AGE; 3202 3202 hdev->conn_info_max_age = DEFAULT_CONN_INFO_MAX_AGE; 3203 + hdev->auth_payload_timeout = DEFAULT_AUTH_PAYLOAD_TIMEOUT; 3203 3204 3204 3205 mutex_init(&hdev->lock); 3205 3206 mutex_init(&hdev->req_lock);
+31
net/bluetooth/hci_debugfs.c
··· 941 941 DEFINE_SIMPLE_ATTRIBUTE(adv_max_interval_fops, adv_max_interval_get, 942 942 adv_max_interval_set, "%llu\n"); 943 943 944 + static int auth_payload_timeout_set(void *data, u64 val) 945 + { 946 + struct hci_dev *hdev = data; 947 + 948 + if (val < 0x0001 || val > 0xffff) 949 + return -EINVAL; 950 + 951 + hci_dev_lock(hdev); 952 + hdev->auth_payload_timeout = val; 953 + hci_dev_unlock(hdev); 954 + 955 + return 0; 956 + } 957 + 958 + static int auth_payload_timeout_get(void *data, u64 *val) 959 + { 960 + struct hci_dev *hdev = data; 961 + 962 + hci_dev_lock(hdev); 963 + *val = hdev->auth_payload_timeout; 964 + hci_dev_unlock(hdev); 965 + 966 + return 0; 967 + } 968 + 969 + DEFINE_SIMPLE_ATTRIBUTE(auth_payload_timeout_fops, 970 + auth_payload_timeout_get, 971 + auth_payload_timeout_set, "%llu\n"); 972 + 944 973 DEFINE_QUIRK_ATTRIBUTE(quirk_strict_duplicate_filter, 945 974 HCI_QUIRK_STRICT_DUPLICATE_FILTER); 946 975 DEFINE_QUIRK_ATTRIBUTE(quirk_simultaneous_discovery, ··· 1023 994 &adv_max_interval_fops); 1024 995 debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs, 1025 996 &hdev->discov_interleaved_timeout); 997 + debugfs_create_file("auth_payload_timeout", 0644, hdev->debugfs, hdev, 998 + &auth_payload_timeout_fops); 1026 999 1027 1000 debugfs_create_file("quirk_strict_duplicate_filter", 0644, 1028 1001 hdev->debugfs, hdev,
+72
net/bluetooth/hci_event.c
··· 579 579 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); 580 580 } 581 581 582 + static void hci_cc_read_auth_payload_timeout(struct hci_dev *hdev, 583 + struct sk_buff *skb) 584 + { 585 + struct hci_rp_read_auth_payload_to *rp = (void *)skb->data; 586 + struct hci_conn *conn; 587 + 588 + BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 589 + 590 + if (rp->status) 591 + return; 592 + 593 + hci_dev_lock(hdev); 594 + 595 + conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 596 + if (conn) 597 + conn->auth_payload_timeout = __le16_to_cpu(rp->timeout); 598 + 599 + hci_dev_unlock(hdev); 600 + } 601 + 602 + static void hci_cc_write_auth_payload_timeout(struct hci_dev *hdev, 603 + struct sk_buff *skb) 604 + { 605 + struct hci_rp_write_auth_payload_to *rp = (void *)skb->data; 606 + struct hci_conn *conn; 607 + void *sent; 608 + 609 + BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); 610 + 611 + if (rp->status) 612 + return; 613 + 614 + sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO); 615 + if (!sent) 616 + return; 617 + 618 + hci_dev_lock(hdev); 619 + 620 + conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); 621 + if (conn) 622 + conn->auth_payload_timeout = get_unaligned_le16(sent + 2); 623 + 624 + hci_dev_unlock(hdev); 625 + } 626 + 582 627 static void hci_cc_read_local_features(struct hci_dev *hdev, 583 628 struct sk_buff *skb) 584 629 { ··· 3020 2975 goto unlock; 3021 2976 } 3022 2977 2978 + /* Set the default Authenticated Payload Timeout after 2979 + * an LE Link is established. As per Core Spec v5.0, Vol 2, Part B 2980 + * Section 3.3, the HCI command WRITE_AUTH_PAYLOAD_TIMEOUT should be 2981 + * sent when the link is active and Encryption is enabled, the conn 2982 + * type can be either LE or ACL and controller must support LMP Ping. 2983 + * Ensure for AES-CCM encryption as well. 2984 + */ 2985 + if (test_bit(HCI_CONN_ENCRYPT, &conn->flags) && 2986 + test_bit(HCI_CONN_AES_CCM, &conn->flags) && 2987 + ((conn->type == ACL_LINK && lmp_ping_capable(hdev)) || 2988 + (conn->type == LE_LINK && (hdev->le_features[0] & HCI_LE_PING)))) { 2989 + struct hci_cp_write_auth_payload_to cp; 2990 + 2991 + cp.handle = cpu_to_le16(conn->handle); 2992 + cp.timeout = cpu_to_le16(hdev->auth_payload_timeout); 2993 + hci_send_cmd(conn->hdev, HCI_OP_WRITE_AUTH_PAYLOAD_TO, 2994 + sizeof(cp), &cp); 2995 + } 2996 + 3023 2997 notify: 3024 2998 if (conn->state == BT_CONFIG) { 3025 2999 if (!ev->status) ··· 3232 3168 3233 3169 case HCI_OP_WRITE_SC_SUPPORT: 3234 3170 hci_cc_write_sc_support(hdev, skb); 3171 + break; 3172 + 3173 + case HCI_OP_READ_AUTH_PAYLOAD_TO: 3174 + hci_cc_read_auth_payload_timeout(hdev, skb); 3175 + break; 3176 + 3177 + case HCI_OP_WRITE_AUTH_PAYLOAD_TO: 3178 + hci_cc_write_auth_payload_timeout(hdev, skb); 3235 3179 break; 3236 3180 3237 3181 case HCI_OP_READ_LOCAL_VERSION: