Add basics for a supplicant driver and use it
authorMarcel Holtmann <marcel@holtmann.org>
Sun, 4 Jan 2009 16:48:41 +0000 (17:48 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Sun, 4 Jan 2009 16:48:41 +0000 (17:48 +0100)
plugins/supplicant.c
plugins/supplicant.h
plugins/wifi.c

index 0d7d293..66cf36f 100644 (file)
@@ -25,9 +25,8 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <dbus/dbus.h>
 
-#include <glib.h>
+#include <gdbus.h>
 
 #define CONNMAN_API_SUBJECT_TO_CHANGE
 #include <connman/log.h>
@@ -1109,7 +1108,7 @@ int __supplicant_disconnect(struct connman_element *element)
        return 0;
 }
 
-void __supplicant_activate(DBusConnection *conn)
+static void supplicant_activate(DBusConnection *conn)
 {
        DBusMessage *message;
 
@@ -1127,24 +1126,108 @@ void __supplicant_activate(DBusConnection *conn)
        dbus_message_unref(message);
 }
 
-int __supplicant_init(DBusConnection *conn)
+static GSList *driver_list = NULL;
+
+static void supplicant_probe(DBusConnection *conn, void *user_data)
+{
+       GSList *list;
+
+       DBG("conn %p", conn);
+
+       for (list = driver_list; list; list = list->next) {
+               struct supplicant_driver *driver = list->data;
+
+               DBG("driver %p name %s", driver, driver->name);
+
+               if (driver->probe)
+                       driver->probe();
+       }
+}
+
+static void supplicant_remove(DBusConnection *conn, void *user_data)
 {
+       GSList *list;
+
        DBG("conn %p", conn);
 
-       connection = conn;
+       for (list = driver_list; list; list = list->next) {
+               struct supplicant_driver *driver = list->data;
+
+               DBG("driver %p name %s", driver, driver->name);
+
+               if (driver->remove)
+                       driver->remove();
+       }
+}
+
+static guint watch;
+
+static int supplicant_create(void)
+{
+       if (g_slist_length(driver_list) > 0)
+               return 0;
+
+       connection = connman_dbus_get_connection();
+       if (connection == NULL)
+               return -EIO;
+
+       DBG("connection %p", connection);
 
        if (dbus_connection_add_filter(connection,
                                supplicant_filter, NULL, NULL) == FALSE) {
-               dbus_connection_unref(connection);
+               connection = connman_dbus_get_connection();
                return -EIO;
        }
 
+       watch = g_dbus_add_service_watch(connection, SUPPLICANT_NAME,
+                       supplicant_probe, supplicant_remove, NULL, NULL);
+
        return 0;
 }
 
-void __supplicant_exit(void)
+static void supplicant_destroy(void)
 {
-       DBG("conn %p", connection);
+       if (g_slist_length(driver_list) > 0)
+               return;
+
+       DBG("connection %p", connection);
+
+       if (watch > 0)
+               g_dbus_remove_watch(connection, watch);
 
        dbus_connection_remove_filter(connection, supplicant_filter, NULL);
+
+       dbus_connection_unref(connection);
+       connection = NULL;
+}
+
+int supplicant_register(struct supplicant_driver *driver)
+{
+       int err;
+
+       DBG("driver %p name %s", driver, driver->name);
+
+       err = supplicant_create();
+       if (err < 0)
+               return err;
+
+       driver_list = g_slist_append(driver_list, driver);
+
+       if (g_dbus_check_service(connection, SUPPLICANT_NAME) == TRUE)
+               supplicant_probe(connection, NULL);
+       else
+               supplicant_activate(connection);
+
+       return 0;
+}
+
+void supplicant_unregister(struct supplicant_driver *driver)
+{
+       DBG("driver %p name %s", driver, driver->name);
+
+       supplicant_remove(connection, NULL);
+
+       driver_list = g_slist_remove(driver_list, driver);
+
+       supplicant_destroy();
 }
index 4543d11..849a59d 100644 (file)
@@ -60,10 +60,16 @@ struct supplicant_callback {
                                        struct supplicant_network *network);
 };
 
-void __supplicant_activate(DBusConnection *conn);
+struct supplicant_driver {
+       const char *name;
+       void (*probe) (void);
+       void (*remove) (void);
+};
 
-int __supplicant_init(DBusConnection *conn);
-void __supplicant_exit(void);
+int supplicant_register(struct supplicant_driver *driver);
+void supplicant_unregister(struct supplicant_driver *driver);
+
+void __supplicant_activate(DBusConnection *conn);
 
 int __supplicant_start(struct connman_device *device,
                                        struct supplicant_callback *callback);
index f52d848..6459f76 100644 (file)
 #include <linux/if_arp.h>
 #include <linux/wireless.h>
 
-#include <gdbus.h>
+#include <dbus/dbus.h>
 
 #define CONNMAN_API_SUBJECT_TO_CHANGE
 #include <connman/plugin.h>
+#include <connman/device.h>
 #include <connman/driver.h>
-#include <connman/dbus.h>
 #include <connman/log.h>
 
 #include "inet.h"
@@ -506,62 +506,48 @@ static struct connman_device_driver wifi_driver = {
        .scan           = wifi_scan,
 };
 
-static void supplicant_connect(DBusConnection *connection, void *user_data)
+static void wifi_register(void)
 {
-       DBG("connection %p", connection);
-
-       __supplicant_init(connection);
+       DBG("");
 
        connman_device_driver_register(&wifi_driver);
 }
 
-static void supplicant_disconnect(DBusConnection *connection, void *user_data)
+static void wifi_unregister(void)
 {
-       DBG("connection %p", connection);
+       DBG("");
 
        connman_device_driver_unregister(&wifi_driver);
-
-       __supplicant_exit();
 }
 
-static DBusConnection *connection;
-static guint watch;
+static struct supplicant_driver supplicant = {
+       .name           = "wifi",
+       .probe          = wifi_register,
+       .remove         = wifi_unregister,
+};
 
 static int wifi_init(void)
 {
        int err;
 
-       connection = connman_dbus_get_connection();
-       if (connection == NULL)
-               return -EIO;
-
        err = connman_driver_register(&network_driver);
+       if (err < 0)
+               return err;
+
+       err = supplicant_register(&supplicant);
        if (err < 0) {
-               dbus_connection_unref(connection);
+               connman_driver_unregister(&network_driver);
                return err;
        }
 
-       watch = g_dbus_add_service_watch(connection, SUPPLICANT_NAME,
-                       supplicant_connect, supplicant_disconnect, NULL, NULL);
-
-       if (g_dbus_check_service(connection, SUPPLICANT_NAME) == TRUE)
-               supplicant_connect(connection, NULL);
-       else
-               __supplicant_activate(connection);
-
        return 0;
 }
 
 static void wifi_exit(void)
 {
-       connman_driver_unregister(&network_driver);
-
-       if (watch > 0)
-               g_dbus_remove_watch(connection, watch);
+       supplicant_unregister(&supplicant);
 
-       supplicant_disconnect(connection, NULL);
-
-       dbus_connection_unref(connection);
+       connman_driver_unregister(&network_driver);
 }
 
 CONNMAN_PLUGIN_DEFINE(wifi, "WiFi interface plugin", VERSION,