Assign supplicant filter only once
authorMarcel Holtmann <marcel@holtmann.org>
Thu, 16 Oct 2008 05:52:06 +0000 (07:52 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 16 Oct 2008 05:52:06 +0000 (07:52 +0200)
plugins/supplicant.c
plugins/supplicant.h
plugins/wifi.c

index b0d74c6..8944d43 100644 (file)
@@ -38,7 +38,6 @@
 #define IEEE80211_CAP_PRIVACY   0x0010
 
 struct supplicant_task {
-       DBusConnection *conn;
        int ifindex;
        gchar *ifname;
        struct connman_element *element;
@@ -52,6 +51,8 @@ struct supplicant_task {
 static GStaticMutex task_mutex = G_STATIC_MUTEX_INIT;
 static GSList *task_list = NULL;
 
+static DBusConnection *connection;
+
 static struct supplicant_task *find_task_by_index(int index)
 {
        GSList *list;
@@ -66,6 +67,20 @@ static struct supplicant_task *find_task_by_index(int index)
        return NULL;
 }
 
+static struct supplicant_task *find_task_by_path(const char *path)
+{
+       GSList *list;
+
+       for (list = task_list; list; list = list->next) {
+               struct supplicant_task *task = list->data;
+
+               if (g_str_equal(task->path, path) == TRUE)
+                       return task;
+       }
+
+       return NULL;
+}
+
 static int get_interface(struct supplicant_task *task)
 {
        DBusMessage *message, *reply;
@@ -84,7 +99,7 @@ static int get_interface(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -139,7 +154,7 @@ static int add_interface(struct supplicant_task *task)
        dbus_message_append_args(message, DBUS_TYPE_STRING, &task->ifname,
                                                        DBUS_TYPE_INVALID);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -196,7 +211,7 @@ static int remove_interface(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -233,7 +248,7 @@ static int set_ap_scan(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -270,7 +285,7 @@ static int add_network(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -326,7 +341,7 @@ static int remove_network(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -368,7 +383,7 @@ static int select_network(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -404,7 +419,7 @@ static int enable_network(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -440,7 +455,7 @@ static int disable_network(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -529,7 +544,7 @@ static int set_network(struct supplicant_task *task, const char *network,
 
        dbus_error_init(&error);
 
-       reply = dbus_connection_send_with_reply_and_block(task->conn,
+       reply = dbus_connection_send_with_reply_and_block(connection,
                                                        message, -1, &error);
        if (reply == NULL) {
                if (dbus_error_is_set(&error) == TRUE) {
@@ -560,7 +575,7 @@ static int initiate_scan(struct supplicant_task *task)
        if (message == NULL)
                return -ENOMEM;
 
-       if (dbus_connection_send_with_reply(task->conn, message,
+       if (dbus_connection_send_with_reply(connection, message,
                                                &call, TIMEOUT) == FALSE) {
                connman_error("Failed to initiate scan");
                dbus_message_unref(message);
@@ -692,7 +707,7 @@ static int get_network_properties(struct supplicant_task *task,
        if (message == NULL)
                return -ENOMEM;
 
-       if (dbus_connection_send_with_reply(task->conn, message,
+       if (dbus_connection_send_with_reply(connection, message,
                                                &call, TIMEOUT) == FALSE) {
                connman_error("Failed to get network properties");
                dbus_message_unref(message);
@@ -754,7 +769,7 @@ static int scan_results_available(struct supplicant_task *task)
        if (message == NULL)
                return -ENOMEM;
 
-       if (dbus_connection_send_with_reply(task->conn, message,
+       if (dbus_connection_send_with_reply(connection, message,
                                                &call, TIMEOUT) == FALSE) {
                connman_error("Failed to request scan result");
                dbus_message_unref(message);
@@ -823,8 +838,8 @@ static void state_change(struct supplicant_task *task, DBusMessage *msg)
 static DBusHandlerResult supplicant_filter(DBusConnection *conn,
                                                DBusMessage *msg, void *data)
 {
-       struct supplicant_task *task = data;
-       const char *member;
+       struct supplicant_task *task;
+       const char *member, *path;
 
        if (dbus_message_has_interface(msg,
                                SUPPLICANT_INTF ".Interface") == FALSE)
@@ -834,6 +849,14 @@ static DBusHandlerResult supplicant_filter(DBusConnection *conn,
        if (member == NULL)
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
+       path = dbus_message_get_path(msg);
+       if (path == NULL)
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+       task = find_task_by_path(path);
+       if (task == NULL)
+               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
        DBG("task %p member %s", task, member);
 
        if (g_str_equal(member, "ScanResultsAvailable") == TRUE)
@@ -849,10 +872,6 @@ static int add_filter(struct supplicant_task *task)
        DBusError error;
        gchar *filter;
 
-       if (dbus_connection_add_filter(task->conn,
-                               supplicant_filter, task, NULL) == FALSE)
-               return -EIO;
-
        filter = g_strdup_printf("type=signal,interface=%s.Interface,path=%s",
                                                SUPPLICANT_INTF, task->path);
 
@@ -860,7 +879,7 @@ static int add_filter(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       dbus_bus_add_match(task->conn, filter, &error);
+       dbus_bus_add_match(connection, filter, &error);
 
        g_free(filter);
 
@@ -884,7 +903,7 @@ static int remove_filter(struct supplicant_task *task)
 
        dbus_error_init(&error);
 
-       dbus_bus_add_match(task->conn, filter, &error);
+       dbus_bus_remove_match(connection, filter, &error);
 
        g_free(filter);
 
@@ -893,8 +912,6 @@ static int remove_filter(struct supplicant_task *task)
                dbus_error_free(&error);
        }
 
-       dbus_connection_remove_filter(task->conn, supplicant_filter, task);
-
        return 0;
 }
 
@@ -920,12 +937,6 @@ int __supplicant_start(struct connman_element *element,
                return -ENOMEM;
        }
 
-       task->conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
-       if (task->conn == NULL) {
-               g_free(task);
-               return -EIO;
-       }
-
        task->created = FALSE;
        task->state = STATE_INACTIVE;
 
@@ -971,8 +982,6 @@ int __supplicant_stop(struct connman_element *element)
 
        remove_interface(task);
 
-       dbus_connection_unref(task->conn);
-
        g_free(task->ifname);
        g_free(task->path);
        g_free(task);
@@ -1011,6 +1020,7 @@ int __supplicant_scan(struct connman_element *element)
 int __supplicant_connect(struct connman_element *element, const char *ssid)
 {
        struct supplicant_task *task;
+       const char *passphrase = NULL;
 
        DBG("element %p name %s", element, element->name);
 
@@ -1023,7 +1033,7 @@ int __supplicant_connect(struct connman_element *element, const char *ssid)
        select_network(task);
        disable_network(task);
 
-       set_network(task, ssid, NULL);
+       set_network(task, ssid, passphrase);
 
        enable_network(task);
 
@@ -1046,3 +1056,29 @@ int __supplicant_disconnect(struct connman_element *element)
 
        return 0;
 }
+
+int __supplicant_init(void)
+{
+       connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+       if (connection == NULL)
+               return -EIO;
+
+       if (dbus_connection_add_filter(connection,
+                               supplicant_filter, NULL, NULL) == FALSE) {
+               dbus_connection_unref(connection);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+void __supplicant_exit(void)
+{
+       if (connection == NULL)
+               return;
+
+       dbus_connection_remove_filter(connection, supplicant_filter, NULL);
+
+       dbus_connection_unref(connection);
+       connection = NULL;
+}
index 9b4f6eb..20552e6 100644 (file)
@@ -52,6 +52,9 @@ struct supplicant_callback {
                                        struct supplicant_network *network);
 };
 
+int __supplicant_init(void);
+void __supplicant_exit(void);
+
 int __supplicant_start(struct connman_element *element,
                                        struct supplicant_callback *callback);
 int __supplicant_stop(struct connman_element *element);
index f4c3373..6be82b4 100644 (file)
@@ -291,13 +291,20 @@ static int wifi_init(void)
 {
        int err;
 
-       err = connman_driver_register(&network_driver);
+       err = __supplicant_init();
        if (err < 0)
                return err;
 
+       err = connman_driver_register(&network_driver);
+       if (err < 0) {
+               __supplicant_exit();
+               return err;
+       }
+
        err = connman_driver_register(&wifi_driver);
        if (err < 0) {
                connman_driver_unregister(&network_driver);
+               __supplicant_exit();
                return err;
        }
 
@@ -308,6 +315,8 @@ static void wifi_exit(void)
 {
        connman_driver_unregister(&network_driver);
        connman_driver_unregister(&wifi_driver);
+
+       __supplicant_exit();
 }
 
 CONNMAN_PLUGIN_DEFINE("wifi", "WiFi interface plugin", VERSION,