Add first draft of new D-Bus API
authorMarcel Holtmann <marcel@holtmann.org>
Sun, 29 Jun 2008 02:57:57 +0000 (04:57 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Sun, 29 Jun 2008 02:57:57 +0000 (04:57 +0200)
include/dbus.h
src/connman.h
src/element.c
src/main.c
src/manager.c
test/list-devices [new file with mode: 0755]
test/list-elements [new file with mode: 0755]
test/list-interfaces [deleted file]
test/monitor-elements [new file with mode: 0755]
test/show-introspection

index a237e38..be98a4e 100644 (file)
@@ -30,15 +30,17 @@ extern "C" {
 
 #define CONNMAN_SERVICE  "org.moblin.connman"
 
-#define CONNMAN_ERROR_INTERFACE  CONNMAN_SERVICE ".Error"
+#define CONNMAN_ERROR_INTERFACE    CONNMAN_SERVICE ".Error"
 
-#define CONNMAN_AGENT_INTERFACE  CONNMAN_SERVICE ".Agent"
+#define CONNMAN_AGENT_INTERFACE    CONNMAN_SERVICE ".Agent"
+
+#define CONNMAN_ELEMENT_INTERFACE  CONNMAN_SERVICE ".Element"
 
-#define CONNMAN_MANAGER_PATH       "/"
 #define CONNMAN_MANAGER_INTERFACE  CONNMAN_SERVICE ".Manager"
+#define CONNMAN_MANAGER_PATH       "/"
 
-#define CONNMAN_IFACE_BASEPATH  "/interface"
-#define CONNMAN_IFACE_INTERFACE  CONNMAN_SERVICE ".Interface"
+#define CONNMAN_IFACE_INTERFACE    CONNMAN_SERVICE ".Interface"
+#define CONNMAN_IFACE_BASEPATH     "/interface"
 
 #define CONNMAN_NETWORK_INTERFACE  CONNMAN_SERVICE ".Network"
 
index e4f51df..05bfe36 100644 (file)
@@ -26,7 +26,6 @@
 #define NM_SERVICE    "org.freedesktop.NetworkManager"
 #define NM_PATH       "/org/freedesktop/NetworkManager"
 #define NM_INTERFACE  NM_SERVICE
-#define NM_DEVICE     NM_SERVICE ".Devices"
 
 int __connman_manager_init(DBusConnection *conn, gboolean compat);
 void __connman_manager_cleanup(void);
@@ -50,10 +49,14 @@ void __connman_plugin_cleanup(void);
 #include <connman/driver.h>
 #include <connman/element.h>
 
-int __connman_element_init(void);
+int __connman_element_init(DBusConnection *conn);
 void __connman_element_cleanup(void);
 
-void __connman_element_list(DBusMessageIter *iter);
+void __connman_element_list(enum connman_element_type type,
+                                               DBusMessageIter *iter);
+
+const char *__connman_element_type2string(enum connman_element_type type);
+const char *__connman_element_subtype2string(enum connman_element_subtype type);
 
 #include <connman/iface.h>
 
index 71332d0..a4f0328 100644 (file)
 #include <errno.h>
 
 #include <glib.h>
-#include <dbus/dbus.h>
+#include <gdbus.h>
 
 #include "connman.h"
 
+static DBusConnection *connection;
+
 static GStaticMutex driver_mutex = G_STATIC_MUTEX_INIT;
 static GSList *driver_list = NULL;
 static GThreadPool *driver_thread;
@@ -38,29 +40,183 @@ static GStaticMutex element_mutex = G_STATIC_MUTEX_INIT;
 static GNode *element_root = NULL;
 static GThreadPool *element_thread;
 
+static const char *type2string(enum connman_element_type type)
+{
+       switch (type) {
+       case CONNMAN_ELEMENT_TYPE_UNKNOWN:
+               return "unknown";
+       case CONNMAN_ELEMENT_TYPE_ROOT:
+               return "root";
+       case CONNMAN_ELEMENT_TYPE_DEVICE:
+               return "device";
+       case CONNMAN_ELEMENT_TYPE_NETWORK:
+               return "network";
+       case CONNMAN_ELEMENT_TYPE_IPV4:
+               return "ipv4";
+       case CONNMAN_ELEMENT_TYPE_IPV6:
+               return "ipv6";
+       case CONNMAN_ELEMENT_TYPE_DHCP:
+               return "dhcp";
+       case CONNMAN_ELEMENT_TYPE_BOOTP:
+               return "bootp";
+       case CONNMAN_ELEMENT_TYPE_ZEROCONF:
+               return "zeroconf";
+       case CONNMAN_ELEMENT_TYPE_CONNECTION:
+               return "42";
+       }
+
+       return NULL;
+}
+
+static const char *subtype2string(enum connman_element_subtype type)
+{
+       switch (type) {
+       case CONNMAN_ELEMENT_SUBTYPE_UNKNOWN:
+               return "unknown";
+       case CONNMAN_ELEMENT_SUBTYPE_ETHERNET:
+               return "ethernet";
+       case CONNMAN_ELEMENT_SUBTYPE_WIFI:
+               return "wifi";
+       case CONNMAN_ELEMENT_SUBTYPE_WIMAX:
+               return "wimax";
+       case CONNMAN_ELEMENT_SUBTYPE_MODEM:
+               return "modem";
+       case CONNMAN_ELEMENT_SUBTYPE_BLUETOOTH:
+               return "bluetooth";
+       }
+
+       return NULL;
+}
+
+static void append_entry(DBusMessageIter *dict,
+                               const char *key, int type, void *val)
+{
+       DBusMessageIter entry, value;
+       const char *signature;
+
+       dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+                                                               NULL, &entry);
+
+       dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+       switch (type) {
+       case DBUS_TYPE_STRING:
+               signature = DBUS_TYPE_STRING_AS_STRING;
+               break;
+       case DBUS_TYPE_UINT16:
+               signature = DBUS_TYPE_UINT16_AS_STRING;
+               break;
+       default:
+               signature = DBUS_TYPE_VARIANT_AS_STRING;
+               break;
+       }
+
+       dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+                                                       signature, &value);
+       dbus_message_iter_append_basic(&value, type, val);
+       dbus_message_iter_close_container(&entry, &value);
+
+       dbus_message_iter_close_container(dict, &entry);
+}
+
+static DBusMessage *get_properties(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_element *element = data;
+       DBusMessage *reply;
+       DBusMessageIter array, dict;
+       const char *str;
+
+       DBG("conn %p", conn);
+
+       reply = dbus_message_new_method_return(msg);
+       if (reply == NULL)
+               return NULL;
+
+       dbus_message_iter_init_append(reply, &array);
+
+       dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
+                       DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                       DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+                       DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+       str = type2string(element->type);
+       if (str != NULL)
+               append_entry(&dict, "Type", DBUS_TYPE_STRING, &str);
+
+       str = subtype2string(element->subtype);
+       if (str != NULL)
+               append_entry(&dict, "Subtype", DBUS_TYPE_STRING, &str);
+
+       if (element->info.driver != NULL)
+               append_entry(&dict, "Driver",
+                               DBUS_TYPE_STRING, &element->info.driver);
+
+       if (element->info.vendor != NULL)
+               append_entry(&dict, "Vendor",
+                               DBUS_TYPE_STRING, &element->info.vendor);
+
+       if (element->info.product != NULL)
+               append_entry(&dict, "Product",
+                               DBUS_TYPE_STRING, &element->info.product);
+
+       if (element->ipv4.address != NULL)
+               append_entry(&dict, "IPv4.Address",
+                               DBUS_TYPE_STRING, &element->ipv4.address);
+
+       if (element->ipv4.netmask != NULL)
+               append_entry(&dict, "IPv4.Netmask",
+                               DBUS_TYPE_STRING, &element->ipv4.netmask);
+
+       if (element->ipv4.gateway != NULL)
+               append_entry(&dict, "IPv4.Gateway",
+                               DBUS_TYPE_STRING, &element->ipv4.gateway);
+
+       dbus_message_iter_close_container(&array, &dict);
+
+       return reply;
+}
+
+static GDBusMethodTable element_methods[] = {
+       { "GetProperties", "", "a{sv}", get_properties },
+       { },
+};
+
+struct append_filter {
+       enum connman_element_type type;
+       DBusMessageIter *iter;
+};
+
 static gboolean append_path(GNode *node, gpointer data)
 {
        struct connman_element *element = node->data;
-       DBusMessageIter *iter = data;
+       struct append_filter *filter = data;
 
        DBG("element %p name %s", element, element->name);
 
        if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
                return FALSE;
 
-       dbus_message_iter_append_basic(iter,
+       if (filter->type != CONNMAN_ELEMENT_TYPE_UNKNOWN &&
+                                       filter->type != element->type)
+               return FALSE;
+
+       dbus_message_iter_append_basic(filter->iter,
                                DBUS_TYPE_OBJECT_PATH, &element->path);
 
        return FALSE;
 }
 
-void __connman_element_list(DBusMessageIter *iter)
+void __connman_element_list(enum connman_element_type type,
+                                               DBusMessageIter *iter)
 {
+       struct append_filter filter = { type, iter };
+
        DBG("");
 
        g_static_mutex_lock(&element_mutex);
        g_node_traverse(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
-                                                       append_path, iter);
+                                                       append_path, &filter);
        g_static_mutex_unlock(&element_mutex);
 }
 
@@ -229,6 +385,22 @@ int connman_element_register(struct connman_element *element,
 
        g_static_mutex_unlock(&element_mutex);
 
+       g_dbus_register_interface(connection, element->path,
+                                       CONNMAN_ELEMENT_INTERFACE,
+                                       element_methods, NULL, NULL,
+                                                       element, NULL);
+
+       g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
+                               CONNMAN_MANAGER_INTERFACE, "ElementAdded",
+                               DBUS_TYPE_OBJECT_PATH, &element->path,
+                                                       DBUS_TYPE_INVALID);
+
+       if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE)
+               g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
+                               CONNMAN_MANAGER_INTERFACE, "DeviceAdded",
+                               DBUS_TYPE_OBJECT_PATH, &element->path,
+                                                       DBUS_TYPE_INVALID);
+
        g_thread_pool_push(element_thread, element, NULL);
 
        return 0;
@@ -240,6 +412,20 @@ void connman_element_unregister(struct connman_element *element)
 
        DBG("element %p name %s", element, element->name);
 
+       if (element->type == CONNMAN_ELEMENT_TYPE_DEVICE)
+               g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
+                               CONNMAN_MANAGER_INTERFACE, "DeviceRemoved",
+                               DBUS_TYPE_OBJECT_PATH, &element->path,
+                                                       DBUS_TYPE_INVALID);
+
+       g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
+                               CONNMAN_MANAGER_INTERFACE, "ElementRemoved",
+                               DBUS_TYPE_OBJECT_PATH, &element->path,
+                                                       DBUS_TYPE_INVALID);
+
+       g_dbus_unregister_interface(connection, element->path,
+                                               CONNMAN_ELEMENT_INTERFACE);
+
        g_static_mutex_lock(&element_mutex);
 
        if (element->driver) {
@@ -353,11 +539,15 @@ static void element_probe(gpointer data, gpointer user_data)
        connman_element_unref(element);
 }
 
-int __connman_element_init(void)
+int __connman_element_init(DBusConnection *conn)
 {
        struct connman_element *element;
 
-       DBG("");
+       DBG("conn %p", conn);
+
+       connection = dbus_connection_ref(conn);
+       if (connection == NULL)
+               return -EIO;
 
        g_static_mutex_lock(&element_mutex);
 
@@ -384,6 +574,9 @@ static gboolean free_node(GNode *node, gpointer data)
 
        DBG("element %p name %s", element, element->name);
 
+       g_dbus_unregister_interface(connection, element->path,
+                                               CONNMAN_ELEMENT_INTERFACE);
+
        if (element->driver) {
                if (element->driver->remove)
                        element->driver->remove(element);
@@ -414,4 +607,6 @@ void __connman_element_cleanup(void)
        element_root = NULL;
 
        g_static_mutex_unlock(&element_mutex);
+
+       dbus_connection_unref(connection);
 }
index 92a97f2..10f9fe6 100644 (file)
@@ -127,7 +127,7 @@ int main(int argc, char *argv[])
 
        __connman_log_init(option_detach, option_debug);
 
-       __connman_element_init();
+       __connman_element_init(conn);
 
        __connman_agent_init(conn);
 
index 7de3668..8ba4f02 100644 (file)
 
 #include "connman.h"
 
-static DBusMessage *list_interfaces(DBusConnection *conn,
+static DBusMessage *register_agent(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
        DBusMessage *reply;
-       DBusMessageIter array, iter;
+       const char *sender, *path;
 
        DBG("conn %p", conn);
 
+       sender = dbus_message_get_sender(msg);
+
+       dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+                                                       DBUS_TYPE_INVALID);
+
        reply = dbus_message_new_method_return(msg);
        if (reply == NULL)
                return NULL;
 
-       dbus_message_iter_init_append(reply, &array);
-
-       dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
-                               DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
-
-       __connman_iface_list(&iter);
+       dbus_message_append_args(reply, DBUS_TYPE_INVALID);
 
-       dbus_message_iter_close_container(&array, &iter);
+       __connman_agent_register(sender, path);
 
        return reply;
 }
 
-static DBusMessage *get_state(DBusConnection *conn,
+static DBusMessage *unregister_agent(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
        DBusMessage *reply;
-       const char *state;
+       const char *sender, *path;
 
        DBG("conn %p", conn);
 
+       sender = dbus_message_get_sender(msg);
+
+       dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+                                                       DBUS_TYPE_INVALID);
+
        reply = dbus_message_new_method_return(msg);
        if (reply == NULL)
                return NULL;
 
-       if (__connman_iface_is_connected() == TRUE)
-               state = "online";
-       else
-               state = "offline";
+       dbus_message_append_args(reply, DBUS_TYPE_INVALID);
 
-       dbus_message_append_args(reply, DBUS_TYPE_STRING, &state,
-                                                       DBUS_TYPE_INVALID);
+       __connman_agent_unregister(sender, path);
 
        return reply;
 }
 
-static DBusMessage *register_agent(DBusConnection *conn,
+static DBusMessage *list_elements(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
        DBusMessage *reply;
-       const char *sender, *path;
+       DBusMessageIter array, iter;
 
        DBG("conn %p", conn);
 
-       sender = dbus_message_get_sender(msg);
-
-       dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
-                                                       DBUS_TYPE_INVALID);
-
        reply = dbus_message_new_method_return(msg);
        if (reply == NULL)
                return NULL;
 
-       dbus_message_append_args(reply, DBUS_TYPE_INVALID);
+       dbus_message_iter_init_append(reply, &array);
 
-       __connman_agent_register(sender, path);
+       dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
+                               DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
+
+       __connman_element_list(CONNMAN_ELEMENT_TYPE_UNKNOWN, &iter);
+
+       dbus_message_iter_close_container(&array, &iter);
 
        return reply;
 }
 
-static DBusMessage *unregister_agent(DBusConnection *conn,
+static DBusMessage *list_devices(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
        DBusMessage *reply;
-       const char *sender, *path;
+       DBusMessageIter array, iter;
 
        DBG("conn %p", conn);
 
-       sender = dbus_message_get_sender(msg);
-
-       dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
-                                                       DBUS_TYPE_INVALID);
-
        reply = dbus_message_new_method_return(msg);
        if (reply == NULL)
                return NULL;
 
-       dbus_message_append_args(reply, DBUS_TYPE_INVALID);
+       dbus_message_iter_init_append(reply, &array);
 
-       __connman_agent_unregister(sender, path);
+       dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
+                               DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter);
+
+       __connman_element_list(CONNMAN_ELEMENT_TYPE_DEVICE, &iter);
+
+       dbus_message_iter_close_container(&array, &iter);
 
        return reply;
 }
 
 static GDBusMethodTable manager_methods[] = {
-       { "ListInterfaces",  "",  "ao", list_interfaces  },
-       { "GetState",        "",  "s",  get_state        },
-       { "RegisterAgent",   "o", "",   register_agent   },
-       { "UnregisterAgent", "o", "",   unregister_agent },
+       { "RegisterAgent",   "o", "", register_agent   },
+       { "UnregisterAgent", "o", "", unregister_agent },
+
+       { "ListElements", "", "ao", list_elements },
+       { "ListDevices",  "", "ao", list_devices  },
        { },
 };
 
 static GDBusSignalTable manager_signals[] = {
-       { "InterfaceAdded",   "o" },
-       { "InterfaceRemoved", "o" },
-       { "StateChanged",     "s" },
+       { "ElementAdded",   "o" },
+       { "ElementUpdated", "o" },
+       { "ElementRemoved", "o" },
+       { "DeviceAdded",    "o" },
+       { "DeviceRemoved",  "o" },
        { },
 };
 
@@ -189,10 +193,7 @@ static DBusMessage *nm_state(DBusConnection *conn,
        if (reply == NULL)
                return NULL;
 
-       if (__connman_iface_is_connected() == TRUE)
-               state = NM_STATE_CONNECTED;
-       else
-               state = NM_STATE_DISCONNECTED;
+       state = NM_STATE_DISCONNECTED;
 
        dbus_message_append_args(reply, DBUS_TYPE_UINT32, &state,
                                                        DBUS_TYPE_INVALID);
diff --git a/test/list-devices b/test/list-devices
new file mode 100755 (executable)
index 0000000..9b9615b
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+
+import dbus
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object("org.moblin.connman", "/"),
+                                       "org.moblin.connman.Manager")
+
+devices = manager.ListDevices()
+
+for path in devices:
+       print "[ %s ]" % (path)
+
+       element = dbus.Interface(bus.get_object("org.moblin.connman", path),
+                                               "org.moblin.connman.Element")
+
+       properties = element.GetProperties()
+       for key in properties.keys():
+               print "    %s = %s" % (key, properties[key])
+
+       print
diff --git a/test/list-elements b/test/list-elements
new file mode 100755 (executable)
index 0000000..3def881
--- /dev/null
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+
+import dbus
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object("org.moblin.connman", "/"),
+                                       "org.moblin.connman.Manager")
+
+elements = manager.ListElements()
+
+for path in elements:
+       print "[ %s ]" % (path)
+
+       element = dbus.Interface(bus.get_object("org.moblin.connman", path),
+                                               "org.moblin.connman.Element")
+
+       properties = element.GetProperties()
+       for key in properties.keys():
+               print "    %s = %s" % (key, properties[key])
+
+       print
diff --git a/test/list-interfaces b/test/list-interfaces
deleted file mode 100755 (executable)
index 3a54a26..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/python
-
-import dbus
-
-bus = dbus.SystemBus()
-
-manager = dbus.Interface(bus.get_object('org.moblin.connman', "/"),
-                                       'org.moblin.connman.Manager')
-
-interfaces = manager.ListInterfaces()
-
-for path in interfaces:
-       print "[ %s ]" % (path)
-
-       interface = dbus.Interface(bus.get_object('org.moblin.connman', path),
-                                       'org.moblin.connman.Interface')
-
-       properties = interface.GetProperties()
-       for key in properties.keys():
-               print "    %s = %s" % (key, properties[key])
-
-       ipv4 = interface.GetIPv4()
-       for key in ipv4.keys():
-               print "    IPv4.%s = %s" % (key, ipv4[key])
-
-       networks = interface.ListNetworks()
-       for i in networks:
-               print "    Network.Path = %s" % (i)
-
-               network = dbus.Interface(bus.get_object('org.moblin.connman', i),
-                                               'org.moblin.connman.Network')
-
-               print "    Network.Identifier = %s" % (network.GetIdentifier())
-               print "    Network.Passphrase = %s" % (network.GetPassphrase())
-
-       print
diff --git a/test/monitor-elements b/test/monitor-elements
new file mode 100755 (executable)
index 0000000..8180395
--- /dev/null
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+
+import gobject
+
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+
+def element_print(action, path):
+       print "%s [ %s ]" % (action, path)
+
+       if (action == "-"):
+               return
+
+       element = dbus.Interface(bus.get_object("org.moblin.connman", path),
+                                               "org.moblin.connman.Element")
+
+       properties = element.GetProperties()
+       for key in properties.keys():
+               print "      %s = %s" % (key, properties[key])
+
+def element_added(path):
+       element_print("+", path)
+
+def element_updated(path):
+       element_print("*", path)
+
+def element_removed(path):
+       element_print("-", path)
+
+if __name__ == '__main__':
+       dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+       bus = dbus.SystemBus()
+
+       bus.add_signal_receiver(element_added,
+                               dbus_interface = "org.moblin.connman.Manager",
+                                               signal_name = "ElementAdded")
+
+       bus.add_signal_receiver(element_updated,
+                               dbus_interface = "org.moblin.connman.Manager",
+                                               signal_name = "ElementUpdated")
+
+       bus.add_signal_receiver(element_removed,
+                               dbus_interface = "org.moblin.connman.Manager",
+                                               signal_name = "ElementRemoved")
+
+       mainloop = gobject.MainLoop()
+       mainloop.run()
index c1cb0ef..86faca1 100755 (executable)
@@ -4,18 +4,18 @@ import dbus
 
 bus = dbus.SystemBus()
 
-object = dbus.Interface(bus.get_object('org.moblin.connman', '/'),
-                               'org.freedesktop.DBus.Introspectable')
+object = dbus.Interface(bus.get_object("org.moblin.connman", '/'),
+                               "org.freedesktop.DBus.Introspectable")
 
 print object.Introspect()
 
-manager = dbus.Interface(bus.get_object('org.moblin.connman', "/"),
-                                       'org.moblin.connman.Manager')
+manager = dbus.Interface(bus.get_object("org.moblin.connman", "/"),
+                                       "org.moblin.connman.Manager")
 
-interfaces = manager.ListInterfaces()
+elements = manager.ListElements()
 
-for path in interfaces:
-       object = dbus.Interface(bus.get_object('org.moblin.connman', path),
-                                       'org.freedesktop.DBus.Introspectable')
+for path in elements:
+       object = dbus.Interface(bus.get_object("org.moblin.connman", path),
+                                       "org.freedesktop.DBus.Introspectable")
 
        print object.Introspect()