diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 1d2dff9f2..9018c083c 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -482,6 +482,15 @@ struct wpa_driver_scan_params { */ unsigned int sched_scan_plans_num; + /** + * sched_scan_start_delay - Delay to use before starting the first scan + * + * Delay (in seconds) before scheduling first scan plan cycle. The + * driver may ignore this parameter and start immediately (or at any + * other time), if this feature is not supported. + */ + u32 sched_scan_start_delay; + /** * bssid - Specific BSSID to scan for * diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c index 4417721e6..10517e403 100644 --- a/src/drivers/driver_nl80211_scan.c +++ b/src/drivers/driver_nl80211_scan.c @@ -595,6 +595,11 @@ int wpa_driver_nl80211_sched_scan(void *priv, } } + if (params->sched_scan_start_delay && + nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, + params->sched_scan_start_delay)) + goto fail; + ret = send_and_recv_msgs(drv, msg, NULL, NULL); /* TODO: if we get an error here, we should fall back to normal scan */ diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 00c5ff0db..e3ce6bc1d 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4432,6 +4432,7 @@ static const struct global_parse_data global_fields[] = { { FUNC(freq_list), 0 }, { INT(scan_cur_freq), 0 }, { INT(sched_scan_interval), 0 }, + { INT(sched_scan_start_delay), 0 }, { INT(tdls_external_control), 0}, { STR(osu_dir), 0 }, { STR(wowlan_triggers), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 3f84b0e1c..a7b043561 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -1096,6 +1096,15 @@ struct wpa_config { */ unsigned int sched_scan_interval; + /** + * sched_scan_start_delay - Schedule scan start delay before first scan + * + * Delay (in seconds) before scheduling first scan plan cycle. The + * driver may ignore this parameter and start immediately (or at any + * other time), if this feature is not supported. + */ + unsigned int sched_scan_start_delay; + /** * tdls_external_control - External control for TDLS setup requests * diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 160a5da2c..2b46fed4f 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1320,6 +1320,10 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "sched_scan_interval=%u\n", config->sched_scan_interval); + if (config->sched_scan_start_delay) + fprintf(f, "sched_scan_start_delay=%u\n", + config->sched_scan_start_delay); + if (config->external_sim) fprintf(f, "external_sim=%d\n", config->external_sim); diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index d19531a3d..413abf63e 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -1512,13 +1512,18 @@ scan: params.sched_scan_plans_num = 1; } + params.sched_scan_start_delay = wpa_s->conf->sched_scan_start_delay; + if (ssid || !wpa_s->first_sched_scan) { wpa_dbg(wpa_s, MSG_DEBUG, - "Starting sched scan: interval %u timeout %d", + "Starting sched scan after %u seconds: interval %u timeout %d", + params.sched_scan_start_delay, params.sched_scan_plans[0].interval, wpa_s->sched_scan_timeout); } else { - wpa_dbg(wpa_s, MSG_DEBUG, "Starting sched scan (no timeout)"); + wpa_dbg(wpa_s, MSG_DEBUG, + "Starting sched scan after %u seconds (no timeout)", + params.sched_scan_start_delay); } wpa_setband_scan_freqs(wpa_s, scan_params); @@ -2588,6 +2593,8 @@ int wpas_start_pno(struct wpa_supplicant *wpa_s) params.sched_scan_plans_num = 1; } + params.sched_scan_start_delay = wpa_s->conf->sched_scan_start_delay; + if (params.freqs == NULL && wpa_s->manual_sched_scan_freqs) { wpa_dbg(wpa_s, MSG_DEBUG, "Limit sched scan to specified channels"); params.freqs = wpa_s->manual_sched_scan_freqs; diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 964311c55..4598cf222 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -578,6 +578,7 @@ static char ** wpa_cli_complete_get(const char *str, int pos) "p2p_go_max_inactivity", "auto_interworking", "okc", "pmf", "dtim_period", "beacon_int", "ignore_old_scan_res", "scan_cur_freq", "sched_scan_interval", + "sched_scan_start_delay", "tdls_external_control", "osu_dir", "wowlan_triggers", "p2p_search_delay", "mac_addr", "rand_addr_lifetime", "preassoc_mac_addr", "key_mgmt_offload", "passive_scan",