diff options
| author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2006-09-05 14:23:02 +0000 | 
|---|---|---|
| committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2006-09-05 14:23:02 +0000 | 
| commit | adf984f0cb0829b4509fdbe8bb8e3ded9c7e496c (patch) | |
| tree | 5d285cdd198a53cd634f39cdfc5a69113570439a | |
| parent | 117091aff7a9416b9fe58214b8a9118cd88a9fb3 (diff) | |
Added DiscoverDevices request owner tracking
| -rw-r--r-- | hcid/dbus-adapter.c | 87 | ||||
| -rw-r--r-- | hcid/dbus.c | 100 | ||||
| -rw-r--r-- | hcid/dbus.h | 3 | 
3 files changed, 117 insertions, 73 deletions
| diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index 6a1573f3..dab3255f 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -2237,6 +2237,10 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D  	hci_close_dev(dd); +	/* track the request owner to cancel it automatically if the owner exits */ +	name_listener_add(conn, dbus_message_get_sender(msg), +				(name_cb_t) discover_devices_req_exit, dbus_data); +  	return send_reply_and_unref(conn, reply);  } @@ -2244,14 +2248,8 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D  {  	DBusMessage *reply = NULL;  	const char *requestor_name; -	struct discovered_dev_info *dev, match; -	struct slist *l; -	struct hci_request rq; -	remote_name_req_cancel_cp cp;  	struct hci_dbus_data *dbus_data = data; -	uint8_t status = 0x00; -	int dd = -1; -	DBusHandlerResult ret_val =  DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +	int err;  	if (!dbus_data->up)  		return error_not_ready(conn, msg); @@ -2270,74 +2268,21 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D  	if (!dbus_data->discovery_requestor ||  			strcmp(dbus_data->discovery_requestor, requestor_name))  		return error_not_authorized(conn, msg); +	/*  +	 * Cleanup the discovered devices list and send the cmd +	 * to cancel inquiry or cancel remote name request +	 */ +	err = cancel_discovery(dbus_data); +	if (err < 0) { +		if (err == -ENODEV) +			return error_no_such_adapter(conn, msg); +		else +			return error_failed(conn, msg, -err); -	dd = hci_open_dev(dbus_data->dev_id); -	if (dd < 0) -		return error_no_such_adapter(conn, msg); - -	memset(&rq, 0, sizeof(rq)); -	memset(&cp, 0, sizeof(cp)); - -	rq.ogf    = OGF_LINK_CTL; - -	rq.rparam = &status; -	rq.rlen   = sizeof(status); -	rq.event = EVT_CMD_COMPLETE; - -	switch (dbus_data->discover_state) { -	case STATE_RESOLVING_NAMES: -		/* find the pending remote name request */ -		memset(&match, 0, sizeof(struct discovered_dev_info)); -		bacpy(&match.bdaddr, BDADDR_ANY); -		match.name_status = NAME_REQUESTED; -		match.discover_type = RESOLVE_NAME; - -		l = slist_find(dbus_data->disc_devices, &match, (cmp_func_t) disc_device_find); -		if (!l) -			goto done; /* no request pending */ - -		dev = l->data; - -		bacpy(&cp.bdaddr, &dev->bdaddr); - -		rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL; -		rq.cparam = &cp; -		rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE; -		break; -	default: /* STATE_DISCOVER */ -		rq.ocf = OCF_INQUIRY_CANCEL; -		break; -	} - -	if (hci_send_req(dd, &rq, 100) < 0) { -		error("Sending command failed: %s (%d)", strerror(errno), errno); -		ret_val = error_failed(conn, msg, errno); -		goto cleanup; -	} - -	if (status) { -		error("Cancel failed with status 0x%02x", status); -		ret_val = error_failed(conn, msg, bt_error(status)); -		goto cleanup;  	} -done:  	reply = dbus_message_new_method_return(msg); -	ret_val = send_reply_and_unref(conn, reply); - -cleanup: -	/* -	 * Reset discovery_requestor and discover_state in the remote name -	 * request event handler or in the inquiry complete handler. -	 */ -	slist_foreach(dbus_data->disc_devices, (slist_func_t) free, NULL); -	slist_free(dbus_data->disc_devices); -	dbus_data->disc_devices = NULL; - -	if (dd >= 0) -		hci_close_dev(dd); - -	return ret_val; +	return send_reply_and_unref(conn, reply);  }  const char *major_class_str(uint32_t class) diff --git a/hcid/dbus.c b/hcid/dbus.c index f82845d3..f3333e6d 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -85,7 +85,7 @@ void bonding_request_free(struct bonding_request_info *dev )  	}  } -int disc_device_find(const struct discovered_dev_info *d1, const struct discovered_dev_info *d2) +static int disc_device_find(const struct discovered_dev_info *d1, const struct discovered_dev_info *d2)  {  	int ret; @@ -406,6 +406,8 @@ static int unregister_dbus_path(const char *path)  		release_passkey_agents(pdata, NULL);  		if (pdata->discovery_requestor) { +			name_listener_remove(connection, pdata->discovery_requestor, +						(name_cb_t) discover_devices_req_exit, pdata);  			free(pdata->discovery_requestor);  			pdata->discovery_requestor = NULL;  		} @@ -648,6 +650,8 @@ int hcid_dbus_stop_device(uint16_t id)  	release_passkey_agents(pdata, NULL);  	if (pdata->discovery_requestor) { +		name_listener_remove(connection, pdata->discovery_requestor, +					(name_cb_t) discover_devices_req_exit, pdata);  		free(pdata->discovery_requestor);  		pdata->discovery_requestor = NULL;  	} @@ -999,6 +1003,8 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)  	pdata->disc_devices = NULL;  	if (pdata->discovery_requestor) { +		name_listener_remove(connection, pdata->discovery_requestor, +					(name_cb_t) discover_devices_req_exit, pdata);  		free(pdata->discovery_requestor);  		pdata->discovery_requestor = NULL;  	} @@ -1189,6 +1195,8 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char  		send_reply_and_unref(connection, message);  		if (pdata->discovery_requestor) { +			name_listener_remove(connection, pdata->discovery_requestor, +						(name_cb_t) discover_devices_req_exit, pdata);  			free(pdata->discovery_requestor);  			pdata->discovery_requestor = NULL;  		} @@ -2028,3 +2036,93 @@ void create_bond_req_exit(const char *name, struct hci_dbus_data *pdata)  	bonding_request_free(pdata->bonding);  	pdata->bonding = NULL;  } + +void discover_devices_req_exit(const char *name, struct hci_dbus_data *pdata) +{ +	debug("DiscoverDevices requestor at %s exited before the operation finishes", name); + +	/*  +	 * Cleanup the discovered devices list and send the cmd to cancel inquiry +	 * or cancel remote name request. The return value can be ignored. +	 */ +	cancel_discovery(pdata); +} + +int cancel_discovery(struct hci_dbus_data *pdata) +{ +	struct discovered_dev_info *dev, match; +	struct slist *l; +	struct hci_request rq; +	remote_name_req_cancel_cp cp; +	int dd = -1, err = 0; +	uint8_t status = 0x00; + +	dd = hci_open_dev(pdata->dev_id); +	if (dd < 0) { +		err = -ENODEV; +		goto cleanup; +	} + +	memset(&rq, 0, sizeof(rq)); +	memset(&cp, 0, sizeof(cp)); + +	rq.ogf    = OGF_LINK_CTL; + +	rq.rparam = &status; +	rq.rlen   = sizeof(status); +	rq.event = EVT_CMD_COMPLETE; + +	switch (pdata->discover_state) { +	case STATE_RESOLVING_NAMES: +		/* find the pending remote name request */ +		memset(&match, 0, sizeof(struct discovered_dev_info)); +		bacpy(&match.bdaddr, BDADDR_ANY); +		match.name_status = NAME_REQUESTED; +		match.discover_type = RESOLVE_NAME; + +		l = slist_find(pdata->disc_devices, &match, (cmp_func_t) disc_device_find); +		if (!l) +			goto cleanup; /* no request pending */ + +		dev = l->data; + +		bacpy(&cp.bdaddr, &dev->bdaddr); + +		rq.ocf = OCF_REMOTE_NAME_REQ_CANCEL; +		rq.cparam = &cp; +		rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE; +		break; +	case STATE_DISCOVER: +		rq.ocf = OCF_INQUIRY_CANCEL; +		break; +	default: +		/* discover is not pending */ +		goto cleanup; +	} + +	if (hci_send_req(dd, &rq, 100) < 0) { +		error("Sending command failed: %s (%d)", strerror(errno), errno); +		err = -errno; +		goto cleanup; +	} + +	if (status) { +		error("Cancel failed with status 0x%02x", status); +		err = -bt_error(status); +		goto cleanup; +	} + +cleanup: +	/* +	 * Reset discovery_requestor and discover_state in the remote name +	 * request event handler or in the inquiry complete handler. +	 */ +	slist_foreach(pdata->disc_devices, (slist_func_t) free, NULL); +	slist_free(pdata->disc_devices); +	pdata->disc_devices = NULL; + +	if (dd >= 0) +		hci_close_dev(dd); + +	return err; +} diff --git a/hcid/dbus.h b/hcid/dbus.h index ecaf008b..3a3bd62e 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -205,6 +205,8 @@ DBusHandlerResult simple_introspect(DBusConnection *conn, DBusMessage *msg, void  service_handler_func_t find_service_handler(struct service_data *services, DBusMessage *msg);  void create_bond_req_exit(const char *name, struct hci_dbus_data *pdata); +void discover_devices_req_exit(const char *name, struct hci_dbus_data *pdata); +int cancel_discovery(struct hci_dbus_data *pdata);  int handle_passkey_request(DBusConnection *conn, int dev, const char *path, bdaddr_t *sba, bdaddr_t *dba);  void release_default_agent(void); @@ -226,7 +228,6 @@ int active_conn_find_by_bdaddr(const void *data, const void *user_data);  void bonding_request_free(struct bonding_request_info *dev);  int pending_bonding_cmp(const void *p1, const void *p2);  int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name_status, int discover_type); -int disc_device_find(const struct discovered_dev_info *d1, const struct discovered_dev_info *d2);  int disc_device_req_name(struct hci_dbus_data *dbus_data);  int discoverable_timeout_handler(void *data); | 
