From f3db25a05bc36a1d9886902e60853a8872d9a5b2 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 20 Jan 2014 16:24:11 +0200 Subject: [PATCH] emulator/bthost: Add SMP callback to fetch LTK --- emulator/bthost.c | 34 ++++++++++++++++++++++++++++++++++ emulator/bthost.h | 2 ++ emulator/smp.c | 14 ++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/emulator/bthost.c b/emulator/bthost.c index 64ebd6a13..a8a1e89bc 100644 --- a/emulator/bthost.c +++ b/emulator/bthost.c @@ -981,6 +981,37 @@ static void evt_le_conn_complete(struct bthost *bthost, const void *data, 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) { @@ -994,6 +1025,9 @@ static void evt_le_meta_event(struct bthost *bthost, const void *data, 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 9a5063aa7..a3c26a161 100644 --- a/emulator/bthost.h +++ b/emulator/bthost.h @@ -110,4 +110,6 @@ void *smp_conn_add(void *smp_data, uint16_t handle, const uint8_t *ia, 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 33799b237..2b4f9a541 100644 --- a/emulator/smp.c +++ b/emulator/smp.c @@ -407,6 +407,20 @@ 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) +{ + 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) { -- 2.47.3