Skip to content

Commit 04a51d6

Browse files
committed
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 <[email protected]>
1 parent a13f316 commit 04a51d6

File tree

3 files changed

+53
-18
lines changed

3 files changed

+53
-18
lines changed

net/bluetooth/hci_conn.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,12 @@ void hci_conn_failed(struct hci_conn *conn, u8 status)
12231223

12241224
static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
12251225
{
1226-
struct hci_conn *conn = data;
1226+
struct hci_conn *conn;
1227+
u16 handle = PTR_ERR(data);
1228+
1229+
conn = hci_conn_hash_lookup_handle(hdev, handle);
1230+
if (!conn)
1231+
return;
12271232

12281233
bt_dev_dbg(hdev, "err %d", err);
12291234

@@ -1248,10 +1253,17 @@ static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
12481253

12491254
static int hci_connect_le_sync(struct hci_dev *hdev, void *data)
12501255
{
1251-
struct hci_conn *conn = data;
1256+
struct hci_conn *conn;
1257+
u16 handle = PTR_ERR(data);
1258+
1259+
conn = hci_conn_hash_lookup_handle(hdev, handle);
1260+
if (!conn)
1261+
return 0;
12521262

12531263
bt_dev_dbg(hdev, "conn %p", conn);
12541264

1265+
conn->state = BT_CONNECT;
1266+
12551267
return hci_le_create_conn_sync(hdev, conn);
12561268
}
12571269

@@ -1321,10 +1333,10 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
13211333
conn->sec_level = BT_SECURITY_LOW;
13221334
conn->conn_timeout = conn_timeout;
13231335

1324-
conn->state = BT_CONNECT;
13251336
clear_bit(HCI_CONN_SCANNING, &conn->flags);
13261337

1327-
err = hci_cmd_sync_queue(hdev, hci_connect_le_sync, conn,
1338+
err = hci_cmd_sync_queue(hdev, hci_connect_le_sync,
1339+
ERR_PTR(conn->handle),
13281340
create_le_conn_complete);
13291341
if (err) {
13301342
hci_conn_del(conn);
@@ -2858,6 +2870,9 @@ int hci_abort_conn(struct hci_conn *conn, u8 reason)
28582870
/* If the connection is pending check the command opcode since that
28592871
* might be blocking on hci_cmd_sync_work while waiting its respective
28602872
* event so we need to hci_cmd_sync_cancel to cancel it.
2873+
*
2874+
* hci_connect_le serializes the connection attempts so only one
2875+
* connection can be in BT_CONNECT at time.
28612876
*/
28622877
if (conn->state == BT_CONNECT && hdev->req_status == HCI_REQ_PEND) {
28632878
switch (hci_skb_event(hdev->sent_cmd)) {

net/bluetooth/hci_sync.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5296,6 +5296,24 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,
52965296
if (conn->type == LE_LINK)
52975297
return hci_le_connect_cancel_sync(hdev, conn, reason);
52985298

5299+
if (conn->type == ISO_LINK) {
5300+
/* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
5301+
* page 1857:
5302+
*
5303+
* If this command is issued for a CIS on the Central and the
5304+
* CIS is successfully terminated before being established,
5305+
* then an HCI_LE_CIS_Established event shall also be sent for
5306+
* this CIS with the Status Operation Cancelled by Host (0x44).
5307+
*/
5308+
if (test_bit(HCI_CONN_CREATE_CIS, &conn->flags))
5309+
return hci_disconnect_sync(hdev, conn, reason);
5310+
5311+
/* There is no way to cancel a BIS without terminating the BIG
5312+
* which is done later on connection cleanup.
5313+
*/
5314+
return 0;
5315+
}
5316+
52995317
if (hdev->hci_ver < BLUETOOTH_VER_1_2)
53005318
return 0;
53015319

@@ -5322,11 +5340,27 @@ static int hci_reject_sco_sync(struct hci_dev *hdev, struct hci_conn *conn,
53225340
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
53235341
}
53245342

5343+
static int hci_le_reject_cis_sync(struct hci_dev *hdev, struct hci_conn *conn,
5344+
u8 reason)
5345+
{
5346+
struct hci_cp_le_reject_cis cp;
5347+
5348+
memset(&cp, 0, sizeof(cp));
5349+
cp.handle = cpu_to_le16(conn->handle);
5350+
cp.reason = reason;
5351+
5352+
return __hci_cmd_sync_status(hdev, HCI_OP_LE_REJECT_CIS,
5353+
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
5354+
}
5355+
53255356
static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
53265357
u8 reason)
53275358
{
53285359
struct hci_cp_reject_conn_req cp;
53295360

5361+
if (conn->type == ISO_LINK)
5362+
return hci_le_reject_cis_sync(hdev, conn, reason);
5363+
53305364
if (conn->type == SCO_LINK || conn->type == ESCO_LINK)
53315365
return hci_reject_sco_sync(hdev, conn, reason);
53325366

net/bluetooth/iso.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -614,18 +614,6 @@ static void iso_sock_kill(struct sock *sk)
614614
sock_put(sk);
615615
}
616616

617-
static void iso_conn_defer_reject(struct hci_conn *conn)
618-
{
619-
struct hci_cp_le_reject_cis cp;
620-
621-
BT_DBG("conn %p", conn);
622-
623-
memset(&cp, 0, sizeof(cp));
624-
cp.handle = cpu_to_le16(conn->handle);
625-
cp.reason = HCI_ERROR_REJ_BAD_ADDR;
626-
hci_send_cmd(conn->hdev, HCI_OP_LE_REJECT_CIS, sizeof(cp), &cp);
627-
}
628-
629617
static void __iso_sock_close(struct sock *sk)
630618
{
631619
BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket);
@@ -650,8 +638,6 @@ static void __iso_sock_close(struct sock *sk)
650638
break;
651639

652640
case BT_CONNECT2:
653-
if (iso_pi(sk)->conn->hcon)
654-
iso_conn_defer_reject(iso_pi(sk)->conn->hcon);
655641
iso_chan_del(sk, ECONNRESET);
656642
break;
657643
case BT_CONNECT:

0 commit comments

Comments
 (0)