2019-12-04 10:50:08

by K, SpoorthiX

[permalink] [raw]
Subject: [PATCH] Add support to update Resolving list

From: Spoorthi Ravishankar Koppad <[email protected]>

Code changes to add or delete the BD address to/from existing
resolving list referred from Bluetooth Core Specification
v5.0 Vol6 Part B Section 6.3, If the link layer privacy feature
is supported by the controller, Link layer may scan devices
using RPA during background scan,the host can add newly
scanned devices to the Resolving list.
`

Signed-off-by: Spoorthi Ravishankar Koppad <[email protected]>
---
include/net/bluetooth/hci.h | 1 +
net/bluetooth/hci_request.c | 85 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 5bc1e30..1574dc1 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -433,6 +433,7 @@ enum {
#define HCI_LE_SLAVE_FEATURES 0x08
#define HCI_LE_PING 0x10
#define HCI_LE_DATA_LEN_EXT 0x20
+#define HCI_LE_LL_PRIVACY 0x40
#define HCI_LE_PHY_2M 0x01
#define HCI_LE_PHY_CODED 0x08
#define HCI_LE_EXT_ADV 0x10
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 621f1a9..5c59cce 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -670,6 +670,85 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
}
}

+static void add_to_resolve_list(struct hci_request *req,
+ struct hci_conn_params *params,
+ struct list_head *list)
+{
+ struct hci_cp_le_add_to_resolv_list cp;
+ struct bdaddr_list_with_irk *entry;
+
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return;
+
+ memset(&cp, 0, sizeof(cp));
+
+ cp.bdaddr_type = params->addr_type;
+ bacpy(&cp.bdaddr, &params->addr);
+ memcpy(entry->peer_irk, cp.peer_irk, 16);
+ memcpy(entry->local_irk, cp.local_irk, 16);
+
+ list_add(&entry->list, list);
+
+ hci_req_add(req, HCI_OP_LE_ADD_TO_RESOLV_LIST, sizeof(cp), &cp);
+}
+
+static void update_resolve_list(struct hci_request *req)
+{
+ struct hci_dev *hdev = req->hdev;
+ struct bdaddr_list *b;
+ struct hci_conn_params *params;
+ int err;
+ u8 resolve_list_entries = 0;
+
+ list_for_each_entry(b, &hdev->le_resolv_list, list) {
+ /* Cannot Remove or add the device to the Resolving list
+ * whenever there is an outstanding connection.
+ */
+ if (!hci_pend_le_action_lookup(&hdev->pend_le_conns,
+ &b->bdaddr,
+ b->bdaddr_type) &&
+ !hci_pend_le_action_lookup(&hdev->pend_le_reports,
+ &b->bdaddr,
+ b->bdaddr_type)) {
+ struct hci_cp_le_del_from_resolv_list cp;
+
+ cp.bdaddr_type = b->bdaddr_type;
+ bacpy(&cp.bdaddr, &b->bdaddr);
+
+ hci_req_add(req, HCI_OP_LE_DEL_FROM_RESOLV_LIST,
+ sizeof(cp), &cp);
+ }
+ }
+ /* During background scanning/active scanning the
+ * device BD address is populated in LE pending
+ * connections list. So, track the list and add to Resolving
+ * list if found by IRK.
+ */
+ list_for_each_entry(params, &hdev->pend_le_conns, action) {
+ if (hci_bdaddr_list_lookup(&hdev->le_resolv_list,
+ &params->addr, params->addr_type))
+ resolve_list_entries++;
+
+ if (hci_find_irk_by_addr(hdev, &params->addr,
+ params->addr_type)) {
+ /* Add device to resolving list */
+ resolve_list_entries++;
+ add_to_resolve_list(req, params, &hdev->le_resolv_list);
+ }
+ }
+
+ /* Device can be resolved in the Host if size of resolving
+ * list is greater than defined in the controller.
+ */
+ if (resolve_list_entries >= hdev->le_resolv_list_size) {
+ err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa);
+ if (err < 0)
+ BT_ERR("%s failed to generate new RPA",
+ hdev->name);
+ }
+}
+
static void add_to_white_list(struct hci_request *req,
struct hci_conn_params *params)
{
@@ -896,6 +975,12 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
(hdev->le_features[0] & HCI_LE_EXT_SCAN_POLICY))
filter_policy |= 0x02;

+ /* If LE Privacy is supported in controller
+ * add the device to resolving list.
+ */
+ if (hci_dev_test_flag(hdev, HCI_LE_LL_PRIVACY))
+ update_resolve_list(req);
+
hci_req_start_scan(req, LE_SCAN_PASSIVE, hdev->le_scan_interval,
hdev->le_scan_window, own_addr_type, filter_policy);
}
--
1.9.1