• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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