mgmt: Add mgmt_pair_device command

This patch adds a new management command for triggering a dedicated
bonding procedure to a remote device.
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index 0bd7533..b74e274 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -231,6 +231,18 @@
 	Return Paramters:	Controller_Index (2 Octets)
 
 
+Pair Device Command
+===================
+
+	Command Code:		0x0014
+	Command Parameters:	Controller_Index (2 Octets)
+				Address (6 Octets)
+				IO_Capability (1 Octet)
+	Return Paramters:	Controller_Index (2 Octets)
+				Address (6 Octets)
+				Status (1 Octet)
+
+
 Read Tracing Buffer Size Command
 ================================
 
diff --git a/lib/mgmt.h b/lib/mgmt.h
index 94be6fa..f940b9d 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -169,6 +169,18 @@
 	uint8_t io_capability;
 } __packed;
 
+#define MGMT_OP_PAIR_DEVICE		0x0014
+struct mgmt_cp_pair_device {
+	uint16_t index;
+	bdaddr_t bdaddr;
+	uint8_t io_cap;
+} __packed;
+struct mgmt_rp_pair_device {
+	uint16_t index;
+	bdaddr_t bdaddr;
+	uint8_t status;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	uint16_t opcode;
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index a621a22..0e5fe61 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -931,6 +931,24 @@
 	btd_event_disconn_complete(&info->bdaddr, &rp->bdaddr);
 }
 
+static void pair_device_complete(int sk, void *buf, size_t len)
+{
+	struct mgmt_rp_pair_device *rp = buf;
+	uint16_t index;
+	char addr[18];
+
+	if (len < sizeof(*rp)) {
+		error("Too small pair_device complete event");
+		return;
+	}
+
+	index = btohs(bt_get_unaligned(&rp->index));
+
+	ba2str(&rp->bdaddr, addr);
+
+	DBG("hci%d %s pairing complete status %u", index, addr, rp->status);
+}
+
 static void get_connections_complete(int sk, void *buf, size_t len)
 {
 	struct mgmt_rp_get_connections *rp = buf;
@@ -1036,6 +1054,9 @@
 	case MGMT_OP_SET_IO_CAPABILITY:
 		DBG("set_io_capability complete");
 		break;
+	case MGMT_OP_PAIR_DEVICE:
+		pair_device_complete(sk, ev->data, len - sizeof(*ev));
+		break;
 	default:
 		error("Unknown command complete for opcode %u", opcode);
 		break;
@@ -1585,12 +1606,26 @@
 
 static int mgmt_create_bonding(int index, bdaddr_t *bdaddr, uint8_t io_cap)
 {
+	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_pair_device)];
+	struct mgmt_hdr *hdr = (void *) buf;
+	struct mgmt_cp_pair_device *cp = (void *) &buf[sizeof(*hdr)];
 	char addr[18];
 
 	ba2str(bdaddr, addr);
 	DBG("hci%d bdaddr %s io_cap 0x%02x", index, addr, io_cap);
 
-	return -ENOSYS;
+	memset(buf, 0, sizeof(buf));
+	hdr->opcode = htobs(MGMT_OP_PAIR_DEVICE);
+	hdr->len = htobs(sizeof(*cp));
+
+	cp->index = htobs(index);
+	bacpy(&cp->bdaddr, bdaddr);
+	cp->io_cap = io_cap;
+
+	if (write(mgmt_sock, &buf, sizeof(buf)) < 0)
+		return -errno;
+
+	return 0;
 }
 
 static int mgmt_cancel_bonding(int index, bdaddr_t *bdaddr)