aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKyeyoon Park <kyeyoonp@qca.qualcomm.com>2014-10-15 23:36:04 (GMT)
committerJouni Malinen <j@w1.fi>2014-10-21 20:25:48 (GMT)
commitec8f36afca731aa6a30a314c54bb83441180719d (patch)
tree024bbf8bdd135f7049d29515b36ed6122e97ab66
parent8a5cc2fe385bc8afa4260f8953664db9861430eb (diff)
downloadhostap-ec8f36afca731aa6a30a314c54bb83441180719d.zip
hostap-ec8f36afca731aa6a30a314c54bb83441180719d.tar.gz
hostap-ec8f36afca731aa6a30a314c54bb83441180719d.tar.bz2
AP: Add support for BSS load element (STA Count, Channel Utilization)
The new "bss_load_update_period" parameter can be used to configure hostapd to advertise its BSS Load element in Beacon and Probe Response frames. This parameter is in the units of BUs (Beacon Units). When enabled, the STA Count and the Channel Utilization value will be updated periodically in the BSS Load element. The AAC is set to 0 sinze explicit admission control is not supported. Channel Utilization is calculated based on the channel survey information from the driver and as such, requires a driver that supports providing that information for the current operating channel. Signed-off-by: Kyeyoon Park <kyeyoonp@qca.qualcomm.com>
-rw-r--r--hostapd/Android.mk1
-rw-r--r--hostapd/Makefile1
-rw-r--r--hostapd/config_file.c9
-rw-r--r--hostapd/hostapd.conf5
-rw-r--r--src/ap/ap_config.h1
-rw-r--r--src/ap/beacon.c15
-rw-r--r--src/ap/bss_load.c65
-rw-r--r--src/ap/bss_load.h17
-rw-r--r--src/ap/drv_callbacks.c41
-rw-r--r--src/ap/hostapd.c8
-rw-r--r--src/ap/hostapd.h8
-rw-r--r--wpa_supplicant/Android.mk1
-rw-r--r--wpa_supplicant/Makefile1
13 files changed, 171 insertions, 2 deletions
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index edaf6fc..84a8778 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -95,6 +95,7 @@ OBJS += src/ap/preauth_auth.c
OBJS += src/ap/pmksa_cache_auth.c
OBJS += src/ap/ieee802_11_shared.c
OBJS += src/ap/beacon.c
+OBJS += src/ap/bss_load.c
OBJS_d =
OBJS_p =
LIBS =
diff --git a/hostapd/Makefile b/hostapd/Makefile
index ac6373e..dc5eacd 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -59,6 +59,7 @@ OBJS += ../src/ap/preauth_auth.o
OBJS += ../src/ap/pmksa_cache_auth.o
OBJS += ../src/ap/ieee802_11_shared.o
OBJS += ../src/ap/beacon.o
+OBJS += ../src/ap/bss_load.o
OBJS_c = hostapd_cli.o ../src/common/wpa_ctrl.o ../src/utils/os_$(CONFIG_OS).o
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index d4ba7cc..ddebf1f 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2489,6 +2489,15 @@ static int hostapd_config_fill(struct hostapd_config *conf,
line, bss->dtim_period);
return 1;
}
+ } else if (os_strcmp(buf, "bss_load_update_period") == 0) {
+ bss->bss_load_update_period = atoi(pos);
+ if (bss->bss_load_update_period < 0 ||
+ bss->bss_load_update_period > 100) {
+ wpa_printf(MSG_ERROR,
+ "Line %d: invalid bss_load_update_period %d",
+ line, bss->bss_load_update_period);
+ return 1;
+ }
} else if (os_strcmp(buf, "rts_threshold") == 0) {
conf->rts_threshold = atoi(pos);
if (conf->rts_threshold < 0 || conf->rts_threshold > 2347) {
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index d4e5bf0..2e6f841 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -435,6 +435,11 @@ wmm_ac_vo_acm=0
# associated stations in the BSS. By default, this bridging is allowed.
#ap_isolate=1
+# BSS Load update period (in BUs)
+# This field is used to enable and configure adding a BSS Load element into
+# Beacon and Probe Response frames.
+#bss_load_update_period=50
+
# Fixed BSS Load value for testing purposes
# This field can be used to configure hostapd to add a fixed BSS Load element
# into Beacon and Probe Response frames for testing purposes. The format is
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index e37a796..b693664 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -196,6 +196,7 @@ struct hostapd_bss_config {
int max_num_sta; /* maximum number of STAs in station table */
int dtim_period;
+ int bss_load_update_period;
int ieee802_1x; /* use IEEE 802.1X */
int eapol_version;
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 4cae0d9..22aef9f 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -34,16 +34,27 @@
static u8 * hostapd_eid_bss_load(struct hostapd_data *hapd, u8 *eid, size_t len)
{
+ if (len < 2 + 5)
+ return eid;
+
#ifdef CONFIG_TESTING_OPTIONS
if (hapd->conf->bss_load_test_set) {
- if (2 + 5 > len)
- return eid;
*eid++ = WLAN_EID_BSS_LOAD;
*eid++ = 5;
os_memcpy(eid, hapd->conf->bss_load_test, 5);
eid += 5;
+ return eid;
}
#endif /* CONFIG_TESTING_OPTIONS */
+ if (hapd->conf->bss_load_update_period) {
+ *eid++ = WLAN_EID_BSS_LOAD;
+ *eid++ = 5;
+ WPA_PUT_LE16(eid, hapd->num_sta);
+ eid += 2;
+ *eid++ = hapd->iface->channel_utilization;
+ WPA_PUT_LE16(eid, 0); /* no available admission capabity */
+ eid += 2;
+ }
return eid;
}
diff --git a/src/ap/bss_load.c b/src/ap/bss_load.c
new file mode 100644
index 0000000..fb63942
--- /dev/null
+++ b/src/ap/bss_load.c
@@ -0,0 +1,65 @@
+/*
+ * BSS Load Element / Channel Utilization
+ * Copyright (c) 2014, Qualcomm Atheros, Inc.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "utils/includes.h"
+
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "hostapd.h"
+#include "bss_load.h"
+#include "ap_drv_ops.h"
+#include "beacon.h"
+
+
+static void update_channel_utilization(void *eloop_data, void *user_data)
+{
+ struct hostapd_data *hapd = eloop_data;
+ unsigned int sec, usec;
+ int err;
+
+ if (!(hapd->beacon_set_done && hapd->started))
+ return;
+
+ err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
+ if (err) {
+ wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
+ return;
+ }
+
+ ieee802_11_set_beacon(hapd);
+
+ sec = ((hapd->bss_load_update_timeout / 1000) * 1024) / 1000;
+ usec = (hapd->bss_load_update_timeout % 1000) * 1024;
+ eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
+ NULL);
+}
+
+
+int bss_load_update_init(struct hostapd_data *hapd)
+{
+ struct hostapd_bss_config *conf = hapd->conf;
+ struct hostapd_config *iconf = hapd->iconf;
+ unsigned int sec, usec;
+
+ if (!conf->bss_load_update_period || !iconf->beacon_int)
+ return -1;
+
+ hapd->bss_load_update_timeout = conf->bss_load_update_period *
+ iconf->beacon_int;
+ sec = ((hapd->bss_load_update_timeout / 1000) * 1024) / 1000;
+ usec = (hapd->bss_load_update_timeout % 1000) * 1024;
+ eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
+ NULL);
+ return 0;
+}
+
+
+void bss_load_update_deinit(struct hostapd_data *hapd)
+{
+ eloop_cancel_timeout(update_channel_utilization, hapd, NULL);
+}
diff --git a/src/ap/bss_load.h b/src/ap/bss_load.h
new file mode 100644
index 0000000..ac3c793
--- /dev/null
+++ b/src/ap/bss_load.h
@@ -0,0 +1,17 @@
+/*
+ * BSS load update
+ * Copyright (c) 2014, Qualcomm Atheros, Inc.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef BSS_LOAD_UPDATE_H
+#define BSS_LOAD_UPDATE_H
+
+
+int bss_load_update_init(struct hostapd_data *hapd);
+void bss_load_update_deinit(struct hostapd_data *hapd);
+
+
+#endif /* BSS_LOAD_UPDATE_H */
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 3bde720..9beb322 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -858,6 +858,42 @@ static void hostapd_update_nf(struct hostapd_iface *iface,
}
+static void hostapd_single_channel_get_survey(struct hostapd_iface *iface,
+ struct survey_results *survey_res)
+{
+ struct hostapd_channel_data *chan;
+ struct freq_survey *survey;
+ u64 divisor, dividend;
+
+ survey = dl_list_first(&survey_res->survey_list, struct freq_survey,
+ list);
+ if (!survey || !survey->freq)
+ return;
+
+ chan = hostapd_get_mode_channel(iface, survey->freq);
+ if (!chan || chan->flag & HOSTAPD_CHAN_DISABLED)
+ return;
+
+ wpa_printf(MSG_DEBUG, "Single Channel Survey: (freq=%d channel_time=%ld channel_time_busy=%ld)",
+ survey->freq,
+ (unsigned long int) survey->channel_time,
+ (unsigned long int) survey->channel_time_busy);
+
+ if (survey->channel_time > iface->last_channel_time &&
+ survey->channel_time > survey->channel_time_busy) {
+ dividend = survey->channel_time_busy -
+ iface->last_channel_time_busy;
+ divisor = survey->channel_time - iface->last_channel_time;
+
+ iface->channel_utilization = dividend * 255 / divisor;
+ wpa_printf(MSG_DEBUG, "Channel Utilization: %d",
+ iface->channel_utilization);
+ }
+ iface->last_channel_time = survey->channel_time;
+ iface->last_channel_time_busy = survey->channel_time_busy;
+}
+
+
static void hostapd_event_get_survey(struct hostapd_data *hapd,
struct survey_results *survey_results)
{
@@ -870,6 +906,11 @@ static void hostapd_event_get_survey(struct hostapd_data *hapd,
return;
}
+ if (survey_results->freq_filter) {
+ hostapd_single_channel_get_survey(iface, survey_results);
+ return;
+ }
+
dl_list_for_each_safe(survey, tmp, &survey_results->survey_list,
struct freq_survey, list) {
chan = hostapd_get_mode_channel(iface, survey->freq);
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 764722f..be7dfd8 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -35,6 +35,7 @@
#include "gas_serv.h"
#include "dfs.h"
#include "ieee802_11.h"
+#include "bss_load.h"
static int hostapd_flush_old_stations(struct hostapd_data *hapd, u16 reason);
@@ -310,6 +311,8 @@ static void hostapd_free_hapd_data(struct hostapd_data *hapd)
gas_serv_deinit(hapd);
#endif /* CONFIG_INTERWORKING */
+ bss_load_update_deinit(hapd);
+
#ifdef CONFIG_SQLITE
bin_clear_free(hapd->tmp_eap_user.identity,
hapd->tmp_eap_user.identity_len);
@@ -875,6 +878,11 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
}
#endif /* CONFIG_INTERWORKING */
+ if (conf->bss_load_update_period && bss_load_update_init(hapd)) {
+ wpa_printf(MSG_ERROR, "BSS Load initialization failed");
+ return -1;
+ }
+
if (!hostapd_drv_none(hapd) && vlan_init(hapd)) {
wpa_printf(MSG_ERROR, "VLAN initialization failed.");
return -1;
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index ca01a68..50ebe0e 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -218,6 +218,9 @@ struct hostapd_data {
unsigned int cs_c_off_proberesp;
int csa_in_progress;
+ /* BSS Load */
+ unsigned int bss_load_update_timeout;
+
#ifdef CONFIG_P2P
struct p2p_data *p2p;
struct p2p_group *p2p_group;
@@ -354,6 +357,11 @@ struct hostapd_iface {
/* lowest observed noise floor in dBm */
s8 lowest_nf;
+ /* channel utilization calculation */
+ u64 last_channel_time;
+ u64 last_channel_time_busy;
+ u8 channel_utilization;
+
unsigned int dfs_cac_ms;
struct os_reltime dfs_cac_start;
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 8b7df6c..7d1bb9e 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -767,6 +767,7 @@ OBJS += src/ap/ieee802_11_shared.c
OBJS += src/ap/drv_callbacks.c
OBJS += src/ap/ap_drv_ops.c
OBJS += src/ap/beacon.c
+OBJS += src/ap/bss_load.c
OBJS += src/ap/eap_user_db.c
ifdef CONFIG_IEEE80211N
OBJS += src/ap/ieee802_11_ht.c
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index 7eee73a..6556ec4 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -782,6 +782,7 @@ OBJS += ../src/ap/ieee802_11_shared.o
OBJS += ../src/ap/drv_callbacks.o
OBJS += ../src/ap/ap_drv_ops.o
OBJS += ../src/ap/beacon.o
+OBJS += ../src/ap/bss_load.o
OBJS += ../src/ap/eap_user_db.o
ifdef CONFIG_IEEE80211N
OBJS += ../src/ap/ieee802_11_ht.o