@@ -470,7 +470,7 @@ static struct hostapd_channel_data *acs_find_chan(struct hostapd_iface *iface,
for (i = 0; i < iface->current_mode->num_channels; i++) {
chan = &iface->current_mode->channels[i];
- if (!acs_usable_chan(chan))
+ if (chan->flag & HOSTAPD_CHAN_DISABLED)
continue;
if (chan->freq == freq)
@@ -490,7 +490,7 @@ static struct hostapd_channel_data *acs_find_chan(struct hostapd_iface *iface,
static struct hostapd_channel_data *
acs_find_ideal_chan(struct hostapd_iface *iface)
{
- struct hostapd_channel_data *chan, *adj_chan, *ideal_chan = NULL;
+ struct hostapd_channel_data *chan, *adj_chan, *ideal_chan = NULL, *rand_chan = NULL;
long double factor, ideal_factor = 0;
int i, j;
int n_chans = 1;
@@ -522,9 +522,10 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
for (i = 0; i < iface->current_mode->num_channels; i++) {
chan = &iface->current_mode->channels[i];
- if (!acs_usable_chan(chan))
+ if (chan->flag & HOSTAPD_CHAN_DISABLED)
continue;
+
/* HT40 on 5 GHz has a limited set of primary channels as per
* 11n Annex J */
if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
@@ -536,14 +537,17 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
continue;
}
- factor = chan->interference_factor;
+ factor = 0;
+ if (acs_usable_chan(chan))
+ factor = chan->interference_factor;
for (j = 1; j < n_chans; j++) {
adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
if (!adj_chan)
break;
- factor += adj_chan->interference_factor;
+ if (acs_usable_chan(adj_chan))
+ factor += adj_chan->interference_factor;
}
if (j != n_chans) {
@@ -562,22 +566,22 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
adj_chan = acs_find_chan(iface, chan->freq +
(j * 20) - 5);
- if (adj_chan)
+ if (adj_chan && acs_usable_chan(adj_chan))
factor += adj_chan->interference_factor;
adj_chan = acs_find_chan(iface, chan->freq +
(j * 20) - 10);
- if (adj_chan)
+ if (adj_chan && acs_usable_chan(adj_chan))
factor += adj_chan->interference_factor;
adj_chan = acs_find_chan(iface, chan->freq +
(j * 20) + 5);
- if (adj_chan)
+ if (adj_chan && acs_usable_chan(adj_chan))
factor += adj_chan->interference_factor;
adj_chan = acs_find_chan(iface, chan->freq +
(j * 20) + 10);
- if (adj_chan)
+ if (adj_chan && acs_usable_chan(adj_chan))
factor += adj_chan->interference_factor;
}
}
@@ -585,17 +589,25 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
wpa_printf(MSG_DEBUG, "ACS: * channel %d: total interference = %Lg",
chan->chan, factor);
- if (!ideal_chan || factor < ideal_factor) {
- ideal_factor = factor;
- ideal_chan = chan;
+ if (acs_usable_chan(chan)) {
+ if (!ideal_chan || factor < ideal_factor) {
+ ideal_factor = factor;
+ ideal_chan = chan;
+ }
}
+
+ /* This channel would at least be usable */
+ if (!rand_chan)
+ rand_chan = chan;
}
- if (ideal_chan)
+ if (ideal_chan) {
wpa_printf(MSG_DEBUG, "ACS: Ideal channel is %d (%d MHz) with total interference factor of %Lg",
ideal_chan->chan, ideal_chan->freq, ideal_factor);
+ return ideal_chan;
+ }
- return ideal_chan;
+ return rand_chan;
}
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com> --- src/ap/acs.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-)