1 /* 2 * Copyright (C) 2024 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.google.uwb.support; 18 19 import static org.junit.Assert.assertArrayEquals; 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertTrue; 22 23 import android.os.PersistableBundle; 24 25 import androidx.test.ext.junit.runners.AndroidJUnit4; 26 import androidx.test.filters.SmallTest; 27 28 import com.google.uwb.support.base.Params; 29 import com.google.uwb.support.aliro.AliroOpenRangingParams; 30 import com.google.uwb.support.aliro.AliroParams; 31 import com.google.uwb.support.aliro.AliroProtocolVersion; 32 import com.google.uwb.support.aliro.AliroPulseShapeCombo; 33 import com.google.uwb.support.aliro.AliroRangingError; 34 import com.google.uwb.support.aliro.AliroRangingReconfiguredParams; 35 import com.google.uwb.support.aliro.AliroRangingStartedParams; 36 import com.google.uwb.support.aliro.AliroSpecificationParams; 37 import com.google.uwb.support.aliro.AliroStartRangingParams; 38 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.util.List; 43 44 @SmallTest 45 @RunWith(AndroidJUnit4.class) 46 public class AliroTests { 47 private static final AliroProtocolVersion[] PROTOCOL_VERSIONS = 48 new AliroProtocolVersion[] { 49 new AliroProtocolVersion(1, 0), 50 new AliroProtocolVersion(2, 0), 51 new AliroProtocolVersion(2, 1) 52 }; 53 54 private static final Integer[] UWB_CONFIGS = 55 new Integer[] {AliroParams.UWB_CONFIG_0, AliroParams.UWB_CONFIG_1}; 56 private static final AliroPulseShapeCombo[] PULSE_SHAPE_COMBOS = 57 new AliroPulseShapeCombo[] { 58 new AliroPulseShapeCombo( 59 AliroParams.PULSE_SHAPE_SYMMETRICAL_ROOT_RAISED_COSINE, 60 AliroParams.PULSE_SHAPE_SYMMETRICAL_ROOT_RAISED_COSINE), 61 new AliroPulseShapeCombo( 62 AliroParams.PULSE_SHAPE_PRECURSOR_FREE, 63 AliroParams.PULSE_SHAPE_PRECURSOR_FREE), 64 new AliroPulseShapeCombo( 65 AliroParams.PULSE_SHAPE_PRECURSOR_FREE_SPECIAL, 66 AliroParams.PULSE_SHAPE_PRECURSOR_FREE_SPECIAL) 67 }; 68 private static final int RAN_MULTIPLIER = 200; 69 private static final Integer[] CHAPS_PER_SLOTS = 70 new Integer[] {AliroParams.CHAPS_PER_SLOT_4, AliroParams.CHAPS_PER_SLOT_12}; 71 private static final Integer[] SYNC_CODES = new Integer[] {10, 23}; 72 private static final Integer[] CHANNELS = 73 new Integer[] {AliroParams.UWB_CHANNEL_5, AliroParams.UWB_CHANNEL_9}; 74 private static final Integer[] HOPPING_CONFIG_MODES = 75 new Integer[] { 76 AliroParams.HOPPING_CONFIG_MODE_ADAPTIVE, 77 AliroParams.HOPPING_CONFIG_MODE_CONTINUOUS 78 }; 79 private static final Integer[] HOPPING_SEQUENCES = 80 new Integer[] {AliroParams.HOPPING_SEQUENCE_AES, AliroParams.HOPPING_SEQUENCE_DEFAULT}; 81 82 @Test testOpenRangingParams()83 public void testOpenRangingParams() { 84 AliroProtocolVersion protocolVersion = AliroParams.PROTOCOL_VERSION_1_0; 85 @AliroParams.UwbConfig int uwbConfig = AliroParams.UWB_CONFIG_1; 86 AliroPulseShapeCombo pulseShapeCombo = 87 new AliroPulseShapeCombo( 88 AliroParams.PULSE_SHAPE_PRECURSOR_FREE, 89 AliroParams.PULSE_SHAPE_PRECURSOR_FREE); 90 int sessionId = 10; 91 int ranMultiplier = 128; 92 @AliroParams.Channel int channel = AliroParams.UWB_CHANNEL_9; 93 @AliroParams.ChapsPerSlot int chapsPerSlot = AliroParams.CHAPS_PER_SLOT_6; 94 int numResponderNodes = 9; 95 @AliroParams.SlotsPerRound int numSlotsPerRound = AliroParams.SLOTS_PER_ROUND_12; 96 @AliroParams.SyncCodeIndex int syncCodeIdx = 22; 97 @AliroParams.HoppingConfigMode int hoppingConfigMode = 98 AliroParams.HOPPING_CONFIG_MODE_ADAPTIVE; 99 @AliroParams.HoppingSequence int hoppingSequence = AliroParams.HOPPING_SEQUENCE_AES; 100 long absoluteInitiationTimeUs = 20_000L; 101 int rangeDataNtfConfig = AliroParams.RANGE_DATA_NTF_CONFIG_ENABLE; 102 int rangeDataNtfProximityNear = 100; 103 int rangeDataNtfProximityFar = 200; 104 double rangeDataNtfAoaAzimuthLower = -0.7; 105 double rangeDataNtfAoaAzimuthUpper = +1.3; 106 double rangeDataNtfAoaElevationLower = -1.1; 107 double rangeDataNtfAoaElevationUpper = +1.2; 108 109 AliroOpenRangingParams params = 110 new AliroOpenRangingParams.Builder() 111 .setProtocolVersion(protocolVersion) 112 .setUwbConfig(uwbConfig) 113 .setPulseShapeCombo(pulseShapeCombo) 114 .setSessionId(sessionId) 115 .setRanMultiplier(ranMultiplier) 116 .setChannel(channel) 117 .setNumChapsPerSlot(chapsPerSlot) 118 .setNumResponderNodes(numResponderNodes) 119 .setNumSlotsPerRound(numSlotsPerRound) 120 .setSyncCodeIndex(syncCodeIdx) 121 .setHoppingConfigMode(hoppingConfigMode) 122 .setHoppingSequence(hoppingSequence) 123 .setAbsoluteInitiationTimeUs(absoluteInitiationTimeUs) 124 .setRangeDataNtfConfig(rangeDataNtfConfig) 125 .setRangeDataNtfProximityNear(rangeDataNtfProximityNear) 126 .setRangeDataNtfProximityFar(rangeDataNtfProximityFar) 127 .setRangeDataNtfAoaAzimuthLower(rangeDataNtfAoaAzimuthLower) 128 .setRangeDataNtfAoaAzimuthUpper(rangeDataNtfAoaAzimuthUpper) 129 .setRangeDataNtfAoaElevationLower(rangeDataNtfAoaElevationLower) 130 .setRangeDataNtfAoaElevationUpper(rangeDataNtfAoaElevationUpper) 131 .build(); 132 133 assertEquals(params.getProtocolVersion(), protocolVersion); 134 assertEquals(params.getUwbConfig(), uwbConfig); 135 assertEquals( 136 params.getPulseShapeCombo().getInitiatorTx(), pulseShapeCombo.getInitiatorTx()); 137 assertEquals( 138 params.getPulseShapeCombo().getResponderTx(), pulseShapeCombo.getResponderTx()); 139 assertEquals(params.getSessionId(), sessionId); 140 assertEquals(params.getSessionType(), AliroParams.SESSION_TYPE_ALIRO); 141 assertEquals(params.getRanMultiplier(), ranMultiplier); 142 assertEquals(params.getChannel(), channel); 143 assertEquals(params.getNumChapsPerSlot(), chapsPerSlot); 144 assertEquals(params.getNumResponderNodes(), numResponderNodes); 145 assertEquals(params.getNumSlotsPerRound(), numSlotsPerRound); 146 assertEquals(params.getSyncCodeIndex(), syncCodeIdx); 147 assertEquals(params.getHoppingConfigMode(), hoppingConfigMode); 148 assertEquals(params.getHoppingSequence(), hoppingSequence); 149 assertEquals(params.getAbsoluteInitiationTimeUs(), absoluteInitiationTimeUs); 150 151 AliroOpenRangingParams fromBundle = AliroOpenRangingParams.fromBundle(params.toBundle()); 152 assertEquals(fromBundle.getProtocolVersion(), protocolVersion); 153 assertEquals(fromBundle.getUwbConfig(), uwbConfig); 154 assertEquals( 155 fromBundle.getPulseShapeCombo().getInitiatorTx(), pulseShapeCombo.getInitiatorTx()); 156 assertEquals( 157 fromBundle.getPulseShapeCombo().getResponderTx(), pulseShapeCombo.getResponderTx()); 158 assertEquals(fromBundle.getSessionId(), sessionId); 159 assertEquals(fromBundle.getRanMultiplier(), ranMultiplier); 160 assertEquals(fromBundle.getChannel(), channel); 161 assertEquals(fromBundle.getNumChapsPerSlot(), chapsPerSlot); 162 assertEquals(fromBundle.getNumResponderNodes(), numResponderNodes); 163 assertEquals(fromBundle.getNumSlotsPerRound(), numSlotsPerRound); 164 assertEquals(fromBundle.getSyncCodeIndex(), syncCodeIdx); 165 assertEquals(fromBundle.getHoppingConfigMode(), hoppingConfigMode); 166 assertEquals(fromBundle.getHoppingSequence(), hoppingSequence); 167 assertEquals(fromBundle.getAbsoluteInitiationTimeUs(), absoluteInitiationTimeUs); 168 assertEquals(fromBundle.getRangeDataNtfConfig(), rangeDataNtfConfig); 169 assertEquals(fromBundle.getRangeDataNtfProximityNear(), rangeDataNtfProximityNear); 170 assertEquals(fromBundle.getRangeDataNtfProximityFar(), rangeDataNtfProximityFar); 171 assertEquals( 172 fromBundle.getRangeDataNtfAoaAzimuthLower(), rangeDataNtfAoaAzimuthLower, 0.1d); 173 assertEquals( 174 fromBundle.getRangeDataNtfAoaAzimuthUpper(), rangeDataNtfAoaAzimuthUpper, 0.1d); 175 assertEquals( 176 fromBundle.getRangeDataNtfAoaElevationLower(), rangeDataNtfAoaElevationLower, 0.1d); 177 assertEquals( 178 fromBundle.getRangeDataNtfAoaElevationUpper(), rangeDataNtfAoaElevationUpper, 0.1d); 179 180 verifyProtocolPresent(params); 181 verifyBundlesEqual(params, fromBundle); 182 } 183 184 @Test testRangingError()185 public void testRangingError() { 186 @AliroParams.ProtocolError int error = AliroParams.PROTOCOL_ERROR_SE_BUSY; 187 AliroRangingError params = new AliroRangingError.Builder().setError(error).build(); 188 189 assertEquals(params.getError(), error); 190 191 AliroRangingError fromBundle = AliroRangingError.fromBundle(params.toBundle()); 192 assertEquals(fromBundle.getError(), error); 193 194 verifyProtocolPresent(params); 195 verifyBundlesEqual(params, fromBundle); 196 } 197 198 @Test testRangingReconfiguredParams()199 public void testRangingReconfiguredParams() { 200 AliroRangingReconfiguredParams params = 201 new AliroRangingReconfiguredParams.Builder().build(); 202 203 AliroRangingReconfiguredParams fromBundle = 204 AliroRangingReconfiguredParams.fromBundle(params.toBundle()); 205 206 verifyProtocolPresent(params); 207 verifyBundlesEqual(params, fromBundle); 208 } 209 210 @Test testStartRangingParams()211 public void testStartRangingParams() { 212 int sessionId = 10; 213 int ranMultiplier = 128; 214 long initiationTimeMs = 10; 215 long absoluteInitiationTimeUs = 15_000L; 216 217 AliroStartRangingParams params = 218 new AliroStartRangingParams.Builder() 219 .setSessionId(sessionId) 220 .setRanMultiplier(ranMultiplier) 221 .setInitiationTimeMs(initiationTimeMs) 222 .setAbsoluteInitiationTimeUs(absoluteInitiationTimeUs) 223 .build(); 224 225 assertEquals(params.getSessionId(), sessionId); 226 assertEquals(params.getRanMultiplier(), ranMultiplier); 227 assertEquals(params.getInitiationTimeMs(), initiationTimeMs); 228 assertEquals(params.getAbsoluteInitiationTimeUs(), absoluteInitiationTimeUs); 229 230 AliroStartRangingParams fromBundle = AliroStartRangingParams.fromBundle(params.toBundle()); 231 232 assertEquals(fromBundle.getSessionId(), sessionId); 233 assertEquals(fromBundle.getRanMultiplier(), ranMultiplier); 234 assertEquals(fromBundle.getInitiationTimeMs(), initiationTimeMs); 235 assertEquals(fromBundle.getAbsoluteInitiationTimeUs(), absoluteInitiationTimeUs); 236 237 verifyProtocolPresent(params); 238 verifyBundlesEqual(params, fromBundle); 239 } 240 241 @Test testRangingStartedParams()242 public void testRangingStartedParams() { 243 int hopModeKey = 98876444; 244 int startingStsIndex = 246802468; 245 @AliroParams.SyncCodeIndex int syncCodeIndex = 10; 246 long uwbTime0 = 50; 247 int ranMultiplier = 10; 248 249 AliroRangingStartedParams params = 250 new AliroRangingStartedParams.Builder() 251 .setHopModeKey(hopModeKey) 252 .setStartingStsIndex(startingStsIndex) 253 .setSyncCodeIndex(syncCodeIndex) 254 .setUwbTime0(uwbTime0) 255 .setRanMultiplier(ranMultiplier) 256 .build(); 257 258 assertEquals(params.getHopModeKey(), hopModeKey); 259 assertEquals(params.getStartingStsIndex(), startingStsIndex); 260 assertEquals(params.getSyncCodeIndex(), syncCodeIndex); 261 assertEquals(params.getUwbTime0(), uwbTime0); 262 assertEquals(params.getRanMultiplier(), ranMultiplier); 263 264 AliroRangingStartedParams fromBundle = 265 AliroRangingStartedParams.fromBundle(params.toBundle()); 266 267 assertEquals(fromBundle.getHopModeKey(), hopModeKey); 268 assertEquals(fromBundle.getStartingStsIndex(), startingStsIndex); 269 assertEquals(fromBundle.getSyncCodeIndex(), syncCodeIndex); 270 assertEquals(fromBundle.getUwbTime0(), uwbTime0); 271 assertEquals(fromBundle.getRanMultiplier(), ranMultiplier); 272 273 verifyProtocolPresent(params); 274 verifyBundlesEqual(params, fromBundle); 275 } 276 277 @Test testSpecificationParams()278 public void testSpecificationParams() { 279 AliroSpecificationParams.Builder paramsBuilder = new AliroSpecificationParams.Builder(); 280 for (AliroProtocolVersion p : PROTOCOL_VERSIONS) { 281 paramsBuilder.addProtocolVersion(p); 282 } 283 284 for (int uwbConfig : UWB_CONFIGS) { 285 paramsBuilder.addUwbConfig(uwbConfig); 286 } 287 288 for (AliroPulseShapeCombo pulseShapeCombo : PULSE_SHAPE_COMBOS) { 289 paramsBuilder.addPulseShapeCombo(pulseShapeCombo); 290 } 291 292 paramsBuilder.setRanMultiplier(RAN_MULTIPLIER); 293 294 for (int chapsPerSlot : CHAPS_PER_SLOTS) { 295 paramsBuilder.addChapsPerSlot(chapsPerSlot); 296 } 297 298 for (int syncCode : SYNC_CODES) { 299 paramsBuilder.addSyncCode(syncCode); 300 } 301 302 for (int channel : CHANNELS) { 303 paramsBuilder.addChannel(channel); 304 } 305 306 for (int hoppingConfigMode : HOPPING_CONFIG_MODES) { 307 paramsBuilder.addHoppingConfigMode(hoppingConfigMode); 308 } 309 310 for (int hoppingSequence : HOPPING_SEQUENCES) { 311 paramsBuilder.addHoppingSequence(hoppingSequence); 312 } 313 314 AliroSpecificationParams params = paramsBuilder.build(); 315 assertArrayEquals(params.getProtocolVersions().toArray(), PROTOCOL_VERSIONS); 316 assertArrayEquals(params.getUwbConfigs().toArray(), UWB_CONFIGS); 317 assertArrayEquals(params.getPulseShapeCombos().toArray(), PULSE_SHAPE_COMBOS); 318 assertEquals(params.getRanMultiplier(), RAN_MULTIPLIER); 319 assertArrayEquals(params.getChapsPerSlot().toArray(), CHAPS_PER_SLOTS); 320 assertArrayEquals(params.getSyncCodes().toArray(), SYNC_CODES); 321 assertArrayEquals(params.getChannels().toArray(), CHANNELS); 322 assertArrayEquals(params.getHoppingConfigModes().toArray(), HOPPING_CONFIG_MODES); 323 assertArrayEquals(params.getHoppingSequences().toArray(), HOPPING_SEQUENCES); 324 325 AliroSpecificationParams fromBundle = 326 AliroSpecificationParams.fromBundle(params.toBundle()); 327 assertArrayEquals(fromBundle.getProtocolVersions().toArray(), PROTOCOL_VERSIONS); 328 assertArrayEquals(fromBundle.getUwbConfigs().toArray(), UWB_CONFIGS); 329 assertArrayEquals(fromBundle.getPulseShapeCombos().toArray(), PULSE_SHAPE_COMBOS); 330 assertEquals(fromBundle.getRanMultiplier(), RAN_MULTIPLIER); 331 assertArrayEquals(fromBundle.getChapsPerSlot().toArray(), CHAPS_PER_SLOTS); 332 assertArrayEquals(fromBundle.getSyncCodes().toArray(), SYNC_CODES); 333 assertArrayEquals(fromBundle.getChannels().toArray(), CHANNELS); 334 assertArrayEquals(fromBundle.getHoppingConfigModes().toArray(), HOPPING_CONFIG_MODES); 335 assertArrayEquals(fromBundle.getHoppingSequences().toArray(), HOPPING_SEQUENCES); 336 337 verifyProtocolPresent(params); 338 assertTrue(params.equals(fromBundle)); 339 340 // Add random channel to params builder to force inequality. 341 paramsBuilder.addChannel(0); 342 // Rebuild params. 343 params = paramsBuilder.build(); 344 // Test that params and fromBundle are not equal. 345 assertTrue(!params.equals(fromBundle)); 346 } 347 348 @Test testSpecificationParams_whenNoChannelsSet()349 public void testSpecificationParams_whenNoChannelsSet() { 350 AliroSpecificationParams.Builder paramsBuilder = new AliroSpecificationParams.Builder(); 351 for (AliroProtocolVersion p : PROTOCOL_VERSIONS) { 352 paramsBuilder.addProtocolVersion(p); 353 } 354 for (int uwbConfig : UWB_CONFIGS) { 355 paramsBuilder.addUwbConfig(uwbConfig); 356 } 357 for (AliroPulseShapeCombo pulseShapeCombo : PULSE_SHAPE_COMBOS) { 358 paramsBuilder.addPulseShapeCombo(pulseShapeCombo); 359 } 360 paramsBuilder.setRanMultiplier(RAN_MULTIPLIER); 361 for (int chapsPerSlot : CHAPS_PER_SLOTS) { 362 paramsBuilder.addChapsPerSlot(chapsPerSlot); 363 } 364 for (int syncCode : SYNC_CODES) { 365 paramsBuilder.addSyncCode(syncCode); 366 } 367 for (int hoppingConfigMode : HOPPING_CONFIG_MODES) { 368 paramsBuilder.addHoppingConfigMode(hoppingConfigMode); 369 } 370 for (int hoppingSequence : HOPPING_SEQUENCES) { 371 paramsBuilder.addHoppingSequence(hoppingSequence); 372 } 373 AliroSpecificationParams params = paramsBuilder.build(); 374 assertEquals(List.of(), params.getChannels()); 375 376 AliroSpecificationParams fromBundle = 377 AliroSpecificationParams.fromBundle(params.toBundle()); 378 assertEquals(List.of(), fromBundle.getChannels()); 379 } 380 verifyProtocolPresent(Params params)381 private void verifyProtocolPresent(Params params) { 382 assertTrue(Params.isProtocol(params.toBundle(), AliroParams.PROTOCOL_NAME)); 383 } 384 verifyBundlesEqual(Params params, Params fromBundle)385 private void verifyBundlesEqual(Params params, Params fromBundle) { 386 assertTrue(PersistableBundle.kindofEquals(params.toBundle(), fromBundle.toBundle())); 387 } 388 } 389