summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2006-09-27 16:25:11 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2006-09-27 16:25:11 +0000
commit255528bec9a5ffdd81ce509f2166a3a405b958d3 (patch)
tree4f0f3944f4d5f26525f8618647d3e1c453b4dc1e
parent247635fe3905e4cc084a167c6db6e53dd7b0554d (diff)
Return correct error reply for CreateBonding when using security mode 3
-rw-r--r--hcid/dbus-adapter.c28
-rw-r--r--hcid/dbus-error.c7
-rw-r--r--hcid/dbus.c12
-rw-r--r--hcid/dbus.h6
-rw-r--r--hcid/security.c2
5 files changed, 37 insertions, 18 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c
index 53b65144..b7425a1a 100644
--- a/hcid/dbus-adapter.c
+++ b/hcid/dbus-adapter.c
@@ -1786,6 +1786,19 @@ failed:
return -1;
}
+static void reply_authentication_failure(struct bonding_request_info *bonding)
+{
+ DBusMessage *reply;
+ int status;
+
+ status = bonding->hci_status ?
+ bonding->hci_status : HCI_AUTHENTICATION_FAILURE;
+
+ reply = new_authentication_return(bonding->rq, status);
+ if (reply)
+ send_reply_and_unref(bonding->conn, reply);
+}
+
static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond,
struct hci_dbus_data *pdata)
{
@@ -1811,10 +1824,12 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond,
if (cond & (G_IO_HUP | G_IO_ERR)) {
debug("Hangup or error on bonding IO channel");
- if (!pdata->bonding->connected)
+
+ if (!pdata->bonding->auth_active)
error_connection_attempt_failed(pdata->bonding->conn, pdata->bonding->rq, ENETDOWN);
else
- error_authentication_failed(pdata->bonding->conn, pdata->bonding->rq);
+ reply_authentication_failure(pdata->bonding);
+
goto failed;
}
@@ -1828,12 +1843,13 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond,
}
if (ret != 0) {
- error_connection_attempt_failed(pdata->bonding->conn, pdata->bonding->rq, ret);
+ if (pdata->bonding->auth_active)
+ reply_authentication_failure(pdata->bonding);
+ else
+ error_connection_attempt_failed(pdata->bonding->conn, pdata->bonding->rq, ret);
goto failed;
}
- pdata->bonding->connected = 1;
-
len = sizeof(cinfo);
if (getsockopt(sk, SOL_L2CAP, L2CAP_CONNINFO, &cinfo, &len) < 0) {
error("Can't get connection info: %s (%d)", strerror(errno), errno);
@@ -1879,6 +1895,8 @@ static gboolean create_bonding_conn_complete(GIOChannel *io, GIOCondition cond,
hci_close_dev(dd);
+ pdata->bonding->auth_active = 1;
+
pdata->bonding->io_id = g_io_add_watch(io, G_IO_NVAL | G_IO_HUP | G_IO_ERR,
(GIOFunc) create_bonding_conn_complete,
pdata);
diff --git a/hcid/dbus-error.c b/hcid/dbus-error.c
index aa7ed5ef..82415cef 100644
--- a/hcid/dbus-error.c
+++ b/hcid/dbus-error.c
@@ -187,13 +187,6 @@ DBusHandlerResult error_authentication_canceled(DBusConnection *conn, DBusMessag
"Authentication Canceled"));
}
-DBusHandlerResult error_authentication_failed(DBusConnection *conn, DBusMessage *msg)
-{
- return send_reply_and_unref(conn,
- dbus_message_new_error(msg, ERROR_INTERFACE ".AuthenticationFailed",
- "Authentication failed"));
-}
-
DBusHandlerResult error_discover_in_progress(DBusConnection *conn, DBusMessage *msg)
{
return error_in_progress(conn, msg, "Discover in progress");
diff --git a/hcid/dbus.c b/hcid/dbus.c
index 06abd9d3..af9859d5 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -225,7 +225,7 @@ static int active_conn_remove(struct slist **list, uint16_t *handle)
return ret_val;
}
-static DBusMessage *dbus_msg_new_authentication_return(DBusMessage *msg, uint8_t status)
+DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
{
switch (status) {
case 0x00: /* success */
@@ -789,6 +789,9 @@ void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba)
memset(info, 0, sizeof(struct pending_pin_info));
bacpy(&info->bdaddr, dba);
pdata->pin_reqs = slist_append(pdata->pin_reqs, info);
+
+ if (pdata->bonding && !bacmp(dba, &pdata->bonding->bdaddr))
+ pdata->bonding->auth_active = 1;
}
int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci)
@@ -856,7 +859,7 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t
error_authentication_canceled(connection, pdata->bonding->rq);
} else {
/* reply authentication success or an error */
- message = dbus_msg_new_authentication_return(pdata->bonding->rq, status);
+ message = new_authentication_return(pdata->bonding->rq, status);
send_reply_and_unref(connection, message);
}
@@ -1552,6 +1555,9 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle, b
pdata->pin_reqs = slist_remove(pdata->pin_reqs, p);
free(p);
}
+
+ if (pdata->bonding)
+ pdata->bonding->hci_status = status;
} else {
/* Sent the remote device connected signal */
message = dbus_message_new_signal(path, ADAPTER_INTERFACE, "RemoteDeviceConnected");
@@ -1634,7 +1640,7 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, uint16_t handle
/* reply authentication canceled */
error_authentication_canceled(connection, pdata->bonding->rq);
} else {
- message = dbus_msg_new_authentication_return(pdata->bonding->rq, HCI_AUTHENTICATION_FAILURE);
+ message = new_authentication_return(pdata->bonding->rq, HCI_AUTHENTICATION_FAILURE);
send_reply_and_unref(connection, message);
}
diff --git a/hcid/dbus.h b/hcid/dbus.h
index e754622e..05edc48b 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -88,8 +88,9 @@ struct bonding_request_info {
DBusMessage *rq;
GIOChannel *io;
guint io_id;
+ int hci_status;
int cancel;
- int connected;
+ int auth_active;
};
struct pending_pin_info {
@@ -158,6 +159,8 @@ DBusHandlerResult bluez_new_failure_msg(DBusConnection *conn, DBusMessage *msg,
DBusMessage *dev_signal_factory(const int devid, const char *prop_name, const int first, ...);
+DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status);
+
int get_default_dev_id(void);
DBusHandlerResult error_failed(DBusConnection *conn, DBusMessage *msg, int err);
@@ -177,7 +180,6 @@ DBusHandlerResult error_bonding_does_not_exist(DBusConnection *conn, DBusMessage
DBusHandlerResult error_bonding_in_progress(DBusConnection *conn, DBusMessage *msg);
DBusHandlerResult error_bonding_not_in_progress(DBusConnection *conn, DBusMessage *msg);
DBusHandlerResult error_authentication_canceled(DBusConnection *conn, DBusMessage *msg);
-DBusHandlerResult error_authentication_failed(DBusConnection *conn, DBusMessage *msg);
DBusHandlerResult error_discover_in_progress(DBusConnection *conn, DBusMessage *msg);
DBusHandlerResult error_connect_in_progress(DBusConnection *conn, DBusMessage *msg);
DBusHandlerResult error_connect_not_in_progress(DBusConnection *conn, DBusMessage *msg);
diff --git a/hcid/security.c b/hcid/security.c
index 77fb9d41..c82fbc00 100644
--- a/hcid/security.c
+++ b/hcid/security.c
@@ -852,7 +852,7 @@ void start_security_manager(int hdev)
chan = g_io_channel_unix_new(dev);
g_io_channel_set_close_on_unref(chan, TRUE);
- io_data[hdev].watch_id = g_io_add_watch_full(chan, 0,
+ io_data[hdev].watch_id = g_io_add_watch_full(chan, G_PRIORITY_HIGH,
G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
io_security_event, di, (GDestroyNotify)free);
io_data[hdev].channel = chan;