WPS: Enforce five second minimum time before AP iteration

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>
This commit is contained in:
Hu Wang 2015-04-24 15:53:08 +03:00 committed by Jouni Malinen
parent cfbdb9958f
commit e7d20342b5
2 changed files with 19 additions and 3 deletions

View file

@ -639,6 +639,7 @@ struct wpa_supplicant {
int wps_success; /* WPS success event received */ int wps_success; /* WPS success event received */
struct wps_er *wps_er; struct wps_er *wps_er;
unsigned int wps_run; unsigned int wps_run;
struct os_reltime wps_pin_start_time;
int blacklist_cleared; int blacklist_cleared;
struct wpabuf *pending_eapol_rx; struct wpabuf *pending_eapol_rx;

View file

@ -39,6 +39,14 @@
#define WPS_PIN_SCAN_IGNORE_SEL_REG 3 #define WPS_PIN_SCAN_IGNORE_SEL_REG 3
#endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */ #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_wps_timeout(void *eloop_ctx, void *timeout_ctx);
static void wpas_clear_wps(struct wpa_supplicant *wpa_s); 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, int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
const char *pin, int p2p_group, u16 dev_pw_id) 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, return wpas_wps_start_dev_pw(wpa_s, NULL, bssid, pin, p2p_group,
dev_pw_id, NULL, NULL, 0, 0); dev_pw_id, NULL, NULL, 0, 0);
} }
@ -1609,9 +1618,15 @@ int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s,
* external Registrar. * external Registrar.
*/ */
if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) { if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) {
if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG) { struct os_reltime age;
wpa_printf(MSG_DEBUG, " skip - WPS AP "
"without active PIN Registrar"); 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); wpabuf_free(wps_ie);
return 0; return 0;
} }