summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2006-08-20 21:41:59 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2006-08-20 21:41:59 +0000
commitec3ac41ca8876f36cc8869ab1c384980f793c40f (patch)
tree54cfad49658e334487dd602dd9cd5219e23454f8
parentbe52c05a25c0cbadcd605b24d66d0c0b682aee18 (diff)
Preliminary support for passkey agent timeouts
-rw-r--r--common/glib-ectomy.c41
-rw-r--r--hcid/dbus-security.c73
-rw-r--r--hcid/dbus.c33
-rw-r--r--hcid/dbus.h1
4 files changed, 87 insertions, 61 deletions
diff --git a/common/glib-ectomy.c b/common/glib-ectomy.c
index 214ee571..f90973ba 100644
--- a/common/glib-ectomy.c
+++ b/common/glib-ectomy.c
@@ -225,16 +225,7 @@ static void timeout_handlers_prepare(GMainContext *context)
static int timeout_cmp(const void *t1, const void *t2)
{
- const struct timeout *tout1 = t1;
- const struct timeout *tout2 = t2;
-
- if (!tout2)
- return -1;
-
- if (tout1 != tout2)
- return -1;
-
- return tout1->id - tout2->id;
+ return t1 - t2;
}
static void timeout_handlers_check(GMainContext *context)
@@ -246,24 +237,30 @@ static void timeout_handlers_check(GMainContext *context)
gettimeofday(&tv, NULL);
while (l) {
+ struct slist *match;
+ gboolean ret;
+
t = l->data;
l = l->next;
if (timercmp(&tv, &t->expiration, <))
continue;
- if (t->function(t->data)) {
- struct slist *match;
- /* if false/expired: remove it from the list
- * Before remove check again in order to cover the situation
- * when the handler is removed/freed by the callback function
- */
- match = slist_find(context->ltimeout, t, timeout_cmp);
- if (match) {
- t = match->data;
- context->ltimeout = slist_remove(context->ltimeout, t);
- free(t);
- }
+ ret = t->function(t->data);
+
+ /* Check if the handler was removed/freed by the callback
+ * function */
+ match = slist_find(context->ltimeout, t, timeout_cmp);
+
+ if (!match)
+ continue;
+
+ /* Update next pointer if callback changed the list */
+ l = match->next;
+
+ if (ret == FALSE) {
+ context->ltimeout = slist_remove(context->ltimeout, t);
+ free(t);
} else {
glong secs, msecs;
/* update the next expiration time */
diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c
index 91a03e5d..c9c6763f 100644
--- a/hcid/dbus-security.c
+++ b/hcid/dbus-security.c
@@ -39,7 +39,8 @@
#include "dbus.h"
#include "hcid.h"
-#define TIMEOUT (30 * 1000) /* 30 seconds */
+#define REQUEST_TIMEOUT (30 * 1000) /* 30 seconds */
+#define AGENT_TIMEOUT (1 * 10 * 1000) /* 3 minutes */
static struct passkey_agent *default_agent = NULL;
@@ -64,6 +65,9 @@ static void passkey_agent_free(struct passkey_agent *agent)
free(req);
}
+ if (agent->timeout)
+ g_timeout_remove(agent->timeout);
+
if (!agent->exited)
release_agent(agent);
@@ -81,6 +85,45 @@ static void passkey_agent_free(struct passkey_agent *agent)
free(agent);
}
+static void agent_exited(const char *name, struct hci_dbus_data *adapter)
+{
+ struct slist *cur, *next;
+
+ debug("Passkey agent %s exited without calling Unregister", name);
+
+ for (cur = adapter->passkey_agents; cur != NULL; cur = next) {
+ struct passkey_agent *agent = cur->data;
+
+ next = cur->next;
+
+ if (strcmp(agent->name, name))
+ continue;
+
+ agent->exited = 1;
+
+ adapter->passkey_agents = slist_remove(adapter->passkey_agents, agent);
+ passkey_agent_free(agent);
+ }
+}
+
+static gboolean agent_timeout(struct passkey_agent *agent)
+{
+ struct hci_dbus_data *pdata = agent->pdata;
+
+ debug("Passkey Agent at %s, %s timed out", agent->name, agent->path);
+
+ if (pdata)
+ pdata->passkey_agents = slist_remove(pdata->passkey_agents, agent);
+
+ name_listener_remove(agent->conn, agent->name, (name_cb_t)agent_exited, pdata);
+
+ agent->timeout = 0;
+
+ passkey_agent_free(agent);
+
+ return FALSE;
+}
+
static void default_agent_exited(const char *name, void *data)
{
debug("%s exited without unregistering the default passkey agent", name);
@@ -167,27 +210,6 @@ static int agent_cmp(const struct passkey_agent *a, const struct passkey_agent *
return 0;
}
-static void agent_exited(const char *name, struct hci_dbus_data *adapter)
-{
- struct slist *cur, *next;
-
- debug("Passkey agent %s exited without calling Unregister", name);
-
- for (cur = adapter->passkey_agents; cur != NULL; cur = next) {
- struct passkey_agent *agent = cur->data;
-
- next = cur->next;
-
- if (strcmp(agent->name, name))
- continue;
-
- agent->exited = 1;
-
- adapter->passkey_agents = slist_remove(adapter->passkey_agents, agent);
- passkey_agent_free(agent);
- }
-}
-
static DBusHandlerResult register_agent(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -233,6 +255,11 @@ static DBusHandlerResult register_agent(DBusConnection *conn,
if (!slist_find(adapter->passkey_agents, &ref, (cmp_func_t)agent_cmp))
name_listener_add(conn, ref.name, (name_cb_t)agent_exited, adapter);
+ /* Because of bugs in glib-ectonomy.c this doesn't work yet */
+#if 0
+ agent->timeout = g_timeout_add(AGENT_TIMEOUT, (GSourceFunc)agent_timeout, agent);
+#endif
+
adapter->passkey_agents = slist_append(adapter->passkey_agents, agent);
return send_reply_and_unref(conn, reply);
@@ -486,7 +513,7 @@ static int call_passkey_agent(DBusConnection *conn,
DBUS_TYPE_INVALID);
if (dbus_connection_send_with_reply(conn, message,
- &req->call, TIMEOUT) == FALSE) {
+ &req->call, REQUEST_TIMEOUT) == FALSE) {
error("D-Bus send failed");
goto failed;
}
diff --git a/hcid/dbus.c b/hcid/dbus.c
index 269d255d..2bb9bf85 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -1440,16 +1440,16 @@ failed:
* Section reserved to D-Bus watch functions
*
*****************************************************************/
-static int message_dispatch_cb(void *data)
+static gboolean message_dispatch_cb(void *data)
{
dbus_connection_ref(connection);
/* Dispatch messages */
- while(dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS);
+ while (dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS);
dbus_connection_unref(connection);
- return -1;
+ return FALSE;
}
static gboolean watch_func(GIOChannel *chan, GIOCondition cond, gpointer data)
@@ -1520,17 +1520,17 @@ static void watch_toggled(DBusWatch *watch, void *data)
remove_watch(watch, data);
}
-static int timeout_handler_dispatch(gpointer data)
+static gboolean timeout_handler_dispatch(gpointer data)
{
timeout_handler_t *handler = data;
/* if not enabled should not be polled by the main loop */
if (dbus_timeout_get_enabled(handler->timeout) != TRUE)
- return -1;
+ return FALSE;
dbus_timeout_handle(handler->timeout);
- return -1;
+ return FALSE;
}
static void timeout_handler_free(void *data)
@@ -1672,21 +1672,21 @@ done:
*
*****************************************************************/
-int discoverable_timeout_handler(void *data)
+gboolean discoverable_timeout_handler(void *data)
{
struct hci_dbus_data *dbus_data = data;
struct hci_request rq;
int dd = -1;
uint8_t hci_mode = dbus_data->mode;
uint8_t status = 0;
- int8_t retval = 0;
+ gboolean retval = TRUE;
hci_mode &= ~SCAN_INQUIRY;
dd = hci_open_dev(dbus_data->dev_id);
if (dd < 0) {
error("HCI device open failed: hci%d", dbus_data->dev_id);
- return 0;
+ return TRUE;
}
memset(&rq, 0, sizeof(rq));
@@ -1708,7 +1708,7 @@ int discoverable_timeout_handler(void *data)
}
dbus_data->timeout_id = 0;
- retval = -1;
+ retval = FALSE;
failed:
if (dd >= 0)
@@ -1717,24 +1717,25 @@ failed:
return retval;
}
-static int system_bus_reconnect(void *data)
+static gboolean system_bus_reconnect(void *data)
{
struct hci_dev_list_req *dl = NULL;
struct hci_dev_req *dr;
- int sk, i, ret_val = 0;
+ int sk, i;
+ gboolean ret_val = TRUE;
if (dbus_connection_get_is_connected(connection))
- return -1;
+ return FALSE;
if (hcid_dbus_init() == FALSE)
- return 0;
+ return TRUE;
/* Create and bind HCI socket */
sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (sk < 0) {
error("Can't open HCI socket: %s (%d)",
strerror(errno), errno);
- return 0;
+ return TRUE;
}
dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));
@@ -1758,7 +1759,7 @@ static int system_bus_reconnect(void *data)
for (i = 0; i < dl->dev_num; i++, dr++)
hcid_dbus_register_device(dr->dev_id);
- ret_val = -1;
+ ret_val = FALSE;
failed:
if (sk >= 0)
diff --git a/hcid/dbus.h b/hcid/dbus.h
index 4aae9164..36c369bc 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -120,6 +120,7 @@ struct passkey_agent {
char *path;
struct slist *pending_requests;
int exited;
+ guint timeout;
};
struct pending_agent_request {