diff mbox series

[1/2] Bluetooth: Disable AdvMonitor SamplingPeriod while active scan

Message ID 20220803132319.1.I5acde3b5af78dbd2ea078d5eb4158d23b496ac87@changeid (mailing list archive)
State New, archived
Headers show
Series [1/2] Bluetooth: Disable AdvMonitor SamplingPeriod while active scan | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/checkpatch success Checkpatch PASS
tedd_an/gitlint success Gitlint PASS
tedd_an/subjectprefix success PASS
tedd_an/buildkernel success Build Kernel PASS
tedd_an/buildkernel32 success Build Kernel32 PASS
tedd_an/incremental_build success Pass
tedd_an/testrunnersetup success Test Runner Setup PASS
tedd_an/testrunnerl2cap-tester success Total: 40, Passed: 40 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnerbnep-tester success Total: 1, Passed: 1 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnermgmt-tester success Total: 494, Passed: 494 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnerrfcomm-tester success Total: 10, Passed: 10 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnersco-tester success Total: 12, Passed: 12 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunnersmp-tester success Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0
tedd_an/testrunneruserchan-tester success Total: 4, Passed: 4 (100.0%), Failed: 0, Not Run: 0

Commit Message

Manish Mandlik Aug. 3, 2022, 8:24 p.m. UTC
Some controllers apply Sampling Period even while active scanning.
So, to keep the behavior consistent across all controllers, don't
use Sampling Period during active scanning to force the controller
to report all advertisements even if it matches the monitor.

Signed-off-by: Manish Mandlik <mmandlik@google.com>
Reviewed-by: Miao-chen Chou <mcchou@google.com>
---

 net/bluetooth/hci_sync.c |  6 ++++++
 net/bluetooth/msft.c     | 45 +++++++++++++++++++++++++++++++++++++---
 net/bluetooth/msft.h     |  2 ++
 3 files changed, 50 insertions(+), 3 deletions(-)

Comments

bluez.test.bot@gmail.com Aug. 3, 2022, 9:08 p.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=665174

---Test result---

Test Summary:
CheckPatch                    PASS      2.05 seconds
GitLint                       PASS      0.86 seconds
SubjectPrefix                 PASS      0.57 seconds
BuildKernel                   PASS      42.46 seconds
BuildKernel32                 PASS      37.16 seconds
Incremental Build with patchesPASS      59.22 seconds
TestRunner: Setup             PASS      622.69 seconds
TestRunner: l2cap-tester      PASS      20.79 seconds
TestRunner: bnep-tester       PASS      8.24 seconds
TestRunner: mgmt-tester       PASS      127.00 seconds
TestRunner: rfcomm-tester     PASS      11.95 seconds
TestRunner: sco-tester        PASS      11.45 seconds
TestRunner: smp-tester        PASS      11.58 seconds
TestRunner: userchan-tester   PASS      7.87 seconds



---
Regards,
Linux Bluetooth
diff mbox series

Patch

diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index e6d804b82b67..cb0c219ebe1c 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -4649,6 +4649,9 @@  int hci_stop_discovery_sync(struct hci_dev *hdev)
 	if (use_ll_privacy(hdev))
 		hci_resume_advertising_sync(hdev);
 
+	/* Sampling Period is disabled while active scanning, re-enable it */
+	msft_set_active_scan(hdev, false);
+
 	/* No further actions needed for LE-only discovery */
 	if (d->type == DISCOV_TYPE_LE)
 		return 0;
@@ -5139,6 +5142,9 @@  int hci_start_discovery_sync(struct hci_dev *hdev)
 	if (err)
 		return err;
 
+	/* Disable Sampling Period while active scanning */
+	msft_set_active_scan(hdev, true);
+
 	bt_dev_dbg(hdev, "timeout %u ms", jiffies_to_msecs(timeout));
 
 	/* When service discovery is used and the controller has a
diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
index bee6a4c656be..f63c911b210c 100644
--- a/net/bluetooth/msft.c
+++ b/net/bluetooth/msft.c
@@ -101,6 +101,7 @@  struct msft_data {
 	struct list_head handle_map;
 	__u8 resuming;
 	__u8 suspending;
+	__u8 active_scan;
 	__u8 filter_enabled;
 };
 
@@ -333,14 +334,14 @@  static int msft_remove_monitor_sync(struct hci_dev *hdev,
 }
 
 /* This function requires the caller holds hci_req_sync_lock */
-int msft_suspend_sync(struct hci_dev *hdev)
+static void remove_all_monitors(struct hci_dev *hdev)
 {
 	struct msft_data *msft = hdev->msft_data;
 	struct adv_monitor *monitor;
 	int handle = 0;
 
 	if (!msft || !msft_monitor_supported(hdev))
-		return 0;
+		return;
 
 	msft->suspending = true;
 
@@ -356,6 +357,12 @@  int msft_suspend_sync(struct hci_dev *hdev)
 
 	/* All monitors have been removed */
 	msft->suspending = false;
+}
+
+/* This function requires the caller holds hci_req_sync_lock */
+int msft_suspend_sync(struct hci_dev *hdev)
+{
+	remove_all_monitors(hdev);
 
 	return 0;
 }
@@ -392,6 +399,7 @@  static bool msft_monitor_pattern_valid(struct adv_monitor *monitor)
 static int msft_add_monitor_sync(struct hci_dev *hdev,
 				 struct adv_monitor *monitor)
 {
+	struct msft_data *msft = hdev->msft_data;
 	struct msft_cp_le_monitor_advertisement *cp;
 	struct msft_le_monitor_advertisement_pattern_data *pattern_data;
 	struct msft_le_monitor_advertisement_pattern *pattern;
@@ -417,7 +425,16 @@  static int msft_add_monitor_sync(struct hci_dev *hdev,
 	cp->rssi_high = monitor->rssi.high_threshold;
 	cp->rssi_low = monitor->rssi.low_threshold;
 	cp->rssi_low_interval = (u8)monitor->rssi.low_threshold_timeout;
-	cp->rssi_sampling_period = monitor->rssi.sampling_period;
+
+	/* Some controllers apply Sampling Period even while active scanning.
+	 * So, to keep the behavior consistent across all controllers, don't
+	 * use Sampling Period during active scanning to force the controller
+	 * to report all advertisements even if it matches the monitor.
+	 */
+	if (msft->active_scan)
+		cp->rssi_sampling_period = 0;
+	else
+		cp->rssi_sampling_period = monitor->rssi.sampling_period;
 
 	cp->cond_type = MSFT_MONITOR_ADVERTISEMENT_TYPE_PATTERN;
 
@@ -815,6 +832,28 @@  void msft_req_add_set_filter_enable(struct hci_request *req, bool enable)
 	hci_req_add(req, hdev->msft_opcode, sizeof(cp), &cp);
 }
 
+/* This function requires the caller holds hci_req_sync_lock */
+void msft_set_active_scan(struct hci_dev *hdev, bool enable)
+{
+	struct msft_data *msft = hdev->msft_data;
+
+	if (!msft)
+		return;
+
+	/* Remove all monitors */
+	remove_all_monitors(hdev);
+
+	/* Clear all tracked devices */
+	hci_dev_lock(hdev);
+	hdev->advmon_pend_notify = false;
+	msft_monitor_device_del(hdev, 0, NULL, 0, true);
+	hci_dev_unlock(hdev);
+
+	/* Update active scan and reregister all monitors */
+	msft->active_scan = enable;
+	reregister_monitor(hdev);
+}
+
 int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
 {
 	struct hci_request req;
diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h
index 2a63205b377b..7dfd866dacc4 100644
--- a/net/bluetooth/msft.h
+++ b/net/bluetooth/msft.h
@@ -22,6 +22,7 @@  __u64 msft_get_features(struct hci_dev *hdev);
 int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor);
 int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
 void msft_req_add_set_filter_enable(struct hci_request *req, bool enable);
+void msft_set_active_scan(struct hci_dev *hdev, bool enable);
 int msft_set_filter_enable(struct hci_dev *hdev, bool enable);
 int msft_suspend_sync(struct hci_dev *hdev);
 int msft_resume_sync(struct hci_dev *hdev);
@@ -55,6 +56,7 @@  static inline int msft_remove_monitor(struct hci_dev *hdev,
 
 static inline void msft_req_add_set_filter_enable(struct hci_request *req,
 						  bool enable) {}
+static inline void msft_set_active_scan(struct hci_dev *hdev, bool enable) {}
 static inline int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
 {
 	return -EOPNOTSUPP;