summaryrefslogtreecommitdiff
path: root/meta/recipes-connectivity/connman/connman-gnome/0004-Handle-WiFi-authentication-using-an-agent.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-connectivity/connman/connman-gnome/0004-Handle-WiFi-authentication-using-an-agent.patch')
-rw-r--r--meta/recipes-connectivity/connman/connman-gnome/0004-Handle-WiFi-authentication-using-an-agent.patch923
1 files changed, 923 insertions, 0 deletions
diff --git a/meta/recipes-connectivity/connman/connman-gnome/0004-Handle-WiFi-authentication-using-an-agent.patch b/meta/recipes-connectivity/connman/connman-gnome/0004-Handle-WiFi-authentication-using-an-agent.patch
new file mode 100644
index 000000000..98230525b
--- /dev/null
+++ b/meta/recipes-connectivity/connman/connman-gnome/0004-Handle-WiFi-authentication-using-an-agent.patch
@@ -0,0 +1,923 @@
+From c742b40860851f1659e801d0a652f854f6783bd1 Mon Sep 17 00:00:00 2001
+Message-Id: <c742b40860851f1659e801d0a652f854f6783bd1.1334369310.git.paul.eggleton@linux.intel.com>
+In-Reply-To: <cover.1334369310.git.paul.eggleton@linux.intel.com>
+References: <cover.1334369310.git.paul.eggleton@linux.intel.com>
+From: Paul Eggleton <paul.eggleton@linux.intel.com>
+Date: Sat, 14 Apr 2012 02:32:43 +0100
+Subject: [PATCH 4/6] Handle WiFi authentication using an agent
+
+Register an agent within the applet which shows an appropriate dialog
+when credentials are requested upon connecting to a secured wireless
+network.
+
+Thanks to Julien Massot for providing the underlying agent library code.
+
+Upstream-Status: Submitted
+
+Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
+---
+ applet/Makefile.am | 3 +-
+ applet/agent.c | 209 +++++++++++++++++++++++
+ applet/agent.h | 29 +++
+ applet/main.c | 3 +
+ common/Makefile.am | 13 +-
+ common/connman-agent.c | 426 ++++++++++++++++++++++++++++++++++++++++++++++
+ common/connman-agent.h | 77 +++++++++
+ common/connman-agent.xml | 26 +++
+ common/marshal.list | 2 +
+ 9 files changed, 783 insertions(+), 5 deletions(-)
+ create mode 100644 applet/agent.c
+ create mode 100644 applet/agent.h
+ create mode 100644 common/connman-agent.c
+ create mode 100644 common/connman-agent.h
+ create mode 100644 common/connman-agent.xml
+
+diff --git a/applet/Makefile.am b/applet/Makefile.am
+index fe582ef..2e7c157 100644
+--- a/applet/Makefile.am
++++ b/applet/Makefile.am
+@@ -2,7 +2,8 @@
+ bin_PROGRAMS = connman-applet
+
+ connman_applet_SOURCES = main.c \
+- properties.h properties.c status.h status.c
++ properties.h properties.c status.h \
++ status.c agent.h agent.c
+
+ connman_applet_LDADD = $(top_builddir)/common/libcommon.a \
+ @GTK_LIBS@ @DBUS_LIBS@
+diff --git a/applet/agent.c b/applet/agent.c
+new file mode 100644
+index 0000000..b12d337
+--- /dev/null
++++ b/applet/agent.c
+@@ -0,0 +1,209 @@
++/*
++ *
++ * Connection Manager
++ *
++ * Agent implementation based on code from bluez-gnome
++ *
++ * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
++ * Copyright (C) 2006-2007 Bastien Nocera <hadess@hadess.net>
++ * Copyright (C) 2012 Intel Corporation
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ */
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <stdlib.h>
++
++#include <glib/gi18n.h>
++#include <gtk/gtk.h>
++
++#include <dbus/dbus-glib.h>
++
++#include <connman-agent.h>
++
++#include "agent.h"
++
++struct input_data {
++ gboolean numeric;
++ gpointer request_data;
++ GtkWidget *dialog;
++ GHashTable *entries;
++};
++
++static struct input_data *input_data_inst = NULL;
++
++static void input_free(struct input_data *input)
++{
++ gtk_widget_destroy(input->dialog);
++
++ g_hash_table_destroy(input->entries);
++
++ if( input_data_inst == input )
++ input_data_inst = NULL;
++
++ g_free(input);
++}
++
++static void request_input_callback(GtkWidget *dialog,
++ gint response, gpointer user_data)
++{
++ GHashTableIter iter;
++ gpointer key, value;
++ GValue *retvalue = NULL;
++ const gchar *text;
++ struct input_data *input = user_data;
++
++ if (response == GTK_RESPONSE_OK) {
++ GHashTable *reply = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
++ g_hash_table_iter_init (&iter, input->entries);
++ while (g_hash_table_iter_next (&iter, &key, &value)) {
++ text = gtk_entry_get_text((GtkEntry *)value);
++ if(strlen(text)) {
++ retvalue = g_slice_new0(GValue);
++ g_value_init(retvalue, G_TYPE_STRING);
++ g_value_set_string(retvalue, text);
++ g_hash_table_insert(reply, g_strdup(key), retvalue);
++ }
++ }
++
++ connman_agent_request_input_set_reply(input->request_data, reply);
++ } else {
++ connman_agent_request_input_abort(input->request_data);
++ }
++
++ input_free(input);
++}
++
++static void show_dialog(gpointer data, gpointer user_data)
++{
++ struct input_data *input = data;
++
++ gtk_widget_show_all(input->dialog);
++
++ gtk_window_present(GTK_WINDOW(input->dialog));
++}
++
++static void request_input_dialog(GHashTable *request,
++ gpointer request_data)
++{
++ GtkWidget *dialog;
++ GtkWidget *label;
++ GtkWidget *table;
++ GtkWidget *entry;
++ struct input_data *input;
++ GHashTableIter iter;
++ gpointer key, value;
++ int elems, i;
++
++ input = g_try_malloc0(sizeof(*input));
++ if (!input)
++ return;
++
++ input->request_data = request_data;
++
++ input->entries = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
++
++ dialog = gtk_dialog_new();
++ gtk_window_set_title(GTK_WINDOW(dialog), _("Connection Manager"));
++ gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
++ gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
++ gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
++ gtk_window_set_urgency_hint(GTK_WINDOW(dialog), TRUE);
++ gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
++ input->dialog = dialog;
++
++ gtk_dialog_add_button(GTK_DIALOG(dialog),
++ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
++ gtk_dialog_add_button(GTK_DIALOG(dialog),
++ GTK_STOCK_OK, GTK_RESPONSE_OK);
++
++ elems = g_hash_table_size(request);
++ table = gtk_table_new(elems+1, 2, FALSE);
++ gtk_table_set_row_spacings(GTK_TABLE(table), 4);
++ gtk_table_set_col_spacings(GTK_TABLE(table), 20);
++ gtk_container_set_border_width(GTK_CONTAINER(table), 12);
++ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table);
++
++ label = gtk_label_new(_("Please provide some network information:"));
++ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
++ gtk_table_attach(GTK_TABLE(table), label, 0, 2, 0, 1,
++ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
++
++ g_hash_table_iter_init (&iter, request);
++ i=1;
++ while (g_hash_table_iter_next (&iter, &key, &value)) {
++ label = gtk_label_new((const char *)key);
++ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
++ gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i+1,
++ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
++
++ entry = gtk_entry_new();
++ gtk_entry_set_max_length(GTK_ENTRY(entry), 64);
++ gtk_entry_set_width_chars(GTK_ENTRY(entry), 16);
++ gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
++ gtk_table_attach(GTK_TABLE(table), entry, 1, 2, i, i+1,
++ GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
++ g_hash_table_insert(input->entries, g_strdup(key), entry);
++
++ i++;
++ }
++
++ input_data_inst = input;
++
++ g_signal_connect(G_OBJECT(dialog), "response",
++ G_CALLBACK(request_input_callback), input);
++
++ show_dialog(input, NULL);
++}
++
++static void request_input(const char *service_id,
++ GHashTable *request, gpointer request_data, gpointer user_data)
++{
++ request_input_dialog(request, request_data);
++}
++
++static gboolean cancel_request(DBusGMethodInvocation *context,
++ gpointer user_data)
++{
++ if( input_data_inst ) {
++ connman_agent_request_input_abort(input_data_inst->request_data);
++
++ input_free(input_data_inst);
++ }
++
++ return TRUE;
++}
++
++int setup_agents(void)
++{
++ ConnmanAgent *agent = connman_agent_new();
++ connman_agent_setup(agent, "/org/gnome/connman/applet");
++
++ connman_agent_set_request_input_func(agent, request_input, agent);
++ connman_agent_set_cancel_func(agent, cancel_request, agent);
++
++ connman_agent_register(agent);
++
++ return 0;
++}
++
++void cleanup_agents(void)
++{
++}
+diff --git a/applet/agent.h b/applet/agent.h
+new file mode 100644
+index 0000000..d85676b
+--- /dev/null
++++ b/applet/agent.h
+@@ -0,0 +1,29 @@
++/*
++ *
++ * Connection Manager
++ *
++ * Agent implementation based on code from bluez-gnome
++ *
++ * Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
++ * Copyright (C) 2006-2007 Bastien Nocera <hadess@hadess.net>
++ * Copyright (C) 2012 Intel Corporation
++ *
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ *
++ */
++
++int setup_agents(void);
++void cleanup_agents(void);
+diff --git a/applet/main.c b/applet/main.c
+index 68a77b1..d06ce60 100644
+--- a/applet/main.c
++++ b/applet/main.c
+@@ -32,6 +32,7 @@
+
+ #include "properties.h"
+ #include "status.h"
++#include "agent.h"
+
+ static gboolean global_ready = FALSE;
+ static gint global_strength = -1;
+@@ -132,6 +133,7 @@ static void manager_init(DBusGConnection *connection)
+ "/", "net.connman.Manager");
+
+ properties_create(manager, manager_property_changed, NULL);
++ setup_agents();
+ }
+
+ static void manager_cleanup(void)
+@@ -148,6 +150,7 @@ static void name_owner_changed(DBusGProxy *proxy, const char *name,
+ if (*new != '\0') {
+ status_offline();
+ properties_enable(manager);
++ setup_agents();
+ } else {
+ properties_disable(manager);
+ status_unavailable();
+diff --git a/common/Makefile.am b/common/Makefile.am
+index ef1267a..5bfff19 100644
+--- a/common/Makefile.am
++++ b/common/Makefile.am
+@@ -3,19 +3,21 @@ noinst_LIBRARIES = libcommon.a
+
+ libcommon_a_SOURCES = connman-dbus.c connman-dbus.h connman-dbus-glue.h \
+ connman-client.h connman-client.c \
+- instance.h instance.c
++ instance.h instance.c \
++ connman-agent.h connman-agent.c
+
+ BUILT_SOURCES = marshal.h marshal.c \
+ connman-dbus-glue.h \
+- instance-glue.h
++ instance-glue.h \
++ connman-agent-glue.h
+
+-nodist_libcommon_a_SOURCES = connman-dbus-glue.h instance-glue.h
++nodist_libcommon_a_SOURCES = connman-dbus-glue.h instance-glue.h connman-agent-glue.h
+
+ CLEANFILES = $(BUILT_SOURCES)
+
+ AM_CFLAGS = @DBUS_CFLAGS@ @GTK_CFLAGS@
+
+-EXTRA_DIST = marshal.list instance.xml connman-dbus.xml
++EXTRA_DIST = marshal.list instance.xml connman-dbus.xml connman-agent.xml
+
+ MAINTAINERCLEANFILES = Makefile.in
+
+@@ -30,3 +32,6 @@ instance-glue.h: instance.xml
+
+ connman-dbus-glue.h: connman-dbus.xml
+ $(DBUS_BINDING_TOOL) --prefix=connman --mode=glib-client --output=$@ $<
++
++connman-agent-glue.h: connman-agent.xml
++ $(DBUS_BINDING_TOOL) --prefix=connman_agent --mode=glib-server --output=$@ $<
+diff --git a/common/connman-agent.c b/common/connman-agent.c
+new file mode 100644
+index 0000000..769bf27
+--- /dev/null
++++ b/common/connman-agent.c
+@@ -0,0 +1,426 @@
++/*
++ * Connection Manager Agent implementation
++ *
++ * Author(s):
++ * - Julien MASSOT <jmassot@aldebaran-robotics.com>
++ * - Paul Eggleton <paul.eggleton@linux.intel.com>
++ *
++ * Copyright (C) 2012 Aldebaran Robotics
++ * Copyright (C) 2012 Intel Corporation
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License version 2.1 as published by the Free Software Foundation.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#include <dbus/dbus-glib.h>
++#include <dbus/dbus-glib-lowlevel.h>
++#include <stdio.h>
++
++#include "connman-agent.h"
++#include "connman-dbus.h"
++
++#define CONNMAN_AGENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
++ CONNMAN_TYPE_AGENT, ConnmanAgentPrivate))
++
++typedef enum {
++ AGENT_ERROR_REJECT,
++ AGENT_ERROR_RETRY
++} AgentError;
++
++#define AGENT_ERROR (agent_error_quark())
++
++#define AGENT_ERROR_TYPE (agent_error_get_type())
++
++static GQuark agent_error_quark(void)
++{
++ static GQuark quark = 0;
++ if (!quark)
++ quark = g_quark_from_static_string("Agent");
++
++ return quark;
++}
++
++#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
++
++static GType agent_error_get_type(void)
++{
++ static GType etype = 0;
++ if (etype == 0) {
++ static const GEnumValue values[] = {
++ ENUM_ENTRY(AGENT_ERROR_REJECT, "Rejected"),
++ ENUM_ENTRY(AGENT_ERROR_RETRY, "Retry"),
++ { 0, 0, 0 }
++ };
++
++ etype = g_enum_register_static("Agent", values);
++ }
++
++ return etype;
++}
++
++typedef struct _ConnmanAgentPrivate ConnmanAgentPrivate;
++
++typedef struct _PendingRequest PendingRequest;
++
++struct _PendingRequest {
++ DBusGMethodInvocation *context;
++ ConnmanAgent *agent;
++};
++
++struct _ConnmanAgentPrivate {
++ gchar *busname;
++ gchar *path;
++ DBusGConnection *connection;
++ DBusGProxy *connman_proxy;
++
++ ConnmanAgentRequestInputFunc input_func;
++ gpointer input_data;
++
++ ConnmanAgentCancelFunc cancel_func;
++ gpointer cancel_data;
++
++ ConnmanAgentReleaseFunc release_func;
++ gpointer release_data;
++
++ ConnmanAgentDebugFunc debug_func;
++ gpointer debug_data;
++
++};
++
++G_DEFINE_TYPE(ConnmanAgent, connman_agent, G_TYPE_OBJECT)
++
++static inline void debug(ConnmanAgent *agent, const char *format, ...)
++{
++ char str[256];
++ va_list ap;
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++
++ if (priv->debug_func == NULL)
++ return;
++
++ va_start(ap, format);
++
++ if (vsnprintf(str, sizeof(str), format, ap) > 0)
++ priv->debug_func(str, priv->debug_data);
++
++ va_end(ap);
++}
++
++gboolean connman_agent_request_input_set_reply(gpointer request_data, GHashTable *reply)
++{
++ PendingRequest *pendingrequest = request_data;
++
++ if (request_data == NULL)
++ return FALSE;
++
++ dbus_g_method_return(pendingrequest->context, reply);
++
++ g_free(pendingrequest);
++
++ return FALSE;
++}
++
++gboolean connman_agent_request_input_abort(gpointer request_data)
++{
++ PendingRequest *pendingrequest = request_data;
++ GError *result;
++ if (request_data == NULL)
++ return FALSE;
++
++ result = g_error_new(AGENT_ERROR, AGENT_ERROR_REJECT,
++ "Input request rejected");
++ dbus_g_method_return_error(pendingrequest->context, result);
++ g_clear_error(&result);
++ g_free(pendingrequest);
++
++ return FALSE;
++}
++
++static gboolean connman_agent_request_input_cb(const GHashTable *reply, gpointer user_data)
++{
++
++ PendingRequest *pendingrequest = user_data;
++
++ dbus_g_method_return(pendingrequest->context, reply);
++
++ g_free(pendingrequest);
++ return FALSE;
++}
++
++gboolean connman_agent_report_error(ConnmanAgent *agent,
++ const char *path, const char *error,
++ DBusGMethodInvocation *context)
++{
++ GError *result;
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++
++ debug(agent, "connection %s, reports an error: %s", path, error);
++ result = g_error_new(AGENT_ERROR, AGENT_ERROR_RETRY,
++ "Retry");
++ dbus_g_method_return_error(context, result);
++ g_clear_error(&result);
++
++ return FALSE;
++}
++
++gboolean connman_agent_request_input(ConnmanAgent *agent,
++ const char *path, GHashTable *fields,
++ DBusGMethodInvocation *context)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++ const char *sender = dbus_g_method_get_sender(context);
++ char *name = NULL, *type = NULL;
++ char **id = NULL;
++ PendingRequest *pendingrequest = NULL;
++
++ debug(agent, "request %s, sender %s", path, sender);
++
++ if (fields == NULL)
++ return FALSE;
++
++ if (priv->input_func != NULL) {
++ id = g_strsplit(path, "/net/connman/service/", 2);
++ if (g_strv_length(id) == 2) {
++ pendingrequest = g_try_new0(PendingRequest, 1);
++ pendingrequest->context = context;
++ pendingrequest->agent = agent;
++ priv->input_func(id[1], fields, pendingrequest, priv->input_data);
++ }
++ g_strfreev(id);
++ }
++
++ return FALSE;
++}
++
++gboolean connman_agent_cancel(ConnmanAgent *agent,
++ DBusGMethodInvocation *context)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++ const char *sender = dbus_g_method_get_sender(context);
++ gboolean result = FALSE;
++
++ debug(agent, "Request Canceled %s", sender);
++
++ if (g_str_equal(sender, priv->busname) == FALSE)
++ return FALSE;
++
++ if (priv->cancel_func)
++ result = priv->cancel_func(context, priv->cancel_data);
++
++ return result;
++}
++
++gboolean connman_agent_release(ConnmanAgent *agent,
++ DBusGMethodInvocation *context)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++ const char *sender = dbus_g_method_get_sender(context);
++
++ debug(agent, "agent %p sender %s", agent, sender);
++
++ if (g_str_equal(sender, priv->busname) == FALSE)
++ return FALSE;
++
++ dbus_g_method_return(context);
++
++ return TRUE;
++}
++
++#include "connman-agent-glue.h"
++
++static void connman_agent_init(ConnmanAgent *agent)
++{
++ debug(agent, "agent %p", agent);
++}
++
++static void connman_agent_finalize(GObject *agent)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++
++ if (priv->connman_proxy != NULL) {
++ g_object_unref(priv->connman_proxy);
++ }
++
++ g_free(priv->path);
++ g_free(priv->busname);
++ dbus_g_connection_unref(priv->connection);
++
++ G_OBJECT_CLASS(connman_agent_parent_class)->finalize(agent);
++}
++
++static void connman_agent_class_init(ConnmanAgentClass *klass)
++{
++ GObjectClass *object_class = (GObjectClass *) klass;
++
++ g_type_class_add_private(klass, sizeof(ConnmanAgentPrivate));
++
++ object_class->finalize = connman_agent_finalize;
++
++ dbus_g_object_type_install_info(CONNMAN_TYPE_AGENT,
++ &dbus_glib_connman_agent_object_info);
++}
++
++ConnmanAgent *connman_agent_new(void)
++{
++ ConnmanAgent *agent;
++ g_type_init();
++
++ agent = CONNMAN_AGENT(g_object_new(CONNMAN_TYPE_AGENT, NULL));
++
++ return agent;
++}
++
++gboolean connman_agent_setup(ConnmanAgent *agent, const char *path)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++ DBusGProxy *proxy;
++ GObject *object;
++ GError *error = NULL;
++
++ debug(agent, "agent_setup %p", agent);
++
++ if (priv->path != NULL)
++ return FALSE;
++
++ priv->path = g_strdup(path);
++ priv->connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
++ if (error != NULL) {
++ g_printerr("Connecting to system bus failed: %s\n",
++ error->message);
++ g_error_free(error);
++ return FALSE;
++ }
++
++ proxy = dbus_g_proxy_new_for_name_owner(priv->connection, CONNMAN_SERVICE,
++ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, NULL);
++
++ g_free(priv->busname);
++
++ if (proxy != NULL) {
++ priv->busname = g_strdup(dbus_g_proxy_get_bus_name(proxy));
++ g_object_unref(proxy);
++ } else
++ priv->busname = NULL;
++
++ object = dbus_g_connection_lookup_g_object(priv->connection, priv->path);
++ if (object != NULL)
++ g_object_unref(object);
++
++ return TRUE;
++}
++
++
++gboolean connman_agent_register(ConnmanAgent *agent)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++ DBusGProxy *proxy;
++ GObject *object;
++ GError *error = NULL;
++ gchar *path;
++
++ debug(agent, "register agent %p", agent);
++
++ if (priv->connman_proxy != NULL)
++ return FALSE;
++
++ priv->connman_proxy = dbus_g_proxy_new_for_name_owner(priv->connection, CONNMAN_SERVICE,
++ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, NULL);
++
++ g_free(priv->busname);
++
++ priv->busname = g_strdup(dbus_g_proxy_get_bus_name(priv->connman_proxy));
++
++ object = dbus_g_connection_lookup_g_object(priv->connection, priv->path);
++ if (object != NULL)
++ g_object_unref(object);
++
++ dbus_g_connection_register_g_object(priv->connection,
++ priv->path, G_OBJECT(agent));
++
++ dbus_g_proxy_call(priv->connman_proxy, "RegisterAgent", &error,
++ DBUS_TYPE_G_OBJECT_PATH, priv->path,
++ G_TYPE_INVALID, G_TYPE_INVALID);
++
++ if (error != NULL) {
++ g_printerr("Agent registration failed: %s\n",
++ error->message);
++ g_error_free(error);
++ return FALSE;
++ }
++
++ return TRUE;
++}
++
++gboolean connman_agent_unregister(ConnmanAgent *agent)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++ GError *error = NULL;
++
++ debug(agent, "unregister agent %p", agent);
++
++ if (priv->connman_proxy == NULL)
++ return FALSE;
++
++ dbus_g_proxy_call(priv->connman_proxy, "UnregisterAgent", &error,
++ DBUS_TYPE_G_OBJECT_PATH, priv->path,
++ G_TYPE_INVALID, G_TYPE_INVALID);
++
++ if (error != NULL) {
++ g_printerr("Agent unregistration failed: %s\n",
++ error->message);
++ g_error_free(error);
++ }
++
++ g_object_unref(priv->connman_proxy);
++ priv->connman_proxy = NULL;
++
++ g_free(priv->path);
++ priv->path = NULL;
++
++ return TRUE;
++}
++
++void connman_agent_set_request_input_func(ConnmanAgent *agent,
++ ConnmanAgentRequestInputFunc func, gpointer data)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++
++ priv->input_func = func;
++ priv->input_data = data;
++}
++
++void connman_agent_set_cancel_func(ConnmanAgent *agent,
++ ConnmanAgentCancelFunc func, gpointer data)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++
++ priv->cancel_func = func;
++ priv->cancel_data = data;
++}
++
++void connman_agent_set_release_func(ConnmanAgent *agent,
++ ConnmanAgentReleaseFunc func, gpointer data)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++
++ priv->release_func = func;
++ priv->release_data = data;
++}
++
++void connman_agent_set_debug_func(ConnmanAgent *agent, ConnmanAgentDebugFunc func, gpointer data)
++{
++ ConnmanAgentPrivate *priv = CONNMAN_AGENT_GET_PRIVATE(agent);
++
++ priv->debug_func = func;
++ priv->debug_data = data;
++}
+diff --git a/common/connman-agent.h b/common/connman-agent.h
+new file mode 100644
+index 0000000..0a1aa92
+--- /dev/null
++++ b/common/connman-agent.h
+@@ -0,0 +1,77 @@
++/*
++ * Connection Manager Agent implementation
++ *
++ * Author(s):
++ * - Julien MASSOT <jmassot@aldebaran-robotics.com>
++ * - Paul Eggleton <paul.eggleton@linux.intel.com>
++ *
++ * Copyright (C) 2012 Aldebaran Robotics
++ * Copyright (C) 2012 Intel Corporation
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License version 2.1 as published by the Free Software Foundation.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#ifndef CONNMAN_AGENT_H_
++# define CONNMAN_AGENT_H_
++
++#include <glib-object.h>
++#include <dbus/dbus-glib.h>
++
++G_BEGIN_DECLS
++
++#define CONNMAN_TYPE_AGENT (connman_agent_get_type())
++#define CONNMAN_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
++ CONNMAN_TYPE_AGENT, ConnmanAgent))
++#define CONNMAN_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
++ CONNMAN_TYPE_AGENT, ConnmanAgentClass))
++#define CONNMAN_IS_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
++ CONNMAN_TYPE_AGENT))
++#define CONNMAN_IS_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
++ CONNMAN_TYPE_AGENT))
++#define CONNMAN_GET_AGENT_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
++ CONNMAN_TYPE_AGENT, ConnmanAgentClass))
++
++typedef struct _ConnmanAgent ConnmanAgent;
++typedef struct _ConnmanAgentClass ConnmanAgentClass;
++
++struct _ConnmanAgent {
++ GObject parent;
++};
++
++struct _ConnmanAgentClass {
++ GObjectClass parent_class;
++};
++
++GType connman_agent_get_type(void);
++
++ConnmanAgent *connman_agent_new(void);
++
++gboolean connman_agent_setup(ConnmanAgent *agent, const char *path);
++
++gboolean connman_agent_register(ConnmanAgent *agent);
++gboolean connman_agent_unregister(ConnmanAgent *agent);
++gboolean connman_agent_request_input_set_reply(gpointer request_data, GHashTable *reply);
++gboolean connman_agent_request_input_abort(gpointer request_data);
++
++typedef void (*ConnmanAgentRequestInputFunc) (const char *service_id, GHashTable *request, gpointer request_data, gpointer user_data);
++typedef gboolean (*ConnmanAgentCancelFunc) (DBusGMethodInvocation *context, gpointer data);
++typedef gboolean (*ConnmanAgentReleaseFunc) (DBusGMethodInvocation *context, gpointer data);
++typedef void (*ConnmanAgentDebugFunc) (const char *str, gpointer user_data);
++
++void connman_agent_set_request_input_func(ConnmanAgent *agent, ConnmanAgentRequestInputFunc func, gpointer data);
++void connman_agent_set_cancel_func(ConnmanAgent *agent, ConnmanAgentCancelFunc func, gpointer data);
++void connman_agent_set_debug_func(ConnmanAgent *agent, ConnmanAgentDebugFunc func, gpointer data);
++
++G_END_DECLS
++#endif /* !CONNMAN_AGENT_H_ */
+diff --git a/common/connman-agent.xml b/common/connman-agent.xml
+new file mode 100644
+index 0000000..ed9ee8b
+--- /dev/null
++++ b/common/connman-agent.xml
+@@ -0,0 +1,26 @@
++<?xml version="1.0" encoding="UTF-8" ?>
++
++<node name="/net/connman/Agent">
++ <interface name="net.connman.Agent">
++ <method name="ReportError">
++ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
++ <arg type="o" direction="in"/>
++ <arg type="s" direction="in"/>
++ </method>
++
++ <method name="RequestInput">
++ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
++ <arg type="o" direction="in"/>
++ <arg type="a{sv}" direction="in"/>
++ <arg type="a{sv}" direction="out"/>
++ </method>
++
++ <method name="Cancel">
++ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
++ </method>
++
++ <method name="Release">
++ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
++ </method>
++ </interface>
++</node>
+diff --git a/common/marshal.list b/common/marshal.list
+index 8b174d0..3c6317b 100644
+--- a/common/marshal.list
++++ b/common/marshal.list
+@@ -1,3 +1,5 @@
+ VOID:STRING,BOXED
++VOID:OBJECT,BOXED
++VOID:OBJECT
+ VOID:BOXED
+ VOID:STRING
+--
+1.7.5.4
+