Bluetooth: hci_core: Remove le_restart_scan work
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 6 Sep 2023 21:13:35 +0000 (14:13 -0700)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 22 Dec 2023 17:55:17 +0000 (12:55 -0500)
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>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_sync.c
net/bluetooth/mgmt.c

index 6a32c06d7fdc8b7bd7efd5514269861dac345470..cf560a9e16b6eea73344e38177808af775f90c1f 100644 (file)
@@ -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;
index d85a7091a1169d714849aeb4f4c7b6967c8a51c1..3563a90ed2ace2e23de6cfdf580299890ef06195 100644 (file)
@@ -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 @@ _return:
 
 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;
index 9dd815b6603feb69461937f5d83986bff532ed0c..bb72ff6eb22f4b30864aefd2588cce982d37d153 100644 (file)
@@ -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)