Skip to content

Commit c32d624

Browse files
Yun-Hao Chungholtmann
authored andcommitted
Bluetooth: disable filter dup when scan for adv monitor
Disable duplicates filter when scanning for advertisement monitor for the following reasons. The scanning includes active scan and passive scan. For HW pattern filtering (ex. MSFT), Realtek and Qualcomm controllers ignore RSSI_Sampling_Period when the duplicates filter is enabled. For SW pattern filtering, when we're not doing interleaved scanning, it is necessary to disable duplicates filter, otherwise hosts can only receive one advertisement and it's impossible to know if a peer is still in range. Signed-off-by: Yun-Hao Chung <[email protected]> Reviewed-by: Archie Pusaka <[email protected]> Reviewed-by: Manish Mandlik <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 79699a7 commit c32d624

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

net/bluetooth/hci_request.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -932,7 +932,7 @@ static bool scan_use_rpa(struct hci_dev *hdev)
932932

933933
static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
934934
u16 window, u8 own_addr_type, u8 filter_policy,
935-
bool addr_resolv)
935+
bool filter_dup, bool addr_resolv)
936936
{
937937
struct hci_dev *hdev = req->hdev;
938938

@@ -997,7 +997,7 @@ static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
997997

998998
memset(&ext_enable_cp, 0, sizeof(ext_enable_cp));
999999
ext_enable_cp.enable = LE_SCAN_ENABLE;
1000-
ext_enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
1000+
ext_enable_cp.filter_dup = filter_dup;
10011001

10021002
hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_ENABLE,
10031003
sizeof(ext_enable_cp), &ext_enable_cp);
@@ -1016,7 +1016,7 @@ static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
10161016

10171017
memset(&enable_cp, 0, sizeof(enable_cp));
10181018
enable_cp.enable = LE_SCAN_ENABLE;
1019-
enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
1019+
enable_cp.filter_dup = filter_dup;
10201020
hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
10211021
&enable_cp);
10221022
}
@@ -1053,6 +1053,8 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
10531053
u8 own_addr_type;
10541054
u8 filter_policy;
10551055
u16 window, interval;
1056+
/* Default is to enable duplicates filter */
1057+
u8 filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
10561058
/* Background scanning should run with address resolution */
10571059
bool addr_resolv = true;
10581060

@@ -1106,14 +1108,29 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
11061108
} else if (hci_is_adv_monitoring(hdev)) {
11071109
window = hdev->le_scan_window_adv_monitor;
11081110
interval = hdev->le_scan_int_adv_monitor;
1111+
1112+
/* Disable duplicates filter when scanning for advertisement
1113+
* monitor for the following reasons.
1114+
*
1115+
* For HW pattern filtering (ex. MSFT), Realtek and Qualcomm
1116+
* controllers ignore RSSI_Sampling_Period when the duplicates
1117+
* filter is enabled.
1118+
*
1119+
* For SW pattern filtering, when we're not doing interleaved
1120+
* scanning, it is necessary to disable duplicates filter,
1121+
* otherwise hosts can only receive one advertisement and it's
1122+
* impossible to know if a peer is still in range.
1123+
*/
1124+
filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
11091125
} else {
11101126
window = hdev->le_scan_window;
11111127
interval = hdev->le_scan_interval;
11121128
}
11131129

11141130
bt_dev_dbg(hdev, "LE passive scan with whitelist = %d", filter_policy);
11151131
hci_req_start_scan(req, LE_SCAN_PASSIVE, interval, window,
1116-
own_addr_type, filter_policy, addr_resolv);
1132+
own_addr_type, filter_policy, filter_dup,
1133+
addr_resolv);
11171134
}
11181135

11191136
static bool adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
@@ -3135,6 +3152,8 @@ static int active_scan(struct hci_request *req, unsigned long opt)
31353152
u8 own_addr_type;
31363153
/* White list is not used for discovery */
31373154
u8 filter_policy = 0x00;
3155+
/* Default is to enable duplicates filter */
3156+
u8 filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
31383157
/* Discovery doesn't require controller address resolution */
31393158
bool addr_resolv = false;
31403159
int err;
@@ -3159,9 +3178,26 @@ static int active_scan(struct hci_request *req, unsigned long opt)
31593178
if (err < 0)
31603179
own_addr_type = ADDR_LE_DEV_PUBLIC;
31613180

3181+
if (hci_is_adv_monitoring(hdev)) {
3182+
/* Duplicate filter should be disabled when some advertisement
3183+
* monitor is activated, otherwise AdvMon can only receive one
3184+
* advertisement for one peer(*) during active scanning, and
3185+
* might report loss to these peers.
3186+
*
3187+
* Note that different controllers have different meanings of
3188+
* |duplicate|. Some of them consider packets with the same
3189+
* address as duplicate, and others consider packets with the
3190+
* same address and the same RSSI as duplicate. Although in the
3191+
* latter case we don't need to disable duplicate filter, but
3192+
* it is common to have active scanning for a short period of
3193+
* time, the power impact should be neglectable.
3194+
*/
3195+
filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
3196+
}
3197+
31623198
hci_req_start_scan(req, LE_SCAN_ACTIVE, interval,
31633199
hdev->le_scan_window_discovery, own_addr_type,
3164-
filter_policy, addr_resolv);
3200+
filter_policy, filter_dup, addr_resolv);
31653201
return 0;
31663202
}
31673203

0 commit comments

Comments
 (0)