From 5f8e010965377c28ede4d09ef8cb4b321d69769f Mon Sep 17 00:00:00 2001 From: Jeffrey Isaacs Date: Mon, 15 Mar 2021 17:02:25 -0400 Subject: [PATCH 1/2] wpa_supplicant: Add is_secondary_scan_iface to wpa_config This is the first in a series of commits that will implement offloading active scanning for available access points to a secondary interface. The motivation behind this is that performing active scans is disruptive to the WiFi connection. In mission critical applications, or when a constant high throughput is required, roaming between APs can result in unacceptable performance. When a client's rssi drops too low, or all the BSS table entries expire, the interface performs an active scan to find the next available AP. The new parameter is_secondary_scan_iface will be specified in the interface config file. When set to 1, scan results from that interface will be used to update the BSS tables in all interfaces whose is_secondary_scan_iface is set to 0. This allows the primary interface to roam between BSSs without having to take time to scan. This parameter does not affect any other parameters. It would make sense that if a secondary interface is specified, the frequency of scans performed on that interface should be increased to fully leverage this feature. Signed-off-by: Jeffrey Isaacs --- wpa_supplicant/config.c | 2 ++ wpa_supplicant/config.h | 12 ++++++++++++ wpa_supplicant/config_file.c | 3 +++ 3 files changed, 17 insertions(+) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index ce5c80d02..1935e097d 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4378,6 +4378,7 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface, config->cert_in_cb = DEFAULT_CERT_IN_CB; config->wpa_rsc_relaxation = DEFAULT_WPA_RSC_RELAXATION; config->extended_key_id = DEFAULT_EXTENDED_KEY_ID; + config->is_secondary_scan_iface = DEFAULT_IS_SECONDARY_SCAN_IFACE; #ifdef CONFIG_MBO config->mbo_cell_capa = DEFAULT_MBO_CELL_CAPA; @@ -5210,6 +5211,7 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(force_kdk_derivation, 0, 1), 0 }, #endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_PASN */ + { INT(is_secondary_scan_iface), 0 }, }; #undef FUNC diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index aac4a9dff..b10beaba4 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -46,6 +46,7 @@ #define DEFAULT_OCE_SUPPORT OCE_STA #define DEFAULT_EXTENDED_KEY_ID 0 #define DEFAULT_SCAN_RES_VALID_FOR_CONNECT 5 +#define DEFAULT_IS_SECONDARY_SCAN_IFACE 0 #include "config_ssid.h" #include "wps/wps.h" @@ -1650,6 +1651,17 @@ struct wpa_config { int force_kdk_derivation; #endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_PASN*/ + + /** + * is_secondary_scan_iface - Enable dedicated scan interface + * + * 0 = Scan results are not shared with other interfaces + * 1 = Scan results from this interface are used to update + the BSS table of each other interface + * + * By default, scan results are not shared + */ + int is_secondary_scan_iface; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index a535e3f08..2f86263b8 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1530,6 +1530,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->wowlan_disconnect_on_deinit) fprintf(f, "wowlan_disconnect_on_deinit=%d\n", config->wowlan_disconnect_on_deinit); + if (config->is_secondary_scan_iface) + fprintf(f, "is_secondary_scan_iface=%d\n", + config->is_secondary_scan_iface); } #endif /* CONFIG_NO_CONFIG_WRITE */ -- 2.17.1 From cbf7388a3cb99f67c240d1b41f9edef6d685732f Mon Sep 17 00:00:00 2001 From: Jeffrey Isaacs Date: Mon, 15 Mar 2021 17:36:56 -0400 Subject: [PATCH 2/2] wpa_supplicant: Implement active scanning from secondary interface This commit implements the changes required for the is_secondary_scan_iface parameter. When the parameter is set for a given interface, when scan results are available on that interface, wpa_bss_update is called using those results on all other interfaces that have is_secondary_scan_interface set to 0. Signed-off-by: Jeffrey Isaacs --- wpa_supplicant/bss.c | 20 +++++++++++++++++++- wpa_supplicant/bss.h | 3 ++- wpa_supplicant/ctrl_iface.c | 2 +- wpa_supplicant/scan.c | 2 +- wpa_supplicant/wnm_sta.c | 2 +- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index e13783ce1..56121436e 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -747,8 +747,26 @@ void wpa_bss_update_start(struct wpa_supplicant *wpa_s) */ void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, struct wpa_scan_res *res, - struct os_reltime *fetch_time) + struct os_reltime *fetch_time, + int secondary_scan) { + struct wpa_supplicant *iface; + iface = wpa_s->global->ifaces; + + while (iface && !secondary_scan) { + if (wpa_s->conf->is_secondary_scan_iface && !iface->conf->is_secondary_scan_iface) { + wpa_bss_update_scan_res(iface, res, fetch_time, 1); + } + if (iface->p2pdev == wpa_s) + iface->p2pdev = iface->parent; + if (iface == wpa_s || iface->parent != wpa_s) { + iface = iface->next; + continue; + } + iface = iface->next; + } + + const u8 *ssid, *p2p, *mesh; struct wpa_bss *bss; diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h index 4078b9b9d..eb34b425d 100644 --- a/wpa_supplicant/bss.h +++ b/wpa_supplicant/bss.h @@ -135,7 +135,8 @@ void notify_bss_changes(struct wpa_supplicant *wpa_s, u32 changes, void wpa_bss_update_start(struct wpa_supplicant *wpa_s); void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, struct wpa_scan_res *res, - struct os_reltime *fetch_time); + struct os_reltime *fetch_time, + int secondary_scan); void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, const char *reason); void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index c05175822..2c3cf2601 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -9291,7 +9291,7 @@ static int wpas_ctrl_iface_driver_scan_res(struct wpa_supplicant *wpa_s, } os_get_reltime(&now); - wpa_bss_update_scan_res(wpa_s, res, &now); + wpa_bss_update_scan_res(wpa_s, res, &now, 0); ret = 0; fail: os_free(res); diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index c53474dae..8684d1c97 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -2509,7 +2509,7 @@ wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, wpa_bss_update_start(wpa_s); for (i = 0; i < scan_res->num; i++) wpa_bss_update_scan_res(wpa_s, scan_res->res[i], - &scan_res->fetch_time); + &scan_res->fetch_time, 0); wpa_bss_update_end(wpa_s, info, new_scan); return scan_res; diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index c4c6651d4..c9ebcaca8 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -1354,7 +1354,7 @@ static int wnm_fetch_scan_results(struct wpa_supplicant *wpa_s) scan_snr(res); scan_est_throughput(wpa_s, res); wpa_bss_update_scan_res(wpa_s, res, - &scan_res->fetch_time); + &scan_res->fetch_time, 0); } } -- 2.17.1