hostapd: Split up channel checking into helpers

This splits up the channel checking upon initialization into a few
helpers. This should make this a bit easier to follow. This also paves
the way for some initial ACS entry code.

Signed-hostap: Michal Kazior <michal.kazior@tieto.com>
This commit is contained in:
Michal Kazior 2013-07-18 09:17:06 +02:00 committed by Jouni Malinen
parent ba873bdf86
commit 245e026ec8
2 changed files with 88 additions and 73 deletions

View file

@ -47,6 +47,11 @@ struct hapd_interfaces {
struct hostapd_dynamic_iface **dynamic_iface;
};
enum hostapd_chan_status {
HOSTAPD_CHAN_VALID = 0, /* channel is ready */
HOSTAPD_CHAN_INVALID = 1, /* no usable channel found */
HOSTAPD_CHAN_ACS = 2, /* ACS work being performed */
};
struct hostapd_probereq_cb {
int (*cb)(void *ctx, const u8 *sa, const u8 *da, const u8 *bssid,

View file

@ -634,6 +634,81 @@ int hostapd_check_ht_capab(struct hostapd_iface *iface)
}
static int hostapd_is_usable_chan(struct hostapd_iface *iface,
int channel, int primary)
{
int i;
struct hostapd_channel_data *chan;
for (i = 0; i < iface->current_mode->num_channels; i++) {
chan = &iface->current_mode->channels[i];
if (chan->chan != channel)
continue;
if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
return 1;
wpa_printf(MSG_DEBUG,
"%schannel [%i] (%i) is disabled for use in AP mode, flags: 0x%x%s%s%s",
primary ? "" : "Configured HT40 secondary ",
i, chan->chan, chan->flag,
chan->flag & HOSTAPD_CHAN_NO_IBSS ? " NO-IBSS" : "",
chan->flag & HOSTAPD_CHAN_PASSIVE_SCAN ?
" PASSIVE-SCAN" : "",
chan->flag & HOSTAPD_CHAN_RADAR ? " RADAR" : "");
}
return 0;
}
static int hostapd_is_usable_chans(struct hostapd_iface *iface)
{
if (!hostapd_is_usable_chan(iface, iface->conf->channel, 1))
return 0;
if (!iface->conf->secondary_channel)
return 1;
return hostapd_is_usable_chan(iface, iface->conf->channel +
iface->conf->secondary_channel * 4, 0);
}
static enum hostapd_chan_status
hostapd_check_chans(struct hostapd_iface *iface)
{
if (iface->conf->channel) {
if (hostapd_is_usable_chans(iface))
return HOSTAPD_CHAN_VALID;
else
return HOSTAPD_CHAN_INVALID;
}
/*
* The user set channel=0 which is used to trigger ACS,
* which we do not yet support.
*/
return HOSTAPD_CHAN_INVALID;
}
static void hostapd_notify_bad_chans(struct hostapd_iface *iface)
{
hostapd_logger(iface->bss[0], NULL,
HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING,
"Configured channel (%d) not found from the "
"channel list of current mode (%d) %s",
iface->conf->channel,
iface->current_mode->mode,
hostapd_hw_mode_txt(iface->current_mode->mode));
hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING,
"Hardware does not support configured channel");
}
/**
* hostapd_select_hw_mode - Select the hardware mode
* @iface: Pointer to interface data.
@ -644,7 +719,7 @@ int hostapd_check_ht_capab(struct hostapd_iface *iface)
*/
int hostapd_select_hw_mode(struct hostapd_iface *iface)
{
int i, j, ok;
int i;
if (iface->num_hw_features < 1)
return -1;
@ -669,80 +744,15 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
return -2;
}
ok = 0;
for (j = 0; j < iface->current_mode->num_channels; j++) {
struct hostapd_channel_data *chan =
&iface->current_mode->channels[j];
if (chan->chan == iface->conf->channel) {
if (chan->flag & HOSTAPD_CHAN_DISABLED) {
wpa_printf(MSG_ERROR,
"channel [%i] (%i) is disabled for "
"use in AP mode, flags: 0x%x%s%s%s",
j, chan->chan, chan->flag,
chan->flag & HOSTAPD_CHAN_NO_IBSS ?
" NO-IBSS" : "",
chan->flag &
HOSTAPD_CHAN_PASSIVE_SCAN ?
" PASSIVE-SCAN" : "",
chan->flag & HOSTAPD_CHAN_RADAR ?
" RADAR" : "");
} else {
ok = 1;
break;
}
}
}
if (ok && iface->conf->secondary_channel) {
int sec_ok = 0;
int sec_chan = iface->conf->channel +
iface->conf->secondary_channel * 4;
for (j = 0; j < iface->current_mode->num_channels; j++) {
struct hostapd_channel_data *chan =
&iface->current_mode->channels[j];
if (!(chan->flag & HOSTAPD_CHAN_DISABLED) &&
(chan->chan == sec_chan)) {
sec_ok = 1;
break;
}
}
if (!sec_ok) {
hostapd_logger(iface->bss[0], NULL,
HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING,
"Configured HT40 secondary channel "
"(%d) not found from the channel list "
"of current mode (%d) %s",
sec_chan, iface->current_mode->mode,
hostapd_hw_mode_txt(
iface->current_mode->mode));
ok = 0;
}
}
if (iface->conf->channel == 0) {
/* TODO: could request a scan of neighboring BSSes and select
* the channel automatically */
wpa_printf(MSG_ERROR, "Channel not configured "
"(hw_mode/channel in hostapd.conf)");
switch (hostapd_check_chans(iface)) {
case HOSTAPD_CHAN_VALID:
return 0;
case HOSTAPD_CHAN_ACS: /* ACS not supported yet */
case HOSTAPD_CHAN_INVALID:
default:
hostapd_notify_bad_chans(iface);
return -3;
}
if (ok == 0 && iface->conf->channel != 0) {
hostapd_logger(iface->bss[0], NULL,
HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING,
"Configured channel (%d) not found from the "
"channel list of current mode (%d) %s",
iface->conf->channel,
iface->current_mode->mode,
hostapd_hw_mode_txt(iface->current_mode->mode));
iface->current_mode = NULL;
}
if (iface->current_mode == NULL) {
hostapd_logger(iface->bss[0], NULL, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_WARNING,
"Hardware does not support configured channel");
return -4;
}
return 0;
}