diff options
| -rw-r--r-- | hcid/agent.c | 5 | ||||
| -rw-r--r-- | hcid/agent.h | 2 | ||||
| -rw-r--r-- | hcid/dbus-hci.c | 35 | ||||
| -rw-r--r-- | hcid/dbus-hci.h | 2 | ||||
| -rw-r--r-- | hcid/security.c | 25 | 
5 files changed, 62 insertions, 7 deletions
| diff --git a/hcid/agent.c b/hcid/agent.c index 2335f09c..5706ea94 100644 --- a/hcid/agent.c +++ b/hcid/agent.c @@ -518,6 +518,11 @@ failed:  	return -1;  } +uint8_t agent_get_io_capability(struct agent *agent) +{ +	return agent->capability; +} +  gboolean agent_matches(struct agent *agent, const char *name, const char *path)  {  	if (g_str_equal(agent->name, name) && g_str_equal(agent->path, path)) diff --git a/hcid/agent.h b/hcid/agent.h index 22f79aa4..2bfe003e 100644 --- a/hcid/agent.h +++ b/hcid/agent.h @@ -49,6 +49,8 @@ int agent_confirm_mode_change(struct agent *agent, const char *new_mode,  int agent_cancel(struct agent *agent); +uint8_t agent_get_io_capability(struct agent *agent); +  gboolean agent_matches(struct agent *agent, const char *name, const char *path);  void agent_init(void); diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index b28b5c7d..14261bfe 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -2269,6 +2269,41 @@ void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr)  	}  } +int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote, uint8_t *cap, +				uint8_t *auth) +{ +	struct adapter *adapter; +	struct device *device; +	struct agent *agent; +	char addr[18]; + +	adapter = find_adapter(local); +	if (!adapter) { +		error("No matching adapter found"); +		return -1; +	} + +	ba2str(remote, addr); + +	device = adapter_find_device(adapter, addr); +	if (device && device->agent) { +		agent = device->agent; +		*auth = 0x03; +	} else { +		agent = adapter->agent; +		*auth = 0x01; +	} + +	if (!agent) { +		error("No agent available for IO capability"); +		return -1; +	} + +	*cap = agent_get_io_capability(agent); + +	return 0; +} +  static int inquiry_cancel(int dd, int to)  {  	struct hci_request rq; diff --git a/hcid/dbus-hci.h b/hcid/dbus-hci.h index 5b8c89e3..671c5f1a 100644 --- a/hcid/dbus-hci.h +++ b/hcid/dbus-hci.h @@ -47,6 +47,8 @@ void hcid_dbus_setscan_enable_complete(bdaddr_t *local);  void hcid_dbus_write_class_complete(bdaddr_t *local);  void hcid_dbus_write_simple_pairing_mode_complete(bdaddr_t *local);  void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr); +int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote, uint8_t *cap, +				uint8_t *auth);  int unregister_adapter_path(const char *path); diff --git a/hcid/security.c b/hcid/security.c index c9e7dda7..6f8151f8 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -375,18 +375,29 @@ static void remote_oob_data_request(int dev, bdaddr_t *sba, void *ptr)  static void io_capa_request(int dev, bdaddr_t *sba, bdaddr_t *dba)  { -	io_capability_neg_reply_cp cp;  	char sa[18], da[18]; +	uint8_t cap, auth;  	ba2str(sba, sa); ba2str(dba, da);  	info("io_capa_request (sba=%s, dba=%s)", sa, da); -	memset(&cp, 0, sizeof(cp)); -	bacpy(&cp.bdaddr, dba); -	cp.reason = HCI_PAIRING_NOT_ALLOWED; - -	hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_NEG_REPLY, -					IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp); +	if (hcid_dbus_get_io_cap(sba, dba, &cap, &auth) < 0) { +		io_capability_neg_reply_cp cp; +		memset(&cp, 0, sizeof(cp)); +		bacpy(&cp.bdaddr, dba); +		cp.reason = HCI_PAIRING_NOT_ALLOWED; +		hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_NEG_REPLY, +				IO_CAPABILITY_NEG_REPLY_CP_SIZE, &cp); +	} else { +		io_capability_reply_cp cp; +		memset(&cp, 0, sizeof(cp)); +		bacpy(&cp.bdaddr, dba); +		cp.capability = cap; +		cp.oob_data = 0x00; +		cp.authentication = auth; +		hci_send_cmd(dev, OGF_LINK_CTL, OCF_IO_CAPABILITY_REPLY, +				IO_CAPABILITY_REPLY_CP_SIZE, &cp); +	}  }  /* PIN code handling */ | 
