Bluetooth: hci_sync: Use address filtering when HCI_PA_SYNC is set

If HCI_PA_SYNC flag is set it means there is a Periodic Advertising
Synchronization pending, so this attempts to locate the address passed
to HCI_OP_LE_PA_CREATE_SYNC and program it in the accept list so only
reports with that address are processed.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2024-02-21 09:38:09 -05:00
parent 168d9bf9c7
commit bba71ef13b

View file

@ -2562,6 +2562,16 @@ static struct conn_params *conn_params_copy(struct list_head *list, size_t *n)
return p;
}
/* Clear LE Accept List */
static int hci_le_clear_accept_list_sync(struct hci_dev *hdev)
{
if (!(hdev->commands[26] & 0x80))
return 0;
return __hci_cmd_sync_status(hdev, HCI_OP_LE_CLEAR_ACCEPT_LIST, 0, NULL,
HCI_CMD_TIMEOUT);
}
/* Device must not be scanning when updating the accept list.
*
* Update is done using the following sequence:
@ -2610,6 +2620,31 @@ static u8 hci_update_accept_list_sync(struct hci_dev *hdev)
goto done;
}
/* Force address filtering if PA Sync is in progress */
if (hci_dev_test_flag(hdev, HCI_PA_SYNC)) {
struct hci_cp_le_pa_create_sync *sent;
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_PA_CREATE_SYNC);
if (sent) {
struct conn_params pa;
memset(&pa, 0, sizeof(pa));
bacpy(&pa.addr, &sent->addr);
pa.addr_type = sent->addr_type;
/* Clear first since there could be addresses left
* behind.
*/
hci_le_clear_accept_list_sync(hdev);
num_entries = 1;
err = hci_le_add_accept_list_sync(hdev, &pa,
&num_entries);
goto done;
}
}
/* Go through the current accept list programmed into the
* controller one by one and check if that address is connected or is
* still in the list of pending connections or list of devices to
@ -4216,16 +4251,6 @@ static int hci_le_read_accept_list_size_sync(struct hci_dev *hdev)
0, NULL, HCI_CMD_TIMEOUT);
}
/* Clear LE Accept List */
static int hci_le_clear_accept_list_sync(struct hci_dev *hdev)
{
if (!(hdev->commands[26] & 0x80))
return 0;
return __hci_cmd_sync_status(hdev, HCI_OP_LE_CLEAR_ACCEPT_LIST, 0, NULL,
HCI_CMD_TIMEOUT);
}
/* Read LE Resolving List Size */
static int hci_le_read_resolv_list_size_sync(struct hci_dev *hdev)
{