summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrik Flykt <patrik.flykt@linux.intel.com>2013-06-12 16:54:29 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2013-06-13 10:38:33 +0300
commit1ac86108dfc3d8e350bda9daf42496fabaa5a3d6 (patch)
tree26485781f0f8fbd62dcb0df96e823a3662348dce
parent01fe75b711144509e06156071d33fb8c731bbb53 (diff)
downloadconnman-1ac86108dfc3d8e350bda9daf42496fabaa5a3d6.tar.gz
connman-1ac86108dfc3d8e350bda9daf42496fabaa5a3d6.tar.bz2
connman-1ac86108dfc3d8e350bda9daf42496fabaa5a3d6.zip
client: Implement support for queueing Agent messages
ConnMan and ConnMan VPN daemon both send only one Agent message at a time. Since they are two different daemons, they can be sending messages at the same time independent of each other. Implement a check for an agent request from the other daemon being already processed and if so store the message for later. When the current agent request has been processed, check if there are pending requests from the other daemon and re-run the pending function. In order to support arbitrary queueing, make all method call implementations asynchronous.
-rw-r--r--client/agent.c69
1 files changed, 60 insertions, 9 deletions
diff --git a/client/agent.c b/client/agent.c
index ad6ac2f8..ce7e1942 100644
--- a/client/agent.c
+++ b/client/agent.c
@@ -48,8 +48,11 @@ struct agent_data {
DBusMessage *reply;
DBusMessageIter iter;
DBusMessageIter dict;
+ GDBusMethodFunction pending_function;
};
+static DBusConnection *agent_connection;
+
static struct agent_data agent_request = {
AGENT_INTERFACE,
};
@@ -119,6 +122,10 @@ static void pending_message_remove(struct agent_data *request)
static void pending_command_complete(char *message)
{
+ struct agent_data *next_request = NULL;
+ DBusMessage *pending_message;
+ GDBusMethodFunction pending_function;
+
__connmanctl_save_rl();
fprintf(stdout, "%s", message);
@@ -129,6 +136,36 @@ static void pending_command_complete(char *message)
__connmanctl_command_mode();
else
__connmanctl_agent_mode("", NULL, NULL);
+
+ if (agent_request.message != NULL)
+ next_request = &agent_request;
+ else if (vpn_agent_request.message != NULL)
+ next_request = &vpn_agent_request;
+
+ if (next_request == NULL)
+ return;
+
+ pending_message = next_request->message;
+ pending_function = next_request->pending_function;
+ next_request->pending_function = NULL;
+
+ pending_function(agent_connection, next_request->message,
+ next_request);
+
+ dbus_message_unref(pending_message);
+}
+
+static bool handle_message(DBusMessage *message, struct agent_data *request,
+ GDBusMethodFunction function)
+{
+ if (agent_request.pending_function == NULL &&
+ vpn_agent_request.pending_function == NULL)
+ return true;
+
+ request->message = dbus_message_ref(message);
+ request->pending_function = function;
+
+ return false;
}
static DBusMessage *agent_release(DBusConnection *connection,
@@ -136,6 +173,9 @@ static DBusMessage *agent_release(DBusConnection *connection,
{
struct agent_data *request = user_data;
+ if (handle_message(message, request, agent_release) == false)
+ return NULL;
+
g_dbus_unregister_interface(connection, agent_path(),
request->interface);
request->registered = false;
@@ -159,6 +199,9 @@ static DBusMessage *agent_cancel(DBusConnection *connection,
{
struct agent_data *request = user_data;
+ if (handle_message(message, request, agent_cancel) == false)
+ return NULL;
+
pending_message_remove(request);
if (strcmp(request->interface, AGENT_INTERFACE) == 0)
@@ -171,8 +214,6 @@ static DBusMessage *agent_cancel(DBusConnection *connection,
return dbus_message_new_method_return(message);
}
-static DBusConnection *agent_connection = NULL;
-
static void request_browser_return(char *input, void *user_data)
{
struct agent_data *request = user_data;
@@ -201,6 +242,9 @@ static DBusMessage *agent_request_browser(DBusConnection *connection,
DBusMessageIter iter;
char *service, *url;
+ if (handle_message(message, request, agent_request_browser) == false)
+ return NULL;
+
dbus_message_iter_init(message, &iter);
dbus_message_iter_get_basic(&iter, &service);
@@ -212,7 +256,6 @@ static DBusMessage *agent_request_browser(DBusConnection *connection,
fprintf(stdout, " %s\n", url);
__connmanctl_redraw_rl();
- agent_connection = connection;
request->message = dbus_message_ref(message);
__connmanctl_agent_mode("Connected (yes/no)? ",
request_browser_return, request);
@@ -253,6 +296,9 @@ static DBusMessage *agent_report_error(DBusConnection *connection,
DBusMessageIter iter;
char *path, *service, *error;
+ if (handle_message(message, request, agent_report_error) == false)
+ return NULL;
+
dbus_message_iter_init(message, &iter);
dbus_message_iter_get_basic(&iter, &path);
@@ -269,7 +315,6 @@ static DBusMessage *agent_report_error(DBusConnection *connection,
fprintf(stdout, " %s\n", error);
__connmanctl_redraw_rl();
- agent_connection = connection;
request->message = dbus_message_ref(message);
__connmanctl_agent_mode("Retry (yes/no)? ", report_error_return,
request);
@@ -400,6 +445,9 @@ static DBusMessage *agent_request_input(DBusConnection *connection,
int i;
+ if (handle_message(message, request, agent_request_input) == false)
+ return NULL;
+
dbus_message_iter_init(message, &iter);
dbus_message_iter_get_basic(&iter, &str);
@@ -458,7 +506,6 @@ static DBusMessage *agent_request_input(DBusConnection *connection,
dbus_message_iter_next(&dict);
}
- agent_connection = connection;
request->reply = dbus_message_new_method_return(message);
dbus_message_iter_init_append(request->reply, &request->iter);
@@ -474,8 +521,8 @@ static DBusMessage *agent_request_input(DBusConnection *connection,
}
static const GDBusMethodTable agent_methods[] = {
- { GDBUS_METHOD("Release", NULL, NULL, agent_release) },
- { GDBUS_METHOD("Cancel", NULL, NULL, agent_cancel) },
+ { GDBUS_ASYNC_METHOD("Release", NULL, NULL, agent_release) },
+ { GDBUS_ASYNC_METHOD("Cancel", NULL, NULL, agent_cancel) },
{ GDBUS_ASYNC_METHOD("RequestBrowser",
GDBUS_ARGS({ "service", "o" },
{ "url", "s" }),
@@ -520,6 +567,8 @@ int __connmanctl_agent_register(DBusConnection *connection)
return -EALREADY;
}
+ agent_connection = connection;
+
if (g_dbus_register_interface(connection, path,
AGENT_INTERFACE, agent_methods,
NULL, NULL, &agent_request,
@@ -581,8 +630,8 @@ int __connmanctl_agent_unregister(DBusConnection *connection)
}
static const GDBusMethodTable vpn_agent_methods[] = {
- { GDBUS_METHOD("Release", NULL, NULL, agent_release) },
- { GDBUS_METHOD("Cancel", NULL, NULL, agent_cancel) },
+ { GDBUS_ASYNC_METHOD("Release", NULL, NULL, agent_release) },
+ { GDBUS_ASYNC_METHOD("Cancel", NULL, NULL, agent_cancel) },
{ GDBUS_ASYNC_METHOD("ReportError",
GDBUS_ARGS({ "service", "o" },
{ "error", "s" }),
@@ -618,6 +667,8 @@ int __connmanctl_vpn_agent_register(DBusConnection *connection)
return -EALREADY;
}
+ agent_connection = connection;
+
if (g_dbus_register_interface(connection, path,
VPN_AGENT_INTERFACE, vpn_agent_methods,
NULL, NULL, &vpn_agent_request,