From: Pasi Sjöholm <[email protected]>
While wifi->state is G_SUPPLICANT_STATE_COMPLETED and gets changed into
G_SUPPLICANT_STATE_4WAY_HANDSHAKE the connection is most probably roaming.
However if for some reason the wifi->state changes into
G_SUPPLICANT_STATE_DISCONNECTED after being G_SUPPLICANT_STATE_4WAY_HANDSHAKE
the handle_4way_handshake_failure() is called from interface_state() it is
required to check wifi->connected and force disconnect if true.
If not the actual disconnection will be skipped unless
retries > FAVORITE_MAXIMUM_RETRIES and wifi->connected will be set as false.
Later on this will cause state-machine deadlock between network.c and wifi.c
as network.c will still think that the network is connected and after wifi.c
thinks it's not.
In short: wifi->state will change into G_SUPPLICANT_STATE_SCANNING->
G_SUPPLICANT_STATE_ASSOCIATING and connman_network_set_associating(network,
true);
gets called. Now the network.c is in both associating and connected. Finally
when
wifi->state goes through G_SUPPLICANT_STATE_4WAY_HANDSHAKE ->
G_SUPPLICANT_STATE_COMPLETED the connman_network_set_connected(network, true);
will be called but it will never call set_connected as it's already connected
and
service state will stay as "associating" until disconnected.
---
plugins/wifi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 42dd407..2c4c2d6 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -2262,6 +2262,9 @@ static bool
handle_4way_handshake_failure(GSupplicantInterface *interface,
if (wifi->state != G_SUPPLICANT_STATE_4WAY_HANDSHAKE)
return false;
+ if (wifi->connected)
+ return false;
+
service = connman_service_lookup_from_network(network);
if (!service)
return false;
--
2.1.0
_______________________________________________
connman mailing list
[email protected]
https://lists.connman.net/mailman/listinfo/connman