[RFC v2 1/4] hostapd: Split up channel checking into helpers
Michal Kazior
michal.kazior
Mon Jul 29 02:19:11 PDT 2013
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 at tieto.com>
---
src/ap/hostapd.h | 5 ++
src/ap/hw_features.c | 162 +++++++++++++++++++++++++++-----------------------
2 files changed, 94 insertions(+), 73 deletions(-)
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 75d9c66..c0b1306 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -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,
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 37112bd..424229b 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -634,6 +634,87 @@ 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 == iface->conf->channel) {
+ if (chan->flag & HOSTAPD_CHAN_DISABLED) {
+ wpa_printf(MSG_ERROR,
+ "%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" : "");
+ } else {
+ return 1;
+ }
+ }
+ }
+
+ 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;
+
+ if (!hostapd_is_usable_chan(iface, iface->conf->secondary_channel, 0))
+ return 0;
+
+ return 1;
+}
+
+
+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 +725,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 +750,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;
}
--
1.7.9.5
More information about the Hostap
mailing list