aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBeni Lev <beni.lev@intel.com>2017-08-21 16:43:53 (GMT)
committerJouni Malinen <j@w1.fi>2019-01-01 16:18:50 (GMT)
commit076f1ea1d9d78a2ecca678e3a7dddec128ff19fc (patch)
tree1c286b2629c213510e9716d35da25348a75dc81c /src
parent19677b77c3a48116eb2fa5db06966da7220cd76d (diff)
downloadhostap-076f1ea1d9d78a2ecca678e3a7dddec128ff19fc.zip
hostap-076f1ea1d9d78a2ecca678e3a7dddec128ff19fc.tar.gz
hostap-076f1ea1d9d78a2ecca678e3a7dddec128ff19fc.tar.bz2
OCE: Add RSSI based association rejection support (AP)
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>
Diffstat (limited to 'src')
-rw-r--r--src/ap/ap_config.c3
-rw-r--r--src/ap/ap_config.h3
-rw-r--r--src/ap/ieee802_11.c28
-rw-r--r--src/ap/ieee802_11.h3
-rw-r--r--src/ap/ieee802_11_shared.c16
5 files changed, 47 insertions, 6 deletions
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 68abb8e..95a3476 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -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;
}
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index f0645dc..c49e2c1 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -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;
};
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 026cbf0..d364308 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -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:
diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h
index b57f2d0..11747e1 100644
--- a/src/ap/ieee802_11.h
+++ b/src/ap/ieee802_11.h
@@ -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,
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index f6c655f..82bc086 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -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;