diff mbox series

[V2,3/4] reconfigure bgscan parameters

Message ID 20200716001743.4085346-4-matthewmwang@chromium.org
State Accepted
Headers show
Series allow reconfiguration of bgscan | expand

Commit Message

Matthew Wang July 16, 2020, 12:17 a.m. UTC
Teach wpa_supplicant to {de,}initialize bgscans when bgscan parameters
are set after initial connection.

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
---
 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       |  3 ++
 6 files changed, 69 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index e4fa43ec7..11baee54b 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 a385da528..59c8e7bbd 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 eea8b40f4..7297ffd4f 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -3533,6 +3533,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 18b66e303..c5225ca99 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -277,6 +277,23 @@  dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
 			continue;
 		}
 
+#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 e7989baef..62a6538b2 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 != NULL) {
+		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 == NULL || 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 */
@@ -7151,6 +7157,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 341d84156..f88120a8d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1445,6 +1445,9 @@  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);
+#ifdef CONFIG_BGSCAN
+void wpa_supplicant_reset_bgscan(struct wpa_supplicant *wpa_s);
+#endif /* CONFIG_BGSCAN */
 
 
 /* MBO functions */