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 <jsoloveckis@maxlinear.com>
This commit is contained in:
Jurijs Soloveckis 2023-11-03 08:14:24 +00:00 committed by Jouni Malinen
parent 3f2c41e318
commit a5d0bb42a2
4 changed files with 17 additions and 10 deletions

View file

@ -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); hapd->sta_aid[(sta->aid - 1) / 32] |= BIT((sta->aid - 1) % 32);
sta->listen_interval = origin_sta->listen_interval; 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 */ /* RSN Authenticator should always be the one on the original station */
wpa_auth_sta_deinit(sta->wpa_sm); wpa_auth_sta_deinit(sta->wpa_sm);
@ -5164,6 +5165,7 @@ static void handle_assoc(struct hostapd_data *hapd,
int delay_assoc = 0; int delay_assoc = 0;
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
int omit_rsnxe = 0; int omit_rsnxe = 0;
bool set_beacon = false;
if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) : if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
sizeof(mgmt->u.assoc_req))) { sizeof(mgmt->u.assoc_req))) {
@ -5405,7 +5407,7 @@ static void handle_assoc(struct hostapd_data *hapd,
sta->nonerp_set = 1; sta->nonerp_set = 1;
hapd->iface->num_sta_non_erp++; hapd->iface->num_sta_non_erp++;
if (hapd->iface->num_sta_non_erp == 1) 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) && 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 == hapd->iface->current_mode->mode ==
HOSTAPD_MODE_IEEE80211G && HOSTAPD_MODE_IEEE80211G &&
hapd->iface->num_sta_no_short_slot_time == 1) 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) if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
@ -5431,10 +5433,11 @@ static void handle_assoc(struct hostapd_data *hapd,
if (hapd->iface->current_mode && if (hapd->iface->current_mode &&
hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
&& hapd->iface->num_sta_no_short_preamble == 1) && 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_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG, HOSTAPD_LEVEL_DEBUG,
@ -5473,6 +5476,9 @@ static void handle_assoc(struct hostapd_data *hapd,
} }
#endif /* CONFIG_FILS */ #endif /* CONFIG_FILS */
if (set_beacon)
ieee802_11_set_beacons(hapd->iface);
fail: fail:
/* /*

View file

@ -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, u16 copy_sta_vendor_vht(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *ie, size_t len); 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_add(struct hostapd_iface *iface, struct sta_info *sta);
void ht40_intolerant_remove(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, u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,

View file

@ -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) if ((sta->flags & WLAN_STA_HT) && sta->ht_capabilities)
update_sta_ht(hapd, sta); update_sta_ht(hapd, sta);
else else
update_sta_no_ht(hapd, sta); update_sta_no_ht(hapd, sta);
if (hostapd_ht_operation_update(hapd->iface) > 0) return hostapd_ht_operation_update(hapd->iface);
ieee802_11_update_beacons(hapd->iface);
} }

View file

@ -16,6 +16,7 @@
#include "ap/hostapd.h" #include "ap/hostapd.h"
#include "ap/sta_info.h" #include "ap/sta_info.h"
#include "ap/ieee802_11.h" #include "ap/ieee802_11.h"
#include "ap/beacon.h"
#include "ap/wpa_auth.h" #include "ap/wpa_auth.h"
#include "wpa_supplicant_i.h" #include "wpa_supplicant_i.h"
#include "driver_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); 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 #ifdef CONFIG_IEEE80211AC
copy_sta_vht_capab(data, sta, elems->vht_capabilities); copy_sta_vht_capab(data, sta, elems->vht_capabilities);