Diff between 7292a4da74489e1e999175199adc273553d9e23c and 52682e25b755d281b21ae7c1b54ecf4016f20280

Changed Files

File Additions Deletions Status
emulator/btdev.c +36 -0 modified

Full Patch

diff --git a/emulator/btdev.c b/emulator/btdev.c
index ddfc562..00ea14e 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -269,6 +269,7 @@ static void set_bredr_commands(struct btdev *btdev)
 	btdev->commands[0]  |= 0x80;	/* Cancel Create Connection */
 	btdev->commands[1]  |= 0x01;	/* Accept Connection Request */
 	btdev->commands[1]  |= 0x02;	/* Reject Connection Request */
+	btdev->commands[1]  |= 0x08;	/* Link Key Request Negative Reply */
 	btdev->commands[1]  |= 0x80;	/* Authentication Requested */
 	btdev->commands[2]  |= 0x08;	/* Remote Name Request */
 	btdev->commands[2]  |= 0x10;	/* Cancel Remote Name Request */
@@ -883,6 +884,24 @@ static void disconnect_complete(struct btdev *btdev, uint16_t handle,
 	send_event(remote, BT_HCI_EVT_DISCONNECT_COMPLETE, &dc, sizeof(dc));
 }
 
+static void link_key_req_neg_reply_complete(struct btdev *btdev,
+							const uint8_t *bdaddr)
+{
+	struct bt_hci_evt_pin_code_request pin_req;
+	struct btdev *remote = btdev->conn;
+
+	if (!remote)
+		return;
+
+	memcpy(pin_req.bdaddr, bdaddr, 6);
+	send_event(btdev, BT_HCI_EVT_PIN_CODE_REQUEST, &pin_req,
+							sizeof(pin_req));
+
+	memcpy(pin_req.bdaddr, btdev->bdaddr, 6);
+	send_event(remote, BT_HCI_EVT_PIN_CODE_REQUEST, &pin_req,
+							sizeof(pin_req));
+}
+
 static void auth_request_complete(struct btdev *btdev, uint16_t handle)
 {
 	struct btdev *remote = btdev->conn;
@@ -1178,6 +1197,7 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
 	struct bt_hci_rsp_le_rand lr;
 	struct bt_hci_rsp_le_test_end lte;
 	struct bt_hci_rsp_remote_name_request_cancel rnrc_rsp;
+	struct bt_hci_rsp_link_key_request_neg_reply lkrnr_rsp;
 	uint8_t status, page;
 
 	switch (opcode) {
@@ -1222,6 +1242,14 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode,
 		cmd_status(btdev, BT_HCI_ERR_SUCCESS, opcode);
 		break;
 
+	case BT_HCI_CMD_LINK_KEY_REQUEST_NEG_REPLY:
+		if (btdev->type == BTDEV_TYPE_LE)
+			goto unsupported;
+		lkrnr_rsp.status = BT_HCI_ERR_SUCCESS;
+		memcpy(lkrnr_rsp.bdaddr, data, 6);
+		cmd_complete(btdev, opcode, &lkrnr_rsp, sizeof(lkrnr_rsp));
+		break;
+
 	case BT_HCI_CMD_AUTH_REQUESTED:
 		if (btdev->type == BTDEV_TYPE_LE)
 			goto unsupported;
@@ -2015,6 +2043,7 @@ static void default_cmd_completion(struct btdev *btdev, uint16_t opcode,
 	const struct bt_hci_cmd_accept_conn_request *acr;
 	const struct bt_hci_cmd_reject_conn_request *rcr;
 	const struct bt_hci_cmd_auth_requested *ar;
+	const struct bt_hci_cmd_link_key_request_neg_reply *lkrnr;
 	const struct bt_hci_cmd_remote_name_request *rnr;
 	const struct bt_hci_cmd_remote_name_request_cancel *rnrc;
 	const struct bt_hci_cmd_read_remote_features *rrf;
@@ -2062,6 +2091,13 @@ static void default_cmd_completion(struct btdev *btdev, uint16_t opcode,
 		conn_complete(btdev, rcr->bdaddr, BT_HCI_ERR_UNKNOWN_CONN_ID);
 		break;
 
+	case BT_HCI_CMD_LINK_KEY_REQUEST_NEG_REPLY:
+		if (btdev->type == BTDEV_TYPE_LE)
+			return;
+		lkrnr = data;
+		link_key_req_neg_reply_complete(btdev, lkrnr->bdaddr);
+		break;
+
 	case BT_HCI_CMD_AUTH_REQUESTED:
 		if (btdev->type == BTDEV_TYPE_LE)
 			return;