Skip to content

Commit 07a9342

Browse files
iulia-tanasescuVudentz
authored andcommitted
Bluetooth: ISO: Send BIG Create Sync via hci_sync
Before issuing the LE BIG Create Sync command, an available BIG handle is chosen by iterating through the conn_hash list and finding the first unused value. If a BIG is terminated, the associated hcons are removed from the list and the LE BIG Terminate Sync command is sent via hci_sync queue. However, a new LE BIG Create sync command might be issued via hci_send_cmd, before the previous BIG sync was terminated. This can cause the same BIG handle to be reused and the LE BIG Create Sync to fail with Command Disallowed. < HCI Command: LE Broadcast Isochronous Group Create Sync (0x08|0x006b) BIG Handle: 0x00 BIG Sync Handle: 0x0002 Encryption: Unencrypted (0x00) Broadcast Code[16]: 00000000000000000000000000000000 Maximum Number Subevents: 0x00 Timeout: 20000 ms (0x07d0) Number of BIS: 1 BIS ID: 0x01 > HCI Event: Command Status (0x0f) plen 4 LE Broadcast Isochronous Group Create Sync (0x08|0x006b) ncmd 1 Status: Command Disallowed (0x0c) < HCI Command: LE Broadcast Isochronous Group Terminate Sync (0x08|0x006c) BIG Handle: 0x00 This commit fixes the ordering of the LE BIG Create Sync/LE BIG Terminate Sync commands, to make sure that either the previous BIG sync is terminated before reusing the handle, or that a new handle is chosen for a new sync. Fixes: eca0ae4 ("Bluetooth: Add initial implementation of BIS connections") Signed-off-by: Iulia Tanasescu <[email protected]> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 25ab2db commit 07a9342

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

net/bluetooth/hci_conn.c

+16-1
Original file line numberDiff line numberDiff line change
@@ -2180,7 +2180,15 @@ static bool hci_conn_check_create_big_sync(struct hci_conn *conn)
21802180
return true;
21812181
}
21822182

2183-
int hci_le_big_create_sync_pending(struct hci_dev *hdev)
2183+
static void big_create_sync_complete(struct hci_dev *hdev, void *data, int err)
2184+
{
2185+
bt_dev_dbg(hdev, "");
2186+
2187+
if (err)
2188+
bt_dev_err(hdev, "Unable to create BIG sync: %d", err);
2189+
}
2190+
2191+
static int big_create_sync(struct hci_dev *hdev, void *data)
21842192
{
21852193
DEFINE_FLEX(struct hci_cp_le_big_create_sync, pdu, bis, num_bis, 0x11);
21862194
struct hci_conn *conn;
@@ -2237,6 +2245,13 @@ int hci_le_big_create_sync_pending(struct hci_dev *hdev)
22372245
struct_size(pdu, bis, pdu->num_bis), pdu);
22382246
}
22392247

2248+
int hci_le_big_create_sync_pending(struct hci_dev *hdev)
2249+
{
2250+
/* Queue big_create_sync */
2251+
return hci_cmd_sync_queue_once(hdev, big_create_sync,
2252+
NULL, big_create_sync_complete);
2253+
}
2254+
22402255
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
22412256
struct bt_iso_qos *qos,
22422257
__u16 sync_handle, __u8 num_bis, __u8 bis[])

net/bluetooth/iso.c

+9
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,13 @@ static void iso_conn_big_sync(struct sock *sk)
13921392
if (!hdev)
13931393
return;
13941394

1395+
/* hci_le_big_create_sync requires hdev lock to be held, since
1396+
* it enqueues the HCI LE BIG Create Sync command via
1397+
* hci_cmd_sync_queue_once, which checks hdev flags that might
1398+
* change.
1399+
*/
1400+
hci_dev_lock(hdev);
1401+
13951402
if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
13961403
err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
13971404
&iso_pi(sk)->qos,
@@ -1402,6 +1409,8 @@ static void iso_conn_big_sync(struct sock *sk)
14021409
bt_dev_err(hdev, "hci_le_big_create_sync: %d",
14031410
err);
14041411
}
1412+
1413+
hci_dev_unlock(hdev);
14051414
}
14061415

14071416
static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,

0 commit comments

Comments
 (0)