Skip to content

Commit 024421c

Browse files
committed
Bluetooth: hci_conn: Fix not setting timeout for BIG Create Sync
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>
1 parent 6d0417e commit 024421c

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
@@ -2832,7 +2832,7 @@ struct hci_evt_le_create_big_complete {
28322832
__le16 bis_handle[];
28332833
} __packed;
28342834

2835-
#define HCI_EVT_LE_BIG_SYNC_ESTABILISHED 0x1d
2835+
#define HCI_EVT_LE_BIG_SYNC_ESTABLISHED 0x1d
28362836
struct hci_evt_le_big_sync_estabilished {
28372837
__u8 status;
28382838
__u8 handle;

include/net/bluetooth/hci_core.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,7 +1524,6 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle);
15241524
void hci_sco_setup(struct hci_conn *conn, __u8 status);
15251525
bool hci_iso_setup_path(struct hci_conn *conn);
15261526
int hci_le_create_cis_pending(struct hci_dev *hdev);
1527-
int hci_le_big_create_sync_pending(struct hci_dev *hdev);
15281527
int hci_conn_check_create_cis(struct hci_conn *conn);
15291528

15301529
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
@@ -1565,9 +1564,9 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,
15651564
__u8 data_len, __u8 *data);
15661565
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
15671566
__u8 dst_type, __u8 sid, struct bt_iso_qos *qos);
1568-
int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
1569-
struct bt_iso_qos *qos,
1570-
__u16 sync_handle, __u8 num_bis, __u8 bis[]);
1567+
int hci_conn_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
1568+
struct bt_iso_qos *qos, __u16 sync_handle,
1569+
__u8 num_bis, __u8 bis[]);
15711570
int hci_conn_check_link_mode(struct hci_conn *conn);
15721571
int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level);
15731572
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
@@ -187,3 +187,4 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
187187
struct hci_conn_params *params);
188188

189189
int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn);
190+
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
@@ -2087,89 +2087,9 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
20872087
return conn;
20882088
}
20892089

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

@@ -2186,9 +2106,10 @@ int hci_le_big_create_sync(struct hci_dev *hdev, struct hci_conn *hcon,
21862106

21872107
hcon->num_bis = num_bis;
21882108
memcpy(hcon->bis, bis, num_bis);
2109+
hcon->conn_timeout = msecs_to_jiffies(qos->bcast.timeout * 10);
21892110
}
21902111

2191-
return hci_le_big_create_sync_pending(hdev);
2112+
return hci_connect_big_sync(hdev, hcon);
21922113
}
21932114

21942115
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
@@ -6928,7 +6928,7 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
69286928

69296929
bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
69306930

6931-
if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
6931+
if (!hci_le_ev_skb_pull(hdev, skb, HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
69326932
flex_array_size(ev, bis, ev->num_bis)))
69336933
return;
69346934

@@ -6999,9 +6999,6 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data,
69996999
}
70007000

70017001
unlock:
7002-
/* Handle any other pending BIG sync command */
7003-
hci_le_big_create_sync_pending(hdev);
7004-
70057002
hci_dev_unlock(hdev);
70067003
}
70077004

@@ -7123,8 +7120,8 @@ static const struct hci_le_ev {
71237120
hci_le_create_big_complete_evt,
71247121
sizeof(struct hci_evt_le_create_big_complete),
71257122
HCI_MAX_EVENT_SIZE),
7126-
/* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABILISHED] */
7127-
HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABILISHED,
7123+
/* [0x1d = HCI_EV_LE_BIG_SYNC_ESTABLISHED] */
7124+
HCI_LE_EV_VL(HCI_EVT_LE_BIG_SYNC_ESTABLISHED,
71287125
hci_le_big_sync_established_evt,
71297126
sizeof(struct hci_evt_le_big_sync_estabilished),
71307127
HCI_MAX_EVENT_SIZE),

net/bluetooth/hci_sync.c

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

net/bluetooth/iso.c

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

14641464
if (!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
1465-
err = hci_le_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
1466-
&iso_pi(sk)->qos,
1467-
iso_pi(sk)->sync_handle,
1468-
iso_pi(sk)->bc_num_bis,
1469-
iso_pi(sk)->bc_bis);
1465+
err = hci_conn_big_create_sync(hdev, iso_pi(sk)->conn->hcon,
1466+
&iso_pi(sk)->qos,
1467+
iso_pi(sk)->sync_handle,
1468+
iso_pi(sk)->bc_num_bis,
1469+
iso_pi(sk)->bc_bis);
14701470
if (err)
1471-
bt_dev_err(hdev, "hci_le_big_create_sync: %d",
1472-
err);
1471+
bt_dev_err(hdev, "hci_big_create_sync: %d", err);
14731472
}
14741473

14751474
release_sock(sk);
@@ -1922,7 +1921,7 @@ static void iso_conn_ready(struct iso_conn *conn)
19221921
hcon);
19231922
} else if (test_bit(HCI_CONN_BIG_SYNC_FAILED, &hcon->flags)) {
19241923
ev = hci_recv_event_data(hcon->hdev,
1925-
HCI_EVT_LE_BIG_SYNC_ESTABILISHED);
1924+
HCI_EVT_LE_BIG_SYNC_ESTABLISHED);
19261925

19271926
/* Get reference to PA sync parent socket, if it exists */
19281927
parent = iso_get_sock(&hcon->src, &hcon->dst,
@@ -2113,12 +2112,11 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
21132112

21142113
if (!test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags) &&
21152114
!test_and_set_bit(BT_SK_BIG_SYNC, &iso_pi(sk)->flags)) {
2116-
err = hci_le_big_create_sync(hdev,
2117-
hcon,
2118-
&iso_pi(sk)->qos,
2119-
iso_pi(sk)->sync_handle,
2120-
iso_pi(sk)->bc_num_bis,
2121-
iso_pi(sk)->bc_bis);
2115+
err = hci_conn_big_create_sync(hdev, hcon,
2116+
&iso_pi(sk)->qos,
2117+
iso_pi(sk)->sync_handle,
2118+
iso_pi(sk)->bc_num_bis,
2119+
iso_pi(sk)->bc_bis);
21222120
if (err) {
21232121
bt_dev_err(hdev, "hci_le_big_create_sync: %d",
21242122
err);

0 commit comments

Comments
 (0)