Skip to content

Commit 6d0417e

Browse files
committed
Bluetooth: hci_conn: Fix not setting conn_timeout for Broadcast Receiver
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>
1 parent 49ba1ca commit 6d0417e

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
@@ -1931,6 +1931,8 @@ struct hci_cp_le_pa_create_sync {
19311931
__u8 sync_cte_type;
19321932
} __packed;
19331933

1934+
#define HCI_OP_LE_PA_CREATE_SYNC_CANCEL 0x2045
1935+
19341936
#define HCI_OP_LE_PA_TERM_SYNC 0x2046
19351937
struct hci_cp_le_pa_term_sync {
19361938
__le16 handle;

include/net/bluetooth/hci_core.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,19 +1113,19 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev,
11131113
return NULL;
11141114
}
11151115

1116-
static inline struct hci_conn *hci_conn_hash_lookup_sid(struct hci_dev *hdev,
1117-
__u8 sid,
1118-
bdaddr_t *dst,
1119-
__u8 dst_type)
1116+
static inline struct hci_conn *
1117+
hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev)
11201118
{
11211119
struct hci_conn_hash *h = &hdev->conn_hash;
11221120
struct hci_conn *c;
11231121

11241122
rcu_read_lock();
11251123

11261124
list_for_each_entry_rcu(c, &h->list, list) {
1127-
if (c->type != ISO_LINK || bacmp(&c->dst, dst) ||
1128-
c->dst_type != dst_type || c->sid != sid)
1125+
if (c->type != ISO_LINK)
1126+
continue;
1127+
1128+
if (!test_bit(HCI_CONN_CREATE_PA_SYNC, &c->flags))
11291129
continue;
11301130

11311131
rcu_read_unlock();
@@ -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_pa_create_sync_pending(struct hci_dev *hdev);
15281527
int hci_le_big_create_sync_pending(struct hci_dev *hdev);
15291528
int hci_conn_check_create_cis(struct hci_conn *conn);
15301529

include/net/bluetooth/hci_sync.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,5 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn);
185185
int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn);
186186
int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn,
187187
struct hci_conn_params *params);
188+
189+
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
@@ -2064,95 +2064,6 @@ static int create_big_sync(struct hci_dev *hdev, void *data)
20642064
return hci_le_create_big(conn, &conn->iso_qos);
20652065
}
20662066

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

21712083
hci_conn_hold(conn);
21722084

2173-
hci_pa_create_sync_pending(hdev);
2085+
hci_connect_pa_sync(hdev, conn);
21742086

21752087
return conn;
21762088
}

net/bluetooth/hci_event.c

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

63796379
hci_dev_clear_flag(hdev, HCI_PA_SYNC);
63806380

6381-
conn = hci_conn_hash_lookup_sid(hdev, ev->sid, &ev->bdaddr,
6382-
ev->bdaddr_type);
6381+
conn = hci_conn_hash_lookup_create_pa_sync(hdev);
63836382
if (!conn) {
63846383
bt_dev_err(hdev,
63856384
"Unable to find connection for dst %pMR sid 0x%2.2x",
@@ -6418,9 +6417,6 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,
64186417
}
64196418

64206419
unlock:
6421-
/* Handle any other pending PA sync command */
6422-
hci_pa_create_sync_pending(hdev);
6423-
64246420
hci_dev_unlock(hdev);
64256421
}
64266422

net/bluetooth/hci_sync.c

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

26942694
/* Force address filtering if PA Sync is in progress */
26952695
if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
2696-
struct hci_cp_le_pa_create_sync *sent;
2696+
struct hci_conn *conn;
26972697

2698-
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_PA_CREATE_SYNC);
2699-
if (sent) {
2698+
conn = hci_conn_hash_lookup_create_pa_sync(hdev);
2699+
if (conn) {
27002700
struct conn_params pa;
27012701

27022702
memset(&pa, 0, sizeof(pa));
27032703

2704-
bacpy(&pa.addr, &sent->addr);
2705-
pa.addr_type = sent->addr_type;
2704+
bacpy(&pa.addr, &conn->dst);
2705+
pa.addr_type = conn->dst_type;
27062706

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

0 commit comments

Comments
 (0)