Home | History | Annotate | Line # | Download | only in ap
      1 /*
      2  * BSS Load Element / Channel Utilization
      3  * Copyright (c) 2014, Qualcomm Atheros, Inc.
      4  *
      5  * This software may be distributed under the terms of the BSD license.
      6  * See README for more details.
      7  */
      8 
      9 #include "utils/includes.h"
     10 
     11 #include "utils/common.h"
     12 #include "utils/eloop.h"
     13 #include "hostapd.h"
     14 #include "bss_load.h"
     15 #include "ap_drv_ops.h"
     16 #include "beacon.h"
     17 
     18 
     19 static int get_bss_load_update_timeout(struct hostapd_data *hapd,
     20 				       unsigned int *sec, unsigned int *usec)
     21 {
     22 	unsigned int update_period = hapd->conf->bss_load_update_period;
     23 	unsigned int beacon_int = hapd->iconf->beacon_int;
     24 	unsigned int update_timeout;
     25 
     26 	if (!update_period || !beacon_int) {
     27 		wpa_printf(MSG_ERROR,
     28 			   "BSS Load: Invalid BSS load update configuration (period=%u beacon_int=%u)",
     29 			   update_period, beacon_int);
     30 		return -1;
     31 	}
     32 
     33 	update_timeout = update_period * beacon_int;
     34 
     35 	*sec = ((update_timeout / 1000) * 1024) / 1000;
     36 	*usec = (update_timeout % 1000) * 1024;
     37 
     38 	return 0;
     39 }
     40 
     41 
     42 static void update_channel_utilization(void *eloop_data, void *user_data)
     43 {
     44 	struct hostapd_data *hapd = eloop_data;
     45 	unsigned int sec, usec;
     46 	int err;
     47 	struct hostapd_iface *iface = hapd->iface;
     48 
     49 	if (!(hapd->beacon_set_done && hapd->started))
     50 		return;
     51 
     52 	err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
     53 	if (err) {
     54 		wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
     55 		return;
     56 	}
     57 
     58 	ieee802_11_set_beacon_per_bss_only(hapd);
     59 
     60 	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
     61 		return;
     62 
     63 	if (hapd->conf->chan_util_avg_period) {
     64 		iface->chan_util_samples_sum += iface->channel_utilization;
     65 		iface->chan_util_num_sample_periods +=
     66 			hapd->conf->bss_load_update_period;
     67 		if (iface->chan_util_num_sample_periods >=
     68 		    hapd->conf->chan_util_avg_period) {
     69 			iface->chan_util_average =
     70 				iface->chan_util_samples_sum /
     71 				(iface->chan_util_num_sample_periods /
     72 				 hapd->conf->bss_load_update_period);
     73 			iface->chan_util_samples_sum = 0;
     74 			iface->chan_util_num_sample_periods = 0;
     75 		}
     76 	}
     77 
     78 	eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
     79 			       NULL);
     80 }
     81 
     82 
     83 int bss_load_update_init(struct hostapd_data *hapd)
     84 {
     85 	unsigned int sec, usec;
     86 
     87 	if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
     88 		return -1;
     89 
     90 	eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
     91 			       NULL);
     92 	return 0;
     93 }
     94 
     95 
     96 void bss_load_update_deinit(struct hostapd_data *hapd)
     97 {
     98 	eloop_cancel_timeout(update_channel_utilization, hapd, NULL);
     99 }
    100