From 150fd0b2b535160a254610bb63948ea9fec87fb4 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 13 Apr 2014 11:47:03 +0300 Subject: [PATCH] WPS: Split eapol_cb reconnect to a separate code path 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 --- wpa_supplicant/wps_supplicant.c | 35 ++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 4c729dd92..2b58749e6 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -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);