wpa_supplicant: Schedule PNO on completion of ongoing sched_scan
authorRaja Mani <rmani@qti.qualcomm.com>
Wed, 22 Jan 2014 14:15:23 +0000 (19:45 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 22 Jan 2014 17:41:45 +0000 (19:41 +0200)
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>

wpa_supplicant/ctrl_iface.c
wpa_supplicant/events.c
wpa_supplicant/scan.c
wpa_supplicant/wpa_supplicant_i.h

index ec79de3..8582900 100644 (file)
@@ -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);
 
index 6e6b011..862ebb0 100644 (file)
@@ -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
index ed8fa30..30da097 100644 (file)
@@ -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:
index 3a28534..078856e 100644 (file)
@@ -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;