]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OCV: Perform an SA Query after a channel switch
authorMathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
Mon, 6 Aug 2018 19:46:35 +0000 (15:46 -0400)
committerJouni Malinen <j@w1.fi>
Mon, 17 Dec 2018 13:50:12 +0000 (15:50 +0200)
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>
src/ap/drv_callbacks.c
wpa_supplicant/events.c
wpa_supplicant/sme.c
wpa_supplicant/sme.h

index 7e71e6f8c46894161836fe80afb1a91f6f2b4e3c..fa81da9f87da301fb4bfd275d7af719a23ff91c1 100644 (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;
index 37d429d33022d055fc795190dcf7b0db1a25dbbe..8eac4be0f57390932943744c92af623828610f81 100644 (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;
index c4abff6eb54d3b8ab6a5d66b309b9f7ca04560a6..779c79b4397619655952f9377b8091814c005c9c 100644 (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)
index f3c8220255745a32ce664c66a05d796ff7eeb2fc..1a7f9e8320c749ae487bc7d748a7fc7ce2e5c32f 100644 (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)
 {
 }