@@ -2235,6 +2235,12 @@ static int hostapd_config_fill(struct hostapd_config *conf,
conf->channel = 0;
} else
conf->channel = atoi(pos);
+ } else if (os_strcmp(buf, "chanlist") == 0) {
+ if (hostapd_parse_intlist(&conf->chanlist, pos)) {
+ wpa_printf(MSG_ERROR, "Line %d: invalid channel "
+ "list", line);
+ errors++;
+ }
} else if (os_strcmp(buf, "beacon_int") == 0) {
int val = atoi(pos);
/* MIB defines range as 1..65535, but very small values
@@ -140,6 +140,14 @@ channel=1
# Defaults:
#acs_num_scans=5
+# Channel list restriction. This option allows hostapd to select one of the
+# provided channels when a channel should be automatically selected. This
+# is currently only used for DFS when the current channels becomes unavailable
+# due to radar interference, and is currently only useful when ieee80211h=1 is
+# set.
+# Default: not set
+#chanlist=100 104 108 112 116
+
# Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
beacon_int=100
@@ -554,6 +554,7 @@ void hostapd_config_free(struct hostapd_config *conf)
os_free(conf->bss);
os_free(conf->supported_rates);
os_free(conf->basic_rates);
+ os_free(conf->chanlist);
os_free(conf);
}
@@ -493,6 +493,7 @@ struct hostapd_config {
int fragm_threshold;
u8 send_probe_response;
u8 channel;
+ int *chanlist;
enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
enum {
LONG_PREAMBLE = 0,
@@ -130,6 +130,24 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
}
+static int is_in_chanlist(struct hostapd_iface *iface,
+ struct hostapd_channel_data *chan)
+{
+ int *chan_entry;
+
+ if (!iface->conf->chanlist)
+ return 1;
+
+ for (chan_entry = iface->conf->chanlist;
+ *chan_entry != -1;
+ chan_entry++) {
+ if (*chan_entry == chan->chan)
+ return 1;
+ }
+ return 0;
+}
+
+
/*
* The function assumes HT40+ operation.
* Make sure to adjust the following variables after calling this:
@@ -162,6 +180,9 @@ static int dfs_find_channel(struct hostapd_iface *iface,
if (!dfs_chan_range_available(mode, i, n_chans, skip_radar))
continue;
+ if (!is_in_chanlist(iface, chan))
+ continue;
+
if (ret_chan && idx == channel_idx) {
wpa_printf(MSG_DEBUG, "Selected ch. #%d", chan->chan);
*ret_chan = chan;