WPS: Enforce five second minimum time before AP iteration
authorHu Wang <huw@qti.qualcomm.com>
Fri, 24 Apr 2015 12:53:08 +0000 (15:53 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 24 Apr 2015 14:55:32 +0000 (17:55 +0300)
Previously, wpa_supplicant was using number of scan iterations
(WPS_PIN_SCAN_IGNORE_SEL_REG = 3) to give some time for finding a WPS AP
with Selected Registrar TRUE before starting to iterate through all WPS
APs. While this works fine in most cases, some drivers may return the
initial three scan results so quickly that the total amount of time is
only couple of seconds in case none of the APs are initially advertising
Selected Registrar TRUE. To give some more time for APs (WPS Registrars)
to become ready, add an additional constraint on the iteration based on
time (WPS_PIN_TIME_IGNORE_SEL_REG = 5 seconds).

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
wpa_supplicant/wpa_supplicant_i.h
wpa_supplicant/wps_supplicant.c

index 1b9753c..0e36b46 100644 (file)
@@ -639,6 +639,7 @@ struct wpa_supplicant {
        int wps_success; /* WPS success event received */
        struct wps_er *wps_er;
        unsigned int wps_run;
+       struct os_reltime wps_pin_start_time;
        int blacklist_cleared;
 
        struct wpabuf *pending_eapol_rx;
index 52594a1..e34573b 100644 (file)
 #define WPS_PIN_SCAN_IGNORE_SEL_REG 3
 #endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */
 
+/*
+ * The minimum time in seconds before trying to associate to a WPS PIN AP that
+ * does not have Selected Registrar TRUE.
+ */
+#ifndef WPS_PIN_TIME_IGNORE_SEL_REG
+#define WPS_PIN_TIME_IGNORE_SEL_REG 5
+#endif /* WPS_PIN_TIME_IGNORE_SEL_REG */
+
 static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
 static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
 
@@ -1216,6 +1224,7 @@ static int wpas_wps_start_dev_pw(struct wpa_supplicant *wpa_s,
 int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
                       const char *pin, int p2p_group, u16 dev_pw_id)
 {
+       os_get_reltime(&wpa_s->wps_pin_start_time);
        return wpas_wps_start_dev_pw(wpa_s, NULL, bssid, pin, p2p_group,
                                     dev_pw_id, NULL, NULL, 0, 0);
 }
@@ -1609,9 +1618,15 @@ int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
                 * external Registrar.
                 */
                if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
-                       if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG) {
-                               wpa_printf(MSG_DEBUG, "   skip - WPS AP "
-                                          "without active PIN Registrar");
+                       struct os_reltime age;
+
+                       os_reltime_age(&wpa_s->wps_pin_start_time, &age);
+
+                       if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG ||
+                           age.sec < WPS_PIN_TIME_IGNORE_SEL_REG) {
+                               wpa_printf(MSG_DEBUG,
+                                          "   skip - WPS AP without active PIN Registrar (scan_runs=%d age=%d)",
+                                          wpa_s->scan_runs, (int) age.sec);
                                wpabuf_free(wps_ie);
                                return 0;
                        }