Search Linux Wireless

[PATCH v2] wpa_supplicant: Add support for auto channel selection in AP mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If conf parameter 'auto_chan_select' is enabled for AP mode, send 
NL80211_ATTR_ACS attribute to cfg80211.
The new channel information is received from cfg80211 through
CH_SWITCH event.

Signed-hostap: Vivek Natarajan <nataraja@xxxxxxxxxxxxxxxx>
---
v2: Add a new flag attribute for _START_AP command to indicate ACS request.
    Update the channel/frequency information within hostapd/wpa_supplicant
    once the driver (firmware) has selected the channel.(This is addressed by
    Thomas' patch, 'nl80211: handle CH_SWITCH event')

 src/ap/ap_config.h           |    1 +
 src/ap/beacon.c              |    1 +
 src/ap/hw_features.c         |    2 +-
 src/drivers/driver.h         |    5 +++++
 src/drivers/driver_nl80211.c |    5 ++++-
 wpa_supplicant/ap.c          |   20 ++++++++++++++++----
 wpa_supplicant/config.c      |    1 +
 wpa_supplicant/config_ssid.h |    8 ++++++++
 8 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 78c9068..54759bb 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -407,6 +407,7 @@ struct hostapd_config {
 	int fragm_threshold;
 	u8 send_probe_response;
 	u8 channel;
+	int acs;
 	enum hostapd_hw_mode hw_mode; /* HOSTAPD_MODE_IEEE80211A, .. */
 	enum {
 		LONG_PREAMBLE = 0,
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index b711063..037f172 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -634,6 +634,7 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
 	params.dtim_period = hapd->conf->dtim_period;
 	params.beacon_int = hapd->iconf->beacon_int;
 	params.basic_rates = hapd->iconf->basic_rates;
+	params.auto_chan_select = hapd->iconf->acs;
 	params.ssid = (u8 *) hapd->conf->ssid.ssid;
 	params.ssid_len = hapd->conf->ssid.ssid_len;
 	params.pairwise_ciphers = hapd->conf->rsn_pairwise ?
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 76c4211..f33b7fd 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -715,7 +715,7 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
 			ok = 0;
 		}
 	}
-	if (iface->conf->channel == 0) {
+	if (iface->conf->channel == 0 && iface->conf->acs == 0) {
 		/* TODO: could request a scan of neighboring BSSes and select
 		 * the channel automatically */
 		wpa_printf(MSG_ERROR, "Channel not configured "
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index f7fb2ef..053ccd0 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -577,6 +577,11 @@ struct wpa_driver_ap_params {
 	int beacon_int;
 
 	/**
+	 * auto_chan_select - Automatic channel selection
+	 */
+	int auto_chan_select;
+
+	/**
 	 * basic_rates: -1 terminated array of basic rates in 100 kbps
 	 *
 	 * This parameter can be used to set a specific basic rate set for the
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 693a885..d4293fd 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5330,6 +5330,8 @@ static int wpa_driver_nl80211_set_ap(void *priv,
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
 	NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
 	NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
+	if (params->auto_chan_select)
+		NLA_PUT_FLAG(msg, NL80211_ATTR_ACS);
 	NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
 		params->ssid);
 	if (params->proberesp && params->proberesp_len)
@@ -6388,7 +6390,8 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
 		nlmode = NL80211_IFTYPE_AP;
 
 	if (wpa_driver_nl80211_set_mode(&drv->first_bss, nlmode) ||
-	    wpa_driver_nl80211_set_freq(&drv->first_bss, params->freq, 0, 0)) {
+	    ((params->freq) &&
+	    wpa_driver_nl80211_set_freq(&drv->first_bss, params->freq, 0, 0))) {
 		nl80211_remove_monitor_interface(drv);
 		return -1;
 	}
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index d531583..87bc9b8 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -52,10 +52,22 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
 
 	os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
 
-	if (ssid->frequency == 0) {
-		/* default channel 11 */
-		conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
-		conf->channel = 11;
+	if (ssid->auto_chan_select) {
+		if (ssid->frequency == 0)
+			wpa_printf(MSG_INFO, "Automatic channel "
+				   "selection is enabled");
+		else {
+			wpa_printf(MSG_INFO, "Automatic channel "
+				   "selection is enabled. Override "
+				   "frequency configuration");
+			ssid->frequency = 0;
+		}
+
+		conf->acs = ssid->auto_chan_select;
+	} else if (ssid->frequency == 0) {
+			/* default channel 11 */
+			conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
+			conf->channel = 8;
 	} else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) {
 		conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
 		conf->channel = (ssid->frequency - 2407) / 5;
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index ce763b3..7b85712 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1598,6 +1598,7 @@ static const struct parse_data ssid_fields[] = {
 	{ INT(wpa_ptk_rekey) },
 	{ STR(bgscan) },
 	{ INT_RANGE(ignore_broadcast_ssid, 0, 2) },
+	{ INT_RANGE(auto_chan_select, 0, 1) },
 #ifdef CONFIG_P2P
 	{ FUNC(p2p_client_list) },
 #endif /* CONFIG_P2P */
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 80d4382..88806fb 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -398,6 +398,14 @@ struct wpa_ssid {
 	int ignore_broadcast_ssid;
 
 	/**
+	 * auto_chan_select - Automatic channel selection in AP mode
+	 *
+	 * Optional parameter to enable channel selection by the driver if it
+	 * is capable of.
+	 */
+
+	int auto_chan_select;
+	/**
 	 * freq_list - Array of allowed frequencies or %NULL for all
 	 *
 	 * This is an optional zero-terminated array of frequencies in
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux