[PATCH] ACS: BSS-based interference computation

Matej Vrba Matej.Vrba at advantech.cz
Tue Mar 4 06:12:06 PST 2025


Adds a fallback BSS-based channel selection if Survey-based selection
fails. Interference factor is simply the number of BSSes on that channel.

Signed-off-by: Matěj Vrba <matej.vrba at advantech.cz>
---
 src/ap/acs.c         | 39 ++++++++++++++++++++++++++++++++++++---
 src/drivers/driver.h |  6 ++++++
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/src/ap/acs.c b/src/ap/acs.c
index f5b36d327..55c989fb9 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -54,7 +54,7 @@
  * Todo / Ideas
  * ------------
  * - implement other interference computation methods
- *   - BSS/RSSI based
+ *   - RSSI based
  *   - spectral scan based
  *   (should be possibly to hook this up with current ACS scans)
  * - add wpa_supplicant support (for P2P)
@@ -557,6 +557,8 @@ static int acs_surveys_are_sufficient(struct hostapd_iface *iface)
 
 static int acs_usable_chan(struct hostapd_channel_data *chan)
 {
+    if (chan->interference_bss_based)
+        return 1;
     return !dl_list_empty(&chan->survey_list) &&
         !(chan->flag & HOSTAPD_CHAN_DISABLED) &&
         acs_survey_list_is_sufficient(chan);
@@ -1253,14 +1255,45 @@ static int acs_study_survey_based(struct hostapd_iface *iface)
     return 0;
 }
 
+static int acs_study_bss_based(struct hostapd_iface *iface)
+{
+    struct wpa_scan_results     *scan_res;
+    unsigned int                 bss_on_ch;
+    struct hostapd_channel_data *chan;
+    wpa_printf(MSG_DEBUG, "ACS: Trying BSS-based ACS");
+
+    scan_res = hostapd_driver_get_scan_results(iface->bss[0]);
+    if (scan_res == NULL) {
+        wpa_printf(MSG_ERROR, "ACS: Scan request failed");
+        hostapd_setup_interface_complete(iface, 1);
+        return -1;
+    }
+
+    for (size_t j = 0; j < iface->current_mode->num_channels; j++) {
+        bss_on_ch = 0;
+        chan = &iface->current_mode->channels[j];
+        for (size_t i = 0; i < scan_res->num; i++) {
+            struct wpa_scan_res *bss = scan_res->res[i];
+            if (bss->freq == chan->freq)
+                bss_on_ch++;
+        }
+        wpa_printf(MSG_MSGDUMP, "ACS: Interference on ch %d (%d MHz): %d", chan->chan, chan->freq, bss_on_ch);
+        chan->interference_factor = bss_on_ch;
+        chan->interference_bss_based = 1;
+    }
+
+    wpa_scan_results_free(scan_res);
+    return 0;
+}
 
 static int acs_study_options(struct hostapd_iface *iface)
 {
     if (acs_study_survey_based(iface) == 0)
         return 0;
+    wpa_printf(MSG_WARNING, "ACS: survey based ACS failed");
 
-    /* TODO: If no surveys are available/sufficient this is a good
-    * place to fallback to BSS-based ACS */
+    if (acs_study_bss_based(iface) == 0)
+        return 0;
 
     return -1;
 }
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 566475214..2b714b8f5 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -159,6 +159,12 @@ struct hostapd_channel_data {
     * need to set this)
     */
     long double interference_factor;
+
+    /**
+    * interference_bss_based - Indicates that the interference was
+    * calculated from number of BSSes
+    */
+    int interference_bss_based;
 #endif /* CONFIG_ACS */
 
     /**
-- 
2.48.1



More information about the Hostap mailing list