summaryrefslogtreecommitdiff
path: root/framework
diff options
context:
space:
mode:
author Mahesh KKV <maheshkkv@google.com> 2025-02-20 19:05:37 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-02-20 19:05:37 -0800
commit1be54ecdeb15b5b49f80863b2f6f509e1094f72b (patch)
tree5ddcef4cbc2eba21eff1f2cf1846d4afe05bef7d /framework
parent2c09d0a564e29f34fa6ca7bcab968398a32d83b6 (diff)
parent3fb8c3592362c5654bcf5af04bf25a292c54519a (diff)
Merge changes I0c7a5557,I4c835885,I5b6b1db3,I775b8576,Ie128b26f into main
* changes: Add coverage for secure ranging in NetworkDetail Add coverage for secure ranging in ScanResult Add coverage for Rsnxe class Fix RangingResult parcelling Add unit test for SecureRangingConfig
Diffstat (limited to 'framework')
-rw-r--r--framework/java/android/net/wifi/rtt/RangingResult.java12
-rw-r--r--framework/java/android/net/wifi/rtt/ResponderConfig.java5
-rw-r--r--framework/tests/src/android/net/wifi/ScanResultTest.java14
-rw-r--r--framework/tests/src/android/net/wifi/rtt/SecureRangingConfigTest.java163
-rw-r--r--framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java168
5 files changed, 360 insertions, 2 deletions
diff --git a/framework/java/android/net/wifi/rtt/RangingResult.java b/framework/java/android/net/wifi/rtt/RangingResult.java
index 604c879daa..166a13b1d9 100644
--- a/framework/java/android/net/wifi/rtt/RangingResult.java
+++ b/framework/java/android/net/wifi/rtt/RangingResult.java
@@ -1168,6 +1168,12 @@ public final class RangingResult implements Parcelable {
if (SdkLevel.isAtLeastV()) {
dest.writeList(mVendorData);
}
+ dest.writeBoolean(mIsRangingAuthenticated);
+ dest.writeBoolean(mIsRangingFrameProtected);
+ dest.writeBoolean(mIsSecureHeLtfEnabled);
+ dest.writeLong(mPasnComebackAfterMillis);
+ dest.writeByteArray(mPasnComebackCookie);
+ dest.writeInt(mSecureHeLtfProtocolVersion);
}
public static final @android.annotation.NonNull Creator<RangingResult> CREATOR =
@@ -1208,6 +1214,12 @@ public final class RangingResult implements Parcelable {
if (SdkLevel.isAtLeastV()) {
builder.setVendorData(ParcelUtil.readOuiKeyedDataList(in));
}
+ builder.setRangingAuthenticated(in.readBoolean())
+ .setRangingFrameProtected(in.readBoolean())
+ .setSecureHeLtfEnabled(in.readBoolean())
+ .setPasnComebackAfterMillis(in.readLong())
+ .setPasnComebackCookie(in.createByteArray())
+ .setSecureHeLtfProtocolVersion(in.readInt());
return builder.build();
}
};
diff --git a/framework/java/android/net/wifi/rtt/ResponderConfig.java b/framework/java/android/net/wifi/rtt/ResponderConfig.java
index 5b4f2da08a..ffa98499ed 100644
--- a/framework/java/android/net/wifi/rtt/ResponderConfig.java
+++ b/framework/java/android/net/wifi/rtt/ResponderConfig.java
@@ -514,13 +514,14 @@ public final class ResponderConfig implements Parcelable {
if (scanResult.getWifiSsid() != null) {
pasnConfigBuilder.setWifiSsid(scanResult.getWifiSsid());
}
+ // If the responder is capable of PASN, always enable frame protection for secure ranging
+ // irrespective of responder mandates or not.
return new SecureRangingConfig.Builder(pasnConfigBuilder.build())
.setSecureHeLtfEnabled(scanResult.isSecureHeLtfSupported())
- .setRangingFrameProtectionEnabled(scanResult.isRangingFrameProtectionRequired())
+ .setRangingFrameProtectionEnabled(true)
.build();
}
-
/**
* Creates a Responder configuration from a MAC address corresponding to a Wi-Fi Aware
* Responder. The Responder parameters are set to defaults.
diff --git a/framework/tests/src/android/net/wifi/ScanResultTest.java b/framework/tests/src/android/net/wifi/ScanResultTest.java
index 32265c3279..c18a66b096 100644
--- a/framework/tests/src/android/net/wifi/ScanResultTest.java
+++ b/framework/tests/src/android/net/wifi/ScanResultTest.java
@@ -435,4 +435,18 @@ public class ScanResultTest {
assertEquals(WifiScanner.WIFI_BAND_5_GHZ, ScanResult.getBandFromOpClass(120, 149));
assertEquals(WifiScanner.WIFI_BAND_6_GHZ, ScanResult.getBandFromOpClass(131, 32));
}
+
+ /**
+ * Test IEEE 802.11az NTB Secure Ranging Parameters.
+ */
+ @Test
+ public void testIeee80211azNtbSecureRangingParameters() {
+ ScanResult scanResult = new ScanResult();
+ scanResult.setFlag(ScanResult.FLAG_80211az_NTB_RESPONDER
+ | ScanResult.FLAG_SECURE_HE_LTF_SUPPORTED
+ | ScanResult.FLAG_RANGING_FRAME_PROTECTION_REQUIRED);
+ assertTrue(scanResult.is80211azNtbResponder());
+ assertTrue(scanResult.isRangingFrameProtectionRequired());
+ assertTrue(scanResult.isSecureHeLtfSupported());
+ }
}
diff --git a/framework/tests/src/android/net/wifi/rtt/SecureRangingConfigTest.java b/framework/tests/src/android/net/wifi/rtt/SecureRangingConfigTest.java
new file mode 100644
index 0000000000..fd661d824c
--- /dev/null
+++ b/framework/tests/src/android/net/wifi/rtt/SecureRangingConfigTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net.wifi.rtt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import android.net.wifi.WifiSsid;
+import android.os.Parcel;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+
+/**
+ * Unit tests for {@link SecureRangingConfig}.
+ */
+@SmallTest
+public class SecureRangingConfigTest {
+
+ private static final boolean TEST_SECURE_HE_LTF = true;
+ private static final boolean TEST_RANGING_FRAME_PROTECTION = false;
+ private static final int TEST_AKM = PasnConfig.AKM_SAE;
+ private static final int TEST_CIPHER = PasnConfig.CIPHER_CCMP_128;
+ private static final byte[] TEST_COOKIE = new byte[]{1, 2, 3};
+ private static final String TEST_SSID = "\"Test SSID\"";
+ private static final String TEST_PASSWORD = "password";
+
+ /**
+ * Verify builder and getter methods work as expected.
+ */
+ @Test
+ public void testBuilderAndGetters() {
+ WifiSsid ssid = WifiSsid.fromString(TEST_SSID);
+ PasnConfig pasnConfig = new PasnConfig.Builder(TEST_AKM, TEST_CIPHER)
+ .setPassword(TEST_PASSWORD)
+ .setWifiSsid(ssid)
+ .setPasnComebackCookie(TEST_COOKIE).build();
+ SecureRangingConfig config = new SecureRangingConfig.Builder(pasnConfig)
+ .setSecureHeLtfEnabled(TEST_SECURE_HE_LTF)
+ .setRangingFrameProtectionEnabled(TEST_RANGING_FRAME_PROTECTION)
+ .build();
+
+ assertEquals(TEST_SECURE_HE_LTF, config.isSecureHeLtfEnabled());
+ assertEquals(TEST_RANGING_FRAME_PROTECTION, config.isRangingFrameProtectionEnabled());
+ assertEquals(pasnConfig, config.getPasnConfig());
+ }
+
+ /**
+ * Verify parceling round trip returns an identical object.
+ */
+ @Test
+ public void testParcelableRoundTrip() {
+ WifiSsid ssid = WifiSsid.fromString(TEST_SSID);
+ PasnConfig pasnConfig = new PasnConfig.Builder(TEST_AKM, TEST_CIPHER)
+ .setPassword(TEST_PASSWORD)
+ .setWifiSsid(ssid)
+ .setPasnComebackCookie(TEST_COOKIE).build();
+
+ SecureRangingConfig config = new SecureRangingConfig.Builder(pasnConfig)
+ .setSecureHeLtfEnabled(TEST_SECURE_HE_LTF)
+ .setRangingFrameProtectionEnabled(TEST_RANGING_FRAME_PROTECTION)
+ .build();
+
+ Parcel parcel = Parcel.obtain();
+ config.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ SecureRangingConfig fromParcel =
+ SecureRangingConfig.CREATOR.createFromParcel(parcel);
+ assertEquals(config, fromParcel);
+ }
+
+ /**
+ * Verify default values when not set through the builder.
+ */
+ @Test
+ public void testDefaultValues() {
+ PasnConfig pasnConfig = new PasnConfig.Builder(TEST_AKM, TEST_CIPHER).build();
+ SecureRangingConfig config = new SecureRangingConfig.Builder(pasnConfig).build();
+
+ assertTrue(config.isSecureHeLtfEnabled());
+ assertTrue(config.isRangingFrameProtectionEnabled());
+ }
+
+ /**
+ * Tests equality and non-equality of objects.
+ */
+ @Test
+ public void testEqualsAndHashCode() {
+ PasnConfig pasnConfig1 = new PasnConfig.Builder(TEST_AKM, TEST_CIPHER)
+ .setPasnComebackCookie(TEST_COOKIE).build();
+ PasnConfig pasnConfig2 = new PasnConfig.Builder(TEST_AKM, TEST_CIPHER).build();
+ SecureRangingConfig config1 = new SecureRangingConfig.Builder(pasnConfig1)
+ .setSecureHeLtfEnabled(TEST_SECURE_HE_LTF)
+ .setRangingFrameProtectionEnabled(TEST_RANGING_FRAME_PROTECTION)
+ .build();
+ SecureRangingConfig config2 = new SecureRangingConfig.Builder(pasnConfig1)
+ .setSecureHeLtfEnabled(TEST_SECURE_HE_LTF)
+ .setRangingFrameProtectionEnabled(TEST_RANGING_FRAME_PROTECTION)
+ .build();
+ SecureRangingConfig config3 = new SecureRangingConfig.Builder(pasnConfig2)
+ .setSecureHeLtfEnabled(TEST_SECURE_HE_LTF)
+ .setRangingFrameProtectionEnabled(TEST_RANGING_FRAME_PROTECTION)
+ .build();
+
+ assertEquals(config1, config2);
+ assertNotEquals(config1, config3);
+ assertEquals(config1.hashCode(), config2.hashCode());
+ }
+
+ /**
+ * Tests toString() method.
+ */
+ @Test
+ public void testToString() {
+ WifiSsid ssid = WifiSsid.fromString(TEST_SSID);
+ PasnConfig pasnConfig = new PasnConfig.Builder(TEST_AKM, TEST_CIPHER)
+ .setPassword(TEST_PASSWORD)
+ .setWifiSsid(ssid)
+ .setPasnComebackCookie(TEST_COOKIE).build();
+ SecureRangingConfig config = new SecureRangingConfig.Builder(pasnConfig)
+ .setSecureHeLtfEnabled(TEST_SECURE_HE_LTF)
+ .setRangingFrameProtectionEnabled(TEST_RANGING_FRAME_PROTECTION)
+ .build();
+
+ String configString = config.toString();
+
+ assertNotNull(configString);
+ assertNotEquals("", configString);
+ }
+
+ @Test
+ public void testBuilderMethodsReturnNonNull() {
+ PasnConfig pasnConfig = new PasnConfig.Builder(TEST_AKM, TEST_CIPHER).build();
+ SecureRangingConfig.Builder builder = new SecureRangingConfig.Builder(pasnConfig);
+ assertNotNull(builder.setSecureHeLtfEnabled(TEST_SECURE_HE_LTF));
+ assertNotNull(builder.setRangingFrameProtectionEnabled(TEST_RANGING_FRAME_PROTECTION));
+ }
+
+
+ @Test(expected = NullPointerException.class)
+ public void testBuilder_nullPasnConfigThrowsException() {
+ new SecureRangingConfig.Builder(null);
+ }
+
+}
diff --git a/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java b/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
index f59fbc9243..08d5f40385 100644
--- a/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
+++ b/framework/tests/src/android/net/wifi/rtt/WifiRttManagerTest.java
@@ -16,9 +16,11 @@
package android.net.wifi.rtt;
+import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.fail;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -32,6 +34,7 @@ import android.net.MacAddress;
import android.net.wifi.OuiKeyedData;
import android.net.wifi.OuiKeyedDataUtil;
import android.net.wifi.ScanResult;
+import android.net.wifi.WifiSsid;
import android.net.wifi.aware.PeerHandle;
import android.os.Bundle;
import android.os.IBinder;
@@ -520,6 +523,64 @@ public class WifiRttManagerTest {
}
/**
+ * Validate that RangingResults parcel works with secure ranging enabled (produces same
+ * object on write/read).
+ */
+ @Test
+ public void testSecureRangingResultsParcel() {
+ int status = RangingResult.STATUS_SUCCESS;
+ final MacAddress mac = MacAddress.fromString("00:01:02:03:04:05");
+ int distanceCm = 105;
+ int distanceStdDevCm = 10;
+ int rssi = 5;
+ int numAttemptedMeasurements = 8;
+ int numSuccessfulMeasurements = 3;
+ long timestamp = System.currentTimeMillis();
+ byte[] lci = { 0x5, 0x6, 0x7 };
+ byte[] lcr = { 0x1, 0x2, 0x3, 0xA, 0xB, 0xC };
+ List<OuiKeyedData> vendorData = OuiKeyedDataUtil.createTestOuiKeyedDataList(5);
+
+ RangingResult.Builder resultBuilder = new RangingResult.Builder()
+ .setStatus(status)
+ .setMacAddress(mac)
+ .setDistanceMm(distanceCm)
+ .setDistanceStdDevMm(distanceStdDevCm)
+ .setRssi(rssi)
+ .setNumAttemptedMeasurements(numAttemptedMeasurements)
+ .setNumSuccessfulMeasurements(numSuccessfulMeasurements)
+ .setLci(lci)
+ .setLcr(lcr)
+ .setRangingTimestampMillis(timestamp)
+ .set80211mcMeasurement(false)
+ .set80211azNtbMeasurement(true)
+ .set80211azInitiatorTxLtfRepetitionsCount(2)
+ .set80211azResponderTxLtfRepetitionsCount(2)
+ .set80211azNumberOfRxSpatialStreams(2)
+ .setPasnComebackCookie(new byte[] {1, 2, 3})
+ .setMaxTimeBetweenNtbMeasurementsMicros(1000)
+ .setMinTimeBetweenNtbMeasurementsMicros(100)
+ .setRangingAuthenticated(true)
+ .setRangingFrameProtected(true);
+
+ if (SdkLevel.isAtLeastV()) {
+ resultBuilder.setVendorData(vendorData);
+ }
+ RangingResult result = resultBuilder.build();
+
+ Parcel parcelW = Parcel.obtain();
+ result.writeToParcel(parcelW, 0);
+ byte[] bytes = parcelW.marshall();
+ parcelW.recycle();
+
+ Parcel parcelR = Parcel.obtain();
+ parcelR.unmarshall(bytes, 0, bytes.length);
+ parcelR.setDataPosition(0);
+ RangingResult rereadResult = RangingResult.CREATOR.createFromParcel(parcelR);
+
+ assertEquals(result, rereadResult);
+ }
+
+ /**
* Validate that RangingResults tests equal even if LCI/LCR is empty (length == 0) and null.
*/
@Test
@@ -568,6 +629,17 @@ public class WifiRttManagerTest {
*/
@Test
public void testResponderConfigParcel() {
+ // Create SecureRangingConfig
+ PasnConfig pasnConfig = new PasnConfig.Builder(PasnConfig.AKM_SAE | PasnConfig.AKM_PASN,
+ PasnConfig.CIPHER_CCMP_256 | PasnConfig.CIPHER_GCMP_256)
+ .setPassword("password")
+ .setWifiSsid(WifiSsid.fromString("\"SSID\""))
+ .setPasnComebackCookie(new byte[]{1, 2, 3})
+ .build();
+ SecureRangingConfig secureRangingConfig = new SecureRangingConfig.Builder(pasnConfig)
+ .setSecureHeLtfEnabled(true)
+ .setRangingFrameProtectionEnabled(true)
+ .build();
// ResponderConfig constructed with a MAC address
ResponderConfig config = new ResponderConfig.Builder()
.setMacAddress(MacAddress.fromString("00:01:02:03:04:05"))
@@ -577,6 +649,10 @@ public class WifiRttManagerTest {
.setCenterFreq0Mhz(2345)
.setCenterFreq1Mhz(2555)
.setPreamble(ScanResult.PREAMBLE_LEGACY)
+ .set80211azNtbSupported(true)
+ .setNtbMaxTimeBetweenMeasurementsMicros(10000)
+ .setNtbMinTimeBetweenMeasurementsMicros(100)
+ .setSecureRangingConfig(secureRangingConfig)
.build();
Parcel parcelW = Parcel.obtain();
@@ -753,4 +829,96 @@ public class WifiRttManagerTest {
verify(mockRttService).getRttCharacteristics();
assertEquals(0, characteristics.size());
}
+
+ /**
+ * Validate secure ranging request call flow with successful results.
+ */
+ @Test
+ public void testSecureRangeSuccess() throws Exception {
+ // Build a scan result with secure ranging support
+ ScanResult.InformationElement htCap = new ScanResult.InformationElement();
+ htCap.id = ScanResult.InformationElement.EID_HT_CAPABILITIES;
+
+ ScanResult.InformationElement vhtCap = new ScanResult.InformationElement();
+ vhtCap.id = ScanResult.InformationElement.EID_VHT_CAPABILITIES;
+
+ ScanResult.InformationElement vsa = new ScanResult.InformationElement();
+ vsa.id = ScanResult.InformationElement.EID_VSA;
+
+ ScanResult.InformationElement heCap = new ScanResult.InformationElement();
+ heCap.id = ScanResult.InformationElement.EID_EXTENSION_PRESENT;
+ heCap.idExt = ScanResult.InformationElement.EID_EXT_HE_CAPABILITIES;
+
+ ScanResult.InformationElement ehtCap = new ScanResult.InformationElement();
+ ehtCap.id = ScanResult.InformationElement.EID_EXTENSION_PRESENT;
+ ehtCap.idExt = ScanResult.InformationElement.EID_EXT_EHT_CAPABILITIES;
+
+ ScanResult.InformationElement[] ie = new ScanResult.InformationElement[3];
+ ie[0] = vhtCap;
+ ie[1] = heCap;
+ ie[2] = ehtCap;
+
+ // Build a secure ranging request
+ ScanResult scanResult = new ScanResult();
+ scanResult.BSSID = "00:01:02:03:04:05";
+ scanResult.setFlag(
+ ScanResult.FLAG_80211az_NTB_RESPONDER | ScanResult.FLAG_SECURE_HE_LTF_SUPPORTED);
+ scanResult.informationElements = ie;
+ scanResult.capabilities = "[RSN-PASN-SAE+SAE_EXT_KEY-GCMP-128]";
+ scanResult.setWifiSsid(WifiSsid.fromString("\"TEST_SSID\""));
+
+ RangingRequest.Builder builder = new RangingRequest.Builder();
+ builder.addAccessPoint(scanResult);
+ builder.setSecurityMode(RangingRequest.SECURITY_MODE_SECURE_AUTH);
+ RangingRequest secureRangingRequest = builder.build();
+
+ // Make sure responder is configured correctly for secure ranging
+ ResponderConfig responderConfig = secureRangingRequest.getRttResponders().get(0);
+ assertNotNull(responderConfig);
+ SecureRangingConfig secureRangingConfig = responderConfig.getSecureRangingConfig();
+ assertNotNull(secureRangingConfig);
+ assertTrue(secureRangingConfig.isRangingFrameProtectionEnabled());
+ assertTrue(secureRangingConfig.isSecureHeLtfEnabled());
+ PasnConfig pasnConfig = secureRangingConfig.getPasnConfig();
+ assertNotNull(pasnConfig);
+ assertEquals(PasnConfig.AKM_PASN | PasnConfig.AKM_SAE, pasnConfig.getBaseAkms());
+ assertEquals(PasnConfig.CIPHER_GCMP_128, pasnConfig.getCiphers());
+ assertNull(pasnConfig.getPasnComebackCookie());
+ assertEquals(WifiSsid.fromString("\"TEST_SSID\""), pasnConfig.getWifiSsid());
+ assertEquals(RangingRequest.SECURITY_MODE_SECURE_AUTH,
+ secureRangingRequest.getSecurityMode());
+
+ List<RangingResult> results = new ArrayList<>();
+ results.add(new RangingResult.Builder()
+ .setStatus(RangingResult.STATUS_SUCCESS)
+ .setMacAddress(MacAddress.fromString(scanResult.BSSID))
+ .setDistanceMm(15)
+ .setDistanceStdDevMm(5)
+ .setRssi(10)
+ .setNumAttemptedMeasurements(8)
+ .setNumSuccessfulMeasurements(5)
+ .setRangingTimestampMillis(666)
+ .set80211mcMeasurement(false)
+ .set80211azNtbMeasurement(true)
+ .setRangingFrameProtected(true)
+ .setSecureHeLtfEnabled(true)
+ .setSecureHeLtfProtocolVersion(0)
+ .build());
+ RangingResultCallback callbackMock = mock(RangingResultCallback.class);
+ ArgumentCaptor<IRttCallback> callbackCaptor = ArgumentCaptor.forClass(IRttCallback.class);
+
+ // verify ranging request passed to service
+ mDut.startRanging(secureRangingRequest, mMockLooperExecutor, callbackMock);
+ verify(mockRttService).startRanging(any(IBinder.class), eq(packageName), eq(featureId),
+ eq(null), eq(secureRangingRequest), callbackCaptor.capture(),
+ any(Bundle.class));
+
+ // service calls back with success
+ callbackCaptor.getValue().onRangingResults(results);
+ mMockLooper.dispatchAll();
+ verify(callbackMock).onRangingResults(results);
+
+ verifyNoMoreInteractions(mockRttService, callbackMock);
+ }
+
}