Diff between 741d28de64048d13455439a206ef114258e716a4 and f3db25a05bc36a1d9886902e60853a8872d9a5b2

Changed Files

File Additions Deletions Status
emulator/bthost.c +34 -0 modified
emulator/bthost.h +2 -0 modified
emulator/smp.c +14 -0 modified

Full Patch

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 64ebd6a..a8a1e89 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 9a5063a..a3c26a1 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 33799b2..2b4f9a5 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)
 {