diff options
| author | Marcel Holtmann <marcel@holtmann.org> | 2008-08-29 23:51:09 +0200 | 
|---|---|---|
| committer | Marcel Holtmann <marcel@holtmann.org> | 2008-08-29 23:51:09 +0200 | 
| commit | 2e2f9a82505b962d20db8cbded2752a27537c566 (patch) | |
| tree | 8ab6cb9ecf4cfcf6a174527112f3d4da7b8fbf79 /src | |
| parent | 41708dccb5d831adaf0862da9c1d7fe3c197db3c (diff) | |
| parent | 93750261a6093a8d987cd23327fd3d90467b5739 (diff) | |
Merge branch 'for-upstream' of git://gitorious.org/bluez/aloks-clone
Diffstat (limited to 'src')
| -rw-r--r-- | src/adapter.c | 166 | ||||
| -rw-r--r-- | src/adapter.h | 8 | ||||
| -rw-r--r-- | src/dbus-hci.c | 238 | ||||
| -rw-r--r-- | src/dbus-hci.h | 2 | 
4 files changed, 196 insertions, 218 deletions
| diff --git a/src/adapter.c b/src/adapter.c index afd909ba..f52cc671 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -167,6 +167,40 @@ static DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn,  			err > 0 ? strerror(err) : "Connection attempt failed");  } +static void send_out_of_range(const char *path, GSList *l) +{ +	while (l) { +		const char *peer_addr = l->data; + +		g_dbus_emit_signal(connection, path, +				ADAPTER_INTERFACE, "DeviceDisappeared", +				DBUS_TYPE_STRING, &peer_addr, +				DBUS_TYPE_INVALID); + +		l = l->next; +	} +} + +static int found_device_cmp(const struct remote_dev_info *d1, +			const struct remote_dev_info *d2) +{ +	int ret; + +	if (bacmp(&d2->bdaddr, BDADDR_ANY)) { +		ret = bacmp(&d1->bdaddr, &d2->bdaddr); +		if (ret) +			return ret; +	} + +	if (d2->name_status != NAME_ANY) { +		ret = (d1->name_status - d2->name_status); +		if (ret) +			return ret; +	} + +	return 0; +} +  static int auth_req_cmp(const void *p1, const void *p2)  {  	const struct pending_auth_info *pb1 = p1; @@ -2483,7 +2517,6 @@ int adapter_stop(struct adapter *adapter)  	adapter->up = 0;  	adapter->scan_mode = SCAN_DISABLED;  	adapter->mode = MODE_OFF; -	adapter->pinq_idle = 0;  	adapter->state = DISCOVER_TYPE_NONE;  	unload_drivers(adapter); @@ -2731,6 +2764,21 @@ void adapter_set_state(struct adapter *adapter, int state)  	if (!adapter)  		return; +	/* Both Standard and periodic Inquiry are in progress */ +	if ((state & STD_INQUIRY) && (state & PERIODIC_INQUIRY)) +		goto set; + +	if (!adapter->found_devices) +		goto set; + +	/* Free list if standard/periodic inquiry is done */ +	if ((adapter->state & (STD_INQUIRY | PERIODIC_INQUIRY)) && +			(state & (~STD_INQUIRY | ~PERIODIC_INQUIRY))) { +		g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL); +		g_slist_free(adapter->found_devices); +		adapter->found_devices = NULL; +	} +set:  	adapter->state = state;  } @@ -2739,6 +2787,122 @@ int adapter_get_state(struct adapter *adapter)  	return adapter->state;  } +struct remote_dev_info *adapter_search_found_devices(struct adapter *adapter, +						struct remote_dev_info *match) +{ +	GSList *l; + +	l = g_slist_find_custom(adapter->found_devices, match, +					(GCompareFunc) found_device_cmp); +	if (l) +		return l->data; + +	return NULL; +} + +int dev_rssi_cmp(struct remote_dev_info *d1, struct remote_dev_info *d2) +{ +	int rssi1, rssi2; + +	rssi1 = d1->rssi < 0 ? -d1->rssi : d1->rssi; +	rssi2 = d2->rssi < 0 ? -d2->rssi : d2->rssi; + +	return rssi1 - rssi2; +} + +int adapter_add_found_device(struct adapter *adapter, bdaddr_t *bdaddr, +				int8_t rssi, name_status_t name_status) +{ +	struct remote_dev_info *dev, match; + +	memset(&match, 0, sizeof(struct remote_dev_info)); +	bacpy(&match.bdaddr, bdaddr); +	match.name_status = NAME_ANY; + +	/* ignore repeated entries */ +	dev = adapter_search_found_devices(adapter, &match); +	if (dev) { +		/* device found, update the attributes */ +		if (rssi != 0) +			dev->rssi = rssi; + +		 /* Get remote name can be received while inquiring. +		  * Keep in mind that multiple inquiry result events can +		  * be received from the same remote device. +		  */ +		if (name_status != NAME_NOT_REQUIRED) +			dev->name_status = name_status; + +		adapter->found_devices = g_slist_sort(adapter->found_devices, +						(GCompareFunc) dev_rssi_cmp); + +		return -EALREADY; +	} + +	dev = g_new0(struct remote_dev_info, 1); + +	bacpy(&dev->bdaddr, bdaddr); +	dev->rssi = rssi; +	dev->name_status = name_status; + +	adapter->found_devices = g_slist_insert_sorted(adapter->found_devices, +						dev, (GCompareFunc) dev_rssi_cmp); + +	return 0; +} + +int adapter_remove_found_device(struct adapter *adapter, bdaddr_t *bdaddr) +{ +	struct remote_dev_info *dev, match; + +	memset(&match, 0, sizeof(struct remote_dev_info)); +	bacpy(&match.bdaddr, bdaddr); + +	dev = adapter_search_found_devices(adapter, &match); +	if (!dev) +		return -1; + +	adapter->found_devices = g_slist_remove(adapter->found_devices, dev); +	g_free(dev); + +	return 0; +} + +void adapter_update_oor_devices(struct adapter *adapter) +{ +	GSList *l = adapter->found_devices; +	struct remote_dev_info *dev; +	bdaddr_t tmp; + +	send_out_of_range(adapter->path, adapter->oor_devices); + +	g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL); +	g_slist_free(adapter->oor_devices); +	adapter->oor_devices = NULL; + +	while (l) { +		dev = l->data; +		baswap(&tmp, &dev->bdaddr); +		adapter->oor_devices = g_slist_append(adapter->oor_devices, +							batostr(&tmp)); +		l = l->next; +	} +} + +void adapter_remove_oor_device(struct adapter *adapter, char *peer_addr) +{ +	GSList *l; + +	l = g_slist_find_custom(adapter->oor_devices, peer_addr, +				(GCompareFunc) strcmp); +	if (l) { +		char *dev = l->data; +		adapter->oor_devices = g_slist_remove(adapter->oor_devices, +								dev); +		g_free(dev); +	} +} +  int btd_register_adapter_driver(struct btd_adapter_driver *driver)  {  	adapter_drivers = g_slist_append(adapter_drivers, driver); diff --git a/src/adapter.h b/src/adapter.h index b39fcd03..e5432b66 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -102,7 +102,6 @@ struct adapter {  	uint8_t scan_mode;		/* scan mode: SCAN_DISABLED, SCAN_PAGE, SCAN_INQUIRY */  	uint8_t mode;			/* off, connectable, discoverable, limited */  	uint8_t global_mode;		/* last valid global mode */ -	int pinq_idle;			/* tracks the idle time for periodic inquiry */  	int state;			/* standard inq, periodic inq, name resloving */  	GSList *found_devices;  	GSList *oor_devices;	/* out of range device list */ @@ -169,6 +168,13 @@ void adapter_set_mode(struct adapter *adapter, uint8_t mode);  uint8_t adapter_get_mode(struct adapter *adapter);  void adapter_set_state(struct adapter *adapter, int state);  int adapter_get_state(struct adapter *adapter); +struct remote_dev_info *adapter_search_found_devices(struct adapter *adapter, +						struct remote_dev_info *match); +int adapter_add_found_device(struct adapter *adapter, bdaddr_t *bdaddr, +				int8_t rssi, name_status_t name_status); +int adapter_remove_found_device(struct adapter *adapter, bdaddr_t *bdaddr); +void adapter_update_oor_devices(struct adapter *adapter); +void adapter_remove_oor_device(struct adapter *adapter, char *peer_addr);  struct btd_adapter_driver {  	const char *name; diff --git a/src/dbus-hci.c b/src/dbus-hci.c index e4c0f345..70b15062 100644 --- a/src/dbus-hci.c +++ b/src/dbus-hci.c @@ -91,97 +91,6 @@ void bonding_request_free(struct bonding_request_info *bonding)  	g_free(bonding);  } -int found_device_cmp(const struct remote_dev_info *d1, -			const struct remote_dev_info *d2) -{ -	int ret; - -	if (bacmp(&d2->bdaddr, BDADDR_ANY)) { -		ret = bacmp(&d1->bdaddr, &d2->bdaddr); -		if (ret) -			return ret; -	} - -	if (d2->name_status != NAME_ANY) { -		ret = (d1->name_status - d2->name_status); -		if (ret) -			return ret; -	} - -	return 0; -} - -int dev_rssi_cmp(struct remote_dev_info *d1, struct remote_dev_info *d2) -{ -	int rssi1, rssi2; - -	rssi1 = d1->rssi < 0 ? -d1->rssi : d1->rssi; -	rssi2 = d2->rssi < 0 ? -d2->rssi : d2->rssi; - -	return rssi1 - rssi2; -} - -static int found_device_add(GSList **list, bdaddr_t *bdaddr, int8_t rssi, -			name_status_t name_status) -{ -	struct remote_dev_info *dev, match; -	GSList *l; - -	memset(&match, 0, sizeof(struct remote_dev_info)); -	bacpy(&match.bdaddr, bdaddr); -	match.name_status = NAME_ANY; - -	/* ignore repeated entries */ -	l = g_slist_find_custom(*list, &match, (GCompareFunc) found_device_cmp); -	if (l) { -		/* device found, update the attributes */ -		dev = l->data; - -		if (rssi != 0) -			dev->rssi = rssi; - -		 /* Get remote name can be received while inquiring. -		  * Keep in mind that multiple inquiry result events can -		  * be received from the same remote device. -		  */ -		if (name_status != NAME_NOT_REQUIRED) -			dev->name_status = name_status; - -		*list = g_slist_sort(*list, (GCompareFunc) dev_rssi_cmp); - -		return -EALREADY; -	} - -	dev = g_new0(struct remote_dev_info, 1); - -	bacpy(&dev->bdaddr, bdaddr); -	dev->rssi = rssi; -	dev->name_status = name_status; - -	*list = g_slist_insert_sorted(*list, dev, (GCompareFunc) dev_rssi_cmp); - -	return 0; -} - -static int found_device_remove(GSList **list, bdaddr_t *bdaddr) -{ -	struct remote_dev_info *dev, match; -	GSList *l; - -	memset(&match, 0, sizeof(struct remote_dev_info)); -	bacpy(&match.bdaddr, bdaddr); - -	l = g_slist_find_custom(*list, &match, (GCompareFunc) found_device_cmp); -	if (!l) -		return -1; - -	dev = l->data; -	*list = g_slist_remove(*list, dev); -	g_free(dev); - -	return 0; -} -  int active_conn_find_by_bdaddr(const void *data, const void *user_data)  {  	const struct active_conn_info *con = data; @@ -845,22 +754,16 @@ static int found_device_req_name(struct adapter *adapter)  	struct hci_request rq;  	evt_cmd_status rp;  	remote_name_req_cp cp; -	struct remote_dev_info match; -	GSList *l; +	struct remote_dev_info *dev, match;  	int dd, req_sent = 0;  	uint16_t dev_id = adapter_get_dev_id(adapter); -	/* get the next remote address */ -	if (!adapter->found_devices) -		return -ENODATA; -  	memset(&match, 0, sizeof(struct remote_dev_info));  	bacpy(&match.bdaddr, BDADDR_ANY);  	match.name_status = NAME_REQUIRED; -	l = g_slist_find_custom(adapter->found_devices, &match, -					(GCompareFunc) found_device_cmp); -	if (!l) +	dev = adapter_search_found_devices(adapter, &match); +	if (!dev)  		return -ENODATA;  	dd = hci_open_dev(dev_id); @@ -878,9 +781,7 @@ static int found_device_req_name(struct adapter *adapter)  	/* send at least one request or return failed if the list is empty */  	do { -		struct remote_dev_info *dev = l->data; - -		 /* flag to indicate the current remote name requested */ +		/* flag to indicate the current remote name requested */  		dev->name_status = NAME_REQUESTED;  		memset(&rp, 0, sizeof(rp)); @@ -902,14 +803,11 @@ static int found_device_req_name(struct adapter *adapter)  		/* if failed, request the next element */  		/* remove the element from the list */ -		adapter->found_devices = g_slist_remove(adapter->found_devices, dev); -		g_free(dev); +		adapter_remove_found_device(adapter, &dev->bdaddr);  		/* get the next element */ -		l = g_slist_find_custom(adapter->found_devices, &match, -					(GCompareFunc) found_device_cmp); - -	} while (l); +		dev = adapter_search_found_devices(adapter, &match); +	} while (dev);  	hci_close_dev(dd); @@ -919,25 +817,9 @@ static int found_device_req_name(struct adapter *adapter)  	return 0;  } -static void send_out_of_range(const char *path, GSList *l) -{ -	while (l) { -		const char *peer_addr = l->data; - -		g_dbus_emit_signal(connection, path, -				ADAPTER_INTERFACE, "DeviceDisappeared", -				DBUS_TYPE_STRING, &peer_addr, -				DBUS_TYPE_INVALID); - -		l = l->next; -	} -} -  void hcid_dbus_inquiry_complete(bdaddr_t *local)  {  	struct adapter *adapter; -	struct remote_dev_info *dev; -	bdaddr_t tmp;  	const gchar *path;  	int state; @@ -951,27 +833,8 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)  	/* Out of range verification */  	if ((adapter_get_state(adapter) & PERIODIC_INQUIRY) && -				!(adapter_get_state(adapter) & STD_INQUIRY)) { -		GSList *l; - -		send_out_of_range(path, adapter->oor_devices); - -		g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL); -		g_slist_free(adapter->oor_devices); -		adapter->oor_devices = NULL; - -		l = adapter->found_devices; -		while (l) { -			dev = l->data; -			baswap(&tmp, &dev->bdaddr); -			adapter->oor_devices = g_slist_append(adapter->oor_devices, -								batostr(&tmp)); -			l = l->next; -		} -	} - -	adapter->pinq_idle = 1; - +				!(adapter_get_state(adapter) & STD_INQUIRY)) +		adapter_update_oor_devices(adapter);  	/*  	 * Enable resolution again: standard inquiry can be  	 * received in the periodic inquiry idle state. @@ -1006,11 +869,6 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)  		adapter_set_state(adapter, state);  	} -	/* free discovered devices list */ -	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL); -	g_slist_free(adapter->found_devices); -	adapter->found_devices = NULL; -  	if (adapter->discov_requestor) {  		g_dbus_remove_watch(connection, adapter->discov_listener);  		adapter->discov_listener = 0; @@ -1094,11 +952,6 @@ void hcid_dbus_periodic_inquiry_exit(bdaddr_t *local, uint8_t status)  	state &= ~(PERIODIC_INQUIRY | RESOLVE_NAME);  	adapter_set_state(adapter, state); -	/* free discovered devices list */ -	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL); -	g_slist_free(adapter->found_devices); -	adapter->found_devices = NULL; -  	/* free out of range devices list */  	g_slist_foreach(adapter->oor_devices, (GFunc) free, NULL);  	g_slist_free(adapter->oor_devices); @@ -1208,10 +1061,9 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,  {  	char filename[PATH_MAX + 1];  	struct adapter *adapter; -	GSList *l;  	char local_addr[18], peer_addr[18], *name, *tmp_name;  	const char *paddr = peer_addr; -	struct remote_dev_info match; +	struct remote_dev_info *dev, match;  	dbus_int16_t tmp_rssi = rssi;  	uint8_t name_type = 0x00;  	name_status_t name_status; @@ -1242,29 +1094,16 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,  		state |= PERIODIC_INQUIRY;  		adapter_set_state(adapter, state);  	} - -	/* reset the idle flag when the inquiry complete event arrives */ -	if (adapter_get_state(adapter) & PERIODIC_INQUIRY) { -		adapter->pinq_idle = 0; -  		/* Out of range list update */ -		l = g_slist_find_custom(adapter->oor_devices, peer_addr, -				(GCompareFunc) strcmp); -		if (l) { -			char *dev = l->data; -			adapter->oor_devices = g_slist_remove(adapter->oor_devices, -								dev); -			g_free(dev); -		} -	} +	if (adapter_get_state(adapter) & PERIODIC_INQUIRY) +		adapter_remove_oor_device(adapter, peer_addr);  	memset(&match, 0, sizeof(struct remote_dev_info));  	bacpy(&match.bdaddr, peer);  	match.name_status = NAME_SENT;  	/* if found: don't send the name again */ -	l = g_slist_find_custom(adapter->found_devices, &match, -			(GCompareFunc) found_device_cmp); -	if (l) +	dev = adapter_search_found_devices(adapter, &match); +	if (dev)  		return;  	/* the inquiry result can be triggered by NON D-Bus client */ @@ -1317,7 +1156,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,  	}  	/* add in the list to track name sent/pending */ -	found_device_add(&adapter->found_devices, peer, rssi, name_status); +	adapter_add_found_device(adapter, peer, rssi, name_status);  }  void hcid_dbus_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class) @@ -1390,17 +1229,12 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,  	}  	/* remove from remote name request list */ -	found_device_remove(&adapter->found_devices, peer); +	adapter_remove_found_device(adapter, peer);  	/* check if there is more devices to request names */  	if (!found_device_req_name(adapter))  		return; /* skip if a new request has been sent */ -	/* free discovered devices list */ -	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL); -	g_slist_free(adapter->found_devices); -	adapter->found_devices = NULL; -  	/* The discovery completed signal must be sent only for discover  	 * devices request WITH name resolving */  	if (adapter->discov_requestor) { @@ -1942,7 +1776,6 @@ static int remote_name_cancel(int dd, bdaddr_t *dba, int to)  int cancel_discovery(struct adapter *adapter)  {  	struct remote_dev_info *dev, match; -	GSList *l;  	int dd, err = 0;  	uint16_t dev_id = adapter_get_dev_id(adapter);  	int state; @@ -1964,10 +1797,8 @@ int cancel_discovery(struct adapter *adapter)  	bacpy(&match.bdaddr, BDADDR_ANY);  	match.name_status = NAME_REQUESTED; -	l = g_slist_find_custom(adapter->found_devices, &match, -				(GCompareFunc) found_device_cmp); -	if (l) { -		dev = l->data; +	dev = adapter_search_found_devices(adapter, &match); +	if (dev) {  		if (remote_name_cancel(dd, &dev->bdaddr, 1000) < 0) {  			error("Read remote name cancel failed: %s, (%d)",  					strerror(errno), errno); @@ -1984,14 +1815,6 @@ int cancel_discovery(struct adapter *adapter)  	hci_close_dev(dd);  cleanup: -	/* -	 * Reset discov_requestor and discover_state in the remote name -	 * request event handler or in the inquiry complete handler. -	 */ -	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL); -	g_slist_free(adapter->found_devices); -	adapter->found_devices = NULL; -  	/* Disable name resolution for non D-Bus clients */  	if (!adapter->pdiscov_requestor) {  		state = adapter_get_state(adapter); @@ -2028,27 +1851,23 @@ static int periodic_inquiry_exit(int dd, int to)  int cancel_periodic_discovery(struct adapter *adapter)  {  	struct remote_dev_info *dev, match; -	GSList *l;  	int dd, err = 0;  	uint16_t dev_id = adapter_get_dev_id(adapter);  	if (!(adapter_get_state(adapter) & PERIODIC_INQUIRY)) -		goto cleanup; +		return err;  	dd = hci_open_dev(dev_id); -	if (dd < 0) { -		err = -ENODEV; -		goto cleanup; -	} +	if (dd < 0) +		return -ENODEV; +  	/* find the pending remote name request */  	memset(&match, 0, sizeof(struct remote_dev_info));  	bacpy(&match.bdaddr, BDADDR_ANY);  	match.name_status = NAME_REQUESTED; -	l = g_slist_find_custom(adapter->found_devices, &match, -			(GCompareFunc) found_device_cmp); -	if (l) { -		dev = l->data; +	dev = adapter_search_found_devices(adapter, &match); +	if (dev) {  		if (remote_name_cancel(dd, &dev->bdaddr, 1000) < 0) {  			error("Read remote name cancel failed: %s, (%d)",  					strerror(errno), errno); @@ -2066,15 +1885,6 @@ int cancel_periodic_discovery(struct adapter *adapter)  	hci_close_dev(dd); -cleanup: -	/* -	 * Reset pdiscov_requestor and pdiscov_active is done when the -	 * cmd complete event for exit periodic inquiry mode cmd arrives. -	 */ -	g_slist_foreach(adapter->found_devices, (GFunc) g_free, NULL); -	g_slist_free(adapter->found_devices); -	adapter->found_devices = NULL; -  	return err;  } diff --git a/src/dbus-hci.h b/src/dbus-hci.h index 621657d0..72b22741 100644 --- a/src/dbus-hci.h +++ b/src/dbus-hci.h @@ -55,8 +55,6 @@ int cancel_periodic_discovery(struct adapter *adapter);  int active_conn_find_by_bdaddr(const void *data, const void *user_data);  void bonding_request_free(struct bonding_request_info *dev); -int found_device_cmp(const struct remote_dev_info *d1, -			const struct remote_dev_info *d2);  int set_limited_discoverable(int dd, const uint8_t *cls, gboolean limited);  int set_service_classes(int dd, const uint8_t *cls, uint8_t value); | 
