From 85161ed17c46ce91fa768576f54c6e2278c07f34 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 29 Jun 2008 04:57:57 +0200 Subject: [PATCH] Add first draft of new D-Bus API --- include/dbus.h | 12 +-- src/connman.h | 9 ++- src/element.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++-- src/main.c | 2 +- src/manager.c | 93 ++++++++++----------- test/list-devices | 22 +++++ test/list-elements | 22 +++++ test/list-interfaces | 36 --------- test/monitor-elements | 49 ++++++++++++ test/show-introspection | 16 ++-- 10 files changed, 364 insertions(+), 106 deletions(-) create mode 100755 test/list-devices create mode 100755 test/list-elements delete mode 100755 test/list-interfaces create mode 100755 test/monitor-elements diff --git a/include/dbus.h b/include/dbus.h index a237e38..be98a4e 100644 --- a/include/dbus.h +++ b/include/dbus.h @@ -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" diff --git a/src/connman.h b/src/connman.h index e4f51df..05bfe36 100644 --- a/src/connman.h +++ b/src/connman.h @@ -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 #include -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 diff --git a/src/element.c b/src/element.c index 71332d0..a4f0328 100644 --- a/src/element.c +++ b/src/element.c @@ -26,10 +26,12 @@ #include #include -#include +#include #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); } diff --git a/src/main.c b/src/main.c index 92a97f2..10f9fe6 100644 --- a/src/main.c +++ b/src/main.c @@ -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); diff --git a/src/manager.c b/src/manager.c index 7de3668..8ba4f02 100644 --- a/src/manager.c +++ b/src/manager.c @@ -27,113 +27,117 @@ #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 index 0000000..9b9615b --- /dev/null +++ b/test/list-devices @@ -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 index 0000000..3def881 --- /dev/null +++ b/test/list-elements @@ -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 index 3a54a26..0000000 --- a/test/list-interfaces +++ /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 index 0000000..8180395 --- /dev/null +++ b/test/monitor-elements @@ -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() diff --git a/test/show-introspection b/test/show-introspection index c1cb0ef..86faca1 100755 --- a/test/show-introspection +++ b/test/show-introspection @@ -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() -- 2.7.4