gsupplicant: Get all BSSs when scan is done
authorLeena Gunda <leena.gunda@wipro.com>
Fri, 22 Oct 2010 09:53:39 +0000 (11:53 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 22 Oct 2010 09:59:01 +0000 (11:59 +0200)
After a scan, all BSSs need to be refreshed and passed back to the device
layer or else the WiFi device networks list is emptied.

Fixes BMC#8324
Fixes BMC#8363

gsupplicant/dbus.c
gsupplicant/dbus.h
gsupplicant/supplicant.c

index 23593f4..53c56ae 100644 (file)
@@ -182,6 +182,90 @@ int supplicant_dbus_property_get_all(const char *path, const char *interface,
        return 0;
 }
 
+static void property_get_reply(DBusPendingCall *call, void *user_data)
+{
+       struct property_get_data *data = user_data;
+       DBusMessage *reply;
+       DBusMessageIter iter;
+
+       reply = dbus_pending_call_steal_reply(call);
+
+       if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR)
+               goto done;
+
+       if (dbus_message_iter_init(reply, &iter) == FALSE)
+               goto done;
+
+       if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) {
+               DBusMessageIter variant;
+
+               dbus_message_iter_recurse(&iter, &variant);
+
+               if (data->function != NULL)
+                       data->function(NULL, &variant, data->user_data);
+       }
+done:
+       dbus_message_unref(reply);
+
+       dbus_pending_call_unref(call);
+}
+
+int supplicant_dbus_property_get(const char *path, const char *interface,
+                               const char *method,
+                               supplicant_dbus_property_function function,
+                                                       void *user_data)
+{
+       struct property_get_data *data;
+       DBusMessage *message;
+       DBusPendingCall *call;
+
+       if (connection == NULL)
+               return -EINVAL;
+
+       if (path == NULL || interface == NULL || method == NULL)
+               return -EINVAL;
+
+       data = dbus_malloc0(sizeof(*data));
+       if (data == NULL)
+               return -ENOMEM;
+
+       message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path,
+                                       DBUS_INTERFACE_PROPERTIES, "Get");
+
+       if (message == NULL) {
+               dbus_free(data);
+               return -ENOMEM;
+       }
+
+       dbus_message_set_auto_start(message, FALSE);
+
+       dbus_message_append_args(message, DBUS_TYPE_STRING, &interface,
+                                       DBUS_TYPE_STRING, &method, NULL);
+
+       if (dbus_connection_send_with_reply(connection, message,
+                                               &call, TIMEOUT) == FALSE) {
+               dbus_message_unref(message);
+               dbus_free(data);
+               return -EIO;
+       }
+
+       if (call == NULL) {
+               dbus_message_unref(message);
+               dbus_free(data);
+               return -EIO;
+       }
+
+       data->function = function;
+       data->user_data = user_data;
+
+       dbus_pending_call_set_notify(call, property_get_reply,
+                                                       data, dbus_free);
+
+       dbus_message_unref(message);
+
+       return 0;
+}
+
 struct property_set_data {
        supplicant_dbus_result_function function;
        void *user_data;
index 254b93e..642e8b1 100644 (file)
@@ -51,6 +51,11 @@ int supplicant_dbus_property_get_all(const char *path, const char *interface,
                                supplicant_dbus_property_function function,
                                                        void *user_data);
 
+int supplicant_dbus_property_get(const char *path, const char *interface,
+                               const char *method,
+                               supplicant_dbus_property_function function,
+                                                       void *user_data);
+
 int supplicant_dbus_property_set(const char *path, const char *interface,
                                const char *key, const char *signature,
                                supplicant_dbus_setup_function setup,
index 2670c94..322b63d 100644 (file)
@@ -1300,6 +1300,45 @@ static void interface_property(const char *key, DBusMessageIter *iter,
                                key, dbus_message_iter_get_arg_type(iter));
 }
 
+static void scan_network_update(DBusMessageIter *iter, void *user_data)
+{
+       GSupplicantInterface *interface = user_data;
+       GSupplicantNetwork *network;
+       char *path;
+
+       if (iter == NULL)
+               return;
+
+       dbus_message_iter_get_basic(iter, &path);
+
+       if (path == NULL)
+               return;
+
+       if (g_strcmp0(path, "/") == 0)
+               return;
+
+       /* Update the network details based on scan BSS data */
+       network = g_hash_table_lookup(interface->bss_mapping, path);
+       if (network != NULL)
+               callback_network_added(network);
+}
+
+static void scan_bss_data(const char *key, DBusMessageIter *iter,
+                               void *user_data)
+{
+       GSupplicantInterface *interface = user_data;
+
+       if (iter)
+               supplicant_dbus_array_foreach(iter, scan_network_update,
+                                               interface);
+
+       if (interface->scan_callback != NULL)
+               interface->scan_callback(0, interface, interface->scan_data);
+
+       interface->scan_callback = NULL;
+       interface->scan_data = NULL;
+}
+
 static GSupplicantInterface *interface_alloc(const char *path)
 {
        GSupplicantInterface *interface;
@@ -1511,18 +1550,23 @@ static void signal_scan_done(const char *path, DBusMessageIter *iter)
 
        dbus_message_iter_get_basic(iter, &success);
 
-       if (interface->scan_callback != NULL) {
-               int result = 0;
+       /*
+        * If scan is unsuccessful return -EIO else get the scanned BSSs
+        * and update the network details accordingly
+        */
+       if (success == FALSE) {
+               if (interface->scan_callback != NULL)
+                       interface->scan_callback(-EIO, interface,
+                                               interface->scan_data);
 
-               if (success == FALSE)
-                       result = -EIO;
+               interface->scan_callback = NULL;
+               interface->scan_data = NULL;
 
-               interface->scan_callback(result, interface,
-                                               interface->scan_data);
+               return;
        }
 
-       interface->scan_callback = NULL;
-       interface->scan_data = NULL;
+       supplicant_dbus_property_get(path, SUPPLICANT_INTERFACE ".Interface",
+                                       "BSSs", scan_bss_data, interface);
 }
 
 static void signal_bss_added(const char *path, DBusMessageIter *iter)