Bluetooth: Add different pairing timeout for Legacy Pairing

The Bluetooth stack uses a reference counting for all established ACL
links and if no user (L2CAP connection) is present, the link will be
terminated to save power. The problem part is the dedicated pairing
when using Legacy Pairing (Bluetooth 2.0 and before). At that point
no user is present and pairing attempts will be disconnected within
10 seconds or less. In previous kernel version this was not a problem
since the disconnect timeout wasn't triggered on incoming connections
for the first time. However this caused issues with broken host stacks
that kept the connections around after dedicated pairing. When the
support for Simple Pairing got added, the link establishment procedure
needed to be changed and now causes issues when using Legacy Pairing

When using Simple Pairing it is possible to do a proper reference
counting of ACL link users. With Legacy Pairing this is not possible
since the specification is unclear in some areas and too many broken
Bluetooth devices have already been deployed. So instead of trying to
deal with all the broken devices, a special pairing timeout will be
introduced that increases the timeout to 60 seconds when pairing is
triggered.

If a broken devices now puts the stack into an unforeseen state, the
worst that happens is the disconnect timeout triggers after 120 seconds
instead of 4 seconds. This allows successful pairings with legacy and
broken devices now.

Based on a report by Johan Hedberg <johan.hedberg@nokia.com>

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

+40 -3
+1
include/net/bluetooth/hci.h
··· 101 101 /* HCI timeouts */ 102 102 #define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */ 103 103 #define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ 104 + #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ 104 105 #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ 105 106 #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ 106 107
+3 -2
include/net/bluetooth/hci_core.h
··· 171 171 __u8 auth_type; 172 172 __u8 sec_level; 173 173 __u8 power_save; 174 + __u16 disc_timeout; 174 175 unsigned long pend; 175 176 176 177 unsigned int sent; ··· 350 349 if (conn->type == ACL_LINK) { 351 350 del_timer(&conn->idle_timer); 352 351 if (conn->state == BT_CONNECTED) { 353 - timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT); 352 + timeo = msecs_to_jiffies(conn->disc_timeout); 354 353 if (!conn->out) 355 - timeo *= 5; 354 + timeo *= 2; 356 355 } else 357 356 timeo = msecs_to_jiffies(10); 358 357 } else
+1
net/bluetooth/hci_conn.c
··· 215 215 conn->state = BT_OPEN; 216 216 217 217 conn->power_save = 1; 218 + conn->disc_timeout = HCI_DISCONN_TIMEOUT; 218 219 219 220 switch (type) { 220 221 case ACL_LINK:
+35 -1
net/bluetooth/hci_event.c
··· 883 883 if (conn->type == ACL_LINK) { 884 884 conn->state = BT_CONFIG; 885 885 hci_conn_hold(conn); 886 + conn->disc_timeout = HCI_DISCONN_TIMEOUT; 886 887 } else 887 888 conn->state = BT_CONNECTED; 888 889 ··· 1064 1063 hci_proto_connect_cfm(conn, ev->status); 1065 1064 hci_conn_put(conn); 1066 1065 } 1067 - } else 1066 + } else { 1068 1067 hci_auth_cfm(conn, ev->status); 1068 + 1069 + hci_conn_hold(conn); 1070 + conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1071 + hci_conn_put(conn); 1072 + } 1069 1073 1070 1074 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { 1071 1075 if (!ev->status) { ··· 1485 1479 1486 1480 static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 1487 1481 { 1482 + struct hci_ev_pin_code_req *ev = (void *) skb->data; 1483 + struct hci_conn *conn; 1484 + 1488 1485 BT_DBG("%s", hdev->name); 1486 + 1487 + hci_dev_lock(hdev); 1488 + 1489 + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 1490 + if (conn) { 1491 + hci_conn_hold(conn); 1492 + conn->disc_timeout = HCI_PAIRING_TIMEOUT; 1493 + hci_conn_put(conn); 1494 + } 1495 + 1496 + hci_dev_unlock(hdev); 1489 1497 } 1490 1498 1491 1499 static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ··· 1509 1489 1510 1490 static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) 1511 1491 { 1492 + struct hci_ev_link_key_notify *ev = (void *) skb->data; 1493 + struct hci_conn *conn; 1494 + 1512 1495 BT_DBG("%s", hdev->name); 1496 + 1497 + hci_dev_lock(hdev); 1498 + 1499 + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); 1500 + if (conn) { 1501 + hci_conn_hold(conn); 1502 + conn->disc_timeout = HCI_DISCONN_TIMEOUT; 1503 + hci_conn_put(conn); 1504 + } 1505 + 1506 + hci_dev_unlock(hdev); 1513 1507 } 1514 1508 1515 1509 static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)