1 /* 2 * Copyright (C) 2022 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.secure.csml; 18 19 import static com.android.server.uwb.config.CapabilityParam.AOA_AZIMUTH_180; 20 import static com.android.server.uwb.config.CapabilityParam.AOA_AZIMUTH_90; 21 import static com.android.server.uwb.config.CapabilityParam.AOA_ELEVATION; 22 import static com.android.server.uwb.config.CapabilityParam.AOA_FOM; 23 24 import android.uwb.UwbAddress; 25 26 import androidx.annotation.NonNull; 27 import androidx.annotation.Nullable; 28 29 import com.android.server.uwb.params.TlvBuffer; 30 import com.android.server.uwb.params.TlvDecoderBuffer; 31 32 import com.google.uwb.support.fira.FiraParams; 33 import com.google.uwb.support.fira.FiraProtocolVersion; 34 35 import java.nio.ByteBuffer; 36 import java.util.EnumSet; 37 import java.util.Optional; 38 39 /** 40 * CONFIGURATION_PARAMS defined in 8.5.3.3. 41 */ 42 public class ConfigurationParams { 43 44 public static final int FIRA_PHY_VERSION = 0x80; 45 public static final int FIRA_MAC_VERSION = 0x81; 46 public static final int DEVICE_ROLES = 0x82; 47 public static final int RANGING_METHOD = 0x83; 48 public static final int STS_CONFIG = 0x84; 49 public static final int MULTI_NODE_MODE = 0x85; 50 public static final int RANGING_TIME_STRUCT = 0x86; 51 public static final int SCHEDULED_MODE = 0x87; 52 public static final int HOPPING_MODE = 0x88; 53 public static final int BLOCK_STRIDING = 0x89; 54 public static final int UWB_INITIATION_TIME = 0x8A; 55 public static final int CHANNEL = 0x8B; 56 public static final int RFRAME_CONFIG = 0x8C; 57 public static final int CC_CONSTRAINT_LENGTH = 0x8D; 58 public static final int PRF_MODE = 0X8E; 59 public static final int SP0_PHY_SET = 0x8F; 60 public static final int SP1_PHY_SET = 0x90; 61 public static final int SP3_PHY_SET = 0x91; 62 public static final int PREAMBLE_CODE_INDEX = 0x92; 63 public static final int RESULT_REPORT_CONFIG = 0x93; 64 public static final int MAC_ADDRESS_MODE = 0x94; 65 public static final int CONTROLEE_SHORT_MAC_ADDRESS = 0x95; 66 public static final int CONTROLLER_MAC_ADDRESS = 0x96; 67 public static final int SLOTS_PER_RR = 0x97; 68 public static final int MAX_CONTENTION_PHASE_LENGTH = 0x98; 69 public static final int SLOT_DURATION = 0x99; 70 public static final int RANGING_INTERVAL = 0x9A; 71 public static final int KEY_ROTATION_RATE = 0x9B; 72 public static final int MAC_FCS_TYPE = 0x9C; 73 public static final int MAX_RR_RETRY = 0x9D; 74 public static final int CONFIGURATION_PARAMS_MAX_COUNT = 30; 75 76 public final FiraProtocolVersion mPhyVersion; 77 public final FiraProtocolVersion mMacVersion; 78 public final Optional<Integer> mDeviceRole; 79 public final Optional<Integer> mRangingMethod; 80 public final Optional<Integer> mStsConfig; 81 public final Optional<Integer> mMultiNodeMode; 82 public final Optional<Byte> mRangingTimeStruct; 83 public final Optional<Integer> mScheduleMode; 84 public final Optional<Boolean> mHoppingMode; 85 public final Optional<Boolean> mBlockStriding; 86 public final Optional<Boolean> mUwbInitiationTime; 87 public final Optional<Integer> mChannel; 88 public final Optional<Integer> mRframeConfig; 89 public final Optional<Integer> mCcConstraintLength; 90 public final Optional<Integer> mPrfMode; 91 public final Optional<Integer> mSp0PhyParameterSet; 92 public final Optional<Integer> mSp1PhyParameterSet; 93 public final Optional<Integer> mSp3PhyParameterSet; 94 public final Optional<Integer> mPreambleCodeIndex; 95 public final Optional<EnumSet<FiraParams.AoaCapabilityFlag>> mResultReportConfig; 96 public final Optional<Integer> mMacAddressMode; 97 public final Optional<UwbAddress> mControleeShortMacAddress; 98 public final Optional<UwbAddress> mControllerMacAddress; 99 public final Optional<Integer> mSlotsPerRangingRound; 100 public final Optional<Integer> mMaxContentionPhaseLength; 101 public final Optional<Integer> mSlotDuration; 102 public final Optional<Integer> mRangingIntervalMs; 103 public final Optional<Integer> mKeyRotationRate; 104 public final Optional<Integer> mMacFcsType; 105 public final Optional<Integer> mMaxRangingRoundRetry; 106 ConfigurationParams( FiraProtocolVersion phyVersion, FiraProtocolVersion macVersion, Optional<Integer> deviceRole, Optional<Integer> rangingMethod, Optional<Integer> stsConfig, Optional<Integer> multiNodeMode, Optional<Byte> rangingTimeStruct, Optional<Integer> scheduleMode, Optional<Boolean> hoppingMode, Optional<Boolean> blockStriding, Optional<Boolean> uwbInitiationTime, Optional<Integer> channel, Optional<Integer> rframeConfig, Optional<Integer> ccConstraintLength, Optional<Integer> prfMode, Optional<Integer> sp0PhyParameterSet, Optional<Integer> sp1PhyParameterSet, Optional<Integer> sp3PhyParameterSet, Optional<Integer> preambleCodeIndex, Optional<EnumSet<FiraParams.AoaCapabilityFlag>> resultReportConfig, Optional<Integer> macAddressMode, Optional<UwbAddress> controleeShortMacAddress, Optional<UwbAddress> controllerMacAddress, Optional<Integer> slotsPerRangingRound, Optional<Integer> maxContentionPhaseLength, Optional<Integer> slotDuration, Optional<Integer> rangingIntervalMs, Optional<Integer> keyRotationRate, Optional<Integer> macFcsType, Optional<Integer> maxRangingRoundRetry)107 public ConfigurationParams( 108 FiraProtocolVersion phyVersion, 109 FiraProtocolVersion macVersion, 110 Optional<Integer> deviceRole, 111 Optional<Integer> rangingMethod, 112 Optional<Integer> stsConfig, 113 Optional<Integer> multiNodeMode, 114 Optional<Byte> rangingTimeStruct, Optional<Integer> scheduleMode, 115 Optional<Boolean> hoppingMode, Optional<Boolean> blockStriding, 116 Optional<Boolean> uwbInitiationTime, 117 Optional<Integer> channel, 118 Optional<Integer> rframeConfig, 119 Optional<Integer> ccConstraintLength, 120 Optional<Integer> prfMode, 121 Optional<Integer> sp0PhyParameterSet, 122 Optional<Integer> sp1PhyParameterSet, 123 Optional<Integer> sp3PhyParameterSet, 124 Optional<Integer> preambleCodeIndex, 125 Optional<EnumSet<FiraParams.AoaCapabilityFlag>> resultReportConfig, 126 Optional<Integer> macAddressMode, 127 Optional<UwbAddress> controleeShortMacAddress, 128 Optional<UwbAddress> controllerMacAddress, 129 Optional<Integer> slotsPerRangingRound, 130 Optional<Integer> maxContentionPhaseLength, 131 Optional<Integer> slotDuration, 132 Optional<Integer> rangingIntervalMs, 133 Optional<Integer> keyRotationRate, 134 Optional<Integer> macFcsType, 135 Optional<Integer> maxRangingRoundRetry) { 136 mPhyVersion = phyVersion; 137 mMacVersion = macVersion; 138 mDeviceRole = deviceRole; 139 mRangingMethod = rangingMethod; 140 mStsConfig = stsConfig; 141 mMultiNodeMode = multiNodeMode; 142 mRangingTimeStruct = rangingTimeStruct; 143 mScheduleMode = scheduleMode; 144 mHoppingMode = hoppingMode; 145 mBlockStriding = blockStriding; 146 mUwbInitiationTime = uwbInitiationTime; 147 mChannel = channel; 148 mRframeConfig = rframeConfig; 149 mCcConstraintLength = ccConstraintLength; 150 mPrfMode = prfMode; 151 mSp0PhyParameterSet = sp0PhyParameterSet; 152 mSp1PhyParameterSet = sp1PhyParameterSet; 153 mSp3PhyParameterSet = sp3PhyParameterSet; 154 mPreambleCodeIndex = preambleCodeIndex; 155 mResultReportConfig = resultReportConfig; 156 mMacAddressMode = macAddressMode; 157 mControleeShortMacAddress = controleeShortMacAddress; 158 mControllerMacAddress = controllerMacAddress; 159 mSlotsPerRangingRound = slotsPerRangingRound; 160 mMaxContentionPhaseLength = maxContentionPhaseLength; 161 mSlotDuration = slotDuration; 162 mRangingIntervalMs = rangingIntervalMs; 163 mKeyRotationRate = keyRotationRate; 164 mMacFcsType = macFcsType; 165 mMaxRangingRoundRetry = maxRangingRoundRetry; 166 } 167 168 /** 169 * Converts the UwbCapabilities to the bytes which are combined per the TLV of CSML 8.5.3.2. 170 */ 171 @NonNull toBytes()172 byte[] toBytes() { 173 TlvBuffer.Builder configParamsBuilder = new TlvBuffer.Builder() 174 .putByteArray(FIRA_PHY_VERSION, new byte[]{ 175 (byte) mPhyVersion.getMajor(), 176 (byte) mPhyVersion.getMinor(), 177 }) 178 .putByteArray(FIRA_MAC_VERSION, new byte[]{ 179 (byte) mMacVersion.getMajor(), 180 (byte) mMacVersion.getMinor(), 181 }); 182 183 mDeviceRole.ifPresent(integer -> configParamsBuilder.putByte(DEVICE_ROLES, 184 integer.byteValue())); 185 186 mRangingMethod.ifPresent(integer -> configParamsBuilder.putByte(RANGING_METHOD, 187 integer.byteValue())); 188 189 //configParamsBuilder.putByte(RANGING_METHOD,(byte) HAS_DS_TWR_SUPPORT.getValue()); 190 191 mStsConfig.ifPresent( 192 integer -> configParamsBuilder.putByte(STS_CONFIG, integer.byteValue())); 193 194 mMultiNodeMode.ifPresent( 195 integer -> configParamsBuilder.putByte(MULTI_NODE_MODE, integer.byteValue())); 196 197 mRangingTimeStruct.ifPresent( 198 aByte -> configParamsBuilder.putByte(RANGING_TIME_STRUCT, aByte)); 199 200 mScheduleMode.ifPresent( 201 integer -> configParamsBuilder.putByte(SCHEDULED_MODE, integer.byteValue())); 202 203 mHoppingMode.ifPresent(aBoolean -> configParamsBuilder.putByte(HOPPING_MODE, 204 (byte) (aBoolean ? 1 : 0))); 205 206 mBlockStriding.ifPresent(aBoolean -> configParamsBuilder.putByte(BLOCK_STRIDING, 207 (byte) (aBoolean ? 1 : 0))); 208 209 mUwbInitiationTime.ifPresent(aBoolean -> configParamsBuilder.putByte(UWB_INITIATION_TIME, 210 (byte) (aBoolean ? 1 : 0))); 211 212 mChannel.ifPresent(integer -> configParamsBuilder.putByte(CHANNEL, integer.byteValue())); 213 214 mRframeConfig.ifPresent(integer -> configParamsBuilder.putByte(RFRAME_CONFIG, 215 integer.byteValue())); 216 217 mCcConstraintLength.ifPresent( 218 cccLen -> configParamsBuilder.putByte(CC_CONSTRAINT_LENGTH, cccLen.byteValue())); 219 220 mPrfMode.ifPresent(integer -> configParamsBuilder.putByte(PRF_MODE, integer.byteValue())); 221 222 mSp0PhyParameterSet.ifPresent(integer -> configParamsBuilder.putByte(SP0_PHY_SET, 223 integer.byteValue())); 224 225 mSp1PhyParameterSet.ifPresent(integer -> configParamsBuilder.putByte(SP1_PHY_SET, 226 integer.byteValue())); 227 228 mSp3PhyParameterSet.ifPresent(integer -> configParamsBuilder.putByte(SP3_PHY_SET, 229 integer.byteValue())); 230 231 mPreambleCodeIndex.ifPresent( 232 integer -> configParamsBuilder.putByte(PREAMBLE_CODE_INDEX, integer.byteValue())); 233 234 mPreambleCodeIndex.ifPresent( 235 integer -> configParamsBuilder.putByte(PREAMBLE_CODE_INDEX, integer.byteValue())); 236 237 if (mResultReportConfig.isPresent()) { 238 byte resultReportConfig = 0; 239 if (mResultReportConfig.get().contains( 240 FiraParams.AoaCapabilityFlag.HAS_AZIMUTH_SUPPORT)) { 241 resultReportConfig = (byte) (resultReportConfig | AOA_AZIMUTH_90); 242 } 243 if (mResultReportConfig.get().contains( 244 FiraParams.AoaCapabilityFlag.HAS_FULL_AZIMUTH_SUPPORT)) { 245 resultReportConfig = (byte) (resultReportConfig | AOA_AZIMUTH_180); 246 } 247 if (mResultReportConfig.get().contains( 248 FiraParams.AoaCapabilityFlag.HAS_ELEVATION_SUPPORT)) { 249 resultReportConfig = (byte) (resultReportConfig | AOA_ELEVATION); 250 } 251 if (mResultReportConfig.get().contains(FiraParams.AoaCapabilityFlag.HAS_FOM_SUPPORT)) { 252 resultReportConfig = (byte) (resultReportConfig | AOA_FOM); 253 } 254 configParamsBuilder.putByte(RESULT_REPORT_CONFIG, resultReportConfig); 255 } 256 257 mMacAddressMode.ifPresent( 258 integer -> configParamsBuilder.putByte(MAC_ADDRESS_MODE, integer.byteValue())); 259 260 mControleeShortMacAddress.ifPresent( 261 uwbAddress -> configParamsBuilder.putByteArray(CONTROLEE_SHORT_MAC_ADDRESS, 262 uwbAddress.toBytes())); 263 264 mControllerMacAddress.ifPresent( 265 uwbAddress -> configParamsBuilder.putByteArray(CONTROLLER_MAC_ADDRESS, 266 uwbAddress.toBytes())); 267 268 mSlotsPerRangingRound.ifPresent( 269 integer -> configParamsBuilder.putByte(SLOTS_PER_RR, integer.byteValue())); 270 271 mMaxContentionPhaseLength.ifPresent( 272 integer -> configParamsBuilder.putByte(MAX_CONTENTION_PHASE_LENGTH, 273 integer.byteValue())); 274 275 mSlotDuration.ifPresent( 276 integer -> configParamsBuilder.putByteArray(SLOT_DURATION, ByteBuffer.allocate( 277 2).putInt( 278 integer).array())); 279 280 mRangingIntervalMs.ifPresent( 281 integer -> configParamsBuilder.putByteArray(RANGING_INTERVAL, ByteBuffer.allocate( 282 2).putInt( 283 integer).array())); 284 285 mKeyRotationRate.ifPresent( 286 integer -> configParamsBuilder.putByte(KEY_ROTATION_RATE, 287 mKeyRotationRate.get().byteValue())); 288 289 mMacFcsType.ifPresent( 290 integer -> configParamsBuilder.putByte(MAC_ADDRESS_MODE, 291 mMacFcsType.get().byteValue())); 292 293 mMaxRangingRoundRetry.ifPresent( 294 integer -> configParamsBuilder.putByteArray(MAX_RR_RETRY, ByteBuffer.allocate( 295 2).putInt( 296 integer).array())); 297 298 return configParamsBuilder.build().getByteArray(); 299 } 300 301 isBitSet(int flags, int mask)302 private static boolean isBitSet(int flags, int mask) { 303 return (flags & mask) != 0; 304 } 305 isPresent(TlvDecoderBuffer tlvDecoderBuffer, int tagType)306 private static boolean isPresent(TlvDecoderBuffer tlvDecoderBuffer, int tagType) { 307 try { 308 tlvDecoderBuffer.getByte(tagType); 309 } catch (IllegalArgumentException e) { 310 try { 311 tlvDecoderBuffer.getByteArray(tagType); 312 } catch (IllegalArgumentException e1) { 313 return false; 314 } 315 } 316 return true; 317 } 318 319 /** 320 * Converts the UwbCapabilities from the data stream, which is encoded per the CSML 8.5.3.2. 321 * 322 * @return null if the data cannot be decoded per spec. 323 */ 324 @Nullable fromBytes(@onNull byte[] data)325 static ConfigurationParams fromBytes(@NonNull byte[] data) { 326 TlvDecoderBuffer configParamsTlv = new TlvDecoderBuffer(data, 327 CONFIGURATION_PARAMS_MAX_COUNT); 328 configParamsTlv.parse(); 329 ConfigurationParams.Builder configParamsBuilder = new ConfigurationParams.Builder(); 330 331 if (isPresent(configParamsTlv, FIRA_PHY_VERSION)) { 332 byte[] firaPhyVersion = configParamsTlv.getByteArray(FIRA_PHY_VERSION); 333 if (firaPhyVersion.length == 2) { 334 FiraProtocolVersion version = new FiraProtocolVersion(firaPhyVersion[0], 335 firaPhyVersion[1]); 336 configParamsBuilder.setPhyVersion(version); 337 } 338 } 339 if (isPresent(configParamsTlv, FIRA_MAC_VERSION)) { 340 byte[] firaMacVersion = configParamsTlv.getByteArray(FIRA_MAC_VERSION); 341 if (firaMacVersion.length == 2) { 342 FiraProtocolVersion version = new FiraProtocolVersion(firaMacVersion[0], 343 firaMacVersion[1]); 344 configParamsBuilder.setMacVersion(version); 345 } 346 } 347 if (isPresent(configParamsTlv, DEVICE_ROLES)) { 348 configParamsBuilder.setDeviceRole(configParamsTlv.getByte(DEVICE_ROLES)); 349 } 350 if (isPresent(configParamsTlv, RANGING_METHOD)) { 351 configParamsBuilder.setRangingMethod( 352 configParamsTlv.getByte(RANGING_METHOD).intValue()); 353 } 354 if (isPresent(configParamsTlv, STS_CONFIG)) { 355 configParamsBuilder.setStsConfig(configParamsTlv.getByte(STS_CONFIG).intValue()); 356 } 357 if (isPresent(configParamsTlv, MULTI_NODE_MODE)) { 358 configParamsBuilder.setMultiNodeMode( 359 configParamsTlv.getByte(MULTI_NODE_MODE).intValue()); 360 } 361 if (isPresent(configParamsTlv, RANGING_TIME_STRUCT)) { 362 configParamsBuilder.setRangingTimeStruct(configParamsTlv.getByte(RANGING_TIME_STRUCT)); 363 } 364 if (isPresent(configParamsTlv, SCHEDULED_MODE)) { 365 configParamsBuilder.setScheduleMode(configParamsTlv.getByte(SCHEDULED_MODE).intValue()); 366 } 367 if (isPresent(configParamsTlv, HOPPING_MODE)) { 368 configParamsBuilder.setHoppingMode(configParamsTlv.getByte(HOPPING_MODE) == 1); 369 } 370 if (isPresent(configParamsTlv, BLOCK_STRIDING)) { 371 configParamsBuilder.setBlockStriding(configParamsTlv.getByte(BLOCK_STRIDING) == 1); 372 } 373 if (isPresent(configParamsTlv, UWB_INITIATION_TIME)) { 374 configParamsBuilder.setUwbInitiationTime( 375 configParamsTlv.getByte(UWB_INITIATION_TIME) == 1); 376 } 377 if (isPresent(configParamsTlv, CHANNEL)) { 378 configParamsBuilder.setChannel(configParamsTlv.getByte(CHANNEL).intValue()); 379 } 380 if (isPresent(configParamsTlv, RFRAME_CONFIG)) { 381 configParamsBuilder.setRframeConfig(configParamsTlv.getByte(RFRAME_CONFIG).intValue()); 382 } 383 if (isPresent(configParamsTlv, CC_CONSTRAINT_LENGTH)) { 384 configParamsBuilder.setCcConstraintLength( 385 configParamsTlv.getByte(CC_CONSTRAINT_LENGTH).intValue()); 386 } 387 if (isPresent(configParamsTlv, PRF_MODE)) { 388 configParamsBuilder.setPrfMode(configParamsTlv.getByte(PRF_MODE).intValue()); 389 } 390 if (isPresent(configParamsTlv, SP0_PHY_SET)) { 391 configParamsBuilder.setSp0PhyParameterSet( 392 configParamsTlv.getByte(SP0_PHY_SET).intValue()); 393 } 394 if (isPresent(configParamsTlv, SP1_PHY_SET)) { 395 configParamsBuilder.setSp1PhyParameterSet( 396 configParamsTlv.getByte(SP1_PHY_SET).intValue()); 397 } 398 if (isPresent(configParamsTlv, SP3_PHY_SET)) { 399 configParamsBuilder.setSp3PhyParameterSet( 400 configParamsTlv.getByte(SP3_PHY_SET).intValue()); 401 } 402 if (isPresent(configParamsTlv, PREAMBLE_CODE_INDEX)) { 403 configParamsBuilder.setPreambleCodeIndex( 404 configParamsTlv.getByte(PREAMBLE_CODE_INDEX).intValue()); 405 } 406 if (isPresent(configParamsTlv, PREAMBLE_CODE_INDEX)) { 407 configParamsBuilder.setPreambleCodeIndex( 408 configParamsTlv.getByte(PREAMBLE_CODE_INDEX).intValue()); 409 } 410 if (isPresent(configParamsTlv, RESULT_REPORT_CONFIG)) { 411 EnumSet<FiraParams.AoaCapabilityFlag> aoaSupport = EnumSet.noneOf( 412 FiraParams.AoaCapabilityFlag.class); 413 byte aoaSupportRaw = configParamsTlv.getByte(RESULT_REPORT_CONFIG); 414 if (isBitSet(aoaSupportRaw, AOA_AZIMUTH_90)) { 415 aoaSupport.add(FiraParams.AoaCapabilityFlag.HAS_AZIMUTH_SUPPORT); 416 } 417 if (isBitSet(aoaSupportRaw, AOA_AZIMUTH_180)) { 418 aoaSupport.add(FiraParams.AoaCapabilityFlag.HAS_FULL_AZIMUTH_SUPPORT); 419 } 420 if (isBitSet(aoaSupportRaw, AOA_ELEVATION)) { 421 aoaSupport.add(FiraParams.AoaCapabilityFlag.HAS_ELEVATION_SUPPORT); 422 } 423 if (isBitSet(aoaSupportRaw, AOA_FOM)) { 424 aoaSupport.add(FiraParams.AoaCapabilityFlag.HAS_FOM_SUPPORT); 425 } 426 configParamsBuilder.setResultReportConfig(aoaSupport); 427 } 428 if (isPresent(configParamsTlv, MAC_ADDRESS_MODE)) { 429 configParamsBuilder.setMacAddressMode( 430 configParamsTlv.getByte(MAC_ADDRESS_MODE).intValue()); 431 } 432 if (isPresent(configParamsTlv, CONTROLEE_SHORT_MAC_ADDRESS)) { 433 UwbAddress controleeAddress = UwbAddress.fromBytes( 434 configParamsTlv.getByteArray(CONTROLEE_SHORT_MAC_ADDRESS)); 435 configParamsBuilder.setControleeShortMacAddress(controleeAddress); 436 } 437 if (isPresent(configParamsTlv, CONTROLLER_MAC_ADDRESS)) { 438 UwbAddress controllerAddress = UwbAddress.fromBytes( 439 configParamsTlv.getByteArray(CONTROLLER_MAC_ADDRESS)); 440 configParamsBuilder.setControllerMacAddress(controllerAddress); 441 } 442 if (isPresent(configParamsTlv, SLOTS_PER_RR)) { 443 configParamsBuilder.setSlotsPerRangingRound( 444 configParamsTlv.getByte(SLOTS_PER_RR).intValue()); 445 } 446 if (isPresent(configParamsTlv, MAX_CONTENTION_PHASE_LENGTH)) { 447 configParamsBuilder.setMaxContentionPhaseLength( 448 configParamsTlv.getByte(MAX_CONTENTION_PHASE_LENGTH).intValue()); 449 } 450 if (isPresent(configParamsTlv, SLOT_DURATION)) { 451 configParamsBuilder.setSlotDuration( 452 ByteBuffer.wrap(configParamsTlv.getByteArray(SLOT_DURATION)).getInt()); 453 } 454 if (isPresent(configParamsTlv, RANGING_INTERVAL)) { 455 configParamsBuilder.setRangingIntervalMs( 456 ByteBuffer.wrap( 457 configParamsTlv.getByteArray(RANGING_INTERVAL)).getInt()); 458 } 459 if (isPresent(configParamsTlv, KEY_ROTATION_RATE)) { 460 configParamsBuilder.setKeyRotationRate( 461 configParamsTlv.getByte(KEY_ROTATION_RATE).intValue()); 462 } 463 if (isPresent(configParamsTlv, MAC_FCS_TYPE)) { 464 configParamsBuilder.setMaxContentionPhaseLength( 465 configParamsTlv.getByte(MAC_FCS_TYPE).intValue()); 466 } 467 if (isPresent(configParamsTlv, MAX_RR_RETRY)) { 468 configParamsBuilder.setMaxRangingRoundRetry( 469 ByteBuffer.wrap(configParamsTlv.getByteArray(MAX_RR_RETRY)).getInt()); 470 } 471 return configParamsBuilder.build(); 472 } 473 474 /** Builder for CONFIGURATION_PARAMS */ 475 static class Builder { 476 // Set all default protocol version to FiRa 1.1 477 private FiraProtocolVersion mPhyVersion = new FiraProtocolVersion(1, 1); 478 private FiraProtocolVersion mMacVersion = new FiraProtocolVersion(1, 1); 479 private Optional<Integer> mDeviceRole = 480 Optional.empty(); 481 private Optional<Integer> mRangingMethod = 482 Optional.empty(); 483 private Optional<Integer> mStsConfig = Optional.empty(); 484 private Optional<Integer> mMultiNodeMode = 485 Optional.empty(); 486 private Optional<Byte> mRangingTimeStruct = Optional.empty(); 487 private Optional<Integer> mScheduleMode = Optional.empty(); 488 private Optional<Boolean> mHoppingMode = Optional.empty(); 489 private Optional<Boolean> mBlockStriding = Optional.empty(); 490 private Optional<Boolean> mUwbInitiationTime = Optional.empty(); 491 private Optional<Integer> mChannel = Optional.empty(); 492 private Optional<Integer> mRframeConfig = Optional.empty(); 493 private Optional<Integer> mCcConstraintLength = 494 Optional.empty(); 495 private Optional<Integer> mPrfMode = Optional.empty(); 496 private Optional<Integer> mSp0PhyParameterSet = Optional.empty(); 497 private Optional<Integer> mSp1PhyParameterSet = Optional.empty(); 498 private Optional<Integer> mSp3PhyParameterSet = Optional.empty(); 499 private Optional<Integer> mPreambleCodeIndex = Optional.empty(); 500 private Optional<EnumSet<FiraParams.AoaCapabilityFlag>> mResultReportConfig = 501 Optional.empty(); 502 private Optional<Integer> mMacAddressMode = Optional.empty(); 503 private Optional<UwbAddress> mControleeShortMacAddress = Optional.empty(); 504 private Optional<UwbAddress> mControllerMacAddress = Optional.empty(); 505 private Optional<Integer> mSlotsPerRangingRound = Optional.empty(); 506 private Optional<Integer> mMaxContentionPhaseLength = Optional.empty(); 507 private Optional<Integer> mSlotDuration = Optional.empty(); 508 private Optional<Integer> mRangingIntervalMs = Optional.empty(); 509 private Optional<Integer> mKeyRotationRate = Optional.empty(); 510 private Optional<Integer> mMacFcsType = Optional.empty(); 511 private Optional<Integer> mMaxRangingRoundRetry = Optional.empty(); 512 setPhyVersion( FiraProtocolVersion phyVersion)513 ConfigurationParams.Builder setPhyVersion( 514 FiraProtocolVersion phyVersion) { 515 mPhyVersion = phyVersion; 516 return this; 517 } 518 setMacVersion( FiraProtocolVersion macVersion)519 ConfigurationParams.Builder setMacVersion( 520 FiraProtocolVersion macVersion) { 521 mMacVersion = macVersion; 522 return this; 523 } 524 setDeviceRole( int deviceRole)525 ConfigurationParams.Builder setDeviceRole( 526 int deviceRole) { 527 mDeviceRole = Optional.of(deviceRole); 528 return this; 529 } 530 setRangingMethod( @iraParams.RangingRoundUsage int rangingMethod)531 ConfigurationParams.Builder setRangingMethod( 532 @FiraParams.RangingRoundUsage int rangingMethod) { 533 mRangingMethod = Optional.of(rangingMethod); 534 return this; 535 } 536 setStsConfig(@iraParams.StsConfig int stsConfig)537 ConfigurationParams.Builder setStsConfig(@FiraParams.StsConfig int stsConfig) { 538 mStsConfig = Optional.of(stsConfig); 539 return this; 540 } 541 setMultiNodeMode( @iraParams.MultiNodeMode int multiNodeMode)542 ConfigurationParams.Builder setMultiNodeMode( 543 @FiraParams.MultiNodeMode int multiNodeMode) { 544 mMultiNodeMode = Optional.of(multiNodeMode); 545 return this; 546 } 547 setRangingTimeStruct(Byte rangingTimeStruct)548 ConfigurationParams.Builder setRangingTimeStruct(Byte rangingTimeStruct) { 549 mRangingTimeStruct = Optional.of(rangingTimeStruct); 550 return this; 551 } 552 setScheduleMode(@iraParams.SchedulingMode int scheduleMode)553 ConfigurationParams.Builder setScheduleMode(@FiraParams.SchedulingMode int scheduleMode) { 554 mScheduleMode = Optional.of(scheduleMode); 555 return this; 556 } 557 setHoppingMode(Boolean hoppingMode)558 ConfigurationParams.Builder setHoppingMode(Boolean hoppingMode) { 559 mHoppingMode = Optional.of(hoppingMode); 560 return this; 561 } 562 setBlockStriding(Boolean blockStriding)563 ConfigurationParams.Builder setBlockStriding(Boolean blockStriding) { 564 mBlockStriding = Optional.of(blockStriding); 565 return this; 566 } 567 setUwbInitiationTime( Boolean uwbInitiationTime)568 ConfigurationParams.Builder setUwbInitiationTime( 569 Boolean uwbInitiationTime) { 570 mUwbInitiationTime = Optional.of(uwbInitiationTime); 571 return this; 572 } 573 setChannel(Integer channel)574 ConfigurationParams.Builder setChannel(Integer channel) { 575 mChannel = Optional.of(channel); 576 return this; 577 } 578 setRframeConfig( @iraParams.RframeConfig int rframeConfig)579 ConfigurationParams.Builder setRframeConfig( 580 @FiraParams.RframeConfig int rframeConfig) { 581 mRframeConfig = Optional.of(rframeConfig); 582 return this; 583 } 584 setCcConstraintLength( @iraParams.CcConstraintLength int ccConstraintLength)585 ConfigurationParams.Builder setCcConstraintLength( 586 @FiraParams.CcConstraintLength int ccConstraintLength) { 587 mCcConstraintLength = Optional.of(ccConstraintLength); 588 return this; 589 } 590 setPrfMode(Integer prfMode)591 ConfigurationParams.Builder setPrfMode(Integer prfMode) { 592 mPrfMode = Optional.of(prfMode); 593 return this; 594 } 595 setSp0PhyParameterSet( Integer sp0PhyParameterSet)596 ConfigurationParams.Builder setSp0PhyParameterSet( 597 Integer sp0PhyParameterSet) { 598 mSp0PhyParameterSet = Optional.of(sp0PhyParameterSet); 599 return this; 600 } 601 setSp1PhyParameterSet( Integer sp1PhyParameterSet)602 ConfigurationParams.Builder setSp1PhyParameterSet( 603 Integer sp1PhyParameterSet) { 604 mSp1PhyParameterSet = Optional.of(sp1PhyParameterSet); 605 return this; 606 } 607 setSp3PhyParameterSet( Integer sp3PhyParameterSet)608 ConfigurationParams.Builder setSp3PhyParameterSet( 609 Integer sp3PhyParameterSet) { 610 mSp3PhyParameterSet = Optional.of(sp3PhyParameterSet); 611 return this; 612 } 613 setPreambleCodeIndex( Integer preambleCodeIndex)614 ConfigurationParams.Builder setPreambleCodeIndex( 615 Integer preambleCodeIndex) { 616 mPreambleCodeIndex = Optional.of(preambleCodeIndex); 617 return this; 618 } 619 setResultReportConfig( EnumSet<FiraParams.AoaCapabilityFlag> resultReportConfig)620 ConfigurationParams.Builder setResultReportConfig( 621 EnumSet<FiraParams.AoaCapabilityFlag> resultReportConfig) { 622 mResultReportConfig = Optional.of(resultReportConfig); 623 return this; 624 } 625 setMacAddressMode( Integer macAddressMode)626 ConfigurationParams.Builder setMacAddressMode( 627 Integer macAddressMode) { 628 mMacAddressMode = Optional.of(macAddressMode); 629 return this; 630 } 631 setControleeShortMacAddress( UwbAddress controleeShortMacAddress)632 ConfigurationParams.Builder setControleeShortMacAddress( 633 UwbAddress controleeShortMacAddress) { 634 mControleeShortMacAddress = Optional.of(controleeShortMacAddress); 635 return this; 636 } 637 setControllerMacAddress( UwbAddress controllerMacAddress)638 ConfigurationParams.Builder setControllerMacAddress( 639 UwbAddress controllerMacAddress) { 640 mControllerMacAddress = Optional.of(controllerMacAddress); 641 return this; 642 } 643 setSlotsPerRangingRound( Integer slotsPerRangingRound)644 ConfigurationParams.Builder setSlotsPerRangingRound( 645 Integer slotsPerRangingRound) { 646 mSlotsPerRangingRound = Optional.of(slotsPerRangingRound); 647 return this; 648 } 649 setMaxContentionPhaseLength( Integer maxContentionPhaseLength)650 ConfigurationParams.Builder setMaxContentionPhaseLength( 651 Integer maxContentionPhaseLength) { 652 mMaxContentionPhaseLength = Optional.of((maxContentionPhaseLength)); 653 return this; 654 } 655 setSlotDuration(Integer slotDuration)656 ConfigurationParams.Builder setSlotDuration(Integer slotDuration) { 657 mSlotDuration = Optional.of(slotDuration); 658 return this; 659 } 660 setRangingIntervalMs( Integer rangingIntervalMs)661 ConfigurationParams.Builder setRangingIntervalMs( 662 Integer rangingIntervalMs) { 663 mRangingIntervalMs = Optional.of(rangingIntervalMs); 664 return this; 665 } 666 setKeyRotationRate(Integer keyRotationRate)667 ConfigurationParams.Builder setKeyRotationRate(Integer keyRotationRate) { 668 mKeyRotationRate = Optional.of(keyRotationRate); 669 return this; 670 } 671 setMacFcsType(Integer macFcsType)672 ConfigurationParams.Builder setMacFcsType(Integer macFcsType) { 673 mMacFcsType = Optional.of(macFcsType); 674 return this; 675 } 676 setMaxRangingRoundRetry( Integer maxRangingRoundRetry)677 ConfigurationParams.Builder setMaxRangingRoundRetry( 678 Integer maxRangingRoundRetry) { 679 mMaxRangingRoundRetry = Optional.of(maxRangingRoundRetry); 680 return this; 681 } 682 build()683 ConfigurationParams build() { 684 return new ConfigurationParams( 685 mPhyVersion, 686 mMacVersion, 687 mDeviceRole, 688 mRangingMethod, 689 mStsConfig, 690 mMultiNodeMode, 691 mRangingTimeStruct, 692 mScheduleMode, 693 mHoppingMode, 694 mBlockStriding, 695 mUwbInitiationTime, 696 mChannel, 697 mRframeConfig, 698 mCcConstraintLength, 699 mPrfMode, 700 mSp0PhyParameterSet, 701 mSp1PhyParameterSet, 702 mSp3PhyParameterSet, 703 mPreambleCodeIndex, 704 mResultReportConfig, 705 mMacAddressMode, 706 mControleeShortMacAddress, 707 mControllerMacAddress, 708 mSlotsPerRangingRound, 709 mMaxContentionPhaseLength, 710 mSlotDuration, 711 mRangingIntervalMs, 712 mKeyRotationRate, 713 mMacFcsType, 714 mMaxRangingRoundRetry 715 ); 716 } 717 } 718 } 719