huangcm
2024-12-18 9d29be7f7249789d6ffd0440067187a9f040c2cd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/*
 * 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 int get_bss_load_update_timeout(struct hostapd_data *hapd,
                      unsigned int *sec, unsigned int *usec)
{
   unsigned int update_period = hapd->conf->bss_load_update_period;
   unsigned int beacon_int = hapd->iconf->beacon_int;
   unsigned int update_timeout;
 
   if (!update_period || !beacon_int) {
       wpa_printf(MSG_ERROR,
              "BSS Load: Invalid BSS load update configuration (period=%u beacon_int=%u)",
              update_period, beacon_int);
       return -1;
   }
 
   update_timeout = update_period * beacon_int;
 
   *sec = ((update_timeout / 1000) * 1024) / 1000;
   *usec = (update_timeout % 1000) * 1024;
 
   return 0;
}
 
 
static void update_channel_utilization(void *eloop_data, void *user_data)
{
   struct hostapd_data *hapd = eloop_data;
   unsigned int sec, usec;
   int err;
   struct hostapd_iface *iface = hapd->iface;
 
   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);
 
   if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
       return;
 
   if (hapd->conf->chan_util_avg_period) {
       iface->chan_util_samples_sum += iface->channel_utilization;
       iface->chan_util_num_sample_periods +=
           hapd->conf->bss_load_update_period;
       if (iface->chan_util_num_sample_periods >=
           hapd->conf->chan_util_avg_period) {
           iface->chan_util_average =
               iface->chan_util_samples_sum /
               (iface->chan_util_num_sample_periods /
                hapd->conf->bss_load_update_period);
           iface->chan_util_samples_sum = 0;
           iface->chan_util_num_sample_periods = 0;
       }
   }
 
   eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
                  NULL);
}
 
 
int bss_load_update_init(struct hostapd_data *hapd)
{
   unsigned int sec, usec;
 
   if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
       return -1;
 
   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);
}