]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Ignore LOW_ACK event for co-operative steering clients
authorRajkumar Manoharan <rmanohar@codeaurora.org>
Tue, 13 Mar 2018 03:20:28 +0000 (08:50 +0530)
committerJouni Malinen <j@w1.fi>
Mon, 19 Mar 2018 18:16:32 +0000 (20:16 +0200)
Ignore hostapd_event_sta_low_ack for a station which has agreed to
steering by checking the agreed_to_steer flag. This flag will be set
whenever a station accepts the BSS transition request from the AP.
Without this ignoring of the LOW_ACK event, the steering in-progress
might be affected due to disassociation. In this way AP will allow some
time (two seconds) for the station to move away and reset the flag after
the timeout.

Co-Developed-by: Tamizh Chelvam <tamizhr@codeaurora.org>
Signed-off-by: Rajkumar Manoharan <rmanohar@codeaurora.org>
Signed-off-by: Tamizh chelvam <tamizhr@codeaurora.org>
src/ap/drv_callbacks.c
src/ap/sta_info.c
src/ap/sta_info.h
src/ap/wnm_ap.c
src/ap/wnm_ap.h

index f0d6a4ccb8d77a6c698c1d14573f29f04cec05e8..b9443ee242cf9e4f96e4a7444095638a5a6591c9 100644 (file)
@@ -642,7 +642,7 @@ void hostapd_event_sta_low_ack(struct hostapd_data *hapd, const u8 *addr)
 {
        struct sta_info *sta = ap_get_sta(hapd, addr);
 
-       if (!sta || !hapd->conf->disassoc_low_ack)
+       if (!sta || !hapd->conf->disassoc_low_ack || sta->agreed_to_steer)
                return;
 
        hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
index 49a0dbe852f51600b3c56c1ee686a6cf5775897a..154879c0651b722b4f8540ca2d18dcd54ef5f802 100644 (file)
@@ -361,6 +361,10 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
 
        os_free(sta->ext_capability);
 
+#ifdef CONFIG_WNM_AP
+       eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta);
+#endif /* CONFIG_WNM_AP */
+
        os_free(sta);
 }
 
index b4e7806db1e6adf4bd14a69d4ac3c2eb82ad5dad..255ac1fee7b021a02006e585d3f72ff756a04be9 100644 (file)
@@ -115,6 +115,7 @@ struct sta_info {
        unsigned int added_unassoc:1;
        unsigned int pending_wds_enable:1;
        unsigned int power_capab:1;
+       unsigned int agreed_to_steer:1;
 
        u16 auth_alg;
 
index f0462829f1820022a7e50ac58aec0bd727d70aa9..710fe502b0fc41abde222473a3b87d22e2a9a03a 100644 (file)
@@ -341,6 +341,19 @@ static void ieee802_11_rx_bss_trans_mgmt_query(struct hostapd_data *hapd,
 }
 
 
+void ap_sta_reset_steer_flag_timer(void *eloop_ctx, void *timeout_ctx)
+{
+       struct hostapd_data *hapd = eloop_ctx;
+       struct sta_info *sta = timeout_ctx;
+
+       if (sta->agreed_to_steer) {
+               wpa_printf(MSG_DEBUG, "%s: Reset steering flag for STA " MACSTR,
+                          hapd->conf->iface, MAC2STR(sta->addr));
+               sta->agreed_to_steer = 0;
+       }
+}
+
+
 static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
                                              const u8 *addr, const u8 *frm,
                                              size_t len)
@@ -348,6 +361,7 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
        u8 dialog_token, status_code, bss_termination_delay;
        const u8 *pos, *end;
        int enabled = hapd->conf->bss_transition;
+       struct sta_info *sta;
 
 #ifdef CONFIG_MBO
        if (hapd->conf->mbo_enabled)
@@ -379,11 +393,23 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
                   "bss_termination_delay=%u", MAC2STR(addr), dialog_token,
                   status_code, bss_termination_delay);
 
+       sta = ap_get_sta(hapd, addr);
+       if (!sta) {
+               wpa_printf(MSG_DEBUG, "Station " MACSTR
+                          " not found for received BSS TM Response",
+                          MAC2STR(addr));
+               return;
+       }
+
        if (status_code == WNM_BSS_TM_ACCEPT) {
                if (end - pos < ETH_ALEN) {
                        wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field");
                        return;
                }
+               sta->agreed_to_steer = 1;
+               eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta);
+               eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer,
+                                      hapd, sta);
                wpa_printf(MSG_DEBUG, "WNM: Target BSSID: " MACSTR,
                           MAC2STR(pos));
                wpa_msg(hapd->msg_ctx, MSG_INFO, BSS_TM_RESP MACSTR
@@ -393,6 +419,7 @@ static void ieee802_11_rx_bss_trans_mgmt_resp(struct hostapd_data *hapd,
                        MAC2STR(pos));
                pos += ETH_ALEN;
        } else {
+               sta->agreed_to_steer = 0;
                wpa_msg(hapd->msg_ctx, MSG_INFO, BSS_TM_RESP MACSTR
                        " status_code=%u bss_termination_delay=%u",
                        MAC2STR(addr), status_code, bss_termination_delay);
index a44eadb85e5550e60eaf8df54e6c2cf4907ffb64..56d0f881ee272b3aafc2f8a400505c1e8b83c833 100644 (file)
@@ -23,5 +23,6 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
                        const u8 *bss_term_dur, const char *url,
                        const u8 *nei_rep, size_t nei_rep_len,
                        const u8 *mbo_attrs, size_t mbo_len);
+void ap_sta_reset_steer_flag_timer(void *eloop_ctx, void *timeout_ctx);
 
 #endif /* WNM_AP_H */