Skip to content

Commit eb8b860

Browse files
Vudentzgregkh
authored andcommitted
Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver
[ Upstream commit 6d0417e ] Broadcast Receiver requires creating PA sync but the command just generates a status so this makes use of __hci_cmd_sync_status_sk to wait for HCI_EV_LE_PA_SYNC_ESTABLISHED, also because of this chance it is not longer necessary to use a custom method to serialize the process of creating the PA sync since the cmd_work_sync itself ensures only one command would be pending which now awaits for HCI_EV_LE_PA_SYNC_ESTABLISHED before proceeding to next connection. Fixes: 4a5e0ba ("Bluetooth: ISO: Do not emit LE PA 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 fe81c26 commit eb8b860

File tree

6 files changed

+95
-107
lines changed

6 files changed

+95
-107
lines changed

include/net/bluetooth/hci.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,6 +1913,8 @@ struct hci_cp_le_pa_create_sync {
19131913
__u8 sync_cte_type;
19141914
} __packed;
19151915

1916+
#define HCI_OP_LE_PA_CREATE_SYNC_CANCEL 0x2045
1917+
19161918
#define HCI_OP_LE_PA_TERM_SYNC 0x2046
19171919
struct hci_cp_le_pa_term_sync {
19181920
__le16 handle;

include/net/bluetooth/hci_core.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,19 +1105,19 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev,
11051105
return NULL;
11061106
}
11071107

1108-
static inline struct hci_conn *hci_conn_hash_lookup_sid(struct hci_dev *hdev,
1109-
__u8 sid,
1110-
bdaddr_t *dst,
1111-
__u8 dst_type)
1108+
static inline struct hci_conn *
1109+
hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev)
11121110
{
11131111
struct hci_conn_hash *h = &hdev->conn_hash;
11141112
struct hci_conn *c;
11151113

11161114
rcu_read_lock();
11171115

11181116
list_for_each_entry_rcu(c, &h->list, list) {
1119-
if (c->type != ISO_LINK || bacmp(&c->dst, dst) ||
1120-
c->dst_type != dst_type || c->sid != sid)
1117+
if (c->type != ISO_LINK)
1118+
continue;
1119+
1120+
if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags))
11211121
continue;
11221122

11231123
rcu_read_unlock();
@@ -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_pa_create_sync_pending(struct hci_dev *hdev);
15101509
int hci_le_big_create_sync_pending(struct hci_dev *hdev);
15111510
int hci_conn_check_create_cis(struct hci_conn *conn);
15121511

include/net/bluetooth/hci_sync.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,5 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn);
186186
int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn);
187187
int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
188188
struct hci_conn_params *params);
189+
190+
int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn);

net/bluetooth/hci_conn.c

Lines changed: 2 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,95 +2061,6 @@ static int create_big_sync(struct hci_dev *hdev, void *data)
20612061
return hci_le_create_big(conn, &conn->iso_qos);
20622062
}
20632063

2064-
static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
2065-
{
2066-
bt_dev_dbg(hdev, "");
2067-
2068-
if (err)
2069-
bt_dev_err(hdev, "Unable to create PA: %d", err);
2070-
}
2071-
2072-
static bool hci_conn_check_create_pa_sync(struct hci_conn *conn)
2073-
{
2074-
if (conn->type != ISO_LINK || conn->sid == HCI_SID_INVALID)
2075-
return false;
2076-
2077-
return true;
2078-
}
2079-
2080-
static int create_pa_sync(struct hci_dev *hdev, void *data)
2081-
{
2082-
struct hci_cp_le_pa_create_sync cp = {0};
2083-
struct hci_conn *conn;
2084-
int err = 0;
2085-
2086-
hci_dev_lock(hdev);
2087-
2088-
rcu_read_lock();
2089-
2090-
/* The spec allows only one pending LE Periodic Advertising Create
2091-
* Sync command at a time. If the command is pending now, don't do
2092-
* anything. We check for pending connections after each PA Sync
2093-
* Established event.
2094-
*
2095-
* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
2096-
* page 2493:
2097-
*
2098-
* If the Host issues this command when another HCI_LE_Periodic_
2099-
* Advertising_Create_Sync command is pending, the Controller shall
2100-
* return the error code Command Disallowed (0x0C).
2101-
*/
2102-
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
2103-
if (test_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags))
2104-
goto unlock;
2105-
}
2106-
2107-
list_for_each_entry_rcu(conn, &hdev->conn_hash.list, list) {
2108-
if (hci_conn_check_create_pa_sync(conn)) {
2109-
struct bt_iso_qos *qos = &conn->iso_qos;
2110-
2111-
cp.options = qos->bcast.options;
2112-
cp.sid = conn->sid;
2113-
cp.addr_type = conn->dst_type;
2114-
bacpy(&cp.addr, &conn->dst);
2115-
cp.skip = cpu_to_le16(qos->bcast.skip);
2116-
cp.sync_timeout = cpu_to_le16(qos->bcast.sync_timeout);
2117-
cp.sync_cte_type = qos->bcast.sync_cte_type;
2118-
2119-
break;
2120-
}
2121-
}
2122-
2123-
unlock:
2124-
rcu_read_unlock();
2125-
2126-
hci_dev_unlock(hdev);
2127-
2128-
if (bacmp(&cp.addr, BDADDR_ANY)) {
2129-
hci_dev_set_flag(hdev, HCI_PA_SYNC);
2130-
set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
2131-
2132-
err = __hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC,
2133-
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
2134-
if (!err)
2135-
err = hci_update_passive_scan_sync(hdev);
2136-
2137-
if (err) {
2138-
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
2139-
clear_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
2140-
}
2141-
}
2142-
2143-
return err;
2144-
}
2145-
2146-
int hci_pa_create_sync_pending(struct hci_dev *hdev)
2147-
{
2148-
/* Queue start pa_create_sync and scan */
2149-
return hci_cmd_sync_queue(hdev, create_pa_sync,
2150-
NULL, create_pa_complete);
2151-
}
2152-
21532064
struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
21542065
__u8 dst_type, __u8 sid,
21552066
struct bt_iso_qos *qos)
@@ -2164,10 +2075,11 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,
21642075
conn->dst_type = dst_type;
21652076
conn->sid = sid;
21662077
conn->state = BT_LISTEN;
2078+
conn->conn_timeout = msecs_to_jiffies(qos->bcast.sync_timeout * 10);
21672079

21682080
hci_conn_hold(conn);
21692081

2170-
hci_pa_create_sync_pending(hdev);
2082+
hci_connect_pa_sync(hdev, conn);
21712083

21722084
return conn;
21732085
}

net/bluetooth/hci_event.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6368,8 +6368,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
63686368

63696369
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
63706370

6371-
conn = hci_conn_hash_lookup_sid(hdev, ev->sid, &ev->bdaddr,
6372-
ev->bdaddr_type);
6371+
conn = hci_conn_hash_lookup_create_pa_sync(hdev);
63736372
if (!conn) {
63746373
bt_dev_err(hdev,
63756374
"Unable to find connection for dst %pMR sid 0x%2.2x",
@@ -6408,9 +6407,6 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
64086407
}
64096408

64106409
unlock:
6411-
/* Handle any other pending PA sync command */
6412-
hci_pa_create_sync_pending(hdev);
6413-
64146410
hci_dev_unlock(hdev);
64156411
}
64166412

net/bluetooth/hci_sync.c

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,16 +2717,16 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
27172717

27182718
/* Force address filtering if PA Sync is in progress */
27192719
if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
2720-
struct hci_cp_le_pa_create_sync *sent;
2720+
struct hci_conn *conn;
27212721

2722-
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_PA_CREATE_SYNC);
2723-
if (sent) {
2722+
conn = hci_conn_hash_lookup_create_pa_sync(hdev);
2723+
if (conn) {
27242724
struct conn_params pa;
27252725

27262726
memset(&pa, 0, sizeof(pa));
27272727

2728-
bacpy(&pa.addr, &sent->addr);
2729-
pa.addr_type = sent->addr_type;
2728+
bacpy(&pa.addr, &conn->dst);
2729+
pa.addr_type = conn->dst_type;
27302730

27312731
/* Clear first since there could be addresses left
27322732
* behind.
@@ -6887,3 +6887,80 @@ int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
68876887
return __hci_cmd_sync_status(hdev, HCI_OP_LE_CONN_UPDATE,
68886888
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
68896889
}
6890+
6891+
static void create_pa_complete(struct hci_dev *hdev, void *data, int err)
6892+
{
6893+
bt_dev_dbg(hdev, "err %d", err);
6894+
6895+
if (!err)
6896+
return;
6897+
6898+
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
6899+
6900+
if (err == -ECANCELED)
6901+
return;
6902+
6903+
hci_dev_lock(hdev);
6904+
6905+
hci_update_passive_scan_sync(hdev);
6906+
6907+
hci_dev_unlock(hdev);
6908+
}
6909+
6910+
static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)
6911+
{
6912+
struct hci_cp_le_pa_create_sync cp;
6913+
struct hci_conn *conn = data;
6914+
struct bt_iso_qos *qos = &conn->iso_qos;
6915+
int err;
6916+
6917+
if (!hci_conn_valid(hdev, conn))
6918+
return -ECANCELED;
6919+
6920+
if (hci_dev_test_and_set_flag(hdev, HCI_PA_SYNC))
6921+
return -EBUSY;
6922+
6923+
/* Mark HCI_CONN_CREATE_PA_SYNC so hci_update_passive_scan_sync can
6924+
* program the address in the allow list so PA advertisements can be
6925+
* received.
6926+
*/
6927+
set_bit(HCI_CONN_CREATE_PA_SYNC, &conn->flags);
6928+
6929+
hci_update_passive_scan_sync(hdev);
6930+
6931+
memset(&cp, 0, sizeof(cp));
6932+
cp.options = qos->bcast.options;
6933+
cp.sid = conn->sid;
6934+
cp.addr_type = conn->dst_type;
6935+
bacpy(&cp.addr, &conn->dst);
6936+
cp.skip = cpu_to_le16(qos->bcast.skip);
6937+
cp.sync_timeout = cpu_to_le16(qos->bcast.sync_timeout);
6938+
cp.sync_cte_type = qos->bcast.sync_cte_type;
6939+
6940+
/* The spec allows only one pending LE Periodic Advertising Create
6941+
* Sync command at a time so we forcefully wait for PA Sync Established
6942+
* event since cmd_work can only schedule one command at a time.
6943+
*
6944+
* BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E
6945+
* page 2493:
6946+
*
6947+
* If the Host issues this command when another HCI_LE_Periodic_
6948+
* Advertising_Create_Sync command is pending, the Controller shall
6949+
* return the error code Command Disallowed (0x0C).
6950+
*/
6951+
err = __hci_cmd_sync_status_sk(hdev, HCI_OP_LE_PA_CREATE_SYNC,
6952+
sizeof(cp), &cp,
6953+
HCI_EV_LE_PA_SYNC_ESTABLISHED,
6954+
conn->conn_timeout, NULL);
6955+
if (err == -ETIMEDOUT)
6956+
__hci_cmd_sync_status(hdev, HCI_OP_LE_PA_CREATE_SYNC_CANCEL,
6957+
0, NULL, HCI_CMD_TIMEOUT);
6958+
6959+
return err;
6960+
}
6961+
6962+
int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn)
6963+
{
6964+
return hci_cmd_sync_queue_once(hdev, hci_le_pa_create_sync, conn,
6965+
create_pa_complete);
6966+
}

0 commit comments

Comments
 (0)