Browse Source

wpa_supplicant: Schedule PNO on completion of ongoing sched_scan

When start PNO request comes from control interface, wpa_supplicant
should wait until ongoing sched_scan (triggered by wpa_supplicant)
gets cancelled. Issuing cancel sched_scan and start PNO scan
one after another from pno_start() would lead wpa_supplicant to clear
wps->sched_scanning flag while getting sched_scan stopped event
from driver for cancel sched_scan request. In fact, PNO scan will
be in progress in driver and wpa_s->sched_scanning will not be set
in such cases.

In addition to this change, RSSI threshold limit is passed as part of
start sched_scan request. This was previously set only in pno_start(),
but the same parameter should be available for generic sched_scan calls
as well and this can now be reached through the new PNO start sequence.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Raja Mani 11 years ago
parent
commit
cf70d2981d
4 changed files with 29 additions and 8 deletions
  1. 11 3
      wpa_supplicant/ctrl_iface.c
  2. 13 4
      wpa_supplicant/events.c
  3. 4 1
      wpa_supplicant/scan.c
  4. 1 0
      wpa_supplicant/wpa_supplicant_i.h

+ 11 - 3
wpa_supplicant/ctrl_iface.c

@@ -54,7 +54,7 @@ static int pno_start(struct wpa_supplicant *wpa_s)
 	struct wpa_ssid *ssid;
 	struct wpa_driver_scan_params params;
 
-	if (wpa_s->pno)
+	if (wpa_s->pno || wpa_s->pno_sched_pending)
 		return 0;
 
 	if ((wpa_s->wpa_state > WPA_SCANNING) &&
@@ -64,8 +64,14 @@ static int pno_start(struct wpa_supplicant *wpa_s)
 	}
 
 	if (wpa_s->wpa_state == WPA_SCANNING) {
-		wpa_supplicant_cancel_sched_scan(wpa_s);
 		wpa_supplicant_cancel_scan(wpa_s);
+		if (wpa_s->sched_scanning) {
+			wpa_printf(MSG_DEBUG, "Schedule PNO on completion of "
+				   "ongoing sched scan");
+			wpa_supplicant_cancel_sched_scan(wpa_s);
+			wpa_s->pno_sched_pending = 1;
+			return 0;
+		}
 	}
 
 	os_memset(&params, 0, sizeof(params));
@@ -128,11 +134,13 @@ static int pno_stop(struct wpa_supplicant *wpa_s)
 {
 	int ret = 0;
 
-	if (wpa_s->pno) {
+	if (wpa_s->pno || wpa_s->sched_scanning) {
 		wpa_s->pno = 0;
 		ret = wpa_supplicant_stop_sched_scan(wpa_s);
 	}
 
+	wpa_s->pno_sched_pending = 0;
+
 	if (wpa_s->wpa_state == WPA_SCANNING)
 		wpa_supplicant_req_scan(wpa_s, 0, 0);
 

+ 13 - 4
wpa_supplicant/events.c

@@ -3244,11 +3244,20 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 			break;
 
 		/*
-		 * If we timed out, start a new sched scan to continue
-		 * searching for more SSIDs.
+		 * Start a new sched scan to continue searching for more SSIDs
+		 * either if timed out or PNO schedule scan is pending.
 		 */
-		if (wpa_s->sched_scan_timed_out)
-			wpa_supplicant_req_sched_scan(wpa_s);
+		if (wpa_s->sched_scan_timed_out || wpa_s->pno_sched_pending) {
+
+			if (wpa_supplicant_req_sched_scan(wpa_s) < 0 &&
+			    wpa_s->pno_sched_pending) {
+				wpa_msg(wpa_s, MSG_ERROR, "Failed to schedule PNO");
+			} else if (wpa_s->pno_sched_pending) {
+				wpa_s->pno_sched_pending = 0;
+				wpa_s->pno = 1;
+			}
+		}
+
 		break;
 	case EVENT_WPS_BUTTON_PUSHED:
 #ifdef CONFIG_WPS

+ 4 - 1
wpa_supplicant/scan.c

@@ -521,7 +521,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
 	size_t max_ssids;
 	enum wpa_states prev_state;
 
-	if (wpa_s->pno) {
+	if (wpa_s->pno || wpa_s->pno_sched_pending) {
 		wpa_dbg(wpa_s, MSG_DEBUG, "Skip scan - PNO is in progress");
 		return;
 	}
@@ -1117,6 +1117,9 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
 		params.extra_ies_len = wpabuf_len(extra_ie);
 	}
 
+	if (wpa_s->conf->filter_rssi)
+		params.filter_rssi = wpa_s->conf->filter_rssi;
+
 	scan_params = &params;
 
 scan:

+ 1 - 0
wpa_supplicant/wpa_supplicant_i.h

@@ -768,6 +768,7 @@ struct wpa_supplicant {
 	} hw;
 
 	int pno;
+	int pno_sched_pending;
 
 	/* WLAN_REASON_* reason codes. Negative if locally generated. */
 	int disconnect_reason;