summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hcid/dbus-adapter.c35
-rw-r--r--hcid/dbus.c72
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);