OCV: Perform an SA Query after a channel switch
After the network changed to a new channel, perform an SA Query with the AP after a random delay if OCV was negotiated for the association. This is used to confirm that we are still operating on the real operating channel of the network. This commit is adding only the station side functionality for this, i.e., the AP behavior is not changed to disconnect stations with OCV that do not go through SA Query. Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
This commit is contained in:
parent
f9da7505bf
commit
f91e68e903
4 changed files with 31 additions and 0 deletions
|
@ -739,6 +739,8 @@ void hostapd_event_sta_opmode_changed(struct hostapd_data *hapd, const u8 *addr,
|
|||
void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
|
||||
int offset, int width, int cf1, int cf2)
|
||||
{
|
||||
/* TODO: If OCV is enabled deauth STAs that don't perform a SA Query */
|
||||
|
||||
#ifdef NEED_AP_MLME
|
||||
int channel, chwidth, is_dfs;
|
||||
u8 seg0_idx = 0, seg1_idx = 0;
|
||||
|
|
|
@ -4339,6 +4339,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|||
}
|
||||
#endif /* CONFIG_AP */
|
||||
|
||||
#ifdef CONFIG_IEEE80211W
|
||||
sme_event_ch_switch(wpa_s);
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_CS);
|
||||
wnm_clear_coloc_intf_reporting(wpa_s);
|
||||
break;
|
||||
|
|
|
@ -2220,6 +2220,7 @@ void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable)
|
|||
|
||||
static const unsigned int sa_query_max_timeout = 1000;
|
||||
static const unsigned int sa_query_retry_timeout = 201;
|
||||
static const unsigned int sa_query_ch_switch_max_delay = 5000; /* in usec */
|
||||
|
||||
static int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
|
@ -2368,6 +2369,26 @@ void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
|
|||
}
|
||||
|
||||
|
||||
void sme_event_ch_switch(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
unsigned int usec;
|
||||
u32 _rand;
|
||||
|
||||
if (wpa_s->wpa_state != WPA_COMPLETED ||
|
||||
!wpa_sm_ocv_enabled(wpa_s->wpa))
|
||||
return;
|
||||
|
||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||
"SME: Channel switch completed - trigger new SA Query to verify new operating channel");
|
||||
sme_stop_sa_query(wpa_s);
|
||||
|
||||
if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0)
|
||||
_rand = os_random();
|
||||
usec = _rand % (sa_query_ch_switch_max_delay + 1);
|
||||
eloop_register_timeout(0, usec, sme_sa_query_timer, wpa_s, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void sme_process_sa_query_request(struct wpa_supplicant *wpa_s,
|
||||
const u8 *sa, const u8 *data,
|
||||
size_t len)
|
||||
|
|
|
@ -28,6 +28,7 @@ void sme_event_disassoc(struct wpa_supplicant *wpa_s,
|
|||
struct disassoc_info *info);
|
||||
void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
|
||||
const u8 *da, u16 reason_code);
|
||||
void sme_event_ch_switch(struct wpa_supplicant *wpa_s);
|
||||
void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa,
|
||||
const u8 *data, size_t len);
|
||||
void sme_state_changed(struct wpa_supplicant *wpa_s);
|
||||
|
@ -89,6 +90,10 @@ static inline void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s,
|
|||
{
|
||||
}
|
||||
|
||||
static inline void sme_event_ch_switch(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void sme_state_changed(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue