Patchwork [PATCHv2,3/3] hostap: add config option for dfs channels

login
register
mail settings
Submitter Jouni Malinen
Date May 9, 2013, 5:35 p.m.
Message ID <20130509173556.GB25904@w1.fi>
Download mbox | patch
Permalink /patch/242802/
State Changes Requested
Headers show

Comments

Jouni Malinen - May 9, 2013, 5:35 p.m.
On Mon, Mar 25, 2013 at 06:16:37PM +0100, Simon Wunderlich wrote:
> Different channels allow different transmission power, at least in ETSI
> countries. Also, ETSI requires a "channel plan" for DFS operation, and
> channels should be randomly choosen from these channels.
> 
> Add a channel list configuration option for users to add channels

I applied the hostapd_parse_rates() renaming part. The rest (see below)
look fine, but depend on the remaining parts of patch 2/3, so I could
not apply that yet.


 From a5f63549ff89825dd28f4ce210389b1715468d1c Mon Sep 17 00:00:00 2001
 From: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
 Date: Thu, 9 May 2013 20:26:52 +0300
 Subject: [PATCH 2/2] hostapd: Add config option for DFS channels

Different channels allow different transmission power at least in ETSI
countries. Also, ETSI requires a "channel plan" for DFS operation, and
channels should be randomly choosen from these channels.

Add a channel list configuration option for users to specify channels
hostapd may pick from.

Signed-hostap: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
---
 hostapd/config_file.c |    6 ++++++
 hostapd/hostapd.conf  |    7 +++++++
 src/ap/ap_config.c    |    1 +
 src/ap/ap_config.h    |    1 +
 src/ap/hostapd.c      |   20 ++++++++++++++++++++
 5 files changed, 35 insertions(+)

Patch

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 231b0f9..b3ed7d1 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2307,6 +2307,12 @@  static int hostapd_config_fill(struct hostapd_config *conf,
 			}
 		} else if (os_strcmp(buf, "channel") == 0) {
 			conf->channel = atoi(pos);
+		} else if (os_strcmp(buf, "dfs_chanlist") == 0) {
+			if (hostapd_parse_intlist(&conf->dfs_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
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index be15b86..590097d 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -123,6 +123,13 @@  hw_mode=g
 # channel will need to be configured separately with iwconfig.
 channel=1
 
+# Allowed DFS Channels
+# This option allows hostapd to select one of the provided DFS channels when the
+# current channel becomes unavailable due to radar interference. Only useful
+# when ieee80211h=1 is set.
+# Default: not set (any DFS channel can be used, if no radar is found)
+#dfs_chanlist=100 104 108 112 116
+
 # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
 beacon_int=100
 
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 7ab86fc..68c80e0 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -550,6 +550,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->dfs_chanlist);
 
 	os_free(conf);
 }
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 7c9ea90..0908312 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -475,6 +475,7 @@  struct hostapd_config {
 	int fragm_threshold;
 	u8 send_probe_response;
 	u8 channel;
+	int *dfs_chanlist;
 	enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
 	enum {
 		LONG_PREAMBLE = 0,
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 021fbc4..5ab9b7c 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1457,6 +1457,23 @@  void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
 }
 
 
+static int hostapd_is_in_dfs_chanlist(struct hostapd_data *hapd,
+				      struct hostapd_channel_data *chan)
+{
+	int *chan_entry;
+
+	if (!hapd->iface->conf->dfs_chanlist)
+		return 1;
+
+	for (chan_entry = hapd->iface->conf->dfs_chanlist; *chan_entry != -1;
+	     chan_entry++) {
+		if (*chan_entry == chan->chan)
+			return 1;
+	}
+	return 0;
+}
+
+
 /*
  * if ret_chan == NULL: returns the number of channels with this dfs state
  * if ret_chan != NULL: return channel at the supplied position.
@@ -1481,6 +1498,9 @@  static int hostapd_dfs_find_channel(struct hostapd_data *hapd, u32 state,
 		    ((chan->flag & HOSTAPD_CHAN_DFS_MASK) != state))
 			continue;
 
+		if (!hostapd_is_in_dfs_chanlist(hapd, chan))
+			continue;
+
 		if (ret_chan && idx == channel_idx) {
 			wpa_printf(MSG_DEBUG, "Selected ch. #%d", chan->chan);
 			*ret_chan = chan;