summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorVamsi Krishna <quic_vamsin@quicinc.com>2019-12-13 11:02:27 +0530
committerSunil Ravi <sunilravi@google.com>2020-02-20 15:04:34 -0800
commit853857e57a4595ab67345fc8a198bb7b06e2aa0b (patch)
tree1d59c3027896e72544118862253cd3d1f3a6136f /tests
parent40369495ec8f3fc06f655d3dd2ab07ae4844c130 (diff)
STA: Add support to connect to FILS enabled APs
Fast Initial Link Setup (FILS) feature defined in 802.11ai specifications provides means to make faster reconnections with APs within a realm using EAP-Reauthentication Protocol (ERP). When a STA connecting initially to an enterprise AP on which FILS is enabled, does full 802.1x EAP handshakes and generates ERP keys. The STA uses the ERP keys (until they are expired) in subsequent connections to the enterprise APs within same realm as that of the AP with which the STA has generated ERP keys to EAP-ERP process to make connection faster. The EAP-ERP request and EAP-ERP response frames will be exchanged via 802.11 authentication frames between STA and AP. More details of EAP-ERP can be found at https://tools.ietf.org/html/rfc6696 FILS specifications defines two AKM suites FILS-SHA256 and FILS-SHA384 for normal connection and two more AKM suites FILS-FT-SHA256 and FILS-FT-SHA384 for FT connections. The first connection without using ERP keys uses open auth algorithm and connects using full eap handshake and the subsequent connections with ERP keys uses FILS auth algorithm. DHCP with rapid commit optimizes the DHCP packet exchange. When using rapid commit feature, DHCP server responds with DHCP ACK packet when it receives DHCP discover packet. More details of DHCP with rapid commit can be found at https://tools.ietf.org/html/rfc4039. The DHCP discover and DHCP ACK packets can be sent with Association request frame and Association response frame using HLP feature defined in FILS protocol in order to get the IP address quickly. When connecting to a FILS AP, start the DHCP client withPreConnection option set to true before sending connect request to wpa_supplicant. DHCP client will form discover packet and sends it to Wi-Fi module, then the DHCP client moves to listen state to be able to receive and process DHCP ACK or DHCP Offer packets. After receiving DHCP discover packet from DHCP client, configure DHCP discover packet as HLP packet to wpa_supplicant and then issue connect request to wpa_supplicant with appropriate FILS AKM suite. The ERP config option also needs to be enabled so that wpa_supplicant generates ERP keys while connecting to FILS APs. If the STA is already connected to a different AP when wpa_supplicant receives the connect request to the FILS AP, wpa_supplicant disconnects with that AP before connecting to FILS AP and sends a disconnection event to frameworks. Do not stop IpClient when disconnection event is received if FILS connection is in progress, as the IpClient is started for ongoing FILS connection. If STA does not have ERP keys required for FILS connection or if the AP is rejecting the connection in FILS mode probably because of AP not having ERP keys, then STA will connect to FILS AP with open auth algorithm using full 802.1x EAP handshake. In these cases wpa_supplicant doesn't include HLP IEs in connect request. Wpa_supplicant notifies framework through connection event whether it sent HLP IEs to AP or not in the connection request. When HLP IEs are not sent in association request frame, abort pre-DHCP connection. When pre-DHCP connection is aborted, DHCP client transitions to dhcpInit state and sends DHCP discover packet to AP through data path. If STA has ERP keys, it will send the DHCP discover packet using HLP IEs in Association Request frame. AP may respond in three ways. 1. AP may not send any DHCP packet uisng HLP IEs in Association Response frame if the DHCP server doesn't send response within a time less than 802.11 mgmt. timeout. In this case, AP sends the DHCP packet as a data packet after sending out Association Response frame. 2. AP may send a DHCP ACK packet using HLP IEs in Association Response frame if the DHCP server supports DHCP with Rapid Commit feature and sends response within a time less than 802.11 mgmt. timeout. 3. AP may send a DHCP OFFER packet using HLP IEs in Association Response frame if the DHCP server doesn't support DHCP with Rapid Commit feature and sends response within a time less than 802.11 mgmt. timeout. Bug: 143259898 Test: atest. Test: Basic wifi sanity. Change-Id: Ib42eb5295fa2403d5a98ceddb15f501c130b61e5
Diffstat (limited to 'tests')
-rw-r--r--tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java220
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java235
-rw-r--r--tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java40
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java19
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java29
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java82
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java40
7 files changed, 654 insertions, 11 deletions
diff --git a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
index c11f82fc6..d45f68f50 100644
--- a/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/ClientModeImplTest.java
@@ -60,6 +60,7 @@ import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
import android.net.ConnectivityManager;
import android.net.DhcpResultsParcelable;
import android.net.InetAddresses;
+import android.net.Layer2PacketParcelable;
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.MacAddress;
@@ -150,6 +151,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
+import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
@@ -341,6 +343,7 @@ public class ClientModeImplTest extends WifiBaseTest {
static final int sFreq = 2437;
static final int sFreq1 = 5240;
static final String WIFI_IFACE_NAME = "mockWlan";
+ static final String sFilsSsid = "FILS-AP";
ClientModeImpl mCmi;
HandlerThread mWifiCoreThread;
@@ -2688,10 +2691,9 @@ public class ClientModeImplTest extends WifiBaseTest {
when(mWifiNative.getMacAddress(WIFI_IFACE_NAME))
.thenReturn(TEST_LOCAL_MAC_ADDRESS.toString());
- WifiConfiguration config = mock(WifiConfiguration.class);
+ WifiConfiguration config = new WifiConfiguration();
config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
- when(config.getNetworkSelectionStatus())
- .thenReturn(new WifiConfiguration.NetworkSelectionStatus());
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config);
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
@@ -2718,10 +2720,9 @@ public class ClientModeImplTest extends WifiBaseTest {
assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest());
assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState());
- WifiConfiguration config = mock(WifiConfiguration.class);
+ WifiConfiguration config = new WifiConfiguration();
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_NONE;
- when(config.getNetworkSelectionStatus())
- .thenReturn(new WifiConfiguration.NetworkSelectionStatus());
when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config);
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
@@ -2765,11 +2766,10 @@ public class ClientModeImplTest extends WifiBaseTest {
assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest());
assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState());
- WifiConfiguration config = mock(WifiConfiguration.class);
+ WifiConfiguration config = new WifiConfiguration();
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
config.setRandomizedMacAddress(MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS));
- when(config.getNetworkSelectionStatus())
- .thenReturn(new WifiConfiguration.NetworkSelectionStatus());
when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(0)).thenReturn(config);
mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
@@ -3203,7 +3203,7 @@ public class ClientModeImplTest extends WifiBaseTest {
disconnect();
mLooper.dispatchAll();
- verify(mWifiScoreCard).resetConnectionState();
+ verify(mWifiScoreCard, times(1)).resetConnectionState();
verify(mWifiScoreCard, never()).noteWifiDisabled(any());
verify(mWifiHealthMonitor, never()).setWifiEnabled(false);
@@ -3211,7 +3211,7 @@ public class ClientModeImplTest extends WifiBaseTest {
mCmi.setWifiStateForApiCalls(WifiManager.WIFI_STATE_DISABLED);
mCmi.setOperationalMode(ClientModeImpl.DISABLED_MODE, null);
mLooper.dispatchAll();
- verify(mWifiScoreCard).resetConnectionState();
+ verify(mWifiScoreCard, times(2)).resetConnectionState();
verify(mWifiHealthMonitor).setWifiEnabled(false);
}
@@ -4509,4 +4509,202 @@ public class ClientModeImplTest extends WifiBaseTest {
assertTrue(mCmi.isWifiBandSupported(WifiScanner.WIFI_BAND_6_GHZ));
verify(mWifiNative).getChannelsForBand(WifiScanner.WIFI_BAND_6_GHZ);
}
+
+ /**
+ * Helper function for setting up fils test.
+ *
+ * @param isDriverSupportFils true if driver support fils.
+ * @return wifi configuration.
+ */
+ private WifiConfiguration setupFilsTest(boolean isDriverSupportFils) {
+ assertEquals(ClientModeImpl.CONNECT_MODE, mCmi.getOperationalModeForTest());
+ assertEquals(WifiManager.WIFI_STATE_ENABLED, mCmi.syncGetWifiState());
+
+ WifiConfiguration config = new WifiConfiguration();
+ config.setSecurityParams(WifiConfiguration.SECURITY_TYPE_EAP);
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+ config.SSID = ScanResultUtil.createQuotedSSID(sFilsSsid);
+ config.networkId = 1;
+ config.setRandomizedMacAddress(TEST_LOCAL_MAC_ADDRESS);
+ config.macRandomizationSetting = WifiConfiguration.RANDOMIZATION_PERSISTENT;
+
+ when(mWifiConfigManager.getConfiguredNetworkWithoutMasking(anyInt())).thenReturn(config);
+ if (isDriverSupportFils) {
+ when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn(
+ WifiManager.WIFI_FEATURE_FILS_SHA256 | WifiManager.WIFI_FEATURE_FILS_SHA384);
+ } else {
+ when(mWifiNative.getSupportedFeatureSet(WIFI_IFACE_NAME)).thenReturn((long) 0);
+ }
+
+ return config;
+ }
+
+ /**
+ * Helper function for setting up a scan result with FILS supported AP.
+ *
+ */
+ private void setupFilsEnabledApInScanResult() {
+ String caps = "[WPA2-EAP+EAP-SHA256+FILS-SHA256-CCMP]"
+ + "[RSN-EAP+EAP-SHA256+FILS-SHA256-CCMP][ESS]";
+ ScanResult scanResult = new ScanResult(WifiSsid.createFromAsciiEncoded(sFilsSsid),
+ sFilsSsid, sBSSID, 1245, 0, caps, -78, 2412, 1025, 22, 33, 20, 0, 0, true);
+ ScanResult.InformationElement ie = createIE(ScanResult.InformationElement.EID_SSID,
+ sFilsSsid.getBytes(StandardCharsets.UTF_8));
+ scanResult.informationElements = new ScanResult.InformationElement[]{ie};
+ List<ScanResult> scanResults = new ArrayList<>();
+ scanResults.add(scanResult);
+
+ when(mScanRequestProxy.getScanResults()).thenReturn(scanResults);
+ }
+
+
+ /**
+ * Helper function to send CMD_START_FILS_CONNECTION along with HLP IEs.
+ *
+ */
+ private void prepareFilsHlpPktAndSendStartConnect() {
+ Layer2PacketParcelable l2Packet = new Layer2PacketParcelable();
+ l2Packet.dstMacAddress = TEST_GLOBAL_MAC_ADDRESS;
+ l2Packet.payload = new byte[] {0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13,
+ 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x00, 0x12, 0x13, 0x55, 0x66};
+ mCmi.sendMessage(ClientModeImpl.CMD_START_FILS_CONNECTION, 0, 0,
+ Collections.singletonList(l2Packet));
+ mLooper.dispatchAll();
+ }
+
+ /**
+ * Verifies that while connecting to AP, the logic looks into the scan result and
+ * looks for AP matching the network type and ssid and update the wificonfig with FILS
+ * AKM if supported.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testFilsAKMUpdateBeforeConnect() throws Exception {
+ initializeAndAddNetworkAndVerifySuccess();
+ WifiConfiguration config = setupFilsTest(true);
+ setupFilsEnabledApInScanResult();
+
+ mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ assertTrue(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.FILS_SHA256));
+ verify(mWifiNative, never()).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config));
+ }
+
+ /**
+ * Verifies that while connecting to AP, framework updates the wifi config with
+ * FILS AKM only if underlying driver support FILS feature.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testFilsAkmIsNotAddedinWifiConfigIfDriverDoesNotSupportFils() throws Exception {
+ initializeAndAddNetworkAndVerifySuccess();
+ WifiConfiguration config = setupFilsTest(false);
+ setupFilsEnabledApInScanResult();
+
+ mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ assertFalse(config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.FILS_SHA256));
+ verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config));
+ }
+
+
+ /**
+ * Verifies that the HLP (DHCP) packets are send to wpa_supplicant
+ * prior to Fils connection.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testFilsHlpUpdateBeforeFilsConnection() throws Exception {
+ initializeAndAddNetworkAndVerifySuccess();
+ WifiConfiguration config = setupFilsTest(true);
+ setupFilsEnabledApInScanResult();
+
+ mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ prepareFilsHlpPktAndSendStartConnect();
+
+ verify(mWifiNative).flushAllHlp(eq(WIFI_IFACE_NAME));
+ verify(mWifiNative).addHlpReq(eq(WIFI_IFACE_NAME), any(), any());
+ verify(mWifiNative).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config));
+ }
+
+ /**
+ * Verifies that an association rejection in first FILS connect attempt doesn't block
+ * the second connection attempt.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testFilsSecondConnectAttemptIsNotBLockedAfterAssocReject() throws Exception {
+ initializeAndAddNetworkAndVerifySuccess();
+ WifiConfiguration config = setupFilsTest(true);
+ setupFilsEnabledApInScanResult();
+
+ mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ prepareFilsHlpPktAndSendStartConnect();
+
+ verify(mWifiNative, times(1)).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config));
+
+ mCmi.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT, 0, 2, sBSSID);
+ mLooper.dispatchAll();
+
+ mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+ prepareFilsHlpPktAndSendStartConnect();
+
+ verify(mWifiNative, times(2)).connectToNetwork(eq(WIFI_IFACE_NAME), eq(config));
+ }
+
+ /**
+ * Verifies Fils connection.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testFilsConnection() throws Exception {
+ initializeAndAddNetworkAndVerifySuccess();
+ WifiConfiguration config = setupFilsTest(true);
+ setupFilsEnabledApInScanResult();
+
+ mCmi.sendMessage(ClientModeImpl.CMD_START_CONNECT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ prepareFilsHlpPktAndSendStartConnect();
+
+ mCmi.sendMessage(WifiMonitor.FILS_NETWORK_CONNECTION_EVENT, 0, 0, sBSSID);
+ mLooper.dispatchAll();
+
+ mCmi.sendMessage(WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
+ new StateChangeResult(0, WifiSsid.createFromAsciiEncoded(sFilsSsid),
+ sBSSID, SupplicantState.COMPLETED));
+ mLooper.dispatchAll();
+
+ assertEquals("ObtainingIpState", getCurrentState().getName());
+
+ DhcpResultsParcelable dhcpResults = new DhcpResultsParcelable();
+ dhcpResults.baseConfiguration = new StaticIpConfiguration();
+ dhcpResults.baseConfiguration.gateway = InetAddresses.parseNumericAddress("1.2.3.4");
+ dhcpResults.baseConfiguration.ipAddress =
+ new LinkAddress(InetAddresses.parseNumericAddress("192.168.1.100"), 0);
+ dhcpResults.baseConfiguration.dnsServers.add(InetAddresses.parseNumericAddress("8.8.8.8"));
+ dhcpResults.leaseDuration = 3600;
+
+ injectDhcpSuccess(dhcpResults);
+ mLooper.dispatchAll();
+
+ WifiInfo wifiInfo = mCmi.getWifiInfo();
+ assertNotNull(wifiInfo);
+ assertEquals(sBSSID, wifiInfo.getBSSID());
+ assertTrue(WifiSsid.createFromAsciiEncoded(sFilsSsid).equals(wifiInfo.getWifiSsid()));
+ assertEquals("ConnectedState", getCurrentState().getName());
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
index 2278d0dfe..64c6e0794 100644
--- a/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SupplicantStaIfaceHalTest.java
@@ -16,6 +16,8 @@
package com.android.server.wifi;
import static android.net.wifi.WifiManager.WIFI_FEATURE_DPP;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_FILS_SHA256;
+import static android.net.wifi.WifiManager.WIFI_FEATURE_FILS_SHA384;
import static android.net.wifi.WifiManager.WIFI_FEATURE_MBO;
import static android.net.wifi.WifiManager.WIFI_FEATURE_OCE;
import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE;
@@ -1673,6 +1675,44 @@ public class SupplicantStaIfaceHalTest extends WifiBaseTest {
}
/**
+ * Test FILS SHA256 key management support.
+ */
+ @Test
+ public void testGetKeyMgmtCapabilitiesFilsSha256() throws Exception {
+ setupMocksForHalV1_3();
+
+ executeAndValidateInitializationSequenceV1_3();
+
+ doAnswer(new GetKeyMgmtCapabilities_1_3Answer(android.hardware.wifi.supplicant.V1_3
+ .ISupplicantStaNetwork.KeyMgmtMask.FILS_SHA256))
+ .when(mISupplicantStaIfaceMockV13).getKeyMgmtCapabilities_1_3(any(
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
+ .getKeyMgmtCapabilities_1_3Callback.class));
+
+ assertEquals(WIFI_FEATURE_FILS_SHA256,
+ mDut.getAdvancedKeyMgmtCapabilities(WLAN0_IFACE_NAME));
+ }
+
+ /**
+ * Test FILS SHA384 key management support.
+ */
+ @Test
+ public void testGetKeyMgmtCapabilitiesFilsSha384() throws Exception {
+ setupMocksForHalV1_3();
+
+ executeAndValidateInitializationSequenceV1_3();
+
+ doAnswer(new GetKeyMgmtCapabilities_1_3Answer(android.hardware.wifi.supplicant.V1_3
+ .ISupplicantStaNetwork.KeyMgmtMask.FILS_SHA384))
+ .when(mISupplicantStaIfaceMockV13).getKeyMgmtCapabilities_1_3(any(
+ android.hardware.wifi.supplicant.V1_3.ISupplicantStaIface
+ .getKeyMgmtCapabilities_1_3Callback.class));
+
+ assertEquals(WIFI_FEATURE_FILS_SHA384,
+ mDut.getAdvancedKeyMgmtCapabilities(WLAN0_IFACE_NAME));
+ }
+
+ /**
* Test Easy Connect (DPP) calls return failure if hal version is less than 1_2
*/
@Test
@@ -2534,4 +2574,199 @@ public class SupplicantStaIfaceHalTest extends WifiBaseTest {
eq(WLAN0_IFACE_NAME), btmFrameDataCaptor.capture());
}
+ /**
+ * Tests the configuring of FILS HLP packet in supplicant.
+ */
+ @Test
+ public void testAddHlpReq() throws Exception {
+ byte[] dstAddr = {0x45, 0x23, 0x12, 0x12, 0x12, 0x45};
+ byte[] hlpPacket = {0x00, 0x01, 0x02, 0x03, 0x04, 0x12, 0x15, 0x34, 0x55, 0x12,
+ 0x12, 0x45, 0x23, 0x52, 0x32, 0x16, 0x15, 0x53, 0x62, 0x32, 0x32, 0x10};
+
+ setupMocksForHalV1_3();
+ when(mISupplicantStaIfaceMockV13.filsHlpAddRequest(any(byte[].class),
+ any(ArrayList.class))).thenReturn(mStatusSuccess);
+
+ // Fail before initialization is performed.
+ assertFalse(mDut.addHlpReq(WLAN0_IFACE_NAME, dstAddr, hlpPacket));
+ verify(mISupplicantStaIfaceMockV13, never()).filsHlpAddRequest(any(byte[].class),
+ any(ArrayList.class));
+
+ executeAndValidateInitializationSequenceV1_3();
+ assertNotNull(mISupplicantStaIfaceCallbackV13);
+
+ ArrayList<Byte> hlpPayload = NativeUtil.byteArrayToArrayList(hlpPacket);
+ assertTrue(mDut.addHlpReq(WLAN0_IFACE_NAME, dstAddr, hlpPacket));
+ verify(mISupplicantStaIfaceMockV13).filsHlpAddRequest(eq(dstAddr), eq(hlpPayload));
+ }
+
+ /**
+ * Tests the flushing of FILS HLP packet from supplicant.
+ */
+ @Test
+ public void testFlushAllHlp() throws Exception {
+
+ setupMocksForHalV1_3();
+ when(mISupplicantStaIfaceMockV13.filsHlpFlushRequest()).thenReturn(mStatusSuccess);
+
+ // Fail before initialization is performed.
+ assertFalse(mDut.flushAllHlp(WLAN0_IFACE_NAME));
+ verify(mISupplicantStaIfaceMockV13, never()).filsHlpFlushRequest();
+
+ executeAndValidateInitializationSequenceV1_3();
+ assertNotNull(mISupplicantStaIfaceCallbackV13);
+
+ assertTrue(mDut.flushAllHlp(WLAN0_IFACE_NAME));
+ verify(mISupplicantStaIfaceMockV13).filsHlpFlushRequest();
+ }
+
+ /**
+ * Tests the handling of state change V13 notification without
+ * any configured network.
+ */
+ @Test
+ public void testonStateChangedV13CallbackWithNoConfiguredNetwork() throws Exception {
+ setupMocksForHalV1_3();
+ executeAndValidateInitializationSequenceV1_3();
+ assertNotNull(mISupplicantStaIfaceCallbackV13);
+
+ mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
+ ISupplicantStaIfaceCallback.State.INACTIVE,
+ NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
+
+ // Can't compare WifiSsid instances because they lack an equals.
+ verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
+ eq(WLAN0_IFACE_NAME), eq(WifiConfiguration.INVALID_NETWORK_ID),
+ any(WifiSsid.class), eq(BSSID), eq(SupplicantState.INACTIVE));
+ }
+
+ /**
+ * Tests the handling of state change V13 notification to
+ * associated after configuring a network.
+ */
+ @Test
+ public void testStateChangeV13ToAssociatedCallback() throws Exception {
+ setupMocksForHalV1_3();
+ executeAndValidateInitializationSequenceV1_3();
+ int frameworkNetworkId = 6;
+ executeAndValidateConnectSequence(frameworkNetworkId, false);
+ assertNotNull(mISupplicantStaIfaceCallbackV13);
+
+ mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
+ ISupplicantStaIfaceCallback.State.ASSOCIATED,
+ NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
+
+ verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
+ eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
+ any(WifiSsid.class), eq(BSSID), eq(SupplicantState.ASSOCIATED));
+ }
+
+ /**
+ * Tests the handling of state change V13 notification to
+ * completed after configuring a network.
+ */
+ @Test
+ public void testStateChangeV13ToCompletedCallback() throws Exception {
+ InOrder wifiMonitorInOrder = inOrder(mWifiMonitor);
+ setupMocksForHalV1_3();
+ executeAndValidateInitializationSequenceV1_3();
+ assertNotNull(mISupplicantStaIfaceCallbackV13);
+ int frameworkNetworkId = 6;
+ executeAndValidateConnectSequence(frameworkNetworkId, false);
+
+ mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
+ ISupplicantStaIfaceCallback.State.COMPLETED,
+ NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
+
+ wifiMonitorInOrder.verify(mWifiMonitor).broadcastNetworkConnectionEvent(
+ eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(BSSID));
+ wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
+ eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
+ any(WifiSsid.class), eq(BSSID), eq(SupplicantState.COMPLETED));
+ }
+
+ /**
+ * Tests the handling of incorrect network passwords, edge case
+ * when onStateChanged_1_3() is used.
+ *
+ * If the network is removed during 4-way handshake, do not call it a password mismatch.
+ */
+ @Test
+ public void testNetworkRemovedDuring4wayWhenonStateChangedV13IsUsed() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+ setupMocksForHalV1_3();
+ executeAndValidateInitializationSequenceV1_3();
+ assertNotNull(mISupplicantStaIfaceCallbackV13);
+
+ int reasonCode = 3;
+
+ mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
+ ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
+ mISupplicantStaIfaceCallback.onNetworkRemoved(SUPPLICANT_NETWORK_ID);
+ mISupplicantStaIfaceCallback.onDisconnected(
+ NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
+ verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(),
+ anyInt());
+ }
+
+ /**
+ * Tests the handling of incorrect network passwords when
+ * onStateChanged_1_3() is used, edge case.
+ *
+ * If the disconnect reason is "IE in 4way differs", do not call it a password mismatch.
+ */
+ @Test
+ public void testIeDiffersWhenonStateChangedV13IsUsed() throws Exception {
+ executeAndValidateInitializationSequence();
+ assertNotNull(mISupplicantStaIfaceCallback);
+ setupMocksForHalV1_3();
+ executeAndValidateInitializationSequenceV1_3();
+ assertNotNull(mISupplicantStaIfaceCallbackV13);
+
+ int reasonCode = ISupplicantStaIfaceCallback.ReasonCode.IE_IN_4WAY_DIFFERS;
+
+ mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
+ ISupplicantStaIfaceCallback.State.FOURWAY_HANDSHAKE,
+ NativeUtil.macAddressToByteArray(BSSID),
+ SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID), false);
+ mISupplicantStaIfaceCallback.onDisconnected(
+ NativeUtil.macAddressToByteArray(BSSID), true, reasonCode);
+ verify(mWifiMonitor, times(0)).broadcastAuthenticationFailureEvent(any(), anyInt(),
+ anyInt());
+ }
+
+ /**
+ * Tests the handling of state change V13 notification to
+ * completed (with FILS HLP IE sent) after configuring a
+ * network.
+ */
+ @Test
+ public void testStateChangeV13WithFilsHlpIESentToCompletedCallback() throws Exception {
+ InOrder wifiMonitorInOrder = inOrder(mWifiMonitor);
+ setupMocksForHalV1_3();
+ executeAndValidateInitializationSequenceV1_3();
+ assertNotNull(mISupplicantStaIfaceCallbackV13);
+ int frameworkNetworkId = 6;
+ executeAndValidateConnectSequence(frameworkNetworkId, false);
+
+ mISupplicantStaIfaceCallbackV13.onStateChanged_1_3(
+ ISupplicantStaIfaceCallback.State.COMPLETED,
+ NativeUtil.macAddressToByteArray(BSSID), SUPPLICANT_NETWORK_ID,
+ NativeUtil.decodeSsid(SUPPLICANT_SSID), true);
+
+ wifiMonitorInOrder.verify(mWifiMonitor).broadcastFilsNetworkConnectionEvent(
+ eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId), eq(BSSID));
+ wifiMonitorInOrder.verify(mWifiMonitor).broadcastSupplicantStateChangeEvent(
+ eq(WLAN0_IFACE_NAME), eq(frameworkNetworkId),
+ any(WifiSsid.class), eq(BSSID), eq(SupplicantState.COMPLETED));
+ }
+
}
diff --git a/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java b/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
index 949b8659f..616472c10 100644
--- a/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/SupplicantStaNetworkHalTest.java
@@ -387,6 +387,29 @@ public class SupplicantStaNetworkHalTest extends WifiBaseTest {
}
/**
+ * Tests the saving/loading of WifiConfiguration with FILS AKM
+ * to wpa_supplicant.
+ */
+ @Test
+ public void testTLSWifiEnterpriseConfigWithFilsEapErp() throws Exception {
+ // Now expose the V1.3 ISupplicantStaNetwork
+ createSupplicantStaNetwork(SupplicantStaNetworkVersion.V1_3);
+
+ WifiConfiguration config = WifiConfigurationTestUtil.createEapNetwork();
+ config.enterpriseConfig =
+ WifiConfigurationTestUtil.createTLSWifiEnterpriseConfigWithNonePhase2();
+ config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.FILS_SHA256);
+ config.enterpriseConfig.setFieldValue(WifiEnterpriseConfig.EAP_ERP, "1");
+ testWifiConfigurationSaveLoad(config);
+ // Check the supplicant variables to ensure that we have added the FILS AKM.
+ assertTrue((mSupplicantVariables.keyMgmtMask & android.hardware.wifi.supplicant.V1_3
+ .ISupplicantStaNetwork.KeyMgmtMask.FILS_SHA256)
+ == android.hardware.wifi.supplicant.V1_3
+ .ISupplicantStaNetwork.KeyMgmtMask.FILS_SHA256);
+ verify(mISupplicantStaNetworkV13).setEapErp(eq(true));
+ }
+
+ /**
* Tests the saving of WifiConfiguration to wpa_supplicant.
*/
@Test
@@ -974,6 +997,14 @@ public class SupplicantStaNetworkHalTest extends WifiBaseTest {
Integer.parseInt(oppKeyCaching) == 1 ? true : false,
mSupplicantVariables.eapProactiveKeyCaching);
}
+ // There is no getter for this one, so check the supplicant variable.
+ String eapErp =
+ config.enterpriseConfig.getFieldValue(WifiEnterpriseConfig.EAP_ERP);
+ if (!TextUtils.isEmpty(eapErp)) {
+ assertEquals(
+ Integer.parseInt(eapErp) == 1 ? true : false,
+ mSupplicantVariables.eapErp);
+ }
}
/**
@@ -1695,6 +1726,14 @@ public class SupplicantStaNetworkHalTest extends WifiBaseTest {
}).when(mISupplicantStaNetworkV13)
.getWapiCertSuite(any(android.hardware.wifi.supplicant.V1_3
.ISupplicantStaNetwork.getWapiCertSuiteCallback.class));
+
+ /** EAP ERP */
+ doAnswer(new AnswerWithArguments() {
+ public SupplicantStatus answer(boolean enable) throws RemoteException {
+ mSupplicantVariables.eapErp = enable;
+ return mStatusSuccess;
+ }
+ }).when(mISupplicantStaNetworkV13).setEapErp(any(boolean.class));
}
private SupplicantStatus createSupplicantStatus(int code) {
@@ -1761,5 +1800,6 @@ public class SupplicantStaNetworkHalTest extends WifiBaseTest {
public int ocsp;
public ArrayList<Byte> serializedPmkCache;
public String wapiCertSuite;
+ public boolean eapErp;
}
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java b/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java
index 40ca9b9a2..6652e9b0c 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiMonitorTest.java
@@ -602,4 +602,23 @@ public class WifiMonitorTest extends WifiBaseTest {
assertEquals(WifiMonitor.MBO_OCE_BSS_TM_HANDLING_DONE, messageCaptor.getValue().what);
}
+ /**
+ * Broadcast fils network connection test.
+ */
+ @Test
+ public void testBroadcastFilsNetworkConnectionEvent() {
+ mWifiMonitor.registerHandler(
+ WLAN_IFACE_NAME, WifiMonitor.FILS_NETWORK_CONNECTION_EVENT, mHandlerSpy);
+ int networkId = NETWORK_ID;
+ String bssid = BSSID;
+ mWifiMonitor.broadcastFilsNetworkConnectionEvent(WLAN_IFACE_NAME, networkId, bssid);
+ mLooper.dispatchAll();
+
+ ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
+ verify(mHandlerSpy).handleMessage(messageCaptor.capture());
+ assertEquals(WifiMonitor.FILS_NETWORK_CONNECTION_EVENT, messageCaptor.getValue().what);
+ assertEquals(networkId, messageCaptor.getValue().arg1);
+ assertEquals(bssid, (String) messageCaptor.getValue().obj);
+ }
+
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
index 79df8fe6f..f1a908549 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNativeTest.java
@@ -1033,4 +1033,33 @@ public class WifiNativeTest extends WifiBaseTest {
WifiNl80211Manager.SEND_MGMT_FRAME_ERROR_UNKNOWN);
verify(mWificondControl, never()).sendMgmtFrame(any(), any(), anyInt(), any(), any());
}
+
+ /**
+ * Tests that WifiNative#addHlpReq() calls
+ * SupplicantStaIfaceHal#addHlpReq()
+ */
+ @Test
+ public void testaddHlpReq() {
+ byte[] hlpPacket = {
+ 0x40, 0x00, 0x3c, 0x00, (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b,
+ 0x33, 0x72, (byte) 0xf4, (byte) 0xf5, (byte) 0xe8, 0x51, (byte) 0x9e, 0x09,
+ (byte) 0xa8, (byte) 0xbd, 0x27, 0x5b, 0x33, 0x72, (byte) 0xb0, 0x66,
+ 0x00, 0x00
+ };
+ mWifiNative.addHlpReq(WIFI_IFACE_NAME, TEST_MAC_ADDRESS, hlpPacket);
+
+ verify(mStaIfaceHal).addHlpReq(eq(WIFI_IFACE_NAME),
+ eq(TEST_MAC_ADDRESS.toByteArray()), eq(hlpPacket));
+ }
+
+ /**
+ * Tests that WifiNative#flushAllHlp() calls
+ * SupplicantStaIfaceHal#flushAllHlp()
+ */
+ @Test
+ public void testflushAllHlp() {
+ mWifiNative.flushAllHlp(WIFI_IFACE_NAME);
+
+ verify(mStaIfaceHal).flushAllHlp(eq(WIFI_IFACE_NAME));
+ }
}
diff --git a/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
index 4b98a59d9..874da7043 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java
@@ -627,6 +627,88 @@ public class InformationElementUtilTest extends WifiBaseTest {
}
/**
+ * Test Capabilities.generateCapabilitiesString() with RSN IE,
+ * CCMP and FILS SHA256. Expect the function to return a string
+ * with the proper security information.
+ */
+ @Test
+ public void buildCapabilities_rsnFilsSha256Element() {
+ InformationElement ieRsn = new InformationElement();
+ ieRsn.id = InformationElement.EID_RSN;
+ ieRsn.bytes = new byte[] {
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of AKMs (3)
+ (byte) 0x03, (byte) 0x00,
+ // WPA AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x01,
+ // WPA SHA256 AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x05,
+ // FILS SHA256 AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x0E,
+ // RSN capabilities
+ (byte) 0x00, (byte) 0x00 };
+
+ InformationElement[] ies = new InformationElement[] { ieRsn };
+ int beaconCap = 0x1 << 4;
+
+ InformationElementUtil.Capabilities capabilities =
+ new InformationElementUtil.Capabilities();
+ capabilities.from(ies, beaconCap, true);
+ String result = capabilities.generateCapabilitiesString();
+
+ assertEquals("[WPA2-EAP+EAP-SHA256+FILS-SHA256-CCMP][RSN-EAP+EAP-SHA256+FILS-SHA256-CCMP]",
+ result);
+ }
+
+ /**
+ * Test Capabilities.generateCapabilitiesString() with RSN IE,
+ * CCMP and FILS SHA384. Expect the function to return a string
+ * with the proper security information.
+ */
+ @Test
+ public void buildCapabilities_rsnFilsSha384Element() {
+ InformationElement ieRsn = new InformationElement();
+ ieRsn.id = InformationElement.EID_RSN;
+ ieRsn.bytes = new byte[] {
+ // RSNE Version (0x0001)
+ (byte) 0x01, (byte) 0x00,
+ // Group cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of cipher suites (1)
+ (byte) 0x01, (byte) 0x00,
+ // Cipher suite: CCMP
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x04,
+ // Number of AKMs (3)
+ (byte) 0x03, (byte) 0x00,
+ // WPA AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x01,
+ // WPA SHA256 AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x05,
+ // FILS SHA384 AKM
+ (byte) 0x00, (byte) 0x0F, (byte) 0xAC, (byte) 0x0F,
+ // RSN capabilities
+ (byte) 0x00, (byte) 0x00 };
+
+ InformationElement[] ies = new InformationElement[] { ieRsn };
+ int beaconCap = 0x1 << 4;
+
+ InformationElementUtil.Capabilities capabilities =
+ new InformationElementUtil.Capabilities();
+ capabilities.from(ies, beaconCap, true);
+ String result = capabilities.generateCapabilitiesString();
+
+ assertEquals("[WPA2-EAP+EAP-SHA256+FILS-SHA384-CCMP][RSN-EAP+EAP-SHA256+FILS-SHA384-CCMP]",
+ result);
+ }
+
+ /**
* Test Capabilities.generateCapabilitiesString() with both RSN and WPA1 IE which are malformed.
* Expect the function to return a string with empty key management & pairswise cipher security
* information.
diff --git a/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
index bc5f880b4..0f69316e7 100644
--- a/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/util/ScanResultUtilTest.java
@@ -203,6 +203,46 @@ public class ScanResultUtilTest extends WifiBaseTest {
assertFalse(ScanResultUtil.isScanResultForPskSaeTransitionNetwork(input));
}
+ /**
+ * Test that provided network supports FILS SHA256 AKM.
+ */
+ @Test
+ public void testFilsSha256AkmSupportedNetwork() {
+ final String ssid = "FILS-AP";
+ String caps = "[WPA2-EAP+EAP-SHA256+FILS-SHA256-CCMP]"
+ + "[RSN-EAP+EAP-SHA256+FILS-SHA256-CCMP][ESS]";
+
+ ScanResult input = new ScanResult(WifiSsid.createFromAsciiEncoded(ssid), ssid,
+ "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
+ 0, true);
+
+ input.informationElements = new InformationElement[] {
+ createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8))
+ };
+
+ assertTrue(ScanResultUtil.isScanResultForFilsSha256Network(input));
+ }
+
+ /**
+ * Test that provided network supports FILS SHA384 AKM.
+ */
+ @Test
+ public void testFilsSha384AkmSupportedNetwork() {
+ final String ssid = "FILS-AP";
+ String caps = "[WPA2-EAP+EAP-SHA384+FILS-SHA384-CCMP]"
+ + "[RSN-EAP+EAP-SHA384+FILS-SHA384-CCMP][ESS]";
+
+ ScanResult input = new ScanResult(WifiSsid.createFromAsciiEncoded(ssid), ssid,
+ "ab:cd:01:ef:45:89", 1245, 0, caps, -78, 2450, 1025, 22, 33, 20, 0,
+ 0, true);
+
+ input.informationElements = new InformationElement[] {
+ createIE(InformationElement.EID_SSID, ssid.getBytes(StandardCharsets.UTF_8))
+ };
+
+ assertTrue(ScanResultUtil.isScanResultForFilsSha384Network(input));
+ }
+
private static InformationElement createIE(int id, byte[] bytes) {
InformationElement ie = new InformationElement();
ie.id = id;