mgmt: Add set_io_capability command
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index eee0492..0bd7533 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -222,6 +222,15 @@
 				Address (6 Octets)
 
 
+Set IO Capability Command
+=========================
+
+	Command Code:		0x0013
+	Command Parameters:	Controller_Index (2 Octets)
+				IO_Capability (1 Octet)
+	Return Paramters:	Controller_Index (2 Octets)
+
+
 Read Tracing Buffer Size Command
 ================================
 
diff --git a/lib/mgmt.h b/lib/mgmt.h
index 476ed57..94be6fa 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -163,6 +163,12 @@
 	bdaddr_t bdaddr;
 } __packed;
 
+#define MGMT_OP_SET_IO_CAPABILITY	0x0013
+struct mgmt_cp_set_io_capability {
+	uint16_t index;
+	uint8_t io_capability;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	uint16_t opcode;
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 260ac7d..719ef01 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -3215,6 +3215,11 @@
 	return 0;
 }
 
+static int hciops_set_io_capability(int index, uint8_t io_capability)
+{
+	return 0;
+}
+
 static struct btd_adapter_ops hci_ops = {
 	.setup = hciops_setup,
 	.cleanup = hciops_cleanup,
@@ -3254,6 +3259,7 @@
 	.disable_cod_cache = hciops_disable_cod_cache,
 	.restore_powered = hciops_restore_powered,
 	.load_keys = hciops_load_keys,
+	.set_io_capability = hciops_set_io_capability,
 };
 
 static int hciops_init(void)
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 1e5a965..6897d51 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -1033,6 +1033,9 @@
 	case MGMT_OP_PIN_CODE_NEG_REPLY:
 		DBG("pin_code_neg_reply complete");
 		break;
+	case MGMT_OP_SET_IO_CAPABILITY:
+		DBG("set_io_capability complete");
+		break;
 	default:
 		error("Unknown command complete for opcode %u", opcode);
 		break;
@@ -1579,6 +1582,27 @@
 	return err;
 }
 
+static int mgmt_set_io_capability(int index, uint8_t io_capability)
+{
+	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_set_io_capability)];
+	struct mgmt_hdr *hdr = (void *) buf;
+	struct mgmt_cp_set_io_capability *cp = (void *) &buf[sizeof(*hdr)];
+
+	DBG("hci%d io_capability 0x%02x", index, io_capability);
+
+	memset(buf, 0, sizeof(buf));
+	hdr->opcode = htobs(MGMT_OP_SET_IO_CAPABILITY);
+	hdr->len = htobs(sizeof(*cp));
+
+	cp->index = htobs(index);
+	cp->io_capability = io_capability;
+
+	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
+		return -errno;
+
+	return 0;
+}
+
 static struct btd_adapter_ops mgmt_ops = {
 	.setup = mgmt_setup,
 	.cleanup = mgmt_cleanup,
@@ -1618,6 +1642,7 @@
 	.disable_cod_cache = mgmt_disable_cod_cache,
 	.restore_powered = mgmt_restore_powered,
 	.load_keys = mgmt_load_keys,
+	.set_io_capability = mgmt_set_io_capability,
 };
 
 static int mgmt_init(void)
diff --git a/src/adapter.c b/src/adapter.c
index 1b8ab05..4c509d8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1834,6 +1834,9 @@
 
 static void agent_removed(struct agent *agent, struct btd_adapter *adapter)
 {
+	adapter_ops->set_io_capability(adapter->dev_id,
+					IO_CAPABILITY_NOINPUTNOOUTPUT);
+
 	adapter->agent = NULL;
 }
 
@@ -1868,6 +1871,8 @@
 	DBG("Agent registered for hci%d at %s:%s", adapter->dev_id, name,
 			path);
 
+	adapter_ops->set_io_capability(adapter->dev_id, cap);
+
 	return dbus_message_new_method_return(msg);
 }
 
diff --git a/src/adapter.h b/src/adapter.h
index 27553b7..b0c7610 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -237,6 +237,7 @@
 	int (*disable_cod_cache) (int index);
 	int (*restore_powered) (int index);
 	int (*load_keys) (int index, GSList *keys, gboolean debug_keys);
+	int (*set_io_capability) (int index, uint8_t io_capability);
 };
 
 int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);