diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dbus-hci.c | 42 | ||||
| -rw-r--r-- | src/dbus-hci.h | 1 | ||||
| -rw-r--r-- | src/device.c | 34 | ||||
| -rw-r--r-- | src/device.h | 4 | ||||
| -rw-r--r-- | src/security.c | 5 | 
5 files changed, 75 insertions, 11 deletions
| diff --git a/src/dbus-hci.c b/src/dbus-hci.c index e480eb7e..795df0a3 100644 --- a/src/dbus-hci.c +++ b/src/dbus-hci.c @@ -518,6 +518,9 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  	bonding = adapter_get_bonding_info(adapter); +	if (bacmp(&bonding->bdaddr, peer)) +		bonding = NULL; +  	if (status == 0) {  		device = adapter_get_device(connection, adapter, peer_addr);  		if (!device) { @@ -547,12 +550,13 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  	/* If this is a new pairing send the appropriate signal for it  	 * and proceed with service discovery */  	if (status == 0) { -		device_set_paired(connection, device, bonding); +		if (device_set_paired(connection, device, bonding) && bonding) +			adapter_free_bonding_request(adapter);  		return;  	}  proceed: -	if (!bonding || bacmp(&bonding->bdaddr, peer)) +	if (!bonding)  		return; /* skip: no bonding req pending */  	if (bonding->cancel) @@ -996,12 +1000,38 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,  	adapter_set_state(adapter, state);  } +void hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer) +{ +	char peer_addr[18]; +	struct btd_device *device; +	struct btd_adapter *adapter; +	struct bonding_request_info *bonding; + +	adapter = manager_find_adapter(local); +	if (!adapter) { +		error("No matching adapter found"); +		return; +	} + +	ba2str(peer, peer_addr); + +	device = adapter_find_device(adapter, peer_addr); + +	bonding = adapter_get_bonding_info(adapter); + +	if (!device_get_connected(device)) +		device_set_secmode3_conn(device, TRUE); +	else if (!bonding) +		hcid_dbus_bonding_process_complete(local, peer, 0); +} +  void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,  				bdaddr_t *peer)  {  	char peer_addr[18];  	struct btd_adapter *adapter;  	struct bonding_request_info *bonding; +	struct btd_device *device;  	adapter = manager_find_adapter(local);  	if (!adapter) { @@ -1011,6 +1041,8 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,  	ba2str(peer, peer_addr); +	device = adapter_get_device(connection, adapter, peer_addr); +  	if (status) {  		struct pending_auth_info *auth; @@ -1020,13 +1052,13 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,  		adapter_remove_auth_request(adapter, peer); +		if (device) +			device_set_secmode3_conn(device, FALSE); +  		bonding = adapter_get_bonding_info(adapter);  		if (bonding)  			bonding->hci_status = status;  	} else { -		struct btd_device *device; - -		device = adapter_find_device(adapter, peer_addr);  		if (device)  			device_set_connected(connection, device, TRUE); diff --git a/src/dbus-hci.h b/src/dbus-hci.h index fb9dac96..f6547ea4 100644 --- a/src/dbus-hci.h +++ b/src/dbus-hci.h @@ -45,6 +45,7 @@ int hcid_dbus_set_io_cap(bdaddr_t *local, bdaddr_t *remote,  int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey);  int hcid_dbus_user_passkey(bdaddr_t *sba, bdaddr_t *dba);  int hcid_dbus_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey); +void hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer);  int unregister_adapter_path(const char *path); diff --git a/src/device.c b/src/device.c index 59e48904..4f5e3c37 100644 --- a/src/device.c +++ b/src/device.c @@ -82,6 +82,11 @@ struct btd_device {  	/* For Secure Simple Pairing */  	uint8_t		cap;  	uint8_t		auth; + +	gboolean	connected; + +	/* Whether were creating a security mode 3 connection */ +	gboolean	secmode3;  };  struct browse_req { @@ -568,9 +573,16 @@ static GDBusSignalTable device_signals[] = {  	{ }  }; +gboolean device_get_connected(struct btd_device *device) +{ +	return device->connected; +} +  void device_set_connected(DBusConnection *conn, struct btd_device *device,  			gboolean connected)  { +	device->connected = connected; +  	if (!connected && device->discov_timer) {  		g_source_remove(device->discov_timer);  		device->discov_timer = 0; @@ -580,6 +592,22 @@ void device_set_connected(DBusConnection *conn, struct btd_device *device,  						DEVICE_INTERFACE,  						"Connected", DBUS_TYPE_BOOLEAN,  						&connected); + +	if (connected && device->secmode3) { +		struct btd_adapter *adapter = device_get_adapter(device); +		bdaddr_t sba; + +		adapter_get_address(adapter, &sba); + +		device->secmode3 = FALSE; + +		hcid_dbus_bonding_process_complete(&sba, &device->bdaddr, 0); +	} +} + +void device_set_secmode3_conn(struct btd_device *device, gboolean enable) +{ +	device->secmode3 = enable;  }  struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapter, @@ -1274,7 +1302,7 @@ static gboolean start_discovery(gpointer user_data)  	return FALSE;  } -void device_set_paired(DBusConnection *conn, struct btd_device *device, +gboolean device_set_paired(DBusConnection *conn, struct btd_device *device,  			struct bonding_request_info *bonding)  {  	dbus_bool_t paired = TRUE; @@ -1286,7 +1314,7 @@ void device_set_paired(DBusConnection *conn, struct btd_device *device,  						DBUS_TYPE_BOOLEAN, &paired);  	if (device->discov_timer) -		return; +		return FALSE;  	/* If we were initiators start service discovery immediately.  	 * However if the other end was the initator wait a few seconds @@ -1299,6 +1327,8 @@ void device_set_paired(DBusConnection *conn, struct btd_device *device,  		device->discov_timer = g_timeout_add(DISCOVERY_TIMER,  							start_discovery,  							device); + +	return TRUE;  }  int btd_register_device_driver(struct btd_device_driver *driver) diff --git a/src/device.h b/src/device.h index 099ecbbc..126426df 100644 --- a/src/device.h +++ b/src/device.h @@ -42,10 +42,12 @@ void device_set_temporary(struct btd_device *device, gboolean temporary);  void device_set_cap(struct btd_device *device, uint8_t cap);  void device_set_auth(struct btd_device *device, uint8_t auth);  uint8_t device_get_auth(struct btd_device *device); -void device_set_paired(DBusConnection *conn, struct btd_device *device, +gboolean device_set_paired(DBusConnection *conn, struct btd_device *device,  			struct bonding_request_info *bonding); +gboolean device_get_connected(struct btd_device *device);  void device_set_connected(DBusConnection *conn, struct btd_device *device,  				gboolean connected); +void device_set_secmode3_conn(struct btd_device *device, gboolean enable);  #define BTD_UUIDS(args...) ((const char *[]) { args, NULL } ) diff --git a/src/security.c b/src/security.c index 964fb5ba..18fbe590 100644 --- a/src/security.c +++ b/src/security.c @@ -367,7 +367,7 @@ static void link_key_notify(int dev, bdaddr_t *sba, void *ptr)  						DISCONNECT_CP_SIZE, &cp);  		}  	} else -		hcid_dbus_bonding_process_complete(sba, dba, 0); +		hcid_dbus_link_key_notify(sba, dba);  	io_data[dev_id].pin_length = -1;  } @@ -775,8 +775,7 @@ static inline void auth_complete(int dev, bdaddr_t *sba, void *ptr)  	if (get_bdaddr(dev, sba, btohs(evt->handle), &dba) < 0)  		return; -	if (evt->status) -		hcid_dbus_bonding_process_complete(sba, &dba, evt->status); +	hcid_dbus_bonding_process_complete(sba, &dba, evt->status);  }  static inline void conn_request(int dev, bdaddr_t *sba, void *ptr) | 
