diff options
| author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2006-08-24 20:24:11 +0000 | 
|---|---|---|
| committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2006-08-24 20:24:11 +0000 | 
| commit | 5d0f59f6c5ea8208c7c2e51b1a4abca4d8f971ef (patch) | |
| tree | 0ab715c5a1daaa89ecf4ddc407f558b47cdd9431 | |
| parent | 657ab7521130ad1335cfb2f0352b59a2516c41fb (diff) | |
CancelBonding improved
| -rw-r--r-- | hcid/dbus-adapter.c | 35 | ||||
| -rw-r--r-- | hcid/dbus.c | 72 | 
2 files changed, 70 insertions, 37 deletions
| diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index 75232a7b..07583d77 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -1793,7 +1793,6 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu  {  	struct hci_dbus_data *dbus_data = data;  	struct slist *l; -	DBusMessage *reply = NULL;  	DBusError err;  	bdaddr_t peer_bdaddr;  	const char *peer_addr; @@ -1831,6 +1830,8 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu  	if (dd < 0)  		return error_no_such_adapter(conn, msg); +	dbus_data->bonding->cancel = dbus_message_ref(msg); +  	l = slist_find(dbus_data->active_conn, &peer_bdaddr, active_conn_find_by_bdaddr);  	if (!l) { @@ -1866,29 +1867,31 @@ static DBusHandlerResult handle_dev_cancel_bonding_req(DBusConnection *conn, DBu  			return error_failed(conn, msg, bt_error(rp.status));  		} -		dbus_data->bonding->cancel = dbus_message_ref(msg); +		/*  +		 * if the HCI doesn't support cancel create connection cmd let +		 * the create connection complete event arrives with page timeout. +		 * Bonding in progress will be returned to requestors. +		 */ +  	} else {  		struct active_conn_info *cinfo = l->data; -		/* FIXME: if waiting remote PIN, which HCI cmd must be sent? */ - -		/* reply to cancel bonding */ -		reply = dbus_message_new_method_return(msg); -		send_reply_and_unref(conn, reply); - -		/* Reply to the create bonding request */ -		error_authentication_canceled(conn, dbus_data->bonding->rq); -		name_listener_remove(conn, dbus_message_get_sender(dbus_data->bonding->rq), -				(name_cb_t) create_bond_req_exit, dbus_data); +		/* for unlock PIN Code Request */ +		hci_send_cmd(dd, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, &peer_bdaddr); -		/* disconnect from the remote device */ +		/*  +		 * Disconnect from the remote device for safety, maybe the +		 * Controller already received the reply for PIN Code Request +		 */  		if (dbus_data->bonding->disconnect) { -			if (hci_disconnect(dd, htobs(cinfo->handle), HCI_OE_USER_ENDED_CONNECTION, 1000) < 0) +			if (hci_disconnect(dd, htobs(cinfo->handle), HCI_AUTHENTICATION_FAILURE, 1000) < 0)  				error("Disconnect failed");  		} -		bonding_request_free(dbus_data->bonding); -		dbus_data->bonding = NULL; +		/* +		 * If disconnect can't be applied and the PIN Code Request +		 * was already replied let the Controller's timer to expire +		 */  	}  	hci_close_dev(dd); diff --git a/hcid/dbus.c b/hcid/dbus.c index c9aca3c5..f356f6ba 100644 --- a/hcid/dbus.c +++ b/hcid/dbus.c @@ -232,6 +232,7 @@ static DBusMessage *dbus_msg_new_authentication_return(DBusMessage *msg, uint8_t  		return dbus_message_new_error(msg, ERROR_INTERFACE".RepeatedAttemps",  							"Repeated Attempts"); +	case 0x06:  	case 0x18: /* pairing not allowed (e.g. gw rejected attempt) */  		return dbus_message_new_error(msg, ERROR_INTERFACE".AuthenticationRejected",  							"Authentication Rejected"); @@ -245,7 +246,6 @@ static DBusMessage *dbus_msg_new_authentication_return(DBusMessage *msg, uint8_t  							"Authentication Canceled");  	case 0x05: /* authentication failure */ -	case 0x06: /* pin missing */  	case 0x0E: /* rejected due to security reasons - is this auth failure? */  	case 0x25: /* encryption mode not acceptable - is this auth failure? */  	case 0x26: /* link key cannot be changed - is this auth failure? */ @@ -795,8 +795,19 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, const u  		}  	} -	message = dbus_msg_new_authentication_return(pdata->bonding->rq, status); -	send_reply_and_unref(connection, message); +	if (pdata->bonding->cancel) { +		/* reply the cancel bonding */ +		message = dbus_message_new_method_return(pdata->bonding->cancel); +		send_reply_and_unref(connection, message); + +		/* reply authentication canceled */ +		error_authentication_canceled(connection, pdata->bonding->rq); +	} else { + +		/* reply authentication success or an error */ +		message = dbus_msg_new_authentication_return(pdata->bonding->rq, status); +		send_reply_and_unref(connection, message); +	}  	name_listener_remove(connection, dbus_message_get_sender(pdata->bonding->rq),  			(name_cb_t) create_bond_req_exit, pdata); @@ -839,20 +850,15 @@ void hcid_dbus_create_conn_cancel(bdaddr_t *local, void *ptr)  		goto failed;  	} -	if (!pdata->bonding) +	if (!pdata->bonding || !pdata->bonding->cancel || +			bacmp(&pdata->bonding->bdaddr, &ret->bdaddr))  		goto failed; -	if (bacmp(&pdata->bonding->bdaddr, &ret->bdaddr)) -		goto failed; -	  	if (!ret->status) {  		reply = dbus_message_new_method_return(pdata->bonding->cancel);  		send_reply_and_unref(connection, reply);  	} else -		error_failed(connection, pdata->bonding->cancel, bt_error(ret->status));	 - -	dbus_message_unref(pdata->bonding->cancel); -	pdata->bonding->cancel = NULL; +		error_failed(connection, pdata->bonding->cancel, bt_error(ret->status));  failed:  	bt_free(local_addr); @@ -1285,20 +1291,35 @@ 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 */ -	if (!pdata->bonding) +	if (!pdata->bonding || bacmp(&pdata->bonding->bdaddr, peer))  		goto done; /* skip */ -	if (bacmp(&pdata->bonding->bdaddr, peer)) -		goto done; /* skip */ +	dd = hci_open_dev(pdata->dev_id); +	if (dd < 0) { +		error_no_such_adapter(connection, pdata->bonding->rq); +		goto bonding_failed; +	} + +	if (pdata->bonding->cancel) { +		/*  +		 * reply to cancel bonding was done in the cancel create connection +		 * handler or in the beginning if the controller doesn't support +		 * cancel cmd. Reply authentication canceled only. +		 */ +		error_authentication_canceled(connection, pdata->bonding->rq); + +		/* +		 * When the controller doesn't support cancel create connection,  +		 * disconnect the if the connection has been completed later. +		 */ +		if (!status) +			hci_disconnect(dd, htobs(handle), HCI_AUTHENTICATION_FAILURE, 1000); -	if (status) { -		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, pdata->bonding->rq); +	if (status) { +		error_connection_attempt_failed(connection, pdata->bonding->rq, bt_error(status));  		goto bonding_failed;  	} @@ -1404,9 +1425,18 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle  		send_reply_and_unref(connection, message);  #endif +		if (pdata->bonding->cancel) { +			/* reply the cancel bonding */ +			message = dbus_message_new_method_return(pdata->bonding->cancel); +			send_reply_and_unref(connection, message); -		message = dbus_msg_new_authentication_return(pdata->bonding->rq, HCI_AUTHENTICATION_FAILURE); -		send_reply_and_unref(connection, message); +			/* reply authentication canceled */ +			error_authentication_canceled(connection, pdata->bonding->rq); +		} else { + +			message = dbus_msg_new_authentication_return(pdata->bonding->rq, HCI_AUTHENTICATION_FAILURE); +			send_reply_and_unref(connection, message); +		}  		name_listener_remove(connection, dbus_message_get_sender(pdata->bonding->rq),  				(name_cb_t) create_bond_req_exit, pdata); | 
