From 4756ecabcfd08bb99968c0c738b7879e7e0211f5 Mon Sep 17 00:00:00 2001 From: Matthew Wang Date: Wed, 15 Jul 2020 17:17:42 -0700 Subject: [PATCH] Allow bgscan parameters to be reconfigured Teach wpa_supplicant to {de,}initialize bgscans when bgscan parameters are set after initial connection. Signed-off-by: Matthew Wang --- wpa_supplicant/config.c | 2 +- wpa_supplicant/config.h | 1 + wpa_supplicant/ctrl_iface.c | 14 ++++++++ wpa_supplicant/dbus/dbus_new_handlers.c | 17 +++++++++ wpa_supplicant/wpa_supplicant.c | 48 +++++++++++++++++-------- wpa_supplicant/wpa_supplicant_i.h | 1 + 6 files changed, 67 insertions(+), 16 deletions(-) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 0cbd09c86..b828b599f 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4963,7 +4963,7 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(eapol_version, 1, 2), 0 }, #endif /* CONFIG_MACSEC */ { INT(ap_scan), 0 }, - { FUNC(bgscan), 0 }, + { FUNC(bgscan), CFG_CHANGED_BGSCAN }, #ifdef CONFIG_MESH { INT(user_mpm), 0 }, { INT_RANGE(max_peer_links, 0, 255), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 3c38e1e57..2a2ad8722 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -376,6 +376,7 @@ struct wpa_cred { #define CFG_CHANGED_SCHED_SCAN_PLANS BIT(17) #define CFG_CHANGED_WOWLAN_TRIGGERS BIT(18) #define CFG_CHANGED_DISABLE_BTM BIT(19) +#define CFG_CHANGED_BGSCAN BIT(20) /** * struct wpa_config - wpa_supplicant configuration data diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 127b5fe0b..7df7ba0d1 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -3547,6 +3547,20 @@ static int wpa_supplicant_ctrl_iface_update_network( if (ret == 1) return 0; /* No change to the previously configured value */ +#ifdef CONFIG_BGSCAN + if (os_strcmp(name, "bgscan") == 0) { + /* + * Reset the bgscan parameters for the current network and + * return. There's no need to flush caches for bgscan parameter + * changes. + */ + if (wpa_s->current_ssid == ssid && + wpa_s->wpa_state == WPA_COMPLETED) + wpa_supplicant_reset_bgscan(wpa_s); + return 0; + } +#endif /* CONFIG_BGSCAN */ + if (os_strcmp(name, "bssid") != 0 && os_strcmp(name, "bssid_hint") != 0 && os_strcmp(name, "priority") != 0) { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index defb9d405..53e869488 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -274,6 +274,23 @@ dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s, if (ret == 1) goto skip_update; +#ifdef CONFIG_BGSCAN + if (os_strcmp(entry.key, "bgscan") == 0) { + /* + * Reset the bgscan parameters for the current network + * and continue. There's no need to flush caches for + * bgscan parameter changes. + */ + if (wpa_s->current_ssid == ssid && + wpa_s->wpa_state == WPA_COMPLETED) + wpa_supplicant_reset_bgscan(wpa_s); + os_free(value); + value = NULL; + wpa_dbus_dict_entry_clear(&entry); + continue; + } +#endif /* CONFIG_BGSCAN */ + if (os_strcmp(entry.key, "bssid") != 0 && os_strcmp(entry.key, "priority") != 0) wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index a7e9e459e..cb243f2f8 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -803,7 +803,22 @@ const char * wpa_supplicant_state_txt(enum wpa_states state) #ifdef CONFIG_BGSCAN -static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s) +static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s) +{ + if (wpa_s->bgscan_ssid) { + bgscan_deinit(wpa_s); + wpa_s->bgscan_ssid = NULL; + } +} + + +/** + * wpa_supplicant_reset_bgscan - Reset the bgscan for the current SSID. + * @wpa_s: Pointer to the wpa_supplicant data + * + * Stop, start, or reconfigure the scan parameters depending on the method. + */ +void wpa_supplicant_reset_bgscan(struct wpa_supplicant *wpa_s) { const char *name; @@ -811,12 +826,12 @@ static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s) name = wpa_s->current_ssid->bgscan; else name = wpa_s->conf->bgscan; - if (name == NULL || name[0] == '\0') + if (!name || name[0] == '\0') { + wpa_supplicant_stop_bgscan(wpa_s); return; + } if (wpas_driver_bss_selection(wpa_s)) return; - if (wpa_s->current_ssid == wpa_s->bgscan_ssid) - return; #ifdef CONFIG_P2P if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) return; @@ -846,15 +861,6 @@ static void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s) wpa_s->bgscan_ssid = NULL; } - -static void wpa_supplicant_stop_bgscan(struct wpa_supplicant *wpa_s) -{ - if (wpa_s->bgscan_ssid != NULL) { - bgscan_deinit(wpa_s); - wpa_s->bgscan_ssid = NULL; - } -} - #endif /* CONFIG_BGSCAN */ @@ -1011,8 +1017,8 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_s->wpa_state = state; #ifdef CONFIG_BGSCAN - if (state == WPA_COMPLETED) - wpa_supplicant_start_bgscan(wpa_s); + if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid) + wpa_supplicant_reset_bgscan(wpa_s); else if (state < WPA_ASSOCIATED) wpa_supplicant_stop_bgscan(wpa_s); #endif /* CONFIG_BGSCAN */ @@ -7255,6 +7261,18 @@ void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s) if (wpa_s->conf->changed_parameters & CFG_CHANGED_DISABLE_BTM) wpa_supplicant_set_default_scan_ies(wpa_s); +#ifdef CONFIG_BGSCAN + /* + * We default to global bgscan parameters only when per-network bgscan + * parameters aren't set. Only bother resetting bgscan parameters if + * this is the case. + */ + if ((wpa_s->conf->changed_parameters & CFG_CHANGED_BGSCAN) && + wpa_s->current_ssid && !wpa_s->current_ssid->bgscan && + wpa_s->wpa_state == WPA_COMPLETED) + wpa_supplicant_reset_bgscan(wpa_s); +#endif /* CONFIG_BGSCAN */ + #ifdef CONFIG_WPS wpas_wps_update_config(wpa_s); #endif /* CONFIG_WPS */ diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index eac3491cc..5d99fcccd 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1465,6 +1465,7 @@ int wpas_beacon_rep_scan_process(struct wpa_supplicant *wpa_s, void wpas_clear_beacon_rep_data(struct wpa_supplicant *wpa_s); void wpas_flush_fils_hlp_req(struct wpa_supplicant *wpa_s); void wpas_clear_disabled_interface(void *eloop_ctx, void *timeout_ctx); +void wpa_supplicant_reset_bgscan(struct wpa_supplicant *wpa_s); /* MBO functions */