Cumulative patch from commit b2b688d18d40cd667d0faa149b4a7172166b3bd4

b2b688d P2P: Fix crash when failed to create GO interface
6197169 WPS NFC: Fix build without CONFIG_AP=y
e1ae5d7 SAE: Fix build without CONFIG_AP=y
813e7b3 P2P: Remove group from timeout on PSK failure
5bf9a6c P2P: Add event messages for possible PSK failures on P2P groups
eac8dab P2P: Document per-client keys and p2p_remove_client
43c693c P2P: Do not store duplicate PSK entries for the same device
f2c5660 P2P: Add a command for removing a client from all groups
01a57fe P2P: Maintain list of per-client PSKs for persistent groups
759fd76 P2P: Select PSK based on Device Address instead of Interface Address
94ddef3 P2P: Make peer's P2P Device Address available to authenticator
52177fb P2P: Store P2P Device Address in per-device PSK records
05766ed P2P: Allow per-device PSK to be assigned
698e921 wpa_cli: Add tab completion for p2p_set field values
0b5fb86 P2P: Stop listen state when listen-only duration is over
02a3e5c wpa_cli: Allow first DISCONNECTED event to be reported
cdf8bfa Disallow WEP configuration in WPA network
731ef43 D-Bus: Fix per-iface object unregistration on not existing objects
447969e D-Bus: Do not send network notification for all P2P groups
eb32460 Fix switching from EAP-SIM to EAP-AKA/AKA'
f2b3f4d P2P: Allow P2P functionality to be disabled per interface
50f4f2a hostapd: Add Automatic Channel Selection (ACS) support
43ee470 P2P: Immediate group removal in GC in case of deauthentication
fcf2052 Fix MNC length for Swisscom SIM cards

Bug: 10606228, 10513949

Change-Id: I63ba0e2ab4fa76e6afa7a34be42e8e847e1511b0
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index 1054dc0..695e99c 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -884,6 +884,12 @@
 OBJS_c += src/utils/edit_simple.c
 endif
 
+ifdef CONFIG_ACS
+L_CFLAGS += -DCONFIG_ACS
+OBJS += src/ap/acs.c
+LIBS += -lm
+endif
+
 ########################
 
 include $(CLEAR_VARS)
diff --git a/hostapd/Makefile b/hostapd/Makefile
index a30a244..fda4e4e 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -817,6 +817,12 @@
 OBJS_c += ../src/utils/edit_simple.o
 endif
 
+ifdef CONFIG_ACS
+CFLAGS += -DCONFIG_ACS
+OBJS += ../src/ap/acs.o
+LIBS += -lm
+endif
+
 ifdef CONFIG_NO_STDOUT_DEBUG
 CFLAGS += -DCONFIG_NO_STDOUT_DEBUG
 endif
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index e9d324f..0b4fd77 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -1104,6 +1104,24 @@
 		return -1;
 	}
 
+	if (bss->wpa) {
+		int wep, i;
+
+		wep = bss->default_wep_key_len > 0 ||
+		       bss->individual_wep_key_len > 0;
+		for (i = 0; i < NUM_WEP_KEYS; i++) {
+			if (bss->ssid.wep.keys_set) {
+				wep = 1;
+				break;
+			}
+		}
+
+		if (wep) {
+			wpa_printf(MSG_ERROR, "WEP configuration in a WPA network is not supported");
+			return -1;
+		}
+	}
+
 	if (bss->wpa && bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
 	    bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
 		wpa_printf(MSG_ERROR, "WPA-PSK using RADIUS enabled, but no "
@@ -2311,7 +2329,15 @@
 				errors++;
 			}
 		} else if (os_strcmp(buf, "channel") == 0) {
-			conf->channel = atoi(pos);
+			if (os_strcmp(pos, "acs_survey") == 0) {
+#ifndef CONFIG_ACS
+				wpa_printf(MSG_ERROR, "Line %d: tries to enable ACS but CONFIG_ACS disabled",
+					   line);
+				errors++;
+#endif /* CONFIG_ACS */
+				conf->channel = 0;
+			} else
+				conf->channel = atoi(pos);
 		} else if (os_strcmp(buf, "beacon_int") == 0) {
 			int val = atoi(pos);
 			/* MIB defines range as 1..65535, but very small values
@@ -2326,6 +2352,16 @@
 				errors++;
 			} else
 				conf->beacon_int = val;
+#ifdef CONFIG_ACS
+		} else if (os_strcmp(buf, "acs_num_scans") == 0) {
+			int val = atoi(pos);
+			if (val <= 0 || val > 100) {
+				wpa_printf(MSG_ERROR, "Line %d: invalid acs_num_scans %d (expected 1..100)",
+					   line, val);
+				errors++;
+			} else
+				conf->acs_num_scans = val;
+#endif /* CONFIG_ACS */
 		} else if (os_strcmp(buf, "dtim_period") == 0) {
 			bss->dtim_period = atoi(pos);
 			if (bss->dtim_period < 1 || bss->dtim_period > 255) {
diff --git a/hostapd/defconfig b/hostapd/defconfig
index c288f46..2dd6fc8 100644
--- a/hostapd/defconfig
+++ b/hostapd/defconfig
@@ -278,3 +278,27 @@
 # certain percentage of probe requests or auth/(re)assoc frames.
 #
 #CONFIG_TESTING_OPTIONS=y
+
+# Automatic Channel Selection
+# This will allow hostapd to pick the channel automatically when channel is set
+# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in
+# similar way.
+#
+# Automatic selection is currently only done through initialization, later on
+# we hope to do background checks to keep us moving to more ideal channels as
+# time goes by. ACS is currently only supported through the nl80211 driver and
+# your driver must have survey dump capability that is filled by the driver
+# during scanning.
+#
+# You can customize the ACS survey algorithm with the hostapd.conf variable
+# acs_num_scans.
+#
+# Supported ACS drivers:
+# * ath9k
+# * ath5k
+# * ath10k
+#
+# For more details refer to:
+# http://wireless.kernel.org/en/users/Documentation/acs
+#
+#CONFIG_ACS=y
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index c46dff5..45897ed 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -121,8 +121,28 @@
 # (default: 0, i.e., not set)
 # Please note that some drivers do not use this value from hostapd and the
 # channel will need to be configured separately with iwconfig.
+#
+# If CONFIG_ACS build option is enabled, the channel can be selected
+# automatically at run time by setting channel=acs_survey or channel=0, both of
+# which will enable the ACS survey based algorithm.
 channel=1
 
+# ACS tuning - Automatic Channel Selection
+# See: http://wireless.kernel.org/en/users/Documentation/acs
+#
+# You can customize the ACS survey algorithm with following variables:
+#
+# acs_num_scans requirement is 1..100 - number of scans to be performed that
+# are used to trigger survey data gathering of an underlying device driver.
+# Scans are passive and typically take a little over 100ms (depending on the
+# driver) on each available channel for given hw_mode. Increasing this value
+# means sacrificing startup time and gathering more data wrt channel
+# interference that may help choosing a better channel. This can also help fine
+# tune the ACS scan time in case a driver has different scan dwell times.
+#
+# Defaults:
+#acs_num_scans=5
+
 # Beacon interval in kus (1.024 ms) (default: 100; range 15..65535)
 beacon_int=100