diff options
| -rw-r--r-- | src/adapter.c | 194 | ||||
| -rw-r--r-- | src/adapter.h | 19 | ||||
| -rw-r--r-- | src/dbus-hci.c | 37 | ||||
| -rw-r--r-- | src/device.c | 76 | ||||
| -rw-r--r-- | src/device.h | 9 | 
5 files changed, 149 insertions, 186 deletions
| diff --git a/src/adapter.c b/src/adapter.c index 5df012e6..458d536f 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -107,7 +107,7 @@ struct btd_adapter {  	DBusMessage *discovery_cancel;	/* discovery cancel message request */  	GSList *passkey_agents;  	struct agent *agent;		/* For the new API */ -	GSList *active_conn; +	GSList *connections;		/* Connected devices */  	GSList *devices;		/* Devices structure pointers */  	GSList *mode_sessions;		/* Request Mode sessions */  	GSList *disc_sessions;		/* Discovery sessions */ @@ -176,25 +176,6 @@ static inline DBusMessage *unsupported_major_class(DBusMessage *msg)  			"Unsupported Major Class");  } -static int active_conn_find_by_bdaddr(const void *data, const void *user_data) -{ -	const struct active_conn_info *con = data; -	const bdaddr_t *bdaddr = user_data; - -	return bacmp(&con->bdaddr, bdaddr); -} - -static int active_conn_find_by_handle(const void *data, const void *user_data) -{ -	const struct active_conn_info *dev = data; -	const uint16_t *handle = user_data; - -	if (dev->handle == *handle) -		return 0; - -	return -1; -} -  static void send_out_of_range(const char *path, GSList *l)  {  	while (l) { @@ -900,6 +881,21 @@ struct btd_device *adapter_find_device(struct btd_adapter *adapter, const char *  	return device;  } +struct btd_device *adapter_find_connection(struct btd_adapter *adapter, +					uint16_t handle) +{ +	GSList *l; + +	for (l = adapter->connections; l; l = l->next) { +		struct btd_device *device = l->data; + +		if (device_has_connection(device, handle)) +			return device; +	} + +	return NULL; +} +  static void adapter_update_devices(struct btd_adapter *adapter)  {  	char **devices; @@ -1816,20 +1812,6 @@ static int adapter_setup(struct btd_adapter *adapter, int dd)  	return 0;  } -static int active_conn_append(GSList **list, bdaddr_t *bdaddr, -				uint16_t handle) -{ -	struct active_conn_info *dev; - -	dev = g_new0(struct active_conn_info, 1); - -	bacpy(&dev->bdaddr, bdaddr); -	dev->handle = handle; - -	*list = g_slist_append(*list, dev); -	return 0; -} -  static void create_stored_device_from_profiles(char *key, char *value,  						void *user_data)  { @@ -1904,6 +1886,36 @@ static void load_drivers(struct btd_adapter *adapter)  	}  } +static void load_connections(struct btd_adapter *adapter, int dd) +{ +	struct hci_conn_list_req *cl = NULL; +	struct hci_conn_info *ci; +	int i; + +	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); + +	cl->dev_id = adapter->dev_id; +	cl->conn_num = 10; +	ci = cl->conn_info; + +	if (ioctl(dd, HCIGETCONNLIST, cl) != 0) { +		g_free(cl); +		return; +	} + +	for (i = 0; i < cl->conn_num; i++, ci++) { +		struct btd_device *device; +		char address[18]; + +		ba2str(&ci->bdaddr, address); +		device = adapter_get_device(connection, adapter, address); +		if (device) +			adapter_add_connection(adapter, device, ci->handle); +	} + +	g_free(cl); +} +  static int get_discoverable_timeout(const char *src)  {  	int timeout; @@ -1927,7 +1939,6 @@ static int get_pairable_timeout(const char *src)  static int adapter_up(struct btd_adapter *adapter, int dd)  {  	char mode[14], srcaddr[18]; -	int i;  	uint8_t scan_mode;  	gboolean powered, dev_down = FALSE; @@ -1980,39 +1991,23 @@ static int adapter_up(struct btd_adapter *adapter, int dd)  	}  proceed: -	if (dev_down == FALSE) +	if (dev_down == FALSE) {  		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE,  				1, &scan_mode); -	/* retrieve the active connections: address the scenario where -	 * the are active connections before the daemon've started */ -	if (adapter->initialized == FALSE) { -		struct hci_conn_list_req *cl = NULL; -		struct hci_conn_info *ci; - -		cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); - -		cl->dev_id = adapter->dev_id; -		cl->conn_num = 10; -		ci = cl->conn_info; - -		if (ioctl(dd, HCIGETCONNLIST, cl) == 0) { -			for (i = 0; i < cl->conn_num; i++, ci++) -				active_conn_append(&adapter->active_conn, -						&ci->bdaddr, ci->handle); -		} - -		g_free(cl); -	} - -	if (dev_down == FALSE)  		emit_property_changed(connection, adapter->path,  					ADAPTER_INTERFACE, "Powered",  					DBUS_TYPE_BOOLEAN, &powered); +	}  	if (adapter->initialized == FALSE) {  		load_drivers(adapter);  		load_devices(adapter); + +		/* retrieve the active connections: address the scenario where +		 * the are active connections before the daemon've started */ +		load_connections(adapter, dd); +  		adapter->initialized = TRUE;  	} @@ -2211,10 +2206,9 @@ int adapter_stop(struct btd_adapter *adapter)  		adapter->oor_devices = NULL;  	} -	if (adapter->active_conn) { -		g_slist_foreach(adapter->active_conn, (GFunc) g_free, NULL); -		g_slist_free(adapter->active_conn); -		adapter->active_conn = NULL; +	if (adapter->connections) { +		g_slist_free(adapter->connections); +		adapter->connections = NULL;  	}  	if (adapter->scan_mode == (SCAN_PAGE | SCAN_INQUIRY)) { @@ -2645,62 +2639,43 @@ struct agent *adapter_get_agent(struct btd_adapter *adapter)  	return adapter->agent;  } -void adapter_add_active_conn(struct btd_adapter *adapter, bdaddr_t *bdaddr, -				uint16_t handle) +void adapter_add_connection(struct btd_adapter *adapter, +				struct btd_device *device, uint16_t handle)  { -	struct active_conn_info *dev; - -	if (!adapter) +	if (g_slist_find(adapter->connections, device)) { +		error("Unable to add connection %d", handle);  		return; +	} -	dev = g_new0(struct active_conn_info, 1); - -	bacpy(&dev->bdaddr, bdaddr); -	dev->handle = handle; - -	adapter->active_conn = g_slist_append(adapter->active_conn, dev); -} - -void adapter_remove_active_conn(struct btd_adapter *adapter, -				struct active_conn_info *dev) -{ -	if (!adapter || !adapter->active_conn) -		return; +	device_add_connection(device, connection, handle); -	adapter->active_conn = g_slist_remove(adapter->active_conn, dev); -	g_free(dev); +	adapter->connections = g_slist_append(adapter->connections, device);  } -struct active_conn_info *adapter_search_active_conn_by_bdaddr(struct btd_adapter *adapter, -						    bdaddr_t *bda) +void adapter_remove_connection(struct btd_adapter *adapter, +				struct btd_device *device, uint16_t handle)  { -	GSList *l; - -	if (!adapter || !adapter->active_conn) -		return NULL; +	bdaddr_t bdaddr; -	l = g_slist_find_custom(adapter->active_conn, bda, -					active_conn_find_by_bdaddr); -	if (l) -		return l->data; +	if (!g_slist_find(adapter->connections, device)) { +		error("No matching connection for handle %u", handle); +		return; +	} -	return NULL; -} +	device_remove_connection(device, connection, handle); -struct active_conn_info *adapter_search_active_conn_by_handle(struct btd_adapter *adapter, -						    uint16_t handle) -{ -	GSList *l; +	adapter->connections = g_slist_remove(adapter->connections, device); -	if (!adapter || !adapter->active_conn) -		return NULL; +	/* clean pending HCI cmds */ +	device_get_address(device, &bdaddr); +	hci_req_queue_remove(adapter->dev_id, &bdaddr); -	l = g_slist_find_custom(adapter->active_conn, &handle, -					active_conn_find_by_handle); -	if (l) -		return l->data; +	if (device_is_temporary(device)) { +		const char *path = device_get_path(device); -	return NULL; +		debug("Removing temporary device %s", path); +		adapter_remove_device(connection, adapter, device); +	}  }  gboolean adapter_has_discov_sessions(struct btd_adapter *adapter) @@ -2761,12 +2736,15 @@ static int btd_adapter_authorize(struct btd_adapter *adapter, const bdaddr_t *ds  	gboolean trusted;  	const gchar *dev_path; +	ba2str(dst, address); +	device = adapter_find_device(adapter, address); +	if (!device) +		return -EPERM; +  	/* Device connected? */ -	if (!g_slist_find_custom(adapter->active_conn, -				dst, active_conn_find_by_bdaddr)) +	if (!g_slist_find(adapter->connections, device))  		return -ENOTCONN; -	ba2str(dst, address);  	trusted = read_trust(&adapter->bdaddr, address, GLOBAL_TRUST);  	if (trusted) { diff --git a/src/adapter.h b/src/adapter.h index 2f9068f2..6c63b7e0 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -53,11 +53,6 @@ struct remote_dev_info {  	name_status_t name_status;  }; -struct active_conn_info { -	bdaddr_t bdaddr; -	uint16_t handle; -}; -  struct hci_dev {  	int ignore; @@ -89,6 +84,8 @@ struct btd_device *adapter_get_device(DBusConnection *conn,  struct btd_device *adapter_find_device(struct btd_adapter *adapter, const char *dest); +struct btd_device *adapter_find_connection(struct btd_adapter *adapter, uint16_t handle); +  void adapter_remove_device(DBusConnection *conn, struct btd_adapter *adapter,  				struct btd_device *device);  struct btd_device *adapter_create_device(DBusConnection *conn, @@ -116,14 +113,10 @@ void adapter_update_oor_devices(struct btd_adapter *adapter);  void adapter_remove_oor_device(struct btd_adapter *adapter, char *peer_addr);  void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);  struct agent *adapter_get_agent(struct btd_adapter *adapter); -void adapter_add_active_conn(struct btd_adapter *adapter, bdaddr_t *bdaddr, -				uint16_t handle); -void adapter_remove_active_conn(struct btd_adapter *adapter, -				struct active_conn_info *dev); -struct active_conn_info *adapter_search_active_conn_by_bdaddr(struct btd_adapter *adapter, -								bdaddr_t *bda); -struct active_conn_info *adapter_search_active_conn_by_handle(struct btd_adapter *adapter, -							uint16_t handle); +void adapter_add_connection(struct btd_adapter *adapter, +				struct btd_device *device, uint16_t handle); +void adapter_remove_connection(struct btd_adapter *adapter, +				struct btd_device *device, uint16_t handle);  gboolean adapter_has_discov_sessions(struct btd_adapter *adapter);  struct btd_adapter_driver { diff --git a/src/dbus-hci.c b/src/dbus-hci.c index 0e574aff..49154a61 100644 --- a/src/dbus-hci.c +++ b/src/dbus-hci.c @@ -936,7 +936,7 @@ void hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer)  		return;  	} -	if (!device_get_connected(device)) +	if (!device_is_connected(device))  		device_set_secmode3_conn(device, TRUE);  	else if (!device_is_bonding(device, NULL))  		hcid_dbus_bonding_process_complete(local, peer, 0); @@ -970,20 +970,15 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,  		return;  	} -	device_set_connected(device, connection, TRUE); - -	/* add in the active connetions list */ -	adapter_add_active_conn(adapter, peer, handle); +	/* add in the device connetions list */ +	adapter_add_connection(adapter, device, handle);  }  void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,  				uint16_t handle, uint8_t reason)  { -	char peer_addr[18];  	struct btd_adapter *adapter;  	struct btd_device *device; -	struct active_conn_info *dev; -	uint16_t dev_id;  	if (status) {  		error("Disconnection failed: 0x%02x", status); @@ -996,31 +991,13 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,  		return;  	} -	dev = adapter_search_active_conn_by_handle(adapter, handle); -	if (!dev) { -		error("No matching connection for handle %u", handle); +	device = adapter_find_connection(adapter, handle); +	if (!device) { +		error("No matching connection found for handle %u", handle);  		return;  	} -	ba2str(&dev->bdaddr, peer_addr); - -	dev_id = adapter_get_dev_id(adapter); - -	/* clean pending HCI cmds */ -	hci_req_queue_remove(dev_id, &dev->bdaddr); - -	adapter_remove_active_conn(adapter, dev); - -	device = adapter_find_device(adapter, peer_addr); -	if (!device) -		return; - -	device_set_connected(device, connection, FALSE); - -	if (device_is_temporary(device)) { -		debug("Removing temporary device %s", peer_addr); -		adapter_remove_device(connection, adapter, device); -	} +	adapter_remove_connection(adapter, device, handle);  }  int set_service_classes(int dd, const uint8_t *cls, uint8_t value) diff --git a/src/device.c b/src/device.c index 7891d1e5..8317dcb9 100644 --- a/src/device.c +++ b/src/device.c @@ -102,7 +102,7 @@ struct btd_device {  	uint8_t		cap;  	uint8_t		auth; -	gboolean	connected; +	uint16_t	handle;			/* Connection handle */  	/* Whether were creating a security mode 3 connection */  	gboolean	secmode3; @@ -225,7 +225,6 @@ static DBusMessage *get_properties(DBusConnection *conn,  	uint32_t class;  	int i;  	GSList *l; -	struct active_conn_info *dev;  	ba2str(&device->bdaddr, dstaddr); @@ -287,13 +286,9 @@ static DBusMessage *get_properties(DBusConnection *conn,  	dict_append_entry(&dict, "Trusted", DBUS_TYPE_BOOLEAN, &boolean);  	/* Connected */ -	dev = adapter_search_active_conn_by_bdaddr(adapter, &device->bdaddr); -	if (dev) -		boolean = TRUE; -	else -		boolean = FALSE; - -	dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &boolean); +	boolean = (device->handle != 0); +	dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, +				&boolean);  	/* UUIDs */  	uuids = g_new0(char *, g_slist_length(device->uuids) + 1); @@ -493,25 +488,18 @@ static DBusMessage *cancel_discover(DBusConnection *conn,  static gboolean disconnect_timeout(gpointer user_data)  {  	struct btd_device *device = user_data; -	struct active_conn_info *ci;  	disconnect_cp cp;  	int dd;  	uint16_t dev_id = adapter_get_dev_id(device->adapter);  	device->disconn_timer = 0; -	ci = adapter_search_active_conn_by_bdaddr(device->adapter, -							&device->bdaddr); - -	if (!ci) -		return FALSE; -  	dd = hci_open_dev(dev_id);  	if (dd < 0)  		goto fail;  	memset(&cp, 0, sizeof(cp)); -	cp.handle = htobs(ci->handle); +	cp.handle = htobs(device->handle);  	cp.reason = HCI_OE_USER_ENDED_CONNECTION;  	hci_send_cmd(dd, OGF_LINK_CTL, OCF_DISCONNECT, @@ -527,12 +515,8 @@ static DBusMessage *disconnect(DBusConnection *conn,  					DBusMessage *msg, void *user_data)  {  	struct btd_device *device = user_data; -	struct active_conn_info *dev; - -	dev = adapter_search_active_conn_by_bdaddr(device->adapter, -							&device->bdaddr); -	if (!dev) +	if (!device->handle)  		return g_dbus_create_error(msg,  				ERROR_INTERFACE ".NotConnected",  				"Device is not connected"); @@ -563,16 +547,14 @@ static GDBusSignalTable device_signals[] = {  	{ }  }; -gboolean device_get_connected(struct btd_device *device) +gboolean device_is_connected(struct btd_device *device)  { -	return device->connected; +	return (device->handle != 0);  } -void device_set_connected(struct btd_device *device, DBusConnection *conn, +static void device_set_connected(struct btd_device *device, DBusConnection *conn,  			gboolean connected)  { -	device->connected = connected; -  	emit_property_changed(conn, device->path, DEVICE_INTERFACE,  				"Connected", DBUS_TYPE_BOOLEAN, &connected); @@ -588,6 +570,39 @@ void device_set_connected(struct btd_device *device, DBusConnection *conn,  	}  } +void device_add_connection(struct btd_device *device, DBusConnection *conn, +				uint16_t handle) +{ +	if (device->handle) { +		error("%s: Unable to add connection %u, %u already exist)", +			device->path, handle, device->handle); +		return; +	} + +	device->handle = handle; + +	device_set_connected(device, conn, TRUE); +} + +void device_remove_connection(struct btd_device *device, DBusConnection *conn, +				uint16_t handle) +{ +	if (device->handle != handle) { +		error("%s: Unable to remove connection %u, handle mismatch (%u)", +			device->path, handle, device->handle); +		return; +	} + +	device->handle = 0; + +	device_set_connected(device, conn, FALSE); +} + +gboolean device_has_connection(struct btd_device *device, uint16_t handle) +{ +	return (handle == device->handle); +} +  void device_set_secmode3_conn(struct btd_device *device, gboolean enable)  {  	device->secmode3 = enable; @@ -626,7 +641,6 @@ struct btd_device *device_create(DBusConnection *conn, struct btd_adapter *adapt  static void device_remove_bonding(struct btd_device *device, DBusConnection *conn)  { -	struct active_conn_info *ci;  	char filename[PATH_MAX + 1];  	char *str, srcaddr[18], dstaddr[18];  	int dd, dev_id; @@ -661,10 +675,8 @@ static void device_remove_bonding(struct btd_device *device, DBusConnection *con  	hci_delete_stored_link_key(dd, &device->bdaddr, 0, HCI_REQ_TIMEOUT);  	/* Send the HCI disconnect command */ -	ci = adapter_search_active_conn_by_bdaddr(device->adapter, -						&device->bdaddr); -	if (ci) { -		int err = hci_disconnect(dd, htobs(ci->handle), +	if (device->handle) { +		int err = hci_disconnect(dd, htobs(device->handle),  					HCI_OE_USER_ENDED_CONNECTION,  					HCI_REQ_TIMEOUT);  		if (err < 0) diff --git a/src/device.h b/src/device.h index c9137f7c..2b2735c0 100644 --- a/src/device.h +++ b/src/device.h @@ -55,9 +55,7 @@ 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); -gboolean device_get_connected(struct btd_device *device); -void device_set_connected(struct btd_device *device, DBusConnection *conn, -				gboolean connected); +gboolean device_is_connected(struct btd_device *device);  void device_set_secmode3_conn(struct btd_device *device, gboolean enable);  DBusMessage *device_create_bonding(struct btd_device *device,  				DBusConnection *conn, DBusMessage *msg, @@ -70,6 +68,11 @@ int device_request_authentication(struct btd_device *device, auth_type_t type,  				uint32_t passkey, void *cb);  void device_cancel_authentication(struct btd_device *device);  gboolean device_is_authenticating(struct btd_device *device); +void device_add_connection(struct btd_device *device, DBusConnection *conn, +				uint16_t handle); +void device_remove_connection(struct btd_device *device, DBusConnection *conn, +				uint16_t handle); +gboolean device_has_connection(struct btd_device *device, uint16_t handle);  #define BTD_UUIDS(args...) ((const char *[]) { args, NULL } ) | 
