1 /* 2 * Copyright (C) 2017 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 android.net.wifi.rtt; 18 19 import android.annotation.ElapsedRealtimeLong; 20 import android.annotation.FlaggedApi; 21 import android.annotation.IntDef; 22 import android.annotation.IntRange; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.SuppressLint; 26 import android.annotation.SystemApi; 27 import android.net.MacAddress; 28 import android.net.wifi.OuiKeyedData; 29 import android.net.wifi.ParcelUtil; 30 import android.net.wifi.ScanResult; 31 import android.net.wifi.WifiAnnotations.ChannelWidth; 32 import android.net.wifi.aware.PeerHandle; 33 import android.os.Build; 34 import android.os.Parcel; 35 import android.os.Parcelable; 36 import android.util.Log; 37 38 import androidx.annotation.RequiresApi; 39 40 import com.android.modules.utils.build.SdkLevel; 41 import com.android.wifi.flags.Flags; 42 43 import java.lang.annotation.Retention; 44 import java.lang.annotation.RetentionPolicy; 45 import java.util.ArrayList; 46 import java.util.Arrays; 47 import java.util.Collections; 48 import java.util.List; 49 import java.util.Objects; 50 51 /** 52 * Ranging result for a request started by 53 * {@link WifiRttManager#startRanging(RangingRequest, java.util.concurrent.Executor, RangingResultCallback)}. 54 * Results are returned in {@link RangingResultCallback#onRangingResults(List)}. 55 * <p> 56 * A ranging result is the distance measurement result for a single device specified in the 57 * {@link RangingRequest}. 58 */ 59 public final class RangingResult implements Parcelable { 60 private static final String TAG = "RangingResult"; 61 private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; 62 63 /** @hide */ 64 @IntDef({STATUS_SUCCESS, STATUS_FAIL, STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC}) 65 @Retention(RetentionPolicy.SOURCE) 66 public @interface RangeResultStatus { 67 } 68 69 /** 70 * Individual range request status, {@link #getStatus()}. Indicates ranging operation was 71 * successful and distance value is valid. 72 */ 73 public static final int STATUS_SUCCESS = 0; 74 75 /** 76 * Individual range request status, {@link #getStatus()}. Indicates ranging operation failed 77 * and the distance value is invalid. 78 */ 79 public static final int STATUS_FAIL = 1; 80 81 /** 82 * Individual range request status, {@link #getStatus()}. Indicates that the ranging operation 83 * failed because the specified peer does not support IEEE 802.11mc RTT operations. Support by 84 * an Access Point can be confirmed using 85 * {@link android.net.wifi.ScanResult#is80211mcResponder()}. 86 * <p> 87 * On such a failure, the individual result fields of {@link RangingResult} such as 88 * {@link RangingResult#getDistanceMm()} are invalid. 89 */ 90 public static final int STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC = 2; 91 92 /** 93 * The unspecified value. 94 */ 95 public static final int UNSPECIFIED = -1; 96 97 private final @RangeResultStatus int mStatus; 98 private final MacAddress mMac; 99 private final PeerHandle mPeerHandle; 100 private final int mDistanceMm; 101 private final int mDistanceStdDevMm; 102 private final int mRssi; 103 private final int mNumAttemptedMeasurements; 104 private final int mNumSuccessfulMeasurements; 105 private final byte[] mLci; 106 private final byte[] mLcr; 107 private final ResponderLocation mResponderLocation; 108 private final long mTimestamp; 109 private final boolean mIs80211mcMeasurement; 110 private final int mFrequencyMHz; 111 private final int mPacketBw; 112 private final boolean mIs80211azNtbMeasurement; 113 private final long mNtbMinMeasurementTime; 114 private final long mNtbMaxMeasurementTime; 115 private final int mI2rTxLtfRepetitions; 116 private final int mR2iTxLtfRepetitions; 117 private final int mNumTxSpatialStreams; 118 private final int mNumRxSpatialStreams; 119 private List<OuiKeyedData> mVendorData; 120 private final boolean mIsRangingAuthenticated; 121 private final boolean mIsRangingFrameProtected; 122 private final boolean mIsSecureHeLtfEnabled; 123 private final int mSecureHeLtfProtocolVersion; 124 private final byte[] mPasnComebackCookie; 125 private final long mPasnComebackAfterMillis; 126 127 /** 128 * Builder class used to construct {@link RangingResult} objects. 129 */ 130 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 131 public static final class Builder { 132 private @RangeResultStatus int mStatus = STATUS_FAIL; 133 private MacAddress mMac = null; 134 private PeerHandle mPeerHandle = null; 135 private int mDistanceMm = 0; 136 private int mDistanceStdDevMm = 0; 137 private int mRssi = -127; 138 private int mNumAttemptedMeasurements = 0; 139 private int mNumSuccessfulMeasurements = 0; 140 private byte[] mLci = null; 141 private byte[] mLcr = null; 142 private ResponderLocation mResponderLocation = null; 143 private long mTimestamp = 0; 144 private boolean mIs80211mcMeasurement = false; 145 private int mFrequencyMHz = UNSPECIFIED; 146 private int mPacketBw = UNSPECIFIED; 147 private boolean mIs80211azNtbMeasurement = false; 148 private long mNtbMinMeasurementTime = UNSPECIFIED; 149 private long mNtbMaxMeasurementTime = UNSPECIFIED; 150 private int mI2rTxLtfRepetitions = UNSPECIFIED; 151 private int mR2iTxLtfRepetitions = UNSPECIFIED; 152 private int mNumTxSpatialStreams = UNSPECIFIED; 153 private int mNumRxSpatialStreams = UNSPECIFIED; 154 private List<OuiKeyedData> mVendorData = Collections.emptyList(); 155 private boolean mIsRangingAuthenticated; 156 private boolean mIsRangingFrameProtected; 157 private boolean mIsSecureHeLtfEnabled; 158 private int mSecureHeLtfProtocolVersion; 159 private byte[] mPasnComebackCookie = null; 160 private long mPasnComebackAfterMillis = UNSPECIFIED; 161 162 /** 163 * Constructs a Builder with default values (see {@link Builder}). 164 */ Builder()165 public Builder() {} 166 167 /** 168 * Constructs a Builder initialized from an existing {@link RangingResult} instance. 169 * 170 * @hide 171 */ Builder(@onNull RangingResult other)172 public Builder(@NonNull RangingResult other) { 173 if (other == null) { 174 Log.e(TAG, "Cannot provide a null RangingResult"); 175 return; 176 } 177 178 mStatus = other.mStatus; 179 mMac = other.mMac; 180 mPeerHandle = other.mPeerHandle; 181 mDistanceMm = other.mDistanceMm; 182 mDistanceStdDevMm = other.mDistanceStdDevMm; 183 mRssi = other.mRssi; 184 mNumAttemptedMeasurements = other.mNumAttemptedMeasurements; 185 mNumSuccessfulMeasurements = other.mNumSuccessfulMeasurements; 186 if (other.mLci != null) mLci = other.mLci.clone(); 187 if (other.mLcr != null) mLcr = other.mLcr.clone(); 188 mResponderLocation = new ResponderLocation(mLci, mLcr); 189 mTimestamp = other.mTimestamp; 190 mIs80211mcMeasurement = other.mIs80211mcMeasurement; 191 mFrequencyMHz = other.mFrequencyMHz; 192 mPacketBw = other.mPacketBw; 193 mIs80211azNtbMeasurement = other.mIs80211azNtbMeasurement; 194 mNtbMinMeasurementTime = other.mNtbMinMeasurementTime; 195 mNtbMaxMeasurementTime = other.mNtbMaxMeasurementTime; 196 mI2rTxLtfRepetitions = other.mI2rTxLtfRepetitions; 197 mR2iTxLtfRepetitions = other.mR2iTxLtfRepetitions; 198 mNumTxSpatialStreams = other.mNumTxSpatialStreams; 199 mNumRxSpatialStreams = other.mNumRxSpatialStreams; 200 mIsRangingAuthenticated = other.mIsRangingAuthenticated; 201 mIsRangingFrameProtected = other.mIsRangingFrameProtected; 202 mIsSecureHeLtfEnabled = other.mIsSecureHeLtfEnabled; 203 mSecureHeLtfProtocolVersion = other.mSecureHeLtfProtocolVersion; 204 if (other.mPasnComebackCookie != null) { 205 mPasnComebackCookie = other.mPasnComebackCookie.clone(); 206 mPasnComebackAfterMillis = other.mPasnComebackAfterMillis; 207 } 208 mVendorData = new ArrayList<>(other.mVendorData); 209 } 210 211 /** 212 * Sets the Range result status. 213 * 214 * @param status Ranging result status, if not set defaults to 215 * {@link #STATUS_FAIL}. 216 * @return The builder to facilitate chaining. 217 */ 218 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 219 @NonNull setStatus(@angeResultStatus int status)220 public Builder setStatus(@RangeResultStatus int status) { 221 mStatus = status; 222 return this; 223 } 224 225 /** 226 * Sets the MAC address of the ranging result. 227 * 228 * @param macAddress Mac address, if not defaults to null. 229 * @return The builder to facilitate chaining. 230 */ 231 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 232 @NonNull setMacAddress(@ullable MacAddress macAddress)233 public Builder setMacAddress(@Nullable MacAddress macAddress) { 234 mMac = macAddress; 235 return this; 236 } 237 238 239 /** 240 * Sets the peer handle. Applicable only for NAN Ranging. 241 * 242 * @param peerHandle Opaque object used to represent a Wi-Fi Aware peer. If not set, 243 * defaults to null. 244 * @return The builder to facilitate chaining. 245 */ 246 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 247 @NonNull setPeerHandle(@ullable PeerHandle peerHandle)248 public Builder setPeerHandle(@Nullable PeerHandle peerHandle) { 249 mPeerHandle = peerHandle; 250 return this; 251 } 252 253 /** 254 * Sets the distance in millimeter. 255 * 256 * @param distanceMm distance. If not set, defaults to 0. 257 * @return The builder to facilitate chaining. 258 */ 259 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 260 @NonNull setDistanceMm(int distanceMm)261 public Builder setDistanceMm(int distanceMm) { 262 mDistanceMm = distanceMm; 263 return this; 264 } 265 266 /** 267 * Sets the standard deviation of the distance in millimeter. 268 * 269 * @param distanceStdDevMm Standard deviation of the distance measurement. If not set 270 * defaults to 0. 271 * @return The builder to facilitate chaining. 272 */ 273 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 274 @NonNull setDistanceStdDevMm(int distanceStdDevMm)275 public Builder setDistanceStdDevMm(int distanceStdDevMm) { 276 mDistanceStdDevMm = distanceStdDevMm; 277 return this; 278 } 279 280 /** 281 * Sets the average RSSI. 282 * 283 * @param rssi Average RSSI. If not set, defaults to -127. 284 * @return The builder to facilitate chaining. 285 */ 286 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 287 @NonNull setRssi(int rssi)288 public Builder setRssi(int rssi) { 289 mRssi = rssi; 290 return this; 291 } 292 293 /** 294 * Sets the total number of RTT measurements attempted. 295 * 296 * @param numAttemptedMeasurements Number of attempted measurements. If not set, default 297 * to 0. 298 * @return The builder to facilitate chaining. 299 */ 300 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 301 @NonNull setNumAttemptedMeasurements(int numAttemptedMeasurements)302 public Builder setNumAttemptedMeasurements(int numAttemptedMeasurements) { 303 mNumAttemptedMeasurements = numAttemptedMeasurements; 304 return this; 305 } 306 307 /** 308 * Sets the total number of successful RTT measurements. 309 * 310 * @param numSuccessfulMeasurements Number of successful measurements. If not set, default 311 * to 0. 312 * @return The builder to facilitate chaining. 313 */ 314 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 315 @NonNull setNumSuccessfulMeasurements(int numSuccessfulMeasurements)316 public Builder setNumSuccessfulMeasurements(int numSuccessfulMeasurements) { 317 mNumSuccessfulMeasurements = numSuccessfulMeasurements; 318 return this; 319 } 320 321 /** 322 * Sets the Location Configuration Information (LCI). 323 * 324 * LCI provides data about the access point's (AP) physical location, such as its 325 * latitude, longitude, and altitude. The format is specified in the IEEE 802.11-2016 326 * specifications, section 9.4.2.22.10. 327 * 328 * @param lci Location configuration information. If not set, defaults to null. 329 * @return The builder to facilitate chaining. 330 */ 331 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 332 @NonNull setLci(@ullable byte[] lci)333 public Builder setLci(@Nullable byte[] lci) { 334 mLci = lci; 335 return this; 336 } 337 338 /** 339 * Sets the Location Civic Report (LCR). 340 * 341 * LCR provides additional details about the AP's location in a human-readable format, 342 * such as the street address, building name, or floor number. This can be helpful for 343 * users to understand the context of their location within a building or complex. 344 * 345 * The format is 346 * specified in the IEEE 802.11-2016 specifications, section 9.4.2.22.13. 347 * 348 * @param lcr Location civic report. If not set, defaults to null. 349 * @return The builder to facilitate chaining. 350 */ 351 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 352 @NonNull setLcr(@ullable byte[] lcr)353 public Builder setLcr(@Nullable byte[] lcr) { 354 mLcr = lcr; 355 return this; 356 } 357 358 /** 359 * Sets Responder Location. 360 * 361 * ResponderLocation is both a Location Configuration Information (LCI) decoder and a 362 * Location Civic Report (LCR) decoder for information received from a Wi-Fi Access Point 363 * (AP) during Wi-Fi RTT ranging process. 364 * 365 * @param responderLocation Responder location. If not set, defaults to null. 366 * @return The builder to facilitate chaining. 367 */ 368 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 369 @NonNull setUnverifiedResponderLocation( @ullable ResponderLocation responderLocation)370 public Builder setUnverifiedResponderLocation( 371 @Nullable ResponderLocation responderLocation) { 372 mResponderLocation = responderLocation; 373 return this; 374 } 375 376 /** 377 * Sets the time stamp at which the ranging operation was performed. 378 * 379 * The timestamp is in milliseconds since boot, including time spent in sleep, 380 * corresponding to values provided by {@link android.os.SystemClock#elapsedRealtime()}. 381 * 382 * @param timestamp time stamp in milliseconds. If not set, default to 0. 383 * @return The builder to facilitate chaining. 384 */ 385 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 386 @NonNull setRangingTimestampMillis(@lapsedRealtimeLong long timestamp)387 public Builder setRangingTimestampMillis(@ElapsedRealtimeLong long timestamp) { 388 mTimestamp = timestamp; 389 return this; 390 } 391 392 393 /** 394 * Sets whether the ranging measurement was performed using IEEE 802.11mc ranging method. 395 * If {@link #set80211mcMeasurement(boolean)} is set as false and 396 * {@link #set80211azNtbMeasurement(boolean)} is also set as false, ranging measurement was 397 * performed using one-side RTT. If not set, default to false. 398 * 399 * @param is80211mcMeasurement true for IEEE 802.11mc measure, otherwise false. 400 * @return The builder to facilitate chaining. 401 */ 402 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 403 @NonNull set80211mcMeasurement(boolean is80211mcMeasurement)404 public Builder set80211mcMeasurement(boolean is80211mcMeasurement) { 405 mIs80211mcMeasurement = is80211mcMeasurement; 406 return this; 407 } 408 409 /** 410 * Sets the center frequency of the primary 20 MHz frequency (in MHz) of the channel over 411 * which the measurement frames are sent. If not set, default to 412 * {@link RangingResult#UNSPECIFIED} 413 * 414 * @param frequencyMHz Frequency. 415 * @return The builder to facilitate chaining. 416 */ 417 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 418 @NonNull setMeasurementChannelFrequencyMHz(int frequencyMHz)419 public Builder setMeasurementChannelFrequencyMHz(int frequencyMHz) { 420 mFrequencyMHz = frequencyMHz; 421 return this; 422 } 423 424 /** 425 * Sets the bandwidth used to transmit the RTT measurement frame. If not set, default to 426 * {@link RangingResult#UNSPECIFIED}. 427 * 428 * @param measurementBandwidth Measurement bandwidth. 429 * @return The builder to facilitate chaining. 430 */ 431 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 432 @NonNull setMeasurementBandwidth(@hannelWidth int measurementBandwidth)433 public Builder setMeasurementBandwidth(@ChannelWidth int measurementBandwidth) { 434 mPacketBw = measurementBandwidth; 435 return this; 436 } 437 438 /** 439 * Sets whether the ranging measurement was performed using IEEE 802.11az non-trigger 440 * ranging method. If {@link #set80211azNtbMeasurement(boolean)} is set as false and 441 * {@link #set80211mcMeasurement(boolean)} is also set as false, ranging measurement was 442 * performed using one-side RTT. If not set defaults to false. 443 * 444 * @param is80211azNtbMeasurement true for IEEE 802.11az non-trigger based measurement, 445 * otherwise false. 446 * @return The builder to facilitate chaining. 447 */ 448 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 449 @NonNull set80211azNtbMeasurement(boolean is80211azNtbMeasurement)450 public Builder set80211azNtbMeasurement(boolean is80211azNtbMeasurement) { 451 mIs80211azNtbMeasurement = is80211azNtbMeasurement; 452 return this; 453 } 454 455 /** 456 * Sets minimum time between measurements in microseconds for IEEE 802.11az non-trigger 457 * based ranging. If not set, defaults to {@link RangingResult#UNSPECIFIED}. 458 * 459 * @param ntbMinMeasurementTime non-trigger based ranging minimum measurement time. 460 * @return The builder to facilitate chaining. 461 */ 462 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 463 @NonNull setMinTimeBetweenNtbMeasurementsMicros(long ntbMinMeasurementTime)464 public Builder setMinTimeBetweenNtbMeasurementsMicros(long ntbMinMeasurementTime) { 465 mNtbMinMeasurementTime = ntbMinMeasurementTime; 466 return this; 467 } 468 469 /** 470 * Sets maximum time between measurements in microseconds for IEEE 802.11az non-trigger 471 * based ranging. If not set, defaults to {@link RangingResult#UNSPECIFIED}. 472 * 473 * @param ntbMaxMeasurementTime non-trigger based ranging maximum measurement time. 474 * @return The builder to facilitate chaining. 475 */ 476 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 477 @NonNull setMaxTimeBetweenNtbMeasurementsMicros(long ntbMaxMeasurementTime)478 public Builder setMaxTimeBetweenNtbMeasurementsMicros(long ntbMaxMeasurementTime) { 479 mNtbMaxMeasurementTime = ntbMaxMeasurementTime; 480 return this; 481 } 482 483 /** 484 * Sets LTF repetitions that the initiator station used in the preamble. If not set, 485 * defaults to {@link RangingResult#UNSPECIFIED}. 486 * 487 * @param i2rTxLtfRepetitions LFT repetition count. 488 * @return The builder to facilitate chaining. 489 */ 490 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 491 @NonNull set80211azInitiatorTxLtfRepetitionsCount(int i2rTxLtfRepetitions)492 public Builder set80211azInitiatorTxLtfRepetitionsCount(int i2rTxLtfRepetitions) { 493 mI2rTxLtfRepetitions = i2rTxLtfRepetitions; 494 return this; 495 } 496 497 /** 498 * Sets LTF repetitions that the responder station used in the preamble. If not set, 499 * defaults to {@link RangingResult#UNSPECIFIED}. 500 * 501 * @param r2iTxLtfRepetitions LFT repetition count. 502 * @return The builder to facilitate chaining. 503 */ 504 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 505 @NonNull set80211azResponderTxLtfRepetitionsCount(int r2iTxLtfRepetitions)506 public Builder set80211azResponderTxLtfRepetitionsCount(int r2iTxLtfRepetitions) { 507 mR2iTxLtfRepetitions = r2iTxLtfRepetitions; 508 return this; 509 } 510 511 /** 512 * Sets number of transmit spatial streams that the initiator station used for the 513 * ranging result. If not set, defaults to {@link RangingResult#UNSPECIFIED}. 514 * 515 * @param numTxSpatialStreams Number of transmit spatial streams. 516 * @return The builder to facilitate chaining. 517 */ 518 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 519 @NonNull set80211azNumberOfTxSpatialStreams(int numTxSpatialStreams)520 public Builder set80211azNumberOfTxSpatialStreams(int numTxSpatialStreams) { 521 mNumTxSpatialStreams = numTxSpatialStreams; 522 return this; 523 } 524 525 /** 526 * Sets number of receive spatial streams that the initiator station used for the ranging 527 * result. If not set, defaults to {@link RangingResult#UNSPECIFIED}. 528 * 529 * @param numRxSpatialStreams Number of receive spatial streams. 530 * @return The builder to facilitate chaining. 531 */ 532 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 533 @NonNull set80211azNumberOfRxSpatialStreams(int numRxSpatialStreams)534 public Builder set80211azNumberOfRxSpatialStreams(int numRxSpatialStreams) { 535 mNumRxSpatialStreams = numRxSpatialStreams; 536 return this; 537 } 538 539 /** 540 * Set additional vendor-provided configuration data. 541 * 542 * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the 543 * vendor-provided configuration data. Note that multiple elements with 544 * the same OUI are allowed. 545 * @hide 546 */ 547 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 548 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 549 @SystemApi 550 @NonNull setVendorData(@onNull List<OuiKeyedData> vendorData)551 public Builder setVendorData(@NonNull List<OuiKeyedData> vendorData) { 552 if (!SdkLevel.isAtLeastV()) { 553 throw new UnsupportedOperationException(); 554 } 555 if (vendorData == null) { 556 throw new IllegalArgumentException("setVendorData received a null value"); 557 } 558 mVendorData = vendorData; 559 return this; 560 } 561 562 /** 563 * Set whether mutual authentication is done for the ranging. Authentication of ranging 564 * enables frame protection also. See {@link #setRangingFrameProtected(boolean)}. 565 * 566 * @param isRangingAuthenticated true if ranging is mutually authenticated, otherwise false. 567 * @return The builder to facilitate chaining. 568 */ 569 @NonNull 570 @FlaggedApi(Flags.FLAG_SECURE_RANGING) setRangingAuthenticated(boolean isRangingAuthenticated)571 public Builder setRangingAuthenticated(boolean isRangingAuthenticated) { 572 mIsRangingAuthenticated = isRangingAuthenticated; 573 return this; 574 } 575 576 /** 577 * Set whether ranging frames are protected. Frame protection provides both encryption and 578 * integrity protection to the ranging frames. 579 * 580 * @param isRangingFrameProtected true if ranging frames are protected, otherwise false. 581 * @return The builder to facilitate chaining. 582 */ 583 @NonNull 584 @FlaggedApi(Flags.FLAG_SECURE_RANGING) setRangingFrameProtected(boolean isRangingFrameProtected)585 public Builder setRangingFrameProtected(boolean isRangingFrameProtected) { 586 mIsRangingFrameProtected = isRangingFrameProtected; 587 return this; 588 } 589 590 /** 591 * Set whether secure HE-LTF is used for this ranging. 592 * 593 * @param isSecureHeLtfEnabled true if secure HE-LTF is enabled, otherwise false. 594 * @return The builder to facilitate chaining. 595 */ 596 @NonNull 597 @FlaggedApi(Flags.FLAG_SECURE_RANGING) setSecureHeLtfEnabled(boolean isSecureHeLtfEnabled)598 public Builder setSecureHeLtfEnabled(boolean isSecureHeLtfEnabled) { 599 mIsSecureHeLtfEnabled = isSecureHeLtfEnabled; 600 return this; 601 } 602 603 /** 604 * Set secure HE-LTF protocol version used for this ranging. 605 * 606 * The secure HE-LTF negotiation supports negotiation of the secure HE-LTF protocol version 607 * which allows a responder and an initiator to negotiate the highest mutually supported 608 * secure HE-LTF protocol version. 609 * 610 * Refer IEEE 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element. 611 * 612 * @param secureHeLtfProtocolVersion Secure HE-LTF protocol version. 613 * @return The builder to facilitate chaining. 614 */ 615 @NonNull 616 @FlaggedApi(Flags.FLAG_SECURE_RANGING) setSecureHeLtfProtocolVersion( @ntRangefrom = 0, to = 7) int secureHeLtfProtocolVersion)617 public Builder setSecureHeLtfProtocolVersion( 618 @IntRange(from = 0, to = 7) int secureHeLtfProtocolVersion) { 619 mSecureHeLtfProtocolVersion = secureHeLtfProtocolVersion; 620 return this; 621 } 622 623 /** 624 * Set comeback cookie. See {@link #getPasnComebackCookie()}. If not set, default value 625 * is null. 626 * 627 * @param pasnComebackCookie an opaque sequence of octets 628 * @return The builder to facilitate chaining. 629 */ 630 @NonNull 631 @FlaggedApi(Flags.FLAG_SECURE_RANGING) setPasnComebackCookie(@onNull byte[] pasnComebackCookie)632 public Builder setPasnComebackCookie(@NonNull byte[] pasnComebackCookie) { 633 mPasnComebackCookie = pasnComebackCookie; 634 return this; 635 } 636 637 /** 638 * Set comeback after time. See {@link #getPasnComebackAfterMillis()}. If not set default 639 * value is {@link RangingResult#UNSPECIFIED}. 640 * 641 * @param comebackAfterMillis the ranging initiator (STA) must wait for the specified 642 * time before retrying secure ranging 643 * @return The builder to facilitate chaining. 644 */ 645 @NonNull 646 @FlaggedApi(Flags.FLAG_SECURE_RANGING) setPasnComebackAfterMillis(long comebackAfterMillis)647 public Builder setPasnComebackAfterMillis(long comebackAfterMillis) { 648 mPasnComebackAfterMillis = comebackAfterMillis; 649 return this; 650 } 651 652 /** 653 * Build {@link RangingResult} 654 * @return an instance of {@link RangingResult} 655 */ 656 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 657 @NonNull build()658 public RangingResult build() { 659 if (mMac == null && mPeerHandle == null) { 660 throw new IllegalArgumentException("Either MAC address or Peer handle is needed"); 661 } 662 if (mIs80211azNtbMeasurement && mIs80211mcMeasurement) { 663 throw new IllegalArgumentException( 664 "A ranging result cannot use both IEEE 802.11mc and IEEE 802.11az " 665 + "measurements simultaneously"); 666 } 667 return new RangingResult(this); 668 } 669 } 670 671 /** @hide */ RangingResult(Builder builder)672 private RangingResult(Builder builder) { 673 mStatus = builder.mStatus; 674 mMac = builder.mMac; 675 mPeerHandle = builder.mPeerHandle; 676 mDistanceMm = builder.mDistanceMm; 677 mDistanceStdDevMm = builder.mDistanceStdDevMm; 678 mRssi = builder.mRssi; 679 mNumAttemptedMeasurements = builder.mNumAttemptedMeasurements; 680 mNumSuccessfulMeasurements = builder.mNumSuccessfulMeasurements; 681 mLci = (builder.mLci == null) ? EMPTY_BYTE_ARRAY : builder.mLci; 682 mLcr = (builder.mLcr == null) ? EMPTY_BYTE_ARRAY : builder.mLcr; 683 mResponderLocation = builder.mResponderLocation; 684 mTimestamp = builder.mTimestamp; 685 mIs80211mcMeasurement = builder.mIs80211mcMeasurement; 686 mFrequencyMHz = builder.mFrequencyMHz; 687 mPacketBw = builder.mPacketBw; 688 mIs80211azNtbMeasurement = builder.mIs80211azNtbMeasurement; 689 mNtbMinMeasurementTime = builder.mNtbMinMeasurementTime; 690 mNtbMaxMeasurementTime = builder.mNtbMaxMeasurementTime; 691 mI2rTxLtfRepetitions = builder.mI2rTxLtfRepetitions; 692 mR2iTxLtfRepetitions = builder.mR2iTxLtfRepetitions; 693 mNumRxSpatialStreams = builder.mNumRxSpatialStreams; 694 mNumTxSpatialStreams = builder.mNumTxSpatialStreams; 695 mVendorData = builder.mVendorData; 696 mIsRangingAuthenticated = builder.mIsRangingAuthenticated; 697 mIsRangingFrameProtected = builder.mIsRangingFrameProtected; 698 mIsSecureHeLtfEnabled = builder.mIsSecureHeLtfEnabled; 699 mSecureHeLtfProtocolVersion = builder.mSecureHeLtfProtocolVersion; 700 mPasnComebackCookie = builder.mPasnComebackCookie; 701 mPasnComebackAfterMillis = builder.mPasnComebackAfterMillis; 702 } 703 704 /** 705 * @return The status of ranging measurement: {@link #STATUS_SUCCESS} in case of success, and 706 * {@link #STATUS_FAIL} in case of failure. 707 */ 708 @RangeResultStatus getStatus()709 public int getStatus() { 710 return mStatus; 711 } 712 713 /** 714 * @return The MAC address of the device whose range measurement was requested. Will correspond 715 * to the MAC address of the device in the {@link RangingRequest}. 716 * <p> 717 * Will return a {@code null} for results corresponding to requests issued using a {@code 718 * PeerHandle}, i.e. using the {@link RangingRequest.Builder#addWifiAwarePeer(PeerHandle)} API. 719 */ 720 @Nullable getMacAddress()721 public MacAddress getMacAddress() { 722 return mMac; 723 } 724 725 /** 726 * @return The PeerHandle of the device whose reange measurement was requested. Will correspond 727 * to the PeerHandle of the devices requested using 728 * {@link RangingRequest.Builder#addWifiAwarePeer(PeerHandle)}. 729 * <p> 730 * Will return a {@code null} for results corresponding to requests issued using a MAC address. 731 */ getPeerHandle()732 @Nullable public PeerHandle getPeerHandle() { 733 return mPeerHandle; 734 } 735 736 /** 737 * @return The distance (in mm) to the device specified by {@link #getMacAddress()} or 738 * {@link #getPeerHandle()}. 739 * <p> 740 * Note: the measured distance may be negative for very close devices. 741 * <p> 742 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 743 * exception. 744 */ getDistanceMm()745 public int getDistanceMm() { 746 if (mStatus != STATUS_SUCCESS) { 747 throw new IllegalStateException( 748 "getDistanceMm(): invoked on an invalid result: getStatus()=" + mStatus); 749 } 750 return mDistanceMm; 751 } 752 753 /** 754 * @return The standard deviation of the measured distance (in mm) to the device specified by 755 * {@link #getMacAddress()} or {@link #getPeerHandle()}. The standard deviation is calculated 756 * over the measurements executed in a single RTT burst. The number of measurements is returned 757 * by {@link #getNumSuccessfulMeasurements()} - 0 successful measurements indicate that the 758 * standard deviation is not valid (a valid standard deviation requires at least 2 data points). 759 * <p> 760 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 761 * exception. 762 */ getDistanceStdDevMm()763 public int getDistanceStdDevMm() { 764 if (mStatus != STATUS_SUCCESS) { 765 throw new IllegalStateException( 766 "getDistanceStdDevMm(): invoked on an invalid result: getStatus()=" + mStatus); 767 } 768 return mDistanceStdDevMm; 769 } 770 771 /** 772 * @return The average RSSI, in units of dBm, observed during the RTT measurement. 773 * <p> 774 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 775 * exception. 776 */ getRssi()777 public int getRssi() { 778 if (mStatus != STATUS_SUCCESS) { 779 throw new IllegalStateException( 780 "getRssi(): invoked on an invalid result: getStatus()=" + mStatus); 781 } 782 return mRssi; 783 } 784 785 /** 786 * @return The number of attempted measurements used in the RTT exchange resulting in this set 787 * of results. The number of successful measurements is returned by 788 * {@link #getNumSuccessfulMeasurements()} which at most, if there are no errors, will be 1 789 * less than the number of attempted measurements. 790 * <p> 791 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 792 * exception. If the value is 0, it should be interpreted as no information available, which may 793 * occur for one-sided RTT measurements. Instead {@link RangingRequest#getRttBurstSize()} 794 * should be used instead. 795 */ getNumAttemptedMeasurements()796 public int getNumAttemptedMeasurements() { 797 if (mStatus != STATUS_SUCCESS) { 798 throw new IllegalStateException( 799 "getNumAttemptedMeasurements(): invoked on an invalid result: getStatus()=" 800 + mStatus); 801 } 802 return mNumAttemptedMeasurements; 803 } 804 805 /** 806 * @return The number of successful measurements used to calculate the distance and standard 807 * deviation. If the number of successful measurements if 1 then then standard deviation, 808 * returned by {@link #getDistanceStdDevMm()}, is not valid (a 0 is returned for the standard 809 * deviation). 810 * <p> 811 * The total number of measurement attempts is returned by 812 * {@link #getNumAttemptedMeasurements()}. The number of successful measurements will be at 813 * most 1 less then the number of attempted measurements. 814 * <p> 815 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 816 * exception. 817 */ getNumSuccessfulMeasurements()818 public int getNumSuccessfulMeasurements() { 819 if (mStatus != STATUS_SUCCESS) { 820 throw new IllegalStateException( 821 "getNumSuccessfulMeasurements(): invoked on an invalid result: getStatus()=" 822 + mStatus); 823 } 824 return mNumSuccessfulMeasurements; 825 } 826 827 /** 828 * @return The unverified responder location represented as {@link ResponderLocation} which 829 * captures location information the responder is programmed to broadcast. The responder 830 * location is referred to as unverified, because we are relying on the device/site 831 * administrator to correctly configure its location data. 832 * <p> 833 * Will return a {@code null} when the location information cannot be parsed. 834 * <p> 835 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 836 * exception. 837 */ 838 @Nullable getUnverifiedResponderLocation()839 public ResponderLocation getUnverifiedResponderLocation() { 840 if (mStatus != STATUS_SUCCESS) { 841 throw new IllegalStateException( 842 "getUnverifiedResponderLocation(): invoked on an invalid result: getStatus()=" 843 + mStatus); 844 } 845 return mResponderLocation; 846 } 847 848 /** 849 * @return The Location Configuration Information (LCI) as self-reported by the peer. The format 850 * is specified in the IEEE 802.11-2016 specifications, section 9.4.2.22.10. 851 * <p> 852 * Note: the information is NOT validated - use with caution. Consider validating it with 853 * other sources of information before using it. 854 */ 855 @SuppressLint("UnflaggedApi") // Flagging API promotion from @SystemApi to public not supported 856 @NonNull getLci()857 public byte[] getLci() { 858 if (mStatus != STATUS_SUCCESS) { 859 throw new IllegalStateException( 860 "getLci(): invoked on an invalid result: getStatus()=" + mStatus); 861 } 862 return mLci; 863 } 864 865 /** 866 * @return The Location Civic report (LCR) as self-reported by the peer. The format 867 * is specified in the IEEE 802.11-2016 specifications, section 9.4.2.22.13. 868 * <p> 869 * Note: the information is NOT validated - use with caution. Consider validating it with 870 * other sources of information before using it. 871 */ 872 @SuppressLint("UnflaggedApi") // Flagging API promotion from @SystemApi to public not supported 873 @NonNull getLcr()874 public byte[] getLcr() { 875 if (mStatus != STATUS_SUCCESS) { 876 throw new IllegalStateException( 877 "getReportedLocationCivic(): invoked on an invalid result: getStatus()=" 878 + mStatus); 879 } 880 return mLcr; 881 } 882 883 /** 884 * @return The timestamp at which the ranging operation was performed. The timestamp is in 885 * milliseconds since boot, including time spent in sleep, corresponding to values provided by 886 * {@link android.os.SystemClock#elapsedRealtime()}. 887 * <p> 888 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 889 * exception. 890 */ getRangingTimestampMillis()891 public long getRangingTimestampMillis() { 892 if (mStatus != STATUS_SUCCESS) { 893 throw new IllegalStateException( 894 "getRangingTimestampMillis(): invoked on an invalid result: getStatus()=" 895 + mStatus); 896 } 897 return mTimestamp; 898 } 899 900 /** 901 * @return The result is true if the IEEE 802.11mc protocol was used. If the result is false, 902 * and {@link #is80211azNtbMeasurement()} is also false a one-side RTT result is provided 903 * which does not subtract the turnaround time at the responder. 904 * <p> 905 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 906 * exception. 907 */ is80211mcMeasurement()908 public boolean is80211mcMeasurement() { 909 if (mStatus != STATUS_SUCCESS) { 910 throw new IllegalStateException( 911 "is80211mcMeasurementResult(): invoked on an invalid result: getStatus()=" 912 + mStatus); 913 } 914 return mIs80211mcMeasurement; 915 } 916 917 /** 918 * @return The result is true if the IEEE 802.11az non-trigger based protocol was used. If the 919 * result is false, and {@link #is80211mcMeasurement()} is also false a one-side RTT result 920 * is provided which does not subtract the turnaround time at the responder. 921 * <p>. 922 * Only valid if {@link #getStatus()} returns {@link #STATUS_SUCCESS}, otherwise will throw an 923 * exception. 924 */ 925 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) is80211azNtbMeasurement()926 public boolean is80211azNtbMeasurement() { 927 if (mStatus != STATUS_SUCCESS) { 928 throw new IllegalStateException( 929 "is80211azNtbMeasurement(): invoked on an invalid result: getStatus()=" 930 + mStatus); 931 } 932 return mIs80211azNtbMeasurement; 933 } 934 935 /** 936 * Gets minimum time between measurements in microseconds for IEEE 802.11az non-trigger based 937 * ranging. 938 * 939 * The next 11az ranging measurement request must be invoked after the minimum time from the 940 * last measurement time {@link #getRangingTimestampMillis()} for the peer. Otherwise, cached 941 * ranging result will be returned for the peer. 942 */ 943 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) getMinTimeBetweenNtbMeasurementsMicros()944 public long getMinTimeBetweenNtbMeasurementsMicros() { 945 return mNtbMinMeasurementTime; 946 } 947 948 /** 949 * Gets maximum time between measurements in microseconds for IEEE 802.11az non-trigger based 950 * ranging. 951 * 952 * The next 11az ranging request needs to be invoked before the maximum time from the last 953 * measurement time {@link #getRangingTimestampMillis()}. Otherwise, the non-trigger based 954 * ranging session will be terminated and a new ranging negotiation will happen with 955 * the responding station. 956 */ 957 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) getMaxTimeBetweenNtbMeasurementsMicros()958 public long getMaxTimeBetweenNtbMeasurementsMicros() { 959 return mNtbMaxMeasurementTime; 960 } 961 962 /** 963 * Gets LTF repetitions that the responder station (RSTA) used in the preamble of the 964 * responder to initiator (I2R) null data PPDU (NDP) for this result. 965 * 966 * LTF repetitions is the multiple transmissions of HE-LTF symbols in an HE ranging NDP. An 967 * HE-LTF repetition value of 1 indicates no repetitions. 968 * 969 * @return LTF repetitions count 970 */ 971 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) get80211azResponderTxLtfRepetitionsCount()972 public int get80211azResponderTxLtfRepetitionsCount() { 973 return mR2iTxLtfRepetitions; 974 } 975 976 /** 977 * Gets LTF repetitions that the initiator station (ISTA) used in the preamble of the 978 * initiator to responder (I2R) null data PPDU (NDP) for this result. 979 * 980 * LTF repetitions is the multiple transmissions of HE-LTF symbols in an HE ranging NDP. An 981 * HE-LTF repetition value of 1 indicates no repetitions. 982 * 983 * @return LTF repetitions count 984 */ 985 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) get80211azInitiatorTxLtfRepetitionsCount()986 public int get80211azInitiatorTxLtfRepetitionsCount() { 987 return mI2rTxLtfRepetitions; 988 } 989 990 /** 991 * Gets number of transmit spatial streams that the initiator station (ISTA) used for the 992 * initiator to responder (I2R) null data PPDU (NDP) for this result. 993 * 994 * @return Number of spatial streams 995 */ 996 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) get80211azNumberOfTxSpatialStreams()997 public int get80211azNumberOfTxSpatialStreams() { 998 return mNumTxSpatialStreams; 999 } 1000 1001 /** 1002 * Gets number of receive spatial streams that the initiator station (ISTA) used for the 1003 * initiator to responder (I2R) null data PPDU (NDP) for this result. 1004 * 1005 * @return Number of spatial streams 1006 */ 1007 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) get80211azNumberOfRxSpatialStreams()1008 public int get80211azNumberOfRxSpatialStreams() { 1009 return mNumRxSpatialStreams; 1010 } 1011 1012 /** 1013 * The center frequency of the primary 20 MHz frequency (in MHz) of the channel over 1014 * which the measurement frames are sent. 1015 * @return center frequency in Mhz of the channel if available, otherwise {@link #UNSPECIFIED} 1016 * is returned. 1017 * <p> 1018 * @throws IllegalStateException if {@link #getStatus()} does not return 1019 * {@link #STATUS_SUCCESS}. 1020 */ getMeasurementChannelFrequencyMHz()1021 public int getMeasurementChannelFrequencyMHz() { 1022 if (mStatus != STATUS_SUCCESS) { 1023 throw new IllegalStateException( 1024 "getMeasurementChannelFrequencyMHz():" 1025 + " invoked on an invalid result: getStatus()= " + mStatus); 1026 } 1027 return mFrequencyMHz; 1028 } 1029 1030 /** 1031 * The bandwidth used to transmit the RTT measurement frame. 1032 * @return one of {@link ScanResult#CHANNEL_WIDTH_20MHZ}, 1033 * {@link ScanResult#CHANNEL_WIDTH_40MHZ}, 1034 * {@link ScanResult#CHANNEL_WIDTH_80MHZ}, {@link ScanResult#CHANNEL_WIDTH_160MHZ}, 1035 * {@link ScanResult #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link ScanResult #CHANNEL_WIDTH_320MHZ} 1036 * if available, otherwise {@link #UNSPECIFIED} is returned. 1037 * <p> 1038 * @throws IllegalStateException if {@link #getStatus()} does not return 1039 * {@link #STATUS_SUCCESS}. 1040 */ getMeasurementBandwidth()1041 public @ChannelWidth int getMeasurementBandwidth() { 1042 if (mStatus != STATUS_SUCCESS) { 1043 throw new IllegalStateException( 1044 "getMeasurementBandwidth(): invoked on an invalid result: getStatus()=" 1045 + mStatus); 1046 } 1047 return mPacketBw; 1048 } 1049 1050 /** 1051 * Get the vendor-provided configuration data, if it exists. 1052 * 1053 * @return Vendor configuration data, or empty list if it does not exist. 1054 * @hide 1055 */ 1056 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 1057 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 1058 @SystemApi 1059 @NonNull getVendorData()1060 public List<OuiKeyedData> getVendorData() { 1061 if (!SdkLevel.isAtLeastV()) { 1062 throw new UnsupportedOperationException(); 1063 } 1064 return mVendorData; 1065 } 1066 1067 /** 1068 * @return whether the ranging is authenticated or not. 1069 * 1070 * Refer IEEE 802.11az-2022 spec, section 12 Security. 1071 */ 1072 @FlaggedApi(Flags.FLAG_SECURE_RANGING) isRangingAuthenticated()1073 public boolean isRangingAuthenticated() { 1074 return mIsRangingAuthenticated; 1075 } 1076 1077 /** 1078 * @return whether the ranging frames are protected or not. 1079 * 1080 * Refer IEEE 802.11az-2022 spec, section 12 Security. 1081 */ 1082 @FlaggedApi(Flags.FLAG_SECURE_RANGING) isRangingFrameProtected()1083 public boolean isRangingFrameProtected() { 1084 return mIsRangingFrameProtected; 1085 } 1086 1087 /** 1088 * @return whether the secure HE-LTF is enabled or not. 1089 * 1090 * Refer IEEE 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element. 1091 */ 1092 @FlaggedApi(Flags.FLAG_SECURE_RANGING) isSecureHeLtfEnabled()1093 public boolean isSecureHeLtfEnabled() { 1094 return mIsSecureHeLtfEnabled; 1095 } 1096 1097 /** 1098 * Get Secure HE-LTF protocol version used. 1099 * 1100 * The secure HE-LTF negotiation supports negotiation of the secure HE-LTF protocol version 1101 * which allows a responder and an initiator to negotiate the highest mutually supported 1102 * secure HE-LTF protocol version. 1103 * 1104 * Refer IEEE 802.11az-2022 spec, section 9.4.2.298 Ranging Parameters element. 1105 */ 1106 @FlaggedApi(Flags.FLAG_SECURE_RANGING) 1107 @IntRange(from = 0, to = 7) getSecureHeLtfProtocolVersion()1108 public int getSecureHeLtfProtocolVersion() { 1109 return mSecureHeLtfProtocolVersion; 1110 } 1111 1112 /** 1113 * Get PASN comeback cookie. PASN authentication allows an AP to indicate the deferral time 1114 * and optionally a Cookie. See {@link #getPasnComebackAfterMillis()} 1115 * <p> 1116 * When an AP receives a large volume of initial PASN Authentication frames, it can use 1117 * the comeback after field in the PASN Parameters element to indicate a deferral time 1118 * and optionally provide a comeback cookie which is an opaque sequence of octets. Upon 1119 * receiving this response, the ranging initiator (STA) must wait for the specified time 1120 * before retrying secure authentication, presenting the received cookie to the AP. 1121 **/ 1122 @FlaggedApi(Flags.FLAG_SECURE_RANGING) 1123 @Nullable getPasnComebackCookie()1124 public byte[] getPasnComebackCookie() { 1125 return mPasnComebackCookie; 1126 } 1127 1128 /** 1129 * Get Comeback after time in milliseconds. See {@link #getPasnComebackCookie()}. A value 0 1130 * indicates the ranging request operation can be tried immediately with the cookie. 1131 */ 1132 @FlaggedApi(Flags.FLAG_SECURE_RANGING) getPasnComebackAfterMillis()1133 public long getPasnComebackAfterMillis() { 1134 return mPasnComebackAfterMillis; 1135 } 1136 1137 @Override describeContents()1138 public int describeContents() { 1139 return 0; 1140 } 1141 1142 @Override writeToParcel(Parcel dest, int flags)1143 public void writeToParcel(Parcel dest, int flags) { 1144 dest.writeInt(mStatus); 1145 if (mMac == null) { 1146 dest.writeBoolean(false); 1147 } else { 1148 dest.writeBoolean(true); 1149 mMac.writeToParcel(dest, flags); 1150 } 1151 if (mPeerHandle == null) { 1152 dest.writeBoolean(false); 1153 } else { 1154 dest.writeBoolean(true); 1155 dest.writeInt(mPeerHandle.peerId); 1156 } 1157 dest.writeInt(mDistanceMm); 1158 dest.writeInt(mDistanceStdDevMm); 1159 dest.writeInt(mRssi); 1160 dest.writeInt(mNumAttemptedMeasurements); 1161 dest.writeInt(mNumSuccessfulMeasurements); 1162 dest.writeByteArray(mLci); 1163 dest.writeByteArray(mLcr); 1164 dest.writeParcelable(mResponderLocation, flags); 1165 dest.writeLong(mTimestamp); 1166 dest.writeBoolean(mIs80211mcMeasurement); 1167 dest.writeInt(mFrequencyMHz); 1168 dest.writeInt(mPacketBw); 1169 dest.writeBoolean(mIs80211azNtbMeasurement); 1170 dest.writeLong(mNtbMinMeasurementTime); 1171 dest.writeLong(mNtbMaxMeasurementTime); 1172 dest.writeInt(mI2rTxLtfRepetitions); 1173 dest.writeInt(mR2iTxLtfRepetitions); 1174 dest.writeInt(mNumTxSpatialStreams); 1175 dest.writeInt(mNumRxSpatialStreams); 1176 if (SdkLevel.isAtLeastV()) { 1177 dest.writeList(mVendorData); 1178 } 1179 dest.writeBoolean(mIsRangingAuthenticated); 1180 dest.writeBoolean(mIsRangingFrameProtected); 1181 dest.writeBoolean(mIsSecureHeLtfEnabled); 1182 dest.writeLong(mPasnComebackAfterMillis); 1183 dest.writeByteArray(mPasnComebackCookie); 1184 dest.writeInt(mSecureHeLtfProtocolVersion); 1185 } 1186 1187 public static final @android.annotation.NonNull Creator<RangingResult> CREATOR = 1188 new Creator<RangingResult>() { 1189 @Override 1190 public RangingResult[] newArray(int size) { 1191 return new RangingResult[size]; 1192 } 1193 1194 @Override 1195 public RangingResult createFromParcel(Parcel in) { 1196 RangingResult.Builder builder = new Builder() 1197 .setStatus(in.readInt()) 1198 .setMacAddress( 1199 in.readBoolean() ? MacAddress.CREATOR.createFromParcel(in) 1200 : null) 1201 .setPeerHandle(in.readBoolean() ? new PeerHandle(in.readInt()) : null) 1202 .setDistanceMm(in.readInt()) 1203 .setDistanceStdDevMm(in.readInt()) 1204 .setRssi(in.readInt()) 1205 .setNumAttemptedMeasurements(in.readInt()) 1206 .setNumSuccessfulMeasurements(in.readInt()) 1207 .setLci(in.createByteArray()) 1208 .setLcr(in.createByteArray()) 1209 .setUnverifiedResponderLocation( 1210 in.readParcelable(this.getClass().getClassLoader())) 1211 .setRangingTimestampMillis(in.readLong()) 1212 .set80211mcMeasurement(in.readBoolean()) 1213 .setMeasurementChannelFrequencyMHz(in.readInt()) 1214 .setMeasurementBandwidth(in.readInt()) 1215 .set80211azNtbMeasurement(in.readBoolean()) 1216 .setMinTimeBetweenNtbMeasurementsMicros(in.readLong()) 1217 .setMaxTimeBetweenNtbMeasurementsMicros(in.readLong()) 1218 .set80211azInitiatorTxLtfRepetitionsCount(in.readInt()) 1219 .set80211azResponderTxLtfRepetitionsCount(in.readInt()) 1220 .set80211azNumberOfTxSpatialStreams(in.readInt()) 1221 .set80211azNumberOfRxSpatialStreams(in.readInt()); 1222 if (SdkLevel.isAtLeastV()) { 1223 builder.setVendorData(ParcelUtil.readOuiKeyedDataList(in)); 1224 } 1225 builder.setRangingAuthenticated(in.readBoolean()) 1226 .setRangingFrameProtected(in.readBoolean()) 1227 .setSecureHeLtfEnabled(in.readBoolean()) 1228 .setPasnComebackAfterMillis(in.readLong()) 1229 .setPasnComebackCookie(in.createByteArray()) 1230 .setSecureHeLtfProtocolVersion(in.readInt()); 1231 return builder.build(); 1232 } 1233 }; 1234 1235 /** @hide */ 1236 @Override toString()1237 public String toString() { 1238 return new StringBuilder("RangingResult: [status=").append(mStatus) 1239 .append(", mac=").append(mMac) 1240 .append(", peerHandle=").append( 1241 mPeerHandle == null ? "<null>" : mPeerHandle.peerId) 1242 .append(", distanceMm=").append(mDistanceMm) 1243 .append(", distanceStdDevMm=").append(mDistanceStdDevMm) 1244 .append(", rssi=").append(mRssi) 1245 .append(", numAttemptedMeasurements=").append(mNumAttemptedMeasurements) 1246 .append(", numSuccessfulMeasurements=").append(mNumSuccessfulMeasurements) 1247 .append(", lci=").append(Arrays.toString(mLci)) 1248 .append(", lcr=").append(Arrays.toString(mLcr)) 1249 .append(", responderLocation=").append(mResponderLocation) 1250 .append(", timestamp=").append(mTimestamp).append(", is80211mcMeasurement=") 1251 .append(mIs80211mcMeasurement) 1252 .append(", frequencyMHz=").append(mFrequencyMHz) 1253 .append(", packetBw=").append(mPacketBw) 1254 .append(", is80211azNtbMeasurement=").append(mIs80211azNtbMeasurement) 1255 .append(", ntbMinMeasurementTimeMicros=").append(mNtbMinMeasurementTime) 1256 .append(", ntbMaxMeasurementTimeMicros=").append(mNtbMaxMeasurementTime) 1257 .append(", i2rTxLtfRepetitions=").append(mI2rTxLtfRepetitions) 1258 .append(", r2iTxLtfRepetitions=").append(mR2iTxLtfRepetitions) 1259 .append(", numTxSpatialStreams=").append(mNumTxSpatialStreams) 1260 .append(", numRxSpatialStreams=").append(mNumRxSpatialStreams) 1261 .append(", vendorData=").append(mVendorData) 1262 .append(", isRangingAuthenticated=").append(mIsRangingAuthenticated) 1263 .append(", isRangingFrameProtected=").append(mIsRangingFrameProtected) 1264 .append(", isSecureHeLtfEnabled=").append(mIsSecureHeLtfEnabled) 1265 .append(", pasnComebackCookie=").append(Arrays.toString(mPasnComebackCookie)) 1266 .append(", pasnComebackAfterMillis=").append(mPasnComebackAfterMillis) 1267 .append("]").toString(); 1268 } 1269 1270 @Override equals(Object o)1271 public boolean equals(Object o) { 1272 if (this == o) { 1273 return true; 1274 } 1275 1276 if (!(o instanceof RangingResult)) { 1277 return false; 1278 } 1279 1280 RangingResult lhs = (RangingResult) o; 1281 1282 return mStatus == lhs.mStatus && Objects.equals(mMac, lhs.mMac) && Objects.equals( 1283 mPeerHandle, lhs.mPeerHandle) && mDistanceMm == lhs.mDistanceMm 1284 && mDistanceStdDevMm == lhs.mDistanceStdDevMm && mRssi == lhs.mRssi 1285 && mNumAttemptedMeasurements == lhs.mNumAttemptedMeasurements 1286 && mNumSuccessfulMeasurements == lhs.mNumSuccessfulMeasurements 1287 && Arrays.equals(mLci, lhs.mLci) && Arrays.equals(mLcr, lhs.mLcr) 1288 && mTimestamp == lhs.mTimestamp 1289 && mIs80211mcMeasurement == lhs.mIs80211mcMeasurement 1290 && Objects.equals(mResponderLocation, lhs.mResponderLocation) 1291 && mFrequencyMHz == lhs.mFrequencyMHz 1292 && mPacketBw == lhs.mPacketBw 1293 && mIs80211azNtbMeasurement == lhs.mIs80211azNtbMeasurement 1294 && mNtbMinMeasurementTime == lhs.mNtbMinMeasurementTime 1295 && mNtbMaxMeasurementTime == lhs.mNtbMaxMeasurementTime 1296 && mI2rTxLtfRepetitions == lhs.mI2rTxLtfRepetitions 1297 && mR2iTxLtfRepetitions == lhs.mR2iTxLtfRepetitions 1298 && mNumTxSpatialStreams == lhs.mNumTxSpatialStreams 1299 && mNumRxSpatialStreams == lhs.mNumRxSpatialStreams 1300 && Objects.equals(mVendorData, lhs.mVendorData) 1301 && mIsRangingAuthenticated == lhs.mIsRangingAuthenticated 1302 && mIsRangingFrameProtected == lhs.mIsRangingFrameProtected 1303 && mIsSecureHeLtfEnabled == lhs.isSecureHeLtfEnabled() 1304 && mPasnComebackAfterMillis == lhs.mPasnComebackAfterMillis 1305 && Arrays.equals(mPasnComebackCookie, lhs.mPasnComebackCookie); 1306 1307 } 1308 1309 @Override hashCode()1310 public int hashCode() { 1311 return Objects.hash(mStatus, mMac, mPeerHandle, mDistanceMm, mDistanceStdDevMm, mRssi, 1312 mNumAttemptedMeasurements, mNumSuccessfulMeasurements, Arrays.hashCode(mLci), 1313 Arrays.hashCode(mLcr), mResponderLocation, mTimestamp, mIs80211mcMeasurement, 1314 mFrequencyMHz, mPacketBw, mIs80211azNtbMeasurement, mNtbMinMeasurementTime, 1315 mNtbMaxMeasurementTime, mI2rTxLtfRepetitions, mR2iTxLtfRepetitions, 1316 mNumTxSpatialStreams, mR2iTxLtfRepetitions, mVendorData, mIsRangingAuthenticated, 1317 mIsRangingFrameProtected, mIsSecureHeLtfEnabled, mPasnComebackAfterMillis, 1318 Arrays.hashCode(mPasnComebackCookie)); 1319 } 1320 } 1321