From cf70d2981df1be7005fb90c2532e737ab39bc119 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Wed, 22 Jan 2014 19:45:23 +0530 Subject: [PATCH] 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 --- wpa_supplicant/ctrl_iface.c | 14 +++++++++++--- wpa_supplicant/events.c | 17 +++++++++++++---- wpa_supplicant/scan.c | 5 ++++- wpa_supplicant/wpa_supplicant_i.h | 1 + 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index ec79de35e..85829005a 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/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(¶ms, 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); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 6e6b011ab..862ebb000 100644 --- a/wpa_supplicant/events.c +++ b/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 diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index ed8fa3045..30da097d9 100644 --- a/wpa_supplicant/scan.c +++ b/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 = ¶ms; scan: diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 3a2853489..078856e8f 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/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;