Commit bba71ef1 authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz
Browse files

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: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 168d9bf9
Loading
Loading
Loading
Loading
+35 −10
Original line number Diff line number Diff line
@@ -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)
{