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