mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-06 05:13:18 +00:00
Bluetooth: hci_core: Remove le_restart_scan work
This removes le_restart_scan work and instead just disables controller duplicate filtering when discovery result_filtering is enabled and HCI_QUIRK_STRICT_DUPLICATE_FILTER is set. Link: https://github.com/bluez/bluez/issues/573 Link: https://github.com/bluez/bluez/issues/572 Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
ba9e401493
commit
78db544b5d
@ -539,7 +539,6 @@ struct hci_dev {
|
||||
struct work_struct tx_work;
|
||||
|
||||
struct delayed_work le_scan_disable;
|
||||
struct delayed_work le_scan_restart;
|
||||
|
||||
struct sk_buff_head rx_q;
|
||||
struct sk_buff_head raw_q;
|
||||
|
@ -348,8 +348,6 @@ static void le_scan_disable(struct work_struct *work)
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
|
||||
goto _return;
|
||||
|
||||
cancel_delayed_work(&hdev->le_scan_restart);
|
||||
|
||||
status = hci_cmd_sync_queue(hdev, scan_disable_sync, NULL, NULL);
|
||||
if (status) {
|
||||
bt_dev_err(hdev, "failed to disable LE scan: %d", status);
|
||||
@ -397,71 +395,6 @@ static void le_scan_disable(struct work_struct *work)
|
||||
|
||||
static int hci_le_set_scan_enable_sync(struct hci_dev *hdev, u8 val,
|
||||
u8 filter_dup);
|
||||
static int hci_le_scan_restart_sync(struct hci_dev *hdev)
|
||||
{
|
||||
/* If controller is not scanning we are done. */
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
|
||||
return 0;
|
||||
|
||||
if (hdev->scanning_paused) {
|
||||
bt_dev_dbg(hdev, "Scanning is paused for suspend");
|
||||
return 0;
|
||||
}
|
||||
|
||||
hci_le_set_scan_enable_sync(hdev, LE_SCAN_DISABLE, 0x00);
|
||||
return hci_le_set_scan_enable_sync(hdev, LE_SCAN_ENABLE,
|
||||
LE_SCAN_FILTER_DUP_ENABLE);
|
||||
}
|
||||
|
||||
static void le_scan_restart(struct work_struct *work)
|
||||
{
|
||||
struct hci_dev *hdev = container_of(work, struct hci_dev,
|
||||
le_scan_restart.work);
|
||||
unsigned long timeout, duration, scan_start, now;
|
||||
int status;
|
||||
|
||||
bt_dev_dbg(hdev, "");
|
||||
|
||||
status = hci_le_scan_restart_sync(hdev);
|
||||
if (status) {
|
||||
bt_dev_err(hdev, "failed to restart LE scan: status %d",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) ||
|
||||
!hdev->discovery.scan_start)
|
||||
goto unlock;
|
||||
|
||||
/* When the scan was started, hdev->le_scan_disable has been queued
|
||||
* after duration from scan_start. During scan restart this job
|
||||
* has been canceled, and we need to queue it again after proper
|
||||
* timeout, to make sure that scan does not run indefinitely.
|
||||
*/
|
||||
duration = hdev->discovery.scan_duration;
|
||||
scan_start = hdev->discovery.scan_start;
|
||||
now = jiffies;
|
||||
if (now - scan_start <= duration) {
|
||||
int elapsed;
|
||||
|
||||
if (now >= scan_start)
|
||||
elapsed = now - scan_start;
|
||||
else
|
||||
elapsed = ULONG_MAX - scan_start + now;
|
||||
|
||||
timeout = duration - elapsed;
|
||||
} else {
|
||||
timeout = 0;
|
||||
}
|
||||
|
||||
queue_delayed_work(hdev->req_workqueue,
|
||||
&hdev->le_scan_disable, timeout);
|
||||
|
||||
unlock:
|
||||
hci_dev_unlock(hdev);
|
||||
}
|
||||
|
||||
static int reenable_adv_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
@ -630,7 +563,6 @@ void hci_cmd_sync_init(struct hci_dev *hdev)
|
||||
INIT_WORK(&hdev->cmd_sync_cancel_work, hci_cmd_sync_cancel_work);
|
||||
INIT_WORK(&hdev->reenable_adv_work, reenable_adv);
|
||||
INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable);
|
||||
INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart);
|
||||
INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire);
|
||||
}
|
||||
|
||||
@ -4960,7 +4892,6 @@ int hci_dev_close_sync(struct hci_dev *hdev)
|
||||
cancel_delayed_work(&hdev->power_off);
|
||||
cancel_delayed_work(&hdev->ncmd_timer);
|
||||
cancel_delayed_work(&hdev->le_scan_disable);
|
||||
cancel_delayed_work(&hdev->le_scan_restart);
|
||||
|
||||
hci_request_cancel_all(hdev);
|
||||
|
||||
@ -5178,7 +5109,6 @@ int hci_stop_discovery_sync(struct hci_dev *hdev)
|
||||
|
||||
if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
|
||||
cancel_delayed_work(&hdev->le_scan_disable);
|
||||
cancel_delayed_work(&hdev->le_scan_restart);
|
||||
|
||||
err = hci_scan_disable_sync(hdev);
|
||||
if (err)
|
||||
@ -5686,19 +5616,18 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
|
||||
if (err < 0)
|
||||
own_addr_type = ADDR_LE_DEV_PUBLIC;
|
||||
|
||||
if (hci_is_adv_monitoring(hdev)) {
|
||||
if (hci_is_adv_monitoring(hdev) ||
|
||||
(test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) &&
|
||||
hdev->discovery.result_filtering)) {
|
||||
/* Duplicate filter should be disabled when some advertisement
|
||||
* monitor is activated, otherwise AdvMon can only receive one
|
||||
* advertisement for one peer(*) during active scanning, and
|
||||
* might report loss to these peers.
|
||||
*
|
||||
* Note that different controllers have different meanings of
|
||||
* |duplicate|. Some of them consider packets with the same
|
||||
* address as duplicate, and others consider packets with the
|
||||
* same address and the same RSSI as duplicate. Although in the
|
||||
* latter case we don't need to disable duplicate filter, but
|
||||
* it is common to have active scanning for a short period of
|
||||
* time, the power impact should be neglectable.
|
||||
* If controller does strict duplicate filtering and the
|
||||
* discovery requires result filtering disables controller based
|
||||
* filtering since that can cause reports that would match the
|
||||
* host filter to not be reported.
|
||||
*/
|
||||
filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
|
||||
}
|
||||
@ -5778,17 +5707,6 @@ int hci_start_discovery_sync(struct hci_dev *hdev)
|
||||
|
||||
bt_dev_dbg(hdev, "timeout %u ms", jiffies_to_msecs(timeout));
|
||||
|
||||
/* When service discovery is used and the controller has a
|
||||
* strict duplicate filter, it is important to remember the
|
||||
* start and duration of the scan. This is required for
|
||||
* restarting scanning during the discovery phase.
|
||||
*/
|
||||
if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) &&
|
||||
hdev->discovery.result_filtering) {
|
||||
hdev->discovery.scan_start = jiffies;
|
||||
hdev->discovery.scan_duration = timeout;
|
||||
}
|
||||
|
||||
queue_delayed_work(hdev->req_workqueue, &hdev->le_scan_disable,
|
||||
timeout);
|
||||
return 0;
|
||||
|
@ -10145,21 +10145,6 @@ static bool eir_has_uuids(u8 *eir, u16 eir_len, u16 uuid_count, u8 (*uuids)[16])
|
||||
return false;
|
||||
}
|
||||
|
||||
static void restart_le_scan(struct hci_dev *hdev)
|
||||
{
|
||||
/* If controller is not scanning we are done. */
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
|
||||
return;
|
||||
|
||||
if (time_after(jiffies + DISCOV_LE_RESTART_DELAY,
|
||||
hdev->discovery.scan_start +
|
||||
hdev->discovery.scan_duration))
|
||||
return;
|
||||
|
||||
queue_delayed_work(hdev->req_workqueue, &hdev->le_scan_restart,
|
||||
DISCOV_LE_RESTART_DELAY);
|
||||
}
|
||||
|
||||
static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir,
|
||||
u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len)
|
||||
{
|
||||
@ -10194,8 +10179,6 @@ static bool is_filter_match(struct hci_dev *hdev, s8 rssi, u8 *eir,
|
||||
* scanning to ensure updated result with updated RSSI values.
|
||||
*/
|
||||
if (test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks)) {
|
||||
restart_le_scan(hdev);
|
||||
|
||||
/* Validate RSSI value against the RSSI threshold once more. */
|
||||
if (hdev->discovery.rssi != HCI_RSSI_INVALID &&
|
||||
rssi < hdev->discovery.rssi)
|
||||
|
Loading…
Reference in New Issue
Block a user