* [RFC v2 1/3] Add HCI commands to enable address resolution in controller
@ 2017-10-09 9:51 Shermin Joy
0 siblings, 0 replies; only message in thread
From: Shermin Joy @ 2017-10-09 9:51 UTC (permalink / raw)
To: linux-bluetooth
Add HCI commands : LE Read Resolving List Size,
LE Add Device to Resolving List, LE Delete Device from Resolving List,
LE Clear Resolving List, LE Set Address Resolution Enable
Signed-off-by: Shermin Joy <shermin.joy@gmail.com>
---
include/net/bluetooth/hci.h | 25 ++++++++++
include/net/bluetooth/hci_core.h | 12 +++++
net/bluetooth/hci_core.c | 20 ++++++++
net/bluetooth/hci_event.c | 98 ++++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_request.c | 62 +++++++++++++++++++++++++
net/bluetooth/hci_request.h | 8 ++++
6 files changed, 225 insertions(+)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index fe98f0a..1ef3ae8 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -398,6 +398,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_EXT_SCAN_POLICY 0x80
#define HCI_LE_CHAN_SEL_ALG2 0x40
@@ -1506,6 +1507,30 @@ struct hci_cp_le_set_default_phy {
__u8 rx_phys;
} __packed;
+#define HCI_OP_LE_ADD_TO_RESOLVING_LIST 0x2027
+struct hci_cp_le_add_to_resolving_list {
+ __u8 peer_bdaddr_type;
+ bdaddr_t peer_bdaddr;
+ __u8 peer_irk[16];
+ __u8 local_irk[16];
+} __packed;
+
+#define HCI_OP_LE_DEL_FROM_RESOLVING_LIST 0x2028
+struct hci_cp_le_del_from_resolving_list {
+ __u8 peer_bdaddr_type;
+ bdaddr_t peer_bdaddr;
+} __packed;
+
+#define HCI_OP_LE_CLEAR_RESOLVING_LIST 0x2029
+
+#define HCI_OP_LE_READ_RESOLVING_LIST_SIZE 0x202A
+struct hci_rp_le_read_resolving_list_size {
+ __u8 status;
+ __u8 size;
+} __packed;
+
+#define HCI_OP_LE_SET_ADDR_RESOL_ENABLE 0x202D
+
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 95ccc1e..65ba086 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -139,6 +139,13 @@ struct smp_irk {
u8 val[16];
};
+struct hci_irk {
+ struct list_head list;
+ bdaddr_t bdaddr;
+ u8 addr_type;
+ u8 val[16];
+};
+
struct link_key {
struct list_head list;
struct rcu_head rcu;
@@ -221,6 +228,7 @@ struct hci_dev {
__u8 features[HCI_MAX_PAGES][8];
__u8 le_features[8];
__u8 le_white_list_size;
+ __u8 le_resolving_list_size;
__u8 le_states[8];
__u8 commands[64];
__u8 hci_ver;
@@ -259,6 +267,7 @@ struct hci_dev {
__u8 ssp_debug_mode;
__u8 hw_error_code;
__u32 clock;
+ bool le_ll_addr_resolve_enabled;
__u16 devid_source;
__u16 devid_vendor;
@@ -361,6 +370,7 @@ struct hci_dev {
struct list_head mgmt_pending;
struct list_head blacklist;
struct list_head whitelist;
+ struct list_head resolvinglist;
struct list_head uuids;
struct list_head link_keys;
struct list_head long_term_keys;
@@ -1536,6 +1546,8 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
void hci_copy_identity_address(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 *bdaddr_type);
+void hci_clear_resolving_list(struct hci_dev *hdev);
+
#define SCO_AIRMODE_MASK 0x0003
#define SCO_AIRMODE_CVSD 0x0000
#define SCO_AIRMODE_TRANSP 0x0003
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6bc679c..bfeeb18 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -731,6 +731,24 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)
hci_req_add(req, HCI_OP_LE_READ_DEF_DATA_LEN, 0, NULL);
}
+ if (hdev->le_features[0] & HCI_LE_LL_PRIVACY) {
+ if (hdev->commands[34] & 0x40)
+ /* Read LE Resolving List Size */
+ hci_req_add(req,
+ HCI_OP_LE_READ_RESOLVING_LIST_SIZE,
+ 0, NULL);
+ if (hdev->commands[35] & 0x02)
+ /* Enable Address Resolution in Controller */
+ hci_req_add(req,
+ HCI_OP_LE_SET_ADDR_RESOL_ENABLE,
+ 0, NULL);
+ if (hdev->commands[34] & 0x20)
+ /* Clear LE Resolving List */
+ hci_req_add(req,
+ HCI_OP_LE_CLEAR_RESOLVING_LIST,
+ 0, NULL);
+ }
+
hci_set_le_support(req);
}
@@ -3021,6 +3039,7 @@ 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->resolvinglist);
INIT_LIST_HEAD(&hdev->uuids);
INIT_LIST_HEAD(&hdev->link_keys);
INIT_LIST_HEAD(&hdev->long_term_keys);
@@ -3221,6 +3240,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
hci_dev_lock(hdev);
hci_bdaddr_list_clear(&hdev->blacklist);
hci_bdaddr_list_clear(&hdev->whitelist);
+ hci_clear_resolving_list(hdev);
hci_uuids_clear(hdev);
hci_link_keys_clear(hdev);
hci_smp_ltks_clear(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0b4dba0..6252307 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1442,6 +1442,84 @@ static void hci_cc_write_ssp_debug_mode(struct hci_dev *hdev, struct sk_buff *sk
hdev->ssp_debug_mode = *mode;
}
+static void hci_cc_le_read_resolving_list_size(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_rp_le_read_resolving_list_size *rp = (void *)skb->data;
+
+ BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
+
+ if (rp->status)
+ return;
+
+ hdev->le_resolving_list_size = rp->size;
+}
+
+static void hci_cc_le_clear_resolving_list(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *)skb->data);
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+ if (status)
+ return;
+
+ /* Clear all entries in the resolving list.*/
+ hci_clear_resolving_list(hdev);
+}
+
+static void hci_cc_le_add_to_resolving_list(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_cp_le_add_to_resolving_list *sent;
+ __u8 status = *((__u8 *)skb->data);
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+ if (status)
+ return;
+
+ sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLVING_LIST);
+ if (!sent)
+ return;
+
+ hci_update_resolving_list(hdev, sent->peer_bdaddr_type,
+ &sent->peer_bdaddr, sent->peer_irk);
+}
+
+static void hci_cc_le_del_from_resolving_list(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_cp_le_del_from_resolving_list *sent;
+ __u8 status = *((__u8 *)skb->data);
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+ if (status)
+ return;
+
+ sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLVING_LIST);
+ if (!sent)
+ return;
+
+ hci_delete_from_resolving_list(hdev, sent->peer_bdaddr_type,
+ &sent->peer_bdaddr);
+}
+
+static void hci_cc_le_set_address_resolution_enable(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *)skb->data);
+
+ BT_DBG("%s status 0x%2.2x", hdev->name, status);
+
+ if (status)
+ return;
+
+ hdev->le_ll_addr_resolve_enabled = true;
+}
+
static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
{
BT_DBG("%s status 0x%2.2x", hdev->name, status);
@@ -3039,6 +3117,26 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
hci_cc_write_ssp_debug_mode(hdev, skb);
break;
+ case HCI_OP_LE_READ_RESOLVING_LIST_SIZE:
+ hci_cc_le_read_resolving_list_size(hdev, skb);
+ break;
+
+ case HCI_OP_LE_CLEAR_RESOLVING_LIST:
+ hci_cc_le_clear_resolving_list(hdev, skb);
+ break;
+
+ case HCI_OP_LE_ADD_TO_RESOLVING_LIST:
+ hci_cc_le_add_to_resolving_list(hdev, skb);
+ break;
+
+ case HCI_OP_LE_DEL_FROM_RESOLVING_LIST:
+ hci_cc_le_del_from_resolving_list(hdev, skb);
+ break;
+
+ case HCI_OP_LE_SET_ADDR_RESOL_ENABLE:
+ hci_cc_le_set_address_resolution_enable(hdev, skb);
+ break;
+
default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
break;
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index b73ac14..8bdc22b 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -773,6 +773,68 @@ static u8 update_white_list(struct hci_request *req)
return 0x01;
}
+struct hci_irk *hci_resolving_list_lookup(struct hci_dev *hdev,
+ bdaddr_t *bdaddr, u8 type)
+{
+ struct hci_irk *b;
+
+ list_for_each_entry(b, &hdev->resolvinglist, list) {
+ if (!bacmp(&b->bdaddr, bdaddr) && b->addr_type == type)
+ return b;
+ }
+
+ return NULL;
+}
+
+int hci_update_resolving_list(struct hci_dev *hdev, u8 addr_type,
+ bdaddr_t *bdaddr, u8 irk_val[16])
+{
+ struct hci_irk *irk;
+
+ irk = hci_resolving_list_lookup(hdev, bdaddr, addr_type);
+ if (irk) {
+ /* If present, remove the entry from current position.*/
+ list_del(&irk->list);
+ } else {
+ irk = kzalloc(sizeof(*irk), GFP_KERNEL);
+ if (!irk)
+ return -ENOMEM;
+ bacpy(&irk->bdaddr, bdaddr);
+ irk->addr_type = addr_type;
+ }
+
+ memcpy(irk->val, irk_val, 16);
+
+ /* Add the entry to the end of the list.*/
+ list_add_tail(&irk->list, &hdev->resolvinglist);
+ return 0;
+}
+
+int hci_delete_from_resolving_list(struct hci_dev *hdev, u8 addr_type,
+ bdaddr_t *bdaddr)
+{
+ struct hci_irk *irk;
+
+ irk = hci_resolving_list_lookup(hdev, bdaddr, addr_type);
+ if (!irk)
+ return -ENOENT;
+
+ /* If present, remove the entry from current position.*/
+ list_del(&irk->list);
+
+ return 0;
+}
+
+void hci_clear_resolving_list(struct hci_dev *hdev)
+{
+ struct hci_irk *irk;
+
+ list_for_each_entry(irk, &hdev->resolvinglist, list) {
+ list_del(&irk->list);
+ kfree(irk);
+ }
+}
+
static bool scan_use_rpa(struct hci_dev *hdev)
{
return hci_dev_test_flag(hdev, HCI_PRIVACY);
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h
index dde77bd..ab4aac6 100644
--- a/net/bluetooth/hci_request.h
+++ b/net/bluetooth/hci_request.h
@@ -66,6 +66,14 @@ struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen,
void hci_req_add_le_scan_disable(struct hci_request *req);
void hci_req_add_le_passive_scan(struct hci_request *req);
+struct hci_irk *hci_resolving_list_lookup(struct hci_dev *hdev,
+ bdaddr_t *bdaddr, u8 type);
+int hci_update_resolving_list(struct hci_dev *hdev, u8 addr_type,
+ bdaddr_t *bdaddr, u8 irk_val[16]);
+int hci_delete_from_resolving_list(struct hci_dev *hdev, u8 addr_type,
+ bdaddr_t *bdaddr);
+void hci_clear_resolving_list(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);
--
1.9.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2017-10-09 9:51 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-10-09 9:51 [RFC v2 1/3] Add HCI commands to enable address resolution in controller Shermin Joy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.