diff --git a/emulator/bthost.c b/emulator/bthost.c
index 64ebd6a..a8a1e89 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
init_conn(bthost, le16_to_cpu(ev->handle), ev->peer_addr, addr_type);
}
+static void evt_le_ltk_request(struct bthost *bthost, const void *data,
+ uint8_t len)
+{
+ const struct bt_hci_evt_le_long_term_key_request *ev = data;
+ struct bt_hci_cmd_le_ltk_req_reply cp;
+ struct bt_hci_cmd_le_ltk_req_neg_reply *neg_cp = (void *) &cp;
+ uint16_t handle, div;
+ struct btconn *conn;
+ int err;
+
+ if (len < sizeof(*ev))
+ return;
+
+ handle = acl_handle(ev->handle);
+ conn = bthost_find_conn(bthost, handle);
+ if (!conn)
+ return;
+
+ div = le16_to_cpu(ev->diversifier);
+
+ cp.handle = ev->handle;
+
+ err = smp_get_ltk(conn->smp_data, ev->number, div, cp.ltk);
+ if (err < 0)
+ send_command(bthost, BT_HCI_CMD_LE_LTK_REQ_NEG_REPLY,
+ neg_cp, sizeof(*neg_cp));
+ else
+ send_command(bthost, BT_HCI_CMD_LE_LTK_REQ_REPLY, &cp,
+ sizeof(cp));
+}
+
static void evt_le_meta_event(struct bthost *bthost, const void *data,
uint8_t len)
{
case BT_HCI_EVT_LE_CONN_COMPLETE:
evt_le_conn_complete(bthost, evt_data, len - 1);
break;
+ case BT_HCI_EVT_LE_LONG_TERM_KEY_REQUEST:
+ evt_le_ltk_request(bthost, evt_data, len - 1);
+ break;
default:
printf("Unsupported LE Meta event 0x%2.2x\n", *event);
break;
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 9a5063a..a3c26a1 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
const uint8_t *ra, bool conn_init);
void smp_conn_del(void *conn_data);
void smp_data(void *conn_data, const void *data, uint16_t len);
+int smp_get_ltk(void *smp_data, const uint8_t *rand, uint16_t div,
+ uint8_t *ltk);
void smp_pair(void *conn_data);
diff --git a/emulator/smp.c b/emulator/smp.c
index 33799b2..2b4f9a5 100644
--- a/emulator/smp.c
+++ b/emulator/smp.c
}
}
+int smp_get_ltk(void *smp_data, const uint8_t *rand, uint16_t div,
+ uint8_t *ltk)
+{
+ struct smp_conn *conn = smp_data;
+ static const uint8_t no_ltk[16] = { 0 };
+
+ if (!memcmp(conn->ltk, no_ltk, 16))
+ return -ENOENT;
+
+ memcpy(ltk, conn->ltk, 16);
+
+ return 0;
+}
+
void *smp_conn_add(void *smp_data, uint16_t handle, const uint8_t *ia,
const uint8_t *ra, bool conn_init)
{