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.fira; 18 19 import static com.android.internal.util.Preconditions.checkArgument; 20 import static com.android.internal.util.Preconditions.checkNotNull; 21 22 import static com.google.uwb.support.fira.FiraParams.AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_INTERLEAVED; 23 24 import static java.util.Objects.requireNonNull; 25 26 import android.os.PersistableBundle; 27 import android.uwb.UwbAddress; 28 import android.uwb.UwbManager; 29 30 import androidx.annotation.IntRange; 31 import androidx.annotation.NonNull; 32 import androidx.annotation.Nullable; 33 34 import com.google.uwb.support.base.RequiredParam; 35 36 import java.util.ArrayList; 37 import java.util.Collections; 38 import java.util.List; 39 40 /** 41 * UWB parameters used to open a FiRa session. 42 * 43 * <p>This is passed as a bundle to the service API {@link UwbManager#openRangingSession}. 44 */ 45 public class FiraOpenSessionParams extends FiraParams { 46 private final FiraProtocolVersion mProtocolVersion; 47 48 private final int mSessionId; 49 @RangingDeviceType private final int mDeviceType; 50 @RangingDeviceRole private final int mDeviceRole; 51 @RangingRoundUsage private final int mRangingRoundUsage; 52 @MultiNodeMode private final int mMultiNodeMode; 53 54 private final UwbAddress mDeviceAddress; 55 56 // Dest address list 57 private final List<UwbAddress> mDestAddressList; 58 59 private final int mInitiationTimeMs; 60 private final int mSlotDurationRstu; 61 private final int mSlotsPerRangingRound; 62 private final int mRangingIntervalMs; 63 private final int mBlockStrideLength; 64 private final int mHoppingMode; 65 66 @IntRange(from = 0, to = 65535) 67 private final int mMaxRangingRoundRetries; 68 69 private final int mSessionPriority; 70 @MacAddressMode final int mMacAddressMode; 71 private final boolean mHasResultReportPhase; 72 @MeasurementReportType private final int mMeasurementReportType; 73 74 @IntRange(from = 1, to = 10) 75 private final int mInBandTerminationAttemptCount; 76 77 @UwbChannel private final int mChannelNumber; 78 private final int mPreambleCodeIndex; 79 @RframeConfig private final int mRframeConfig; 80 @PrfMode private final int mPrfMode; 81 @PreambleDuration private final int mPreambleDuration; 82 @SfdIdValue private final int mSfdId; 83 @StsSegmentCountValue private final int mStsSegmentCount; 84 @StsLength private final int mStsLength; 85 @PsduDataRate private final int mPsduDataRate; 86 @BprfPhrDataRate private final int mBprfPhrDataRate; 87 @MacFcsType private final int mFcsType; 88 private final boolean mIsTxAdaptivePayloadPowerEnabled; 89 @StsConfig private final int mStsConfig; 90 private final int mSubSessionId; 91 @AoaType private final int mAoaType; 92 93 // 2-byte long array 94 @Nullable private final byte[] mVendorId; 95 96 // 6-byte long array 97 @Nullable private final byte[] mStaticStsIV; 98 99 private final boolean mIsKeyRotationEnabled; 100 private final int mKeyRotationRate; 101 @AoaResultRequestMode private final int mAoaResultRequest; 102 @RangeDataNtfConfig private final int mRangeDataNtfConfig; 103 private final int mRangeDataNtfProximityNear; 104 private final int mRangeDataNtfProximityFar; 105 private final boolean mHasTimeOfFlightReport; 106 private final boolean mHasAngleOfArrivalAzimuthReport; 107 private final boolean mHasAngleOfArrivalElevationReport; 108 private final boolean mHasAngleOfArrivalFigureOfMeritReport; 109 private final int mNumOfMsrmtFocusOnRange; 110 private final int mNumOfMsrmtFocusOnAoaAzimuth; 111 private final int mNumOfMsrmtFocusOnAoaElevation; 112 113 private static final int BUNDLE_VERSION_1 = 1; 114 private static final int BUNDLE_VERSION_CURRENT = BUNDLE_VERSION_1; 115 116 private static final String KEY_PROTOCOL_VERSION = "protocol_version"; 117 private static final String KEY_SESSION_ID = "session_id"; 118 private static final String KEY_DEVICE_TYPE = "device_type"; 119 private static final String KEY_DEVICE_ROLE = "device_role"; 120 private static final String KEY_RANGING_ROUND_USAGE = "ranging_round_usage"; 121 private static final String KEY_MULTI_NODE_MODE = "multi_node_mode"; 122 private static final String KEY_DEVICE_ADDRESS = "device_address"; 123 private static final String KEY_DEST_ADDRESS_LIST = "dest_address_list"; 124 private static final String KEY_INITIATION_TIME_MS = "initiation_time_ms"; 125 private static final String KEY_SLOT_DURATION_RSTU = "slot_duration_rstu"; 126 private static final String KEY_SLOTS_PER_RANGING_ROUND = "slots_per_ranging_round"; 127 private static final String KEY_RANGING_INTERVAL_MS = "ranging_interval_ms"; 128 private static final String KEY_BLOCK_STRIDE_LENGTH = "block_stride_length"; 129 private static final String KEY_HOPPING_MODE = "hopping_mode"; 130 private static final String KEY_MAX_RANGING_ROUND_RETRIES = "max_ranging_round_retries"; 131 private static final String KEY_SESSION_PRIORITY = "session_priority"; 132 private static final String KEY_MAC_ADDRESS_MODE = "mac_address_mode"; 133 private static final String KEY_IN_BAND_TERMINATION_ATTEMPT_COUNT = 134 "in_band_termination_attempt_count"; 135 private static final String KEY_CHANNEL_NUMBER = "channel_number"; 136 private static final String KEY_PREAMBLE_CODE_INDEX = "preamble_code_index"; 137 private static final String KEY_RFRAME_CONFIG = "rframe_config"; 138 private static final String KEY_PRF_MODE = "prf_mode"; 139 private static final String KEY_PREAMBLE_DURATION = "preamble_duration"; 140 private static final String KEY_SFD_ID = "sfd_id"; 141 private static final String KEY_STS_SEGMENT_COUNT = "sts_segment_count"; 142 private static final String KEY_STS_LENGTH = "sts_length"; 143 private static final String KEY_PSDU_DATA_RATE = "psdu_data_rate"; 144 private static final String KEY_BPRF_PHR_DATA_RATE = "bprf_phr_data_rate"; 145 private static final String KEY_FCS_TYPE = "fcs_type"; 146 private static final String KEY_IS_TX_ADAPTIVE_PAYLOAD_POWER_ENABLED = 147 "is_tx_adaptive_payload_power_enabled"; 148 private static final String KEY_STS_CONFIG = "sts_config"; 149 private static final String KEY_SUB_SESSION_ID = "sub_session_id"; 150 private static final String KEY_VENDOR_ID = "vendor_id"; 151 private static final String KEY_STATIC_STS_IV = "static_sts_iv"; 152 private static final String KEY_IS_KEY_ROTATION_ENABLED = "is_key_rotation_enabled"; 153 private static final String KEY_KEY_ROTATION_RATE = "key_rotation_rate"; 154 private static final String KEY_AOA_RESULT_REQUEST = "aoa_result_request"; 155 private static final String KEY_RANGE_DATA_NTF_CONFIG = "range_data_ntf_config"; 156 private static final String KEY_RANGE_DATA_NTF_PROXIMITY_NEAR = "range_data_ntf_proximity_near"; 157 private static final String KEY_RANGE_DATA_NTF_PROXIMITY_FAR = "range_data_ntf_proximity_far"; 158 private static final String KEY_HAS_TIME_OF_FLIGHT_REPORT = "has_time_of_flight_report"; 159 private static final String KEY_HAS_ANGLE_OF_ARRIVAL_AZIMUTH_REPORT = 160 "has_angle_of_arrival_azimuth_report"; 161 private static final String KEY_HAS_ANGLE_OF_ARRIVAL_ELEVATION_REPORT = 162 "has_angle_of_arrival_elevation_report"; 163 private static final String KEY_HAS_ANGLE_OF_ARRIVAL_FIGURE_OF_MERIT_REPORT = 164 "has_angle_of_arrival_figure_of_merit_report"; 165 private static final String KEY_HAS_RESULT_REPORT_PHASE = "has_result_report_phase"; 166 private static final String KEY_MEASUREMENT_REPORT_TYPE = "measurement_report_type"; 167 private static final String KEY_AOA_TYPE = "aoa_type"; 168 private static final String KEY_NUM_OF_MSRMT_FOCUS_ON_RANGE = 169 "num_of_msrmt_focus_on_range"; 170 private static final String KEY_NUM_OF_MSRMT_FOCUS_ON_AOA_AZIMUTH = 171 "num_of_msrmt_focus_on_aoa_azimuth"; 172 private static final String KEY_NUM_OF_MSRMT_FOCUS_ON_AOA_ELEVATION = 173 "num_of_msrmt_focus_on_aoa_elevation"; 174 FiraOpenSessionParams( FiraProtocolVersion protocolVersion, int sessionId, @RangingDeviceType int deviceType, @RangingDeviceRole int deviceRole, @RangingRoundUsage int rangingRoundUsage, @MultiNodeMode int multiNodeMode, UwbAddress deviceAddress, List<UwbAddress> destAddressList, int initiationTimeMs, int slotDurationRstu, int slotsPerRangingRound, int rangingIntervalMs, int blockStrideLength, int hoppingMode, @IntRange(from = 0, to = 65535) int maxRangingRoundRetries, int sessionPriority, @MacAddressMode int macAddressMode, boolean hasResultReportPhase, @MeasurementReportType int measurementReportType, @IntRange(from = 1, to = 10) int inBandTerminationAttemptCount, @UwbChannel int channelNumber, int preambleCodeIndex, @RframeConfig int rframeConfig, @PrfMode int prfMode, @PreambleDuration int preambleDuration, @SfdIdValue int sfdId, @StsSegmentCountValue int stsSegmentCount, @StsLength int stsLength, @PsduDataRate int psduDataRate, @BprfPhrDataRate int bprfPhrDataRate, @MacFcsType int fcsType, boolean isTxAdaptivePayloadPowerEnabled, @StsConfig int stsConfig, int subSessionId, @Nullable byte[] vendorId, @Nullable byte[] staticStsIV, boolean isKeyRotationEnabled, int keyRotationRate, @AoaResultRequestMode int aoaResultRequest, @RangeDataNtfConfig int rangeDataNtfConfig, int rangeDataNtfProximityNear, int rangeDataNtfProximityFar, boolean hasTimeOfFlightReport, boolean hasAngleOfArrivalAzimuthReport, boolean hasAngleOfArrivalElevationReport, boolean hasAngleOfArrivalFigureOfMeritReport, @AoaType int aoaType, int numOfMsrmtFocusOnRange, int numOfMsrmtFocusOnAoaAzimuth, int numOfMsrmtFocusOnAoaElevation)175 private FiraOpenSessionParams( 176 FiraProtocolVersion protocolVersion, 177 int sessionId, 178 @RangingDeviceType int deviceType, 179 @RangingDeviceRole int deviceRole, 180 @RangingRoundUsage int rangingRoundUsage, 181 @MultiNodeMode int multiNodeMode, 182 UwbAddress deviceAddress, 183 List<UwbAddress> destAddressList, 184 int initiationTimeMs, 185 int slotDurationRstu, 186 int slotsPerRangingRound, 187 int rangingIntervalMs, 188 int blockStrideLength, 189 int hoppingMode, 190 @IntRange(from = 0, to = 65535) int maxRangingRoundRetries, 191 int sessionPriority, 192 @MacAddressMode int macAddressMode, 193 boolean hasResultReportPhase, 194 @MeasurementReportType int measurementReportType, 195 @IntRange(from = 1, to = 10) int inBandTerminationAttemptCount, 196 @UwbChannel int channelNumber, 197 int preambleCodeIndex, 198 @RframeConfig int rframeConfig, 199 @PrfMode int prfMode, 200 @PreambleDuration int preambleDuration, 201 @SfdIdValue int sfdId, 202 @StsSegmentCountValue int stsSegmentCount, 203 @StsLength int stsLength, 204 @PsduDataRate int psduDataRate, 205 @BprfPhrDataRate int bprfPhrDataRate, 206 @MacFcsType int fcsType, 207 boolean isTxAdaptivePayloadPowerEnabled, 208 @StsConfig int stsConfig, 209 int subSessionId, 210 @Nullable byte[] vendorId, 211 @Nullable byte[] staticStsIV, 212 boolean isKeyRotationEnabled, 213 int keyRotationRate, 214 @AoaResultRequestMode int aoaResultRequest, 215 @RangeDataNtfConfig int rangeDataNtfConfig, 216 int rangeDataNtfProximityNear, 217 int rangeDataNtfProximityFar, 218 boolean hasTimeOfFlightReport, 219 boolean hasAngleOfArrivalAzimuthReport, 220 boolean hasAngleOfArrivalElevationReport, 221 boolean hasAngleOfArrivalFigureOfMeritReport, 222 @AoaType int aoaType, 223 int numOfMsrmtFocusOnRange, 224 int numOfMsrmtFocusOnAoaAzimuth, 225 int numOfMsrmtFocusOnAoaElevation) { 226 mProtocolVersion = protocolVersion; 227 mSessionId = sessionId; 228 mDeviceType = deviceType; 229 mDeviceRole = deviceRole; 230 mRangingRoundUsage = rangingRoundUsage; 231 mMultiNodeMode = multiNodeMode; 232 mDeviceAddress = deviceAddress; 233 mDestAddressList = destAddressList; 234 mInitiationTimeMs = initiationTimeMs; 235 mSlotDurationRstu = slotDurationRstu; 236 mSlotsPerRangingRound = slotsPerRangingRound; 237 mRangingIntervalMs = rangingIntervalMs; 238 mBlockStrideLength = blockStrideLength; 239 mHoppingMode = hoppingMode; 240 mMaxRangingRoundRetries = maxRangingRoundRetries; 241 mSessionPriority = sessionPriority; 242 mMacAddressMode = macAddressMode; 243 mHasResultReportPhase = hasResultReportPhase; 244 mMeasurementReportType = measurementReportType; 245 mInBandTerminationAttemptCount = inBandTerminationAttemptCount; 246 mChannelNumber = channelNumber; 247 mPreambleCodeIndex = preambleCodeIndex; 248 mRframeConfig = rframeConfig; 249 mPrfMode = prfMode; 250 mPreambleDuration = preambleDuration; 251 mSfdId = sfdId; 252 mStsSegmentCount = stsSegmentCount; 253 mStsLength = stsLength; 254 mPsduDataRate = psduDataRate; 255 mBprfPhrDataRate = bprfPhrDataRate; 256 mFcsType = fcsType; 257 mIsTxAdaptivePayloadPowerEnabled = isTxAdaptivePayloadPowerEnabled; 258 mStsConfig = stsConfig; 259 mSubSessionId = subSessionId; 260 mVendorId = vendorId; 261 mStaticStsIV = staticStsIV; 262 mIsKeyRotationEnabled = isKeyRotationEnabled; 263 mKeyRotationRate = keyRotationRate; 264 mAoaResultRequest = aoaResultRequest; 265 mRangeDataNtfConfig = rangeDataNtfConfig; 266 mRangeDataNtfProximityNear = rangeDataNtfProximityNear; 267 mRangeDataNtfProximityFar = rangeDataNtfProximityFar; 268 mHasTimeOfFlightReport = hasTimeOfFlightReport; 269 mHasAngleOfArrivalAzimuthReport = hasAngleOfArrivalAzimuthReport; 270 mHasAngleOfArrivalElevationReport = hasAngleOfArrivalElevationReport; 271 mHasAngleOfArrivalFigureOfMeritReport = hasAngleOfArrivalFigureOfMeritReport; 272 mAoaType = aoaType; 273 mNumOfMsrmtFocusOnRange = numOfMsrmtFocusOnRange; 274 mNumOfMsrmtFocusOnAoaAzimuth = numOfMsrmtFocusOnAoaAzimuth; 275 mNumOfMsrmtFocusOnAoaElevation = numOfMsrmtFocusOnAoaElevation; 276 } 277 278 @Override getBundleVersion()279 protected int getBundleVersion() { 280 return BUNDLE_VERSION_CURRENT; 281 } 282 getSessionId()283 public int getSessionId() { 284 return mSessionId; 285 } 286 287 @RangingDeviceType getDeviceType()288 public int getDeviceType() { 289 return mDeviceType; 290 } 291 292 @RangingDeviceRole getDeviceRole()293 public int getDeviceRole() { 294 return mDeviceRole; 295 } 296 297 @RangingRoundUsage getRangingRoundUsage()298 public int getRangingRoundUsage() { 299 return mRangingRoundUsage; 300 } 301 302 @MultiNodeMode getMultiNodeMode()303 public int getMultiNodeMode() { 304 return mMultiNodeMode; 305 } 306 getDeviceAddress()307 public UwbAddress getDeviceAddress() { 308 return mDeviceAddress; 309 } 310 getDestAddressList()311 public List<UwbAddress> getDestAddressList() { 312 return Collections.unmodifiableList(mDestAddressList); 313 } 314 getInitiationTimeMs()315 public int getInitiationTimeMs() { 316 return mInitiationTimeMs; 317 } 318 getSlotDurationRstu()319 public int getSlotDurationRstu() { 320 return mSlotDurationRstu; 321 } 322 getSlotsPerRangingRound()323 public int getSlotsPerRangingRound() { 324 return mSlotsPerRangingRound; 325 } 326 getRangingIntervalMs()327 public int getRangingIntervalMs() { 328 return mRangingIntervalMs; 329 } 330 getBlockStrideLength()331 public int getBlockStrideLength() { 332 return mBlockStrideLength; 333 } 334 getHoppingMode()335 public int getHoppingMode() { 336 return mHoppingMode; 337 } 338 339 @IntRange(from = 0, to = 65535) getMaxRangingRoundRetries()340 public int getMaxRangingRoundRetries() { 341 return mMaxRangingRoundRetries; 342 } 343 getSessionPriority()344 public int getSessionPriority() { 345 return mSessionPriority; 346 } 347 348 @MacAddressMode getMacAddressMode()349 public int getMacAddressMode() { 350 return mMacAddressMode; 351 } 352 hasResultReportPhase()353 public boolean hasResultReportPhase() { 354 return mHasResultReportPhase; 355 } 356 357 @MeasurementReportType getMeasurementReportType()358 public int getMeasurementReportType() { 359 return mMeasurementReportType; 360 } 361 362 @IntRange(from = 1, to = 10) getInBandTerminationAttemptCount()363 public int getInBandTerminationAttemptCount() { 364 return mInBandTerminationAttemptCount; 365 } 366 367 @UwbChannel getChannelNumber()368 public int getChannelNumber() { 369 return mChannelNumber; 370 } 371 getPreambleCodeIndex()372 public int getPreambleCodeIndex() { 373 return mPreambleCodeIndex; 374 } 375 376 @RframeConfig getRframeConfig()377 public int getRframeConfig() { 378 return mRframeConfig; 379 } 380 381 @PrfMode getPrfMode()382 public int getPrfMode() { 383 return mPrfMode; 384 } 385 386 @PreambleDuration getPreambleDuration()387 public int getPreambleDuration() { 388 return mPreambleDuration; 389 } 390 391 @SfdIdValue getSfdId()392 public int getSfdId() { 393 return mSfdId; 394 } 395 396 @StsSegmentCountValue getStsSegmentCount()397 public int getStsSegmentCount() { 398 return mStsSegmentCount; 399 } 400 401 @StsLength getStsLength()402 public int getStsLength() { 403 return mStsLength; 404 } 405 406 @PsduDataRate getPsduDataRate()407 public int getPsduDataRate() { 408 return mPsduDataRate; 409 } 410 411 @BprfPhrDataRate getBprfPhrDataRate()412 public int getBprfPhrDataRate() { 413 return mBprfPhrDataRate; 414 } 415 416 @MacFcsType getFcsType()417 public int getFcsType() { 418 return mFcsType; 419 } 420 isTxAdaptivePayloadPowerEnabled()421 public boolean isTxAdaptivePayloadPowerEnabled() { 422 return mIsTxAdaptivePayloadPowerEnabled; 423 } 424 425 @StsConfig getStsConfig()426 public int getStsConfig() { 427 return mStsConfig; 428 } 429 getSubSessionId()430 public int getSubSessionId() { 431 return mSubSessionId; 432 } 433 434 @Nullable getVendorId()435 public byte[] getVendorId() { 436 return mVendorId; 437 } 438 439 @Nullable getStaticStsIV()440 public byte[] getStaticStsIV() { 441 return mStaticStsIV; 442 } 443 isKeyRotationEnabled()444 public boolean isKeyRotationEnabled() { 445 return mIsKeyRotationEnabled; 446 } 447 getKeyRotationRate()448 public int getKeyRotationRate() { 449 return mKeyRotationRate; 450 } 451 452 @AoaResultRequestMode getAoaResultRequest()453 public int getAoaResultRequest() { 454 return mAoaResultRequest; 455 } 456 457 @RangeDataNtfConfig getRangeDataNtfConfig()458 public int getRangeDataNtfConfig() { 459 return mRangeDataNtfConfig; 460 } 461 getRangeDataNtfProximityNear()462 public int getRangeDataNtfProximityNear() { 463 return mRangeDataNtfProximityNear; 464 } 465 getRangeDataNtfProximityFar()466 public int getRangeDataNtfProximityFar() { 467 return mRangeDataNtfProximityFar; 468 } 469 hasTimeOfFlightReport()470 public boolean hasTimeOfFlightReport() { 471 return mHasTimeOfFlightReport; 472 } 473 hasAngleOfArrivalAzimuthReport()474 public boolean hasAngleOfArrivalAzimuthReport() { 475 return mHasAngleOfArrivalAzimuthReport; 476 } 477 hasAngleOfArrivalElevationReport()478 public boolean hasAngleOfArrivalElevationReport() { 479 return mHasAngleOfArrivalElevationReport; 480 } 481 hasAngleOfArrivalFigureOfMeritReport()482 public boolean hasAngleOfArrivalFigureOfMeritReport() { 483 return mHasAngleOfArrivalFigureOfMeritReport; 484 } 485 486 @AoaType getAoaType()487 public int getAoaType() { 488 return mAoaType; 489 } 490 getNumOfMsrmtFocusOnRange()491 public int getNumOfMsrmtFocusOnRange() { 492 return mNumOfMsrmtFocusOnRange; 493 } 494 getNumOfMsrmtFocusOnAoaAzimuth()495 public int getNumOfMsrmtFocusOnAoaAzimuth() { 496 return mNumOfMsrmtFocusOnAoaAzimuth; 497 } 498 getNumOfMsrmtFocusOnAoaElevation()499 public int getNumOfMsrmtFocusOnAoaElevation() { 500 return mNumOfMsrmtFocusOnAoaElevation; 501 } 502 503 @Nullable byteArrayToIntArray(@ullable byte[] bytes)504 private static int[] byteArrayToIntArray(@Nullable byte[] bytes) { 505 if (bytes == null) { 506 return null; 507 } 508 509 int[] values = new int[bytes.length]; 510 for (int i = 0; i < values.length; i++) { 511 values[i] = bytes[i]; 512 } 513 return values; 514 } 515 516 @Nullable intArrayToByteArray(@ullable int[] values)517 private static byte[] intArrayToByteArray(@Nullable int[] values) { 518 if (values == null) { 519 return null; 520 } 521 byte[] bytes = new byte[values.length]; 522 for (int i = 0; i < values.length; i++) { 523 bytes[i] = (byte) values[i]; 524 } 525 return bytes; 526 } 527 528 @Override toBundle()529 public PersistableBundle toBundle() { 530 PersistableBundle bundle = super.toBundle(); 531 bundle.putString(KEY_PROTOCOL_VERSION, mProtocolVersion.toString()); 532 bundle.putInt(KEY_SESSION_ID, mSessionId); 533 bundle.putInt(KEY_DEVICE_TYPE, mDeviceType); 534 bundle.putInt(KEY_DEVICE_ROLE, mDeviceRole); 535 bundle.putInt(KEY_RANGING_ROUND_USAGE, mRangingRoundUsage); 536 bundle.putInt(KEY_MULTI_NODE_MODE, mMultiNodeMode); 537 // Always store address as long in bundle. 538 bundle.putLong(KEY_DEVICE_ADDRESS, uwbAddressToLong(mDeviceAddress)); 539 540 // Dest Address list needs to be converted to long array. 541 long[] destAddressList = new long[mDestAddressList.size()]; 542 int i = 0; 543 for (UwbAddress destAddress : mDestAddressList) { 544 destAddressList[i++] = uwbAddressToLong(destAddress); 545 } 546 bundle.putLongArray(KEY_DEST_ADDRESS_LIST, destAddressList); 547 548 bundle.putInt(KEY_INITIATION_TIME_MS, mInitiationTimeMs); 549 bundle.putInt(KEY_SLOT_DURATION_RSTU, mSlotDurationRstu); 550 bundle.putInt(KEY_SLOTS_PER_RANGING_ROUND, mSlotsPerRangingRound); 551 bundle.putInt(KEY_RANGING_INTERVAL_MS, mRangingIntervalMs); 552 bundle.putInt(KEY_BLOCK_STRIDE_LENGTH, mBlockStrideLength); 553 bundle.putInt(KEY_HOPPING_MODE, mHoppingMode); 554 bundle.putInt(KEY_MAX_RANGING_ROUND_RETRIES, mMaxRangingRoundRetries); 555 bundle.putInt(KEY_SESSION_PRIORITY, mSessionPriority); 556 bundle.putInt(KEY_MAC_ADDRESS_MODE, mMacAddressMode); 557 bundle.putBoolean(KEY_HAS_RESULT_REPORT_PHASE, mHasResultReportPhase); 558 bundle.putInt(KEY_MEASUREMENT_REPORT_TYPE, mMeasurementReportType); 559 bundle.putInt(KEY_IN_BAND_TERMINATION_ATTEMPT_COUNT, mInBandTerminationAttemptCount); 560 bundle.putInt(KEY_CHANNEL_NUMBER, mChannelNumber); 561 bundle.putInt(KEY_PREAMBLE_CODE_INDEX, mPreambleCodeIndex); 562 bundle.putInt(KEY_RFRAME_CONFIG, mRframeConfig); 563 bundle.putInt(KEY_PRF_MODE, mPrfMode); 564 bundle.putInt(KEY_PREAMBLE_DURATION, mPreambleDuration); 565 bundle.putInt(KEY_SFD_ID, mSfdId); 566 bundle.putInt(KEY_STS_SEGMENT_COUNT, mStsSegmentCount); 567 bundle.putInt(KEY_STS_LENGTH, mStsLength); 568 bundle.putInt(KEY_PSDU_DATA_RATE, mPsduDataRate); 569 bundle.putInt(KEY_BPRF_PHR_DATA_RATE, mBprfPhrDataRate); 570 bundle.putInt(KEY_FCS_TYPE, mFcsType); 571 bundle.putBoolean( 572 KEY_IS_TX_ADAPTIVE_PAYLOAD_POWER_ENABLED, mIsTxAdaptivePayloadPowerEnabled); 573 bundle.putInt(KEY_STS_CONFIG, mStsConfig); 574 if (mStsConfig == STS_CONFIG_DYNAMIC_FOR_CONTROLEE_INDIVIDUAL_KEY) { 575 bundle.putInt(KEY_SUB_SESSION_ID, mSubSessionId); 576 } 577 bundle.putIntArray(KEY_VENDOR_ID, byteArrayToIntArray(mVendorId)); 578 bundle.putIntArray(KEY_STATIC_STS_IV, byteArrayToIntArray(mStaticStsIV)); 579 bundle.putBoolean(KEY_IS_KEY_ROTATION_ENABLED, mIsKeyRotationEnabled); 580 bundle.putInt(KEY_KEY_ROTATION_RATE, mKeyRotationRate); 581 bundle.putInt(KEY_AOA_RESULT_REQUEST, mAoaResultRequest); 582 bundle.putInt(KEY_RANGE_DATA_NTF_CONFIG, mRangeDataNtfConfig); 583 bundle.putInt(KEY_RANGE_DATA_NTF_PROXIMITY_NEAR, mRangeDataNtfProximityNear); 584 bundle.putInt(KEY_RANGE_DATA_NTF_PROXIMITY_FAR, mRangeDataNtfProximityFar); 585 bundle.putBoolean(KEY_HAS_TIME_OF_FLIGHT_REPORT, mHasTimeOfFlightReport); 586 bundle.putBoolean(KEY_HAS_ANGLE_OF_ARRIVAL_AZIMUTH_REPORT, mHasAngleOfArrivalAzimuthReport); 587 bundle.putBoolean( 588 KEY_HAS_ANGLE_OF_ARRIVAL_ELEVATION_REPORT, mHasAngleOfArrivalElevationReport); 589 bundle.putBoolean( 590 KEY_HAS_ANGLE_OF_ARRIVAL_FIGURE_OF_MERIT_REPORT, 591 mHasAngleOfArrivalFigureOfMeritReport); 592 bundle.putInt(KEY_AOA_TYPE, mAoaType); 593 bundle.putInt(KEY_NUM_OF_MSRMT_FOCUS_ON_RANGE, mNumOfMsrmtFocusOnRange); 594 bundle.putInt(KEY_NUM_OF_MSRMT_FOCUS_ON_AOA_AZIMUTH, mNumOfMsrmtFocusOnAoaAzimuth); 595 bundle.putInt(KEY_NUM_OF_MSRMT_FOCUS_ON_AOA_ELEVATION, mNumOfMsrmtFocusOnAoaElevation); 596 return bundle; 597 } 598 fromBundle(PersistableBundle bundle)599 public static FiraOpenSessionParams fromBundle(PersistableBundle bundle) { 600 if (!isCorrectProtocol(bundle)) { 601 throw new IllegalArgumentException("Invalid protocol"); 602 } 603 604 switch (getBundleVersion(bundle)) { 605 case BUNDLE_VERSION_1: 606 return parseBundleVersion1(bundle); 607 608 default: 609 throw new IllegalArgumentException("unknown bundle version"); 610 } 611 } 612 parseBundleVersion1(PersistableBundle bundle)613 private static FiraOpenSessionParams parseBundleVersion1(PersistableBundle bundle) { 614 int macAddressMode = bundle.getInt(KEY_MAC_ADDRESS_MODE); 615 int addressByteLength = 2; 616 if (macAddressMode == MAC_ADDRESS_MODE_8_BYTES) { 617 addressByteLength = 8; 618 } 619 UwbAddress deviceAddress = 620 longToUwbAddress(bundle.getLong(KEY_DEVICE_ADDRESS), addressByteLength); 621 622 long[] destAddresses = bundle.getLongArray(KEY_DEST_ADDRESS_LIST); 623 List<UwbAddress> destAddressList = new ArrayList<>(); 624 for (long address : destAddresses) { 625 destAddressList.add(longToUwbAddress(address, addressByteLength)); 626 } 627 628 return new FiraOpenSessionParams.Builder() 629 .setProtocolVersion( 630 FiraProtocolVersion.fromString( 631 requireNonNull(bundle.getString(KEY_PROTOCOL_VERSION)))) 632 .setSessionId(bundle.getInt(KEY_SESSION_ID)) 633 .setDeviceType(bundle.getInt(KEY_DEVICE_TYPE)) 634 .setDeviceRole(bundle.getInt(KEY_DEVICE_ROLE)) 635 .setRangingRoundUsage(bundle.getInt(KEY_RANGING_ROUND_USAGE)) 636 .setMultiNodeMode(bundle.getInt(KEY_MULTI_NODE_MODE)) 637 .setDeviceAddress(deviceAddress) 638 .setDestAddressList(destAddressList) 639 .setInitiationTimeMs(bundle.getInt(KEY_INITIATION_TIME_MS)) 640 .setSlotDurationRstu(bundle.getInt(KEY_SLOT_DURATION_RSTU)) 641 .setSlotsPerRangingRound(bundle.getInt(KEY_SLOTS_PER_RANGING_ROUND)) 642 .setRangingIntervalMs(bundle.getInt(KEY_RANGING_INTERVAL_MS)) 643 .setBlockStrideLength(bundle.getInt(KEY_BLOCK_STRIDE_LENGTH)) 644 .setHoppingMode(bundle.getInt(KEY_HOPPING_MODE)) 645 .setMaxRangingRoundRetries(bundle.getInt(KEY_MAX_RANGING_ROUND_RETRIES)) 646 .setSessionPriority(bundle.getInt(KEY_SESSION_PRIORITY)) 647 .setMacAddressMode(bundle.getInt(KEY_MAC_ADDRESS_MODE)) 648 .setHasResultReportPhase(bundle.getBoolean(KEY_HAS_RESULT_REPORT_PHASE)) 649 .setMeasurementReportType(bundle.getInt(KEY_MEASUREMENT_REPORT_TYPE)) 650 .setInBandTerminationAttemptCount( 651 bundle.getInt(KEY_IN_BAND_TERMINATION_ATTEMPT_COUNT)) 652 .setChannelNumber(bundle.getInt(KEY_CHANNEL_NUMBER)) 653 .setPreambleCodeIndex(bundle.getInt(KEY_PREAMBLE_CODE_INDEX)) 654 .setRframeConfig(bundle.getInt(KEY_RFRAME_CONFIG)) 655 .setPrfMode(bundle.getInt(KEY_PRF_MODE)) 656 .setPreambleDuration(bundle.getInt(KEY_PREAMBLE_DURATION)) 657 .setSfdId(bundle.getInt(KEY_SFD_ID)) 658 .setStsSegmentCount(bundle.getInt(KEY_STS_SEGMENT_COUNT)) 659 .setStsLength(bundle.getInt(KEY_STS_LENGTH)) 660 .setPsduDataRate(bundle.getInt(KEY_PSDU_DATA_RATE)) 661 .setBprfPhrDataRate(bundle.getInt(KEY_BPRF_PHR_DATA_RATE)) 662 .setFcsType(bundle.getInt(KEY_FCS_TYPE)) 663 .setIsTxAdaptivePayloadPowerEnabled( 664 bundle.getBoolean(KEY_IS_TX_ADAPTIVE_PAYLOAD_POWER_ENABLED)) 665 .setStsConfig(bundle.getInt(KEY_STS_CONFIG)) 666 .setSubSessionId(bundle.getInt(KEY_SUB_SESSION_ID)) 667 .setVendorId(intArrayToByteArray(bundle.getIntArray(KEY_VENDOR_ID))) 668 .setStaticStsIV(intArrayToByteArray(bundle.getIntArray(KEY_STATIC_STS_IV))) 669 .setIsKeyRotationEnabled(bundle.getBoolean(KEY_IS_KEY_ROTATION_ENABLED)) 670 .setKeyRotationRate(bundle.getInt(KEY_KEY_ROTATION_RATE)) 671 .setAoaResultRequest(bundle.getInt(KEY_AOA_RESULT_REQUEST)) 672 .setRangeDataNtfConfig(bundle.getInt(KEY_RANGE_DATA_NTF_CONFIG)) 673 .setRangeDataNtfProximityNear(bundle.getInt(KEY_RANGE_DATA_NTF_PROXIMITY_NEAR)) 674 .setRangeDataNtfProximityFar(bundle.getInt(KEY_RANGE_DATA_NTF_PROXIMITY_FAR)) 675 .setHasTimeOfFlightReport(bundle.getBoolean(KEY_HAS_TIME_OF_FLIGHT_REPORT)) 676 .setHasAngleOfArrivalAzimuthReport( 677 bundle.getBoolean(KEY_HAS_ANGLE_OF_ARRIVAL_AZIMUTH_REPORT)) 678 .setHasAngleOfArrivalElevationReport( 679 bundle.getBoolean(KEY_HAS_ANGLE_OF_ARRIVAL_ELEVATION_REPORT)) 680 .setHasAngleOfArrivalFigureOfMeritReport( 681 bundle.getBoolean(KEY_HAS_ANGLE_OF_ARRIVAL_FIGURE_OF_MERIT_REPORT)) 682 .setAoaType(bundle.getInt(KEY_AOA_TYPE)) 683 .setMeasurementFocusRatio( 684 bundle.getInt(KEY_NUM_OF_MSRMT_FOCUS_ON_RANGE), 685 bundle.getInt(KEY_NUM_OF_MSRMT_FOCUS_ON_AOA_AZIMUTH), 686 bundle.getInt(KEY_NUM_OF_MSRMT_FOCUS_ON_AOA_ELEVATION)) 687 .build(); 688 } 689 getProtocolVersion()690 public FiraProtocolVersion getProtocolVersion() { 691 return mProtocolVersion; 692 } 693 694 /** Builder */ 695 public static final class Builder { 696 private final RequiredParam<FiraProtocolVersion> mProtocolVersion = new RequiredParam<>(); 697 698 private final RequiredParam<Integer> mSessionId = new RequiredParam<>(); 699 private final RequiredParam<Integer> mDeviceType = new RequiredParam<>(); 700 private final RequiredParam<Integer> mDeviceRole = new RequiredParam<>(); 701 702 /** UCI spec default: DS-TWR with deferred mode */ 703 @RangingRoundUsage 704 private int mRangingRoundUsage = RANGING_ROUND_USAGE_DS_TWR_DEFERRED_MODE; 705 706 private final RequiredParam<Integer> mMultiNodeMode = new RequiredParam<>(); 707 private UwbAddress mDeviceAddress = null; 708 private List<UwbAddress> mDestAddressList = null; 709 710 /** UCI spec default: 0ms */ 711 private int mInitiationTimeMs = 0; 712 713 /** UCI spec default: 2400 RSTU (2 ms). */ 714 private int mSlotDurationRstu = 2400; 715 716 /** UCI spec default: 30 slots per ranging round. */ 717 private int mSlotsPerRangingRound = 30; 718 719 /** UCI spec default: RANGING_INTERVAL 200 ms */ 720 private int mRangingIntervalMs = 200; 721 722 /** UCI spec default: no block striding. */ 723 private int mBlockStrideLength = 0; 724 725 /** UCI spec default: no hopping. */ 726 private int mHoppingMode = HOPPING_MODE_DISABLE; 727 728 /** UCI spec default: Termination is disabled and ranging round attempt is infinite */ 729 @IntRange(from = 0, to = 65535) 730 private int mMaxRangingRoundRetries = 0; 731 732 /** UCI spec default: priority 50 */ 733 private int mSessionPriority = 50; 734 735 /** UCI spec default: 2-byte short address */ 736 @MacAddressMode private int mMacAddressMode = MAC_ADDRESS_MODE_2_BYTES; 737 738 /** UCI spec default: RANGING_ROUND_CONTROL bit 0 default 1 */ 739 private boolean mHasResultReportPhase = true; 740 741 /** UCI spec default: RANGING_ROUND_CONTROL bit 7 default 0 */ 742 @MeasurementReportType 743 private int mMeasurementReportType = MEASUREMENT_REPORT_TYPE_INITIATOR_TO_RESPONDER; 744 745 /** UCI spec default: in-band termination signal will be sent once. */ 746 @IntRange(from = 1, to = 10) 747 private int mInBandTerminationAttemptCount = 1; 748 749 /** UCI spec default: Channel 9, which is the only mandatory channel. */ 750 @UwbChannel private int mChannelNumber = UWB_CHANNEL_9; 751 752 /** UCI spec default: index 10 */ 753 @UwbPreambleCodeIndex private int mPreambleCodeIndex = UWB_PREAMBLE_CODE_INDEX_10; 754 755 /** UCI spec default: SP3 */ 756 private int mRframeConfig = RFRAME_CONFIG_SP3; 757 758 /** UCI spec default: BPRF */ 759 @PrfMode private int mPrfMode = PRF_MODE_BPRF; 760 761 /** UCI spec default: 64 symbols */ 762 @PreambleDuration private int mPreambleDuration = PREAMBLE_DURATION_T64_SYMBOLS; 763 764 /** UCI spec default: ID 2 */ 765 @SfdIdValue private int mSfdId = SFD_ID_VALUE_2; 766 767 /** UCI spec default: one STS segment */ 768 @StsSegmentCountValue private int mStsSegmentCount = STS_SEGMENT_COUNT_VALUE_1; 769 770 /** UCI spec default: 64 symbols */ 771 @StsLength private int mStsLength = STS_LENGTH_64_SYMBOLS; 772 773 /** UCI spec default: 6.81Mb/s */ 774 @PsduDataRate private int mPsduDataRate = PSDU_DATA_RATE_6M81; 775 776 /** UCI spec default: 850kb/s */ 777 @BprfPhrDataRate private int mBprfPhrDataRate = BPRF_PHR_DATA_RATE_850K; 778 779 /** UCI spec default: CRC-16 */ 780 @MacFcsType private int mFcsType = MAC_FCS_TYPE_CRC_16; 781 782 /** UCI spec default: adaptive payload power for TX disabled */ 783 private boolean mIsTxAdaptivePayloadPowerEnabled = false; 784 785 /** UCI spec default: static STS */ 786 @StsConfig private int mStsConfig = STS_CONFIG_STATIC; 787 788 /** 789 * Per UCI spec, only required when STS config is 790 * STS_CONFIG_DYNAMIC_FOR_CONTROLEE_INDIVIDUAL_KEY. 791 */ 792 private final RequiredParam<Integer> mSubSessionId = new RequiredParam<>(); 793 794 /** STATIC STS only. For Key generation. 16-bit long */ 795 @Nullable private byte[] mVendorId = null; 796 797 /** STATIC STS only. For Key generation. 48-bit long */ 798 @Nullable private byte[] mStaticStsIV = null; 799 800 /** UCI spec default: no key rotation */ 801 private boolean mIsKeyRotationEnabled = false; 802 803 /** UCI spec default: 0 */ 804 private int mKeyRotationRate = 0; 805 806 /** UCI spec default: AoA enabled. */ 807 @AoaResultRequestMode 808 private int mAoaResultRequest = AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS; 809 810 /** UCI spec default: Ranging notification enabled. */ 811 @RangeDataNtfConfig private int mRangeDataNtfConfig = RANGE_DATA_NTF_CONFIG_ENABLE; 812 813 /** UCI spec default: 0 (No low-bound filtering) */ 814 private int mRangeDataNtfProximityNear = 0; 815 816 /** UCI spec default: 20000 cm (or 200 meters) */ 817 private int mRangeDataNtfProximityFar = 20000; 818 819 /** UCI spec default: RESULT_REPORT_CONFIG bit 0 is 1 */ 820 private boolean mHasTimeOfFlightReport = true; 821 822 /** UCI spec default: RESULT_REPORT_CONFIG bit 1 is 0 */ 823 private boolean mHasAngleOfArrivalAzimuthReport = false; 824 825 /** UCI spec default: RESULT_REPORT_CONFIG bit 2 is 0 */ 826 private boolean mHasAngleOfArrivalElevationReport = false; 827 828 /** UCI spec default: RESULT_REPORT_CONFIG bit 3 is 0 */ 829 private boolean mHasAngleOfArrivalFigureOfMeritReport = false; 830 831 /** Not defined in UCI, we use Azimuth-only as default */ 832 @AoaType private int mAoaType = AOA_TYPE_AZIMUTH; 833 834 /** Interleaving ratios are not set by default */ 835 private int mNumOfMsrmtFocusOnRange = 0; 836 private int mNumOfMsrmtFocusOnAoaAzimuth = 0; 837 private int mNumOfMsrmtFocusOnAoaElevation = 0; 838 Builder()839 public Builder() {} 840 Builder(@onNull Builder builder)841 public Builder(@NonNull Builder builder) { 842 mProtocolVersion.set(builder.mProtocolVersion.get()); 843 mSessionId.set(builder.mSessionId.get()); 844 mDeviceType.set(builder.mDeviceType.get()); 845 mDeviceRole.set(builder.mDeviceRole.get()); 846 mRangingRoundUsage = builder.mRangingRoundUsage; 847 mMultiNodeMode.set(builder.mMultiNodeMode.get()); 848 mDeviceAddress = builder.mDeviceAddress; 849 mDestAddressList = builder.mDestAddressList; 850 mInitiationTimeMs = builder.mInitiationTimeMs; 851 mSlotDurationRstu = builder.mSlotDurationRstu; 852 mSlotsPerRangingRound = builder.mSlotsPerRangingRound; 853 mRangingIntervalMs = builder.mRangingIntervalMs; 854 mBlockStrideLength = builder.mBlockStrideLength; 855 mHoppingMode = builder.mHoppingMode; 856 mMaxRangingRoundRetries = builder.mMaxRangingRoundRetries; 857 mSessionPriority = builder.mSessionPriority; 858 mMacAddressMode = builder.mMacAddressMode; 859 mHasResultReportPhase = builder.mHasResultReportPhase; 860 mMeasurementReportType = builder.mMeasurementReportType; 861 mInBandTerminationAttemptCount = builder.mInBandTerminationAttemptCount; 862 mChannelNumber = builder.mChannelNumber; 863 mPreambleCodeIndex = builder.mPreambleCodeIndex; 864 mRframeConfig = builder.mRframeConfig; 865 mPrfMode = builder.mPrfMode; 866 mPreambleDuration = builder.mPreambleDuration; 867 mSfdId = builder.mSfdId; 868 mStsSegmentCount = builder.mStsSegmentCount; 869 mStsLength = builder.mStsLength; 870 mPsduDataRate = builder.mPsduDataRate; 871 mBprfPhrDataRate = builder.mBprfPhrDataRate; 872 mFcsType = builder.mFcsType; 873 mIsTxAdaptivePayloadPowerEnabled = builder.mIsTxAdaptivePayloadPowerEnabled; 874 mStsConfig = builder.mStsConfig; 875 if (builder.mSubSessionId.isSet()) mSubSessionId.set(builder.mSubSessionId.get()); 876 mVendorId = builder.mVendorId; 877 mStaticStsIV = builder.mStaticStsIV; 878 mIsKeyRotationEnabled = builder.mIsKeyRotationEnabled; 879 mKeyRotationRate = builder.mKeyRotationRate; 880 mAoaResultRequest = builder.mAoaResultRequest; 881 mRangeDataNtfConfig = builder.mRangeDataNtfConfig; 882 mRangeDataNtfProximityNear = builder.mRangeDataNtfProximityNear; 883 mRangeDataNtfProximityFar = builder.mRangeDataNtfProximityFar; 884 mHasTimeOfFlightReport = builder.mHasTimeOfFlightReport; 885 mHasAngleOfArrivalAzimuthReport = builder.mHasAngleOfArrivalAzimuthReport; 886 mHasAngleOfArrivalElevationReport = builder.mHasAngleOfArrivalElevationReport; 887 mHasAngleOfArrivalFigureOfMeritReport = builder.mHasAngleOfArrivalFigureOfMeritReport; 888 mAoaType = builder.mAoaType; 889 } 890 setProtocolVersion(FiraProtocolVersion version)891 public FiraOpenSessionParams.Builder setProtocolVersion(FiraProtocolVersion version) { 892 mProtocolVersion.set(version); 893 return this; 894 } 895 setSessionId(int sessionId)896 public FiraOpenSessionParams.Builder setSessionId(int sessionId) { 897 mSessionId.set(sessionId); 898 return this; 899 } 900 setDeviceType(@angingDeviceType int deviceType)901 public FiraOpenSessionParams.Builder setDeviceType(@RangingDeviceType int deviceType) { 902 mDeviceType.set(deviceType); 903 return this; 904 } 905 setDeviceRole(@angingDeviceRole int deviceRole)906 public FiraOpenSessionParams.Builder setDeviceRole(@RangingDeviceRole int deviceRole) { 907 mDeviceRole.set(deviceRole); 908 return this; 909 } 910 setRangingRoundUsage( @angingRoundUsage int rangingRoundUsage)911 public FiraOpenSessionParams.Builder setRangingRoundUsage( 912 @RangingRoundUsage int rangingRoundUsage) { 913 mRangingRoundUsage = rangingRoundUsage; 914 return this; 915 } 916 setMultiNodeMode(@ultiNodeMode int multiNodeMode)917 public FiraOpenSessionParams.Builder setMultiNodeMode(@MultiNodeMode int multiNodeMode) { 918 mMultiNodeMode.set(multiNodeMode); 919 return this; 920 } 921 setDeviceAddress(UwbAddress deviceAddress)922 public FiraOpenSessionParams.Builder setDeviceAddress(UwbAddress deviceAddress) { 923 mDeviceAddress = deviceAddress; 924 return this; 925 } 926 setDestAddressList(List<UwbAddress> destAddressList)927 public FiraOpenSessionParams.Builder setDestAddressList(List<UwbAddress> destAddressList) { 928 mDestAddressList = destAddressList; 929 return this; 930 } 931 setInitiationTimeMs(int initiationTimeMs)932 public FiraOpenSessionParams.Builder setInitiationTimeMs(int initiationTimeMs) { 933 mInitiationTimeMs = initiationTimeMs; 934 return this; 935 } 936 setSlotDurationRstu(int slotDurationRstu)937 public FiraOpenSessionParams.Builder setSlotDurationRstu(int slotDurationRstu) { 938 mSlotDurationRstu = slotDurationRstu; 939 return this; 940 } 941 setSlotsPerRangingRound(int slotsPerRangingRound)942 public FiraOpenSessionParams.Builder setSlotsPerRangingRound(int slotsPerRangingRound) { 943 mSlotsPerRangingRound = slotsPerRangingRound; 944 return this; 945 } 946 setRangingIntervalMs(int rangingIntervalMs)947 public FiraOpenSessionParams.Builder setRangingIntervalMs(int rangingIntervalMs) { 948 mRangingIntervalMs = rangingIntervalMs; 949 return this; 950 } 951 setBlockStrideLength(int blockStrideLength)952 public FiraOpenSessionParams.Builder setBlockStrideLength(int blockStrideLength) { 953 mBlockStrideLength = blockStrideLength; 954 return this; 955 } 956 setHoppingMode(int hoppingMode)957 public FiraOpenSessionParams.Builder setHoppingMode(int hoppingMode) { 958 this.mHoppingMode = hoppingMode; 959 return this; 960 } 961 setMaxRangingRoundRetries( @ntRangefrom = 0, to = 65535) int maxRangingRoundRetries)962 public FiraOpenSessionParams.Builder setMaxRangingRoundRetries( 963 @IntRange(from = 0, to = 65535) int maxRangingRoundRetries) { 964 mMaxRangingRoundRetries = maxRangingRoundRetries; 965 return this; 966 } 967 setSessionPriority(int sessionPriority)968 public FiraOpenSessionParams.Builder setSessionPriority(int sessionPriority) { 969 mSessionPriority = sessionPriority; 970 return this; 971 } 972 setMacAddressMode(int macAddressMode)973 public FiraOpenSessionParams.Builder setMacAddressMode(int macAddressMode) { 974 this.mMacAddressMode = macAddressMode; 975 return this; 976 } 977 setHasResultReportPhase(boolean hasResultReportPhase)978 public FiraOpenSessionParams.Builder setHasResultReportPhase(boolean hasResultReportPhase) { 979 mHasResultReportPhase = hasResultReportPhase; 980 return this; 981 } 982 setMeasurementReportType( @easurementReportType int measurementReportType)983 public FiraOpenSessionParams.Builder setMeasurementReportType( 984 @MeasurementReportType int measurementReportType) { 985 mMeasurementReportType = measurementReportType; 986 return this; 987 } 988 setInBandTerminationAttemptCount( @ntRangefrom = 1, to = 10) int inBandTerminationAttemptCount)989 public FiraOpenSessionParams.Builder setInBandTerminationAttemptCount( 990 @IntRange(from = 1, to = 10) int inBandTerminationAttemptCount) { 991 mInBandTerminationAttemptCount = inBandTerminationAttemptCount; 992 return this; 993 } 994 setChannelNumber(@wbChannel int channelNumber)995 public FiraOpenSessionParams.Builder setChannelNumber(@UwbChannel int channelNumber) { 996 mChannelNumber = channelNumber; 997 return this; 998 } 999 setPreambleCodeIndex( @wbPreambleCodeIndex int preambleCodeIndex)1000 public FiraOpenSessionParams.Builder setPreambleCodeIndex( 1001 @UwbPreambleCodeIndex int preambleCodeIndex) { 1002 mPreambleCodeIndex = preambleCodeIndex; 1003 return this; 1004 } 1005 setRframeConfig(@frameConfig int rframeConfig)1006 public FiraOpenSessionParams.Builder setRframeConfig(@RframeConfig int rframeConfig) { 1007 mRframeConfig = rframeConfig; 1008 return this; 1009 } 1010 setPrfMode(@rfMode int prfMode)1011 public FiraOpenSessionParams.Builder setPrfMode(@PrfMode int prfMode) { 1012 mPrfMode = prfMode; 1013 return this; 1014 } 1015 setPreambleDuration( @reambleDuration int preambleDuration)1016 public FiraOpenSessionParams.Builder setPreambleDuration( 1017 @PreambleDuration int preambleDuration) { 1018 mPreambleDuration = preambleDuration; 1019 return this; 1020 } 1021 setSfdId(@fdIdValue int sfdId)1022 public FiraOpenSessionParams.Builder setSfdId(@SfdIdValue int sfdId) { 1023 mSfdId = sfdId; 1024 return this; 1025 } 1026 setStsSegmentCount( @tsSegmentCountValue int stsSegmentCount)1027 public FiraOpenSessionParams.Builder setStsSegmentCount( 1028 @StsSegmentCountValue int stsSegmentCount) { 1029 mStsSegmentCount = stsSegmentCount; 1030 return this; 1031 } 1032 setStsLength(@tsLength int stsLength)1033 public FiraOpenSessionParams.Builder setStsLength(@StsLength int stsLength) { 1034 mStsLength = stsLength; 1035 return this; 1036 } 1037 setPsduDataRate(@sduDataRate int psduDataRate)1038 public FiraOpenSessionParams.Builder setPsduDataRate(@PsduDataRate int psduDataRate) { 1039 mPsduDataRate = psduDataRate; 1040 return this; 1041 } 1042 setBprfPhrDataRate( @prfPhrDataRate int bprfPhrDataRate)1043 public FiraOpenSessionParams.Builder setBprfPhrDataRate( 1044 @BprfPhrDataRate int bprfPhrDataRate) { 1045 mBprfPhrDataRate = bprfPhrDataRate; 1046 return this; 1047 } 1048 setFcsType(@acFcsType int fcsType)1049 public FiraOpenSessionParams.Builder setFcsType(@MacFcsType int fcsType) { 1050 mFcsType = fcsType; 1051 return this; 1052 } 1053 setIsTxAdaptivePayloadPowerEnabled( boolean isTxAdaptivePayloadPowerEnabled)1054 public FiraOpenSessionParams.Builder setIsTxAdaptivePayloadPowerEnabled( 1055 boolean isTxAdaptivePayloadPowerEnabled) { 1056 mIsTxAdaptivePayloadPowerEnabled = isTxAdaptivePayloadPowerEnabled; 1057 return this; 1058 } 1059 setStsConfig(@tsConfig int stsConfig)1060 public FiraOpenSessionParams.Builder setStsConfig(@StsConfig int stsConfig) { 1061 mStsConfig = stsConfig; 1062 return this; 1063 } 1064 setSubSessionId(int subSessionId)1065 public FiraOpenSessionParams.Builder setSubSessionId(int subSessionId) { 1066 mSubSessionId.set(subSessionId); 1067 return this; 1068 } 1069 setVendorId(@ullable byte[] vendorId)1070 public FiraOpenSessionParams.Builder setVendorId(@Nullable byte[] vendorId) { 1071 mVendorId = vendorId; 1072 return this; 1073 } 1074 setStaticStsIV(@ullable byte[] staticStsIV)1075 public FiraOpenSessionParams.Builder setStaticStsIV(@Nullable byte[] staticStsIV) { 1076 mStaticStsIV = staticStsIV; 1077 return this; 1078 } 1079 setIsKeyRotationEnabled(boolean isKeyRotationEnabled)1080 public FiraOpenSessionParams.Builder setIsKeyRotationEnabled(boolean isKeyRotationEnabled) { 1081 mIsKeyRotationEnabled = isKeyRotationEnabled; 1082 return this; 1083 } 1084 setKeyRotationRate(int keyRotationRate)1085 public FiraOpenSessionParams.Builder setKeyRotationRate(int keyRotationRate) { 1086 mKeyRotationRate = keyRotationRate; 1087 return this; 1088 } 1089 setAoaResultRequest( @oaResultRequestMode int aoaResultRequest)1090 public FiraOpenSessionParams.Builder setAoaResultRequest( 1091 @AoaResultRequestMode int aoaResultRequest) { 1092 mAoaResultRequest = aoaResultRequest; 1093 return this; 1094 } 1095 setRangeDataNtfConfig( @angeDataNtfConfig int rangeDataNtfConfig)1096 public FiraOpenSessionParams.Builder setRangeDataNtfConfig( 1097 @RangeDataNtfConfig int rangeDataNtfConfig) { 1098 mRangeDataNtfConfig = rangeDataNtfConfig; 1099 return this; 1100 } 1101 setRangeDataNtfProximityNear( int rangeDataNtfProximityNear)1102 public FiraOpenSessionParams.Builder setRangeDataNtfProximityNear( 1103 int rangeDataNtfProximityNear) { 1104 mRangeDataNtfProximityNear = rangeDataNtfProximityNear; 1105 return this; 1106 } 1107 setRangeDataNtfProximityFar( int rangeDataNtfProximityFar)1108 public FiraOpenSessionParams.Builder setRangeDataNtfProximityFar( 1109 int rangeDataNtfProximityFar) { 1110 mRangeDataNtfProximityFar = rangeDataNtfProximityFar; 1111 return this; 1112 } 1113 setHasTimeOfFlightReport( boolean hasTimeOfFlightReport)1114 public FiraOpenSessionParams.Builder setHasTimeOfFlightReport( 1115 boolean hasTimeOfFlightReport) { 1116 mHasTimeOfFlightReport = hasTimeOfFlightReport; 1117 return this; 1118 } 1119 setHasAngleOfArrivalAzimuthReport( boolean hasAngleOfArrivalAzimuthReport)1120 public FiraOpenSessionParams.Builder setHasAngleOfArrivalAzimuthReport( 1121 boolean hasAngleOfArrivalAzimuthReport) { 1122 mHasAngleOfArrivalAzimuthReport = hasAngleOfArrivalAzimuthReport; 1123 return this; 1124 } 1125 setHasAngleOfArrivalElevationReport( boolean hasAngleOfArrivalElevationReport)1126 public FiraOpenSessionParams.Builder setHasAngleOfArrivalElevationReport( 1127 boolean hasAngleOfArrivalElevationReport) { 1128 mHasAngleOfArrivalElevationReport = hasAngleOfArrivalElevationReport; 1129 return this; 1130 } 1131 setHasAngleOfArrivalFigureOfMeritReport( boolean hasAngleOfArrivalFigureOfMeritReport)1132 public FiraOpenSessionParams.Builder setHasAngleOfArrivalFigureOfMeritReport( 1133 boolean hasAngleOfArrivalFigureOfMeritReport) { 1134 mHasAngleOfArrivalFigureOfMeritReport = hasAngleOfArrivalFigureOfMeritReport; 1135 return this; 1136 } 1137 setAoaType(int aoaType)1138 public FiraOpenSessionParams.Builder setAoaType(int aoaType) { 1139 mAoaType = aoaType; 1140 return this; 1141 } 1142 1143 /** 1144 * After the session has been started, the device starts by 1145 * performing numOfMsrmtFocusOnRange range-only measurements (no 1146 * AoA), then it proceeds with numOfMsrmtFocusOnAoaAzimuth AoA 1147 * azimuth measurements followed by numOfMsrmtFocusOnAoaElevation 1148 * AoA elevation measurements. 1149 * If this is not invoked, the focus of each measurement is left 1150 * to the UWB vendor. 1151 * 1152 * Only valid when {@link #setAoaResultRequest(int)} is set to 1153 * {@link FiraParams#AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_INTERLEAVED}. 1154 */ setMeasurementFocusRatio( int numOfMsrmtFocusOnRange, int numOfMsrmtFocusOnAoaAzimuth, int numOfMsrmtFocusOnAoaElevation)1155 public FiraOpenSessionParams.Builder setMeasurementFocusRatio( 1156 int numOfMsrmtFocusOnRange, 1157 int numOfMsrmtFocusOnAoaAzimuth, 1158 int numOfMsrmtFocusOnAoaElevation) { 1159 mNumOfMsrmtFocusOnRange = numOfMsrmtFocusOnRange; 1160 mNumOfMsrmtFocusOnAoaAzimuth = numOfMsrmtFocusOnAoaAzimuth; 1161 mNumOfMsrmtFocusOnAoaElevation = numOfMsrmtFocusOnAoaElevation; 1162 return this; 1163 } 1164 checkAddress()1165 private void checkAddress() { 1166 checkArgument( 1167 mMacAddressMode == MAC_ADDRESS_MODE_2_BYTES 1168 || mMacAddressMode == MAC_ADDRESS_MODE_8_BYTES); 1169 int addressByteLength = UwbAddress.SHORT_ADDRESS_BYTE_LENGTH; 1170 if (mMacAddressMode == MAC_ADDRESS_MODE_8_BYTES) { 1171 addressByteLength = UwbAddress.EXTENDED_ADDRESS_BYTE_LENGTH; 1172 } 1173 1174 // Make sure address length matches the address mode 1175 checkArgument(mDeviceAddress != null && mDeviceAddress.size() == addressByteLength); 1176 checkNotNull(mDestAddressList); 1177 for (UwbAddress destAddress : mDestAddressList) { 1178 checkArgument(destAddress != null && destAddress.size() == addressByteLength); 1179 } 1180 } 1181 checkStsConfig()1182 private void checkStsConfig() { 1183 if (mStsConfig == STS_CONFIG_STATIC) { 1184 // These two fields are used by Static STS only. 1185 checkArgument(mVendorId != null && mVendorId.length == 2); 1186 checkArgument(mStaticStsIV != null && mStaticStsIV.length == 6); 1187 } 1188 1189 if (mStsConfig != STS_CONFIG_DYNAMIC_FOR_CONTROLEE_INDIVIDUAL_KEY) { 1190 // Sub Session ID is used for dynamic individual key STS only. 1191 if (!mSubSessionId.isSet()) { 1192 mSubSessionId.set(0); 1193 } 1194 } 1195 } 1196 checkInterleavingRatio()1197 private void checkInterleavingRatio() { 1198 if (mAoaResultRequest != AOA_RESULT_REQUEST_MODE_REQ_AOA_RESULTS_INTERLEAVED) { 1199 checkArgument(mNumOfMsrmtFocusOnRange == 0); 1200 checkArgument(mNumOfMsrmtFocusOnAoaAzimuth == 0); 1201 checkArgument(mNumOfMsrmtFocusOnAoaElevation == 0); 1202 } else { 1203 // at-least one of the ratio params should be set for interleaving mode. 1204 checkArgument(mNumOfMsrmtFocusOnRange > 0 1205 || mNumOfMsrmtFocusOnAoaAzimuth > 0 1206 || mNumOfMsrmtFocusOnAoaElevation > 0); 1207 } 1208 } 1209 build()1210 public FiraOpenSessionParams build() { 1211 checkAddress(); 1212 checkStsConfig(); 1213 checkInterleavingRatio(); 1214 return new FiraOpenSessionParams( 1215 mProtocolVersion.get(), 1216 mSessionId.get(), 1217 mDeviceType.get(), 1218 mDeviceRole.get(), 1219 mRangingRoundUsage, 1220 mMultiNodeMode.get(), 1221 mDeviceAddress, 1222 mDestAddressList, 1223 mInitiationTimeMs, 1224 mSlotDurationRstu, 1225 mSlotsPerRangingRound, 1226 mRangingIntervalMs, 1227 mBlockStrideLength, 1228 mHoppingMode, 1229 mMaxRangingRoundRetries, 1230 mSessionPriority, 1231 mMacAddressMode, 1232 mHasResultReportPhase, 1233 mMeasurementReportType, 1234 mInBandTerminationAttemptCount, 1235 mChannelNumber, 1236 mPreambleCodeIndex, 1237 mRframeConfig, 1238 mPrfMode, 1239 mPreambleDuration, 1240 mSfdId, 1241 mStsSegmentCount, 1242 mStsLength, 1243 mPsduDataRate, 1244 mBprfPhrDataRate, 1245 mFcsType, 1246 mIsTxAdaptivePayloadPowerEnabled, 1247 mStsConfig, 1248 mSubSessionId.get(), 1249 mVendorId, 1250 mStaticStsIV, 1251 mIsKeyRotationEnabled, 1252 mKeyRotationRate, 1253 mAoaResultRequest, 1254 mRangeDataNtfConfig, 1255 mRangeDataNtfProximityNear, 1256 mRangeDataNtfProximityFar, 1257 mHasTimeOfFlightReport, 1258 mHasAngleOfArrivalAzimuthReport, 1259 mHasAngleOfArrivalElevationReport, 1260 mHasAngleOfArrivalFigureOfMeritReport, 1261 mAoaType, 1262 mNumOfMsrmtFocusOnRange, 1263 mNumOfMsrmtFocusOnAoaAzimuth, 1264 mNumOfMsrmtFocusOnAoaElevation); 1265 } 1266 } 1267 } 1268