[PATCH 2/4] hostapd: add RSSI based association rejection support
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Mon Aug 21 09:43:53 PDT 2017
From: Beni Lev <beni.lev at intel.com>
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 at intel.com>
---
hostapd/config_file.c | 4 ++++
hostapd/hostapd.conf | 9 +++++++++
src/ap/ap_config.c | 3 +++
src/ap/ap_config.h | 3 +++
src/ap/ieee802_11.c | 25 +++++++++++++++++++------
src/ap/ieee802_11.h | 3 +++
src/ap/ieee802_11_shared.c | 14 ++++++++++++++
7 files changed, 55 insertions(+), 6 deletions(-)
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index cc799d4..4062569 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -3740,6 +3740,10 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "dpp_csign_expiry") == 0) {
bss->dpp_csign_expiry = strtol(pos, NULL, 0);
#endif /* CONFIG_DPP */
+ } 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'",
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 7ad3206..63a47f3 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -2225,3 +2225,12 @@ own_ip_addr=127.0.0.1
#bss=wlan0_1
#bssid=00:13:10:95:fe:0b
# ...
+
+# RSSI based assocition rejection settings
+#
+# Reject STA association if RSSI is below given threshold(in dBm)
+#rssi_reject_assoc_rssi=-75
+#
+# Assoc retry delay in seconds allowed by the STA if RSSI has not met the
+# threshold. (default=30)
+#rssi_reject_assoc_timeout=60
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 07a13f8..eb4e293 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -219,6 +219,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;
}
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 8e5ff52..514aaf5 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -785,6 +785,9 @@ struct hostapd_config {
struct he_phy_capabilities_info he_phy_capab;
struct he_operation he_op;
#endif /* CONFIG_IEEE80211AX */
+
+ int rssi_reject_assoc_rssi;
+ int rssi_reject_assoc_timeout;
};
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 7999611..6f51214 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2576,7 +2576,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;
@@ -2621,6 +2621,13 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
/* Extended supported rates */
p = hostapd_eid_ext_supp_rates(hapd, p);
+ if (status_code == WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS) {
+ int delta = hapd->iconf->rssi_reject_assoc_rssi - rssi;
+
+ p = hostapd_eid_mbo_rssi_assoc_rej(hapd, p, buf + buflen - p,
+ delta);
+ }
+
#ifdef CONFIG_IEEE80211R_AP
if (sta && status_code == WLAN_STATUS_SUCCESS) {
/* IEEE 802.11r: Mobility Domain Information, Fast BSS
@@ -2820,7 +2827,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;
@@ -2860,7 +2867,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;
@@ -2931,6 +2938,12 @@ static void handle_assoc(struct hostapd_data *hapd,
}
sta = ap_get_sta(hapd, mgmt->sa);
+
+ if (hapd->iconf->rssi_reject_assoc_rssi &&
+ rssi < hapd->iconf->rssi_reject_assoc_rssi) {
+ resp = WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS;
+ goto fail;
+ }
#ifdef CONFIG_IEEE80211R_AP
if (sta && sta->auth_alg == WLAN_AUTH_FT &&
(sta->flags & WLAN_STA_AUTH) == 0) {
@@ -3218,7 +3231,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);
/*
@@ -3652,12 +3665,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, fi->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, fi->ssi_signal);
ret = 1;
break;
case WLAN_FC_STYPE_DISASSOC:
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index 0653fb2..97cfdaf 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -112,6 +112,9 @@ static inline void sae_clear_retransmit_timer(struct hostapd_data *hapd,
}
#endif /* CONFIG_SAE */
+u8 * hostapd_eid_mbo_rssi_assoc_rej(struct hostapd_data *hapd, u8 *eid,
+ size_t len, int delta);
+
#ifdef CONFIG_MBO
u8 * hostapd_eid_mbo(struct hostapd_data *hapd, u8 *eid, size_t len);
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index 902f64f..66fb4ef 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -539,6 +539,20 @@ u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid)
return pos;
}
+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);
+}
#ifdef CONFIG_MBO
--
2.7.4
More information about the Hostap
mailing list