Skip to content

Commit 620810a

Browse files
Vudentzgregkh
authored andcommitted
Bluetooth: hci_conn: Fix not setting timeout for BIG Create Sync
[ Upstream commit 024421c ] BIG Create Sync requires the command to just generates a status so this makes use of __hci_cmd_sync_status_sk to wait for HCI_EVT_LE_BIG_SYNC_ESTABLISHED, also because of this chance it is not longer necessary to use a custom method to serialize the process of creating the BIG sync since the cmd_work_sync itself ensures only one command would be pending which now awaits for HCI_EVT_LE_BIG_SYNC_ESTABLISHED before proceeding to next connection. Fixes: 42ecf19 ("Bluetooth: ISO: Do not emit LE BIG Create Sync if previous is pending") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent eb8b860 commit 620810a

File tree

7 files changed

+88
-109
lines changed

7 files changed

+88
-109
lines changed

include/net/bluetooth/hci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2814,7 +2814,7 @@ struct hci_evt_le_create_big_complete {
28142814
__le16 bis_handle[];
28152815
} __packed;
28162816

2817-
#define HCI_EVT_LE_BIG_SYNC_ESTABILISHED 0x1d
2817+
#define HCI_EVT_LE_BIG_SYNC_ESTABLISHED 0x1d
28182818
struct hci_evt_le_big_sync_estabilished {
28192819
__u8 status;
28202820
__u8 handle;

include/net/bluetooth/hci_core.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,7 +1506,6 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
15061506
void hci_sco_setup(struct hci_conn *conn, __u8 status);
15071507
bool hci_iso_setup_path(struct hci_conn *conn);
15081508
int hci_le_create_cis_pending(struct hci_dev *hdev);
1509-
int hci_le_big_create_sync_pending(struct hci_dev *hdev);
15101509
int hci_conn_check_create_cis(struct hci_conn *conn);
15111510

15121511
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
@@ -1547,9 +1546,9 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
15471546
__u8 data_len, __u8 *data);
15481547
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
15491548
__u8 dst_type, __u8 sid, struct bt_iso_qos *qos);
1550-
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
1551-
struct bt_iso_qos *qos,
1552-
__u16 sync_handle, __u8 num_bis, __u8 bis[]);
1549+
int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
1550+
struct bt_iso_qos *qos, __u16 sync_handle,
1551+
__u8 num_bis, __u8 bis[]);
15531552
int hci_conn_check_link_mode(struct hci_conn *conn);
15541553
int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
15551554
int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type,

include/net/bluetooth/hci_sync.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,4 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
188188
struct hci_conn_params *params);
189189

190190
int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn);
191+
int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn);

net/bluetooth/hci_conn.c

Lines changed: 5 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2084,89 +2084,9 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
20842084
return conn;
20852085
}
20862086

2087-
static bool hci_conn_check_create_big_sync(struct hci_conn *conn)
2088-
{
2089-
if (!conn->num_bis)
2090-
return false;
2091-
2092-
return true;
2093-
}
2094-
2095-
static void big_create_sync_complete(struct hci_dev *hdev, void *data, int err)
2096-
{
2097-
bt_dev_dbg(hdev, "");
2098-
2099-
if (err)
2100-
bt_dev_err(hdev, "Unable to create BIG sync: %d", err);
2101-
}
2102-
2103-
static int big_create_sync(struct hci_dev *hdev, void *data)
2104-
{
2105-
DEFINE_FLEX(struct hci_cp_le_big_create_sync, pdu, bis, num_bis, 0x11);
2106-
struct hci_conn *conn;
2107-
2108-
rcu_read_lock();
2109-
2110-
pdu->num_bis = 0;
2111-
2112-
/* The spec allows only one pending LE BIG Create Sync command at
2113-
* a time. If the command is pending now, don't do anything. We
2114-
* check for pending connections after each BIG Sync Established
2115-
* event.
2116-
*
2117-
* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
2118-
* page 2586:
2119-
*
2120-
* If the Host sends this command when the Controller is in the
2121-
* process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_
2122-
* Established event has not been generated, the Controller shall
2123-
* return the error code Command Disallowed (0x0C).
2124-
*/
2125-
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
2126-
if (test_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags))
2127-
goto unlock;
2128-
}
2129-
2130-
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
2131-
if (hci_conn_check_create_big_sync(conn)) {
2132-
struct bt_iso_qos *qos = &conn->iso_qos;
2133-
2134-
set_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags);
2135-
2136-
pdu->handle = qos->bcast.big;
2137-
pdu->sync_handle = cpu_to_le16(conn->sync_handle);
2138-
pdu->encryption = qos->bcast.encryption;
2139-
memcpy(pdu->bcode, qos->bcast.bcode,
2140-
sizeof(pdu->bcode));
2141-
pdu->mse = qos->bcast.mse;
2142-
pdu->timeout = cpu_to_le16(qos->bcast.timeout);
2143-
pdu->num_bis = conn->num_bis;
2144-
memcpy(pdu->bis, conn->bis, conn->num_bis);
2145-
2146-
break;
2147-
}
2148-
}
2149-
2150-
unlock:
2151-
rcu_read_unlock();
2152-
2153-
if (!pdu->num_bis)
2154-
return 0;
2155-
2156-
return hci_send_cmd(hdev, HCI_OP_LE_BIG_CREATE_SYNC,
2157-
struct_size(pdu, bis, pdu->num_bis), pdu);
2158-
}
2159-
2160-
int hci_le_big_create_sync_pending(struct hci_dev *hdev)
2161-
{
2162-
/* Queue big_create_sync */
2163-
return hci_cmd_sync_queue_once(hdev, big_create_sync,
2164-
NULL, big_create_sync_complete);
2165-
}
2166-
2167-
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
2168-
struct bt_iso_qos *qos,
2169-
__u16 sync_handle, __u8 num_bis, __u8 bis[])
2087+
int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
2088+
struct bt_iso_qos *qos, __u16 sync_handle,
2089+
__u8 num_bis, __u8 bis[])
21702090
{
21712091
int err;
21722092

@@ -2183,9 +2103,10 @@ int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
21832103

21842104
hcon->num_bis = num_bis;
21852105
memcpy(hcon->bis, bis, num_bis);
2106+
hcon->conn_timeout = msecs_to_jiffies(qos->bcast.timeout * 10);
21862107
}
21872108

2188-
return hci_le_big_create_sync_pending(hdev);
2109+
return hci_connect_big_sync(hdev, hcon);
21892110
}
21902111

21912112
static void create_big_complete(struct hci_dev *hdev, void *data, int err)

net/bluetooth/hci_event.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6918,7 +6918,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
69186918

69196919
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
69206920

6921-
if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
6921+
if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
69226922
flex_array_size(ev, bis, ev->num_bis)))
69236923
return;
69246924

@@ -6988,9 +6988,6 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
69886988
}
69896989

69906990
unlock:
6991-
/* Handle any other pending BIG sync command */
6992-
hci_le_big_create_sync_pending(hdev);
6993-
69946991
hci_dev_unlock(hdev);
69956992
}
69966993

@@ -7112,8 +7109,8 @@ static const struct hci_le_ev {
71127109
hci_le_create_big_complete_evt,
71137110
sizeof(struct hci_evt_le_create_big_complete),
71147111
HCI_MAX_EVENT_SIZE),
7115-
/* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */
7116-
HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
7112+
/* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABLISHED] */
7113+
HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
71177114
hci_le_big_sync_established_evt,
71187115
sizeof(struct hci_evt_le_big_sync_estabilished),
71197116
HCI_MAX_EVENT_SIZE),

net/bluetooth/hci_sync.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6964,3 +6964,66 @@ int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn)
69646964
return hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync, conn,
69656965
create_pa_complete);
69666966
}
6967+
6968+
static void create_big_complete(struct hci_dev *hdev, void *data, int err)
6969+
{
6970+
struct hci_conn *conn = data;
6971+
6972+
bt_dev_dbg(hdev, "err %d", err);
6973+
6974+
if (err == -ECANCELED)
6975+
return;
6976+
6977+
if (hci_conn_valid(hdev, conn))
6978+
clear_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags);
6979+
}
6980+
6981+
static int hci_le_big_create_sync(struct hci_dev *hdev, void *data)
6982+
{
6983+
DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, 0x11);
6984+
struct hci_conn *conn = data;
6985+
struct bt_iso_qos *qos = &conn->iso_qos;
6986+
int err;
6987+
6988+
if (!hci_conn_valid(hdev, conn))
6989+
return -ECANCELED;
6990+
6991+
set_bit(HCI_CONN_CREATE_BIG_SYNC, &conn->flags);
6992+
6993+
memset(cp, 0, sizeof(*cp));
6994+
cp->handle = qos->bcast.big;
6995+
cp->sync_handle = cpu_to_le16(conn->sync_handle);
6996+
cp->encryption = qos->bcast.encryption;
6997+
memcpy(cp->bcode, qos->bcast.bcode, sizeof(cp->bcode));
6998+
cp->mse = qos->bcast.mse;
6999+
cp->timeout = cpu_to_le16(qos->bcast.timeout);
7000+
cp->num_bis = conn->num_bis;
7001+
memcpy(cp->bis, conn->bis, conn->num_bis);
7002+
7003+
/* The spec allows only one pending LE BIG Create Sync command at
7004+
* a time, so we forcefully wait for BIG Sync Established event since
7005+
* cmd_work can only schedule one command at a time.
7006+
*
7007+
* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
7008+
* page 2586:
7009+
*
7010+
* If the Host sends this command when the Controller is in the
7011+
* process of synchronizing to any BIG, i.e. the HCI_LE_BIG_Sync_
7012+
* Established event has not been generated, the Controller shall
7013+
* return the error code Command Disallowed (0x0C).
7014+
*/
7015+
err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_BIG_CREATE_SYNC,
7016+
struct_size(cp, bis, cp->num_bis), cp,
7017+
HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
7018+
conn->conn_timeout, NULL);
7019+
if (err == -ETIMEDOUT)
7020+
hci_le_big_terminate_sync(hdev, cp->handle);
7021+
7022+
return err;
7023+
}
7024+
7025+
int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn)
7026+
{
7027+
return hci_cmd_sync_queue_once(hdev, hci_le_big_create_sync, conn,
7028+
create_big_complete);
7029+
}

net/bluetooth/iso.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,14 +1414,13 @@ static void iso_conn_big_sync(struct sock *sk)
14141414
lock_sock(sk);
14151415

14161416
if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
1417-
err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
1418-
&iso_pi(sk)->qos,
1419-
iso_pi(sk)->sync_handle,
1420-
iso_pi(sk)->bc_num_bis,
1421-
iso_pi(sk)->bc_bis);
1417+
err = hci_conn_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
1418+
&iso_pi(sk)->qos,
1419+
iso_pi(sk)->sync_handle,
1420+
iso_pi(sk)->bc_num_bis,
1421+
iso_pi(sk)->bc_bis);
14221422
if (err)
1423-
bt_dev_err(hdev, "hci_le_big_create_sync: %d",
1424-
err);
1423+
bt_dev_err(hdev, "hci_big_create_sync: %d", err);
14251424
}
14261425

14271426
release_sock(sk);
@@ -1855,7 +1854,7 @@ static void iso_conn_ready(struct iso_conn *conn)
18551854
if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags) ||
18561855
test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
18571856
ev = hci_recv_event_data(hcon->hdev,
1858-
HCI_EVT_LE_BIG_SYNC_ESTABILISHED);
1857+
HCI_EVT_LE_BIG_SYNC_ESTABLISHED);
18591858

18601859
/* Get reference to PA sync parent socket, if it exists */
18611860
parent = iso_get_sock(&hcon->src, &hcon->dst,
@@ -2047,12 +2046,11 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
20472046

20482047
if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
20492048
!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
2050-
err = hci_le_big_create_sync(hdev,
2051-
hcon,
2052-
&iso_pi(sk)->qos,
2053-
iso_pi(sk)->sync_handle,
2054-
iso_pi(sk)->bc_num_bis,
2055-
iso_pi(sk)->bc_bis);
2049+
err = hci_conn_big_create_sync(hdev, hcon,
2050+
&iso_pi(sk)->qos,
2051+
iso_pi(sk)->sync_handle,
2052+
iso_pi(sk)->bc_num_bis,
2053+
iso_pi(sk)->bc_bis);
20562054
if (err) {
20572055
bt_dev_err(hdev, "hci_le_big_create_sync: %d",
20582056
err);

0 commit comments

Comments
 (0)