linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC] agent: Allow to stack default agents
@ 2014-04-28 14:27 Szymon Janc
  2014-04-29  8:27 ` Johan Hedberg
  0 siblings, 1 reply; 2+ messages in thread
From: Szymon Janc @ 2014-04-28 14:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

There is no API for notifying agent that it is no longer default one.
This can lead to situation when ie. console agent (bluetoothctl) is
set as default leaving UI agent unfunctional after bluetoothctl exited.

This patch adds stacking of default agents in case more then one agent
requested being default.
---
 src/agent.c | 47 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/src/agent.c b/src/agent.c
index 4a2f606..e12bb39 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -46,6 +46,7 @@
 #include "adapter.h"
 #include "device.h"
 #include "agent.h"
+#include "shared/queue.h"
 
 #define IO_CAPABILITY_DISPLAYONLY	0x00
 #define IO_CAPABILITY_DISPLAYYESNO	0x01
@@ -58,7 +59,7 @@
 #define AGENT_INTERFACE "org.bluez.Agent1"
 
 static GHashTable *agent_list;
-static struct agent *default_agent = NULL;
+struct queue *default_agents = NULL;
 
 typedef enum {
 	AGENT_REQUEST_PASSKEY,
@@ -152,18 +153,38 @@ static void set_io_cap(struct btd_adapter *adapter, gpointer user_data)
 	adapter_set_io_capability(adapter, io_cap);
 }
 
-static void set_default_agent(struct agent *agent)
+static bool add_default_agent(struct agent *agent)
 {
-	if (default_agent == agent)
+	if (queue_peek_head(default_agents) == agent)
+		return true;
+
+	queue_remove(default_agents, agent);
+
+	if (!queue_push_head(default_agents, agent))
+		return false;
+
+	DBG("Default agent set to %s %s", agent->owner, agent->path);
+
+	adapter_foreach(set_io_cap, agent);
+
+	return true;
+}
+
+static void remove_default_agent(struct agent *agent)
+{
+	if (queue_peek_head(default_agents) != agent) {
+		queue_remove(default_agents, agent);
 		return;
+	}
+
+	queue_remove(default_agents, agent);
 
+	agent = queue_peek_head(default_agents);
 	if (agent)
 		DBG("Default agent set to %s %s", agent->owner, agent->path);
 	else
 		DBG("Default agent cleared");
 
-	default_agent = agent;
-
 	adapter_foreach(set_io_cap, agent);
 }
 
@@ -178,8 +199,7 @@ static void agent_disconnect(DBusConnection *conn, void *user_data)
 		agent->watch = 0;
 	}
 
-	if (agent == default_agent)
-		set_default_agent(NULL);
+	remove_default_agent(agent);
 
 	g_hash_table_remove(agent_list, agent->owner);
 }
@@ -247,8 +267,8 @@ struct agent *agent_get(const char *owner)
 			return agent_ref(agent);
 	}
 
-	if (default_agent)
-		return agent_ref(default_agent);
+	if (!queue_isempty(default_agents))
+		return agent_ref(queue_peek_head(default_agents));
 
 	return NULL;
 }
@@ -889,6 +909,8 @@ static void agent_destroy(gpointer data)
 		agent_release(agent);
 	}
 
+	remove_default_agent(agent);
+
 	agent_unref(agent);
 }
 
@@ -987,7 +1009,8 @@ static DBusMessage *request_default(DBusConnection *conn, DBusMessage *msg,
 	if (g_str_equal(path, agent->path) == FALSE)
 		return btd_error_does_not_exist(msg);
 
-	set_default_agent(agent);
+	if(!add_default_agent(agent))
+		return btd_error_failed(msg, "Failed to set as default");
 
 	return dbus_message_new_method_return(msg);
 }
@@ -1008,6 +1031,8 @@ void btd_agent_init(void)
 	agent_list = g_hash_table_new_full(g_str_hash, g_str_equal,
 						NULL, agent_destroy);
 
+	default_agents = queue_new();
+
 	g_dbus_register_interface(btd_get_dbus_connection(),
 				"/org/bluez", "org.bluez.AgentManager1",
 				methods, NULL, NULL, NULL, NULL);
@@ -1018,6 +1043,6 @@ void btd_agent_cleanup(void)
 	g_dbus_unregister_interface(btd_get_dbus_connection(),
 				"/org/bluez", "org.bluez.AgentManager1");
 
-	set_default_agent(NULL);
 	g_hash_table_destroy(agent_list);
+	queue_destroy(default_agents, NULL);
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [RFC] agent: Allow to stack default agents
  2014-04-28 14:27 [RFC] agent: Allow to stack default agents Szymon Janc
@ 2014-04-29  8:27 ` Johan Hedberg
  0 siblings, 0 replies; 2+ messages in thread
From: Johan Hedberg @ 2014-04-29  8:27 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth

Hi Szymon,

On Mon, Apr 28, 2014, Szymon Janc wrote:
> There is no API for notifying agent that it is no longer default one.
> This can lead to situation when ie. console agent (bluetoothctl) is
> set as default leaving UI agent unfunctional after bluetoothctl exited.
> 
> This patch adds stacking of default agents in case more then one agent
> requested being default.
> ---
>  src/agent.c | 47 ++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 36 insertions(+), 11 deletions(-)

Besides one minor coding style issue (which I fixed) this looks good to
me and should hopefully help avoid confusion when playing around with
bluetoothctl and GUI based agents. The patch has now been applied.

Johan

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-04-29  8:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-28 14:27 [RFC] agent: Allow to stack default agents Szymon Janc
2014-04-29  8:27 ` Johan Hedberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).