bss_load.c revision 346981
120253Sjoerg/*
220302Sjoerg * BSS Load Element / Channel Utilization
320302Sjoerg * Copyright (c) 2014, Qualcomm Atheros, Inc.
420253Sjoerg *
520253Sjoerg * This software may be distributed under the terms of the BSD license.
620253Sjoerg * See README for more details.
720253Sjoerg */
820253Sjoerg
920302Sjoerg#include "utils/includes.h"
1020253Sjoerg
1120253Sjoerg#include "utils/common.h"
1220253Sjoerg#include "utils/eloop.h"
1320253Sjoerg#include "hostapd.h"
1420302Sjoerg#include "bss_load.h"
1520253Sjoerg#include "ap_drv_ops.h"
1620253Sjoerg#include "beacon.h"
1720302Sjoerg
1820253Sjoerg
1920253Sjoergstatic int get_bss_load_update_timeout(struct hostapd_data *hapd,
2020253Sjoerg				       unsigned int *sec, unsigned int *usec)
2120253Sjoerg{
2220253Sjoerg	unsigned int update_period = hapd->conf->bss_load_update_period;
2320253Sjoerg	unsigned int beacon_int = hapd->iconf->beacon_int;
2420253Sjoerg	unsigned int update_timeout;
2544229Sdavidn
2620253Sjoerg	if (!update_period || !beacon_int) {
2720253Sjoerg		wpa_printf(MSG_ERROR,
2830259Scharnier			   "BSS Load: Invalid BSS load update configuration (period=%u beacon_int=%u)",
2930259Scharnier			   update_period, beacon_int);
3050479Speter		return -1;
3130259Scharnier	}
3230259Scharnier
3330259Scharnier	update_timeout = update_period * beacon_int;
3430259Scharnier
3520253Sjoerg	*sec = ((update_timeout / 1000) * 1024) / 1000;
3620253Sjoerg	*usec = (update_timeout % 1000) * 1024;
3720253Sjoerg
3830259Scharnier	return 0;
3920253Sjoerg}
4020555Sdavidn
4120555Sdavidn
4220555Sdavidnstatic void update_channel_utilization(void *eloop_data, void *user_data)
4330259Scharnier{
4422394Sdavidn	struct hostapd_data *hapd = eloop_data;
4564918Sgreen	unsigned int sec, usec;
4622394Sdavidn	int err;
4720555Sdavidn	struct hostapd_iface *iface = hapd->iface;
4822394Sdavidn
4920253Sjoerg	if (!(hapd->beacon_set_done && hapd->started))
5020253Sjoerg		return;
5120253Sjoerg
5223318Sache	err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
5322394Sdavidn	if (err) {
5422394Sdavidn		wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
5523318Sache		return;
5622394Sdavidn	}
5722394Sdavidn
5852512Sdavidn	ieee802_11_set_beacon(hapd);
5924214Sache
6044386Sdavidn	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
6120253Sjoerg		return;
6220253Sjoerg
6320253Sjoerg	if (hapd->conf->chan_util_avg_period) {
6420253Sjoerg		iface->chan_util_samples_sum += iface->channel_utilization;
6520253Sjoerg		iface->chan_util_num_sample_periods +=
6620253Sjoerg			hapd->conf->bss_load_update_period;
6720253Sjoerg		if (iface->chan_util_num_sample_periods >=
6820253Sjoerg		    hapd->conf->chan_util_avg_period) {
6920253Sjoerg			iface->chan_util_average =
7020747Sdavidn				iface->chan_util_samples_sum /
7120253Sjoerg				(iface->chan_util_num_sample_periods /
7220253Sjoerg				 hapd->conf->bss_load_update_period);
7320253Sjoerg			iface->chan_util_samples_sum = 0;
7420253Sjoerg			iface->chan_util_num_sample_periods = 0;
7520253Sjoerg		}
7620253Sjoerg	}
7720253Sjoerg
7820253Sjoerg	eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
7920253Sjoerg			       NULL);
8020253Sjoerg}
8120253Sjoerg
8220253Sjoerg
8320253Sjoergint bss_load_update_init(struct hostapd_data *hapd)
8420253Sjoerg{
8520253Sjoerg	unsigned int sec, usec;
8620253Sjoerg
8720253Sjoerg	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
8820253Sjoerg		return -1;
8920253Sjoerg
9020253Sjoerg	eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
9120253Sjoerg			       NULL);
9220253Sjoerg	return 0;
9320253Sjoerg}
9420253Sjoerg
9520253Sjoerg
9620253Sjoergvoid bss_load_update_deinit(struct hostapd_data *hapd)
9720253Sjoerg{
9820253Sjoerg	eloop_cancel_timeout(update_channel_utilization, hapd, NULL);
9920253Sjoerg}
10020253Sjoerg