mgmt: Add PIN Code request handling
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index 613b7fc..eee0492 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -202,6 +202,24 @@
Address2 (6 Octets)
...
+PIN Code Reply Command
+=======================
+
+ Command Code: 0x0011
+ Command Parameters: Controller_Index (2 Octets)
+ Return Paramters: Controller_Index (2 Octets)
+ Address (6 Octets)
+ PIN_Length (1 Octet)
+ PIN_Code (16 Octets)
+
+
+PIN Code Negative Reply Command
+===============================
+
+ Command Code: 0x0012
+ Command Parameters: Controller_Index (2 Octets)
+ Return Paramters: Controller_Index (2 Octets)
+ Address (6 Octets)
Read Tracing Buffer Size Command
@@ -354,3 +372,10 @@
Event Parameters Controller_Index (2 Octets)
Address (6 Octets)
Status (1 Octet)
+
+PIN Code Request Event
+======================
+
+Event Code 0x000E
+Event Parameters Controller_Index (2 Octets)
+ Address (6 Octets)
diff --git a/lib/mgmt.h b/lib/mgmt.h
index e9079ff..476ed57 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -149,6 +149,20 @@
bdaddr_t conn[0];
} __packed;
+#define MGMT_OP_PIN_CODE_REPLY 0x0011
+struct mgmt_cp_pin_code_reply {
+ uint16_t index;
+ bdaddr_t bdaddr;
+ uint8_t pin_len;
+ uint8_t pin_code[16];
+} __packed;
+
+#define MGMT_OP_PIN_CODE_NEG_REPLY 0x0012
+struct mgmt_cp_pin_code_neg_reply {
+ uint16_t index;
+ bdaddr_t bdaddr;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
uint16_t opcode;
@@ -210,3 +224,9 @@
bdaddr_t bdaddr;
uint8_t status;
} __packed;
+
+#define MGMT_EV_PIN_CODE_REQUEST 0x000E
+struct mgmt_ev_pin_code_request {
+ uint16_t index;
+ bdaddr_t bdaddr;
+} __packed;
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 51a4c93..dc88022 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -534,6 +534,87 @@
btd_event_conn_complete(&info->bdaddr, ev->status, &ev->bdaddr);
}
+static int mgmt_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin)
+{
+ char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_pin_code_reply)];
+ struct mgmt_hdr *hdr = (void *) buf;
+ size_t buf_len;
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ DBG("index %d addr %s pin %s", index, addr, pin ? pin : "<none>");
+
+ memset(buf, 0, sizeof(buf));
+
+ if (pin == NULL) {
+ struct mgmt_cp_pin_code_neg_reply *cp;
+
+ hdr->opcode = htobs(MGMT_OP_PIN_CODE_NEG_REPLY);
+ hdr->len = htobs(sizeof(*cp));
+
+ cp = (void *) &buf[sizeof(*hdr)];
+ cp->index = htobs(index);
+ bacpy(&cp->bdaddr, bdaddr);
+
+ buf_len = sizeof(*hdr) + sizeof(*cp);
+ } else {
+ struct mgmt_cp_pin_code_reply *cp;
+ size_t pin_len;
+
+ pin_len = strlen(pin);
+ if (pin_len > 16)
+ return -EINVAL;
+
+ hdr->opcode = htobs(MGMT_OP_PIN_CODE_REPLY);
+ hdr->len = htobs(sizeof(*cp));
+
+ cp = (void *) &buf[sizeof(*hdr)];
+ cp->index = htobs(index);
+ bacpy(&cp->bdaddr, bdaddr);
+ cp->pin_len = pin_len;
+ memcpy(cp->pin_code, pin, pin_len);
+
+ buf_len = sizeof(*hdr) + sizeof(*cp);
+ }
+
+ if (write(mgmt_sock, buf, buf_len) < 0)
+ return -errno;
+
+ return 0;
+}
+
+static void mgmt_pin_code_request(int sk, void *buf, size_t len)
+{
+ struct mgmt_ev_pin_code_request *ev = buf;
+ struct controller_info *info;
+ uint16_t index;
+ char addr[18];
+ int err;
+
+ if (len < sizeof(*ev)) {
+ error("Too small pin_code_request event");
+ return;
+ }
+
+ index = btohs(bt_get_unaligned(&ev->index));
+ ba2str(&ev->bdaddr, addr);
+
+ DBG("hci%u %s", index, addr);
+
+ if (index > max_index) {
+ error("Unexpected index %u in pin_code_request event", index);
+ return;
+ }
+
+ info = &controllers[index];
+
+ err = btd_event_request_pin(&info->bdaddr, &ev->bdaddr);
+ if (err < 0) {
+ error("btd_event_request_pin: %s", strerror(-err));
+ mgmt_pincode_reply(index, &ev->bdaddr, NULL);
+ }
+}
+
static void uuid_to_uuid128(uuid_t *uuid128, const uuid_t *uuid)
{
if (uuid->type == SDP_UUID16)
@@ -1064,6 +1145,9 @@
case MGMT_EV_CONNECT_FAILED:
mgmt_connect_failed(sk, buf + MGMT_HDR_SIZE, len);
break;
+ case MGMT_EV_PIN_CODE_REQUEST:
+ mgmt_pin_code_request(sk, buf + MGMT_HDR_SIZE, len);
+ break;
default:
error("Unknown Management opcode %u", opcode);
break;
@@ -1366,16 +1450,6 @@
return -ENOSYS;
}
-static int mgmt_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin)
-{
- char addr[18];
-
- ba2str(bdaddr, addr);
- DBG("index %d addr %s pin %s", index, addr, pin);
-
- return -ENOSYS;
-}
-
static int mgmt_confirm_reply(int index, bdaddr_t *bdaddr, gboolean success)
{
char addr[18];