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>
master
Kyeyoon Park 10 years ago committed by Jouni Malinen
parent 8a5cc2fe38
commit ec8f36afca

@ -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 =

@ -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

@ -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) {

@ -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

@ -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;

@ -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;
}

@ -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);
}

@ -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 */

@ -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);

@ -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;

@ -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;

@ -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

@ -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

Loading…
Cancel
Save