summaryrefslogtreecommitdiff
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-06-27 15:55:47 -0700
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-08-11 11:42:43 -0700
commit04a51d616929eb96b7a3e547bc11d3bb46af2c9f (patch)
tree741f503312ed0c1a0feb7b59cfe3b923275c8d5f /net/bluetooth/hci_conn.c
parenta13f316e90fdb1fb6df6582e845aa9b3270f3581 (diff)
Bluetooth: hci_sync: Fix not handling ISO_LINK in hci_abort_conn_sync
ISO_LINK connections where not being handled properly on hci_abort_conn_sync which sometimes resulted in sending the wrong commands, or in case of having the reject command being sent by the socket code (iso.c) which is sort of a layer violation. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index fa9236dfba3e..a0ffe7db412b 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1223,7 +1223,12 @@ void hci_conn_failed(struct hci_conn *conn, u8 status)
static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
{
- struct hci_conn *conn = data;
+ struct hci_conn *conn;
+ u16 handle = PTR_ERR(data);
+
+ conn = hci_conn_hash_lookup_handle(hdev, handle);
+ if (!conn)
+ return;
bt_dev_dbg(hdev, "err %d", err);
@@ -1248,10 +1253,17 @@ done:
static int hci_connect_le_sync(struct hci_dev *hdev, void *data)
{
- struct hci_conn *conn = data;
+ struct hci_conn *conn;
+ u16 handle = PTR_ERR(data);
+
+ conn = hci_conn_hash_lookup_handle(hdev, handle);
+ if (!conn)
+ return 0;
bt_dev_dbg(hdev, "conn %p", conn);
+ conn->state = BT_CONNECT;
+
return hci_le_create_conn_sync(hdev, conn);
}
@@ -1321,10 +1333,10 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
conn->sec_level = BT_SECURITY_LOW;
conn->conn_timeout = conn_timeout;
- conn->state = BT_CONNECT;
clear_bit(HCI_CONN_SCANNING, &conn->flags);
- err = hci_cmd_sync_queue(hdev, hci_connect_le_sync, conn,
+ err = hci_cmd_sync_queue(hdev, hci_connect_le_sync,
+ ERR_PTR(conn->handle),
create_le_conn_complete);
if (err) {
hci_conn_del(conn);
@@ -2858,6 +2870,9 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
/* If the connection is pending check the command opcode since that
* might be blocking on hci_cmd_sync_work while waiting its respective
* event so we need to hci_cmd_sync_cancel to cancel it.
+ *
+ * hci_connect_le serializes the connection attempts so only one
+ * connection can be in BT_CONNECT at time.
*/
if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) {
switch (hci_skb_event(hdev->sent_cmd)) {