From a5d0bb42a22675945271f3007f117b8f476ed12a Mon Sep 17 00:00:00 2001 From: Jurijs Soloveckis Date: Fri, 3 Nov 2023 08:14:24 +0000 Subject: [PATCH] Reduce delay between Association Request and Association Response There is a delay between sending Association Response frame after having received Association Request frame, due to the fact that between receiving the request and sending the response the Beacon frame contents 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 BSSs and connected STAs. Optimize this by updating the beacon only once, even if there are multiple reasons for updates. Signed-off-by: Jurijs Soloveckis --- src/ap/ieee802_11.c | 16 +++++++++++----- src/ap/ieee802_11.h | 2 +- src/ap/ieee802_11_ht.c | 5 ++--- wpa_supplicant/mesh_mpm.c | 4 +++- 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 678925c7f..889348762 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_update_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; + bool set_beacon = false; 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 = true; } 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 = true; } 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 = true; } - update_ht_state(hapd, sta); + if (update_ht_state(hapd, sta) > 0) + set_beacon = true; hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_DEBUG, @@ -5473,6 +5476,9 @@ static void handle_assoc(struct hostapd_data *hapd, } #endif /* CONFIG_FILS */ + if (set_beacon) + ieee802_11_set_beacons(hapd->iface); + fail: /* 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..138c01399 100644 --- a/wpa_supplicant/mesh_mpm.c +++ b/wpa_supplicant/mesh_mpm.c @@ -16,6 +16,7 @@ #include "ap/hostapd.h" #include "ap/sta_info.h" #include "ap/ieee802_11.h" +#include "ap/beacon.h" #include "ap/wpa_auth.h" #include "wpa_supplicant_i.h" #include "driver_i.h" @@ -769,7 +770,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_update_beacons(data->iface); #ifdef CONFIG_IEEE80211AC copy_sta_vht_capab(data, sta, elems->vht_capabilities);