[PATCH v2] Reduce delay between Assoc REQ and Assoc RESP

Jurijs Soloveckis jsoloveckis at maxlinear.com
Fri Nov 3 01:14:24 PDT 2023


There is a delay between sending association response after association request,
due to the fact that between receiving the request and sending the response
the beacon is updated, after analyzing inputs from the STA.
There may be several updates if multiple fields need to change.
This can cause issues with some devices in noisy environments with many VAPs
and connected STAs.
The solution:
1. Handle the update of the beacon after association response is sent
2. Update the beacon only once, even if there are multiple reasons for updates

Signed-off-by: Jurijs Soloveckis <jsoloveckis at maxlinear.com>
---
 src/ap/ieee802_11.c       | 16 +++++++++++-----
 src/ap/ieee802_11.h       |  2 +-
 src/ap/ieee802_11_ht.c    |  5 ++---
 wpa_supplicant/mesh_mpm.c |  3 ++-
 4 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 2defe6c91..2d3457842 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -4437,7 +4437,8 @@ static void ieee80211_ml_process_link(struct hostapd_data *hapd,
 	}
 	hapd->sta_aid[(sta->aid - 1) / 32] |= BIT((sta->aid - 1) % 32);
 	sta->listen_interval = origin_sta->listen_interval;
-	update_ht_state(hapd, sta);
+	if (update_ht_state(hapd, sta) > 0)
+		ieee802_11_set_beacons(hapd->iface);
 
 	/* RSN Authenticator should always be the one on the original station */
 	wpa_auth_sta_deinit(sta->wpa_sm);
@@ -5164,6 +5165,7 @@ static void handle_assoc(struct hostapd_data *hapd,
 	int delay_assoc = 0;
 #endif /* CONFIG_FILS */
 	int omit_rsnxe = 0;
+	int set_beacon = 0;
 
 	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
 				      sizeof(mgmt->u.assoc_req))) {
@@ -5405,7 +5407,7 @@ static void handle_assoc(struct hostapd_data *hapd,
 		sta->nonerp_set = 1;
 		hapd->iface->num_sta_non_erp++;
 		if (hapd->iface->num_sta_non_erp == 1)
-			ieee802_11_update_beacons(hapd->iface);
+			set_beacon++;
 	}
 
 	if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
@@ -5416,7 +5418,7 @@ static void handle_assoc(struct hostapd_data *hapd,
 		    hapd->iface->current_mode->mode ==
 		    HOSTAPD_MODE_IEEE80211G &&
 		    hapd->iface->num_sta_no_short_slot_time == 1)
-			ieee802_11_update_beacons(hapd->iface);
+			set_beacon++;
 	}
 
 	if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -5431,10 +5433,11 @@ static void handle_assoc(struct hostapd_data *hapd,
 		if (hapd->iface->current_mode &&
 		    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
 		    && hapd->iface->num_sta_no_short_preamble == 1)
-			ieee802_11_update_beacons(hapd->iface);
+			set_beacon++;
 	}
 
-	update_ht_state(hapd, sta);
+	if (update_ht_state(hapd, sta) > 0 )
+		set_beacon++;
 
 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 		       HOSTAPD_LEVEL_DEBUG,
@@ -5475,6 +5478,9 @@ static void handle_assoc(struct hostapd_data *hapd,
 
  fail:
 
+	if (set_beacon)
+		ieee802_11_set_beacons(hapd->iface);
+
 	/*
 	 * In case of a successful response, add the station to the driver.
 	 * Otherwise, the kernel may ignore Data frames before we process the
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 4e7d8fbe8..8ffce0bf5 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -100,7 +100,7 @@ u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta,
 u16 copy_sta_vendor_vht(struct hostapd_data *hapd, struct sta_info *sta,
 			const u8 *ie, size_t len);
 
-void update_ht_state(struct hostapd_data *hapd, struct sta_info *sta);
+int update_ht_state(struct hostapd_data *hapd, struct sta_info *sta);
 void ht40_intolerant_add(struct hostapd_iface *iface, struct sta_info *sta);
 void ht40_intolerant_remove(struct hostapd_iface *iface, struct sta_info *sta);
 u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c
index cf3867c86..f90f1254e 100644
--- a/src/ap/ieee802_11_ht.c
+++ b/src/ap/ieee802_11_ht.c
@@ -479,15 +479,14 @@ static void update_sta_no_ht(struct hostapd_data *hapd, struct sta_info *sta)
 }
 
 
-void update_ht_state(struct hostapd_data *hapd, struct sta_info *sta)
+int update_ht_state(struct hostapd_data *hapd, struct sta_info *sta)
 {
 	if ((sta->flags & WLAN_STA_HT) && sta->ht_capabilities)
 		update_sta_ht(hapd, sta);
 	else
 		update_sta_no_ht(hapd, sta);
 
-	if (hostapd_ht_operation_update(hapd->iface) > 0)
-		ieee802_11_update_beacons(hapd->iface);
+	return hostapd_ht_operation_update(hapd->iface);
 }
 
 
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 77417ae6a..b80831d4b 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -769,7 +769,8 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
 		set_disable_ht40(sta->ht_capabilities, 1);
 	}
 
-	update_ht_state(data, sta);
+	if (update_ht_state(data, sta) > 0 )
+		ieee802_11_set_beacons(data->iface);
 
 #ifdef CONFIG_IEEE80211AC
 	copy_sta_vht_capab(data, sta, elems->vht_capabilities);
-- 
2.17.1




More information about the Hostap mailing list