From 4f53c2c3ccd5565a6a875c158c6d2d669d16a50f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 8 Jan 2014 14:33:58 +0200 Subject: [PATCH] emulator: Add basic support for Link Key Request Reply command --- emulator/btdev.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/emulator/btdev.c b/emulator/btdev.c index e34be7148..f4ed94d75 100644 --- a/emulator/btdev.c +++ b/emulator/btdev.c @@ -57,6 +57,8 @@ struct btdev { struct btdev *conn; + uint8_t link_key[16]; + btdev_command_func command_handler; void *command_data; @@ -118,6 +120,8 @@ struct btdev { #define MAX_BTDEV_ENTRIES 16 +static const uint8_t LINK_KEY_NONE[16] = { 0 }; + static struct btdev *btdev_list[MAX_BTDEV_ENTRIES] = { }; static int get_hook_index(struct btdev *btdev, enum btdev_hook_type type, @@ -269,6 +273,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] |= 0x04; /* Link Key Request Reply */ btdev->commands[1] |= 0x08; /* Link Key Request Negative Reply */ btdev->commands[1] |= 0x20; /* PIN Code Request Negative Reply */ btdev->commands[1] |= 0x80; /* Authentication Requested */ @@ -885,6 +890,35 @@ 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_reply_complete(struct btdev *btdev, + const uint8_t *bdaddr, + const uint8_t *link_key) +{ + struct btdev *remote = btdev->conn; + struct bt_hci_evt_auth_complete ev; + + memcpy(btdev->link_key, link_key, 16); + + if (!remote) + return; + + if (!memcmp(remote->link_key, LINK_KEY_NONE, 16)) { + send_event(remote, BT_HCI_EVT_LINK_KEY_REQUEST, + btdev->bdaddr, 6); + return; + } + + ev.handle = cpu_to_le16(42); + + if (!memcmp(btdev->link_key, remote->link_key, 16)) + ev.status = BT_HCI_ERR_SUCCESS; + else + ev.status = BT_HCI_ERR_AUTH_FAILURE; + + send_event(btdev, BT_HCI_EVT_AUTH_COMPLETE, &ev, sizeof(ev)); + send_event(remote, BT_HCI_EVT_AUTH_COMPLETE, &ev, sizeof(ev)); +} + static void link_key_req_neg_reply_complete(struct btdev *btdev, const uint8_t *bdaddr) { @@ -937,7 +971,6 @@ static void auth_request_complete(struct btdev *btdev, uint16_t handle) } send_event(btdev, BT_HCI_EVT_LINK_KEY_REQUEST, remote->bdaddr, 6); - send_event(remote, BT_HCI_EVT_LINK_KEY_REQUEST, btdev->bdaddr, 6); } static void name_request_complete(struct btdev *btdev, @@ -1216,6 +1249,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_reply lkrr_rsp; struct bt_hci_rsp_link_key_request_neg_reply lkrnr_rsp; struct bt_hci_rsp_pin_code_request_neg_reply pcrnr_rsp; uint8_t status, page; @@ -1262,6 +1296,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_REPLY: + if (btdev->type == BTDEV_TYPE_LE) + goto unsupported; + lkrr_rsp.status = BT_HCI_ERR_SUCCESS; + memcpy(lkrr_rsp.bdaddr, data, 6); + cmd_complete(btdev, opcode, &lkrr_rsp, sizeof(lkrr_rsp)); + break; + case BT_HCI_CMD_LINK_KEY_REQUEST_NEG_REPLY: if (btdev->type == BTDEV_TYPE_LE) goto unsupported; @@ -2071,6 +2113,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_reply *lkrr; const struct bt_hci_cmd_link_key_request_neg_reply *lkrnr; const struct bt_hci_cmd_pin_code_request_neg_reply *pcrnr; const struct bt_hci_cmd_remote_name_request *rnr; @@ -2120,6 +2163,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_REPLY: + if (btdev->type == BTDEV_TYPE_LE) + return; + lkrr = data; + link_key_req_reply_complete(btdev, lkrr->bdaddr, lkrr->link_key); + break; + case BT_HCI_CMD_LINK_KEY_REQUEST_NEG_REPLY: if (btdev->type == BTDEV_TYPE_LE) return; -- 2.47.3