Add workaround for DHCP startup failures with WiFi networks
authorSam Leffler <sleffler@google.com>
Mon, 30 Nov 2009 17:26:15 +0000 (18:26 +0100)
committerMarcel Holtmann <marcel@holtmann.org>
Mon, 30 Nov 2009 17:29:48 +0000 (18:29 +0100)
When connecting to a wireless network the supplicant plugin holds
to a network object. But this object is removed from the object table
as a consequence of doing a device disconnect. If a network connect
is in progress when nother connect request comes in (e.g. via D-Bus)
it will irst disconnect which causes the object to be yanked from the
global table. When the first connect request completes the reference
held by the supplicant code is "unregistered" and not usable in starting
up a DHCP client. This leaves it in an unfixable state (restart required).

Workaround is to check in __connman_device_disconnect whether a network
is "connecting" and not disconnect it.

src/device.c

index 9378eef..f11ecf4 100644 (file)
@@ -1263,6 +1263,22 @@ int __connman_device_disconnect(struct connman_device *device)
        while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
                struct connman_network *network = value;
 
+               if (__connman_network_get_connecting(network) == TRUE) {
+                       /*
+                        * Skip network in the process of connecting.
+                        * This is a workaround for WiFi networks serviced
+                        * by the supplicant plugin that hold a reference
+                        * to the network.  If we disconnect the network
+                        * here then the referenced object will not be
+                        * registered and usage (like launching DHCP client)
+                        * will fail.  There is nothing to be gained by
+                        * removing the network here anyway.
+                        */
+                       connman_warn("Skipping disconnect of %s",
+                               connman_network_get_identifier(network));
+                       continue;
+               }
+
                __connman_network_disconnect(network);
        }