diff --git a/src/drivers/driver.h b/src/drivers/driver.h index b4442becb..4e5ab34b4 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -340,6 +340,15 @@ struct wpa_driver_scan_params { * and not to transmit the frames at any of those rates. */ u8 p2p_probe; + + /** + * only_new_results - Request driver to report only new results + * + * This is used to request the driver to report only BSSes that have + * been detected after this scan request has been started, i.e., to + * flush old cached BSS entries. + */ + int only_new_results; }; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 5aa692586..6c4c81670 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -4679,6 +4679,12 @@ nl80211_scan_common(struct wpa_driver_nl80211_data *drv, u8 cmd, params->filter_ssids = NULL; drv->num_filter_ssids = params->num_filter_ssids; + if (params->only_new_results) { + wpa_printf(MSG_DEBUG, "nl80211: Add NL80211_SCAN_FLAG_FLUSH"); + NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, + NL80211_SCAN_FLAG_FLUSH); + } + return msg; fail: diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index 033384ce1..9ea690330 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -820,6 +820,8 @@ void wpa_bss_flush(struct wpa_supplicant *wpa_s) { struct wpa_bss *bss, *n; + wpa_s->clear_driver_scan_cache = 1; + if (wpa_s->bss.next == NULL) return; /* BSS table not yet initialized */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 7d7576f6e..03b5e1724 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5278,6 +5278,7 @@ static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params, wpa_s->manual_scan_passive = 0; wpa_s->manual_scan_use_id = 0; + wpa_s->manual_scan_only_new = 0; if (params) { if (os_strncasecmp(params, "TYPE=ONLY", 9) == 0) @@ -5296,6 +5297,10 @@ static void wpas_ctrl_scan(struct wpa_supplicant *wpa_s, char *params, pos = os_strstr(params, "use_id="); if (pos) wpa_s->manual_scan_use_id = atoi(pos + 7); + + pos = os_strstr(params, "only_new=1"); + if (pos) + wpa_s->manual_scan_only_new = 1; } else { os_free(wpa_s->manual_scan_freqs); wpa_s->manual_scan_freqs = NULL; diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 34c430fab..167ab9ddb 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -155,6 +155,8 @@ int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, wpa_supplicant_notify_scanning(wpa_s, 1); + if (wpa_s->clear_driver_scan_cache) + params->only_new_results = 1; ret = wpa_drv_scan(wpa_s, params); if (ret) { wpa_supplicant_notify_scanning(wpa_s, 0); @@ -164,6 +166,7 @@ int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, wpa_s->scan_runs++; wpa_s->normal_scans++; wpa_s->own_scan_requested = 1; + params->only_new_results = 0; } return ret; @@ -727,6 +730,10 @@ ssid_list_set: wpa_supplicant_optimize_freqs(wpa_s, ¶ms); extra_ie = wpa_supplicant_extra_ies(wpa_s); + if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && + wpa_s->manual_scan_only_new) + params.only_new_results = 1; + if (wpa_s->last_scan_req == MANUAL_SCAN_REQ && params.freqs == NULL && wpa_s->manual_scan_freqs) { wpa_dbg(wpa_s, MSG_DEBUG, "Limit manual scan to specified channels"); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 2e3f24494..8563b1838 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -484,9 +484,11 @@ struct wpa_supplicant { int *manual_scan_freqs; unsigned int manual_scan_passive:1; unsigned int manual_scan_use_id:1; + unsigned int manual_scan_only_new:1; unsigned int own_scan_requested:1; unsigned int own_scan_running:1; unsigned int external_scan_running:1; + unsigned int clear_driver_scan_cache:1; unsigned int manual_scan_id; int scan_interval; /* time in sec between scans to find suitable AP */ int normal_scans; /* normal scans run before sched_scan */