bss_load.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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. #include "utils/includes.h"
  9. #include "utils/common.h"
  10. #include "utils/eloop.h"
  11. #include "hostapd.h"
  12. #include "bss_load.h"
  13. #include "ap_drv_ops.h"
  14. #include "beacon.h"
  15. static int get_bss_load_update_timeout(struct hostapd_data *hapd,
  16. unsigned int *sec, unsigned int *usec)
  17. {
  18. unsigned int update_period = hapd->conf->bss_load_update_period;
  19. unsigned int beacon_int = hapd->iconf->beacon_int;
  20. unsigned int update_timeout;
  21. if (!update_period || !beacon_int) {
  22. wpa_printf(MSG_ERROR,
  23. "BSS Load: Invalid BSS load update configuration (period=%u beacon_int=%u)",
  24. update_period, beacon_int);
  25. return -1;
  26. }
  27. update_timeout = update_period * beacon_int;
  28. *sec = ((update_timeout / 1000) * 1024) / 1000;
  29. *usec = (update_timeout % 1000) * 1024;
  30. return 0;
  31. }
  32. static void update_channel_utilization(void *eloop_data, void *user_data)
  33. {
  34. struct hostapd_data *hapd = eloop_data;
  35. unsigned int sec, usec;
  36. int err;
  37. struct hostapd_iface *iface = hapd->iface;
  38. if (!(hapd->beacon_set_done && hapd->started))
  39. return;
  40. err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
  41. if (err) {
  42. wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
  43. return;
  44. }
  45. ieee802_11_set_beacon(hapd);
  46. if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
  47. return;
  48. if (hapd->conf->chan_util_avg_period) {
  49. iface->chan_util_samples_sum += iface->channel_utilization;
  50. iface->chan_util_num_sample_periods +=
  51. hapd->conf->bss_load_update_period;
  52. if (iface->chan_util_num_sample_periods >=
  53. hapd->conf->chan_util_avg_period) {
  54. iface->chan_util_average =
  55. iface->chan_util_samples_sum /
  56. (iface->chan_util_num_sample_periods /
  57. hapd->conf->bss_load_update_period);
  58. iface->chan_util_samples_sum = 0;
  59. iface->chan_util_num_sample_periods = 0;
  60. }
  61. }
  62. eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
  63. NULL);
  64. }
  65. int bss_load_update_init(struct hostapd_data *hapd)
  66. {
  67. unsigned int sec, usec;
  68. if (get_bss_load_update_timeout(hapd, &sec, &usec) < 0)
  69. return -1;
  70. eloop_register_timeout(sec, usec, update_channel_utilization, hapd,
  71. NULL);
  72. return 0;
  73. }
  74. void bss_load_update_deinit(struct hostapd_data *hapd)
  75. {
  76. eloop_cancel_timeout(update_channel_utilization, hapd, NULL);
  77. }