Bluetooth: hci_conn: Always use sk_timeo as conn_timeout
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 7 Feb 2024 20:26:20 +0000 (15:26 -0500)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 6 Mar 2024 22:22:41 +0000 (17:22 -0500)
This aligns the use socket sk_timeo as conn_timeout when initiating a
connection and then use it when scheduling the resulting HCI command,
that way the command is actually aborted synchronously thus not
blocking commands generated by hci_abort_conn_sync to inform the
controller the connection is to be aborted.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
net/bluetooth/6lowpan.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_sync.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/bluetooth/sco.c

index 34aa9d0290fee62b16d73fa44d1c18f2756272aa..2bdea85b7c447c178678da27ddf30aa88fefc371 100644 (file)
@@ -1495,9 +1495,10 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
                                u16 conn_timeout, u8 role);
 struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
                                 u8 sec_level, u8 auth_type,
-                                enum conn_reasons conn_reason);
+                                enum conn_reasons conn_reason, u16 timeout);
 struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
-                                __u16 setting, struct bt_codec *codec);
+                                __u16 setting, struct bt_codec *codec,
+                                u16 timeout);
 struct hci_conn *hci_bind_cis(struct hci_dev *hdev, bdaddr_t *dst,
                              __u8 dst_type, struct bt_iso_qos *qos);
 struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
index 92d7197f9a5636943a97e584921cd3730ec97c0d..a4278aa618ab110be904752449b280a3661b73b1 100644 (file)
@@ -939,7 +939,7 @@ int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);
 struct l2cap_chan *l2cap_chan_create(void);
 void l2cap_chan_close(struct l2cap_chan *chan, int reason);
 int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
-                      bdaddr_t *dst, u8 dst_type);
+                      bdaddr_t *dst, u8 dst_type, u16 timeout);
 int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu);
 int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
 void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
index 4eb1b3ced0d27eae5eb135d98fe65fcf701dff98..715cbafbf6631c275aa87f459812c7f3bdbc2923 100644 (file)
@@ -892,7 +892,7 @@ static int bt_6lowpan_connect(bdaddr_t *addr, u8 dst_type)
        chan->ops = &bt_6lowpan_chan_ops;
 
        err = l2cap_chan_connect(chan, cpu_to_le16(L2CAP_PSM_IPSP), 0,
-                                addr, dst_type);
+                                addr, dst_type, L2CAP_CONN_TIMEOUT);
 
        BT_DBG("chan %p err %d", chan, err);
        if (err < 0)
index a4beed8587eb7694fd756f109591f4f8db36eb79..8164502234c555eabd09231202d3fad9fa19b2fd 100644 (file)
@@ -1607,7 +1607,7 @@ done:
 
 struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
                                 u8 sec_level, u8 auth_type,
-                                enum conn_reasons conn_reason)
+                                enum conn_reasons conn_reason, u16 timeout)
 {
        struct hci_conn *acl;
 
@@ -1643,6 +1643,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
                acl->sec_level = BT_SECURITY_LOW;
                acl->pending_sec_level = sec_level;
                acl->auth_type = auth_type;
+               acl->conn_timeout = timeout;
 
                err = hci_acl_create_connection_sync(hdev, acl);
                if (err) {
@@ -1683,14 +1684,15 @@ static struct hci_link *hci_conn_link(struct hci_conn *parent,
 }
 
 struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
-                                __u16 setting, struct bt_codec *codec)
+                                __u16 setting, struct bt_codec *codec,
+                                u16 timeout)
 {
        struct hci_conn *acl;
        struct hci_conn *sco;
        struct hci_link *link;
 
        acl = hci_connect_acl(hdev, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING,
-                             CONN_REASON_SCO_CONNECT);
+                             CONN_REASON_SCO_CONNECT, timeout);
        if (IS_ERR(acl))
                return acl;
 
index 617407b81ffecaf2bc1dd0809ae99abdad39789f..788a889210d868bc5a3a881c19f56c43ee08015e 100644 (file)
@@ -6548,7 +6548,7 @@ static int __hci_acl_create_connection_sync(struct hci_dev *hdev, void *data)
        err = __hci_cmd_sync_status_sk(hdev, HCI_OP_CREATE_CONN,
                                       sizeof(cp), &cp,
                                       HCI_EV_CONN_COMPLETE,
-                                      HCI_ACL_CONN_TIMEOUT, NULL);
+                                      conn->conn_timeout, NULL);
 
        if (err == -ETIMEDOUT)
                hci_abort_conn_sync(hdev, conn, HCI_ERROR_LOCAL_HOST_TERM);
index ab5a9d42fae71a5c71490e5e6d957f351505f450..467b242d8be071da16bd48d04e1520ce1e1aa8a6 100644 (file)
@@ -6925,7 +6925,7 @@ static void l2cap_chan_by_pid(struct l2cap_chan *chan, void *data)
 }
 
 int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
-                      bdaddr_t *dst, u8 dst_type)
+                      bdaddr_t *dst, u8 dst_type, u16 timeout)
 {
        struct l2cap_conn *conn;
        struct hci_conn *hcon;
@@ -7018,19 +7018,17 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 
                if (hci_dev_test_flag(hdev, HCI_ADVERTISING))
                        hcon = hci_connect_le(hdev, dst, dst_type, false,
-                                             chan->sec_level,
-                                             HCI_LE_CONN_TIMEOUT,
+                                             chan->sec_level, timeout,
                                              HCI_ROLE_SLAVE);
                else
                        hcon = hci_connect_le_scan(hdev, dst, dst_type,
-                                                  chan->sec_level,
-                                                  HCI_LE_CONN_TIMEOUT,
+                                                  chan->sec_level, timeout,
                                                   CONN_REASON_L2CAP_CHAN);
 
        } else {
                u8 auth_type = l2cap_get_auth_type(chan);
                hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type,
-                                      CONN_REASON_L2CAP_CHAN);
+                                      CONN_REASON_L2CAP_CHAN, timeout);
        }
 
        if (IS_ERR(hcon)) {
index ee7a41d6994fc22fab0d0e5ba4d15fbfe2b21995..4287aa6cc988e3ce34849d1f317be8fd8645832c 100644 (file)
@@ -254,7 +254,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
                chan->mode = L2CAP_MODE_LE_FLOWCTL;
 
        err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
-                                &la.l2_bdaddr, la.l2_bdaddr_type);
+                                &la.l2_bdaddr, la.l2_bdaddr_type,
+                                sk->sk_sndtimeo);
        if (err)
                return err;
 
index 064a67157d438b8e3ce29a7bc1b0ee9ced24c6b6..78ab562807d0f161e07eae2bf579e1bd7bb1ac8f 100644 (file)
@@ -3444,7 +3444,8 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 
        if (cp->addr.type == BDADDR_BREDR) {
                conn = hci_connect_acl(hdev, &cp->addr.bdaddr, sec_level,
-                                      auth_type, CONN_REASON_PAIR_DEVICE);
+                                      auth_type, CONN_REASON_PAIR_DEVICE,
+                                      HCI_ACL_CONN_TIMEOUT);
        } else {
                u8 addr_type = le_addr_type(cp->addr.type);
                struct hci_conn_params *p;
index c736186aba26beadccd76c66f0af72835d740551..43daf965a01e4ac5c9329150080b00dcd63c7e1c 100644 (file)
@@ -264,7 +264,8 @@ static int sco_connect(struct sock *sk)
        }
 
        hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
-                              sco_pi(sk)->setting, &sco_pi(sk)->codec);
+                              sco_pi(sk)->setting, &sco_pi(sk)->codec,
+                              sk->sk_sndtimeo);
        if (IS_ERR(hcon)) {
                err = PTR_ERR(hcon);
                goto unlock;