Add D-Bus interface features for device driver
authorMarcel Holtmann <marcel@holtmann.org>
Wed, 24 Dec 2008 09:39:28 +0000 (10:39 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 24 Dec 2008 09:39:28 +0000 (10:39 +0100)
include/device.h
src/device.c

index 31531481220429b3926248e4001c1f3952daf824..e59eb3e6503c25982b20377c702ae0f226947495 100644 (file)
@@ -67,6 +67,7 @@ struct connman_device {
        unsigned long capabilities;
        enum connman_device_policy policy;
        enum connman_device_state state;
+       gboolean powered;
 
        struct connman_device_driver *driver;
        void *driver_data;
@@ -74,8 +75,8 @@ struct connman_device {
        GSList *networks;
 };
 
-extern int connman_device_set_enabled(struct connman_device *device,
-                                                       gboolean enabled);
+extern int connman_device_set_powered(struct connman_device *device,
+                                                       gboolean powered);
 
 struct connman_device_driver {
        const char *name;
index b70b95f88bac837decf2e18b40a3bf70e1827230..5c95d6863a7d1b0729d90a089e216142cf9b388e 100644 (file)
 #endif
 
 #include <errno.h>
+#include <gdbus.h>
 
 #include "connman.h"
 
+static DBusMessage *get_properties(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_device *device = data;
+       DBusMessage *reply;
+       DBusMessageIter array, dict;
+
+       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);
+
+       connman_dbus_dict_append_variant(&dict, "Powered",
+                                       DBUS_TYPE_BOOLEAN, &device->powered);
+
+       dbus_message_iter_close_container(&array, &dict);
+
+       return reply;
+}
+
+static DBusMessage *set_property(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       struct connman_element *element = data;
+       DBusMessageIter iter, value;
+       const char *name;
+
+       DBG("conn %p", conn);
+
+       if (dbus_message_iter_init(msg, &iter) == FALSE)
+               return __connman_error_invalid_arguments(msg);
+
+       dbus_message_iter_get_basic(&iter, &name);
+       dbus_message_iter_next(&iter);
+       dbus_message_iter_recurse(&iter, &value);
+
+       if (__connman_security_check_privileges(msg) < 0)
+               return __connman_error_permission_denied(msg);
+
+       __connman_element_store(element);
+
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static DBusMessage *create_network(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       DBG("conn %p", conn);
+
+       if (__connman_security_check_privileges(msg) < 0)
+               return __connman_error_permission_denied(msg);
+
+       return __connman_error_invalid_arguments(msg);
+}
+
+static DBusMessage *remove_network(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       DBG("conn %p", conn);
+
+       if (__connman_security_check_privileges(msg) < 0)
+               return __connman_error_permission_denied(msg);
+
+       return __connman_error_invalid_arguments(msg);
+}
+
+static DBusMessage *propose_scan(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       DBG("conn %p", conn);
+
+       return __connman_error_failed(msg);
+}
+
+static GDBusMethodTable device_methods[] = {
+       { "GetProperties", "",      "a{sv}", get_properties },
+       { "SetProperty",   "sv",    "",      set_property   },
+       { "CreateNetwork", "a{sv}", "o",     create_network },
+       { "RemoveNetwork", "o",     "",      remove_network },
+       { "ProposeScan",   "",      "",      propose_scan   },
+       { },
+};
+
+static GDBusSignalTable device_signals[] = {
+       { "PropertyChanged", "sv" },
+       { },
+};
+
+static DBusConnection *connection;
+
+static int register_interface(struct connman_element *element)
+{
+       struct connman_device *device = connman_element_get_data(element);
+
+       g_dbus_unregister_interface(connection, element->path,
+                                               CONNMAN_DEVICE_INTERFACE);
+
+       if (g_dbus_register_interface(connection, element->path,
+                                       CONNMAN_DEVICE_INTERFACE,
+                                       device_methods, device_signals,
+                                       NULL, device, NULL) == FALSE) {
+               connman_error("Failed to register %s device", element->path);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static void unregister_interface(struct connman_element *element)
+{
+       g_dbus_unregister_interface(connection, element->path,
+                                               CONNMAN_DEVICE_INTERFACE);
+}
+
 static GSList *driver_list = NULL;
 
+static gint compare_priority(gconstpointer a, gconstpointer b)
+{
+       const struct connman_device_driver *driver1 = a;
+       const struct connman_device_driver *driver2 = b;
+
+       return driver2->priority - driver1->priority;
+}
+
+/**
+ * connman_device_driver_register:
+ * @driver: device driver definition
+ *
+ * Register a new device driver
+ *
+ * Returns: %0 on success
+ */
+int connman_device_driver_register(struct connman_device_driver *driver)
+{
+       DBG("driver %p name %s", driver, driver->name);
+
+       driver_list = g_slist_insert_sorted(driver_list, driver,
+                                                       compare_priority);
+
+       //__connman_driver_rescan(&device_driver);
+
+       return 0;
+}
+
+/**
+ * connman_device_driver_unregister:
+ * @driver: device driver definition
+ *
+ * Remove a previously registered device driver
+ */
+void connman_device_driver_unregister(struct connman_device_driver *driver)
+{
+       DBG("driver %p name %s", driver, driver->name);
+
+       driver_list = g_slist_remove(driver_list, driver);
+}
+
+/**
+ * connman_device_set_powered:
+ * @device: device structure
+ *
+ * Change power state of device
+ */
+int connman_device_set_powered(struct connman_device *device,
+                                                       gboolean powered)
+{
+       DBG("driver %p powered %d", device, powered);
+
+       if (device->powered == powered)
+               return -EALREADY;
+
+       device->powered = powered;
+
+       return 0;
+}
+
 static gboolean match_driver(struct connman_device *device,
                                        struct connman_device_driver *driver)
 {
@@ -43,6 +226,7 @@ static int device_probe(struct connman_element *element)
 {
        struct connman_device *device;
        GSList *list;
+       int err;
 
        DBG("element %p name %s", element, element->name);
 
@@ -55,6 +239,14 @@ static int device_probe(struct connman_element *element)
 
        device->element = element;
 
+       connman_element_set_data(element, device);
+
+       err = register_interface(element);
+       if (err < 0) {
+               g_free(device);
+               return err;
+       }
+
        for (list = driver_list; list; list = list->next) {
                struct connman_device_driver *driver = list->data;
 
@@ -65,14 +257,11 @@ static int device_probe(struct connman_element *element)
 
                if (driver->probe(device) == 0) {
                        device->driver = driver;
-                       connman_element_set_data(element, device);
-                       return 0;
+                       break;
                }
        }
 
-       g_free(device);
-
-       return -ENODEV;
+       return 0;
 }
 
 static void device_remove(struct connman_element *element)
@@ -81,6 +270,8 @@ static void device_remove(struct connman_element *element)
 
        DBG("element %p name %s", element, element->name);
 
+       unregister_interface(element);
+
        if (device->driver && device->driver->remove)
                device->driver->remove(device);
 
@@ -101,6 +292,8 @@ int __connman_device_init(void)
 {
        DBG("");
 
+       connection = connman_dbus_get_connection();
+
        return connman_driver_register(&device_driver);
 }
 
@@ -109,45 +302,6 @@ void __connman_device_cleanup(void)
        DBG("");
 
        connman_driver_unregister(&device_driver);
-}
-
-static gint compare_priority(gconstpointer a, gconstpointer b)
-{
-       const struct connman_device_driver *driver1 = a;
-       const struct connman_device_driver *driver2 = b;
-
-       return driver2->priority - driver1->priority;
-}
 
-/**
- * connman_device_driver_register:
- * @driver: device driver definition
- *
- * Register a new device driver
- *
- * Returns: %0 on success
- */
-int connman_device_driver_register(struct connman_device_driver *driver)
-{
-       DBG("driver %p name %s", driver, driver->name);
-
-       driver_list = g_slist_insert_sorted(driver_list, driver,
-                                                       compare_priority);
-
-       //__connman_driver_rescan(&device_driver);
-
-       return 0;
-}
-
-/**
- * connman_device_driver_unregister:
- * @driver: device driver definition
- *
- * Remove a previously registered device driver
- */
-void connman_device_driver_unregister(struct connman_device_driver *driver)
-{
-       DBG("driver %p name %s", driver, driver->name);
-
-       driver_list = g_slist_remove(driver_list, driver);
+       dbus_connection_unref(connection);
 }