Add PropertyChanged signal declaration
[connman] / src / element.c
index e24b1e0..6086b7b 100644 (file)
@@ -40,6 +40,8 @@ static GSList *driver_list = NULL;
 static GThreadPool *thread_register = NULL;
 static GThreadPool *thread_unregister = NULL;
 
+static gchar *device_filter = NULL;
+
 static const char *type2string(enum connman_element_type type)
 {
        switch (type) {
@@ -102,6 +104,9 @@ static void append_entry(DBusMessageIter *dict,
        dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
 
        switch (type) {
+       case DBUS_TYPE_BOOLEAN:
+               signature = DBUS_TYPE_BOOLEAN_AS_STRING;
+               break;
        case DBUS_TYPE_STRING:
                signature = DBUS_TYPE_STRING_AS_STRING;
                break;
@@ -170,6 +175,9 @@ static DBusMessage *get_properties(DBusConnection *conn,
        if (str != NULL)
                append_entry(&dict, "Subtype", DBUS_TYPE_STRING, &str);
 
+       append_entry(&dict, "Connected",
+                               DBUS_TYPE_BOOLEAN, &element->connected);
+
        if (element->priority > 0)
                append_entry(&dict, "Priority",
                                DBUS_TYPE_UINT16, &element->priority);
@@ -199,8 +207,77 @@ static DBusMessage *get_properties(DBusConnection *conn,
        return reply;
 }
 
+static DBusMessage *set_property(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *do_update(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_element *element = data;
+
+       DBG("conn %p", conn);
+
+       if (element->driver == NULL)
+               return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+       if (element->driver->update) {
+               DBG("Calling update callback");
+               element->driver->update(element);
+       }
+
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *do_connect(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_element *element = data;
+
+       DBG("conn %p", conn);
+
+       if (element->driver == NULL)
+               return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+       if (element->driver->connect) {
+               DBG("Calling connect callback");
+               element->driver->connect(element);
+       }
+
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *do_disconnect(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_element *element = data;
+
+       DBG("conn %p", conn);
+
+       if (element->driver == NULL)
+               return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+
+       if (element->driver->disconnect) {
+               DBG("Calling disconnect callback");
+               element->driver->disconnect(element);
+       }
+
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
 static GDBusMethodTable element_methods[] = {
-       { "GetProperties", "", "a{sv}", get_properties },
+       { "GetProperties", "",   "a{sv}", get_properties },
+       { "SetProperty",   "sv", "",      set_property   },
+       { "Update",        "",   "",      do_update      },
+       { "Connect",       "",   "",      do_connect     },
+       { "Disconnect",    "",   "",      do_disconnect  },
+       { },
+};
+
+static GDBusSignalTable element_signals[] = {
+       { "PropertyChanged", "sv" },
        { },
 };
 
@@ -253,6 +330,9 @@ static gint compare_priority(gconstpointer a, gconstpointer b)
 static gboolean match_driver(struct connman_element *element,
                                        struct connman_driver *driver)
 {
+       if (element->type == CONNMAN_ELEMENT_TYPE_ROOT)
+               return FALSE;
+
        if (element->type != driver->type &&
                        driver->type != CONNMAN_ELEMENT_TYPE_UNKNOWN)
                return FALSE;
@@ -357,6 +437,8 @@ struct connman_element *connman_element_create(void)
        element->subtype = CONNMAN_ELEMENT_SUBTYPE_UNKNOWN;
        element->state   = CONNMAN_ELEMENT_STATE_CLOSED;
 
+       element->connected = FALSE;
+
        element->netdev.index = -1;
 
        return element;
@@ -529,6 +611,11 @@ int connman_element_register(struct connman_element *element,
 {
        DBG("element %p name %s parent %p", element, element->name, parent);
 
+       if (device_filter && element->type == CONNMAN_ELEMENT_TYPE_DEVICE) {
+               if (g_str_equal(device_filter, element->netdev.name) == FALSE)
+                       return -EINVAL;
+       }
+
        if (connman_element_ref(element) == NULL)
                return -EINVAL;
 
@@ -630,14 +717,10 @@ static void register_element(gpointer data, gpointer user_data)
 
        g_node_append_data(node, element);
 
-       g_static_rw_lock_writer_unlock(&element_lock);
-
-       __connman_element_store(element);
-
        if (g_dbus_register_interface(connection, element->path,
                                        CONNMAN_ELEMENT_INTERFACE,
-                                       element_methods, NULL, NULL,
-                                               element, NULL) == FALSE)
+                                       element_methods, element_signals,
+                                       NULL, element, NULL) == FALSE)
                connman_error("Failed to register %s", element->path);
 
        g_dbus_emit_signal(connection, CONNMAN_MANAGER_PATH,
@@ -645,11 +728,9 @@ static void register_element(gpointer data, gpointer user_data)
                                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_static_rw_lock_writer_unlock(&element_lock);
+
+       __connman_element_store(element);
 
        g_static_rw_lock_writer_lock(&element_lock);
 
@@ -672,17 +753,12 @@ static void register_element(gpointer data, gpointer user_data)
        g_static_rw_lock_writer_unlock(&element_lock);
 }
 
-static void unregister_element(gpointer data, gpointer user_data)
+static gboolean remove_element(GNode *node, gpointer user_data)
 {
-       struct connman_element *element = data;
-       GNode *node;
+       struct connman_element *element = node->data;
 
        DBG("element %p name %s", element, element->name);
 
-       g_static_rw_lock_writer_lock(&element_lock);
-
-       node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
-
        if (element->driver) {
                if (element->driver->remove)
                        element->driver->remove(element);
@@ -697,14 +773,6 @@ static void unregister_element(gpointer data, gpointer user_data)
                g_node_destroy(node);
        }
 
-       g_static_rw_lock_writer_unlock(&element_lock);
-
-       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,
@@ -714,9 +782,29 @@ static void unregister_element(gpointer data, gpointer user_data)
                                                CONNMAN_ELEMENT_INTERFACE);
 
        connman_element_unref(element);
+
+       return FALSE;
+}
+
+static void unregister_element(gpointer data, gpointer user_data)
+{
+       struct connman_element *element = data;
+       GNode *node;
+
+       DBG("element %p name %s", element, element->name);
+
+       g_static_rw_lock_writer_lock(&element_lock);
+
+       node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
+
+       if (node != NULL)
+               g_node_traverse(node, G_POST_ORDER,
+                               G_TRAVERSE_ALL, -1, remove_element, NULL);
+
+       g_static_rw_lock_writer_unlock(&element_lock);
 }
 
-int __connman_element_init(DBusConnection *conn)
+int __connman_element_init(DBusConnection *conn, const char *device)
 {
        struct connman_element *element;
 
@@ -726,6 +814,8 @@ int __connman_element_init(DBusConnection *conn)
        if (connection == NULL)
                return -EIO;
 
+       device_filter = g_strdup(device);
+
        g_static_rw_lock_writer_lock(&element_lock);
 
        element = connman_element_create();
@@ -801,5 +891,7 @@ void __connman_element_cleanup(void)
        element_root = NULL;
        g_static_rw_lock_writer_unlock(&element_lock);
 
+       g_free(device_filter);
+
        dbus_connection_unref(connection);
 }