Browse Source

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>
Loic Poulain 12 years ago
parent
commit
1245503188
3 changed files with 10 additions and 7 deletions
  1. 1 0
      wpa_supplicant/events.c
  2. 8 6
      wpa_supplicant/scan.c
  3. 1 1
      wpa_supplicant/wpa_supplicant_i.h

+ 1 - 0
wpa_supplicant/events.c

@@ -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;

+ 8 - 6
wpa_supplicant/scan.c

@@ -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;

+ 1 - 1
wpa_supplicant/wpa_supplicant_i.h

@@ -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;