Hi all,
Here is my ConnmanAgent as example, this file is used in my devices.
It's mostlly inspired from bluez-gnome.
I send it in order to help those want to add an agent in connman-gnome.

---
 common/connman-agent.xml         |   25 +++
 common/connmanagent.c            |  414 ++++++++++++++++++++++++++++++++++++++
 common/connmanagent.h            |   59 ++++++
 common/marshal-connmanagent.list |    4 +
 4 files changed, 502 insertions(+), 0 deletions(-)
 create mode 100644 common/connman-agent.xml
 create mode 100644 common/connmanagent.c
 create mode 100644 common/connmanagent.h
 create mode 100644 common/marshal-connmanagent.list

diff --git a/common/connman-agent.xml b/common/connman-agent.xml
new file mode 100644
index 0000000..8669eac
--- /dev/null
+++ b/common/connman-agent.xml
@@ -0,0 +1,25 @@
+<?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/connmanagent.c b/common/connmanagent.c
new file mode 100644
index 0000000..c4d96ec
--- /dev/null
+++ b/common/connmanagent.c
@@ -0,0 +1,414 @@
+/*
+** Author(s):
+**  - Julien MASSOT <[email protected]>
+**
+** Copyright (C) 2012 Aldebaran Robotics
+*/
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <stdio.h>
+#include "connmanagent.h"
+
+#define CONNMAN_SERVICE                "net.connman"
+#define CONNMAN_MANAGER_PATH           "/"
+#define CONNMAN_MANAGER_INTERFACE       "net.connman.Manager"
+#define CONNMAN_SERVICE_INTERFACE       CONNMAN_SERVICE ".Service"
+#define CONNMAN_SERVICE_PATH            "/net/connman/service/"
+#define CONNMAN_TECHNOLOGY_PATH         "/net/connman/technology/"
+
+#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(ConnmanAgent *agent, 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/connmanagent.h b/common/connmanagent.h
new file mode 100644
index 0000000..d9bfcd8
--- /dev/null
+++ b/common/connmanagent.h
@@ -0,0 +1,59 @@
+/*
+** Author(s):
+**  - Julien MASSOT <[email protected]>
+**
+** Copyright (C) 2012 Aldebaran Robotics
+*/
+
+#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(ConnmanAgent *agent, 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_debug_func(ConnmanAgent *agent, ConnmanAgentDebugFunc 
func, gpointer data);
+
+G_END_DECLS
+#endif             /* !CONNMAN_AGENT_H_ */
diff --git a/common/marshal-connmanagent.list b/common/marshal-connmanagent.list
new file mode 100644
index 0000000..0587796
--- /dev/null
+++ b/common/marshal-connmanagent.list
@@ -0,0 +1,4 @@
+VOID:STRING,BOXED
+VOID:OBJECT,BOXED
+VOID:OBJECT
+VOID:BOXED
--
1.7.5.4

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to