diff options
| -rw-r--r-- | common/glib-ectomy.c | 41 | ||||
| -rw-r--r-- | hcid/dbus-security.c | 73 | ||||
| -rw-r--r-- | hcid/dbus.c | 33 | ||||
| -rw-r--r-- | hcid/dbus.h | 1 | 
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 {  | 
