WPS: Split eapol_cb reconnect to a separate code path
authorJouni Malinen <j@w1.fi>
Sun, 13 Apr 2014 08:47:03 +0000 (11:47 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 13 Apr 2014 08:47:03 +0000 (11:47 +0300)
Use eloop timeout to run the reconnect command after eapol_cb has
returned. This reduces stack use and can simplify the driver
command/event sequence by allowing the disconnection events from the
provisioning step to be processed before starting the actual data
connection.

Signed-off-by: Jouni Malinen <j@w1.fi>
wpa_supplicant/wps_supplicant.c

index 4c729dd..2b58749 100644 (file)
@@ -52,6 +52,25 @@ static void wpas_wps_clear_ap_info(struct wpa_supplicant *wpa_s)
 }
 
 
+static void wpas_wps_assoc_with_cred(void *eloop_ctx, void *timeout_ctx)
+{
+       struct wpa_supplicant *wpa_s = eloop_ctx;
+       int use_fast_assoc = timeout_ctx != NULL;
+
+       wpa_printf(MSG_DEBUG, "WPS: Continuing association after eapol_cb");
+       if (!use_fast_assoc ||
+           wpa_supplicant_fast_associate(wpa_s) != 1)
+               wpa_supplicant_req_scan(wpa_s, 0, 0);
+}
+
+
+static void wpas_wps_assoc_with_cred_cancel(struct wpa_supplicant *wpa_s)
+{
+       eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 0);
+       eloop_cancel_timeout(wpas_wps_assoc_with_cred, wpa_s, (void *) 1);
+}
+
+
 int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
 {
 #ifdef CONFIG_P2P
@@ -124,9 +143,18 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
                        wpabuf_free(wps);
                }
 
-               if (!use_fast_assoc ||
-                   wpa_supplicant_fast_associate(wpa_s) != 1)
-                       wpa_supplicant_req_scan(wpa_s, 0, 0);
+               /*
+                * Complete the next step from an eloop timeout to allow pending
+                * driver events related to the disconnection to be processed
+                * first. This makes it less likely for disconnection event to
+                * cause problems with the following connection.
+                */
+               wpa_printf(MSG_DEBUG, "WPS: Continue association from timeout");
+               wpas_wps_assoc_with_cred_cancel(wpa_s);
+               eloop_register_timeout(0, 10000,
+                                      wpas_wps_assoc_with_cred, wpa_s,
+                                      use_fast_assoc ? (void *) 1 :
+                                      (void *) 0);
                return 1;
        }
 
@@ -1431,6 +1459,7 @@ static void wpas_wps_nfc_clear(struct wps_context *wps)
 
 void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
 {
+       wpas_wps_assoc_with_cred_cancel(wpa_s);
        eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
        eloop_cancel_timeout(wpas_wps_clear_timeout, wpa_s, NULL);
        eloop_cancel_timeout(wpas_wps_reenable_networks_cb, wpa_s, NULL);