There exists scenarios, when connman receives a group
request and the requesting peer hasn't been discovered
yet, wpa_supplicant issues a peer found just before
signaling group request. However, the just signaled peer
found have its properties published by wpa_s on a timeout
basis (dbus property), thus causing group request signal
to be "lost", as the ident and other peer information
are not available until this timeout expires in wpa_supplicant.

That said, this patch defers the signaled group request to
be concluded after peer property has been properly filled
in, when, of course, the described scenario occurs.
---
 gsupplicant/supplicant.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index b796524..fd16caf 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -139,6 +139,7 @@ static GHashTable *interface_table;
 static GHashTable *bss_mapping;
 static GHashTable *peer_mapping;
 static GHashTable *group_mapping;
+static GHashTable *pending_peer_connection;
 
 struct _GSupplicantWpsCredentials {
        unsigned char ssid[32];
@@ -599,6 +600,9 @@ static void remove_peer(gpointer data)
        if (peer_mapping)
                g_hash_table_remove(peer_mapping, peer->path);
 
+       if (pending_peer_connection)
+               g_hash_table_remove(pending_peer_connection, peer->path);
+
        g_free(peer->path);
        g_free(peer->name);
        g_free(peer->identifier);
@@ -2575,6 +2579,7 @@ static void peer_groups_relation(DBusMessageIter *iter, 
void *user_data)
 static void peer_property(const char *key, DBusMessageIter *iter,
                                                        void *user_data)
 {
+       GSupplicantPeer *pending_peer;
        GSupplicantPeer *peer = user_data;
 
        SUPPLICANT_DBG("key: %s", key);
@@ -2586,6 +2591,14 @@ static void peer_property(const char *key, 
DBusMessageIter *iter,
                if (peer->name) {
                        create_peer_identifier(peer);
                        callback_peer_found(peer);
+                       pending_peer = g_hash_table_lookup(
+                                       pending_peer_connection, peer->path);
+
+                       if (pending_peer && pending_peer == peer) {
+                               callback_peer_request(peer);
+                               g_hash_table_remove(pending_peer_connection,
+                                               peer->path);
+                       }
                }
 
                return;
@@ -2929,7 +2942,15 @@ static void signal_group_request(const char *path, 
DBusMessageIter *iter)
        if (!peer)
                return;
 
-       callback_peer_request(peer);
+       /*
+        * Peer has been previously found and property set,
+        * otherwise, defer connection to when peer property
+        * is set.
+        */
+       if (peer->identifier)
+               callback_peer_request(peer);
+       else
+               g_hash_table_replace(pending_peer_connection, peer->path, peer);
 }
 
 static void signal_group_peer_joined(const char *path, DBusMessageIter *iter)
@@ -5082,6 +5103,8 @@ int g_supplicant_register(const GSupplicantCallbacks 
*callbacks)
                                                                NULL, NULL);
        group_mapping = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                                NULL, NULL);
+       pending_peer_connection = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                               NULL, NULL);
 
        supplicant_dbus_setup(connection);
 
-- 
1.9.1

_______________________________________________
connman mailing list
connman@connman.net
https://lists.connman.net/mailman/listinfo/connman

Reply via email to