Restore scan_req if sta scan is rescheduled in the scan results event

On scan results event if a concurrent P2P scan was triggered previously,
scan results processing is canceled, p2p_find executed, and a new sta
scan is triggered (pending scan). However, this new sta scan does not
restore the scan_req value of the previous scan (whose scan result has
been canceled).

If we are currently connected to an AP and use ap_scan=2, the new
triggered scan will cause an associtation-without-scan in
wpa_supplicant_scan:
(ap_scan == 2 & scan_req != MANUAL_SCAN_REQ)
	=> wpa_supplicant_assoc_try()
causing an association error and a disconnection.

This patch fixes this issue by restoring the previous scan_req value.

Signed-off-by: Loic Poulain <loicx.poulain@intel.com>
This commit is contained in:
Loic Poulain 2013-05-31 12:15:56 +02:00 committed by Jouni Malinen
parent bdec7ee5c9
commit 1245503188
3 changed files with 10 additions and 7 deletions

View file

@ -1203,6 +1203,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) { if (p2p_other_scan_completed(wpa_s->global->p2p) == 1) {
wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation " wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Pending P2P operation "
"stopped scan processing"); "stopped scan processing");
wpa_s->scan_req = wpa_s->last_scan_req;
wpa_s->sta_scan_pending = 1; wpa_s->sta_scan_pending = 1;
wpa_supplicant_req_scan(wpa_s, 5, 0); wpa_supplicant_req_scan(wpa_s, 5, 0);
return -1; return -1;

View file

@ -545,7 +545,6 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
{ {
struct wpa_supplicant *wpa_s = eloop_ctx; struct wpa_supplicant *wpa_s = eloop_ctx;
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
enum scan_req_type scan_req = NORMAL_SCAN_REQ;
int ret; int ret;
struct wpabuf *extra_ie = NULL; struct wpabuf *extra_ie = NULL;
struct wpa_driver_scan_params params; struct wpa_driver_scan_params params;
@ -630,7 +629,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
max_ssids = WPAS_MAX_SCAN_SSIDS; max_ssids = WPAS_MAX_SCAN_SSIDS;
} }
scan_req = wpa_s->scan_req; wpa_s->last_scan_req = wpa_s->scan_req;
wpa_s->scan_req = NORMAL_SCAN_REQ; wpa_s->scan_req = NORMAL_SCAN_REQ;
os_memset(&params, 0, sizeof(params)); os_memset(&params, 0, sizeof(params));
@ -648,7 +647,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
goto scan; goto scan;
} }
if (scan_req != MANUAL_SCAN_REQ && wpa_s->connect_without_scan) { if (wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
wpa_s->connect_without_scan) {
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
if (ssid == wpa_s->connect_without_scan) if (ssid == wpa_s->connect_without_scan)
break; break;
@ -687,7 +687,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
} }
} }
if (scan_req != MANUAL_SCAN_REQ && wpa_s->conf->ap_scan == 2) { if (wpa_s->last_scan_req != MANUAL_SCAN_REQ &&
wpa_s->conf->ap_scan == 2) {
wpa_s->connect_without_scan = NULL; wpa_s->connect_without_scan = NULL;
wpa_s->prev_scan_wildcard = 0; wpa_s->prev_scan_wildcard = 0;
wpa_supplicant_assoc_try(wpa_s, ssid); wpa_supplicant_assoc_try(wpa_s, ssid);
@ -843,7 +844,8 @@ scan:
* station interface when we are not configured to prefer station * station interface when we are not configured to prefer station
* connection and a concurrent operation is already in process. * connection and a concurrent operation is already in process.
*/ */
if (wpa_s->scan_for_connection && scan_req == NORMAL_SCAN_REQ && if (wpa_s->scan_for_connection &&
wpa_s->last_scan_req == NORMAL_SCAN_REQ &&
!scan_params->freqs && !params.freqs && !scan_params->freqs && !params.freqs &&
wpas_is_p2p_prioritized(wpa_s) && wpas_is_p2p_prioritized(wpa_s) &&
wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE && wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
@ -874,7 +876,7 @@ scan:
if (prev_state != wpa_s->wpa_state) if (prev_state != wpa_s->wpa_state)
wpa_supplicant_set_state(wpa_s, prev_state); wpa_supplicant_set_state(wpa_s, prev_state);
/* Restore scan_req since we will try to scan again */ /* Restore scan_req since we will try to scan again */
wpa_s->scan_req = scan_req; wpa_s->scan_req = wpa_s->last_scan_req;
wpa_supplicant_req_scan(wpa_s, 1, 0); wpa_supplicant_req_scan(wpa_s, 1, 0);
} else { } else {
wpa_s->scan_for_connection = 0; wpa_s->scan_for_connection = 0;

View file

@ -463,7 +463,7 @@ struct wpa_supplicant {
* to be run. * to be run.
*/ */
MANUAL_SCAN_REQ MANUAL_SCAN_REQ
} scan_req; } scan_req, last_scan_req;
struct os_time scan_trigger_time; struct os_time scan_trigger_time;
int scan_runs; /* number of scan runs since WPS was started */ int scan_runs; /* number of scan runs since WPS was started */
int *next_scan_freqs; int *next_scan_freqs;