]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OCE: Add RSSI based association rejection support (AP)
authorBeni Lev <beni.lev@intel.com>
Mon, 21 Aug 2017 16:43:53 +0000 (19:43 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 1 Jan 2019 16:18:50 +0000 (18:18 +0200)
An AP might reject a STA association request due to low RSSI. In such
case, the AP informs the STA the desired RSSI improvement and a retry
timeout. The STA might retry to associate even if the RSSI hasn't
improved if the retry timeout expired.

Signed-off-by: Beni Lev <beni.lev@intel.com>
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/ieee802_11.c
src/ap/ieee802_11.h
src/ap/ieee802_11_shared.c

index cb8d26fce818aeb9a60da727e0d61d6f8ff5eda7..19ccb30cd85f418efb6977947ec6edc65079a6ab 100644 (file)
@@ -4156,6 +4156,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                }
 
                bss->multi_ap = val;
+       } else if (os_strcmp(buf, "rssi_reject_assoc_rssi") == 0) {
+               conf->rssi_reject_assoc_rssi = atoi(pos);
+       } else if (os_strcmp(buf, "rssi_reject_assoc_timeout") == 0) {
+               conf->rssi_reject_assoc_timeout = atoi(pos);
        } else {
                wpa_printf(MSG_ERROR,
                           "Line %d: unknown configuration item '%s'",
index e934b9f34e88f00edd8de001c1dc867708d9c4a8..d234a43399486a39ccfdd2339ecc2ac23831ca1b 100644 (file)
@@ -2295,6 +2295,21 @@ own_ip_addr=127.0.0.1
 # Default is 0 = OCE disabled
 #oce=0
 
+# RSSI-based assocition rejection
+#
+# Reject STA association if RSSI is below given threshold (in dBm)
+# Allowed range: -60 to -90 dBm; default = 0 (rejection disabled)
+# Note: This rejection happens based on a signal strength detected while
+# receiving a single frame and as such, there is significant risk of the value
+# not being accurate and this resulting in valid stations being rejected. As
+# such, this functionality is not recommended to be used for purposes other than
+# testing.
+#rssi_reject_assoc_rssi=-75
+#
+# Association retry delay in seconds allowed by the STA if RSSI has not met the
+# threshold (range: 0..255, default=30).
+#rssi_reject_assoc_timeout=30
+
 ##### Fast Session Transfer (FST) support #####################################
 #
 # The options in this section are only available when the build configuration
index 68abb8e32830f7389e1665d9b78decb328864bef..95a34763ba933bfbce4ed9dc9c72369fc0115e6f 100644 (file)
@@ -241,6 +241,9 @@ struct hostapd_config * hostapd_config_defaults(void)
         * environments for the current frequency band in the country. */
        conf->country[2] = ' ';
 
+       conf->rssi_reject_assoc_rssi = 0;
+       conf->rssi_reject_assoc_timeout = 30;
+
        return conf;
 }
 
index f0645dcf9d5d00bd0fffa47a3cff03f8971da7c0..c49e2c1c41f8c9bf79767d10c1e396b84fd414fd 100644 (file)
@@ -849,6 +849,9 @@ struct hostapd_config {
 #define CH_SWITCH_VHT_ENABLED BIT(0)
 #define CH_SWITCH_VHT_DISABLED BIT(1)
        unsigned int ch_switch_vht_config;
+
+       int rssi_reject_assoc_rssi;
+       int rssi_reject_assoc_timeout;
 };
 
 
index 026cbf025eba3c003bd8b8bed1e3ca438c355f44..d36430801d621661f281f572a9dc02538cc2363a 100644 (file)
@@ -2976,7 +2976,7 @@ static int add_associated_sta(struct hostapd_data *hapd,
 
 static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
                           const u8 *addr, u16 status_code, int reassoc,
-                          const u8 *ies, size_t ies_len)
+                          const u8 *ies, size_t ies_len, int rssi)
 {
        int send_len;
        u8 *buf;
@@ -3021,6 +3021,16 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
        /* Extended supported rates */
        p = hostapd_eid_ext_supp_rates(hapd, p);
 
+#ifdef CONFIG_MBO
+       if (status_code == WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS &&
+           rssi != 0) {
+               int delta = hapd->iconf->rssi_reject_assoc_rssi - rssi;
+
+               p = hostapd_eid_mbo_rssi_assoc_rej(hapd, p, buf + buflen - p,
+                                                  delta);
+       }
+#endif /* CONFIG_MBO */
+
 #ifdef CONFIG_IEEE80211R_AP
        if (sta && status_code == WLAN_STATUS_SUCCESS) {
                /* IEEE 802.11r: Mobility Domain Information, Fast BSS
@@ -3292,7 +3302,7 @@ void fils_hlp_finish_assoc(struct hostapd_data *hapd, struct sta_info *sta)
        reply_res = send_assoc_resp(hapd, sta, sta->addr, WLAN_STATUS_SUCCESS,
                                    sta->fils_pending_assoc_is_reassoc,
                                    sta->fils_pending_assoc_req,
-                                   sta->fils_pending_assoc_req_len);
+                                   sta->fils_pending_assoc_req_len, 0);
        os_free(sta->fils_pending_assoc_req);
        sta->fils_pending_assoc_req = NULL;
        sta->fils_pending_assoc_req_len = 0;
@@ -3329,7 +3339,7 @@ void fils_hlp_timeout(void *eloop_ctx, void *eloop_data)
 
 static void handle_assoc(struct hostapd_data *hapd,
                         const struct ieee80211_mgmt *mgmt, size_t len,
-                        int reassoc)
+                        int reassoc, int rssi)
 {
        u16 capab_info, listen_interval, seq_ctrl, fc;
        u16 resp = WLAN_STATUS_SUCCESS, reply_res;
@@ -3512,6 +3522,12 @@ static void handle_assoc(struct hostapd_data *hapd,
                resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
                goto fail;
        }
+
+       if (hapd->iconf->rssi_reject_assoc_rssi && rssi &&
+           rssi < hapd->iconf->rssi_reject_assoc_rssi) {
+               resp = WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS;
+               goto fail;
+       }
 #endif /* CONFIG_MBO */
 
        /*
@@ -3710,7 +3726,7 @@ static void handle_assoc(struct hostapd_data *hapd,
 #endif /* CONFIG_FILS */
 
        reply_res = send_assoc_resp(hapd, sta, mgmt->sa, resp, reassoc, pos,
-                                   left);
+                                   left, rssi);
        os_free(tmp);
 
        /*
@@ -4155,12 +4171,12 @@ int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
                break;
        case WLAN_FC_STYPE_ASSOC_REQ:
                wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
-               handle_assoc(hapd, mgmt, len, 0);
+               handle_assoc(hapd, mgmt, len, 0, ssi_signal);
                ret = 1;
                break;
        case WLAN_FC_STYPE_REASSOC_REQ:
                wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
-               handle_assoc(hapd, mgmt, len, 1);
+               handle_assoc(hapd, mgmt, len, 1, ssi_signal);
                ret = 1;
                break;
        case WLAN_FC_STYPE_DISASSOC:
index b57f2d0bac0f9d46e5ddc948c32bb62b895cb5f1..11747e135cc8a1d6c1490f17a8b7a09a5c353cab 100644 (file)
@@ -122,6 +122,9 @@ u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len);
 
 u8 hostapd_mbo_ie_len(struct hostapd_data *hapd);
 
+u8 * hostapd_eid_mbo_rssi_assoc_rej(struct hostapd_data *hapd, u8 *eid,
+                                   size_t len, int delta);
+
 #else /* CONFIG_MBO */
 
 static inline u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid,
index f6c655fd3f5f5f54ec155e0f1171bd03fc52f418..82bc086a7dfb229f5e8a8355654463ac1d9e3af0 100644 (file)
@@ -682,6 +682,22 @@ u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid)
 
 #ifdef CONFIG_MBO
 
+u8 * hostapd_eid_mbo_rssi_assoc_rej(struct hostapd_data *hapd, u8 *eid,
+                                   size_t len, int delta)
+{
+       u8 mbo[4];
+
+       mbo[0] = OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT;
+       mbo[1] = 2;
+       /* Delta RSSI */
+       mbo[2] = delta;
+       /* Retry delay */
+       mbo[3] = hapd->iconf->rssi_reject_assoc_timeout;
+
+       return eid + mbo_add_ie(eid, len, mbo, 4);
+}
+
+
 u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len)
 {
        u8 mbo[9], *mbo_pos = mbo;