NOTE: this page is for archival only, see the note at the end of the page.

ACS (Automatic Channel Selection)

Automatic Channel Selection algorithms and implementations are used to enable interfaces to automatically figure out which channel configuration to use for initiating communication, for any mode of operation which initiates radiation (AP, Mesh, IBSS, P2P).

There are different algorithms that can be used to finding an ideal channel. We currently only have one, described below.

ACS code

All algorithms can be dumped into a generic permissively licensed userspace application which can then be used for integration into differente projects. The code is hosted at:

You can send patches To: and Cc:

Survey based algorithm

The survey based algorithm relies on the nl80211 survey API command to query the interface for channel active time, channel busy time, channel tx time and noise. The active time consists of the amount of time the radio has spent on the channel. The busy time consists of the amount of time the channel has spent on the channel but noticed the channel was busy and could not initiate communication if it wanted to. The tx time is the amount of time the channel has spent on the channel transmitting data. The survey algorithm relies on these values to build an interference factor to give a sense of how much interference was detected on the channel and then picks the channel with the lowest interference factor.

The interference factor is defined as the ratio of the observed busy time over the time we spent on the channel, this value is then amplified by the noise floor observed on the channel in comparison to the lowest noise floor observed on the entire band.

This corresponds to:

(busy time - tx time) / (active time - tx time) * 2^(chan_nf - band_min_nf)

The coefficient of of 2 reflects the way power in "far-field" radiation decreases as the square of distance from the antenna What this does is it decreases the observed busy time ratio if the noise observed was low but increases it if the noise was high, proportionally to the way "far field" radiation changes over distance. Using a minimum noise instead of some "known low noise" value allows this code to be agnostic to any card used, even if the card is yielding incorrect values for noise floor. The minimum noise floor would be the lowest recorded noise floor from all surveyed channels. It is worth showing a few examples of what the multiplier produces to demonstrate how it amplifies the value for high noise. Since we have recorded the lowest observed noise floor by using the delta between what we observed and the lowest observed noise floor on the band we would get multipliers that are always positive and the lowest multiplier would be a value of 1 given that 2^0 = 1. Lets assume the lowest recorded noise floor was -110 dBm here are a few example values:

mcgrof@tux ~ $ calc
C-style arbitrary precision calculator (version
Calc is open software. For license details type:  help copyright
[Type "exit" to exit, or "help" for help.]

; define f(x) = 2^(x - -110)
f(x) defined
; f(-110)
; f(-109)
; f(-108)

The right hand value of the formula then can be thought of as the amplifier of the observed 'business'.

Since the values obtained here can vary from fractional to millions the sane thing to do here is to use log2() to reflect the observed interference factor. log2() values less than 0 then represent fractional results, while > 1 values non-fractional results. The computation of the interference factor then becomes:

log2( (busy time - tx time) / (active time - tx time) * 2^(chan_nf - band_min_nf))

--- or due to logarithm identities ---

log2(busy time - tx time) - log2(active time - tx time) + log2(2^(chan_nf - band_min_nf))

-- and since log2(2^x) = x --

log2(busy time - tx time) - log2(active time - tx time) + chan_nf - band_min_nf

This "interference factor" is purely subjective and ony time will tell how usable this is. By using the minimum noise floor we remove any possible issues due to card calibration. The computation of the interference factor then is dependent on what the card itself picks up as the minimum noise, not an actual real possible card noise value.

Example output:

2412 MHz: 7.429173
2417 MHz: 10.460830
2422 MHz: 12.671070
2427 MHz: 13.583892
2432 MHz: 13.405357
2442 MHz: 13.566887
2447 MHz: 15.630824
2452 MHz: 14.639748
2457 MHz: 14.139193
2467 MHz: 11.914643
2472 MHz: 16.996074
2484 MHz: 15.175455
5180 MHz: -0.218548
5200 MHz: -2.204059
5220 MHz: -1.762898
5240 MHz: -1.314665
5260 MHz: -3.100989
5280 MHz: -2.157037
5300 MHz: -1.842629
5320 MHz: -1.498928
5500 MHz: 3.304770
5520 MHz: 2.345992
5540 MHz: 2.749775
5560 MHz: 2.390887
5580 MHz: 2.592958
5600 MHz: 2.420149
5620 MHz: 2.650282
5640 MHz: 2.954027
5660 MHz: 2.991007
5680 MHz: 2.955472
5700 MHz: 2.280499
5745 MHz: 2.388630
5765 MHz: 2.332542
5785 MHz: 0.955708
5805 MHz: 1.025377
5825 MHz: 0.843392
Ideal freq: 5260 MHz


Initial implementation is now complete, ACS hostapd RFC patches have been posted.


This is a static dump of the wiki, taken after locking it in January 2015. The new wiki is at
versions of this page: last, v13, v12, v11, v10, v9, v8, v7, v6, v5, v4, v3, v2, v1