summaryrefslogtreecommitdiff
path: root/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c13
-rw-r--r--net/bluetooth/hci_event.c5
-rw-r--r--net/bluetooth/hci_request.c17
-rw-r--r--net/bluetooth/mgmt.c5
4 files changed, 34 insertions, 6 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 59132b3e2cde..7959b851cc63 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3005,6 +3005,8 @@ void hci_adv_monitors_clear(struct hci_dev *hdev)
hci_free_adv_monitor(monitor);
idr_destroy(&hdev->adv_monitors_idr);
+
+ hci_update_background_scan(hdev);
}
void hci_free_adv_monitor(struct adv_monitor *monitor)
@@ -3038,6 +3040,9 @@ int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
hdev->adv_monitors_cnt++;
monitor->handle = handle;
+
+ hci_update_background_scan(hdev);
+
return 0;
}
@@ -3069,9 +3074,17 @@ int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle)
idr_for_each(&hdev->adv_monitors_idr, &free_adv_monitor, hdev);
}
+ hci_update_background_scan(hdev);
+
return 0;
}
+/* This function requires the caller holds hdev->lock */
+bool hci_is_adv_monitoring(struct hci_dev *hdev)
+{
+ return !idr_is_empty(&hdev->adv_monitors_idr);
+}
+
struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
bdaddr_t *bdaddr, u8 type)
{
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8981954ff4c4..e08d4dd9a24e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -5447,14 +5447,15 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
/* Passive scanning shouldn't trigger any device found events,
* except for devices marked as CONN_REPORT for which we do send
- * device found events.
+ * device found events, or advertisement monitoring requested.
*/
if (hdev->le_scan_type == LE_SCAN_PASSIVE) {
if (type == LE_ADV_DIRECT_IND)
return;
if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
- bdaddr, bdaddr_type))
+ bdaddr, bdaddr_type) &&
+ idr_is_empty(&hdev->adv_monitors_idr))
return;
if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND)
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index eee9c007a5fb..29decd7e8051 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -413,11 +413,15 @@ static void __hci_update_background_scan(struct hci_request *req)
*/
hci_discovery_filter_clear(hdev);
+ BT_DBG("%s ADV monitoring is %s", hdev->name,
+ hci_is_adv_monitoring(hdev) ? "on" : "off");
+
if (list_empty(&hdev->pend_le_conns) &&
- list_empty(&hdev->pend_le_reports)) {
+ list_empty(&hdev->pend_le_reports) &&
+ !hci_is_adv_monitoring(hdev)) {
/* If there is no pending LE connections or devices
- * to be scanned for, we should stop the background
- * scanning.
+ * to be scanned for or no ADV monitors, we should stop the
+ * background scanning.
*/
/* If controller is not scanning we are done. */
@@ -794,6 +798,13 @@ static u8 update_white_list(struct hci_request *req)
return 0x00;
}
+ /* Once the controller offloading of advertisement monitor is in place,
+ * the if condition should include the support of MSFT extension
+ * support.
+ */
+ if (!idr_is_empty(&hdev->adv_monitors_idr))
+ return 0x00;
+
/* Select filter policy to use white list */
return 0x01;
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b194da4de2d7..ec66160a673c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -8575,8 +8575,11 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
if (!hci_discovery_active(hdev)) {
if (link_type == ACL_LINK)
return;
- if (link_type == LE_LINK && list_empty(&hdev->pend_le_reports))
+ if (link_type == LE_LINK &&
+ list_empty(&hdev->pend_le_reports) &&
+ !hci_is_adv_monitoring(hdev)) {
return;
+ }
}
if (hdev->discovery.result_filtering) {