linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/14] Combination of pending patches
@ 2020-06-17 14:39 Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 01/14] Bluetooth: mgmt: Add commands for runtime configuration Marcel Holtmann
                   ` (14 more replies)
  0 siblings, 15 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

This is the list of pending patches and fixes merged together. Please
review that the set and functionality is correct and working as
expected.

In v2 the Reviewed-by tags have been added.

Abhishek Pandit-Subedi (4):
  Bluetooth: Add bdaddr_list_with_flags for classic whitelist
  Bluetooth: Replace wakeable list with flag
  Bluetooth: Replace wakeable in hci_conn_params
  Bluetooth: Add get/set device flags mgmt op

Manish Mandlik (1):
  Bluetooth: Terminate the link if pairing is cancelled

Marcel Holtmann (2):
  Bluetooth: mgmt: Add commands for runtime configuration
  Bluetooth: mgmt: Use command complete on success for set system config

Miao-chen Chou (7):
  Bluetooth: Add definitions for advertisement monitor features
  Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
  Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR
  Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR
  Bluetooth: Notify adv monitor added event
  Bluetooth: Notify adv monitor removed event
  Bluetooth: Update background scan and report device based on
    advertisement monitors

 include/net/bluetooth/hci_core.h |  73 +++++-
 include/net/bluetooth/mgmt.h     |  77 +++++++
 net/bluetooth/hci_conn.c         |  11 +-
 net/bluetooth/hci_core.c         | 153 ++++++++++++-
 net/bluetooth/hci_event.c        |  13 +-
 net/bluetooth/hci_request.c      |  32 ++-
 net/bluetooth/l2cap_core.c       |   6 +-
 net/bluetooth/mgmt.c             | 382 ++++++++++++++++++++++++++++++-
 net/bluetooth/mgmt_config.c      |  23 +-
 net/bluetooth/mgmt_config.h      |   6 +
 net/bluetooth/msft.c             |   7 +
 net/bluetooth/msft.h             |   9 +
 12 files changed, 755 insertions(+), 37 deletions(-)

-- 
2.26.2


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

* [PATCH v2 01/14] Bluetooth: mgmt: Add commands for runtime configuration
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 02/14] Bluetooth: Add bdaddr_list_with_flags for classic whitelist Marcel Holtmann
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

This adds the required read/set commands for runtime configuration. Even
while currently no parameters are specified, the commands are made
available.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: Alain Michaud <alainm@chromium.org>
---
 net/bluetooth/mgmt.c        |  7 +++++++
 net/bluetooth/mgmt_config.c | 18 ++++++++++++++++++
 net/bluetooth/mgmt_config.h |  6 ++++++
 3 files changed, 31 insertions(+)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 99fbfd467d04..ecfdfc4df486 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -114,6 +114,8 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_EXP_FEATURE,
 	MGMT_OP_READ_DEF_SYSTEM_CONFIG,
 	MGMT_OP_SET_DEF_SYSTEM_CONFIG,
+	MGMT_OP_READ_DEF_RUNTIME_CONFIG,
+	MGMT_OP_SET_DEF_RUNTIME_CONFIG,
 };
 
 static const u16 mgmt_events[] = {
@@ -166,6 +168,7 @@ static const u16 mgmt_untrusted_commands[] = {
 	MGMT_OP_READ_SECURITY_INFO,
 	MGMT_OP_READ_EXP_FEATURES_INFO,
 	MGMT_OP_READ_DEF_SYSTEM_CONFIG,
+	MGMT_OP_READ_DEF_RUNTIME_CONFIG,
 };
 
 static const u16 mgmt_untrusted_events[] = {
@@ -7305,6 +7308,10 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 						HCI_MGMT_UNTRUSTED },
 	{ set_def_system_config,   MGMT_SET_DEF_SYSTEM_CONFIG_SIZE,
 						HCI_MGMT_VAR_LEN },
+	{ read_def_runtime_config, MGMT_READ_DEF_RUNTIME_CONFIG_SIZE,
+						HCI_MGMT_UNTRUSTED },
+	{ set_def_runtime_config,  MGMT_SET_DEF_RUNTIME_CONFIG_SIZE,
+						HCI_MGMT_VAR_LEN },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)
diff --git a/net/bluetooth/mgmt_config.c b/net/bluetooth/mgmt_config.c
index f6dfbe93542c..8e7ad2a51dbb 100644
--- a/net/bluetooth/mgmt_config.c
+++ b/net/bluetooth/mgmt_config.c
@@ -251,3 +251,21 @@ int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
 			       MGMT_OP_SET_DEF_SYSTEM_CONFIG,
 			       MGMT_STATUS_SUCCESS);
 }
+
+int read_def_runtime_config(struct sock *sk, struct hci_dev *hdev, void *data,
+			    u16 data_len)
+{
+	bt_dev_dbg(hdev, "sock %p", sk);
+
+	return mgmt_cmd_complete(sk, hdev->id,
+				 MGMT_OP_READ_DEF_RUNTIME_CONFIG, 0, NULL, 0);
+}
+
+int set_def_runtime_config(struct sock *sk, struct hci_dev *hdev, void *data,
+			   u16 data_len)
+{
+	bt_dev_dbg(hdev, "sock %p", sk);
+
+	return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_DEF_SYSTEM_CONFIG,
+			       MGMT_STATUS_INVALID_PARAMS);
+}
diff --git a/net/bluetooth/mgmt_config.h b/net/bluetooth/mgmt_config.h
index 51da6e63b1a0..a4965f107891 100644
--- a/net/bluetooth/mgmt_config.h
+++ b/net/bluetooth/mgmt_config.h
@@ -9,3 +9,9 @@ int read_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
 
 int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
 			  u16 data_len);
+
+int read_def_runtime_config(struct sock *sk, struct hci_dev *hdev, void *data,
+			    u16 data_len);
+
+int set_def_runtime_config(struct sock *sk, struct hci_dev *hdev, void *data,
+			   u16 data_len);
-- 
2.26.2


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

* [PATCH v2 02/14] Bluetooth: Add bdaddr_list_with_flags for classic whitelist
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 01/14] Bluetooth: mgmt: Add commands for runtime configuration Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 03/14] Bluetooth: Replace wakeable list with flag Marcel Holtmann
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>

In order to more easily add device flags to classic devices, create
a new type of bdaddr_list that supports setting flags.

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Alain Michaud <alainm@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h | 18 ++++++++--
 net/bluetooth/hci_core.c         | 58 ++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |  8 ++---
 net/bluetooth/mgmt.c             |  5 +--
 4 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0d5dbb6cb5a0..95a3935325bb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -136,6 +136,13 @@ struct bdaddr_list_with_irk {
 	u8 local_irk[16];
 };
 
+struct bdaddr_list_with_flags {
+	struct list_head list;
+	bdaddr_t bdaddr;
+	u8 bdaddr_type;
+	u32 current_flags;
+};
+
 struct bt_uuid {
 	struct list_head list;
 	u8 uuid[16];
@@ -1169,12 +1176,19 @@ struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
 struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
 				    struct list_head *list, bdaddr_t *bdaddr,
 				    u8 type);
+struct bdaddr_list_with_flags *
+hci_bdaddr_list_lookup_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+				  u8 type);
 int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
 int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
-					u8 type, u8 *peer_irk, u8 *local_irk);
+				 u8 type, u8 *peer_irk, u8 *local_irk);
+int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+				   u8 type, u32 flags);
 int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
 int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
-								u8 type);
+				 u8 type);
+int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+				   u8 type);
 void hci_bdaddr_list_clear(struct list_head *list);
 
 struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4f1052a7c488..8a471bec2731 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3023,6 +3023,20 @@ struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
 	return NULL;
 }
 
+struct bdaddr_list_with_flags *
+hci_bdaddr_list_lookup_with_flags(struct list_head *bdaddr_list,
+				  bdaddr_t *bdaddr, u8 type)
+{
+	struct bdaddr_list_with_flags *b;
+
+	list_for_each_entry(b, bdaddr_list, list) {
+		if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
+			return b;
+	}
+
+	return NULL;
+}
+
 void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
 {
 	struct bdaddr_list *b, *n;
@@ -3084,6 +3098,30 @@ int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
 	return 0;
 }
 
+int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+				   u8 type, u32 flags)
+{
+	struct bdaddr_list_with_flags *entry;
+
+	if (!bacmp(bdaddr, BDADDR_ANY))
+		return -EBADF;
+
+	if (hci_bdaddr_list_lookup(list, bdaddr, type))
+		return -EEXIST;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	bacpy(&entry->bdaddr, bdaddr);
+	entry->bdaddr_type = type;
+	entry->current_flags = flags;
+
+	list_add(&entry->list, list);
+
+	return 0;
+}
+
 int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
 {
 	struct bdaddr_list *entry;
@@ -3123,6 +3161,26 @@ int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
 	return 0;
 }
 
+int hci_bdaddr_list_del_with_flags(struct list_head *list, bdaddr_t *bdaddr,
+				   u8 type)
+{
+	struct bdaddr_list_with_flags *entry;
+
+	if (!bacmp(bdaddr, BDADDR_ANY)) {
+		hci_bdaddr_list_clear(list);
+		return 0;
+	}
+
+	entry = hci_bdaddr_list_lookup_with_flags(list, bdaddr, type);
+	if (!entry)
+		return -ENOENT;
+
+	list_del(&entry->list);
+	kfree(entry);
+
+	return 0;
+}
+
 /* This function requires the caller holds hdev->lock */
 struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
 					       bdaddr_t *addr, u8 addr_type)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index cfeaee347db3..8981954ff4c4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2697,10 +2697,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	 */
 	if (hci_dev_test_flag(hdev, HCI_MGMT) &&
 	    !hci_dev_test_flag(hdev, HCI_CONNECTABLE) &&
-	    !hci_bdaddr_list_lookup(&hdev->whitelist, &ev->bdaddr,
-				    BDADDR_BREDR)) {
-		    hci_reject_conn(hdev, &ev->bdaddr);
-		    return;
+	    !hci_bdaddr_list_lookup_with_flags(&hdev->whitelist, &ev->bdaddr,
+					       BDADDR_BREDR)) {
+		hci_reject_conn(hdev, &ev->bdaddr);
+		return;
 	}
 
 	/* Connection accepted */
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ecfdfc4df486..d0d0fa832c8a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -6000,8 +6000,9 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
 			goto unlock;
 		}
 
-		err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr,
-					  cp->addr.type);
+		err = hci_bdaddr_list_add_with_flags(&hdev->whitelist,
+						     &cp->addr.bdaddr,
+						     cp->addr.type, 0);
 		if (err)
 			goto unlock;
 
-- 
2.26.2


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

* [PATCH v2 03/14] Bluetooth: Replace wakeable list with flag
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 01/14] Bluetooth: mgmt: Add commands for runtime configuration Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 02/14] Bluetooth: Add bdaddr_list_with_flags for classic whitelist Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 04/14] Bluetooth: Replace wakeable in hci_conn_params Marcel Holtmann
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>

Since the classic device list now supports flags, convert the wakeable
list into a flag on the existing device list.

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Alain Michaud <alainm@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h | 11 ++++++++++-
 net/bluetooth/hci_core.c         |  1 -
 net/bluetooth/hci_request.c      | 12 ++++++++----
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 95a3935325bb..0643c737ba85 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -143,6 +143,16 @@ struct bdaddr_list_with_flags {
 	u32 current_flags;
 };
 
+enum hci_conn_flags {
+	HCI_CONN_FLAG_REMOTE_WAKEUP,
+	HCI_CONN_FLAG_MAX
+};
+
+#define hci_conn_test_flag(nr, flags) ((flags) & (1U << nr))
+
+/* Make sure number of flags doesn't exceed sizeof(current_flags) */
+static_assert(HCI_CONN_FLAG_MAX < 32);
+
 struct bt_uuid {
 	struct list_head list;
 	u8 uuid[16];
@@ -463,7 +473,6 @@ struct hci_dev {
 	struct list_head	mgmt_pending;
 	struct list_head	blacklist;
 	struct list_head	whitelist;
-	struct list_head	wakeable;
 	struct list_head	uuids;
 	struct list_head	link_keys;
 	struct list_head	long_term_keys;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8a471bec2731..8e01afb2ee8c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3499,7 +3499,6 @@ struct hci_dev *hci_alloc_dev(void)
 	INIT_LIST_HEAD(&hdev->mgmt_pending);
 	INIT_LIST_HEAD(&hdev->blacklist);
 	INIT_LIST_HEAD(&hdev->whitelist);
-	INIT_LIST_HEAD(&hdev->wakeable);
 	INIT_LIST_HEAD(&hdev->uuids);
 	INIT_LIST_HEAD(&hdev->link_keys);
 	INIT_LIST_HEAD(&hdev->long_term_keys);
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index a7f572ad38ef..a5b53d3ea508 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -968,15 +968,19 @@ static void hci_req_clear_event_filter(struct hci_request *req)
 
 static void hci_req_set_event_filter(struct hci_request *req)
 {
-	struct bdaddr_list *b;
+	struct bdaddr_list_with_flags *b;
 	struct hci_cp_set_event_filter f;
 	struct hci_dev *hdev = req->hdev;
-	u8 scan;
+	u8 scan = SCAN_DISABLED;
 
 	/* Always clear event filter when starting */
 	hci_req_clear_event_filter(req);
 
-	list_for_each_entry(b, &hdev->wakeable, list) {
+	list_for_each_entry(b, &hdev->whitelist, list) {
+		if (!hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP,
+					b->current_flags))
+			continue;
+
 		memset(&f, 0, sizeof(f));
 		bacpy(&f.addr_conn_flt.bdaddr, &b->bdaddr);
 		f.flt_type = HCI_FLT_CONN_SETUP;
@@ -985,9 +989,9 @@ static void hci_req_set_event_filter(struct hci_request *req)
 
 		bt_dev_dbg(hdev, "Adding event filters for %pMR", &b->bdaddr);
 		hci_req_add(req, HCI_OP_SET_EVENT_FLT, sizeof(f), &f);
+		scan = SCAN_PAGE;
 	}
 
-	scan = !list_empty(&hdev->wakeable) ? SCAN_PAGE : SCAN_DISABLED;
 	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
 }
 
-- 
2.26.2


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

* [PATCH v2 04/14] Bluetooth: Replace wakeable in hci_conn_params
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (2 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 03/14] Bluetooth: Replace wakeable list with flag Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 05/14] Bluetooth: Add get/set device flags mgmt op Marcel Holtmann
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>

Replace the wakeable boolean with flags in hci_conn_params and all users
of this boolean. This will be used by the get/set device flags mgmt op.

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Alain Michaud <alainm@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h | 2 +-
 net/bluetooth/hci_request.c      | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0643c737ba85..6f88e5d81bd2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -660,7 +660,7 @@ struct hci_conn_params {
 
 	struct hci_conn *conn;
 	bool explicit_connect;
-	bool wakeable;
+	u32 current_flags;
 };
 
 extern struct list_head hci_dev_list;
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index a5b53d3ea508..eee9c007a5fb 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -710,7 +710,8 @@ static int add_to_white_list(struct hci_request *req,
 	}
 
 	/* During suspend, only wakeable devices can be in whitelist */
-	if (hdev->suspended && !params->wakeable)
+	if (hdev->suspended && !hci_conn_test_flag(HCI_CONN_FLAG_REMOTE_WAKEUP,
+						   params->current_flags))
 		return 0;
 
 	*num_entries += 1;
-- 
2.26.2


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

* [PATCH v2 05/14] Bluetooth: Add get/set device flags mgmt op
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (3 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 04/14] Bluetooth: Replace wakeable in hci_conn_params Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 18:03   ` Abhishek Pandit-Subedi
  2020-06-17 14:39 ` [PATCH v2 06/14] Bluetooth: Add definitions for advertisement monitor features Marcel Holtmann
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>

Add the get device flags and set device flags mgmt ops and the device
flags changed event. Their behavior is described in detail in
mgmt-api.txt in bluez.

Sample btmon trace when a HID device is added (trimmed to 75 chars):

@ MGMT Command: Unknown (0x0050) plen 11        {0x0001} [hci0] 18:06:14.98
        90 c5 13 cd f3 cd 02 01 00 00 00                 ...........
@ MGMT Event: Unknown (0x002a) plen 15          {0x0004} [hci0] 18:06:14.98
        90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
@ MGMT Event: Unknown (0x002a) plen 15          {0x0003} [hci0] 18:06:14.98
        90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
@ MGMT Event: Unknown (0x002a) plen 15          {0x0002} [hci0] 18:06:14.98
        90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
@ MGMT Event: Command Compl.. (0x0001) plen 10  {0x0001} [hci0] 18:06:14.98
      Unknown (0x0050) plen 7
        Status: Success (0x00)
        90 c5 13 cd f3 cd 02                             .......
@ MGMT Command: Add Device (0x0033) plen 8      {0x0001} [hci0] 18:06:14.98
        LE Address: CD:F3:CD:13:C5:90 (Static)
        Action: Auto-connect remote device (0x02)
@ MGMT Event: Device Added (0x001a) plen 8      {0x0004} [hci0] 18:06:14.98
        LE Address: CD:F3:CD:13:C5:90 (Static)
        Action: Auto-connect remote device (0x02)
@ MGMT Event: Device Added (0x001a) plen 8      {0x0003} [hci0] 18:06:14.98
        LE Address: CD:F3:CD:13:C5:90 (Static)
        Action: Auto-connect remote device (0x02)
@ MGMT Event: Device Added (0x001a) plen 8      {0x0002} [hci0] 18:06:14.98
        LE Address: CD:F3:CD:13:C5:90 (Static)
        Action: Auto-connect remote device (0x02)
@ MGMT Event: Unknown (0x002a) plen 15          {0x0004} [hci0] 18:06:14.98
        90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
@ MGMT Event: Unknown (0x002a) plen 15          {0x0003} [hci0] 18:06:14.98
        90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
@ MGMT Event: Unknown (0x002a) plen 15          {0x0002} [hci0] 18:06:14.98
        90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
@ MGMT Event: Unknown (0x002a) plen 15          {0x0001} [hci0] 18:06:14.98
        90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............

Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
Reviewed-by: Alain Michaud <alainm@chromium.org>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/mgmt.h |  28 ++++++++
 net/bluetooth/mgmt.c         | 128 +++++++++++++++++++++++++++++++++++
 2 files changed, 156 insertions(+)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index e515288f328f..8e47b0c5fe52 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -720,6 +720,27 @@ struct mgmt_rp_set_exp_feature {
 #define MGMT_OP_SET_DEF_RUNTIME_CONFIG	0x004e
 #define MGMT_SET_DEF_RUNTIME_CONFIG_SIZE	0
 
+#define MGMT_OP_GET_DEVICE_FLAGS	0x004F
+#define MGMT_GET_DEVICE_FLAGS_SIZE	7
+struct mgmt_cp_get_device_flags {
+	struct mgmt_addr_info addr;
+} __packed;
+struct mgmt_rp_get_device_flags {
+	struct mgmt_addr_info addr;
+	__le32 supported_flags;
+	__le32 current_flags;
+} __packed;
+
+#define MGMT_OP_SET_DEVICE_FLAGS	0x0050
+#define MGMT_SET_DEVICE_FLAGS_SIZE	11
+struct mgmt_cp_set_device_flags {
+	struct mgmt_addr_info addr;
+	__le32 current_flags;
+} __packed;
+struct mgmt_rp_set_device_flags {
+	struct mgmt_addr_info addr;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
@@ -951,3 +972,10 @@ struct mgmt_ev_exp_feature_changed {
 	__u8	uuid[16];
 	__le32	flags;
 } __packed;
+
+#define MGMT_EV_DEVICE_FLAGS_CHANGED		0x002a
+struct mgmt_ev_device_flags_changed {
+	struct mgmt_addr_info addr;
+	__le32 supported_flags;
+	__le32 current_flags;
+} __packed;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index d0d0fa832c8a..e409ff48e8e6 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -116,6 +116,8 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_DEF_SYSTEM_CONFIG,
 	MGMT_OP_READ_DEF_RUNTIME_CONFIG,
 	MGMT_OP_SET_DEF_RUNTIME_CONFIG,
+	MGMT_OP_GET_DEVICE_FLAGS,
+	MGMT_OP_SET_DEVICE_FLAGS,
 };
 
 static const u16 mgmt_events[] = {
@@ -156,6 +158,7 @@ static const u16 mgmt_events[] = {
 	MGMT_EV_EXT_INFO_CHANGED,
 	MGMT_EV_PHY_CONFIGURATION_CHANGED,
 	MGMT_EV_EXP_FEATURE_CHANGED,
+	MGMT_EV_DEVICE_FLAGS_CHANGED,
 };
 
 static const u16 mgmt_untrusted_commands[] = {
@@ -3856,6 +3859,120 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
 			       MGMT_STATUS_NOT_SUPPORTED);
 }
 
+#define SUPPORTED_DEVICE_FLAGS() ((1U << HCI_CONN_FLAG_MAX) - 1)
+
+static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
+			    u16 data_len)
+{
+	struct mgmt_cp_get_device_flags *cp = data;
+	struct mgmt_rp_get_device_flags rp;
+	struct bdaddr_list_with_flags *br_params;
+	struct hci_conn_params *params;
+	u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
+	u32 current_flags = 0;
+	u8 status = MGMT_STATUS_INVALID_PARAMS;
+
+	bt_dev_dbg(hdev, "Get device flags %pMR (type 0x%x)\n",
+		   &cp->addr.bdaddr, cp->addr.type);
+
+	if (cp->addr.type == BDADDR_BREDR) {
+		br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
+							      &cp->addr.bdaddr,
+							      cp->addr.type);
+		if (!br_params)
+			goto done;
+
+		current_flags = br_params->current_flags;
+	} else {
+		params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+						le_addr_type(cp->addr.type));
+
+		if (!params)
+			goto done;
+
+		current_flags = params->current_flags;
+	}
+
+	bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
+	rp.addr.type = cp->addr.type;
+	rp.supported_flags = cpu_to_le32(supported_flags);
+	rp.current_flags = cpu_to_le32(current_flags);
+
+	status = MGMT_STATUS_SUCCESS;
+
+done:
+	return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_DEVICE_FLAGS, status,
+				&rp, sizeof(rp));
+}
+
+static void device_flags_changed(struct sock *sk, struct hci_dev *hdev,
+				 bdaddr_t *bdaddr, u8 bdaddr_type,
+				 u32 supported_flags, u32 current_flags)
+{
+	struct mgmt_ev_device_flags_changed ev;
+
+	bacpy(&ev.addr.bdaddr, bdaddr);
+	ev.addr.type = bdaddr_type;
+	ev.supported_flags = cpu_to_le32(supported_flags);
+	ev.current_flags = cpu_to_le32(current_flags);
+
+	mgmt_event(MGMT_EV_DEVICE_FLAGS_CHANGED, hdev, &ev, sizeof(ev), sk);
+}
+
+static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
+			    u16 len)
+{
+	struct mgmt_cp_set_device_flags *cp = data;
+	struct bdaddr_list_with_flags *br_params;
+	struct hci_conn_params *params;
+	u8 status = MGMT_STATUS_INVALID_PARAMS;
+	u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
+	u32 current_flags = __le32_to_cpu(cp->current_flags);
+
+	bt_dev_dbg(hdev, "Set device flags %pMR (type 0x%x) = 0x%x",
+		   &cp->addr.bdaddr, cp->addr.type,
+		   __le32_to_cpu(current_flags));
+
+	if ((supported_flags | current_flags) != supported_flags) {
+		bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
+			    current_flags, supported_flags);
+		goto done;
+	}
+
+	if (cp->addr.type == BDADDR_BREDR) {
+		br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
+							      &cp->addr.bdaddr,
+							      cp->addr.type);
+
+		if (br_params) {
+			br_params->current_flags = current_flags;
+			status = MGMT_STATUS_SUCCESS;
+		} else {
+			bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)",
+				    &cp->addr.bdaddr, cp->addr.type);
+		}
+	} else {
+		params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+						le_addr_type(cp->addr.type));
+		if (params) {
+			params->current_flags = current_flags;
+			status = MGMT_STATUS_SUCCESS;
+		} else {
+			bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
+				    &cp->addr.bdaddr,
+				    le_addr_type(cp->addr.type));
+		}
+	}
+
+done:
+	if (status == MGMT_STATUS_SUCCESS)
+		device_flags_changed(sk, hdev, &cp->addr.bdaddr, cp->addr.type,
+				     supported_flags, current_flags);
+
+	return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_FLAGS, status,
+				 &cp->addr, sizeof(cp->addr));
+}
+
 static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
 				         u16 opcode, struct sk_buff *skb)
 {
@@ -5973,7 +6090,9 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
 {
 	struct mgmt_cp_add_device *cp = data;
 	u8 auto_conn, addr_type;
+	struct hci_conn_params *params;
 	int err;
+	u32 current_flags = 0;
 
 	bt_dev_dbg(hdev, "sock %p", sk);
 
@@ -6041,12 +6160,19 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
 					MGMT_STATUS_FAILED, &cp->addr,
 					sizeof(cp->addr));
 		goto unlock;
+	} else {
+		params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
+						addr_type);
+		if (params)
+			current_flags = params->current_flags;
 	}
 
 	hci_update_background_scan(hdev);
 
 added:
 	device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
+	device_flags_changed(NULL, hdev, &cp->addr.bdaddr, cp->addr.type,
+			     SUPPORTED_DEVICE_FLAGS(), current_flags);
 
 	err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
 				MGMT_STATUS_SUCCESS, &cp->addr,
@@ -7313,6 +7439,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 						HCI_MGMT_UNTRUSTED },
 	{ set_def_runtime_config,  MGMT_SET_DEF_RUNTIME_CONFIG_SIZE,
 						HCI_MGMT_VAR_LEN },
+	{ get_device_flags,        MGMT_GET_DEVICE_FLAGS_SIZE },
+	{ set_device_flags,        MGMT_SET_DEVICE_FLAGS_SIZE },
 };
 
 void mgmt_index_added(struct hci_dev *hdev)
-- 
2.26.2


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

* [PATCH v2 06/14] Bluetooth: Add definitions for advertisement monitor features
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (4 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 05/14] Bluetooth: Add get/set device flags mgmt op Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 07/14] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES Marcel Holtmann
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Miao-chen Chou <mcchou@chromium.org>

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>
Signed-off-by: Marcel Holtmann <marcel@holtmann.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 8e47b0c5fe52..beae5c3980f0 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -741,6 +741,45 @@ struct mgmt_rp_set_device_flags {
 	struct mgmt_addr_info addr;
 } __packed;
 
+#define MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS    BIT(0)
+
+#define MGMT_OP_READ_ADV_MONITOR_FEATURES	0x0051
+#define MGMT_READ_ADV_MONITOR_FEATURES_SIZE	0
+struct mgmt_rp_read_adv_monitor_features {
+	__le32 supported_features;
+	__le32 enabled_features;
+	__le16 max_num_handles;
+	__u8 max_num_patterns;
+	__le16 num_handles;
+	__le16 handles[];
+}  __packed;
+
+struct mgmt_adv_pattern {
+	__u8 ad_type;
+	__u8 offset;
+	__u8 length;
+	__u8 value[31];
+} __packed;
+
+#define MGMT_OP_ADD_ADV_PATTERNS_MONITOR	0x0052
+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 {
+	__le16 monitor_handle;
+} __packed;
+
+#define MGMT_OP_REMOVE_ADV_MONITOR		0x0053
+struct mgmt_cp_remove_adv_monitor {
+	__le16 monitor_handle;
+} __packed;
+#define MGMT_REMOVE_ADV_MONITOR_SIZE		2
+struct mgmt_rp_remove_adv_monitor {
+	__le16 monitor_handle;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
@@ -979,3 +1018,13 @@ struct mgmt_ev_device_flags_changed {
 	__le32 supported_flags;
 	__le32 current_flags;
 } __packed;
+
+#define MGMT_EV_ADV_MONITOR_ADDED	0x002b
+struct mgmt_ev_adv_monitor_added {
+	__le16 monitor_handle;
+}  __packed;
+
+#define MGMT_EV_ADV_MONITOR_REMOVED	0x002c
+struct mgmt_ev_adv_monitor_removed {
+	__le16 monitor_handle;
+}  __packed;
-- 
2.26.2


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

* [PATCH v2 07/14] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (5 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 06/14] Bluetooth: Add definitions for advertisement monitor features Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 08/14] Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR Marcel Holtmann
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Miao-chen Chou <mcchou@chromium.org>

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>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h | 24 ++++++++++++++++
 net/bluetooth/hci_core.c         | 10 ++++++-
 net/bluetooth/mgmt.c             | 48 ++++++++++++++++++++++++++++++++
 net/bluetooth/msft.c             |  7 +++++
 net/bluetooth/msft.h             |  9 ++++++
 5 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 6f88e5d81bd2..4e9d51087674 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>
 
@@ -237,6 +238,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 */
@@ -511,6 +530,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;
@@ -1258,6 +1280,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 8e01afb2ee8c..53aec32a5850 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)
 {
@@ -3646,6 +3651,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:
@@ -3716,6 +3723,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 e409ff48e8e6..8aec7fbe9a38 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -37,6 +37,7 @@
 #include "smp.h"
 #include "mgmt_util.h"
 #include "mgmt_config.h"
+#include "msft.h"
 
 #define MGMT_VERSION	1
 #define MGMT_REVISION	17
@@ -118,6 +119,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_DEF_RUNTIME_CONFIG,
 	MGMT_OP_GET_DEVICE_FLAGS,
 	MGMT_OP_SET_DEVICE_FLAGS,
+	MGMT_OP_READ_ADV_MONITOR_FEATURES,
 };
 
 static const u16 mgmt_events[] = {
@@ -3973,6 +3975,51 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
 				 &cp->addr, sizeof(cp->addr));
 }
 
+static int read_adv_mon_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 = cpu_to_le32(supported);
+	rp->enabled_features = 0;
+	rp->max_num_handles = cpu_to_le16(HCI_MAX_ADV_MONITOR_NUM_HANDLES);
+	rp->max_num_patterns = HCI_MAX_ADV_MONITOR_NUM_PATTERNS;
+	rp->num_handles = cpu_to_le16(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)
 {
@@ -7441,6 +7488,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 						HCI_MGMT_VAR_LEN },
 	{ get_device_flags,        MGMT_GET_DEVICE_FLAGS_SIZE },
 	{ set_device_flags,        MGMT_SET_DEVICE_FLAGS_SIZE },
+	{ read_adv_mon_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 d6c4e6b5ae77..8579bfeb2836 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 5aa9130e1f8a..e9c478e890b8 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] 20+ messages in thread

* [PATCH v2 08/14] Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (6 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 07/14] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 09/14] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR Marcel Holtmann
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Miao-chen Chou <mcchou@chromium.org>

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>
Signed-off-by: Marcel Holtmann <marcel@holtmann.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 4e9d51087674..13fad419ae7d 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1281,6 +1281,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 53aec32a5850..ce481fab349d 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 8aec7fbe9a38..1eca36e51706 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -120,6 +120,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_GET_DEVICE_FLAGS,
 	MGMT_OP_SET_DEVICE_FLAGS,
 	MGMT_OP_READ_ADV_MONITOR_FEATURES,
+	MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
 };
 
 static const u16 mgmt_events[] = {
@@ -4020,6 +4021,103 @@ static int read_adv_mon_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 = cpu_to_le16(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)
 {
@@ -7489,6 +7587,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 	{ get_device_flags,        MGMT_GET_DEVICE_FLAGS_SIZE },
 	{ set_device_flags,        MGMT_SET_DEVICE_FLAGS_SIZE },
 	{ read_adv_mon_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] 20+ messages in thread

* [PATCH v2 09/14] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (7 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 08/14] Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 10/14] Bluetooth: Notify adv monitor added event Marcel Holtmann
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Miao-chen Chou <mcchou@chromium.org>

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>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 31 ++++++++++++++++++++++++++++
 net/bluetooth/mgmt.c             | 35 ++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 13fad419ae7d..c54f9295892e 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1283,6 +1283,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 ce481fab349d..59132b3e2cde 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 1eca36e51706..cff24fde72d2 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -121,6 +121,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_DEVICE_FLAGS,
 	MGMT_OP_READ_ADV_MONITOR_FEATURES,
 	MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
+	MGMT_OP_REMOVE_ADV_MONITOR,
 };
 
 static const u16 mgmt_events[] = {
@@ -4118,6 +4119,39 @@ 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;
+	u16 handle;
+	int err;
+
+	BT_DBG("request for %s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	handle = __le16_to_cpu(cp->monitor_handle);
+
+	err = hci_remove_adv_monitor(hdev, 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)
 {
@@ -7589,6 +7623,7 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
 	{ read_adv_mon_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] 20+ messages in thread

* [PATCH v2 10/14] Bluetooth: Notify adv monitor added event
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (8 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 09/14] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 11/14] Bluetooth: Notify adv monitor removed event Marcel Holtmann
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Miao-chen Chou <mcchou@chromium.org>

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>
Signed-off-by: Marcel Holtmann <marcel@holtmann.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 cff24fde72d2..3268d9a00608 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -191,6 +191,7 @@ static const u16 mgmt_untrusted_events[] = {
 	MGMT_EV_EXT_INDEX_REMOVED,
 	MGMT_EV_EXT_INFO_CHANGED,
 	MGMT_EV_EXP_FEATURE_CHANGED,
+	MGMT_EV_ADV_MONITOR_ADDED,
 };
 
 #define CACHE_TIMEOUT	msecs_to_jiffies(2 * 1000)
@@ -3977,6 +3978,16 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
 				 &cp->addr, sizeof(cp->addr));
 }
 
+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 = cpu_to_le16(handle);
+
+	mgmt_event(MGMT_EV_ADV_MONITOR_ADDED, hdev, &ev, sizeof(ev), sk);
+}
+
 static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev,
 				 void *data, u16 len)
 {
@@ -4029,8 +4040,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);
@@ -4094,6 +4105,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) {
@@ -4104,6 +4117,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 = cpu_to_le16(m->handle);
-- 
2.26.2


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

* [PATCH v2 11/14] Bluetooth: Notify adv monitor removed event
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (9 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 10/14] Bluetooth: Notify adv monitor added event Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 12/14] Bluetooth: Update background scan and report device based on advertisement monitors Marcel Holtmann
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Miao-chen Chou <mcchou@chromium.org>

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>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/mgmt.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 3268d9a00608..b194da4de2d7 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -192,6 +192,7 @@ static const u16 mgmt_untrusted_events[] = {
 	MGMT_EV_EXT_INFO_CHANGED,
 	MGMT_EV_EXP_FEATURE_CHANGED,
 	MGMT_EV_ADV_MONITOR_ADDED,
+	MGMT_EV_ADV_MONITOR_REMOVED,
 };
 
 #define CACHE_TIMEOUT	msecs_to_jiffies(2 * 1000)
@@ -3988,6 +3989,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 = cpu_to_le16(handle);
+
+	mgmt_event(MGMT_EV_ADV_MONITOR_REMOVED, hdev, &ev, sizeof(ev), sk);
+}
+
 static int read_adv_mon_features(struct sock *sk, struct hci_dev *hdev,
 				 void *data, u16 len)
 {
@@ -4140,6 +4151,7 @@ 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;
 	u16 handle;
 	int err;
 
@@ -4148,6 +4160,7 @@ static int remove_adv_monitor(struct sock *sk, struct hci_dev *hdev,
 	hci_dev_lock(hdev);
 
 	handle = __le16_to_cpu(cp->monitor_handle);
+	prev_adv_monitors_cnt = hdev->adv_monitors_cnt;
 
 	err = hci_remove_adv_monitor(hdev, handle);
 	if (err == -ENOENT) {
@@ -4156,6 +4169,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, handle);
+
 	hci_dev_unlock(hdev);
 
 	rp.monitor_handle = cp->monitor_handle;
-- 
2.26.2


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

* [PATCH v2 12/14] Bluetooth: Update background scan and report device based on advertisement monitors
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (10 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 11/14] Bluetooth: Notify adv monitor removed event Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
       [not found]   ` <CGME20200629223028eucas1p27b9482456072d7864f7505379885a0b4@eucas1p2.samsung.com>
  2020-06-17 14:39 ` [PATCH v2 13/14] Bluetooth: Terminate the link if pairing is cancelled Marcel Holtmann
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Miao-chen Chou <mcchou@chromium.org>

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>
Signed-off-by: Marcel Holtmann <marcel@holtmann.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 c54f9295892e..524057598ffd 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1284,6 +1284,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 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) {
-- 
2.26.2


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

* [PATCH v2 13/14] Bluetooth: Terminate the link if pairing is cancelled
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (11 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 12/14] Bluetooth: Update background scan and report device based on advertisement monitors Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-17 14:39 ` [PATCH v2 14/14] Bluetooth: mgmt: Use command complete on success for set system config Marcel Holtmann
  2020-06-18 10:17 ` [PATCH v2 00/14] Combination of pending patches Johan Hedberg
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

From: Manish Mandlik <mmandlik@google.com>

If user decides to cancel the ongoing pairing process (e.g. by clicking
the cancel button on pairing/passkey window), abort any ongoing pairing
and then terminate the link if it was created because of the pair
device action.

Signed-off-by: Manish Mandlik <mmandlik@google.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h | 14 ++++++++++++--
 net/bluetooth/hci_conn.c         | 11 ++++++++---
 net/bluetooth/l2cap_core.c       |  6 ++++--
 net/bluetooth/mgmt.c             | 22 ++++++++++++++++++----
 4 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 524057598ffd..77d29341b064 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -564,6 +564,12 @@ struct hci_dev {
 
 #define HCI_PHY_HANDLE(handle)	(handle & 0xff)
 
+enum conn_reasons {
+	CONN_REASON_PAIR_DEVICE,
+	CONN_REASON_L2CAP_CHAN,
+	CONN_REASON_SCO_CONNECT,
+};
+
 struct hci_conn {
 	struct list_head list;
 
@@ -615,6 +621,8 @@ struct hci_conn {
 	__s8		max_tx_power;
 	unsigned long	flags;
 
+	enum conn_reasons conn_reason;
+
 	__u32		clock;
 	__u16		clock_accuracy;
 
@@ -1040,12 +1048,14 @@ struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
 
 struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
 				     u8 dst_type, u8 sec_level,
-				     u16 conn_timeout);
+				     u16 conn_timeout,
+				     enum conn_reasons conn_reason);
 struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 				u8 dst_type, u8 sec_level, u16 conn_timeout,
 				u8 role, bdaddr_t *direct_rpa);
 struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
-				 u8 sec_level, u8 auth_type);
+				 u8 sec_level, u8 auth_type,
+				 enum conn_reasons conn_reason);
 struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
 				 __u16 setting);
 int hci_conn_check_link_mode(struct hci_conn *conn);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 9bdffc4e79b0..47f3a45d7dcb 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1174,7 +1174,8 @@ static int hci_explicit_conn_params_set(struct hci_dev *hdev,
 /* This function requires the caller holds hdev->lock */
 struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
 				     u8 dst_type, u8 sec_level,
-				     u16 conn_timeout)
+				     u16 conn_timeout,
+				     enum conn_reasons conn_reason)
 {
 	struct hci_conn *conn;
 
@@ -1219,6 +1220,7 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
 	conn->sec_level = BT_SECURITY_LOW;
 	conn->pending_sec_level = sec_level;
 	conn->conn_timeout = conn_timeout;
+	conn->conn_reason = conn_reason;
 
 	hci_update_background_scan(hdev);
 
@@ -1228,7 +1230,8 @@ struct hci_conn *hci_connect_le_scan(struct hci_dev *hdev, bdaddr_t *dst,
 }
 
 struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
-				 u8 sec_level, u8 auth_type)
+				 u8 sec_level, u8 auth_type,
+				 enum conn_reasons conn_reason)
 {
 	struct hci_conn *acl;
 
@@ -1248,6 +1251,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
 
 	hci_conn_hold(acl);
 
+	acl->conn_reason = conn_reason;
 	if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
 		acl->sec_level = BT_SECURITY_LOW;
 		acl->pending_sec_level = sec_level;
@@ -1264,7 +1268,8 @@ struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
 	struct hci_conn *acl;
 	struct hci_conn *sco;
 
-	acl = hci_connect_acl(hdev, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING);
+	acl = hci_connect_acl(hdev, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING,
+			      CONN_REASON_SCO_CONNECT);
 	if (IS_ERR(acl))
 		return acl;
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index fe913a5c754a..35d2bc569a2d 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -7893,11 +7893,13 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 		else
 			hcon = hci_connect_le_scan(hdev, dst, dst_type,
 						   chan->sec_level,
-						   HCI_LE_CONN_TIMEOUT);
+						   HCI_LE_CONN_TIMEOUT,
+						   CONN_REASON_L2CAP_CHAN);
 
 	} else {
 		u8 auth_type = l2cap_get_auth_type(chan);
-		hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type);
+		hcon = hci_connect_acl(hdev, dst, chan->sec_level, auth_type,
+				       CONN_REASON_L2CAP_CHAN);
 	}
 
 	if (IS_ERR(hcon)) {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ec66160a673c..2a732cab1dc9 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2931,7 +2931,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	if (cp->addr.type == BDADDR_BREDR) {
 		conn = hci_connect_acl(hdev, &cp->addr.bdaddr, sec_level,
-				       auth_type);
+				       auth_type, CONN_REASON_PAIR_DEVICE);
 	} else {
 		u8 addr_type = le_addr_type(cp->addr.type);
 		struct hci_conn_params *p;
@@ -2950,9 +2950,9 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 		if (p->auto_connect == HCI_AUTO_CONN_EXPLICIT)
 			p->auto_connect = HCI_AUTO_CONN_DISABLED;
 
-		conn = hci_connect_le_scan(hdev, &cp->addr.bdaddr,
-					   addr_type, sec_level,
-					   HCI_LE_CONN_TIMEOUT);
+		conn = hci_connect_le_scan(hdev, &cp->addr.bdaddr, addr_type,
+					   sec_level, HCI_LE_CONN_TIMEOUT,
+					   CONN_REASON_PAIR_DEVICE);
 	}
 
 	if (IS_ERR(conn)) {
@@ -3053,6 +3053,20 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_CANCEL_PAIR_DEVICE, 0,
 				addr, sizeof(*addr));
+
+	/* Since user doesn't want to proceed with the connection, abort any
+	 * ongoing pairing and then terminate the link if it was created
+	 * because of the pair device action.
+	 */
+	if (addr->type == BDADDR_BREDR)
+		hci_remove_link_key(hdev, &addr->bdaddr);
+	else
+		smp_cancel_and_remove_pairing(hdev, &addr->bdaddr,
+					      le_addr_type(addr->type));
+
+	if (conn->conn_reason == CONN_REASON_PAIR_DEVICE)
+		hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
+
 unlock:
 	hci_dev_unlock(hdev);
 	return err;
-- 
2.26.2


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

* [PATCH v2 14/14] Bluetooth: mgmt: Use command complete on success for set system config
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (12 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 13/14] Bluetooth: Terminate the link if pairing is cancelled Marcel Holtmann
@ 2020-06-17 14:39 ` Marcel Holtmann
  2020-06-18 10:17 ` [PATCH v2 00/14] Combination of pending patches Johan Hedberg
  14 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-17 14:39 UTC (permalink / raw)
  To: linux-bluetooth

The command status reply is only for failure. When completing set system
config command, the reply has to be command complete.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Reviewed-by: Alain Michaud <alainm@chromium.org>
---
 net/bluetooth/mgmt_config.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/mgmt_config.c b/net/bluetooth/mgmt_config.c
index 8e7ad2a51dbb..8d01a8ff85e9 100644
--- a/net/bluetooth/mgmt_config.c
+++ b/net/bluetooth/mgmt_config.c
@@ -247,9 +247,8 @@ int set_def_system_config(struct sock *sk, struct hci_dev *hdev, void *data,
 		buffer += exp_len;
 	}
 
-	return mgmt_cmd_status(sk, hdev->id,
-			       MGMT_OP_SET_DEF_SYSTEM_CONFIG,
-			       MGMT_STATUS_SUCCESS);
+	return mgmt_cmd_complete(sk, hdev->id,
+				 MGMT_OP_SET_DEF_SYSTEM_CONFIG, 0, NULL, 0);
 }
 
 int read_def_runtime_config(struct sock *sk, struct hci_dev *hdev, void *data,
-- 
2.26.2


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

* Re: [PATCH v2 05/14] Bluetooth: Add get/set device flags mgmt op
  2020-06-17 14:39 ` [PATCH v2 05/14] Bluetooth: Add get/set device flags mgmt op Marcel Holtmann
@ 2020-06-17 18:03   ` Abhishek Pandit-Subedi
  0 siblings, 0 replies; 20+ messages in thread
From: Abhishek Pandit-Subedi @ 2020-06-17 18:03 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Bluez mailing list

Hi Marcel,

This looks good to me. Thanks for removing
HCI_MGMT_DEVICE_FLAGS_EVENTS -- I misunderstood what it was for.

Abhishek

On Wed, Jun 17, 2020 at 7:39 AM Marcel Holtmann <marcel@holtmann.org> wrote:
>
> From: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
>
> Add the get device flags and set device flags mgmt ops and the device
> flags changed event. Their behavior is described in detail in
> mgmt-api.txt in bluez.
>
> Sample btmon trace when a HID device is added (trimmed to 75 chars):
>
> @ MGMT Command: Unknown (0x0050) plen 11        {0x0001} [hci0] 18:06:14.98
>         90 c5 13 cd f3 cd 02 01 00 00 00                 ...........
> @ MGMT Event: Unknown (0x002a) plen 15          {0x0004} [hci0] 18:06:14.98
>         90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
> @ MGMT Event: Unknown (0x002a) plen 15          {0x0003} [hci0] 18:06:14.98
>         90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
> @ MGMT Event: Unknown (0x002a) plen 15          {0x0002} [hci0] 18:06:14.98
>         90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
> @ MGMT Event: Command Compl.. (0x0001) plen 10  {0x0001} [hci0] 18:06:14.98
>       Unknown (0x0050) plen 7
>         Status: Success (0x00)
>         90 c5 13 cd f3 cd 02                             .......
> @ MGMT Command: Add Device (0x0033) plen 8      {0x0001} [hci0] 18:06:14.98
>         LE Address: CD:F3:CD:13:C5:90 (Static)
>         Action: Auto-connect remote device (0x02)
> @ MGMT Event: Device Added (0x001a) plen 8      {0x0004} [hci0] 18:06:14.98
>         LE Address: CD:F3:CD:13:C5:90 (Static)
>         Action: Auto-connect remote device (0x02)
> @ MGMT Event: Device Added (0x001a) plen 8      {0x0003} [hci0] 18:06:14.98
>         LE Address: CD:F3:CD:13:C5:90 (Static)
>         Action: Auto-connect remote device (0x02)
> @ MGMT Event: Device Added (0x001a) plen 8      {0x0002} [hci0] 18:06:14.98
>         LE Address: CD:F3:CD:13:C5:90 (Static)
>         Action: Auto-connect remote device (0x02)
> @ MGMT Event: Unknown (0x002a) plen 15          {0x0004} [hci0] 18:06:14.98
>         90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
> @ MGMT Event: Unknown (0x002a) plen 15          {0x0003} [hci0] 18:06:14.98
>         90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
> @ MGMT Event: Unknown (0x002a) plen 15          {0x0002} [hci0] 18:06:14.98
>         90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
> @ MGMT Event: Unknown (0x002a) plen 15          {0x0001} [hci0] 18:06:14.98
>         90 c5 13 cd f3 cd 02 01 00 00 00 01 00 00 00     ...............
>
> Signed-off-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
> Reviewed-by: Alain Michaud <alainm@chromium.org>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  include/net/bluetooth/mgmt.h |  28 ++++++++
>  net/bluetooth/mgmt.c         | 128 +++++++++++++++++++++++++++++++++++
>  2 files changed, 156 insertions(+)
>
> diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
> index e515288f328f..8e47b0c5fe52 100644
> --- a/include/net/bluetooth/mgmt.h
> +++ b/include/net/bluetooth/mgmt.h
> @@ -720,6 +720,27 @@ struct mgmt_rp_set_exp_feature {
>  #define MGMT_OP_SET_DEF_RUNTIME_CONFIG 0x004e
>  #define MGMT_SET_DEF_RUNTIME_CONFIG_SIZE       0
>
> +#define MGMT_OP_GET_DEVICE_FLAGS       0x004F
> +#define MGMT_GET_DEVICE_FLAGS_SIZE     7
> +struct mgmt_cp_get_device_flags {
> +       struct mgmt_addr_info addr;
> +} __packed;
> +struct mgmt_rp_get_device_flags {
> +       struct mgmt_addr_info addr;
> +       __le32 supported_flags;
> +       __le32 current_flags;
> +} __packed;
> +
> +#define MGMT_OP_SET_DEVICE_FLAGS       0x0050
> +#define MGMT_SET_DEVICE_FLAGS_SIZE     11
> +struct mgmt_cp_set_device_flags {
> +       struct mgmt_addr_info addr;
> +       __le32 current_flags;
> +} __packed;
> +struct mgmt_rp_set_device_flags {
> +       struct mgmt_addr_info addr;
> +} __packed;
> +
>  #define MGMT_EV_CMD_COMPLETE           0x0001
>  struct mgmt_ev_cmd_complete {
>         __le16  opcode;
> @@ -951,3 +972,10 @@ struct mgmt_ev_exp_feature_changed {
>         __u8    uuid[16];
>         __le32  flags;
>  } __packed;
> +
> +#define MGMT_EV_DEVICE_FLAGS_CHANGED           0x002a
> +struct mgmt_ev_device_flags_changed {
> +       struct mgmt_addr_info addr;
> +       __le32 supported_flags;
> +       __le32 current_flags;
> +} __packed;
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index d0d0fa832c8a..e409ff48e8e6 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -116,6 +116,8 @@ static const u16 mgmt_commands[] = {
>         MGMT_OP_SET_DEF_SYSTEM_CONFIG,
>         MGMT_OP_READ_DEF_RUNTIME_CONFIG,
>         MGMT_OP_SET_DEF_RUNTIME_CONFIG,
> +       MGMT_OP_GET_DEVICE_FLAGS,
> +       MGMT_OP_SET_DEVICE_FLAGS,
>  };
>
>  static const u16 mgmt_events[] = {
> @@ -156,6 +158,7 @@ static const u16 mgmt_events[] = {
>         MGMT_EV_EXT_INFO_CHANGED,
>         MGMT_EV_PHY_CONFIGURATION_CHANGED,
>         MGMT_EV_EXP_FEATURE_CHANGED,
> +       MGMT_EV_DEVICE_FLAGS_CHANGED,
>  };
>
>  static const u16 mgmt_untrusted_commands[] = {
> @@ -3856,6 +3859,120 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
>                                MGMT_STATUS_NOT_SUPPORTED);
>  }
>
> +#define SUPPORTED_DEVICE_FLAGS() ((1U << HCI_CONN_FLAG_MAX) - 1)
> +
> +static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
> +                           u16 data_len)
> +{
> +       struct mgmt_cp_get_device_flags *cp = data;
> +       struct mgmt_rp_get_device_flags rp;
> +       struct bdaddr_list_with_flags *br_params;
> +       struct hci_conn_params *params;
> +       u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
> +       u32 current_flags = 0;
> +       u8 status = MGMT_STATUS_INVALID_PARAMS;
> +
> +       bt_dev_dbg(hdev, "Get device flags %pMR (type 0x%x)\n",
> +                  &cp->addr.bdaddr, cp->addr.type);
> +
> +       if (cp->addr.type == BDADDR_BREDR) {
> +               br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
> +                                                             &cp->addr.bdaddr,
> +                                                             cp->addr.type);
> +               if (!br_params)
> +                       goto done;
> +
> +               current_flags = br_params->current_flags;
> +       } else {
> +               params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
> +                                               le_addr_type(cp->addr.type));
> +
> +               if (!params)
> +                       goto done;
> +
> +               current_flags = params->current_flags;
> +       }
> +
> +       bacpy(&rp.addr.bdaddr, &cp->addr.bdaddr);
> +       rp.addr.type = cp->addr.type;
> +       rp.supported_flags = cpu_to_le32(supported_flags);
> +       rp.current_flags = cpu_to_le32(current_flags);
> +
> +       status = MGMT_STATUS_SUCCESS;
> +
> +done:
> +       return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_GET_DEVICE_FLAGS, status,
> +                               &rp, sizeof(rp));
> +}
> +
> +static void device_flags_changed(struct sock *sk, struct hci_dev *hdev,
> +                                bdaddr_t *bdaddr, u8 bdaddr_type,
> +                                u32 supported_flags, u32 current_flags)
> +{
> +       struct mgmt_ev_device_flags_changed ev;
> +
> +       bacpy(&ev.addr.bdaddr, bdaddr);
> +       ev.addr.type = bdaddr_type;
> +       ev.supported_flags = cpu_to_le32(supported_flags);
> +       ev.current_flags = cpu_to_le32(current_flags);
> +
> +       mgmt_event(MGMT_EV_DEVICE_FLAGS_CHANGED, hdev, &ev, sizeof(ev), sk);
> +}
> +
> +static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
> +                           u16 len)
> +{
> +       struct mgmt_cp_set_device_flags *cp = data;
> +       struct bdaddr_list_with_flags *br_params;
> +       struct hci_conn_params *params;
> +       u8 status = MGMT_STATUS_INVALID_PARAMS;
> +       u32 supported_flags = SUPPORTED_DEVICE_FLAGS();
> +       u32 current_flags = __le32_to_cpu(cp->current_flags);
> +
> +       bt_dev_dbg(hdev, "Set device flags %pMR (type 0x%x) = 0x%x",
> +                  &cp->addr.bdaddr, cp->addr.type,
> +                  __le32_to_cpu(current_flags));
> +
> +       if ((supported_flags | current_flags) != supported_flags) {
> +               bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
> +                           current_flags, supported_flags);
> +               goto done;
> +       }
> +
> +       if (cp->addr.type == BDADDR_BREDR) {
> +               br_params = hci_bdaddr_list_lookup_with_flags(&hdev->whitelist,
> +                                                             &cp->addr.bdaddr,
> +                                                             cp->addr.type);
> +
> +               if (br_params) {
> +                       br_params->current_flags = current_flags;
> +                       status = MGMT_STATUS_SUCCESS;
> +               } else {
> +                       bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)",
> +                                   &cp->addr.bdaddr, cp->addr.type);
> +               }
> +       } else {
> +               params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
> +                                               le_addr_type(cp->addr.type));
> +               if (params) {
> +                       params->current_flags = current_flags;
> +                       status = MGMT_STATUS_SUCCESS;
> +               } else {
> +                       bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
> +                                   &cp->addr.bdaddr,
> +                                   le_addr_type(cp->addr.type));
> +               }
> +       }
> +
> +done:
> +       if (status == MGMT_STATUS_SUCCESS)
> +               device_flags_changed(sk, hdev, &cp->addr.bdaddr, cp->addr.type,
> +                                    supported_flags, current_flags);
> +
> +       return mgmt_cmd_complete(sk, hdev->id, MGMT_OP_SET_DEVICE_FLAGS, status,
> +                                &cp->addr, sizeof(cp->addr));
> +}
> +
>  static void read_local_oob_data_complete(struct hci_dev *hdev, u8 status,
>                                          u16 opcode, struct sk_buff *skb)
>  {
> @@ -5973,7 +6090,9 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
>  {
>         struct mgmt_cp_add_device *cp = data;
>         u8 auto_conn, addr_type;
> +       struct hci_conn_params *params;
>         int err;
> +       u32 current_flags = 0;
>
>         bt_dev_dbg(hdev, "sock %p", sk);
>
> @@ -6041,12 +6160,19 @@ static int add_device(struct sock *sk, struct hci_dev *hdev,
>                                         MGMT_STATUS_FAILED, &cp->addr,
>                                         sizeof(cp->addr));
>                 goto unlock;
> +       } else {
> +               params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
> +                                               addr_type);
> +               if (params)
> +                       current_flags = params->current_flags;
>         }
>
>         hci_update_background_scan(hdev);
>
>  added:
>         device_added(sk, hdev, &cp->addr.bdaddr, cp->addr.type, cp->action);
> +       device_flags_changed(NULL, hdev, &cp->addr.bdaddr, cp->addr.type,
> +                            SUPPORTED_DEVICE_FLAGS(), current_flags);
>
>         err = mgmt_cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE,
>                                 MGMT_STATUS_SUCCESS, &cp->addr,
> @@ -7313,6 +7439,8 @@ static const struct hci_mgmt_handler mgmt_handlers[] = {
>                                                 HCI_MGMT_UNTRUSTED },
>         { set_def_runtime_config,  MGMT_SET_DEF_RUNTIME_CONFIG_SIZE,
>                                                 HCI_MGMT_VAR_LEN },
> +       { get_device_flags,        MGMT_GET_DEVICE_FLAGS_SIZE },
> +       { set_device_flags,        MGMT_SET_DEVICE_FLAGS_SIZE },
>  };
>
>  void mgmt_index_added(struct hci_dev *hdev)
> --
> 2.26.2
>

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

* Re: [PATCH v2 00/14] Combination of pending patches
  2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
                   ` (13 preceding siblings ...)
  2020-06-17 14:39 ` [PATCH v2 14/14] Bluetooth: mgmt: Use command complete on success for set system config Marcel Holtmann
@ 2020-06-18 10:17 ` Johan Hedberg
  14 siblings, 0 replies; 20+ messages in thread
From: Johan Hedberg @ 2020-06-18 10:17 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth

Hi Marcel,

On Wed, Jun 17, 2020, Marcel Holtmann wrote:
> This is the list of pending patches and fixes merged together. Please
> review that the set and functionality is correct and working as
> expected.
> 
> In v2 the Reviewed-by tags have been added.
> 
> Abhishek Pandit-Subedi (4):
>   Bluetooth: Add bdaddr_list_with_flags for classic whitelist
>   Bluetooth: Replace wakeable list with flag
>   Bluetooth: Replace wakeable in hci_conn_params
>   Bluetooth: Add get/set device flags mgmt op
> 
> Manish Mandlik (1):
>   Bluetooth: Terminate the link if pairing is cancelled
> 
> Marcel Holtmann (2):
>   Bluetooth: mgmt: Add commands for runtime configuration
>   Bluetooth: mgmt: Use command complete on success for set system config
> 
> Miao-chen Chou (7):
>   Bluetooth: Add definitions for advertisement monitor features
>   Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES
>   Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR
>   Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR
>   Bluetooth: Notify adv monitor added event
>   Bluetooth: Notify adv monitor removed event
>   Bluetooth: Update background scan and report device based on
>     advertisement monitors
> 
>  include/net/bluetooth/hci_core.h |  73 +++++-
>  include/net/bluetooth/mgmt.h     |  77 +++++++
>  net/bluetooth/hci_conn.c         |  11 +-
>  net/bluetooth/hci_core.c         | 153 ++++++++++++-
>  net/bluetooth/hci_event.c        |  13 +-
>  net/bluetooth/hci_request.c      |  32 ++-
>  net/bluetooth/l2cap_core.c       |   6 +-
>  net/bluetooth/mgmt.c             | 382 ++++++++++++++++++++++++++++++-
>  net/bluetooth/mgmt_config.c      |  23 +-
>  net/bluetooth/mgmt_config.h      |   6 +
>  net/bluetooth/msft.c             |   7 +
>  net/bluetooth/msft.h             |   9 +
>  12 files changed, 755 insertions(+), 37 deletions(-)

All patches in this set have been applied to bluetooth-next. Thanks.

Johan

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

* Re: [PATCH v2 12/14] Bluetooth: Update background scan and report device based on advertisement monitors
       [not found]   ` <CGME20200629223028eucas1p27b9482456072d7864f7505379885a0b4@eucas1p2.samsung.com>
@ 2020-06-29 22:30     ` Marek Szyprowski
  2020-06-30  6:49       ` Marcel Holtmann
  0 siblings, 1 reply; 20+ messages in thread
From: Marek Szyprowski @ 2020-06-29 22:30 UTC (permalink / raw)
  To: Marcel Holtmann, linux-bluetooth, 'Linux Samsung SOC',
	Miao-chen Chou, Johan Hedberg

Hi

On 17.06.2020 16:39, Marcel Holtmann wrote:
> From: Miao-chen Chou <mcchou@chromium.org>
>
> 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>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

This patch landed recently in linux-next as commit 8208f5a9d435 
("Bluetooth: Update background scan and report device based on 
advertisement monitors").

It causes a regression, a kernel oops during system suspend/resume cycle 
on Samsung Exynos5250 based Snow Chromebook:

8<--- cut here ---
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = 86c149f5
[00000000] *pgd=00000000
Internal error: Oops: 5 [#1] SMP ARM
Modules linked in: cmac cros_ec_sysfs cros_ec_lightbar cros_ec_debugfs 
cros_ec_chardev cros_ec_keyb cros_ec_dev snd_soc_hdmi_codec cros_ec_i2c 
cros_ec snd_soc_snow snd_soc_i2s snd_soc_idma snd_soc_s3c_dma exynosdrm 
analogix_dp exynos_gsc v4l2_mem2mem snd_soc_max98095 snd_soc_core 
ac97_bus snd_pcm_dmaengine snd_pcm snd_timer nxp_ptn3460 snd soundcore 
pwm_samsung spi_s3c64xx cyapatp crc_itu_t mwifiex_sdio mwifiex 
sha256_generic libsha256 sha256_arm btmrvl_sdio btmrvl cfg80211 
bluetooth s5p_mfc governor_simpleondemand videobuf2_dma_contig 
videobuf2_memops videobuf2_v4l2 ecdh_generic ecc videobuf2_common 
videodev phy_exynos_usb2 ohci_exynos panfrost gpu_sched mc s3c2410_wdt 
s5p_sss s5p_cec exynos_rng rtc_s3c i2c_arb_gpio_challenge
CPU: 1 PID: 16 Comm: kworker/1:0 Not tainted 
5.7.0-rc7-02995-g8208f5a9d435 #8564
Hardware name: Samsung Exynos (Flattened Device Tree)
Workqueue: events_freezable mmc_rescan
PC is at __queue_work+0x6c/0x4e8
LR is at __queue_work+0x68/0x4e8
pc : [<c03619d8>]    lr : [<c03619d4>]    psr: 60000093
...
Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 10c5387d  Table: 6be2406a  DAC: 00000051
Process kworker/1:0 (pid: 16, stack limit = 0xf9898f75)
Stack: (0xee117de0 to 0xee118000)
...
[<c03619d8>] (__queue_work) from [<c0361e94>] (queue_work_on+0x40/0x4c)
[<c0361e94>] (queue_work_on) from [<bf17dd0c>] 
(hci_adv_monitors_clear+0x74/0x90 [bluetooth])
[<bf17dd0c>] (hci_adv_monitors_clear [bluetooth]) from [<bf17e138>] 
(hci_unregister_dev+0x158/0x224 [bluetooth])
[<bf17e138>] (hci_unregister_dev [bluetooth]) from [<bf1d1638>] 
(btmrvl_remove_card+0x58/0x7c [btmrvl])
[<bf1d1638>] (btmrvl_remove_card [btmrvl]) from [<c0d09698>] 
(sdio_bus_remove+0x30/0x11c)
[<c0d09698>] (sdio_bus_remove) from [<c09d534c>] 
(device_release_driver_internal+0xe8/0x1ac)
[<c09d534c>] (device_release_driver_internal) from [<c09d3e18>] 
(bus_remove_device+0xcc/0xf8)
[<c09d3e18>] (bus_remove_device) from [<c09cfa3c>] (device_del+0x15c/0x384)
[<c09cfa3c>] (device_del) from [<c0d098b8>] (sdio_remove_func+0x20/0x34)
[<c0d098b8>] (sdio_remove_func) from [<c0d075bc>] 
(mmc_sdio_remove+0x38/0x64)
[<c0d075bc>] (mmc_sdio_remove) from [<c0d08858>] (mmc_sdio_detect+0x6c/0xf8)
[<c0d08858>] (mmc_sdio_detect) from [<c0cff6f0>] (mmc_rescan+0x1d0/0x42c)
[<c0cff6f0>] (mmc_rescan) from [<c0362454>] (process_one_work+0x178/0x4ac)
[<c0362454>] (process_one_work) from [<c0362b44>] (worker_thread+0x2c/0x530)
[<c0362b44>] (worker_thread) from [<c0368610>] (kthread+0x12c/0x158)
[<c0368610>] (kthread) from [<c03001a8>] (ret_from_fork+0x14/0x2c)
Exception stack(0xee117fb0 to 0xee117ff8)
...
---[ end trace 0ec00d142e0a49cf ]---

This board uses btmrvl_sdio bluetooth driver if that helps. Reverting 
this commit in linux-next 20200629 'fixes' the issue.

I can do more tests if needed on this hardware, just let me know how can 
I help and what to do.

> ---
>   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(-)

 > ...

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

* Re: [PATCH v2 12/14] Bluetooth: Update background scan and report device based on advertisement monitors
  2020-06-29 22:30     ` Marek Szyprowski
@ 2020-06-30  6:49       ` Marcel Holtmann
  2020-06-30  7:36         ` Marek Szyprowski
  0 siblings, 1 reply; 20+ messages in thread
From: Marcel Holtmann @ 2020-06-30  6:49 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: linux-bluetooth, Linux Samsung SOC, Miao-chen Chou, Johan Hedberg

Hi Marek,

>> 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>
>> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> 
> This patch landed recently in linux-next as commit 8208f5a9d435 
> ("Bluetooth: Update background scan and report device based on 
> advertisement monitors").
> 
> It causes a regression, a kernel oops during system suspend/resume cycle 
> on Samsung Exynos5250 based Snow Chromebook:
> 
> 8<--- cut here ---
> Unable to handle kernel NULL pointer dereference at virtual address 00000000
> pgd = 86c149f5
> [00000000] *pgd=00000000
> Internal error: Oops: 5 [#1] SMP ARM
> Modules linked in: cmac cros_ec_sysfs cros_ec_lightbar cros_ec_debugfs 
> cros_ec_chardev cros_ec_keyb cros_ec_dev snd_soc_hdmi_codec cros_ec_i2c 
> cros_ec snd_soc_snow snd_soc_i2s snd_soc_idma snd_soc_s3c_dma exynosdrm 
> analogix_dp exynos_gsc v4l2_mem2mem snd_soc_max98095 snd_soc_core 
> ac97_bus snd_pcm_dmaengine snd_pcm snd_timer nxp_ptn3460 snd soundcore 
> pwm_samsung spi_s3c64xx cyapatp crc_itu_t mwifiex_sdio mwifiex 
> sha256_generic libsha256 sha256_arm btmrvl_sdio btmrvl cfg80211 
> bluetooth s5p_mfc governor_simpleondemand videobuf2_dma_contig 
> videobuf2_memops videobuf2_v4l2 ecdh_generic ecc videobuf2_common 
> videodev phy_exynos_usb2 ohci_exynos panfrost gpu_sched mc s3c2410_wdt 
> s5p_sss s5p_cec exynos_rng rtc_s3c i2c_arb_gpio_challenge
> CPU: 1 PID: 16 Comm: kworker/1:0 Not tainted 
> 5.7.0-rc7-02995-g8208f5a9d435 #8564
> Hardware name: Samsung Exynos (Flattened Device Tree)
> Workqueue: events_freezable mmc_rescan
> PC is at __queue_work+0x6c/0x4e8
> LR is at __queue_work+0x68/0x4e8
> pc : [<c03619d8>]    lr : [<c03619d4>]    psr: 60000093
> ...
> Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
> Control: 10c5387d  Table: 6be2406a  DAC: 00000051
> Process kworker/1:0 (pid: 16, stack limit = 0xf9898f75)
> Stack: (0xee117de0 to 0xee118000)
> ...
> [<c03619d8>] (__queue_work) from [<c0361e94>] (queue_work_on+0x40/0x4c)
> [<c0361e94>] (queue_work_on) from [<bf17dd0c>] 
> (hci_adv_monitors_clear+0x74/0x90 [bluetooth])
> [<bf17dd0c>] (hci_adv_monitors_clear [bluetooth]) from [<bf17e138>] 
> (hci_unregister_dev+0x158/0x224 [bluetooth])
> [<bf17e138>] (hci_unregister_dev [bluetooth]) from [<bf1d1638>] 
> (btmrvl_remove_card+0x58/0x7c [btmrvl])
> [<bf1d1638>] (btmrvl_remove_card [btmrvl]) from [<c0d09698>] 
> (sdio_bus_remove+0x30/0x11c)
> [<c0d09698>] (sdio_bus_remove) from [<c09d534c>] 
> (device_release_driver_internal+0xe8/0x1ac)
> [<c09d534c>] (device_release_driver_internal) from [<c09d3e18>] 
> (bus_remove_device+0xcc/0xf8)
> [<c09d3e18>] (bus_remove_device) from [<c09cfa3c>] (device_del+0x15c/0x384)
> [<c09cfa3c>] (device_del) from [<c0d098b8>] (sdio_remove_func+0x20/0x34)
> [<c0d098b8>] (sdio_remove_func) from [<c0d075bc>] 
> (mmc_sdio_remove+0x38/0x64)
> [<c0d075bc>] (mmc_sdio_remove) from [<c0d08858>] (mmc_sdio_detect+0x6c/0xf8)
> [<c0d08858>] (mmc_sdio_detect) from [<c0cff6f0>] (mmc_rescan+0x1d0/0x42c)
> [<c0cff6f0>] (mmc_rescan) from [<c0362454>] (process_one_work+0x178/0x4ac)
> [<c0362454>] (process_one_work) from [<c0362b44>] (worker_thread+0x2c/0x530)
> [<c0362b44>] (worker_thread) from [<c0368610>] (kthread+0x12c/0x158)
> [<c0368610>] (kthread) from [<c03001a8>] (ret_from_fork+0x14/0x2c)
> Exception stack(0xee117fb0 to 0xee117ff8)
> ...
> ---[ end trace 0ec00d142e0a49cf ]---
> 
> This board uses btmrvl_sdio bluetooth driver if that helps. Reverting 
> this commit in linux-next 20200629 'fixes' the issue.
> 
> I can do more tests if needed on this hardware, just let me know how can 
> I help and what to do.

can you check latest bluetooth-next. I think that we applied a fix for it.

Regards

Marcel


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

* Re: [PATCH v2 12/14] Bluetooth: Update background scan and report device based on advertisement monitors
  2020-06-30  6:49       ` Marcel Holtmann
@ 2020-06-30  7:36         ` Marek Szyprowski
  0 siblings, 0 replies; 20+ messages in thread
From: Marek Szyprowski @ 2020-06-30  7:36 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: linux-bluetooth, Linux Samsung SOC, Miao-chen Chou, Johan Hedberg

Hi Marcel,

On 30.06.2020 08:49, Marcel Holtmann wrote:
>>> 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>
>>> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
>> This patch landed recently in linux-next as commit 8208f5a9d435
>> ("Bluetooth: Update background scan and report device based on
>> advertisement monitors").
>>
>> It causes a regression, a kernel oops during system suspend/resume cycle
>> on Samsung Exynos5250 based Snow Chromebook:
>>
>> 8<--- cut here ---
>> Unable to handle kernel NULL pointer dereference at virtual address 00000000
>> pgd = 86c149f5
>> [00000000] *pgd=00000000
>> Internal error: Oops: 5 [#1] SMP ARM
>> Modules linked in: cmac cros_ec_sysfs cros_ec_lightbar cros_ec_debugfs
>> cros_ec_chardev cros_ec_keyb cros_ec_dev snd_soc_hdmi_codec cros_ec_i2c
>> cros_ec snd_soc_snow snd_soc_i2s snd_soc_idma snd_soc_s3c_dma exynosdrm
>> analogix_dp exynos_gsc v4l2_mem2mem snd_soc_max98095 snd_soc_core
>> ac97_bus snd_pcm_dmaengine snd_pcm snd_timer nxp_ptn3460 snd soundcore
>> pwm_samsung spi_s3c64xx cyapatp crc_itu_t mwifiex_sdio mwifiex
>> sha256_generic libsha256 sha256_arm btmrvl_sdio btmrvl cfg80211
>> bluetooth s5p_mfc governor_simpleondemand videobuf2_dma_contig
>> videobuf2_memops videobuf2_v4l2 ecdh_generic ecc videobuf2_common
>> videodev phy_exynos_usb2 ohci_exynos panfrost gpu_sched mc s3c2410_wdt
>> s5p_sss s5p_cec exynos_rng rtc_s3c i2c_arb_gpio_challenge
>> CPU: 1 PID: 16 Comm: kworker/1:0 Not tainted
>> 5.7.0-rc7-02995-g8208f5a9d435 #8564
>> Hardware name: Samsung Exynos (Flattened Device Tree)
>> Workqueue: events_freezable mmc_rescan
>> PC is at __queue_work+0x6c/0x4e8
>> LR is at __queue_work+0x68/0x4e8
>> pc : [<c03619d8>]    lr : [<c03619d4>]    psr: 60000093
>> ...
>> Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
>> Control: 10c5387d  Table: 6be2406a  DAC: 00000051
>> Process kworker/1:0 (pid: 16, stack limit = 0xf9898f75)
>> Stack: (0xee117de0 to 0xee118000)
>> ...
>> [<c03619d8>] (__queue_work) from [<c0361e94>] (queue_work_on+0x40/0x4c)
>> [<c0361e94>] (queue_work_on) from [<bf17dd0c>]
>> (hci_adv_monitors_clear+0x74/0x90 [bluetooth])
>> [<bf17dd0c>] (hci_adv_monitors_clear [bluetooth]) from [<bf17e138>]
>> (hci_unregister_dev+0x158/0x224 [bluetooth])
>> [<bf17e138>] (hci_unregister_dev [bluetooth]) from [<bf1d1638>]
>> (btmrvl_remove_card+0x58/0x7c [btmrvl])
>> [<bf1d1638>] (btmrvl_remove_card [btmrvl]) from [<c0d09698>]
>> (sdio_bus_remove+0x30/0x11c)
>> [<c0d09698>] (sdio_bus_remove) from [<c09d534c>]
>> (device_release_driver_internal+0xe8/0x1ac)
>> [<c09d534c>] (device_release_driver_internal) from [<c09d3e18>]
>> (bus_remove_device+0xcc/0xf8)
>> [<c09d3e18>] (bus_remove_device) from [<c09cfa3c>] (device_del+0x15c/0x384)
>> [<c09cfa3c>] (device_del) from [<c0d098b8>] (sdio_remove_func+0x20/0x34)
>> [<c0d098b8>] (sdio_remove_func) from [<c0d075bc>]
>> (mmc_sdio_remove+0x38/0x64)
>> [<c0d075bc>] (mmc_sdio_remove) from [<c0d08858>] (mmc_sdio_detect+0x6c/0xf8)
>> [<c0d08858>] (mmc_sdio_detect) from [<c0cff6f0>] (mmc_rescan+0x1d0/0x42c)
>> [<c0cff6f0>] (mmc_rescan) from [<c0362454>] (process_one_work+0x178/0x4ac)
>> [<c0362454>] (process_one_work) from [<c0362b44>] (worker_thread+0x2c/0x530)
>> [<c0362b44>] (worker_thread) from [<c0368610>] (kthread+0x12c/0x158)
>> [<c0368610>] (kthread) from [<c03001a8>] (ret_from_fork+0x14/0x2c)
>> Exception stack(0xee117fb0 to 0xee117ff8)
>> ...
>> ---[ end trace 0ec00d142e0a49cf ]---
>>
>> This board uses btmrvl_sdio bluetooth driver if that helps. Reverting
>> this commit in linux-next 20200629 'fixes' the issue.
>>
>> I can do more tests if needed on this hardware, just let me know how can
>> I help and what to do.
> can you check latest bluetooth-next. I think that we applied a fix for it.

Indeed. Commit f2790f025a0e ("Bluetooth: fix kernel null pointer 
dereference error on suspend") fixed the issue.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

end of thread, other threads:[~2020-06-30  7:36 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-17 14:39 [PATCH v2 00/14] Combination of pending patches Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 01/14] Bluetooth: mgmt: Add commands for runtime configuration Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 02/14] Bluetooth: Add bdaddr_list_with_flags for classic whitelist Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 03/14] Bluetooth: Replace wakeable list with flag Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 04/14] Bluetooth: Replace wakeable in hci_conn_params Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 05/14] Bluetooth: Add get/set device flags mgmt op Marcel Holtmann
2020-06-17 18:03   ` Abhishek Pandit-Subedi
2020-06-17 14:39 ` [PATCH v2 06/14] Bluetooth: Add definitions for advertisement monitor features Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 07/14] Bluetooth: Add handler of MGMT_OP_READ_ADV_MONITOR_FEATURES Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 08/14] Bluetooth: Add handler of MGMT_OP_ADD_ADV_PATTERNS_MONITOR Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 09/14] Bluetooth: Add handler of MGMT_OP_REMOVE_ADV_MONITOR Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 10/14] Bluetooth: Notify adv monitor added event Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 11/14] Bluetooth: Notify adv monitor removed event Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 12/14] Bluetooth: Update background scan and report device based on advertisement monitors Marcel Holtmann
     [not found]   ` <CGME20200629223028eucas1p27b9482456072d7864f7505379885a0b4@eucas1p2.samsung.com>
2020-06-29 22:30     ` Marek Szyprowski
2020-06-30  6:49       ` Marcel Holtmann
2020-06-30  7:36         ` Marek Szyprowski
2020-06-17 14:39 ` [PATCH v2 13/14] Bluetooth: Terminate the link if pairing is cancelled Marcel Holtmann
2020-06-17 14:39 ` [PATCH v2 14/14] Bluetooth: mgmt: Use command complete on success for set system config Marcel Holtmann
2020-06-18 10:17 ` [PATCH v2 00/14] Combination of pending patches Johan Hedberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).