Linux-Bluetooth Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH v5 1/8] Bluetooth: Translate additional address type correctly
@ 2020-07-23 12:38 Sathish Narasimman
  2020-07-23 12:38 ` [PATCH v5 2/8] Bluetooth: Configure controller address resolution if available Sathish Narasimman
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-23 12:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcel Holtmann, Sathish Narsimman

From: Marcel Holtmann <marcel@holtmann.org>

When using controller based address resolution, then the new address
types 0x02 and 0x03 are used. These types need to be converted back into
either public address or random address types.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sathish Narsimman <sathish.narasimman@intel.com>
---
 include/net/bluetooth/hci.h | 6 ++++--
 net/bluetooth/hci_core.c    | 9 +++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 1f18f71363e9..abab8b5981a7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -2268,8 +2268,10 @@ struct hci_ev_le_conn_complete {
 #define LE_EXT_ADV_SCAN_RSP		0x0008
 #define LE_EXT_ADV_LEGACY_PDU		0x0010
 
-#define ADDR_LE_DEV_PUBLIC	0x00
-#define ADDR_LE_DEV_RANDOM	0x01
+#define ADDR_LE_DEV_PUBLIC		0x00
+#define ADDR_LE_DEV_RANDOM		0x01
+#define ADDR_LE_DEV_PUBLIC_RESOLVED	0x02
+#define ADDR_LE_DEV_RANDOM_RESOLVED	0x03
 
 #define HCI_EV_LE_ADVERTISING_REPORT	0x02
 struct hci_ev_le_advertising_info {
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6509f785dd14..4af208b82138 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3290,6 +3290,15 @@ struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
 {
 	struct hci_conn_params *param;
 
+	switch (addr_type) {
+	case ADDR_LE_DEV_PUBLIC_RESOLVED:
+		addr_type = ADDR_LE_DEV_PUBLIC;
+		break;
+	case ADDR_LE_DEV_RANDOM_RESOLVED:
+		addr_type = ADDR_LE_DEV_RANDOM;
+		break;
+	}
+
 	list_for_each_entry(param, list, action) {
 		if (bacmp(&param->addr, addr) == 0 &&
 		    param->addr_type == addr_type)
-- 
2.17.1


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

* [PATCH v5 2/8] Bluetooth: Configure controller address resolution if available
  2020-07-23 12:38 [PATCH v5 1/8] Bluetooth: Translate additional address type correctly Sathish Narasimman
@ 2020-07-23 12:38 ` Sathish Narasimman
  2020-07-23 12:38 ` [PATCH v5 3/8] Bluetooth: Update resolving list when updating whitelist Sathish Narasimman
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-23 12:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcel Holtmann, Sathish Narsimman

From: Marcel Holtmann <marcel@holtmann.org>

When the LL Privacy support is available, then as part of enabling or
disabling passive background scanning, it is required to set up the
controller based address resolution as well.

Since only passive background scanning is utilizing the whitelist, the
address resolution is now bound to the whitelist and passive background
scanning. All other resolution can be easily done by the host stack.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sathish Narsimman <sathish.narasimman@intel.com>
---
 include/net/bluetooth/hci_core.h |  3 +++
 net/bluetooth/hci_request.c      | 26 +++++++++++++++++++++++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index bee1b4778ccc..8caac20556b4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1359,6 +1359,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
 #define scan_coded(dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_CODED) || \
 			 ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_CODED))
 
+/* Use LL Privacy based address resolution if supported */
+#define use_ll_privacy(dev) ((dev)->le_features[0] & HCI_LE_LL_PRIVACY)
+
 /* Use ext scanning if set ext scan param and ext scan enable is supported */
 #define use_ext_scan(dev) (((dev)->commands[37] & 0x20) && \
 			   ((dev)->commands[37] & 0x40))
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 7c0c2fda04ad..7d0ba53ffed0 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -675,6 +675,12 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
 		cp.enable = LE_SCAN_DISABLE;
 		hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
 	}
+
+	if (use_ll_privacy(hdev) &&
+	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) {
+		__u8 enable = 0x00;
+		hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
+	}
 }
 
 static void del_from_white_list(struct hci_request *req, bdaddr_t *bdaddr,
@@ -816,7 +822,8 @@ static bool scan_use_rpa(struct hci_dev *hdev)
 }
 
 static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
-			       u16 window, u8 own_addr_type, u8 filter_policy)
+			       u16 window, u8 own_addr_type, u8 filter_policy,
+			       bool addr_resolv)
 {
 	struct hci_dev *hdev = req->hdev;
 
@@ -825,6 +832,11 @@ static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
 		return;
 	}
 
+	if (use_ll_privacy(hdev) && addr_resolv) {
+		u8 enable = 0x01;
+		hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
+	}
+
 	/* Use ext scanning if set ext scan param and ext scan enable is
 	 * supported
 	 */
@@ -898,12 +910,18 @@ static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
 	}
 }
 
+/* Ensure to call hci_req_add_le_scan_disable() first to disable the
+ * controller based address resolution to be able to reconfigure
+ * resolving list.
+ */
 void hci_req_add_le_passive_scan(struct hci_request *req)
 {
 	struct hci_dev *hdev = req->hdev;
 	u8 own_addr_type;
 	u8 filter_policy;
 	u16 window, interval;
+	/* Background scanning should run with address resolution */
+	bool addr_resolv = true;
 
 	if (hdev->scanning_paused) {
 		bt_dev_dbg(hdev, "Scanning is paused for suspend");
@@ -949,7 +967,7 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
 
 	bt_dev_dbg(hdev, "LE passive scan with whitelist = %d", filter_policy);
 	hci_req_start_scan(req, LE_SCAN_PASSIVE, interval, window,
-			   own_addr_type, filter_policy);
+			   own_addr_type, filter_policy, addr_resolv);
 }
 
 static u8 get_adv_instance_scan_rsp_len(struct hci_dev *hdev, u8 instance)
@@ -2789,6 +2807,8 @@ static int active_scan(struct hci_request *req, unsigned long opt)
 	u8 own_addr_type;
 	/* White list is not used for discovery */
 	u8 filter_policy = 0x00;
+	/* Discovery doesn't require controller address resolution */
+	bool addr_resolv = false;
 	int err;
 
 	BT_DBG("%s", hdev->name);
@@ -2811,7 +2831,7 @@ static int active_scan(struct hci_request *req, unsigned long opt)
 
 	hci_req_start_scan(req, LE_SCAN_ACTIVE, interval,
 			   hdev->le_scan_window_discovery, own_addr_type,
-			   filter_policy);
+			   filter_policy, addr_resolv);
 	return 0;
 }
 
-- 
2.17.1


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

* [PATCH v5 3/8] Bluetooth: Update resolving list when updating whitelist
  2020-07-23 12:38 [PATCH v5 1/8] Bluetooth: Translate additional address type correctly Sathish Narasimman
  2020-07-23 12:38 ` [PATCH v5 2/8] Bluetooth: Configure controller address resolution if available Sathish Narasimman
@ 2020-07-23 12:38 ` Sathish Narasimman
  2020-07-23 12:38 ` [PATCH v5 4/8] Bluetooth: Translate additional address type during le_conn Sathish Narasimman
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-23 12:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Marcel Holtmann, Sathish Narsimman

From: Marcel Holtmann <marcel@holtmann.org>

When the whitelist is updated, then also update the entries of the
resolving list for devices where IRKs are available.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Sathish Narsimman <sathish.narasimman@intel.com>
---
 net/bluetooth/hci_request.c | 41 +++++++++++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 7d0ba53ffed0..85de1f356610 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -694,6 +694,21 @@ static void del_from_white_list(struct hci_request *req, bdaddr_t *bdaddr,
 	bt_dev_dbg(req->hdev, "Remove %pMR (0x%x) from whitelist", &cp.bdaddr,
 		   cp.bdaddr_type);
 	hci_req_add(req, HCI_OP_LE_DEL_FROM_WHITE_LIST, sizeof(cp), &cp);
+
+	if (use_ll_privacy(req->hdev)) {
+		struct smp_irk *irk;
+
+		irk = hci_find_irk_by_addr(req->hdev, bdaddr, bdaddr_type);
+		if (irk) {
+			struct hci_cp_le_del_from_resolv_list cp;
+
+			cp.bdaddr_type = bdaddr_type;
+			bacpy(&cp.bdaddr, bdaddr);
+
+			hci_req_add(req, HCI_OP_LE_DEL_FROM_RESOLV_LIST,
+				    sizeof(cp), &cp);
+		}
+	}
 }
 
 /* Adds connection to white list if needed. On error, returns -1. */
@@ -714,7 +729,7 @@ static int add_to_white_list(struct hci_request *req,
 		return -1;
 
 	/* White list can not be used with RPAs */
-	if (!allow_rpa &&
+	if (!allow_rpa && !use_ll_privacy(hdev) &&
 	    hci_find_irk_by_addr(hdev, &params->addr, params->addr_type)) {
 		return -1;
 	}
@@ -732,6 +747,28 @@ static int add_to_white_list(struct hci_request *req,
 		   cp.bdaddr_type);
 	hci_req_add(req, HCI_OP_LE_ADD_TO_WHITE_LIST, sizeof(cp), &cp);
 
+	if (use_ll_privacy(hdev)) {
+		struct smp_irk *irk;
+
+		irk = hci_find_irk_by_addr(hdev, &params->addr,
+					   params->addr_type);
+		if (irk) {
+			struct hci_cp_le_add_to_resolv_list cp;
+
+			cp.bdaddr_type = params->addr_type;
+			bacpy(&cp.bdaddr, &params->addr);
+			memcpy(cp.peer_irk, irk->val, 16);
+
+			if (hci_dev_test_flag(hdev, HCI_PRIVACY))
+				memcpy(cp.local_irk, hdev->irk, 16);
+			else
+				memset(cp.local_irk, 0, 16);
+
+			hci_req_add(req, HCI_OP_LE_ADD_TO_RESOLV_LIST,
+				    sizeof(cp), &cp);
+		}
+	}
+
 	return 0;
 }
 
@@ -772,7 +809,7 @@ static u8 update_white_list(struct hci_request *req)
 		}
 
 		/* White list can not be used with RPAs */
-		if (!allow_rpa &&
+		if (!allow_rpa && !use_ll_privacy(hdev) &&
 		    hci_find_irk_by_addr(hdev, &b->bdaddr, b->bdaddr_type)) {
 			return 0x00;
 		}
-- 
2.17.1


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

* [PATCH v5 4/8] Bluetooth: Translate additional address type during le_conn
  2020-07-23 12:38 [PATCH v5 1/8] Bluetooth: Translate additional address type correctly Sathish Narasimman
  2020-07-23 12:38 ` [PATCH v5 2/8] Bluetooth: Configure controller address resolution if available Sathish Narasimman
  2020-07-23 12:38 ` [PATCH v5 3/8] Bluetooth: Update resolving list when updating whitelist Sathish Narasimman
@ 2020-07-23 12:38 ` Sathish Narasimman
  2020-07-23 12:39 ` [PATCH v5 5/8] Bluetooth: Let controller creates RPA during le create conn Sathish Narasimman
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-23 12:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sathish Narasimman

When using controller based address resolution, then the new address
types 0x02 and 0x03 are used. These types need to be converted back into
either public address or random address types.

This patch is specially during LE_CREATE_CONN if using own_add_type as 0x02
or 0x03.

Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
---
 net/bluetooth/hci_event.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 61f8c4d12028..6388fb55b4d2 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2296,6 +2296,22 @@ static void cs_le_create_conn(struct hci_dev *hdev, bdaddr_t *peer_addr,
 	if (!conn)
 		return;
 
+	/* When using controller based address resolution, then the new
+	 * address types 0x02 and 0x03 are used. These types need to be
+	 * converted back into either public address or random address type
+	 */
+	if (use_ll_privacy(hdev) &&
+	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) {
+		switch (own_address_type) {
+		case ADDR_LE_DEV_PUBLIC_RESOLVED:
+			own_address_type = ADDR_LE_DEV_PUBLIC;
+			break;
+		case ADDR_LE_DEV_RANDOM_RESOLVED:
+			own_address_type = ADDR_LE_DEV_RANDOM;
+			break;
+		}
+	}
+
 	/* Store the initiator and responder address information which
 	 * is needed for SMP. These values will not change during the
 	 * lifetime of the connection.
-- 
2.17.1


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

* [PATCH v5 5/8] Bluetooth: Let controller creates RPA during le create conn
  2020-07-23 12:38 [PATCH v5 1/8] Bluetooth: Translate additional address type correctly Sathish Narasimman
                   ` (2 preceding siblings ...)
  2020-07-23 12:38 ` [PATCH v5 4/8] Bluetooth: Translate additional address type during le_conn Sathish Narasimman
@ 2020-07-23 12:39 ` Sathish Narasimman
  2020-07-23 12:39 ` [PATCH v5 6/8] Bluetooth: Enable/Disable address resolution " Sathish Narasimman
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-23 12:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sathish Narasimman

When address resolution is enabled and set_privacy is enabled let's
use own address type as 0x03

Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
---
 net/bluetooth/hci_request.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 85de1f356610..e48f0945a417 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -2242,7 +2242,13 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
 	if (use_rpa) {
 		int to;
 
-		*own_addr_type = ADDR_LE_DEV_RANDOM;
+		/* If Controller supports LL Privacy use own address type is
+		 * 0x03
+		 */
+		if (use_ll_privacy(hdev))
+			*own_addr_type = ADDR_LE_DEV_RANDOM_RESOLVED;
+		else
+			*own_addr_type = ADDR_LE_DEV_RANDOM;
 
 		if (!hci_dev_test_and_clear_flag(hdev, HCI_RPA_EXPIRED) &&
 		    !bacmp(&hdev->random_addr, &hdev->rpa))
-- 
2.17.1


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

* [PATCH v5 6/8] Bluetooth: Enable/Disable address resolution during le create conn
  2020-07-23 12:38 [PATCH v5 1/8] Bluetooth: Translate additional address type correctly Sathish Narasimman
                   ` (3 preceding siblings ...)
  2020-07-23 12:39 ` [PATCH v5 5/8] Bluetooth: Let controller creates RPA during le create conn Sathish Narasimman
@ 2020-07-23 12:39 ` Sathish Narasimman
  2020-07-23 12:39 ` [PATCH v5 7/8] Bluetooth: Enable RPA Timeout Sathish Narasimman
  2020-07-23 12:39 ` [PATCH v5 8/8] Bluetooth: Enable controller RPA resolution using Experimental feature Sathish Narasimman
  6 siblings, 0 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-23 12:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sathish Narasimman

In this patch if le_create_conn process is started restrict to
disable address resolution and same is disabled during
le_enh_connection_complete

Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
---
 net/bluetooth/hci_conn.c    |  7 +++++-
 net/bluetooth/hci_event.c   |  4 ++++
 net/bluetooth/hci_request.c | 45 ++++++++++++++++++++++++++++---------
 net/bluetooth/hci_request.h |  3 ++-
 net/bluetooth/mgmt.c        |  2 +-
 5 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index be67361ff2f0..9832f8445d43 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1003,6 +1003,11 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 	struct hci_request req;
 	int err;
 
+	/* This ensures that during disable le_scan address resolution
+	 * will not be disabled if it is followed by le_create_conn
+	 */
+	bool rpa_le_conn = true;
+
 	/* Let's make sure that le is enabled.*/
 	if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
 		if (lmp_le_capable(hdev))
@@ -1103,7 +1108,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 	 * state.
 	 */
 	if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
-		hci_req_add_le_scan_disable(&req);
+		hci_req_add_le_scan_disable(&req, rpa_le_conn);
 		hci_dev_set_flag(hdev, HCI_LE_SCAN_INTERRUPTED);
 	}
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6388fb55b4d2..628831b15c0a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -5228,6 +5228,10 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
 			     le16_to_cpu(ev->interval),
 			     le16_to_cpu(ev->latency),
 			     le16_to_cpu(ev->supervision_timeout));
+
+	if (use_ll_privacy(hdev) &&
+	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
+		hci_req_disable_address_resolution(hdev);
 }
 
 static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index e48f0945a417..70e077cc7dfa 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -428,7 +428,7 @@ static void __hci_update_background_scan(struct hci_request *req)
 		if (!hci_dev_test_flag(hdev, HCI_LE_SCAN))
 			return;
 
-		hci_req_add_le_scan_disable(req);
+		hci_req_add_le_scan_disable(req, false);
 
 		BT_DBG("%s stopping background scanning", hdev->name);
 	} else {
@@ -447,7 +447,7 @@ static void __hci_update_background_scan(struct hci_request *req)
 		 * don't miss any advertising (due to duplicates filter).
 		 */
 		if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
-			hci_req_add_le_scan_disable(req);
+			hci_req_add_le_scan_disable(req, false);
 
 		hci_req_add_le_passive_scan(req);
 
@@ -652,7 +652,7 @@ void __hci_req_update_eir(struct hci_request *req)
 	hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
 }
 
-void hci_req_add_le_scan_disable(struct hci_request *req)
+void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn)
 {
 	struct hci_dev *hdev = req->hdev;
 
@@ -676,8 +676,9 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
 		hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
 	}
 
+	/* Disable address resolution */
 	if (use_ll_privacy(hdev) &&
-	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION)) {
+	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) && !rpa_le_conn) {
 		__u8 enable = 0x00;
 		hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
 	}
@@ -1072,7 +1073,7 @@ static void hci_req_config_le_suspend_scan(struct hci_request *req)
 {
 	/* Before changing params disable scan if enabled */
 	if (hci_dev_test_flag(req->hdev, HCI_LE_SCAN))
-		hci_req_add_le_scan_disable(req);
+		hci_req_add_le_scan_disable(req, false);
 
 	/* Configure params and enable scanning */
 	hci_req_add_le_passive_scan(req);
@@ -1140,7 +1141,7 @@ void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next)
 
 		/* Disable LE passive scan if enabled */
 		if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
-			hci_req_add_le_scan_disable(&req);
+			hci_req_add_le_scan_disable(&req, false);
 
 		/* Mark task needing completion */
 		set_bit(SUSPEND_SCAN_DISABLE, hdev->suspend_tasks);
@@ -1696,6 +1697,28 @@ int hci_req_update_adv_data(struct hci_dev *hdev, u8 instance)
 	return hci_req_run(&req, NULL);
 }
 
+static void enable_addr_resolution_complete(struct hci_dev *hdev, u8 status,
+					    u16 opcode)
+{
+	BT_DBG("%s status %u", hdev->name, status);
+}
+
+void hci_req_disable_address_resolution(struct hci_dev *hdev)
+{
+	struct hci_request req;
+	__u8 enable = 0x00;
+
+	if (!use_ll_privacy(hdev) &&
+	    !hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
+		return;
+
+	hci_req_init(&req, hdev);
+
+	hci_req_add(&req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
+
+	hci_req_run(&req, enable_addr_resolution_complete);
+}
+
 static void adv_enable_complete(struct hci_dev *hdev, u8 status, u16 opcode)
 {
 	BT_DBG("%s status %u", hdev->name, status);
@@ -2667,7 +2690,7 @@ static void bg_scan_update(struct work_struct *work)
 
 static int le_scan_disable(struct hci_request *req, unsigned long opt)
 {
-	hci_req_add_le_scan_disable(req);
+	hci_req_add_le_scan_disable(req, false);
 	return 0;
 }
 
@@ -2770,7 +2793,7 @@ static int le_scan_restart(struct hci_request *req, unsigned long opt)
 		return 0;
 	}
 
-	hci_req_add_le_scan_disable(req);
+	hci_req_add_le_scan_disable(req, false);
 
 	if (use_ext_scan(hdev)) {
 		struct hci_cp_le_set_ext_scan_enable ext_enable_cp;
@@ -2861,7 +2884,7 @@ static int active_scan(struct hci_request *req, unsigned long opt)
 	 * discovery scanning parameters.
 	 */
 	if (hci_dev_test_flag(hdev, HCI_LE_SCAN))
-		hci_req_add_le_scan_disable(req);
+		hci_req_add_le_scan_disable(req, false);
 
 	/* All active scans will be done with either a resolvable private
 	 * address (when privacy feature has been enabled) or non-resolvable
@@ -2976,14 +2999,14 @@ bool hci_req_stop_discovery(struct hci_request *req)
 
 		if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
 			cancel_delayed_work(&hdev->le_scan_disable);
-			hci_req_add_le_scan_disable(req);
+			hci_req_add_le_scan_disable(req, false);
 		}
 
 		ret = true;
 	} else {
 		/* Passive scanning */
 		if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
-			hci_req_add_le_scan_disable(req);
+			hci_req_add_le_scan_disable(req, false);
 			ret = true;
 		}
 	}
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h
index bbe892ab078a..6a12e84c66c4 100644
--- a/net/bluetooth/hci_request.h
+++ b/net/bluetooth/hci_request.h
@@ -65,11 +65,12 @@ void __hci_req_write_fast_connectable(struct hci_request *req, bool enable);
 void __hci_req_update_name(struct hci_request *req);
 void __hci_req_update_eir(struct hci_request *req);
 
-void hci_req_add_le_scan_disable(struct hci_request *req);
+void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn);
 void hci_req_add_le_passive_scan(struct hci_request *req);
 
 void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next);
 
+void hci_req_disable_address_resolution(struct hci_dev *hdev);
 void hci_req_reenable_advertising(struct hci_dev *hdev);
 void __hci_req_enable_advertising(struct hci_request *req);
 void __hci_req_disable_advertising(struct hci_request *req);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f45105d2de77..47bcfe2fb14c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -5226,7 +5226,7 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
 
 		hci_req_init(&req, hdev);
 
-		hci_req_add_le_scan_disable(&req);
+		hci_req_add_le_scan_disable(&req, false);
 		hci_req_add_le_passive_scan(&req);
 
 		hci_req_run(&req, NULL);
-- 
2.17.1


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

* [PATCH v5 7/8] Bluetooth: Enable RPA Timeout
  2020-07-23 12:38 [PATCH v5 1/8] Bluetooth: Translate additional address type correctly Sathish Narasimman
                   ` (4 preceding siblings ...)
  2020-07-23 12:39 ` [PATCH v5 6/8] Bluetooth: Enable/Disable address resolution " Sathish Narasimman
@ 2020-07-23 12:39 ` Sathish Narasimman
  2020-07-23 12:39 ` [PATCH v5 8/8] Bluetooth: Enable controller RPA resolution using Experimental feature Sathish Narasimman
  6 siblings, 0 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-23 12:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sathish Narasimman

Enable RPA timeout during bluetooth initialization.
The RPA timeout value is used from hdev, which initialized from
debug_fs

Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
---
 include/net/bluetooth/hci.h | 2 ++
 net/bluetooth/hci_core.c    | 8 ++++++++
 2 files changed, 10 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index abab8b5981a7..4ff2fc4498f3 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1637,6 +1637,8 @@ struct hci_rp_le_read_resolv_list_size {
 
 #define HCI_OP_LE_SET_ADDR_RESOLV_ENABLE 0x202d
 
+#define HCI_OP_LE_SET_RPA_TIMEOUT	0x202e
+
 #define HCI_OP_LE_READ_MAX_DATA_LEN	0x202f
 struct hci_rp_le_read_max_data_len {
 	__u8	status;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4af208b82138..2030536cc5d8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -762,6 +762,14 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)
 			hci_req_add(req, HCI_OP_LE_CLEAR_RESOLV_LIST, 0, NULL);
 		}
 
+		if (hdev->commands[35] & 0x40) {
+			__le16 rpa_timeout = cpu_to_le16(hdev->rpa_timeout);
+
+			/* Set RPA timeout */
+			hci_req_add(req, HCI_OP_LE_SET_RPA_TIMEOUT, 2,
+				    &rpa_timeout);
+		}
+
 		if (hdev->le_features[0] & HCI_LE_DATA_LEN_EXT) {
 			/* Read LE Maximum Data Length */
 			hci_req_add(req, HCI_OP_LE_READ_MAX_DATA_LEN, 0, NULL);
-- 
2.17.1


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

* [PATCH v5 8/8] Bluetooth: Enable controller RPA resolution using Experimental feature
  2020-07-23 12:38 [PATCH v5 1/8] Bluetooth: Translate additional address type correctly Sathish Narasimman
                   ` (5 preceding siblings ...)
  2020-07-23 12:39 ` [PATCH v5 7/8] Bluetooth: Enable RPA Timeout Sathish Narasimman
@ 2020-07-23 12:39 ` Sathish Narasimman
  2020-07-27 11:46   ` Sathish Narasimman
  2020-07-30  9:12   ` Marcel Holtmann
  6 siblings, 2 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-23 12:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sathish Narasimman

This patch adds support to enable the use of RPA Address resolution
using expermental feature mgmt command.

Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
---
 include/net/bluetooth/hci.h |   1 +
 net/bluetooth/hci_event.c   |   1 +
 net/bluetooth/hci_request.c |   7 ++-
 net/bluetooth/mgmt.c        | 112 ++++++++++++++++++++++++++++++++++++
 4 files changed, 120 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 4ff2fc4498f3..55205d805c22 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -307,6 +307,7 @@ enum {
 	HCI_FORCE_BREDR_SMP,
 	HCI_FORCE_STATIC_ADDR,
 	HCI_LL_RPA_RESOLUTION,
+	HCI_ENABLE_LL_PRIVACY,
 	HCI_CMD_PENDING,
 	HCI_FORCE_NO_MITM,
 
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 628831b15c0a..33d8458fdd4a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -5230,6 +5230,7 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
 			     le16_to_cpu(ev->supervision_timeout));
 
 	if (use_ll_privacy(hdev) &&
+	    hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
 	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
 		hci_req_disable_address_resolution(hdev);
 }
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 70e077cc7dfa..435400a43a78 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -678,8 +678,10 @@ void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn)
 
 	/* Disable address resolution */
 	if (use_ll_privacy(hdev) &&
+	    hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
 	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) && !rpa_le_conn) {
 		__u8 enable = 0x00;
+
 		hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
 	}
 }
@@ -870,8 +872,11 @@ static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
 		return;
 	}
 
-	if (use_ll_privacy(hdev) && addr_resolv) {
+	if (use_ll_privacy(hdev) &&
+	    hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
+	    addr_resolv) {
 		u8 enable = 0x01;
+
 		hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
 	}
 
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 47bcfe2fb14c..adde92cf015d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3759,6 +3759,12 @@ static const u8 simult_central_periph_uuid[16] = {
 	0x96, 0x46, 0xc0, 0x42, 0xb5, 0x10, 0x1b, 0x67,
 };
 
+/* 15c0a148-c273-11ea-b3de-0242ac130004 */
+static const u8 rpa_resolution_uuid[16] = {
+	0x04, 0x00, 0x13, 0xac, 0x42, 0x02, 0xde, 0xb3,
+	0xea, 0x11, 0x73, 0xc2, 0x48, 0xa1, 0xc0, 0x15,
+};
+
 static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
 				  void *data, u16 data_len)
 {
@@ -3795,6 +3801,21 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
 		idx++;
 	}
 
+	if (use_ll_privacy(hdev)) {
+		if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) {
+			flags = BIT(0);
+			if (!hci_dev_test_flag(hdev, HCI_ADVERTISING))
+				flags |= BIT(1);
+		} else
+			flags = 0;
+
+		memcpy(rp->features[idx].uuid, rpa_resolution_uuid, 16);
+		rp->features[idx].flags = cpu_to_le32(flags);
+		idx++;
+
+		new_settings(hdev, sk);
+	}
+
 	rp->feature_count = cpu_to_le16(idx);
 
 	/* After reading the experimental features information, enable
@@ -3807,6 +3828,27 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
 				 0, rp, sizeof(*rp) + (20 * idx));
 }
 
+static int exp_ll_privacy_feature_changed(bool enabled, struct sock *skip)
+{
+	struct mgmt_ev_exp_feature_changed ev;
+	u32 flags;
+
+	memset(&ev, 0, sizeof(ev));
+	memcpy(ev.uuid, rpa_resolution_uuid, 16);
+
+	if (enabled)
+		flags = 0x03;
+	else
+		flags = 0;
+
+	ev.flags = cpu_to_le32(flags);
+
+	return mgmt_limited_event(MGMT_EV_EXP_FEATURE_CHANGED, NULL,
+				  &ev, sizeof(ev),
+				  HCI_MGMT_EXP_FEATURE_EVENTS, skip);
+
+}
+
 #ifdef CONFIG_BT_FEATURE_DEBUG
 static int exp_debug_feature_changed(bool enabled, struct sock *skip)
 {
@@ -3845,6 +3887,18 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
 		}
 #endif
 
+		if (use_ll_privacy(hdev)) {
+			bool changed;
+
+			changed = hci_dev_test_flag(hdev,
+						    HCI_ENABLE_LL_PRIVACY);
+
+			hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY);
+
+			if (changed)
+				exp_ll_privacy_feature_changed(false, sk);
+		}
+
 		hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS);
 
 		return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE,
@@ -3895,6 +3949,64 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
 	}
 #endif
 
+	if (!memcmp(cp->uuid, rpa_resolution_uuid, 16)) {
+		bool val, changed;
+		int err;
+		u32 flags;
+
+		/* Parameters are limited to a single octet */
+		if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1)
+			return mgmt_cmd_status(sk, MGMT_INDEX_NONE,
+					       MGMT_OP_SET_EXP_FEATURE,
+					       MGMT_STATUS_INVALID_PARAMS);
+
+		/* Only boolean on/off is supported */
+		if (cp->param[0] != 0x00 && cp->param[0] != 0x01)
+			return mgmt_cmd_status(sk, MGMT_INDEX_NONE,
+					       MGMT_OP_SET_EXP_FEATURE,
+					       MGMT_STATUS_INVALID_PARAMS);
+
+		val = !!cp->param[0];
+
+		if (val) {
+			changed = !hci_dev_test_flag(hdev,
+						     HCI_ENABLE_LL_PRIVACY);
+
+			hci_dev_set_flag(hdev, HCI_ENABLE_LL_PRIVACY);
+
+			/* Enable LL privacy */
+			flags = BIT(0);
+			/* Disable HCI_ADVERTISING flag */
+			flags |= BIT(1);
+
+			hci_dev_clear_flag(hdev, HCI_ADVERTISING);
+
+		} else {
+			changed = hci_dev_test_flag(hdev,
+						    HCI_ENABLE_LL_PRIVACY);
+			hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY);
+
+			flags = 0;
+		}
+
+		memcpy(rp.uuid, rpa_resolution_uuid, 16);
+
+		rp.flags = cpu_to_le32(flags);
+
+		hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS);
+
+		err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE,
+					MGMT_OP_SET_EXP_FEATURE, 0,
+					&rp, sizeof(rp));
+
+		if (changed) {
+			exp_ll_privacy_feature_changed(val, sk);
+			new_settings(hdev, sk);
+		}
+
+		return err;
+	}
+
 	return mgmt_cmd_status(sk, hdev ? hdev->id : MGMT_INDEX_NONE,
 			       MGMT_OP_SET_EXP_FEATURE,
 			       MGMT_STATUS_NOT_SUPPORTED);
-- 
2.17.1


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

* Re: [PATCH v5 8/8] Bluetooth: Enable controller RPA resolution using Experimental feature
  2020-07-23 12:39 ` [PATCH v5 8/8] Bluetooth: Enable controller RPA resolution using Experimental feature Sathish Narasimman
@ 2020-07-27 11:46   ` Sathish Narasimman
  2020-07-30  9:12   ` Marcel Holtmann
  1 sibling, 0 replies; 10+ messages in thread
From: Sathish Narasimman @ 2020-07-27 11:46 UTC (permalink / raw)
  To: Bluez mailing list, Chethan T N, Marcel Holtmann; +Cc: Sathish Narasimman

Hi

gentle reminder

On Thu, Jul 23, 2020 at 6:05 PM Sathish Narasimman <nsathish41@gmail.com> wrote:
>
> This patch adds support to enable the use of RPA Address resolution
> using expermental feature mgmt command.
>
> Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
> ---
>  include/net/bluetooth/hci.h |   1 +
>  net/bluetooth/hci_event.c   |   1 +
>  net/bluetooth/hci_request.c |   7 ++-
>  net/bluetooth/mgmt.c        | 112 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 120 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index 4ff2fc4498f3..55205d805c22 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -307,6 +307,7 @@ enum {
>         HCI_FORCE_BREDR_SMP,
>         HCI_FORCE_STATIC_ADDR,
>         HCI_LL_RPA_RESOLUTION,
> +       HCI_ENABLE_LL_PRIVACY,
>         HCI_CMD_PENDING,
>         HCI_FORCE_NO_MITM,
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 628831b15c0a..33d8458fdd4a 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -5230,6 +5230,7 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
>                              le16_to_cpu(ev->supervision_timeout));
>
>         if (use_ll_privacy(hdev) &&
> +           hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
>             hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
>                 hci_req_disable_address_resolution(hdev);
>  }
> diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
> index 70e077cc7dfa..435400a43a78 100644
> --- a/net/bluetooth/hci_request.c
> +++ b/net/bluetooth/hci_request.c
> @@ -678,8 +678,10 @@ void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn)
>
>         /* Disable address resolution */
>         if (use_ll_privacy(hdev) &&
> +           hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
>             hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) && !rpa_le_conn) {
>                 __u8 enable = 0x00;
> +
>                 hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
>         }
>  }
> @@ -870,8 +872,11 @@ static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
>                 return;
>         }
>
> -       if (use_ll_privacy(hdev) && addr_resolv) {
> +       if (use_ll_privacy(hdev) &&
> +           hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
> +           addr_resolv) {
>                 u8 enable = 0x01;
> +
>                 hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
>         }
>
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index 47bcfe2fb14c..adde92cf015d 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -3759,6 +3759,12 @@ static const u8 simult_central_periph_uuid[16] = {
>         0x96, 0x46, 0xc0, 0x42, 0xb5, 0x10, 0x1b, 0x67,
>  };
>
> +/* 15c0a148-c273-11ea-b3de-0242ac130004 */
> +static const u8 rpa_resolution_uuid[16] = {
> +       0x04, 0x00, 0x13, 0xac, 0x42, 0x02, 0xde, 0xb3,
> +       0xea, 0x11, 0x73, 0xc2, 0x48, 0xa1, 0xc0, 0x15,
> +};
> +
>  static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
>                                   void *data, u16 data_len)
>  {
> @@ -3795,6 +3801,21 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
>                 idx++;
>         }
>
> +       if (use_ll_privacy(hdev)) {
> +               if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) {
> +                       flags = BIT(0);
> +                       if (!hci_dev_test_flag(hdev, HCI_ADVERTISING))
> +                               flags |= BIT(1);
> +               } else
> +                       flags = 0;
> +
> +               memcpy(rp->features[idx].uuid, rpa_resolution_uuid, 16);
> +               rp->features[idx].flags = cpu_to_le32(flags);
> +               idx++;
> +
> +               new_settings(hdev, sk);
> +       }
> +
>         rp->feature_count = cpu_to_le16(idx);
>
>         /* After reading the experimental features information, enable
> @@ -3807,6 +3828,27 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
>                                  0, rp, sizeof(*rp) + (20 * idx));
>  }
>
> +static int exp_ll_privacy_feature_changed(bool enabled, struct sock *skip)
> +{
> +       struct mgmt_ev_exp_feature_changed ev;
> +       u32 flags;
> +
> +       memset(&ev, 0, sizeof(ev));
> +       memcpy(ev.uuid, rpa_resolution_uuid, 16);
> +
> +       if (enabled)
> +               flags = 0x03;
> +       else
> +               flags = 0;
> +
> +       ev.flags = cpu_to_le32(flags);
> +
> +       return mgmt_limited_event(MGMT_EV_EXP_FEATURE_CHANGED, NULL,
> +                                 &ev, sizeof(ev),
> +                                 HCI_MGMT_EXP_FEATURE_EVENTS, skip);
> +
> +}
> +
>  #ifdef CONFIG_BT_FEATURE_DEBUG
>  static int exp_debug_feature_changed(bool enabled, struct sock *skip)
>  {
> @@ -3845,6 +3887,18 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
>                 }
>  #endif
>
> +               if (use_ll_privacy(hdev)) {
> +                       bool changed;
> +
> +                       changed = hci_dev_test_flag(hdev,
> +                                                   HCI_ENABLE_LL_PRIVACY);
> +
> +                       hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY);
> +
> +                       if (changed)
> +                               exp_ll_privacy_feature_changed(false, sk);
> +               }
> +
>                 hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS);
>
>                 return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE,
> @@ -3895,6 +3949,64 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
>         }
>  #endif
>
> +       if (!memcmp(cp->uuid, rpa_resolution_uuid, 16)) {
> +               bool val, changed;
> +               int err;
> +               u32 flags;
> +
> +               /* Parameters are limited to a single octet */
> +               if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1)
> +                       return mgmt_cmd_status(sk, MGMT_INDEX_NONE,
> +                                              MGMT_OP_SET_EXP_FEATURE,
> +                                              MGMT_STATUS_INVALID_PARAMS);
> +
> +               /* Only boolean on/off is supported */
> +               if (cp->param[0] != 0x00 && cp->param[0] != 0x01)
> +                       return mgmt_cmd_status(sk, MGMT_INDEX_NONE,
> +                                              MGMT_OP_SET_EXP_FEATURE,
> +                                              MGMT_STATUS_INVALID_PARAMS);
> +
> +               val = !!cp->param[0];
> +
> +               if (val) {
> +                       changed = !hci_dev_test_flag(hdev,
> +                                                    HCI_ENABLE_LL_PRIVACY);
> +
> +                       hci_dev_set_flag(hdev, HCI_ENABLE_LL_PRIVACY);
> +
> +                       /* Enable LL privacy */
> +                       flags = BIT(0);
> +                       /* Disable HCI_ADVERTISING flag */
> +                       flags |= BIT(1);
> +
> +                       hci_dev_clear_flag(hdev, HCI_ADVERTISING);
> +
> +               } else {
> +                       changed = hci_dev_test_flag(hdev,
> +                                                   HCI_ENABLE_LL_PRIVACY);
> +                       hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY);
> +
> +                       flags = 0;
> +               }
> +
> +               memcpy(rp.uuid, rpa_resolution_uuid, 16);
> +
> +               rp.flags = cpu_to_le32(flags);
> +
> +               hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS);
> +
> +               err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE,
> +                                       MGMT_OP_SET_EXP_FEATURE, 0,
> +                                       &rp, sizeof(rp));
> +
> +               if (changed) {
> +                       exp_ll_privacy_feature_changed(val, sk);
> +                       new_settings(hdev, sk);
> +               }
> +
> +               return err;
> +       }
> +
>         return mgmt_cmd_status(sk, hdev ? hdev->id : MGMT_INDEX_NONE,
>                                MGMT_OP_SET_EXP_FEATURE,
>                                MGMT_STATUS_NOT_SUPPORTED);
> --
> 2.17.1
>

Regards
Sathish N

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

* Re: [PATCH v5 8/8] Bluetooth: Enable controller RPA resolution using Experimental feature
  2020-07-23 12:39 ` [PATCH v5 8/8] Bluetooth: Enable controller RPA resolution using Experimental feature Sathish Narasimman
  2020-07-27 11:46   ` Sathish Narasimman
@ 2020-07-30  9:12   ` Marcel Holtmann
  1 sibling, 0 replies; 10+ messages in thread
From: Marcel Holtmann @ 2020-07-30  9:12 UTC (permalink / raw)
  To: Sathish Narasimman; +Cc: Bluetooth Kernel Mailing List, Sathish Narasimman

Hi Sathish,

> This patch adds support to enable the use of RPA Address resolution
> using expermental feature mgmt command.
> 
> Signed-off-by: Sathish Narasimman <sathish.narasimman@intel.com>
> ---
> include/net/bluetooth/hci.h |   1 +
> net/bluetooth/hci_event.c   |   1 +
> net/bluetooth/hci_request.c |   7 ++-
> net/bluetooth/mgmt.c        | 112 ++++++++++++++++++++++++++++++++++++
> 4 files changed, 120 insertions(+), 1 deletion(-)
> 
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index 4ff2fc4498f3..55205d805c22 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -307,6 +307,7 @@ enum {
> 	HCI_FORCE_BREDR_SMP,
> 	HCI_FORCE_STATIC_ADDR,
> 	HCI_LL_RPA_RESOLUTION,
> +	HCI_ENABLE_LL_PRIVACY,
> 	HCI_CMD_PENDING,
> 	HCI_FORCE_NO_MITM,
> 
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 628831b15c0a..33d8458fdd4a 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -5230,6 +5230,7 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
> 			     le16_to_cpu(ev->supervision_timeout));
> 
> 	if (use_ll_privacy(hdev) &&
> +	    hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
> 	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION))
> 		hci_req_disable_address_resolution(hdev);
> }
> diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
> index 70e077cc7dfa..435400a43a78 100644
> --- a/net/bluetooth/hci_request.c
> +++ b/net/bluetooth/hci_request.c
> @@ -678,8 +678,10 @@ void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn)
> 
> 	/* Disable address resolution */
> 	if (use_ll_privacy(hdev) &&
> +	    hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
> 	    hci_dev_test_flag(hdev, HCI_LL_RPA_RESOLUTION) && !rpa_le_conn) {
> 		__u8 enable = 0x00;
> +
> 		hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
> 	}
> }
> @@ -870,8 +872,11 @@ static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
> 		return;
> 	}
> 
> -	if (use_ll_privacy(hdev) && addr_resolv) {
> +	if (use_ll_privacy(hdev) &&
> +	    hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY) &&
> +	    addr_resolv) {
> 		u8 enable = 0x01;
> +
> 		hci_req_add(req, HCI_OP_LE_SET_ADDR_RESOLV_ENABLE, 1, &enable);
> 	}
> 
> diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
> index 47bcfe2fb14c..adde92cf015d 100644
> --- a/net/bluetooth/mgmt.c
> +++ b/net/bluetooth/mgmt.c
> @@ -3759,6 +3759,12 @@ static const u8 simult_central_periph_uuid[16] = {
> 	0x96, 0x46, 0xc0, 0x42, 0xb5, 0x10, 0x1b, 0x67,
> };
> 
> +/* 15c0a148-c273-11ea-b3de-0242ac130004 */
> +static const u8 rpa_resolution_uuid[16] = {
> +	0x04, 0x00, 0x13, 0xac, 0x42, 0x02, 0xde, 0xb3,
> +	0xea, 0x11, 0x73, 0xc2, 0x48, 0xa1, 0xc0, 0x15,
> +};
> +
> static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
> 				  void *data, u16 data_len)
> {
> @@ -3795,6 +3801,21 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
> 		idx++;
> 	}
> 
> +	if (use_ll_privacy(hdev)) {

this function can be called with hdev and !hdev and you need to handle this correctly.

	if (hdev && use_ll_privacy(hdev)) {

> +		if (hci_dev_test_flag(hdev, HCI_ENABLE_LL_PRIVACY)) {
> +			flags = BIT(0);
> +			if (!hci_dev_test_flag(hdev, HCI_ADVERTISING))
> +				flags |= BIT(1);
> +		} else
> +			flags = 0;

I think that I should have explained this in a bit more detail. The BIT(1) needs to be always set when the feature can change settings. It means that bluetoothd needs to re-read controller information to get the new settings.

> +
> +		memcpy(rp->features[idx].uuid, rpa_resolution_uuid, 16);
> +		rp->features[idx].flags = cpu_to_le32(flags);
> +		idx++;
> +
> +		new_settings(hdev, sk);
> +	}
> +
> 	rp->feature_count = cpu_to_le16(idx);

I prefer also to extend the buffer to 62 bytes so that it can potentially fit 3 options.

> 
> 	/* After reading the experimental features information, enable
> @@ -3807,6 +3828,27 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev,
> 				 0, rp, sizeof(*rp) + (20 * idx));
> }
> 
> +static int exp_ll_privacy_feature_changed(bool enabled, struct sock *skip)
> +{
> +	struct mgmt_ev_exp_feature_changed ev;
> +	u32 flags;
> +
> +	memset(&ev, 0, sizeof(ev));
> +	memcpy(ev.uuid, rpa_resolution_uuid, 16);
> +
> +	if (enabled)
> +		flags = 0x03;
> +	else
> +		flags = 0;
> +
> +	ev.flags = cpu_to_le32(flags);
> +
> +	return mgmt_limited_event(MGMT_EV_EXP_FEATURE_CHANGED, NULL,
> +				  &ev, sizeof(ev),
> +				  HCI_MGMT_EXP_FEATURE_EVENTS, skip);

This needs to be send to hdev and not NULL.

> +
> +}
> +
> #ifdef CONFIG_BT_FEATURE_DEBUG
> static int exp_debug_feature_changed(bool enabled, struct sock *skip)
> {
> @@ -3845,6 +3887,18 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
> 		}
> #endif
> 
> +		if (use_ll_privacy(hdev)) {

The experimental setting mgmt might not always be used with a hdev. In addition this feature change must be limited to controller that are powered off.

	if (hdev && use_ll_privacy(hdev) && !hdev_is_powered(hdev)) {

> +			bool changed;
> +
> +			changed = hci_dev_test_flag(hdev,
> +						    HCI_ENABLE_LL_PRIVACY);
> +
> +			hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY);
> +
> +			if (changed)
> +				exp_ll_privacy_feature_changed(false, sk);
> +		}
> +


> 		hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS);
> 
> 		return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE,
> @@ -3895,6 +3949,64 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
> 	}
> #endif
> 
> +	if (!memcmp(cp->uuid, rpa_resolution_uuid, 16)) {
> +		bool val, changed;
> +		int err;
> +		u32 flags;
> +

                /* Command requires to use the controller index */               
                if (!hdev)                                                       
                        return mgmt_cmd_status(sk, MGMT_INDEX_NONE,              
                                               MGMT_OP_SET_EXP_FEATURE,          
                                               MGMT_STATUS_INVALID_INDEX);       
                                                                                 
                /* Changes can only be made when controller is powered down */   
                if (hdev_is_powered(hdev))                                       
                        return mgmt_cmd_status(sk, hdev->id,                     
                                               MGMT_OP_SET_EXP_FEATURE,          
                                               MGMT_STATUS_NOT_POWERED); 

> +		/* Parameters are limited to a single octet */
> +		if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1)
> +			return mgmt_cmd_status(sk, MGMT_INDEX_NONE,

Need to be hdev->id instead of MGMT_INDEX_NONE.

> +					       MGMT_OP_SET_EXP_FEATURE,
> +					       MGMT_STATUS_INVALID_PARAMS);
> +
> +		/* Only boolean on/off is supported */
> +		if (cp->param[0] != 0x00 && cp->param[0] != 0x01)
> +			return mgmt_cmd_status(sk, MGMT_INDEX_NONE,

Same as above.

> +					       MGMT_OP_SET_EXP_FEATURE,
> +					       MGMT_STATUS_INVALID_PARAMS);
> +
> +		val = !!cp->param[0];
> +
> +		if (val) {
> +			changed = !hci_dev_test_flag(hdev,
> +						     HCI_ENABLE_LL_PRIVACY);
> +
> +			hci_dev_set_flag(hdev, HCI_ENABLE_LL_PRIVACY);
> +
> +			/* Enable LL privacy */
> +			flags = BIT(0);
> +			/* Disable HCI_ADVERTISING flag */
> +			flags |= BIT(1);
> +
> +			hci_dev_clear_flag(hdev, HCI_ADVERTISING);
> +
> +		} else {
> +			changed = hci_dev_test_flag(hdev,
> +						    HCI_ENABLE_LL_PRIVACY);
> +			hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY);
> +
> +			flags = 0;

BIT(1) needs to be set all the time to indicate that supported settings changed.

> +		}
> +
> +		memcpy(rp.uuid, rpa_resolution_uuid, 16);
> +
> +		rp.flags = cpu_to_le32(flags);
> +
> +		hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS);
> +
> +		err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE,

Here also we have to use hdev->id and not MGMT_INDEX_NONE.

> +					MGMT_OP_SET_EXP_FEATURE, 0,
> +					&rp, sizeof(rp));
> +
> +		if (changed) {
> +			exp_ll_privacy_feature_changed(val, sk);
> +			new_settings(hdev, sk);

The new_settings is not helpful. The BIT(1) will already indicate that bluetoothd has to re-read the controller info to get the actual supported settings.

> +		}
> +
> +		return err;
> +	}
> +
> 	return mgmt_cmd_status(sk, hdev ? hdev->id : MGMT_INDEX_NONE,
> 			       MGMT_OP_SET_EXP_FEATURE,
> 			       MGMT_STATUS_NOT_SUPPORTED);

So I fixed these all up and hopefully didn’t make a mistake. I am re-sending the whole series with the fixes. Please review.

Regards

Marcel


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

end of thread, back to index

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-23 12:38 [PATCH v5 1/8] Bluetooth: Translate additional address type correctly Sathish Narasimman
2020-07-23 12:38 ` [PATCH v5 2/8] Bluetooth: Configure controller address resolution if available Sathish Narasimman
2020-07-23 12:38 ` [PATCH v5 3/8] Bluetooth: Update resolving list when updating whitelist Sathish Narasimman
2020-07-23 12:38 ` [PATCH v5 4/8] Bluetooth: Translate additional address type during le_conn Sathish Narasimman
2020-07-23 12:39 ` [PATCH v5 5/8] Bluetooth: Let controller creates RPA during le create conn Sathish Narasimman
2020-07-23 12:39 ` [PATCH v5 6/8] Bluetooth: Enable/Disable address resolution " Sathish Narasimman
2020-07-23 12:39 ` [PATCH v5 7/8] Bluetooth: Enable RPA Timeout Sathish Narasimman
2020-07-23 12:39 ` [PATCH v5 8/8] Bluetooth: Enable controller RPA resolution using Experimental feature Sathish Narasimman
2020-07-27 11:46   ` Sathish Narasimman
2020-07-30  9:12   ` Marcel Holtmann

Linux-Bluetooth Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-bluetooth/0 linux-bluetooth/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-bluetooth linux-bluetooth/ https://lore.kernel.org/linux-bluetooth \
		linux-bluetooth@vger.kernel.org
	public-inbox-index linux-bluetooth

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-bluetooth


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git