From b59e6f267bdfac786d252cf159a43a43823ee864 Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 27 Sep 2011 22:21:35 +0300 Subject: [PATCH] Add filter support to scheduled scans Pass SSIDs to be matched in scheduled scan results. Only the SSIDs that are included in the match lists will be reported by the driver, so the filtering can be offloaded to the hardware and the power consumption can be reduced. Signed-off-by: Luciano Coelho --- src/drivers/driver.h | 1 + wpa_supplicant/scan.c | 35 ++++++++++++++++++------------- wpa_supplicant/wpa_supplicant.c | 1 + wpa_supplicant/wpa_supplicant_i.h | 1 + 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index f28d60819..0847d37db 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -696,6 +696,7 @@ struct wpa_driver_capa { int max_scan_ssids; int max_sched_scan_ssids; int sched_scan_supported; + int max_match_sets; /** * max_remain_on_chan - Maximum remain-on-channel duration in msec diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index c73f2be3b..afb44237f 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -628,7 +628,6 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) struct wpa_ssid *ssid; struct wpabuf *wps_ie = NULL; int ret; - int use_wildcard = 0; unsigned int max_sched_scan_ssids; if (!wpa_s->sched_scan_supported) @@ -644,6 +643,10 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) os_memset(¶ms, 0, sizeof(params)); + /* If we can't allocate space for the filters, we just don't filter */ + params.filter_ssids = os_zalloc(wpa_s->max_match_sets * + sizeof(struct wpa_driver_scan_filter)); + prev_state = wpa_s->wpa_state; if (wpa_s->wpa_state == WPA_DISCONNECTED || wpa_s->wpa_state == WPA_INACTIVE) @@ -678,33 +681,36 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) continue; } - if (!ssid->scan_ssid) - use_wildcard = 1; - else { + if (params.filter_ssids && ssid->ssid && ssid->ssid_len) { + os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid, + ssid->ssid, ssid->ssid_len); + params.filter_ssids[params.num_filter_ssids].ssid_len = + ssid->ssid_len; + params.num_filter_ssids++; + } + + if (ssid->scan_ssid) { params.ssids[params.num_ssids].ssid = ssid->ssid; params.ssids[params.num_ssids].ssid_len = ssid->ssid_len; params.num_ssids++; - if (params.num_ssids + 1 >= max_sched_scan_ssids) { + if (params.num_ssids >= max_sched_scan_ssids) { wpa_s->prev_sched_ssid = ssid; break; } } + + if (params.num_filter_ssids >= wpa_s->max_match_sets) + break; wpa_s->prev_sched_ssid = ssid; ssid = ssid->next; } - if (ssid || use_wildcard) { - wpa_dbg(wpa_s, MSG_DEBUG, "Include wildcard SSID in " - "the sched scan request"); - params.num_ssids++; - } else { - wpa_dbg(wpa_s, MSG_DEBUG, "ssid %p - list ended", ssid); - } - - if (!params.num_ssids) + if (!params.num_ssids) { + os_free(params.filter_ssids); return 0; + } if (wpa_s->wps) wps_ie = wpa_supplicant_extra_ies(wpa_s, ¶ms); @@ -716,6 +722,7 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) ret = wpa_supplicant_start_sched_scan(wpa_s, ¶ms, wpa_s->sched_scan_interval); wpabuf_free(wps_ie); + os_free(params.filter_ssids); if (ret) { wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan"); if (prev_state != wpa_s->wpa_state) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 9fa737c1d..82bf8b151 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2286,6 +2286,7 @@ next_driver: wpa_s->max_scan_ssids = capa.max_scan_ssids; wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids; wpa_s->sched_scan_supported = capa.sched_scan_supported; + wpa_s->max_match_sets = capa.max_match_sets; wpa_s->max_remain_on_chan = capa.max_remain_on_chan; wpa_s->max_stations = capa.max_stations; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 8395686d8..d49c88abf 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -437,6 +437,7 @@ struct wpa_supplicant { int max_scan_ssids; int max_sched_scan_ssids; int sched_scan_supported; + unsigned int max_match_sets; unsigned int max_remain_on_chan; unsigned int max_stations;