All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 1/7] Bluetooth: Add definitions for advertisement monitor features
@ 2020-05-28 23:54 Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 2/7] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES Miao-chen Chou
                   ` (5 more replies)
  0 siblings, 6 replies; 9+ messages in thread
From: Miao-chen Chou @ 2020-05-28 23:54 UTC (permalink / raw)
  To: Bluetooth Kernel Mailing List
  Cc: Alain Michaud, Marcel Holtmann, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun, Miao-chen Chou,
	David S. Miller, Jakub Kicinski, Johan Hedberg, linux-kernel,
	netdev

This adds support for Advertisement Monitor API. Here are the commands
and events added.
- Read Advertisement Monitor Feature command
- Add Advertisement Pattern Monitor command
- Remove Advertisement Monitor command
- Advertisement Monitor Added event
- Advertisement Monitor Removed event

Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
---

 include/net/bluetooth/mgmt.h | 49 ++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 16e0d87bd8fae..df36c50d15f53 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -702,6 +702,45 @@ struct mgmt_rp_set_exp_feature {
 	__le32 flags;
 } __packed;
 
+#define MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS    BIT(0)
+
+#define MGMT_OP_READ_ADV_MONITOR_FEATURES	0x004B
+#define MGMT_READ_ADV_MONITOR_FEATURES_SIZE	0
+struct mgmt_rp_read_adv_monitor_features {
+	__u32 supported_features;
+	__u32 enabled_features;
+	__u16 max_num_handles;
+	__u8 max_num_patterns;
+	__u16 num_handles;
+	__u16 handles[];
+}  __packed;
+
+struct mgmt_adv_pattern {
+	__u8 ad_type;
+	__u8 offset;
+	__u8 length;
+	__u8 value[31];
+} __packed;
+
+#define MGMT_OP_ADD_ADV_PATTERNS_MONITOR	0x004C
+struct mgmt_cp_add_adv_patterns_monitor {
+	__u8 pattern_count;
+	struct mgmt_adv_pattern patterns[];
+} __packed;
+#define MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE	1
+struct mgmt_rp_add_adv_patterns_monitor {
+	__u16 monitor_handle;
+} __packed;
+
+#define MGMT_OP_REMOVE_ADV_MONITOR		0x004D
+struct mgmt_cp_remove_adv_monitor {
+	__u16 monitor_handle;
+} __packed;
+#define MGMT_REMOVE_ADV_MONITOR_SIZE		2
+struct mgmt_rp_remove_adv_monitor {
+	__u16 monitor_handle;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
@@ -933,3 +972,13 @@ struct mgmt_ev_exp_feature_changed {
 	__u8	uuid[16];
 	__le32	flags;
 } __packed;
+
+#define MGMT_EV_ADV_MONITOR_ADDED	0x0028
+struct mgmt_ev_adv_monitor_added {
+	__u16 monitor_handle;
+}  __packed;
+
+#define MGMT_EV_ADV_MONITOR_REMOVED	0x0029
+struct mgmt_ev_adv_monitor_removed {
+	__u16 monitor_handle;
+}  __packed;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v1 2/7] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
  2020-05-28 23:54 [PATCH v1 1/7] Bluetooth: Add definitions for advertisement monitor features Miao-chen Chou
@ 2020-05-28 23:54 ` Miao-chen Chou
  2020-06-03 17:59   ` Marcel Holtmann
  2020-05-28 23:54 ` [PATCH v1 3/7] Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR Miao-chen Chou
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Miao-chen Chou @ 2020-05-28 23:54 UTC (permalink / raw)
  To: Bluetooth Kernel Mailing List
  Cc: Alain Michaud, Marcel Holtmann, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun, Miao-chen Chou,
	David S. Miller, Jakub Kicinski, Johan Hedberg, linux-kernel,
	netdev

This adds the request handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
command. Since the controller-based monitoring is not yet in place, this
report only the supported features but not the enabled features.

The following test was performed.
- Issuing btmgmt advmon-features.

Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
---

 include/net/bluetooth/hci_core.h | 24 +++++++++++++++++
 net/bluetooth/hci_core.c         | 10 ++++++-
 net/bluetooth/mgmt.c             | 46 ++++++++++++++++++++++++++++++++
 net/bluetooth/msft.c             |  7 +++++
 net/bluetooth/msft.h             |  9 +++++++
 5 files changed, 95 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index cdd4f1db8670e..431fe0265dcfb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -25,6 +25,7 @@
 #ifndef __HCI_CORE_H
 #define __HCI_CORE_H
 
+#include <linux/idr.h>
 #include <linux/leds.h>
 #include <linux/rculist.h>
 
@@ -220,6 +221,24 @@ struct adv_info {
 #define HCI_MAX_ADV_INSTANCES		5
 #define HCI_DEFAULT_ADV_DURATION	2
 
+struct adv_pattern {
+	struct list_head list;
+	__u8 ad_type;
+	__u8 offset;
+	__u8 length;
+	__u8 value[HCI_MAX_AD_LENGTH];
+};
+
+struct adv_monitor {
+	struct list_head patterns;
+	bool		active;
+	__u16		handle;
+};
+
+#define HCI_MIN_ADV_MONITOR_HANDLE		1
+#define HCI_MAX_ADV_MONITOR_NUM_HANDLES	32
+#define HCI_MAX_ADV_MONITOR_NUM_PATTERNS	16
+
 #define HCI_MAX_SHORT_NAME_LENGTH	10
 
 /* Min encryption key size to match with SMP */
@@ -477,6 +496,9 @@ struct hci_dev {
 	__u16			adv_instance_timeout;
 	struct delayed_work	adv_instance_expire;
 
+	struct idr		adv_monitors_idr;
+	unsigned int		adv_monitors_cnt;
+
 	__u8			irk[16];
 	__u32			rpa_timeout;
 	struct delayed_work	rpa_expired;
@@ -1217,6 +1239,8 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
 int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
 void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
 
+void hci_adv_monitors_clear(struct hci_dev *hdev);
+
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
 void hci_init_sysfs(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index dbe2d79f233fb..23bfe4f1d1e9d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -26,7 +26,6 @@
 /* Bluetooth HCI core. */
 
 #include <linux/export.h>
-#include <linux/idr.h>
 #include <linux/rfkill.h>
 #include <linux/debugfs.h>
 #include <linux/crypto.h>
@@ -2996,6 +2995,12 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
 	return 0;
 }
 
+/* This function requires the caller holds hdev->lock */
+void hci_adv_monitors_clear(struct hci_dev *hdev)
+{
+	idr_destroy(&hdev->adv_monitors_idr);
+}
+
 struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
 					 bdaddr_t *bdaddr, u8 type)
 {
@@ -3574,6 +3579,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	queue_work(hdev->req_workqueue, &hdev->power_on);
 
+	idr_init(&hdev->adv_monitors_idr);
+
 	return id;
 
 err_wqueue:
@@ -3644,6 +3651,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
 	hci_smp_irks_clear(hdev);
 	hci_remote_oob_data_clear(hdev);
 	hci_adv_instances_clear(hdev);
+	hci_adv_monitors_clear(hdev);
 	hci_bdaddr_list_clear(&hdev->le_white_list);
 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
 	hci_conn_params_clear_all(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9e8a3cccc6ca3..8d8275ee9718b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -36,6 +36,7 @@
 #include "hci_request.h"
 #include "smp.h"
 #include "mgmt_util.h"
+#include "msft.h"
 
 #define MGMT_VERSION	1
 #define MGMT_REVISION	17
@@ -111,6 +112,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_READ_SECURITY_INFO,
 	MGMT_OP_READ_EXP_FEATURES_INFO,
 	MGMT_OP_SET_EXP_FEATURE,
+	MGMT_OP_READ_ADV_MONITOR_FEATURES,
 };
 
 static const u16 mgmt_events[] = {
@@ -3849,6 +3851,49 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
 			       MGMT_STATUS_NOT_SUPPORTED);
 }
 
+static int read_adv_monitor_features(struct sock *sk, struct hci_dev *hdev,
+				     void *data, u16 len)
+{
+	struct adv_monitor *monitor = NULL;
+	struct mgmt_rp_read_adv_monitor_features *rp = NULL;
+	int handle;
+	size_t rp_size = 0;
+	__u32 supported = 0;
+	__u16 num_handles = 0;
+	__u16 handles[HCI_MAX_ADV_MONITOR_NUM_HANDLES];
+
+	BT_DBG("request for %s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	if (msft_get_features(hdev) & MSFT_FEATURE_MASK_LE_ADV_MONITOR)
+		supported |= MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS;
+
+	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
+		handles[num_handles++] = monitor->handle;
+
+	hci_dev_unlock(hdev);
+
+	rp_size = sizeof(*rp) + (num_handles * sizeof(u16));
+	rp = kmalloc(rp_size, GFP_KERNEL);
+	if (!rp)
+		return -ENOMEM;
+
+	// Once controller-based monitoring is in place, the enabled_features
+	// should reflect the use.
+	rp->supported_features = supported;
+	rp->enabled_features = 0;
+	rp->max_num_handles = HCI_MAX_ADV_MONITOR_NUM_HANDLES;
+	rp->max_num_patterns = HCI_MAX_ADV_MONITOR_NUM_PATTERNS;
+	rp->num_handles = num_handles;
+	if (num_handles)
+		memcpy(&rp->handles, &handles, (num_handles * sizeof(u16)));
+
+	return mgmt_cmd_complete(sk, hdev->id,
+				 MGMT_OP_READ_ADV_MONITOR_FEATURES,
+				 MGMT_STATUS_SUCCESS, rp, rp_size);
+}
+
 static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
 				         u16 opcode, struct sk_buff *skb)
 {
@@ -7297,6 +7342,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 	{ set_exp_feature,         MGMT_SET_EXP_FEATURE_SIZE,
 						HCI_MGMT_VAR_LEN |
 						HCI_MGMT_HDEV_OPTIONAL },
+	{ read_adv_monitor_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)
diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
index d6c4e6b5ae777..8579bfeb28364 100644
--- a/net/bluetooth/msft.c
+++ b/net/bluetooth/msft.c
@@ -139,3 +139,10 @@ void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 	bt_dev_dbg(hdev, "MSFT vendor event %u", event);
 }
+
+__u64 msft_get_features(struct hci_dev *hdev)
+{
+	struct msft_data *msft = hdev->msft_data;
+
+	return  msft ? msft->features : 0;
+}
diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h
index 5aa9130e1f8ab..e9c478e890b8b 100644
--- a/net/bluetooth/msft.h
+++ b/net/bluetooth/msft.h
@@ -3,16 +3,25 @@
  * Copyright (C) 2020 Google Corporation
  */
 
+#define MSFT_FEATURE_MASK_BREDR_RSSI_MONITOR		BIT(0)
+#define MSFT_FEATURE_MASK_LE_CONN_RSSI_MONITOR		BIT(1)
+#define MSFT_FEATURE_MASK_LE_ADV_RSSI_MONITOR		BIT(2)
+#define MSFT_FEATURE_MASK_LE_ADV_MONITOR		BIT(3)
+#define MSFT_FEATURE_MASK_CURVE_VALIDITY		BIT(4)
+#define MSFT_FEATURE_MASK_CONCURRENT_ADV_MONITOR	BIT(5)
+
 #if IS_ENABLED(CONFIG_BT_MSFTEXT)
 
 void msft_do_open(struct hci_dev *hdev);
 void msft_do_close(struct hci_dev *hdev);
 void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb);
+__u64 msft_get_features(struct hci_dev *hdev);
 
 #else
 
 static inline void msft_do_open(struct hci_dev *hdev) {}
 static inline void msft_do_close(struct hci_dev *hdev) {}
 static inline void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb) {}
+static inline __u64 msft_get_features(struct hci_dev *hdev) { return 0; }
 
 #endif
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v1 3/7] Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR
  2020-05-28 23:54 [PATCH v1 1/7] Bluetooth: Add definitions for advertisement monitor features Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 2/7] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES Miao-chen Chou
@ 2020-05-28 23:54 ` Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 4/7] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR Miao-chen Chou
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Miao-chen Chou @ 2020-05-28 23:54 UTC (permalink / raw)
  To: Bluetooth Kernel Mailing List
  Cc: Alain Michaud, Marcel Holtmann, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun, Miao-chen Chou,
	David S. Miller, Jakub Kicinski, Johan Hedberg, linux-kernel,
	netdev

This adds the request handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR command.
Note that the controller-based monitoring is not yet in place. This tracks
the content of the monitor without sending HCI traffic, so the request
returns immediately.

The following manual test was performed.
- Issue btmgmt advmon-add with valid and invalid inputs.
- Issue btmgmt advmon-add more the allowed number of monitors.

Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
---

 include/net/bluetooth/hci_core.h |   2 +
 net/bluetooth/hci_core.c         |  40 +++++++++++++
 net/bluetooth/mgmt.c             | 100 +++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 431fe0265dcfb..862d94f711bc0 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1240,6 +1240,8 @@ int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
 void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
 
 void hci_adv_monitors_clear(struct hci_dev *hdev);
+void hci_free_adv_monitor(struct adv_monitor *monitor);
+int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 23bfe4f1d1e9d..93c16bfc6da15 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2998,9 +2998,49 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
 /* This function requires the caller holds hdev->lock */
 void hci_adv_monitors_clear(struct hci_dev *hdev)
 {
+	struct adv_monitor *monitor;
+	int handle;
+
+	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
+		hci_free_adv_monitor(monitor);
+
 	idr_destroy(&hdev->adv_monitors_idr);
 }
 
+void hci_free_adv_monitor(struct adv_monitor *monitor)
+{
+	struct adv_pattern *pattern;
+	struct adv_pattern *tmp;
+
+	if (!monitor)
+		return;
+
+	list_for_each_entry_safe(pattern, tmp, &monitor->patterns, list)
+		kfree(pattern);
+
+	kfree(monitor);
+}
+
+/* This function requires the caller holds hdev->lock */
+int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
+{
+	int min, max, handle;
+
+	if (!monitor)
+		return -EINVAL;
+
+	min = HCI_MIN_ADV_MONITOR_HANDLE;
+	max = HCI_MIN_ADV_MONITOR_HANDLE + HCI_MAX_ADV_MONITOR_NUM_HANDLES;
+	handle = idr_alloc(&hdev->adv_monitors_idr, monitor, min, max,
+			   GFP_KERNEL);
+	if (handle < 0)
+		return handle;
+
+	hdev->adv_monitors_cnt++;
+	monitor->handle = handle;
+	return 0;
+}
+
 struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
 					 bdaddr_t *bdaddr, u8 type)
 {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 8d8275ee9718b..9c1704ca6ad1e 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -113,6 +113,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_READ_EXP_FEATURES_INFO,
 	MGMT_OP_SET_EXP_FEATURE,
 	MGMT_OP_READ_ADV_MONITOR_FEATURES,
+	MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
 };
 
 static const u16 mgmt_events[] = {
@@ -3894,6 +3895,103 @@ static int read_adv_monitor_features(struct sock *sk, struct hci_dev *hdev,
 				 MGMT_STATUS_SUCCESS, rp, rp_size);
 }
 
+static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
+				    void *data, u16 len)
+{
+	struct mgmt_cp_add_adv_patterns_monitor *cp = data;
+	struct mgmt_rp_add_adv_patterns_monitor rp;
+	struct adv_monitor *m = NULL;
+	struct adv_pattern *p = NULL;
+	__u8 cp_ofst = 0, cp_len = 0;
+	unsigned int mp_cnt = 0;
+	int err, i;
+
+	BT_DBG("request for %s", hdev->name);
+
+	if (len <= sizeof(*cp) || cp->pattern_count == 0) {
+		err = mgmt_cmd_status(sk, hdev->id,
+				      MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+				      MGMT_STATUS_INVALID_PARAMS);
+		goto failed;
+	}
+
+	m = kmalloc(sizeof(*m), GFP_KERNEL);
+	if (!m) {
+		err = -ENOMEM;
+		goto failed;
+	}
+
+	INIT_LIST_HEAD(&m->patterns);
+	m->active = false;
+
+	for (i = 0; i < cp->pattern_count; i++) {
+		if (++mp_cnt > HCI_MAX_ADV_MONITOR_NUM_PATTERNS) {
+			err = mgmt_cmd_status(sk, hdev->id,
+					      MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+					      MGMT_STATUS_INVALID_PARAMS);
+			goto failed;
+		}
+
+		cp_ofst = cp->patterns[i].offset;
+		cp_len = cp->patterns[i].length;
+		if (cp_ofst >= HCI_MAX_AD_LENGTH ||
+		    cp_len > HCI_MAX_AD_LENGTH ||
+		    (cp_ofst + cp_len) > HCI_MAX_AD_LENGTH) {
+			err = mgmt_cmd_status(sk, hdev->id,
+					      MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+					      MGMT_STATUS_INVALID_PARAMS);
+			goto failed;
+		}
+
+		p = kmalloc(sizeof(*p), GFP_KERNEL);
+		if (!p) {
+			err = -ENOMEM;
+			goto failed;
+		}
+
+		p->ad_type = cp->patterns[i].ad_type;
+		p->offset = cp->patterns[i].offset;
+		p->length = cp->patterns[i].length;
+		memcpy(p->value, cp->patterns[i].value, p->length);
+
+		INIT_LIST_HEAD(&p->list);
+		list_add(&p->list, &m->patterns);
+	}
+
+	if (mp_cnt != cp->pattern_count) {
+		err = mgmt_cmd_status(sk, hdev->id,
+				      MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+				      MGMT_STATUS_INVALID_PARAMS);
+		goto failed;
+	}
+
+	hci_dev_lock(hdev);
+
+	err = hci_add_adv_monitor(hdev, m);
+	if (err) {
+		if (err == -ENOSPC) {
+			mgmt_cmd_status(sk, hdev->id,
+					MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+					MGMT_STATUS_NO_RESOURCES);
+		}
+		goto unlock;
+	}
+
+	hci_dev_unlock(hdev);
+
+	rp.monitor_handle = m->handle;
+
+	return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+				 MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
+
+unlock:
+	hci_dev_unlock(hdev);
+
+failed:
+	hci_free_adv_monitor(m);
+	return err;
+}
+
 static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
 				         u16 opcode, struct sk_buff *skb)
 {
@@ -7343,6 +7441,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 						HCI_MGMT_VAR_LEN |
 						HCI_MGMT_HDEV_OPTIONAL },
 	{ read_adv_monitor_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
+	{ add_adv_patterns_monitor, MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE,
+						HCI_MGMT_VAR_LEN },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v1 4/7] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR
  2020-05-28 23:54 [PATCH v1 1/7] Bluetooth: Add definitions for advertisement monitor features Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 2/7] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 3/7] Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR Miao-chen Chou
@ 2020-05-28 23:54 ` Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 5/7] Bluetooth: Notify adv monitor added event Miao-chen Chou
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Miao-chen Chou @ 2020-05-28 23:54 UTC (permalink / raw)
  To: Bluetooth Kernel Mailing List
  Cc: Alain Michaud, Marcel Holtmann, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun, Miao-chen Chou,
	David S. Miller, Jakub Kicinski, Johan Hedberg, linux-kernel,
	netdev

This adds the request handler of MGMT_OP_REMOVE_ADV_MONITOR command.
Note that the controller-based monitoring is not yet in place. This
removes the internal monitor(s) without sending HCI traffic, so the
request returns immediately.

The following test was performed.
- Issue btmgmt advmon-remove with valid and invalid handles.

Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
---

 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 31 +++++++++++++++++++++++++++++++
 net/bluetooth/mgmt.c             | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 862d94f711bc0..78ac7fd282d77 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1242,6 +1242,7 @@ void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
 void hci_adv_monitors_clear(struct hci_dev *hdev);
 void hci_free_adv_monitor(struct adv_monitor *monitor);
 int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
+int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 93c16bfc6da15..1fcd0cc2dcc5b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3041,6 +3041,37 @@ int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor)
 	return 0;
 }
 
+static int free_adv_monitor(int id, void *ptr, void *data)
+{
+	struct hci_dev *hdev = data;
+	struct adv_monitor *monitor = ptr;
+
+	idr_remove(&hdev->adv_monitors_idr, monitor->handle);
+	hci_free_adv_monitor(monitor);
+
+	return 0;
+}
+
+/* This function requires the caller holds hdev->lock */
+int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle)
+{
+	struct adv_monitor *monitor;
+
+	if (handle) {
+		monitor = idr_find(&hdev->adv_monitors_idr, handle);
+		if (!monitor)
+			return -ENOENT;
+
+		idr_remove(&hdev->adv_monitors_idr, monitor->handle);
+		hci_free_adv_monitor(monitor);
+	} else {
+		/* Remove all monitors if handle is 0. */
+		idr_for_each(&hdev->adv_monitors_idr, &free_adv_monitor, hdev);
+	}
+
+	return 0;
+}
+
 struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
 					 bdaddr_t *bdaddr, u8 type)
 {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 9c1704ca6ad1e..710ec00219a0b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -114,6 +114,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_EXP_FEATURE,
 	MGMT_OP_READ_ADV_MONITOR_FEATURES,
 	MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+	MGMT_OP_REMOVE_ADV_MONITOR,
 };
 
 static const u16 mgmt_events[] = {
@@ -3992,6 +3993,36 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
 	return err;
 }
 
+static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
+			      void *data, u16 len)
+{
+	struct mgmt_cp_remove_adv_monitor *cp = data;
+	struct mgmt_rp_remove_adv_monitor rp;
+	int err;
+
+	BT_DBG("request for %s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	err = hci_remove_adv_monitor(hdev, cp->monitor_handle);
+	if (err == -ENOENT) {
+		err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR,
+				      MGMT_STATUS_INVALID_INDEX);
+		goto unlock;
+	}
+
+	hci_dev_unlock(hdev);
+
+	rp.monitor_handle = cp->monitor_handle;
+
+	return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR,
+				 MGMT_STATUS_SUCCESS, &rp, sizeof(rp));
+
+unlock:
+	hci_dev_unlock(hdev);
+	return err;
+}
+
 static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
 				         u16 opcode, struct sk_buff *skb)
 {
@@ -7443,6 +7474,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 	{ read_adv_monitor_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
 	{ add_adv_patterns_monitor, MGMT_ADD_ADV_PATTERNS_MONITOR_SIZE,
 						HCI_MGMT_VAR_LEN },
+	{ remove_adv_monitor, MGMT_REMOVE_ADV_MONITOR_SIZE },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v1 5/7] Bluetooth: Notify adv monitor added event
  2020-05-28 23:54 [PATCH v1 1/7] Bluetooth: Add definitions for advertisement monitor features Miao-chen Chou
                   ` (2 preceding siblings ...)
  2020-05-28 23:54 ` [PATCH v1 4/7] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR Miao-chen Chou
@ 2020-05-28 23:54 ` Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 6/7] Bluetooth: Notify adv monitor removed event Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 7/7] Bluetooth: Update background scan and report device based on advertisement monitors Miao-chen Chou
  5 siblings, 0 replies; 9+ messages in thread
From: Miao-chen Chou @ 2020-05-28 23:54 UTC (permalink / raw)
  To: Bluetooth Kernel Mailing List
  Cc: Alain Michaud, Marcel Holtmann, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun, Miao-chen Chou,
	David S. Miller, Jakub Kicinski, Johan Hedberg, linux-kernel,
	netdev

This notifies management sockets on MGMT_EV_ADV_MONITOR_ADDED event.

The following test was performed.
- Start two btmgmt consoles, issue a btmgmt advmon-add command on one
console and observe a MGMT_EV_ADV_MONITOR_ADDED event on the other

Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
---

 net/bluetooth/mgmt.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 710ec00219a0b..da65b6ab2e3a0 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -155,6 +155,7 @@ static const u16 mgmt_events[] = {
 	MGMT_EV_EXT_INFO_CHANGED,
 	MGMT_EV_PHY_CONFIGURATION_CHANGED,
 	MGMT_EV_EXP_FEATURE_CHANGED,
+	MGMT_EV_ADV_MONITOR_ADDED,
 };
 
 static const u16 mgmt_untrusted_commands[] = {
@@ -3853,6 +3854,16 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
 			       MGMT_STATUS_NOT_SUPPORTED);
 }
 
+static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev,
+				   u16 handle)
+{
+	struct mgmt_ev_adv_monitor_added ev;
+
+	ev.monitor_handle = handle;
+
+	mgmt_event(MGMT_EV_ADV_MONITOR_ADDED, hdev, &ev, sizeof(ev), sk);
+}
+
 static int read_adv_monitor_features(struct sock *sk, struct hci_dev *hdev,
 				     void *data, u16 len)
 {
@@ -3903,8 +3914,8 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
 	struct mgmt_rp_add_adv_patterns_monitor rp;
 	struct adv_monitor *m = NULL;
 	struct adv_pattern *p = NULL;
+	unsigned int mp_cnt = 0, prev_adv_monitors_cnt;
 	__u8 cp_ofst = 0, cp_len = 0;
-	unsigned int mp_cnt = 0;
 	int err, i;
 
 	BT_DBG("request for %s", hdev->name);
@@ -3968,6 +3979,8 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
 
 	hci_dev_lock(hdev);
 
+	prev_adv_monitors_cnt = hdev->adv_monitors_cnt;
+
 	err = hci_add_adv_monitor(hdev, m);
 	if (err) {
 		if (err == -ENOSPC) {
@@ -3978,6 +3991,9 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev,
 		goto unlock;
 	}
 
+	if (hdev->adv_monitors_cnt > prev_adv_monitors_cnt)
+		mgmt_adv_monitor_added(sk, hdev, m->handle);
+
 	hci_dev_unlock(hdev);
 
 	rp.monitor_handle = m->handle;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v1 6/7] Bluetooth: Notify adv monitor removed event
  2020-05-28 23:54 [PATCH v1 1/7] Bluetooth: Add definitions for advertisement monitor features Miao-chen Chou
                   ` (3 preceding siblings ...)
  2020-05-28 23:54 ` [PATCH v1 5/7] Bluetooth: Notify adv monitor added event Miao-chen Chou
@ 2020-05-28 23:54 ` Miao-chen Chou
  2020-05-28 23:54 ` [PATCH v1 7/7] Bluetooth: Update background scan and report device based on advertisement monitors Miao-chen Chou
  5 siblings, 0 replies; 9+ messages in thread
From: Miao-chen Chou @ 2020-05-28 23:54 UTC (permalink / raw)
  To: Bluetooth Kernel Mailing List
  Cc: Alain Michaud, Marcel Holtmann, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun, Miao-chen Chou,
	David S. Miller, Jakub Kicinski, Johan Hedberg, linux-kernel,
	netdev

This notifies management sockets on MGMT_EV_ADV_MONITOR_REMOVED event.

The following test was performed.
- Start two btmgmt consoles, issue a btmgmt advmon-remove command on one
console and observe a MGMT_EV_ADV_MONITOR_REMOVED event on the other.

Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
---

 net/bluetooth/mgmt.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index da65b6ab2e3a0..728d79663cbcf 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -156,6 +156,7 @@ static const u16 mgmt_events[] = {
 	MGMT_EV_PHY_CONFIGURATION_CHANGED,
 	MGMT_EV_EXP_FEATURE_CHANGED,
 	MGMT_EV_ADV_MONITOR_ADDED,
+	MGMT_EV_ADV_MONITOR_REMOVED,
 };
 
 static const u16 mgmt_untrusted_commands[] = {
@@ -3864,6 +3865,16 @@ static void mgmt_adv_monitor_added(struct sock *sk, struct hci_dev *hdev,
 	mgmt_event(MGMT_EV_ADV_MONITOR_ADDED, hdev, &ev, sizeof(ev), sk);
 }
 
+static void mgmt_adv_monitor_removed(struct sock *sk, struct hci_dev *hdev,
+				     u16 handle)
+{
+	struct mgmt_ev_adv_monitor_added ev;
+
+	ev.monitor_handle = handle;
+
+	mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk);
+}
+
 static int read_adv_monitor_features(struct sock *sk, struct hci_dev *hdev,
 				     void *data, u16 len)
 {
@@ -4014,12 +4025,15 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
 {
 	struct mgmt_cp_remove_adv_monitor *cp = data;
 	struct mgmt_rp_remove_adv_monitor rp;
+	unsigned int prev_adv_monitors_cnt;
 	int err;
 
 	BT_DBG("request for %s", hdev->name);
 
 	hci_dev_lock(hdev);
 
+	prev_adv_monitors_cnt = hdev->adv_monitors_cnt;
+
 	err = hci_remove_adv_monitor(hdev, cp->monitor_handle);
 	if (err == -ENOENT) {
 		err = mgmt_cmd_status(sk, hdev->id, MGMT_OP_REMOVE_ADV_MONITOR,
@@ -4027,6 +4041,9 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
 		goto unlock;
 	}
 
+	if (hdev->adv_monitors_cnt < prev_adv_monitors_cnt)
+		mgmt_adv_monitor_removed(sk, hdev, cp->monitor_handle);
+
 	hci_dev_unlock(hdev);
 
 	rp.monitor_handle = cp->monitor_handle;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v1 7/7] Bluetooth: Update background scan and report device based on advertisement monitors
  2020-05-28 23:54 [PATCH v1 1/7] Bluetooth: Add definitions for advertisement monitor features Miao-chen Chou
                   ` (4 preceding siblings ...)
  2020-05-28 23:54 ` [PATCH v1 6/7] Bluetooth: Notify adv monitor removed event Miao-chen Chou
@ 2020-05-28 23:54 ` Miao-chen Chou
  5 siblings, 0 replies; 9+ messages in thread
From: Miao-chen Chou @ 2020-05-28 23:54 UTC (permalink / raw)
  To: Bluetooth Kernel Mailing List
  Cc: Alain Michaud, Marcel Holtmann, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun, Miao-chen Chou,
	David S. Miller, Jakub Kicinski, Johan Hedberg, linux-kernel,
	netdev

This calls hci_update_background_scan() when there is any update on the
advertisement monitors. If there is at least one advertisement monitor,
the filtering policy of scan parameters should be 0x00. This also reports
device found mgmt events if there is at least one monitor.

The following cases were tested with btmgmt advmon-* commands.
(1) add a ADV monitor and observe that the passive scanning is
triggered.
(2) remove the last ADV monitor and observe that the passive scanning is
terminated.
(3) with a LE peripheral paired, repeat (1) and observe the passive
scanning continues.
(4) with a LE peripheral paired, repeat (2) and observe the passive
scanning continues.
(5) with a ADV monitor, suspend/resume the host and observe the passive
scanning continues.

Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
---

 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 13 +++++++++++++
 net/bluetooth/hci_event.c        |  5 +++--
 net/bluetooth/hci_request.c      | 17 ++++++++++++++---
 net/bluetooth/mgmt.c             |  5 ++++-
 5 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 78ac7fd282d77..1ce89e546a64e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1243,6 +1243,7 @@ void hci_adv_monitors_clear(struct hci_dev *hdev);
 void hci_free_adv_monitor(struct adv_monitor *monitor);
 int hci_add_adv_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
 int hci_remove_adv_monitor(struct hci_dev *hdev, u16 handle);
+bool hci_is_adv_monitoring(struct hci_dev *hdev);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1fcd0cc2dcc5b..08c8ce26146d3 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 cfeaee347db32..cbcc0b590fd41 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 1fc55685da62d..b743e3fc063d8 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -418,11 +418,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. */
@@ -798,6 +802,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 728d79663cbcf..d070373345c5d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -8427,8 +8427,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) {
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/7] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
  2020-05-28 23:54 ` [PATCH v1 2/7] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES Miao-chen Chou
@ 2020-06-03 17:59   ` Marcel Holtmann
  2020-06-03 23:05     ` Miao-chen Chou
  0 siblings, 1 reply; 9+ messages in thread
From: Marcel Holtmann @ 2020-06-03 17:59 UTC (permalink / raw)
  To: Miao-chen Chou
  Cc: Bluetooth Kernel Mailing List, Alain Michaud, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun,
	David S. Miller, Jakub Kicinski, Johan Hedberg, linux-kernel,
	netdev

Hi Miao-chen,

> This adds the request handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
> command. Since the controller-based monitoring is not yet in place, this
> report only the supported features but not the enabled features.
> 
> The following test was performed.
> - Issuing btmgmt advmon-features.
> 
> Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
> ---
> 
> include/net/bluetooth/hci_core.h | 24 +++++++++++++++++
> net/bluetooth/hci_core.c         | 10 ++++++-
> net/bluetooth/mgmt.c             | 46 ++++++++++++++++++++++++++++++++
> net/bluetooth/msft.c             |  7 +++++
> net/bluetooth/msft.h             |  9 +++++++
> 5 files changed, 95 insertions(+), 1 deletion(-)
> 
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index cdd4f1db8670e..431fe0265dcfb 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -25,6 +25,7 @@
> #ifndef __HCI_CORE_H
> #define __HCI_CORE_H
> 
> +#include <linux/idr.h>
> #include <linux/leds.h>
> #include <linux/rculist.h>
> 
> @@ -220,6 +221,24 @@ struct adv_info {
> #define HCI_MAX_ADV_INSTANCES		5
> #define HCI_DEFAULT_ADV_DURATION	2
> 
> +struct adv_pattern {
> +	struct list_head list;
> +	__u8 ad_type;
> +	__u8 offset;
> +	__u8 length;
> +	__u8 value[HCI_MAX_AD_LENGTH];
> +};
> +
> +struct adv_monitor {
> +	struct list_head patterns;
> +	bool		active;
> +	__u16		handle;
> +};
> +
> +#define HCI_MIN_ADV_MONITOR_HANDLE		1
> +#define HCI_MAX_ADV_MONITOR_NUM_HANDLES	32
> +#define HCI_MAX_ADV_MONITOR_NUM_PATTERNS	16
> +
> #define HCI_MAX_SHORT_NAME_LENGTH	10
> 
> /* Min encryption key size to match with SMP */
> @@ -477,6 +496,9 @@ struct hci_dev {
> 	__u16			adv_instance_timeout;
> 	struct delayed_work	adv_instance_expire;
> 
> +	struct idr		adv_monitors_idr;
> +	unsigned int		adv_monitors_cnt;
> +
> 	__u8			irk[16];
> 	__u32			rpa_timeout;
> 	struct delayed_work	rpa_expired;
> @@ -1217,6 +1239,8 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
> int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
> void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
> 
> +void hci_adv_monitors_clear(struct hci_dev *hdev);
> +
> void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
> 
> void hci_init_sysfs(struct hci_dev *hdev);
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index dbe2d79f233fb..23bfe4f1d1e9d 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -26,7 +26,6 @@
> /* Bluetooth HCI core. */
> 
> #include <linux/export.h>
> -#include <linux/idr.h>
> #include <linux/rfkill.h>
> #include <linux/debugfs.h>
> #include <linux/crypto.h>
> @@ -2996,6 +2995,12 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
> 	return 0;
> }
> 
> +/* This function requires the caller holds hdev->lock */
> +void hci_adv_monitors_clear(struct hci_dev *hdev)
> +{
> +	idr_destroy(&hdev->adv_monitors_idr);
> +}
> +
> struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
> 					 bdaddr_t *bdaddr, u8 type)
> {
> @@ -3574,6 +3579,8 @@ int hci_register_dev(struct hci_dev *hdev)
> 
> 	queue_work(hdev->req_workqueue, &hdev->power_on);
> 
> +	idr_init(&hdev->adv_monitors_idr);
> +
> 	return id;
> 
> err_wqueue:
> @@ -3644,6 +3651,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
> 	hci_smp_irks_clear(hdev);
> 	hci_remote_oob_data_clear(hdev);
> 	hci_adv_instances_clear(hdev);
> +	hci_adv_monitors_clear(hdev);
> 	hci_bdaddr_list_clear(&hdev->le_white_list);
> 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
> 	hci_conn_params_clear_all(hdev);
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index 9e8a3cccc6ca3..8d8275ee9718b 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -36,6 +36,7 @@
> #include "hci_request.h"
> #include "smp.h"
> #include "mgmt_util.h"
> +#include "msft.h"
> 
> #define MGMT_VERSION	1
> #define MGMT_REVISION	17
> @@ -111,6 +112,7 @@ static const u16 mgmt_commands[] = {
> 	MGMT_OP_READ_SECURITY_INFO,
> 	MGMT_OP_READ_EXP_FEATURES_INFO,
> 	MGMT_OP_SET_EXP_FEATURE,
> +	MGMT_OP_READ_ADV_MONITOR_FEATURES,
> };
> 
> static const u16 mgmt_events[] = {
> @@ -3849,6 +3851,49 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
> 			       MGMT_STATUS_NOT_SUPPORTED);
> }
> 
> +static int read_adv_monitor_features(struct sock *sk, struct hci_dev *hdev,
> +				     void *data, u16 len)
> +{
> +	struct adv_monitor *monitor = NULL;
> +	struct mgmt_rp_read_adv_monitor_features *rp = NULL;
> +	int handle;
> +	size_t rp_size = 0;
> +	__u32 supported = 0;
> +	__u16 num_handles = 0;
> +	__u16 handles[HCI_MAX_ADV_MONITOR_NUM_HANDLES];
> +
> +	BT_DBG("request for %s", hdev->name);
> +
> +	hci_dev_lock(hdev);
> +
> +	if (msft_get_features(hdev) & MSFT_FEATURE_MASK_LE_ADV_MONITOR)
> +		supported |= MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS;
> +
> +	idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
> +		handles[num_handles++] = monitor->handle;

I would put { } here to make it readable.

> +
> +	hci_dev_unlock(hdev);
> +
> +	rp_size = sizeof(*rp) + (num_handles * sizeof(u16));
> +	rp = kmalloc(rp_size, GFP_KERNEL);
> +	if (!rp)
> +		return -ENOMEM;
> +
> +	// Once controller-based monitoring is in place, the enabled_features
> +	// should reflect the use.

Please use /* */ comment style here.

> +	rp->supported_features = supported;
> +	rp->enabled_features = 0;
> +	rp->max_num_handles = HCI_MAX_ADV_MONITOR_NUM_HANDLES;
> +	rp->max_num_patterns = HCI_MAX_ADV_MONITOR_NUM_PATTERNS;

These are little-endian.

> +	rp->num_handles = num_handles;
> +	if (num_handles)
> +		memcpy(&rp->handles, &handles, (num_handles * sizeof(u16)));
> +
> +	return mgmt_cmd_complete(sk, hdev->id,
> +				 MGMT_OP_READ_ADV_MONITOR_FEATURES,
> +				 MGMT_STATUS_SUCCESS, rp, rp_size);
> +}
> +
> static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
> 				         u16 opcode, struct sk_buff *skb)
> {
> @@ -7297,6 +7342,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
> 	{ set_exp_feature,         MGMT_SET_EXP_FEATURE_SIZE,
> 						HCI_MGMT_VAR_LEN |
> 						HCI_MGMT_HDEV_OPTIONAL },
> +	{ read_adv_monitor_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
> };
> 
> void mgmt_index_added(struct hci_dev *hdev)
> diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
> index d6c4e6b5ae777..8579bfeb28364 100644
> --- a/net/bluetooth/msft.c
> +++ b/net/bluetooth/msft.c
> @@ -139,3 +139,10 @@ void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb)
> 
> 	bt_dev_dbg(hdev, "MSFT vendor event %u", event);
> }
> +
> +__u64 msft_get_features(struct hci_dev *hdev)
> +{
> +	struct msft_data *msft = hdev->msft_data;
> +
> +	return  msft ? msft->features : 0;
> +}
> diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h
> index 5aa9130e1f8ab..e9c478e890b8b 100644
> --- a/net/bluetooth/msft.h
> +++ b/net/bluetooth/msft.h
> @@ -3,16 +3,25 @@
>  * Copyright (C) 2020 Google Corporation
>  */
> 
> +#define MSFT_FEATURE_MASK_BREDR_RSSI_MONITOR		BIT(0)
> +#define MSFT_FEATURE_MASK_LE_CONN_RSSI_MONITOR		BIT(1)
> +#define MSFT_FEATURE_MASK_LE_ADV_RSSI_MONITOR		BIT(2)
> +#define MSFT_FEATURE_MASK_LE_ADV_MONITOR		BIT(3)
> +#define MSFT_FEATURE_MASK_CURVE_VALIDITY		BIT(4)
> +#define MSFT_FEATURE_MASK_CONCURRENT_ADV_MONITOR	BIT(5)
> +
> #if IS_ENABLED(CONFIG_BT_MSFTEXT)
> 
> void msft_do_open(struct hci_dev *hdev);
> void msft_do_close(struct hci_dev *hdev);
> void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb);
> +__u64 msft_get_features(struct hci_dev *hdev);
> 
> #else
> 
> static inline void msft_do_open(struct hci_dev *hdev) {}
> static inline void msft_do_close(struct hci_dev *hdev) {}
> static inline void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb) {}
> +static inline __u64 msft_get_features(struct hci_dev *hdev) { return 0; }

Regards

Marcel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v1 2/7] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
  2020-06-03 17:59   ` Marcel Holtmann
@ 2020-06-03 23:05     ` Miao-chen Chou
  0 siblings, 0 replies; 9+ messages in thread
From: Miao-chen Chou @ 2020-06-03 23:05 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Bluetooth Kernel Mailing List, Alain Michaud, Manish Mandlik,
	Luiz Augusto von Dentz, Yoni Shavit, Michael Sun,
	David S. Miller, Jakub Kicinski, Johan Hedberg, LKML, netdev

Hi Marcel,

Thanks for your review. V2 was uploaded to address these 3 comments.

Regards,
Miao

On Wed, Jun 3, 2020 at 10:59 AM Marcel Holtmann <marcel@holtmann.org> wrote:
>
> Hi Miao-chen,
>
> > This adds the request handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
> > command. Since the controller-based monitoring is not yet in place, this
> > report only the supported features but not the enabled features.
> >
> > The following test was performed.
> > - Issuing btmgmt advmon-features.
> >
> > Signed-off-by: Miao-chen Chou <mcchou@chromium.org>
> > ---
> >
> > include/net/bluetooth/hci_core.h | 24 +++++++++++++++++
> > net/bluetooth/hci_core.c         | 10 ++++++-
> > net/bluetooth/mgmt.c             | 46 ++++++++++++++++++++++++++++++++
> > net/bluetooth/msft.c             |  7 +++++
> > net/bluetooth/msft.h             |  9 +++++++
> > 5 files changed, 95 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> > index cdd4f1db8670e..431fe0265dcfb 100644
> > --- a/include/net/bluetooth/hci_core.h
> > +++ b/include/net/bluetooth/hci_core.h
> > @@ -25,6 +25,7 @@
> > #ifndef __HCI_CORE_H
> > #define __HCI_CORE_H
> >
> > +#include <linux/idr.h>
> > #include <linux/leds.h>
> > #include <linux/rculist.h>
> >
> > @@ -220,6 +221,24 @@ struct adv_info {
> > #define HCI_MAX_ADV_INSTANCES         5
> > #define HCI_DEFAULT_ADV_DURATION      2
> >
> > +struct adv_pattern {
> > +     struct list_head list;
> > +     __u8 ad_type;
> > +     __u8 offset;
> > +     __u8 length;
> > +     __u8 value[HCI_MAX_AD_LENGTH];
> > +};
> > +
> > +struct adv_monitor {
> > +     struct list_head patterns;
> > +     bool            active;
> > +     __u16           handle;
> > +};
> > +
> > +#define HCI_MIN_ADV_MONITOR_HANDLE           1
> > +#define HCI_MAX_ADV_MONITOR_NUM_HANDLES      32
> > +#define HCI_MAX_ADV_MONITOR_NUM_PATTERNS     16
> > +
> > #define HCI_MAX_SHORT_NAME_LENGTH     10
> >
> > /* Min encryption key size to match with SMP */
> > @@ -477,6 +496,9 @@ struct hci_dev {
> >       __u16                   adv_instance_timeout;
> >       struct delayed_work     adv_instance_expire;
> >
> > +     struct idr              adv_monitors_idr;
> > +     unsigned int            adv_monitors_cnt;
> > +
> >       __u8                    irk[16];
> >       __u32                   rpa_timeout;
> >       struct delayed_work     rpa_expired;
> > @@ -1217,6 +1239,8 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
> > int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance);
> > void hci_adv_instances_set_rpa_expired(struct hci_dev *hdev, bool rpa_expired);
> >
> > +void hci_adv_monitors_clear(struct hci_dev *hdev);
> > +
> > void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
> >
> > void hci_init_sysfs(struct hci_dev *hdev);
> > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> > index dbe2d79f233fb..23bfe4f1d1e9d 100644
> > --- a/net/bluetooth/hci_core.c
> > +++ b/net/bluetooth/hci_core.c
> > @@ -26,7 +26,6 @@
> > /* Bluetooth HCI core. */
> >
> > #include <linux/export.h>
> > -#include <linux/idr.h>
> > #include <linux/rfkill.h>
> > #include <linux/debugfs.h>
> > #include <linux/crypto.h>
> > @@ -2996,6 +2995,12 @@ int hci_add_adv_instance(struct hci_dev *hdev, u8 instance, u32 flags,
> >       return 0;
> > }
> >
> > +/* This function requires the caller holds hdev->lock */
> > +void hci_adv_monitors_clear(struct hci_dev *hdev)
> > +{
> > +     idr_destroy(&hdev->adv_monitors_idr);
> > +}
> > +
> > struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
> >                                        bdaddr_t *bdaddr, u8 type)
> > {
> > @@ -3574,6 +3579,8 @@ int hci_register_dev(struct hci_dev *hdev)
> >
> >       queue_work(hdev->req_workqueue, &hdev->power_on);
> >
> > +     idr_init(&hdev->adv_monitors_idr);
> > +
> >       return id;
> >
> > err_wqueue:
> > @@ -3644,6 +3651,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
> >       hci_smp_irks_clear(hdev);
> >       hci_remote_oob_data_clear(hdev);
> >       hci_adv_instances_clear(hdev);
> > +     hci_adv_monitors_clear(hdev);
> >       hci_bdaddr_list_clear(&hdev->le_white_list);
> >       hci_bdaddr_list_clear(&hdev->le_resolv_list);
> >       hci_conn_params_clear_all(hdev);
> > diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> > index 9e8a3cccc6ca3..8d8275ee9718b 100644
> > --- a/net/bluetooth/mgmt.c
> > +++ b/net/bluetooth/mgmt.c
> > @@ -36,6 +36,7 @@
> > #include "hci_request.h"
> > #include "smp.h"
> > #include "mgmt_util.h"
> > +#include "msft.h"
> >
> > #define MGMT_VERSION  1
> > #define MGMT_REVISION 17
> > @@ -111,6 +112,7 @@ static const u16 mgmt_commands[] = {
> >       MGMT_OP_READ_SECURITY_INFO,
> >       MGMT_OP_READ_EXP_FEATURES_INFO,
> >       MGMT_OP_SET_EXP_FEATURE,
> > +     MGMT_OP_READ_ADV_MONITOR_FEATURES,
> > };
> >
> > static const u16 mgmt_events[] = {
> > @@ -3849,6 +3851,49 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
> >                              MGMT_STATUS_NOT_SUPPORTED);
> > }
> >
> > +static int read_adv_monitor_features(struct sock *sk, struct hci_dev *hdev,
> > +                                  void *data, u16 len)
> > +{
> > +     struct adv_monitor *monitor = NULL;
> > +     struct mgmt_rp_read_adv_monitor_features *rp = NULL;
> > +     int handle;
> > +     size_t rp_size = 0;
> > +     __u32 supported = 0;
> > +     __u16 num_handles = 0;
> > +     __u16 handles[HCI_MAX_ADV_MONITOR_NUM_HANDLES];
> > +
> > +     BT_DBG("request for %s", hdev->name);
> > +
> > +     hci_dev_lock(hdev);
> > +
> > +     if (msft_get_features(hdev) & MSFT_FEATURE_MASK_LE_ADV_MONITOR)
> > +             supported |= MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS;
> > +
> > +     idr_for_each_entry(&hdev->adv_monitors_idr, monitor, handle)
> > +             handles[num_handles++] = monitor->handle;
>
> I would put { } here to make it readable.
>
> > +
> > +     hci_dev_unlock(hdev);
> > +
> > +     rp_size = sizeof(*rp) + (num_handles * sizeof(u16));
> > +     rp = kmalloc(rp_size, GFP_KERNEL);
> > +     if (!rp)
> > +             return -ENOMEM;
> > +
> > +     // Once controller-based monitoring is in place, the enabled_features
> > +     // should reflect the use.
>
> Please use /* */ comment style here.
>
> > +     rp->supported_features = supported;
> > +     rp->enabled_features = 0;
> > +     rp->max_num_handles = HCI_MAX_ADV_MONITOR_NUM_HANDLES;
> > +     rp->max_num_patterns = HCI_MAX_ADV_MONITOR_NUM_PATTERNS;
>
> These are little-endian.
>
> > +     rp->num_handles = num_handles;
> > +     if (num_handles)
> > +             memcpy(&rp->handles, &handles, (num_handles * sizeof(u16)));
> > +
> > +     return mgmt_cmd_complete(sk, hdev->id,
> > +                              MGMT_OP_READ_ADV_MONITOR_FEATURES,
> > +                              MGMT_STATUS_SUCCESS, rp, rp_size);
> > +}
> > +
> > static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
> >                                        u16 opcode, struct sk_buff *skb)
> > {
> > @@ -7297,6 +7342,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
> >       { set_exp_feature,         MGMT_SET_EXP_FEATURE_SIZE,
> >                                               HCI_MGMT_VAR_LEN |
> >                                               HCI_MGMT_HDEV_OPTIONAL },
> > +     { read_adv_monitor_features, MGMT_READ_ADV_MONITOR_FEATURES_SIZE },
> > };
> >
> > void mgmt_index_added(struct hci_dev *hdev)
> > diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
> > index d6c4e6b5ae777..8579bfeb28364 100644
> > --- a/net/bluetooth/msft.c
> > +++ b/net/bluetooth/msft.c
> > @@ -139,3 +139,10 @@ void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb)
> >
> >       bt_dev_dbg(hdev, "MSFT vendor event %u", event);
> > }
> > +
> > +__u64 msft_get_features(struct hci_dev *hdev)
> > +{
> > +     struct msft_data *msft = hdev->msft_data;
> > +
> > +     return  msft ? msft->features : 0;
> > +}
> > diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h
> > index 5aa9130e1f8ab..e9c478e890b8b 100644
> > --- a/net/bluetooth/msft.h
> > +++ b/net/bluetooth/msft.h
> > @@ -3,16 +3,25 @@
> >  * Copyright (C) 2020 Google Corporation
> >  */
> >
> > +#define MSFT_FEATURE_MASK_BREDR_RSSI_MONITOR         BIT(0)
> > +#define MSFT_FEATURE_MASK_LE_CONN_RSSI_MONITOR               BIT(1)
> > +#define MSFT_FEATURE_MASK_LE_ADV_RSSI_MONITOR                BIT(2)
> > +#define MSFT_FEATURE_MASK_LE_ADV_MONITOR             BIT(3)
> > +#define MSFT_FEATURE_MASK_CURVE_VALIDITY             BIT(4)
> > +#define MSFT_FEATURE_MASK_CONCURRENT_ADV_MONITOR     BIT(5)
> > +
> > #if IS_ENABLED(CONFIG_BT_MSFTEXT)
> >
> > void msft_do_open(struct hci_dev *hdev);
> > void msft_do_close(struct hci_dev *hdev);
> > void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb);
> > +__u64 msft_get_features(struct hci_dev *hdev);
> >
> > #else
> >
> > static inline void msft_do_open(struct hci_dev *hdev) {}
> > static inline void msft_do_close(struct hci_dev *hdev) {}
> > static inline void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb) {}
> > +static inline __u64 msft_get_features(struct hci_dev *hdev) { return 0; }
>
> Regards
>
> Marcel
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-06-03 23:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-28 23:54 [PATCH v1 1/7] Bluetooth: Add definitions for advertisement monitor features Miao-chen Chou
2020-05-28 23:54 ` [PATCH v1 2/7] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES Miao-chen Chou
2020-06-03 17:59   ` Marcel Holtmann
2020-06-03 23:05     ` Miao-chen Chou
2020-05-28 23:54 ` [PATCH v1 3/7] Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR Miao-chen Chou
2020-05-28 23:54 ` [PATCH v1 4/7] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR Miao-chen Chou
2020-05-28 23:54 ` [PATCH v1 5/7] Bluetooth: Notify adv monitor added event Miao-chen Chou
2020-05-28 23:54 ` [PATCH v1 6/7] Bluetooth: Notify adv monitor removed event Miao-chen Chou
2020-05-28 23:54 ` [PATCH v1 7/7] Bluetooth: Update background scan and report device based on advertisement monitors Miao-chen Chou

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.