diff options
| author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2006-03-23 21:03:31 +0000 | 
|---|---|---|
| committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2006-03-23 21:03:31 +0000 | 
| commit | 923976d833265decd9a3dd2b3aa7fca7c843c93a (patch) | |
| tree | 38bf2e1fb11fe3b8389c3670f068ab6940c32f36 | |
| parent | b7fb0f9b9054c138a82e0843a8c82f550c6922eb (diff) | |
Removed create bonding queue, disconnect after the bonding finishes and code cleanup
| -rw-r--r-- | hcid/dbus-adapter.c | 251 | ||||
| -rw-r--r-- | hcid/dbus.c | 189 | ||||
| -rw-r--r-- | hcid/dbus.h | 31 | 
3 files changed, 217 insertions, 254 deletions
| diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index e3484c88..ad1d12c1 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -112,35 +112,21 @@ static int check_address(const char *addr)  	return 0;  } -int active_conn_find_by_bdaddr(const void *data, const void *user_data) +static struct bonding_request_info *bonding_request_new(bdaddr_t *peer)  { -	const struct active_conn_info *con = data; -	const bdaddr_t *bdaddr = user_data; - -	if (memcmp(con->bdaddr, bdaddr, sizeof(*bdaddr)) == 0) -		return 0; - -	return -1; -} - -static int bonding_requests_append(struct slist **list, bdaddr_t *bdaddr, DBusMessage *msg, int disconnect) -{ -	struct bonding_request_info *dev; - -	dev = malloc(sizeof(*dev)); +	struct bonding_request_info *bonding; +	 +	bonding = malloc(sizeof(*bonding)); -	if (!dev) -		return -1; +	if (!bonding) +		return NULL; -	memset(dev, 0, sizeof(*dev)); -	dev->bdaddr = malloc(sizeof(*dev->bdaddr)); -	bacpy(dev->bdaddr, bdaddr); -	dev->req_msg = msg; -	dev->disconnect = disconnect; +	memset(bonding, 0, sizeof(*bonding)); -	*list = slist_append(*list, dev); +	bonding->bdaddr = malloc(sizeof(*bonding->bdaddr)); +	bacpy(bonding->bdaddr, peer); -	return 0; +	return bonding;  }  static DBusHandlerResult handle_dev_get_address_req(DBusConnection *conn, DBusMessage *msg, void *data) @@ -974,9 +960,14 @@ static DBusHandlerResult handle_dev_get_remote_name_req(DBusConnection *conn, DB  	str2ba(peer_addr, &peer_bdaddr);  	disc_device_append(&dbus_data->disc_devices, &peer_bdaddr, NAME_PENDING); -	/* check if there is a discover process running */ -	if (dbus_data->discover_state == DISCOVER_OFF) -		disc_device_req_name(dbus_data); +	/*  +	 * if there is a discover process running, just queue the request. +	 * Otherwise, send the HCI cmd to get the remote name +	 */ +	if (dbus_data->discover_state == STATE_IDLE) { +		if (!disc_device_req_name(dbus_data)) +			dbus_data->discover_state = STATE_RESOLVING_NAMES; +	}  	return error_request_deferred(conn, msg);  } @@ -1232,8 +1223,7 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu  	char *peer_addr = NULL;  	char *str;  	struct hci_dbus_data *dbus_data = data; -	struct slist *lbon; -	struct slist *lconn; +	struct slist *l;  	bdaddr_t peer_bdaddr;  	int dd, ecode, disconnect; @@ -1254,12 +1244,11 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu  	str2ba(peer_addr, &peer_bdaddr);  	/* check if there is a pending bonding request */ -	lbon = slist_find(dbus_data->bonding_requests, &peer_bdaddr, bonding_requests_find); - -	if (lbon) +	if (dbus_data->bonding)  		return error_bonding_in_progress(conn, msg); -	if (dbus_data->requestor_name) +	/* check if there is a pending discover */ +	if (dbus_data->discover_state != STATE_IDLE || dbus_data->requestor_name)  		return error_discover_in_progress(conn, msg);   	ecode = get_device_address(dbus_data->dev_id, local_addr, sizeof(local_addr)); @@ -1296,9 +1285,9 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu  	rq.rlen = EVT_CMD_STATUS_SIZE;  	/* check if there is an active connection */ -	lconn = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr); +	l = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr); -	if (!lconn) { +	if (!l) {  		memset(&cc_cp, 0, sizeof(cc_cp));  		/* create a new connection */  		bacpy(&cc_cp.bdaddr, &peer_bdaddr); @@ -1312,12 +1301,11 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu  		rq.clen   = CREATE_CONN_CP_SIZE;  		disconnect = 1;  	} else { -		struct active_conn_info *dev = lconn->data; +		struct active_conn_info *dev = l->data; +  		memset(&ar_cp, 0, sizeof(ar_cp)); -		/* active connection found */  		ar_cp.handle = dev->handle; -  		rq.ocf    = OCF_AUTH_REQUESTED;  		rq.cparam = &ar_cp;  		rq.clen   = AUTH_REQUESTED_CP_SIZE; @@ -1337,9 +1325,11 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu  		return error_failed(conn, msg, bt_error(rp.status));  	} -	/* add in the bonding requests list */ -	bonding_requests_append(&dbus_data->bonding_requests, &peer_bdaddr, -					dbus_message_ref(msg), disconnect); +	dbus_data->bonding = bonding_request_new(&peer_bdaddr); +	dbus_data->bonding->disconnect = disconnect; +	dbus_data->bonding->rq = dbus_message_ref(msg); + +	dbus_data->requestor_name = strdup(dbus_message_get_sender(msg));  	hci_close_dev(dd); @@ -1349,14 +1339,8 @@ static DBusHandlerResult handle_dev_create_bonding_req(DBusConnection *conn, DBu  static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBusMessage *msg, void *data)  {  	struct hci_dbus_data *dbus_data = data; -	struct bonding_request_info *dev; -	struct slist *lconn; -	struct slist *lbon; +	struct slist *l;  	DBusMessage *reply = NULL; -	struct hci_request rq; -	create_conn_cancel_cp cc_cp; -	disconnect_cp dc_cp; -	evt_cmd_status rp;  	DBusError err;  	bdaddr_t peer_bdaddr;  	const char *peer_addr; @@ -1376,43 +1360,60 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu  	if (check_address(peer_addr) < 0)  		return error_invalid_arguments(conn, msg); -	/* FIXME: check authorization */ -  	str2ba(peer_addr, &peer_bdaddr);  	/* check if there is a pending bonding request */ -	lbon = slist_find(dbus_data->bonding_requests, &peer_bdaddr, bonding_requests_find); - -	if (!lbon) { +	if ((!dbus_data->bonding) || +	    	(memcmp(dbus_data->bonding->bdaddr, &peer_bdaddr, sizeof(bdaddr_t)))) {  		error("No bonding request pending.");  		return error_unknown_address(conn, msg);  	} -	lconn = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr); - -	dev = lbon->data; +	if (strcmp(dbus_data->requestor_name, dbus_message_get_sender(msg))) +		return error_not_authorized(conn, msg);  	dd = hci_open_dev(dbus_data->dev_id);  	if (dd < 0)  		return error_no_such_adapter(conn, msg); -	memset(&rq, 0, sizeof(rq)); -	rq.ogf    = OGF_LINK_CTL; -	rq.rparam  = &rp; -	rq.rlen    = EVT_CMD_STATUS_SIZE; -	rq.event   = EVT_CMD_STATUS; +	l = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr); -	if (!lconn) { +	if (!l) {  		/* connection request is pending */ -		memset(&cc_cp, 0, sizeof(cc_cp)); -		bacpy(&cc_cp.bdaddr, dev->bdaddr); -		rq.ocf    = OCF_CREATE_CONN_CANCEL; -		rq.cparam = &cc_cp; -		rq.clen   = CREATE_CONN_CANCEL_CP_SIZE; +		struct hci_request rq; +		create_conn_cancel_cp cp; +		evt_cmd_status rp; -		dev->cancel_msg = dbus_message_ref(msg); +		memset(&rq, 0, sizeof(rq)); +		memset(&cp, 0, sizeof(cp)); +		memset(&rp, 0, sizeof(rp)); + +		bacpy(&cp.bdaddr, dbus_data->bonding->bdaddr); + +		rq.ogf     = OGF_LINK_CTL; +		rq.ocf     = OCF_CREATE_CONN_CANCEL; +		rq.rparam  = &rp; +		rq.rlen    = EVT_CMD_STATUS_SIZE; +		rq.event   = EVT_CMD_STATUS; +		rq.cparam  = &cp; +		rq.clen    = CREATE_CONN_CANCEL_CP_SIZE; + +		if (hci_send_req(dd, &rq, 100) < 0) { +			error("Cancel bonding - unable to send the HCI request: %s (%d)", +			      strerror(errno), errno); +			hci_close_dev(dd); +			return error_failed(conn, msg, errno); +		} + +		if (rp.status) { +			error("Cancel bonding - Failed with status 0x%02x", rp.status); +			hci_close_dev(dd); +			return error_failed(conn, msg, bt_error(rp.status)); +		} + +		dbus_data->bonding->cancel = dbus_message_ref(msg);  	} else { -		struct active_conn_info *cinfo = lconn->data; +		struct active_conn_info *cinfo = l->data;  		/* FIXME: if waiting remote PIN, which HCI cmd must be sent? */  		/* reply to cancel bonding */ @@ -1420,36 +1421,16 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu  		send_reply_and_unref(conn, reply);  		/* Reply to the create bonding request */ -		error_authentication_canceled(conn, dev->req_msg); - -		dbus_data->bonding_requests = slist_remove(dbus_data->bonding_requests, dev); -		bonding_request_info_free(dev, NULL); +		error_authentication_canceled(conn, dbus_data->bonding->rq);  		/* disconnect from the remote device */ +		if (dbus_data->bonding->disconnect) { +			if (hci_disconnect(dd, htobs(cinfo->handle), HCI_OE_USER_ENDED_CONNECTION, 1000) < 0) +				error("Disconnect failed"); +		} -		/* FIXME: send the disconnect if the connection was created by a create  -		 * bonding procedure only. Otherwise, keep the connection active. -		 */  -		memset(&dc_cp, 0, sizeof(dc_cp)); -		dc_cp.handle = cinfo->handle; -		dc_cp.reason = 0x05; -		rq.ocf       = OCF_DISCONNECT; -		rq.cparam    = &dc_cp; -		rq.clen      = DISCONNECT_CP_SIZE; -	} - -	if (hci_send_req(dd, &rq, 100) < 0) { - -		error("Cancel bonding - unable to send the HCI request: %s (%d)", -		      strerror(errno), errno); -		hci_close_dev(dd); -		return error_failed(conn, msg, errno); -	} - -	if (rp.status) { -		error("Cancel bonding - Failed with status 0x%02x", rp.status); -		hci_close_dev(dd); -		return error_failed(conn, msg, bt_error(rp.status)); +		bonding_request_free(dbus_data->bonding); +		dbus_data->bonding = NULL;  	}  	hci_close_dev(dd); @@ -1459,13 +1440,13 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu  static DBusHandlerResult handle_dev_remove_bonding_req(DBusConnection *conn, DBusMessage *msg, void *data)  {  	struct hci_dbus_data *dbus_data = data; +	struct slist *l;  	DBusConnection *connection = get_dbus_connection();  	DBusMessage *reply;  	DBusMessage *signal;  	DBusError err;  	char filename[PATH_MAX + 1];  	char addr[18], *addr_ptr; -	struct hci_conn_info_req *cr;  	bdaddr_t bdaddr;  	int dd; @@ -1500,29 +1481,16 @@ static DBusHandlerResult handle_dev_remove_bonding_req(DBusConnection *conn, DBu  	/* Delete the link key from the Bluetooth chip */  	hci_delete_stored_link_key(dd, &bdaddr, 0, 1000); -	/* Close active connections for the remote device */ -	cr = malloc(sizeof(*cr) + sizeof(struct hci_conn_info)); -	if (!cr) { -		error("Can't allocate memory"); -		hci_close_dev(dd); -		return error_out_of_memory(conn, msg); -	} - -	bacpy(&cr->bdaddr, &bdaddr); -	cr->type = ACL_LINK; -	if (ioctl(dd, HCIGETCONNINFO, (unsigned long) cr) < 0) { -		/* Ignore when there isn't active connections, return success */ -		hci_close_dev(dd); -		free(cr); -		return send_reply_and_unref(conn, dbus_message_new_method_return(msg)); -	} - -	/* Send the HCI disconnect command */ -	if (hci_disconnect(dd, htobs(cr->conn_info->handle), HCI_OE_USER_ENDED_CONNECTION, 1000) < 0) { -		error("Disconnect failed"); -		free(cr); -		hci_close_dev(dd); -		return error_failed(conn, msg, errno); +	/* find the connection */ +	l = slist_find(dbus_data->active_conn, &bdaddr, active_conn_find_by_bdaddr); +	if (l) { +		struct active_conn_info *con = l->data; +		/* Send the HCI disconnect command */ +		if (hci_disconnect(dd, htobs(con->handle), HCI_OE_USER_ENDED_CONNECTION, 1000) < 0) { +			error("Disconnect failed"); +			hci_close_dev(dd); +			return error_failed(conn, msg, errno); +		}  	}  	/* FIXME: which condition must be verified before send the signal */ @@ -1537,8 +1505,6 @@ static DBusHandlerResult handle_dev_remove_bonding_req(DBusConnection *conn, DBu  	reply = dbus_message_new_method_return(msg); -	free(cr); -  	hci_close_dev(dd);  	return send_reply_and_unref(conn, reply); @@ -1715,7 +1681,6 @@ static DBusHandlerResult handle_dev_get_encryption_key_size_req(DBusConnection *  static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, DBusMessage *msg, void *data)  {  	DBusMessage *reply = NULL; -	const char *requestor_name;  	const char *method;  	inquiry_cp cp;  	evt_cmd_status rp; @@ -1725,15 +1690,12 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D  	uint32_t lap = 0x9e8b33;  	int dd; -	if (dbus_data->requestor_name) +	if (dbus_data->discover_state != STATE_IDLE)  		return error_discover_in_progress(conn, msg); -	method = dbus_message_get_member(msg); -	if (strcmp("DiscoverDevicesWithoutNameResolving", method) == 0) -		dbus_data->discover_state = DISCOVER_RUNNING; -	else  -		dbus_data->discover_state = DISCOVER_RUNNING_WITH_NAMES; -		 +	if (dbus_data->bonding) +		return error_bonding_in_progress(conn, msg); +  	dd = hci_open_dev(dbus_data->dev_id);  	if (dd < 0)  		return error_no_such_adapter(conn, msg); @@ -1757,7 +1719,6 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D  	if (hci_send_req(dd, &rq, 100) < 0) {  		error("Unable to start inquiry: %s (%d)",  							strerror(errno), errno); -		dbus_data->discover_state = DISCOVER_OFF;  		hci_close_dev(dd);  		return error_failed(conn, msg, errno);  	} @@ -1768,8 +1729,13 @@ static DBusHandlerResult handle_dev_discover_devices_req(DBusConnection *conn, D  		return error_failed(conn, msg, bt_error(rp.status));  	} -	requestor_name = dbus_message_get_sender(msg); -	dbus_data->requestor_name = strdup(requestor_name); +	method = dbus_message_get_member(msg); +	if (strcmp("DiscoverDevicesWithoutNameResolving", method) == 0) +		dbus_data->discover_type = WITHOUT_NAME_RESOLVING; +	else  +		dbus_data->discover_type = RESOLVE_NAMES; +		 +	dbus_data->requestor_name = strdup(dbus_message_get_sender(msg));  	reply = dbus_message_new_method_return(msg); @@ -1792,8 +1758,9 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D  	requestor_name = dbus_message_get_sender(msg);  	/* is there discover pending? */ -	if (!dbus_data->requestor_name) -		return error_not_authorized(conn, msg); +	if (dbus_data->discover_state != STATE_DISCOVER && +	    	dbus_data->discover_state != STATE_RESOLVING_NAMES) +		return error_not_authorized(conn, msg); /* FIXME: find a better error name */  	/* only the discover requestor can cancel the inquiry process */  	if (strcmp(dbus_data->requestor_name, requestor_name)) @@ -1810,9 +1777,7 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D  	rq.rlen   = sizeof(status);  	switch (dbus_data->discover_state) { -	case DISCOVER_OFF: -		goto failed; -	case RESOLVING_NAMES: +	case STATE_RESOLVING_NAMES:  		/* get the first element */  		dev = (struct discovered_dev_info *) (dbus_data->disc_devices)->data; @@ -1823,8 +1788,7 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D  		rq.clen = REMOTE_NAME_REQ_CANCEL_CP_SIZE;  		rq.event = EVT_CMD_STATUS;  		break; -	case DISCOVER_RUNNING: -	case DISCOVER_RUNNING_WITH_NAMES: +	default: /* STATE_DISCOVER */  		rq.ocf = OCF_INQUIRY_CANCEL;  		break;  	} @@ -1843,13 +1807,14 @@ static DBusHandlerResult handle_dev_cancel_discovery_req(DBusConnection *conn, D  		return error_failed(conn, msg, bt_error(status));  	} -failed:  	slist_foreach(dbus_data->disc_devices, disc_device_info_free, NULL);  	slist_free(dbus_data->disc_devices);  	dbus_data->disc_devices = NULL; -	free(dbus_data->requestor_name); -	dbus_data->requestor_name = NULL; +	if (dbus_data->requestor_name) { +		free(dbus_data->requestor_name); +		dbus_data->requestor_name = NULL; +	}  	reply = dbus_message_new_method_return(msg); diff --git a/hcid/dbus.c b/hcid/dbus.c index b9525ae1..f58697e2 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -108,16 +108,14 @@ void disc_device_info_free(void *data, void *user_data)  	}  } -void bonding_request_info_free(void *data, void *user_data) +void bonding_request_free(struct bonding_request_info *dev )  { -	struct bonding_request_info *dev = data; -  	if (dev) {  		free(dev->bdaddr); -		if (dev->req_msg) -			dbus_message_unref(dev->req_msg); -		if (dev->cancel_msg) -			dbus_message_unref(dev->cancel_msg); +		if (dev->rq) +			dbus_message_unref(dev->rq); +		if (dev->cancel) +			dbus_message_unref(dev->cancel);  		free(dev);  	}  } @@ -132,18 +130,7 @@ static void active_conn_info_free(void *data, void *user_data)  	}  } -int bonding_requests_find(const void *data, const void *user_data) -{ -	const struct bonding_request_info *dev = data; -	const bdaddr_t *bdaddr = user_data; - -	if (memcmp(dev->bdaddr, bdaddr, sizeof(*bdaddr)) == 0) -		return 0; - -	return -1; -} - -int disc_device_find_by_bdaddr(const void *data, const void *user_data) +static int disc_device_find_by_bdaddr(const void *data, const void *user_data)  {  	const struct discovered_dev_info *dev = data;  	const bdaddr_t *bdaddr = user_data; @@ -212,6 +199,17 @@ static int disc_device_remove(struct slist **list, bdaddr_t *bdaddr)  	return ret_val;  } +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; + +	if (memcmp(con->bdaddr, bdaddr, sizeof(*bdaddr)) == 0) +		return 0; + +	return -1; +} +  static int active_conn_find_by_handle(const void *data, const void *user_data)  {  	const struct active_conn_info *dev = data; @@ -442,10 +440,9 @@ static gboolean unregister_dbus_path(const char *path)  			pdata->disc_devices = NULL;  		} -		if (pdata->bonding_requests) { -			slist_foreach(pdata->bonding_requests, bonding_request_info_free, NULL); -			slist_free(pdata->bonding_requests); -			pdata->bonding_requests = NULL; +		if (pdata->bonding) { +			bonding_request_free(pdata->bonding); +			pdata->bonding = NULL;  		}  		if (pdata->active_conn) { @@ -632,8 +629,6 @@ void hcid_dbus_bonding_created_complete(bdaddr_t *local, bdaddr_t *peer, const u  	struct hci_dbus_data *pdata;  	DBusMessage *msg_reply = NULL;  	DBusMessage *msg_signal = NULL; -	struct bonding_request_info *dev = NULL;  -	struct slist *l;  	char *local_addr, *peer_addr;  	const char *name;  	bdaddr_t tmp; @@ -681,23 +676,36 @@ void hcid_dbus_bonding_created_complete(bdaddr_t *local, bdaddr_t *peer, const u  		goto failed;  	} -	l = slist_find(pdata->bonding_requests, peer, bonding_requests_find); - -	if (!l) -		goto failed; - -	dev = l->data; +	if (!pdata->bonding) +		goto failed; /* skip: no bonding req pending */ -	msg_reply = dbus_msg_new_authentication_return(dev->req_msg, status); +	msg_reply = dbus_msg_new_authentication_return(pdata->bonding->rq, status);  	if (dbus_connection_send(connection, msg_reply, NULL) == FALSE) {  		error("Can't send D-Bus reply for create bonding request");  		goto failed;  	}  	/* FIXME: disconnect if required */ +	if (pdata->bonding->disconnect) { +		struct slist *l; + +		l = slist_find(pdata->active_conn, peer, active_conn_find_by_bdaddr); +		if (l) { +			struct active_conn_info *con = l->data; +			int dd = hci_open_dev(pdata->dev_id); +			/* Send the HCI disconnect command */ +			if (hci_disconnect(dd, con->handle, HCI_OE_USER_ENDED_CONNECTION, 100) < 0) { +				error("Disconnect failed"); +			} +			hci_close_dev(dd); +		} +	} + +	bonding_request_free(pdata->bonding); +	pdata->bonding = NULL; -	pdata->bonding_requests = slist_remove(pdata->bonding_requests, dev); -	bonding_request_info_free(dev, NULL); +	free(pdata->requestor_name); +	pdata->requestor_name = NULL;  failed:  	if (msg_signal) @@ -720,10 +728,8 @@ void hcid_dbus_create_conn_cancel(bdaddr_t *local, void *ptr)  	char path[MAX_PATH_LENGTH];  	bdaddr_t tmp;  	ret_param_conn_cancel *ret = ptr + sizeof(evt_cmd_complete); -	struct bonding_request_info *dev = NULL;  	DBusMessage *reply;  	char *local_addr, *peer_addr; -	struct slist *l;  	struct hci_dbus_data *pdata;  	int id; @@ -742,24 +748,20 @@ void hcid_dbus_create_conn_cancel(bdaddr_t *local, void *ptr)  		goto failed;  	} -	l = slist_find(pdata->bonding_requests, &ret->bdaddr, bonding_requests_find); - -	if (!l) +	if (!pdata->bonding)  		goto failed; -	dev = l->data; - +	if (memcmp(pdata->bonding->bdaddr, &ret->bdaddr, sizeof(bdaddr_t))) +		goto failed; +	  	if (!ret->status) { -		reply = dbus_message_new_method_return(dev->cancel_msg); +		reply = dbus_message_new_method_return(pdata->bonding->cancel);  		send_reply_and_unref(connection, reply);  	} else -		error_failed(connection, dev->cancel_msg, bt_error(ret->status));	 +		error_failed(connection, pdata->bonding->cancel, bt_error(ret->status));	 -	dbus_message_unref(dev->cancel_msg); -	dev->cancel_msg = NULL; -	/* Don't remove from the list. It will be necessary  -	 * to return the reply for create bonding request -	 */ +	dbus_message_unref(pdata->bonding->cancel); +	pdata->bonding->cancel = NULL;  failed:  	bt_free(local_addr); @@ -768,6 +770,7 @@ failed:  void hcid_dbus_inquiry_start(bdaddr_t *local)  { +	struct hci_dbus_data *pdata;  	DBusMessage *message = NULL;  	char path[MAX_PATH_LENGTH];  	char *local_addr; @@ -784,6 +787,9 @@ void hcid_dbus_inquiry_start(bdaddr_t *local)  	snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id); +	if (dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) +		pdata->discover_state = STATE_DISCOVER; +  	message = dbus_message_new_signal(path, ADAPTER_INTERFACE,  						"DiscoveryStarted");  	if (message == NULL) { @@ -919,12 +925,14 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)  	snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id);  	if (dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) { -		if (!disc_device_req_name(pdata)) { -			pdata->discover_state = RESOLVING_NAMES; -			goto failed; /* skip - there is name to resolve */ -		} -		pdata->discover_state = DISCOVER_OFF; +		if (pdata->discover_type == RESOLVE_NAMES) { +			if (!disc_device_req_name(pdata)) { +				pdata->discover_state = STATE_RESOLVING_NAMES; +				goto failed; /* skip - there is name to resolve */ +			} +		} +		pdata->discover_state = STATE_IDLE;  		/* free discovered devices list */  		slist_foreach(pdata->disc_devices, disc_device_info_free, NULL); @@ -1063,26 +1071,13 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class, i  		free(name);  		name_status = NAME_SENT; - -		/* -		 * Add in the discovered devices list to avoid -		 * multiple remote name update signals -		 */ -		switch (pdata->discover_state) { -		    case DISCOVER_RUNNING_WITH_NAMES: -		    case DISCOVER_RUNNING: -			    disc_device_append(&pdata->disc_devices, peer, name_status); -			    break; -		    default: /* ignore */ -			    break; -		} +	}  +	/* queue only results triggered by D-Bus clients */ +	if (pdata->requestor_name) +		disc_device_append(&pdata->disc_devices, peer, name_status); -	} else { -		/* check if the remote name needs be requested */ -		if (pdata->discover_state == DISCOVER_RUNNING_WITH_NAMES) -			disc_device_append(&pdata->disc_devices, peer, name_status); -	} +	disc_device_append(&pdata->disc_devices, peer, name_status);  failed:  	if (signal_device) @@ -1133,12 +1128,14 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char  	if (!disc_device_req_name(pdata))  		goto failed; /* skip if a new request has been sent */ +	pdata->discover_state = STATE_IDLE; +  	/* free discovered devices list */  	slist_foreach(pdata->disc_devices, disc_device_info_free, NULL);  	slist_free(pdata->disc_devices);  	pdata->disc_devices = NULL; -	if (pdata->discover_state != DISCOVER_OFF) { +	if (pdata->discover_type == RESOLVE_NAMES) {  		message = dbus_message_new_signal(path, ADAPTER_INTERFACE,  						  "DiscoveryCompleted"); @@ -1148,8 +1145,6 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, char  			free(pdata->requestor_name);  			pdata->requestor_name = NULL;  		} - -		pdata->discover_state = DISCOVER_OFF;  	}  failed: @@ -1165,8 +1160,6 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b  	evt_cmd_status rp;  	auth_requested_cp cp;  	struct hci_dbus_data *pdata = NULL; -	const struct slist *l; -	struct bonding_request_info *dev = NULL;  	char *local_addr, *peer_addr;  	bdaddr_t tmp;  	int dd = -1, id; @@ -1177,14 +1170,14 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b  	id = hci_devid(local_addr);  	if (id < 0) {  		error("No matching device id for %s", local_addr); -		goto failed; +		goto done;  	}  	snprintf(path, sizeof(path), "%s/hci%d", ADAPTER_PATH, id);  	if (!dbus_connection_get_object_path_data(connection, path, (void *) &pdata)) {  		error("Getting %s path data failed!", path); -		goto failed; +		goto done;  	}  	if (!status) { @@ -1202,21 +1195,21 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b  	}  	/* check if this connection request was requested by a bonding procedure */ -	l = slist_find(pdata->bonding_requests, peer, bonding_requests_find); -	if (!l)  -		goto failed; +	if (!pdata->bonding) +		goto done; /* skip */ -	dev = l->data; +	if (memcmp(pdata->bonding->bdaddr, peer, sizeof(bdaddr_t))) +		goto done; /* skip */  	if (status) { -		error_connection_attempt_failed(connection, dev->req_msg, bt_error(status)); -		goto failed; +		error_connection_attempt_failed(connection, pdata->bonding->rq, bt_error(status)); +		goto bonding_failed;  	}  	dd = hci_open_dev(pdata->dev_id);  	if (dd < 0) { -		error_no_such_adapter(connection, dev->req_msg); -		goto failed; +		error_no_such_adapter(connection, pdata->bonding->rq); +		goto bonding_failed;  	}  	/* request authentication */ @@ -1237,22 +1230,24 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b  	if (hci_send_req(dd, &rq, 100) < 0) {  		error("Unable to send the HCI request: %s (%d)",  				strerror(errno), errno); -		error_failed(connection, dev->req_msg, errno); -		goto failed; +		error_failed(connection, pdata->bonding->rq, errno); +		goto bonding_failed;  	}  	if (rp.status) {  		error("Failed with status 0x%02x", rp.status); -		error_failed(connection, dev->req_msg, bt_error(rp.status)); -		goto failed; -	} -	goto done; -failed: -	/* remove from the list if the HCI pairing request was not sent */ -	if (dev) { -		pdata->bonding_requests = slist_remove(pdata->bonding_requests, dev); -		bonding_request_info_free(dev, NULL); +		error_failed(connection, pdata->bonding->rq, bt_error(rp.status)); +		goto bonding_failed;  	} + +	goto done; /* skip: authentication requested */ + +bonding_failed: +	/* free bonding request if the HCI pairing request was not sent */ +	bonding_request_free(pdata->bonding); +	pdata->bonding = NULL; +	free(pdata->requestor_name); +	pdata->requestor_name = NULL;  done:  	hci_close_dev(dd); diff --git a/hcid/dbus.h b/hcid/dbus.h index c745fbee..da2d3af0 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -73,11 +73,14 @@ struct service_data {  typedef int (timeout_handler_func_t) (void *data);  typedef enum { -	DISCOVER_OFF, -	DISCOVER_RUNNING, -	DISCOVER_RUNNING_WITH_NAMES, -	RESOLVING_NAMES -} discover_state_t; +	STATE_IDLE, +	STATE_DISCOVER, +	STATE_RESOLVING_NAMES +}discover_state_t; + +/* discover type  */ +#define WITHOUT_NAME_RESOLVING		0 +#define RESOLVE_NAMES			1  typedef enum {  	NAME_PENDING, @@ -91,8 +94,8 @@ struct discovered_dev_info {  struct bonding_request_info {  	bdaddr_t *bdaddr; -	DBusMessage *req_msg; -	DBusMessage *cancel_msg; +	DBusMessage *rq; +	DBusMessage *cancel;  	int disconnect; /* disconnect after finish */  }; @@ -107,12 +110,13 @@ struct hci_dbus_data {  	uint32_t discoverable_timeout;  	uint32_t timeout_hits;  	timeout_handler_func_t *timeout_handler; -	uint8_t mode;		/* scan mode */ -	discover_state_t discover_state; +	uint8_t mode;		           /* scan mode */ +	discover_state_t discover_state;   /* discover states */ +	int discover_type;                 /* with/without name resolving */  	struct slist *disc_devices; -	char *requestor_name;	/* requestor unique name */ +	char *requestor_name;	           /* requestor unique name */  	struct slist *passkey_agents; -	struct slist *bonding_requests; +	struct bonding_request_info *bonding;  	struct slist *active_conn;  }; @@ -187,10 +191,9 @@ static inline DBusHandlerResult send_reply_and_unref(DBusConnection *conn, DBusM  	return DBUS_HANDLER_RESULT_HANDLED;  } +int active_conn_find_by_bdaddr(const void *data, const void *user_data); +void bonding_request_free(struct bonding_request_info *dev);  void disc_device_info_free(void *data, void *user_data); -void bonding_request_info_free(void *data, void *user_data); -int bonding_requests_find(const void *data, const void *user_data); -int disc_device_find_by_bdaddr(const void *data, const void *user_data);  int disc_device_append(struct slist **list, bdaddr_t *bdaddr, name_status_t name_status);  int disc_device_req_name(struct hci_dbus_data *dbus_data); | 
