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:
Mathy Vanhoef 2018-08-06 15:46:35 -04:00 committed by Jouni Malinen
parent f9da7505bf
commit f91e68e903
4 changed files with 31 additions and 0 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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)
{
}