Skip to content
/ linux Public
forked from torvalds/linux

Commit c09b80b

Browse files
committed
Bluetooth: hci_conn: Fix not waiting for HCI_EVT_LE_CIS_ESTABLISHED
When submitting HCI_OP_LE_CREATE_CIS the code shall wait for HCI_EVT_LE_CIS_ESTABLISHED thus enforcing the serialization of HCI_OP_LE_CREATE_CIS as the Core spec does not allow to send them in parallel: BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2566: If the Host issues this command before all the HCI_LE_CIS_Established events from the previous use of the command have been generated, the Controller shall return the error code Command Disallowed (0x0C). Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent c14516f commit c09b80b

File tree

3 files changed

+68
-57
lines changed

3 files changed

+68
-57
lines changed

include/net/bluetooth/hci_sync.h

+2
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason);
122122

123123
int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn);
124124

125+
int hci_le_create_cis_sync(struct hci_dev *hdev, struct hci_conn *conn);
126+
125127
int hci_le_remove_cig_sync(struct hci_dev *hdev, u8 handle);
126128

127129
int hci_le_terminate_big_sync(struct hci_dev *hdev, u8 handle, u8 reason);

net/bluetooth/hci_conn.c

+1-57
Original file line numberDiff line numberDiff line change
@@ -1932,63 +1932,7 @@ bool hci_iso_setup_path(struct hci_conn *conn)
19321932

19331933
static int hci_create_cis_sync(struct hci_dev *hdev, void *data)
19341934
{
1935-
struct {
1936-
struct hci_cp_le_create_cis cp;
1937-
struct hci_cis cis[0x1f];
1938-
} cmd;
1939-
struct hci_conn *conn = data;
1940-
u8 cig;
1941-
1942-
memset(&cmd, 0, sizeof(cmd));
1943-
cmd.cis[0].acl_handle = cpu_to_le16(conn->parent->handle);
1944-
cmd.cis[0].cis_handle = cpu_to_le16(conn->handle);
1945-
cmd.cp.num_cis++;
1946-
cig = conn->iso_qos.ucast.cig;
1947-
1948-
hci_dev_lock(hdev);
1949-
1950-
rcu_read_lock();
1951-
1952-
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
1953-
struct hci_cis *cis = &cmd.cis[cmd.cp.num_cis];
1954-
1955-
if (conn == data || conn->type != ISO_LINK ||
1956-
conn->state == BT_CONNECTED ||
1957-
conn->iso_qos.ucast.cig != cig)
1958-
continue;
1959-
1960-
/* Check if all CIS(s) belonging to a CIG are ready */
1961-
if (!conn->parent || conn->parent->state != BT_CONNECTED ||
1962-
conn->state != BT_CONNECT) {
1963-
cmd.cp.num_cis = 0;
1964-
break;
1965-
}
1966-
1967-
/* Group all CIS with state BT_CONNECT since the spec don't
1968-
* allow to send them individually:
1969-
*
1970-
* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
1971-
* page 2566:
1972-
*
1973-
* If the Host issues this command before all the
1974-
* HCI_LE_CIS_Established events from the previous use of the
1975-
* command have been generated, the Controller shall return the
1976-
* error code Command Disallowed (0x0C).
1977-
*/
1978-
cis->acl_handle = cpu_to_le16(conn->parent->handle);
1979-
cis->cis_handle = cpu_to_le16(conn->handle);
1980-
cmd.cp.num_cis++;
1981-
}
1982-
1983-
rcu_read_unlock();
1984-
1985-
hci_dev_unlock(hdev);
1986-
1987-
if (!cmd.cp.num_cis)
1988-
return 0;
1989-
1990-
return hci_send_cmd(hdev, HCI_OP_LE_CREATE_CIS, sizeof(cmd.cp) +
1991-
sizeof(cmd.cis[0]) * cmd.cp.num_cis, &cmd);
1935+
return hci_le_create_cis_sync(hdev, data);
19921936
}
19931937

19941938
int hci_le_create_cis(struct hci_conn *conn)

net/bluetooth/hci_sync.c

+65
Original file line numberDiff line numberDiff line change
@@ -6137,6 +6137,71 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
61376137
return err;
61386138
}
61396139

6140+
int hci_le_create_cis_sync(struct hci_dev *hdev, struct hci_conn *conn)
6141+
{
6142+
struct {
6143+
struct hci_cp_le_create_cis cp;
6144+
struct hci_cis cis[0x1f];
6145+
} cmd;
6146+
u8 cig;
6147+
struct hci_conn *hcon = conn;
6148+
6149+
memset(&cmd, 0, sizeof(cmd));
6150+
cmd.cis[0].acl_handle = cpu_to_le16(conn->parent->handle);
6151+
cmd.cis[0].cis_handle = cpu_to_le16(conn->handle);
6152+
cmd.cp.num_cis++;
6153+
cig = conn->iso_qos.ucast.cig;
6154+
6155+
hci_dev_lock(hdev);
6156+
6157+
rcu_read_lock();
6158+
6159+
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
6160+
struct hci_cis *cis = &cmd.cis[cmd.cp.num_cis];
6161+
6162+
if (conn == hcon || conn->type != ISO_LINK ||
6163+
conn->state == BT_CONNECTED ||
6164+
conn->iso_qos.ucast.cig != cig)
6165+
continue;
6166+
6167+
/* Check if all CIS(s) belonging to a CIG are ready */
6168+
if (!conn->parent || conn->parent->state != BT_CONNECTED ||
6169+
conn->state != BT_CONNECT) {
6170+
cmd.cp.num_cis = 0;
6171+
break;
6172+
}
6173+
6174+
/* Group all CIS with state BT_CONNECT since the spec don't
6175+
* allow to send them individually:
6176+
*
6177+
* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
6178+
* page 2566:
6179+
*
6180+
* If the Host issues this command before all the
6181+
* HCI_LE_CIS_Established events from the previous use of the
6182+
* command have been generated, the Controller shall return the
6183+
* error code Command Disallowed (0x0C).
6184+
*/
6185+
cis->acl_handle = cpu_to_le16(conn->parent->handle);
6186+
cis->cis_handle = cpu_to_le16(conn->handle);
6187+
cmd.cp.num_cis++;
6188+
}
6189+
6190+
rcu_read_unlock();
6191+
6192+
hci_dev_unlock(hdev);
6193+
6194+
if (!cmd.cp.num_cis)
6195+
return 0;
6196+
6197+
/* Wait for HCI_LE_CIS_Established */
6198+
return __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_CREATE_CIS,
6199+
sizeof(cmd.cp) + sizeof(cmd.cis[0]) *
6200+
cmd.cp.num_cis, &cmd,
6201+
HCI_EVT_LE_CIS_ESTABLISHED,
6202+
conn->conn_timeout, NULL);
6203+
}
6204+
61406205
int hci_le_remove_cig_sync(struct hci_dev *hdev, u8 handle)
61416206
{
61426207
struct hci_cp_le_remove_cig cp;

0 commit comments

Comments
 (0)