From 1dd5b101c511217eb6ae43fb3d3747a186f914d8 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 8 Jan 2014 14:46:17 +0200 Subject: [PATCH] emulator: Add basic support for PIN Code Request Reply command --- emulator/btdev.c | 60 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/emulator/btdev.c b/emulator/btdev.c index f4ed94d75..1e31b34dc 100644 --- a/emulator/btdev.c +++ b/emulator/btdev.c @@ -58,6 +58,8 @@ struct btdev { struct btdev *conn; uint8_t link_key[16]; + uint16_t pin[16]; + uint8_t pin_len; btdev_command_func command_handler; void *command_data; @@ -923,18 +925,48 @@ static void link_key_req_neg_reply_complete(struct btdev *btdev, const uint8_t *bdaddr) { struct bt_hci_evt_pin_code_request pin_req; + + memcpy(pin_req.bdaddr, bdaddr, 6); + send_event(btdev, BT_HCI_EVT_PIN_CODE_REQUEST, &pin_req, + sizeof(pin_req)); +} + +static void pin_code_req_reply_complete(struct btdev *btdev, + const uint8_t *bdaddr, uint8_t pin_len, + const uint8_t *pin_code) +{ + struct bt_hci_evt_auth_complete ev; 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(btdev->pin, pin_code, pin_len); + btdev->pin_len = pin_len; - memcpy(pin_req.bdaddr, btdev->bdaddr, 6); - send_event(remote, BT_HCI_EVT_PIN_CODE_REQUEST, &pin_req, + if (!remote->pin_len) { + struct bt_hci_evt_pin_code_request pin_req; + + memcpy(pin_req.bdaddr, btdev->bdaddr, 6); + send_event(remote, BT_HCI_EVT_PIN_CODE_REQUEST, &pin_req, sizeof(pin_req)); + return; + } + + if (btdev->pin_len == remote->pin_len && + !memcmp(btdev->pin, remote->pin, btdev->pin_len)) + ev.status = BT_HCI_ERR_SUCCESS; + else + ev.status = BT_HCI_ERR_AUTH_FAILURE; + + ev.handle = cpu_to_le16(42); + send_event(btdev, BT_HCI_EVT_AUTH_COMPLETE, &ev, sizeof(ev)); + + ev.handle = cpu_to_le16(42); + send_event(remote, BT_HCI_EVT_AUTH_COMPLETE, &ev, sizeof(ev)); + + btdev->pin_len = 0; + remote->pin_len = 0; } static void pin_code_req_neg_reply_complete(struct btdev *btdev, @@ -1251,6 +1283,7 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode, 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 pcrr_rsp; struct bt_hci_rsp_pin_code_request_neg_reply pcrnr_rsp; uint8_t status, page; @@ -1312,6 +1345,14 @@ static void default_cmd(struct btdev *btdev, uint16_t opcode, cmd_complete(btdev, opcode, &lkrnr_rsp, sizeof(lkrnr_rsp)); break; + case BT_HCI_CMD_PIN_CODE_REQUEST_REPLY: + if (btdev->type == BTDEV_TYPE_LE) + goto unsupported; + pcrr_rsp.status = BT_HCI_ERR_SUCCESS; + memcpy(pcrr_rsp.bdaddr, data, 6); + cmd_complete(btdev, opcode, &pcrr_rsp, sizeof(pcrr_rsp)); + break; + case BT_HCI_CMD_PIN_CODE_REQUEST_NEG_REPLY: if (btdev->type == BTDEV_TYPE_LE) goto unsupported; @@ -2116,6 +2157,7 @@ static void default_cmd_completion(struct btdev *btdev, uint16_t opcode, 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_pin_code_request_reply *pcrr; 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; @@ -2177,6 +2219,14 @@ static void default_cmd_completion(struct btdev *btdev, uint16_t opcode, link_key_req_neg_reply_complete(btdev, lkrnr->bdaddr); break; + case BT_HCI_CMD_PIN_CODE_REQUEST_REPLY: + if (btdev->type == BTDEV_TYPE_LE) + return; + pcrr = data; + pin_code_req_reply_complete(btdev, pcrr->bdaddr, pcrr->pin_len, + pcrr->pin_code); + break; + case BT_HCI_CMD_PIN_CODE_REQUEST_NEG_REPLY: if (btdev->type == BTDEV_TYPE_LE) return; -- 2.47.3