Skip to content

Commit 396ce4a

Browse files
iulia-tanasescusmb49
authored andcommitted
Bluetooth: ISO: Send BIG Create Sync via hci_sync
BugLink: https://bugs.launchpad.net/bugs/2101915 [ Upstream commit 07a9342b94a91b306ed1cf6aa8254aea210764c9 ] 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 <iulia.tanasescu@nxp.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Koichiro Den <koichiro.den@canonical.com> Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
1 parent 5ae3d65 commit 396ce4a

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

net/bluetooth/hci_conn.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2196,7 +2196,15 @@ static bool hci_conn_check_create_big_sync(struct hci_conn *conn)
21962196
return true;
21972197
}
21982198

2199-
int hci_le_big_create_sync_pending(struct hci_dev *hdev)
2199+
static void big_create_sync_complete(struct hci_dev *hdev, void *data, int err)
2200+
{
2201+
bt_dev_dbg(hdev, "");
2202+
2203+
if (err)
2204+
bt_dev_err(hdev, "Unable to create BIG sync: %d", err);
2205+
}
2206+
2207+
static int big_create_sync(struct hci_dev *hdev, void *data)
22002208
{
22012209
DEFINE_FLEX(struct hci_cp_le_big_create_sync, pdu, bis, num_bis, 0x11);
22022210
struct hci_conn *conn;
@@ -2253,6 +2261,13 @@ int hci_le_big_create_sync_pending(struct hci_dev *hdev)
22532261
struct_size(pdu, bis, pdu->num_bis), pdu);
22542262
}
22552263

2264+
int hci_le_big_create_sync_pending(struct hci_dev *hdev)
2265+
{
2266+
/* Queue big_create_sync */
2267+
return hci_cmd_sync_queue_once(hdev, big_create_sync,
2268+
NULL, big_create_sync_complete);
2269+
}
2270+
22562271
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
22572272
struct bt_iso_qos *qos,
22582273
__u16 sync_handle, __u8 num_bis, __u8 bis[])

net/bluetooth/iso.c

Lines changed: 9 additions & 0 deletions
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)