From d0330d57f3d320719c1f8fc8478a6dc5ef613946 Mon Sep 17 00:00:00 2001 From: Purushottam Kushwaha Date: Mon, 6 Mar 2017 13:23:10 +0530 Subject: [PATCH] nl80211: Add option to delay start of schedule scan plans The userspace may want to delay the the first scheduled scan. This enhances sched_scan to add initial delay (in seconds) before starting first scan cycle. The driver may optionally choose to ignore this parameter and start immediately (or at any other time). This uses NL80211_ATTR_SCHED_SCAN_DELAY to add this via user global configurable option: sched_scan_start_delay. Signed-off-by: Jouni Malinen --- src/drivers/driver.h | 9 +++++++++ src/drivers/driver_nl80211_scan.c | 5 +++++ wpa_supplicant/config.c | 1 + wpa_supplicant/config.h | 9 +++++++++ wpa_supplicant/config_file.c | 4 ++++ wpa_supplicant/scan.c | 11 +++++++++-- wpa_supplicant/wpa_cli.c | 1 + 7 files changed, 38 insertions(+), 2 deletions(-) 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",