Bluetooth: Add support for sending New IRK event
authorJohan Hedberg <johan.hedberg@intel.com>
Wed, 19 Feb 2014 13:18:31 +0000 (15:18 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 19 Feb 2014 16:04:24 +0000 (08:04 -0800)
This patch adds the necessary helper function to send the New IRK mgmt
event and makes sure that the function is called at when SMP key
distribution has completed. The event is sent before the New LTK event
so user space knows which remote device to associate with the keys.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
include/net/bluetooth/mgmt.h
net/bluetooth/mgmt.c
net/bluetooth/smp.c

index 59ae04c2684f3ea71061dc4d34c0b6dd1436e17b..3be2905010cd9dc3efbb5ed6f9177d095429d8d5 100644 (file)
@@ -1211,6 +1211,7 @@ void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
 int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
 void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key);
+void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
 void mgmt_reenable_advertising(struct hci_dev *hdev);
 void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 
index e4fa13e559e2f91fd98b609b9ad70cba15bf74db..2e46251e8aec9a81a17833327e7352b6ba265321 100644 (file)
@@ -536,3 +536,10 @@ struct mgmt_ev_passkey_notify {
        __le32  passkey;
        __u8    entered;
 } __packed;
+
+#define MGMT_EV_NEW_IRK                        0x0018
+struct mgmt_ev_new_irk {
+       __u8     store_hint;
+       bdaddr_t rpa;
+       struct mgmt_irk_info irk;
+} __packed;
index bcfc6da67a5ccbaf2a567f0841901858ec9c4748..1daa837da091508fad7386730948b10bc4a52652 100644 (file)
@@ -4792,6 +4792,21 @@ void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key)
        mgmt_event(MGMT_EV_NEW_LONG_TERM_KEY, hdev, &ev, sizeof(ev), NULL);
 }
 
+void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk)
+{
+       struct mgmt_ev_new_irk ev;
+
+       memset(&ev, 0, sizeof(ev));
+
+       ev.store_hint = 0x01;
+       bacpy(&ev.rpa, &irk->rpa);
+       bacpy(&ev.irk.addr.bdaddr, &irk->bdaddr);
+       ev.irk.addr.type = link_to_bdaddr(LE_LINK, irk->addr_type);
+       memcpy(ev.irk.val, irk->val, sizeof(irk->val));
+
+       mgmt_event(MGMT_EV_NEW_IRK, hdev, &ev, sizeof(ev), NULL);
+}
+
 static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
                                  u8 data_len)
 {
index f05c1b71d99ad5c5002d46d98fc5f010f71323be..f06068072bdd78c9d542da4d18d75e556c061ce4 100644 (file)
@@ -1112,6 +1112,9 @@ static void smp_notify_keys(struct l2cap_conn *conn)
        struct hci_conn *hcon = conn->hcon;
        struct hci_dev *hdev = hcon->hdev;
 
+       if (smp->remote_irk)
+               mgmt_new_irk(hdev, smp->remote_irk);
+
        if (smp->ltk) {
                smp->ltk->bdaddr_type = hcon->dst_type;
                bacpy(&smp->ltk->bdaddr, &hcon->dst);