Skip to content

Commit b950aa8

Browse files
Ankit Navikholtmann
authored andcommitted
Bluetooth: Add definitions and track LE resolve list modification
Add the definitions for adding entries to the LE resolve list and removing entries from the LE resolve list. When the LE resolve list gets changed via HCI commands make sure that the internal storage of the resolve list entries gets updated. Signed-off-by: Ankit Navik <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 3e4be65 commit b950aa8

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed

include/net/bluetooth/hci.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1517,6 +1517,20 @@ struct hci_cp_le_write_def_data_len {
15171517
__le16 tx_time;
15181518
} __packed;
15191519

1520+
#define HCI_OP_LE_ADD_TO_RESOLV_LIST 0x2027
1521+
struct hci_cp_le_add_to_resolv_list {
1522+
__u8 bdaddr_type;
1523+
bdaddr_t bdaddr;
1524+
__u8 peer_irk[16];
1525+
__u8 local_irk[16];
1526+
} __packed;
1527+
1528+
#define HCI_OP_LE_DEL_FROM_RESOLV_LIST 0x2028
1529+
struct hci_cp_le_del_from_resolv_list {
1530+
__u8 bdaddr_type;
1531+
bdaddr_t bdaddr;
1532+
} __packed;
1533+
15201534
#define HCI_OP_LE_CLEAR_RESOLV_LIST 0x2029
15211535

15221536
#define HCI_OP_LE_READ_RESOLV_LIST_SIZE 0x202a

include/net/bluetooth/hci_core.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ struct bdaddr_list {
103103
u8 bdaddr_type;
104104
};
105105

106+
struct bdaddr_list_with_irk {
107+
struct list_head list;
108+
bdaddr_t bdaddr;
109+
u8 bdaddr_type;
110+
u8 peer_irk[16];
111+
u8 local_irk[16];
112+
};
113+
106114
struct bt_uuid {
107115
struct list_head list;
108116
u8 uuid[16];
@@ -1058,8 +1066,15 @@ int hci_inquiry(void __user *arg);
10581066

10591067
struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
10601068
bdaddr_t *bdaddr, u8 type);
1069+
struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
1070+
struct list_head *list, bdaddr_t *bdaddr,
1071+
u8 type);
10611072
int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
1073+
int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
1074+
u8 type, u8 *peer_irk, u8 *local_irk);
10621075
int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
1076+
int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
1077+
u8 type);
10631078
void hci_bdaddr_list_clear(struct list_head *list);
10641079

10651080
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,

net/bluetooth/hci_core.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,6 +2839,20 @@ struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *bdaddr_list,
28392839
return NULL;
28402840
}
28412841

2842+
struct bdaddr_list_with_irk *hci_bdaddr_list_lookup_with_irk(
2843+
struct list_head *bdaddr_list, bdaddr_t *bdaddr,
2844+
u8 type)
2845+
{
2846+
struct bdaddr_list_with_irk *b;
2847+
2848+
list_for_each_entry(b, bdaddr_list, list) {
2849+
if (!bacmp(&b->bdaddr, bdaddr) && b->bdaddr_type == type)
2850+
return b;
2851+
}
2852+
2853+
return NULL;
2854+
}
2855+
28422856
void hci_bdaddr_list_clear(struct list_head *bdaddr_list)
28432857
{
28442858
struct bdaddr_list *b, *n;
@@ -2871,6 +2885,35 @@ int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type)
28712885
return 0;
28722886
}
28732887

2888+
int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2889+
u8 type, u8 *peer_irk, u8 *local_irk)
2890+
{
2891+
struct bdaddr_list_with_irk *entry;
2892+
2893+
if (!bacmp(bdaddr, BDADDR_ANY))
2894+
return -EBADF;
2895+
2896+
if (hci_bdaddr_list_lookup(list, bdaddr, type))
2897+
return -EEXIST;
2898+
2899+
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
2900+
if (!entry)
2901+
return -ENOMEM;
2902+
2903+
bacpy(&entry->bdaddr, bdaddr);
2904+
entry->bdaddr_type = type;
2905+
2906+
if (peer_irk)
2907+
memcpy(entry->peer_irk, peer_irk, 16);
2908+
2909+
if (local_irk)
2910+
memcpy(entry->local_irk, local_irk, 16);
2911+
2912+
list_add(&entry->list, list);
2913+
2914+
return 0;
2915+
}
2916+
28742917
int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
28752918
{
28762919
struct bdaddr_list *entry;
@@ -2890,6 +2933,26 @@ int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type)
28902933
return 0;
28912934
}
28922935

2936+
int hci_bdaddr_list_del_with_irk(struct list_head *list, bdaddr_t *bdaddr,
2937+
u8 type)
2938+
{
2939+
struct bdaddr_list_with_irk *entry;
2940+
2941+
if (!bacmp(bdaddr, BDADDR_ANY)) {
2942+
hci_bdaddr_list_clear(list);
2943+
return 0;
2944+
}
2945+
2946+
entry = hci_bdaddr_list_lookup_with_irk(list, bdaddr, type);
2947+
if (!entry)
2948+
return -ENOENT;
2949+
2950+
list_del(&entry->list);
2951+
kfree(entry);
2952+
2953+
return 0;
2954+
}
2955+
28932956
/* This function requires the caller holds hdev->lock */
28942957
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
28952958
bdaddr_t *addr, u8 addr_type)

net/bluetooth/hci_event.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,45 @@ static void hci_cc_le_write_def_data_len(struct hci_dev *hdev,
14541454
hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
14551455
}
14561456

1457+
static void hci_cc_le_add_to_resolv_list(struct hci_dev *hdev,
1458+
struct sk_buff *skb)
1459+
{
1460+
struct hci_cp_le_add_to_resolv_list *sent;
1461+
__u8 status = *((__u8 *) skb->data);
1462+
1463+
BT_DBG("%s status 0x%2.2x", hdev->name, status);
1464+
1465+
if (status)
1466+
return;
1467+
1468+
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_ADD_TO_RESOLV_LIST);
1469+
if (!sent)
1470+
return;
1471+
1472+
hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
1473+
sent->bdaddr_type, sent->peer_irk,
1474+
sent->local_irk);
1475+
}
1476+
1477+
static void hci_cc_le_del_from_resolv_list(struct hci_dev *hdev,
1478+
struct sk_buff *skb)
1479+
{
1480+
struct hci_cp_le_del_from_resolv_list *sent;
1481+
__u8 status = *((__u8 *) skb->data);
1482+
1483+
BT_DBG("%s status 0x%2.2x", hdev->name, status);
1484+
1485+
if (status)
1486+
return;
1487+
1488+
sent = hci_sent_cmd_data(hdev, HCI_OP_LE_DEL_FROM_RESOLV_LIST);
1489+
if (!sent)
1490+
return;
1491+
1492+
hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
1493+
sent->bdaddr_type);
1494+
}
1495+
14571496
static void hci_cc_le_clear_resolv_list(struct hci_dev *hdev,
14581497
struct sk_buff *skb)
14591498
{
@@ -3279,6 +3318,14 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
32793318
hci_cc_le_write_def_data_len(hdev, skb);
32803319
break;
32813320

3321+
case HCI_OP_LE_ADD_TO_RESOLV_LIST:
3322+
hci_cc_le_add_to_resolv_list(hdev, skb);
3323+
break;
3324+
3325+
case HCI_OP_LE_DEL_FROM_RESOLV_LIST:
3326+
hci_cc_le_del_from_resolv_list(hdev, skb);
3327+
break;
3328+
32823329
case HCI_OP_LE_CLEAR_RESOLV_LIST:
32833330
hci_cc_le_clear_resolv_list(hdev, skb);
32843331
break;

0 commit comments

Comments
 (0)