1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.uwb; 18 19 import static com.google.uwb.support.fira.FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_INTERLEAVED; 20 import static com.google.uwb.support.fira.FiraParams.AOA_TYPE_AZIMUTH_AND_ELEVATION; 21 import static com.google.uwb.support.fira.FiraParams.BPRF_PHR_DATA_RATE_6M81; 22 import static com.google.uwb.support.fira.FiraParams.MAC_ADDRESS_MODE_8_BYTES; 23 import static com.google.uwb.support.fira.FiraParams.MAC_FCS_TYPE_CRC_32; 24 import static com.google.uwb.support.fira.FiraParams.MEASUREMENT_REPORT_TYPE_INITIATOR_TO_RESPONDER; 25 import static com.google.uwb.support.fira.FiraParams.MULTI_NODE_MODE_MANY_TO_MANY; 26 import static com.google.uwb.support.fira.FiraParams.PREAMBLE_DURATION_T32_SYMBOLS; 27 import static com.google.uwb.support.fira.FiraParams.PRF_MODE_HPRF; 28 import static com.google.uwb.support.fira.FiraParams.PROTOCOL_VERSION_1_1; 29 import static com.google.uwb.support.fira.FiraParams.PSDU_DATA_RATE_7M80; 30 import static com.google.uwb.support.fira.FiraParams.RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG; 31 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_ROLE_INITIATOR; 32 import static com.google.uwb.support.fira.FiraParams.RANGING_DEVICE_TYPE_CONTROLEE; 33 import static com.google.uwb.support.fira.FiraParams.RANGING_ROUND_USAGE_SS_TWR_DEFERRED_MODE; 34 import static com.google.uwb.support.fira.FiraParams.RFRAME_CONFIG_SP1; 35 import static com.google.uwb.support.fira.FiraParams.SESSION_TYPE_RANGING; 36 import static com.google.uwb.support.fira.FiraParams.SFD_ID_VALUE_3; 37 import static com.google.uwb.support.fira.FiraParams.STS_CONFIG_DYNAMIC_FOR_CONTROLEE_INDIVIDUAL_KEY; 38 import static com.google.uwb.support.fira.FiraParams.STS_LENGTH_128_SYMBOLS; 39 import static com.google.uwb.support.fira.FiraParams.STS_SEGMENT_COUNT_VALUE_2; 40 41 import static org.junit.Assert.assertEquals; 42 import static org.mockito.ArgumentMatchers.any; 43 import static org.mockito.ArgumentMatchers.anyInt; 44 import static org.mockito.ArgumentMatchers.anyString; 45 import static org.mockito.ArgumentMatchers.eq; 46 import static org.mockito.Mockito.mock; 47 import static org.mockito.Mockito.verify; 48 import static org.mockito.Mockito.when; 49 50 import android.platform.test.annotations.Presubmit; 51 import android.uwb.UwbAddress; 52 53 import androidx.test.filters.SmallTest; 54 import androidx.test.runner.AndroidJUnit4; 55 56 import com.android.server.uwb.data.UwbConfigStatusData; 57 import com.android.server.uwb.data.UwbTlvData; 58 import com.android.server.uwb.data.UwbUciConstants; 59 import com.android.server.uwb.jni.NativeUwbManager; 60 import com.android.server.uwb.proto.UwbStatsLog; 61 import com.android.uwb.flags.FeatureFlags; 62 63 import com.google.uwb.support.fira.FiraOpenSessionParams; 64 import com.google.uwb.support.fira.FiraParams; 65 import com.google.uwb.support.fira.FiraProtocolVersion; 66 import com.google.uwb.support.radar.RadarOpenSessionParams; 67 import com.google.uwb.support.radar.RadarParams; 68 import com.google.uwb.support.rftest.RfTestOpenSessionParams; 69 70 import org.junit.Before; 71 import org.junit.Test; 72 import org.junit.runner.RunWith; 73 import org.mockito.Mock; 74 import org.mockito.MockitoAnnotations; 75 76 import java.util.ArrayList; 77 import java.util.Arrays; 78 import java.util.List; 79 80 /** 81 * Tests for {@link UwbConfigurationManager}. 82 */ 83 @RunWith(AndroidJUnit4.class) 84 @SmallTest 85 @Presubmit 86 public class UwbConfigurationManagerTest { 87 private static final String TEST_CHIP_ID = "testChipId"; 88 @Mock 89 private NativeUwbManager mNativeUwbManager; 90 @Mock 91 private UwbInjector mUwbInjector; 92 @Mock private FeatureFlags mFeatureFlags; 93 private UwbConfigurationManager mUwbConfigurationManager; 94 @Mock 95 private UwbSessionManager.UwbSession mUwbSession; 96 private FiraOpenSessionParams mFiraParams; 97 @Mock 98 private UwbSessionManager.UwbSession mRadarSession; 99 100 private static final RadarOpenSessionParams TEST_RADAR_OPEN_SESSION_PARAMS = 101 new RadarOpenSessionParams.Builder() 102 .setSessionId(22) 103 .setBurstPeriod(100) 104 .setSweepPeriod(40) 105 .setSweepsPerBurst(16) 106 .setSamplesPerSweep(128) 107 .setChannelNumber(FiraParams.UWB_CHANNEL_5) 108 .setSweepOffset(-1) 109 .setRframeConfig(FiraParams.RFRAME_CONFIG_SP3) 110 .setPreambleDuration(RadarParams.PREAMBLE_DURATION_T16384_SYMBOLS) 111 .setPreambleCodeIndex(90) 112 .setSessionPriority(99) 113 .setBitsPerSample(RadarParams.BITS_PER_SAMPLES_32) 114 .setPrfMode(FiraParams.PRF_MODE_HPRF) 115 .setNumberOfBursts(1000) 116 .setRadarDataType(RadarParams.RADAR_DATA_TYPE_RADAR_SWEEP_SAMPLES) 117 .build(); 118 119 private static final RfTestOpenSessionParams TEST_RFTEST_OPEN_SESSION_PARAMS = 120 new RfTestOpenSessionParams.Builder() 121 .setChannelNumber(FiraParams.UWB_CHANNEL_5) 122 .setNumberOfControlee(1) 123 .setDeviceAddress(UwbAddress.fromBytes(new byte[] { 0x4, 0x6})) 124 .setDestAddressList(Arrays.asList(UwbAddress.fromBytes(new byte[] { 0x4, 0x6}))) 125 .setSlotDurationRstu(2400) 126 .setStsIndex(0) 127 .setFcsType(0) 128 .setDeviceRole(1) 129 .setRframeConfig(FiraParams.RFRAME_CONFIG_SP3) 130 .setPreambleCodeIndex(90) 131 .setSfdId(2) 132 .setPsduDataRate(0) 133 .setPreambleDuration(0) 134 .setPrfMode(FiraParams.PRF_MODE_HPRF) 135 .setStsSegmentCount(1) 136 .setNumberOfPackets(1000) 137 .setTgap(2000) 138 .setTstart(450) 139 .setTwin(750) 140 .setRandomizePsdu(0) 141 .setPhrRangingBit(0) 142 .setRmarkerTxStart(0) 143 .setRmarkerRxStart(0) 144 .setStsIndexAutoIncr(0) 145 .setStsDetectBitmap(0) 146 .build(); 147 @Before setUp()148 public void setUp() throws Exception { 149 MockitoAnnotations.initMocks(this); 150 mUwbConfigurationManager = new UwbConfigurationManager(mNativeUwbManager, mUwbInjector); 151 mFiraParams = getFiraParams(); 152 153 when(mUwbSession.getSessionId()).thenReturn(1); 154 when(mUwbSession.getProtocolName()).thenReturn(FiraParams.PROTOCOL_NAME); 155 when(mUwbSession.getProfileType()).thenReturn( 156 UwbStatsLog.UWB_SESSION_INITIATED__PROFILE__FIRA); 157 when(mUwbSession.getParams()).thenReturn(mFiraParams); 158 159 when(mRadarSession.getSessionId()).thenReturn(1); 160 when(mRadarSession.getProtocolName()).thenReturn(RadarParams.PROTOCOL_NAME); 161 when(mRadarSession.getParams()).thenReturn(TEST_RADAR_OPEN_SESSION_PARAMS); 162 163 // Setup the unit tests to have the default behavior of using the UWBS UCI version. 164 when(mUwbInjector.getFeatureFlags()).thenReturn(mFeatureFlags); 165 } 166 167 @Test testSetAppConfigurations()168 public void testSetAppConfigurations() throws Exception { 169 byte[] cfgStatus = {0x01, UwbUciConstants.STATUS_CODE_OK}; 170 UwbConfigStatusData appConfig = new UwbConfigStatusData(UwbUciConstants.STATUS_CODE_OK, 171 1, cfgStatus); 172 when(mNativeUwbManager.setAppConfigurations(anyInt(), anyInt(), anyInt(), 173 any(byte[].class), anyString())).thenReturn(appConfig); 174 175 DeviceConfigFacade mockDeviceConfig = mock(DeviceConfigFacade.class); 176 when(mockDeviceConfig.isAntennaModeConfigSupported()).thenReturn(false); 177 when(mUwbInjector.getDeviceConfigFacade()).thenReturn(mockDeviceConfig); 178 179 int status = mUwbConfigurationManager 180 .setAppConfigurations(mUwbSession.getSessionId(), mFiraParams, TEST_CHIP_ID, 181 PROTOCOL_VERSION_1_1); 182 183 verify(mNativeUwbManager).setAppConfigurations(anyInt(), anyInt(), anyInt(), 184 any(byte[].class), eq(TEST_CHIP_ID)); 185 assertEquals(UwbUciConstants.STATUS_CODE_OK, status); 186 } 187 188 @Test testSetAppConfigurations_radarSession()189 public void testSetAppConfigurations_radarSession() throws Exception { 190 byte[] cfgStatus = {0x01, UwbUciConstants.STATUS_CODE_OK}; 191 UwbConfigStatusData appConfig = new UwbConfigStatusData(UwbUciConstants.STATUS_CODE_OK, 192 1, cfgStatus); 193 when(mNativeUwbManager.setRadarAppConfigurations(anyInt(), anyInt(), anyInt(), 194 any(byte[].class), anyString())).thenReturn(appConfig); 195 196 int status = mUwbConfigurationManager.setAppConfigurations( 197 mRadarSession.getSessionId(), TEST_RADAR_OPEN_SESSION_PARAMS, TEST_CHIP_ID, 198 PROTOCOL_VERSION_1_1); 199 200 verify(mNativeUwbManager).setRadarAppConfigurations(anyInt(), anyInt(), anyInt(), 201 any(byte[].class), eq(TEST_CHIP_ID)); 202 assertEquals(UwbUciConstants.STATUS_CODE_OK, status); 203 } 204 205 @Test testGetAppConfigurations()206 public void testGetAppConfigurations() throws Exception { 207 byte[] tlvs = {0x01, 0x02, 0x02, 0x03}; 208 UwbTlvData getAppConfig = new UwbTlvData(UwbUciConstants.STATUS_CODE_OK, 1, tlvs); 209 when(mNativeUwbManager.getAppConfigurations(anyInt(), anyInt(), anyInt(), 210 any(byte[].class), anyString())).thenReturn(getAppConfig); 211 212 mUwbConfigurationManager.getAppConfigurations(mUwbSession.getSessionId(), 213 mFiraParams.getProtocolName(), new byte[0], FiraOpenSessionParams.class, 214 TEST_CHIP_ID, FiraParams.PROTOCOL_VERSION_1_1); 215 216 verify(mNativeUwbManager).getAppConfigurations(anyInt(), anyInt(), anyInt(), 217 any(byte[].class), eq(TEST_CHIP_ID)); 218 } 219 220 @Test testGetCapsInfo()221 public void testGetCapsInfo() throws Exception { 222 byte[] tlvs = {0x01, 0x02, 0x02, 0x03}; 223 UwbTlvData getAppConfig = new UwbTlvData(UwbUciConstants.STATUS_CODE_OK, 1, tlvs); 224 when(mNativeUwbManager.getCapsInfo(anyString())).thenReturn(getAppConfig); 225 226 mUwbConfigurationManager.getCapsInfo(mFiraParams.getProtocolName(), 227 FiraOpenSessionParams.class, TEST_CHIP_ID, any()); 228 229 verify(mNativeUwbManager).getCapsInfo(TEST_CHIP_ID); 230 } 231 232 @Test testSetRfTestAppConfigurations()233 public void testSetRfTestAppConfigurations() throws Exception { 234 byte[] cfgStatus = {0x01, UwbUciConstants.STATUS_CODE_OK}; 235 UwbConfigStatusData appConfig = new UwbConfigStatusData(UwbUciConstants.STATUS_CODE_OK, 236 1, cfgStatus); 237 when(mNativeUwbManager.setRfTestAppConfigurations(anyInt(), anyInt(), anyInt(), 238 any(byte[].class), anyString())).thenReturn(appConfig); 239 240 int status = mUwbConfigurationManager.setRfTestAppConfigurations( 241 mUwbSession.getSessionId(), TEST_RFTEST_OPEN_SESSION_PARAMS, TEST_CHIP_ID); 242 243 verify(mNativeUwbManager).setRfTestAppConfigurations(anyInt(), anyInt(), anyInt(), 244 any(byte[].class), eq(TEST_CHIP_ID)); 245 assertEquals(UwbUciConstants.STATUS_CODE_OK, status); 246 } 247 getFiraParams()248 private FiraOpenSessionParams getFiraParams() { 249 FiraProtocolVersion protocolVersion = FiraParams.PROTOCOL_VERSION_1_1; 250 int sessionId = 10; 251 int sessionType = SESSION_TYPE_RANGING; 252 int deviceType = RANGING_DEVICE_TYPE_CONTROLEE; 253 int deviceRole = RANGING_DEVICE_ROLE_INITIATOR; 254 int rangingRoundUsage = RANGING_ROUND_USAGE_SS_TWR_DEFERRED_MODE; 255 int multiNodeMode = MULTI_NODE_MODE_MANY_TO_MANY; 256 int addressMode = MAC_ADDRESS_MODE_8_BYTES; 257 UwbAddress deviceAddress = UwbAddress.fromBytes(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); 258 UwbAddress destAddress1 = UwbAddress.fromBytes(new byte[] {1, 2, 3, 4, 5, 6, 7, 8}); 259 UwbAddress destAddress2 = 260 UwbAddress.fromBytes(new byte[] {(byte) 0xFF, (byte) 0xFE, 3, 4, 5, 6, 7, 8}); 261 List<UwbAddress> destAddressList = new ArrayList<>(); 262 destAddressList.add(destAddress1); 263 destAddressList.add(destAddress2); 264 int initiationTime = 100; 265 int slotDurationRstu = 2400; 266 int slotsPerRangingRound = 10; 267 int rangingIntervalMs = 100; 268 int blockStrideLength = 2; 269 int maxRangingRoundRetries = 3; 270 int sessionPriority = 100; 271 boolean hasRangingResultReportMessage = true; 272 boolean hasControlMessage = true; 273 boolean hasRangingControlPhase = false; 274 int measurementReportType = MEASUREMENT_REPORT_TYPE_INITIATOR_TO_RESPONDER; 275 int inBandTerminationAttemptCount = 8; 276 int channelNumber = 10; 277 int preambleCodeIndex = 12; 278 int rframeConfig = RFRAME_CONFIG_SP1; 279 int prfMode = PRF_MODE_HPRF; 280 int preambleDuration = PREAMBLE_DURATION_T32_SYMBOLS; 281 int sfdId = SFD_ID_VALUE_3; 282 int stsSegmentCount = STS_SEGMENT_COUNT_VALUE_2; 283 int stsLength = STS_LENGTH_128_SYMBOLS; 284 byte[] sessionKey = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 285 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; 286 byte[] subsessionKey = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 287 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; 288 int psduDataRate = PSDU_DATA_RATE_7M80; 289 int bprfPhrDataRate = BPRF_PHR_DATA_RATE_6M81; 290 int fcsType = MAC_FCS_TYPE_CRC_32; 291 boolean isTxAdaptivePayloadPowerEnabled = true; 292 int stsConfig = STS_CONFIG_DYNAMIC_FOR_CONTROLEE_INDIVIDUAL_KEY; 293 int subSessionId = 24; 294 byte[] vendorId = new byte[] {(byte) 0xFE, (byte) 0xDC}; 295 byte[] staticStsIV = new byte[] {(byte) 0xDF, (byte) 0xCE, (byte) 0xAB, 0x12, 0x34, 0x56}; 296 boolean isKeyRotationEnabled = true; 297 int keyRotationRate = 15; 298 int aoaResultRequest = AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_INTERLEAVED; 299 int rangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE_PROXIMITY_LEVEL_TRIG; 300 int rangeDataNtfProximityNear = 50; 301 int rangeDataNtfProximityFar = 200; 302 boolean hasTimeOfFlightReport = true; 303 boolean hasAngleOfArrivalAzimuthReport = true; 304 boolean hasAngleOfArrivalElevationReport = true; 305 boolean hasAngleOfArrivalFigureOfMeritReport = true; 306 int aoaType = AOA_TYPE_AZIMUTH_AND_ELEVATION; 307 int numOfMsrmtFocusOnRange = 1; 308 int numOfMsrmtFocusOnAoaAzimuth = 2; 309 int numOfMsrmtFocusOnAoaElevation = 3; 310 311 FiraOpenSessionParams params = 312 new FiraOpenSessionParams.Builder() 313 .setProtocolVersion(protocolVersion) 314 .setSessionId(sessionId) 315 .setSessionType(sessionType) 316 .setDeviceType(deviceType) 317 .setDeviceRole(deviceRole) 318 .setRangingRoundUsage(rangingRoundUsage) 319 .setMultiNodeMode(multiNodeMode) 320 .setDeviceAddress(deviceAddress) 321 .setDestAddressList(destAddressList) 322 .setInitiationTime(initiationTime) 323 .setSlotDurationRstu(slotDurationRstu) 324 .setSlotsPerRangingRound(slotsPerRangingRound) 325 .setRangingIntervalMs(rangingIntervalMs) 326 .setBlockStrideLength(blockStrideLength) 327 .setMaxRangingRoundRetries(maxRangingRoundRetries) 328 .setSessionPriority(sessionPriority) 329 .setMacAddressMode(addressMode) 330 .setHasRangingResultReportMessage(hasRangingResultReportMessage) 331 .setHasControlMessage(hasControlMessage) 332 .setHasRangingControlPhase(hasRangingControlPhase) 333 .setMeasurementReportType(measurementReportType) 334 .setInBandTerminationAttemptCount(inBandTerminationAttemptCount) 335 .setChannelNumber(channelNumber) 336 .setPreambleCodeIndex(preambleCodeIndex) 337 .setRframeConfig(rframeConfig) 338 .setPrfMode(prfMode) 339 .setPreambleDuration(preambleDuration) 340 .setSfdId(sfdId) 341 .setStsSegmentCount(stsSegmentCount) 342 .setStsLength(stsLength) 343 .setSessionKey(sessionKey) 344 .setSubsessionKey(subsessionKey) 345 .setPsduDataRate(psduDataRate) 346 .setBprfPhrDataRate(bprfPhrDataRate) 347 .setFcsType(fcsType) 348 .setIsTxAdaptivePayloadPowerEnabled(isTxAdaptivePayloadPowerEnabled) 349 .setStsConfig(stsConfig) 350 .setSubSessionId(subSessionId) 351 .setVendorId(vendorId) 352 .setStaticStsIV(staticStsIV) 353 .setIsKeyRotationEnabled(isKeyRotationEnabled) 354 .setKeyRotationRate(keyRotationRate) 355 .setAoaResultRequest(aoaResultRequest) 356 .setRangeDataNtfConfig(rangeDataNtfConfig) 357 .setRangeDataNtfProximityNear(rangeDataNtfProximityNear) 358 .setRangeDataNtfProximityFar(rangeDataNtfProximityFar) 359 .setHasTimeOfFlightReport(hasTimeOfFlightReport) 360 .setHasAngleOfArrivalAzimuthReport(hasAngleOfArrivalAzimuthReport) 361 .setHasAngleOfArrivalElevationReport(hasAngleOfArrivalElevationReport) 362 .setHasAngleOfArrivalFigureOfMeritReport( 363 hasAngleOfArrivalFigureOfMeritReport) 364 .setAoaType(aoaType) 365 .setMeasurementFocusRatio( 366 numOfMsrmtFocusOnRange, 367 numOfMsrmtFocusOnAoaAzimuth, 368 numOfMsrmtFocusOnAoaElevation) 369 .build(); 370 return params; 371 } 372 } 373