Below is patch for:
http://bugs.meego.com/show_bug.cgi?id=10454
http://bugs.meego.com/show_bug.cgi?id=11201

When ConnMan is SIGKILLed and restarted WiFi plugin will reuse the existing 
interface. It will get a list of existing BSSs and for each BSS in the BSSs 
list, interface_bss_added() is called. In interface_bss_added() if there is a 
next DBusMessageIter iterator and if it is valid, it is assumed that the next 
iterator would contain the key/value pairs for the BSS properties and 
bss_property is invoked. But for the BSSs list the next iterator contains the 
object path of next BSS in the list. As a result we get no properties for the 
BSS and a GSupplicantNetwork is created with empty ssid etc. 

Also for the BSSs list, supplicant_dbus_array_foreach() is invoked with 
interface_bss_added() as callback. In interface_bss_added() the iter is moved 
to the next iterator. Now supplicant_dbus_array_foreach() again moves the 
iterator to next after the callback is invoked. As a result we end up moving 
the iterator twice and miss adding few BSS from the BSSs list. And hence the 
bug.

interface_bss_added() is called with BSS followed by its properties only from 
signal_bss_added(). Whereas for CurrentBSS and BSSs list GetAll D-Bus method is 
invoked for fetching the BSS's properties.

Separating the cases of BSS's being added with and without properties will fix 
the issue.

---
 gsupplicant/supplicant.c |   54 ++++++++++++++++++++++++++++++++++-----------
 1 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 0e4f932..bb77537 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -1137,7 +1137,8 @@ static void bss_property(const char *key, DBusMessageIter 
*iter,
                                key, dbus_message_iter_get_arg_type(iter));
 }
 
-static void interface_bss_added(DBusMessageIter *iter, void *user_data)
+static struct g_supplicant_bss *interface_bss_added(DBusMessageIter *iter,
+                                                       void *user_data)
 {
        GSupplicantInterface *interface = user_data;
        GSupplicantNetwork *network;
@@ -1148,10 +1149,10 @@ static void interface_bss_added(DBusMessageIter *iter, 
void *user_data)
 
        dbus_message_iter_get_basic(iter, &path);
        if (path == NULL)
-               return;
+               return NULL;
 
        if (g_strcmp0(path, "/") == 0)
-               return;
+               return NULL;
 
        SUPPLICANT_DBG("%s", path);
 
@@ -1159,24 +1160,51 @@ static void interface_bss_added(DBusMessageIter *iter, 
void *user_data)
        if (network != NULL) {
                bss = g_hash_table_lookup(network->bss_table, path);
                if (bss != NULL)
-                       return;
+                       return NULL;
        }
 
        bss = g_try_new0(struct g_supplicant_bss, 1);
        if (bss == NULL)
-               return;
+               return NULL;
 
        bss->interface = interface;
        bss->path = g_strdup(path);
 
+       return bss;
+}
+
+static void interface_bss_added_with_keys(DBusMessageIter *iter, void 
*user_data)
+{
+       struct g_supplicant_bss *bss = NULL;
+
+       SUPPLICANT_DBG("");
+
+       bss = interface_bss_added(iter, user_data);
+
+       if (bss == NULL)
+               return;
+
        dbus_message_iter_next(iter);
-       if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) {
-               supplicant_dbus_property_foreach(iter, bss_property, bss);
-               bss_property(NULL, NULL, bss);
+
+       if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_INVALID)
                return;
-       }
+ 
+       supplicant_dbus_property_foreach(iter, bss_property, bss);
+       bss_property(NULL, NULL, bss);
+}
+       
+static void interface_bss_added_without_keys(DBusMessageIter *iter, void 
*user_data)
+{
+       struct g_supplicant_bss *bss = NULL;
 
-       supplicant_dbus_property_get_all(path,
+       SUPPLICANT_DBG("");
+
+       bss = interface_bss_added(iter, user_data);
+
+       if (bss == NULL)
+               return;
+
+       supplicant_dbus_property_get_all(bss->path,
                                        SUPPLICANT_INTERFACE ".BSS",
                                                        bss_property, bss);
 }
@@ -1285,11 +1313,11 @@ static void interface_property(const char *key, 
DBusMessageIter *iter,
                if (str != NULL)
                        interface->bridge = g_strdup(str);
        } else if (g_strcmp0(key, "CurrentBSS") == 0) {
-               interface_bss_added(iter, interface);
+               interface_bss_added_without_keys(iter, interface);
        } else if (g_strcmp0(key, "CurrentNetwork") == 0) {
                interface_network_added(iter, interface);
        } else if (g_strcmp0(key, "BSSs") == 0) {
-               supplicant_dbus_array_foreach(iter, interface_bss_added,
+               supplicant_dbus_array_foreach(iter, 
interface_bss_added_without_keys,
                                                                interface);
        } else if (g_strcmp0(key, "Blobs") == 0) {
                /* Nothing */
@@ -1580,7 +1608,7 @@ static void signal_bss_added(const char *path, 
DBusMessageIter *iter)
        if (interface == NULL)
                return;
 
-       interface_bss_added(iter, interface);
+       interface_bss_added_with_keys(iter, interface);
 }
 
 static void signal_bss_removed(const char *path, DBusMessageIter *iter)
-- 
1.7.2.2

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to