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 static android.net.wifi.ScanResult.InformationElement.EID_EXTENSION_PRESENT; 20 import static android.net.wifi.ScanResult.InformationElement.EID_EXT_EHT_CAPABILITIES; 21 import static android.net.wifi.ScanResult.InformationElement.EID_EXT_HE_CAPABILITIES; 22 import static android.net.wifi.ScanResult.InformationElement.EID_HT_CAPABILITIES; 23 import static android.net.wifi.ScanResult.InformationElement.EID_VHT_CAPABILITIES; 24 25 import android.annotation.FlaggedApi; 26 import android.annotation.IntDef; 27 import android.annotation.IntRange; 28 import android.annotation.NonNull; 29 import android.annotation.Nullable; 30 import android.annotation.SystemApi; 31 import android.net.MacAddress; 32 import android.net.wifi.ScanResult; 33 import android.net.wifi.WifiAnnotations; 34 import android.net.wifi.aware.PeerHandle; 35 import android.os.Parcel; 36 import android.os.Parcelable; 37 import android.util.Log; 38 39 import com.android.wifi.flags.Flags; 40 41 import java.lang.annotation.Retention; 42 import java.lang.annotation.RetentionPolicy; 43 import java.util.Objects; 44 45 /** 46 * Defines the configuration of an IEEE 802.11mc Responder. The Responder may be an Access Point 47 * (AP), a Wi-Fi Aware device, or a manually configured Responder. 48 * <p> 49 * A Responder configuration may be constructed from a {@link ScanResult} or manually (with the 50 * data obtained out-of-band from a peer). 51 */ 52 public final class ResponderConfig implements Parcelable { 53 private static final String TAG = "ResponderConfig"; 54 private static final int AWARE_BAND_2_DISCOVERY_CHANNEL = 2437; 55 56 /** @hide */ 57 @IntDef({RESPONDER_AP, RESPONDER_STA, RESPONDER_P2P_GO, RESPONDER_P2P_CLIENT, RESPONDER_AWARE}) 58 @Retention(RetentionPolicy.SOURCE) 59 public @interface ResponderType { 60 } 61 62 /** 63 * Responder is an access point(AP). 64 */ 65 66 public static final int RESPONDER_AP = 0; 67 68 /** 69 * Responder is a client device(STA). 70 */ 71 public static final int RESPONDER_STA = 1; 72 73 /** 74 * Responder is a Wi-Fi Direct Group Owner (GO). 75 * @hide 76 */ 77 @SystemApi 78 public static final int RESPONDER_P2P_GO = 2; 79 80 /** 81 * Responder is a Wi-Fi Direct Group Client. 82 * @hide 83 */ 84 @SystemApi 85 public static final int RESPONDER_P2P_CLIENT = 3; 86 87 /** 88 * Responder is a Wi-Fi Aware device. 89 * @hide 90 */ 91 @SystemApi 92 public static final int RESPONDER_AWARE = 4; 93 94 /** @hide */ 95 @IntDef({ 96 CHANNEL_WIDTH_20MHZ, CHANNEL_WIDTH_40MHZ, CHANNEL_WIDTH_80MHZ, CHANNEL_WIDTH_160MHZ, 97 CHANNEL_WIDTH_80MHZ_PLUS_MHZ, CHANNEL_WIDTH_320MHZ}) 98 @Retention(RetentionPolicy.SOURCE) 99 public @interface ChannelWidth { 100 } 101 102 103 /** 104 * Channel bandwidth is 20 MHZ 105 * @hide 106 */ 107 @SystemApi 108 public static final int CHANNEL_WIDTH_20MHZ = 0; 109 110 /** 111 * Channel bandwidth is 40 MHZ 112 * @hide 113 */ 114 @SystemApi 115 public static final int CHANNEL_WIDTH_40MHZ = 1; 116 117 /** 118 * Channel bandwidth is 80 MHZ 119 * @hide 120 */ 121 @SystemApi 122 public static final int CHANNEL_WIDTH_80MHZ = 2; 123 124 /** 125 * Channel bandwidth is 160 MHZ 126 * @hide 127 */ 128 @SystemApi 129 public static final int CHANNEL_WIDTH_160MHZ = 3; 130 131 /** 132 * Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ 133 * @hide 134 */ 135 @SystemApi 136 public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; 137 138 /** 139 * Channel bandwidth is 320 MHZ 140 * @hide 141 */ 142 @SystemApi 143 public static final int CHANNEL_WIDTH_320MHZ = 5; 144 145 /** @hide */ 146 @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT, PREAMBLE_HE, PREAMBLE_EHT}) 147 @Retention(RetentionPolicy.SOURCE) 148 public @interface PreambleType { 149 } 150 151 /** 152 * Preamble type: Legacy. 153 * @hide 154 */ 155 @SystemApi 156 public static final int PREAMBLE_LEGACY = 0; 157 158 /** 159 * Preamble type: HT. 160 * @hide 161 */ 162 @SystemApi 163 public static final int PREAMBLE_HT = 1; 164 165 /** 166 * Preamble type: VHT. 167 * @hide 168 */ 169 @SystemApi 170 public static final int PREAMBLE_VHT = 2; 171 172 /** 173 * Preamble type: HE. 174 * @hide 175 */ 176 @SystemApi 177 public static final int PREAMBLE_HE = 3; 178 179 /** 180 * Preamble type: EHT. 181 * @hide 182 */ 183 @SystemApi 184 public static final int PREAMBLE_EHT = 4; 185 186 private static final long DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS = 250000; 187 private static final long DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS = 15000000; 188 189 /** 190 * The MAC address of the Responder. Will be null if a Wi-Fi Aware peer identifier (the 191 * peerHandle field) ise used to identify the Responder. 192 * @hide 193 */ 194 @SystemApi 195 @Nullable public final MacAddress macAddress; 196 197 /** 198 * The peer identifier of a Wi-Fi Aware Responder. Will be null if a MAC Address (the macAddress 199 * field) is used to identify the Responder. 200 * @hide 201 */ 202 @SystemApi 203 @Nullable public final PeerHandle peerHandle; 204 205 /** 206 * The device type of the Responder. 207 * @hide 208 */ 209 @SystemApi 210 public final int responderType; 211 212 /** 213 * Indicates whether the Responder device supports IEEE 802.11mc. 214 * @hide 215 */ 216 @SystemApi 217 public final boolean supports80211mc; 218 219 /** 220 * Indicates whether the Responder device supports IEEE 802.11az non-trigger based ranging. 221 * @hide 222 */ 223 @SystemApi 224 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 225 public final boolean supports80211azNtb; 226 227 /** 228 * Responder channel bandwidth, specified using {@link ChannelWidth}. 229 * @hide 230 */ 231 @SystemApi 232 public final int channelWidth; 233 234 /** 235 * The primary 20 MHz frequency (in MHz) of the channel of the Responder. 236 * @hide 237 */ 238 @SystemApi 239 public final int frequency; 240 241 /** 242 * Not used if the {@link #channelWidth} is 20 MHz. If the Responder uses 40, 80, 160 or 243 * 320 MHz, this is the center frequency (in MHz), if the Responder uses 80 + 80 MHz, 244 * this is the center frequency of the first segment (in MHz). 245 * @hide 246 */ 247 @SystemApi 248 public final int centerFreq0; 249 250 /** 251 * Only used if the {@link #channelWidth} is 80 + 80 MHz. If the Responder uses 80 + 80 MHz, 252 * this is the center frequency of the second segment (in MHz). 253 * @hide 254 */ 255 @SystemApi 256 public final int centerFreq1; 257 258 /** 259 * The preamble used by the Responder, specified using {@link PreambleType}. 260 * @hide 261 */ 262 @SystemApi 263 public final int preamble; 264 265 private long mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS; 266 private long mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS; 267 268 /** 269 * Constructs Responder configuration from the builder 270 * @param builder See {@link Builder} 271 * @hide 272 */ ResponderConfig(Builder builder)273 public ResponderConfig(Builder builder) { 274 if (builder.mMacAddress == null && builder.mPeerHandle == null) { 275 throw new IllegalArgumentException( 276 "Invalid ResponderConfig - must specify a MAC address or Peer handle"); 277 } 278 this.macAddress = builder.mMacAddress; 279 this.peerHandle = builder.mPeerHandle; 280 this.responderType = builder.mResponderType; 281 this.supports80211mc = builder.mSupports80211Mc; 282 this.supports80211azNtb = builder.mSupports80211azNtb; 283 this.channelWidth = builder.mChannelWidth; 284 this.frequency = builder.mFrequency; 285 this.centerFreq0 = builder.mCenterFreq0; 286 this.centerFreq1 = builder.mCenterFreq1; 287 this.preamble = builder.mPreamble; 288 this.mNtbMinMeasurementTime = builder.mNtbMinMeasurementTime; 289 this.mNtbMaxMeasurementTime = builder.mNtbMaxMeasurementTime; 290 } 291 292 /** 293 * Constructs Responder configuration, using a MAC address to identify the Responder. 294 * 295 * @param macAddress The MAC address of the Responder. 296 * @param responderType The type of the responder device, specified using 297 * {@link ResponderType}. 298 * For an access point (AP) use {@code RESPONDER_AP}. 299 * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc. 300 * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}. 301 * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder. 302 * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses 303 * 40, 80, 160 or 320 MHz, this is the center frequency (in MHz), if the 304 * Responder uses 80 + 80 MHz, this is the center frequency of the first 305 * segment (in MHz). 306 * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the 307 * Responder 308 * uses 80 + 80 MHz, this is the center frequency of the second segment 309 * (in 310 * MHz). 311 * @param preamble The preamble used by the Responder, specified using 312 * {@link PreambleType}. 313 * @hide 314 */ 315 @SystemApi ResponderConfig(@onNull MacAddress macAddress, @ResponderType int responderType, boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0, int centerFreq1, @PreambleType int preamble)316 public ResponderConfig(@NonNull MacAddress macAddress, @ResponderType int responderType, 317 boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0, 318 int centerFreq1, @PreambleType int preamble) { 319 if (macAddress == null) { 320 throw new IllegalArgumentException( 321 "Invalid ResponderConfig - must specify a MAC address"); 322 } 323 this.macAddress = macAddress; 324 this.peerHandle = null; 325 this.responderType = responderType; 326 this.supports80211mc = supports80211mc; 327 this.channelWidth = channelWidth; 328 this.frequency = frequency; 329 this.centerFreq0 = centerFreq0; 330 this.centerFreq1 = centerFreq1; 331 this.preamble = preamble; 332 this.supports80211azNtb = false; 333 this.mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS; 334 this.mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS; 335 } 336 337 /** 338 * Constructs Responder configuration, using a Wi-Fi Aware PeerHandle to identify the Responder. 339 * 340 * @param peerHandle The Wi-Fi Aware peer identifier of the Responder. 341 * @param responderType The type of the responder device, specified using 342 * {@link ResponderType}. 343 * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc. 344 * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}. 345 * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder. 346 * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses 347 * 40, 80, 160, or 320 MHz, this is the center frequency (in MHz), if the 348 * Responder uses 80 + 80 MHz, this is the center frequency of the first 349 * segment (in MHz). 350 * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the 351 * Responder 352 * uses 80 + 80 MHz, this is the center frequency of the second segment 353 * (in 354 * MHz). 355 * @param preamble The preamble used by the Responder, specified using 356 * {@link PreambleType}. 357 * @hide 358 */ 359 @SystemApi ResponderConfig(@onNull PeerHandle peerHandle, @ResponderType int responderType, boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0, int centerFreq1, @PreambleType int preamble)360 public ResponderConfig(@NonNull PeerHandle peerHandle, @ResponderType int responderType, 361 boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0, 362 int centerFreq1, @PreambleType int preamble) { 363 this.macAddress = null; 364 this.peerHandle = peerHandle; 365 this.responderType = responderType; 366 this.supports80211mc = supports80211mc; 367 this.channelWidth = channelWidth; 368 this.frequency = frequency; 369 this.centerFreq0 = centerFreq0; 370 this.centerFreq1 = centerFreq1; 371 this.preamble = preamble; 372 this.supports80211azNtb = false; 373 this.mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS; 374 this.mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS; 375 } 376 377 /** 378 * Constructs Responder configuration. This is a constructor which specifies both 379 * a MAC address and a Wi-Fi PeerHandle to identify the Responder. For an RTT RangingRequest 380 * the Wi-Fi Aware peer identifier can be constructed using an Identifier set to zero. 381 * 382 * @param macAddress The MAC address of the Responder. 383 * @param peerHandle The Wi-Fi Aware peer identifier of the Responder. 384 * @param responderType The type of the responder device, specified using 385 * {@link ResponderType}. 386 * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc. 387 * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}. 388 * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder. 389 * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses 390 * 40, 80, 160 or 320 MHz, this is the center frequency (in MHz), if the 391 * Responder uses 80 + 80 MHz, this is the center frequency of the first 392 * segment (in MHz). 393 * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the 394 * Responder 395 * uses 80 + 80 MHz, this is the center frequency of the second segment 396 * (in 397 * MHz). 398 * @param preamble The preamble used by the Responder, specified using 399 * {@link PreambleType}. 400 * 401 * @hide 402 */ ResponderConfig(@onNull MacAddress macAddress, @NonNull PeerHandle peerHandle, @ResponderType int responderType, boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0, int centerFreq1, @PreambleType int preamble)403 public ResponderConfig(@NonNull MacAddress macAddress, @NonNull PeerHandle peerHandle, 404 @ResponderType int responderType, boolean supports80211mc, 405 @ChannelWidth int channelWidth, int frequency, int centerFreq0, int centerFreq1, 406 @PreambleType int preamble) { 407 this.macAddress = macAddress; 408 this.peerHandle = peerHandle; 409 this.responderType = responderType; 410 this.supports80211mc = supports80211mc; 411 this.channelWidth = channelWidth; 412 this.frequency = frequency; 413 this.centerFreq0 = centerFreq0; 414 this.centerFreq1 = centerFreq1; 415 this.preamble = preamble; 416 this.supports80211azNtb = false; 417 this.mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS; 418 this.mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS; 419 } 420 421 /** 422 * Creates a Responder configuration from a {@link ScanResult} corresponding to an Access 423 * Point (AP), which can be obtained from {@link android.net.wifi.WifiManager#getScanResults()}. 424 */ 425 @NonNull fromScanResult(@onNull ScanResult scanResult)426 public static ResponderConfig fromScanResult(@NonNull ScanResult scanResult) { 427 MacAddress macAddress = MacAddress.fromString(scanResult.BSSID); 428 int responderType = RESPONDER_AP; 429 boolean supports80211mc = scanResult.is80211mcResponder(); 430 boolean supports80211azNtbRanging = scanResult.is80211azNtbResponder(); 431 int channelWidth = scanResult.channelWidth; 432 int frequency = scanResult.frequency; 433 int centerFreq0 = scanResult.centerFreq0; 434 int centerFreq1 = scanResult.centerFreq1; 435 436 int preamble; 437 if (scanResult.informationElements != null && scanResult.informationElements.length != 0) { 438 boolean htCapabilitiesPresent = false; 439 boolean vhtCapabilitiesPresent = false; 440 boolean heCapabilitiesPresent = false; 441 boolean ehtCapabilitiesPresent = false; 442 443 for (ScanResult.InformationElement ie : scanResult.informationElements) { 444 if (ie.id == EID_HT_CAPABILITIES) { 445 htCapabilitiesPresent = true; 446 } else if (ie.id == EID_VHT_CAPABILITIES) { 447 vhtCapabilitiesPresent = true; 448 } else if (ie.id == EID_EXTENSION_PRESENT && ie.idExt == EID_EXT_HE_CAPABILITIES) { 449 heCapabilitiesPresent = true; 450 } else if (ie.id == EID_EXTENSION_PRESENT && ie.idExt == EID_EXT_EHT_CAPABILITIES) { 451 ehtCapabilitiesPresent = true; 452 } 453 } 454 455 if (ehtCapabilitiesPresent && ScanResult.is6GHz(frequency)) { 456 preamble = ScanResult.PREAMBLE_EHT; 457 } else if (heCapabilitiesPresent && ScanResult.is6GHz(frequency)) { 458 preamble = ScanResult.PREAMBLE_HE; 459 } else if (vhtCapabilitiesPresent) { 460 preamble = ScanResult.PREAMBLE_VHT; 461 } else if (htCapabilitiesPresent) { 462 preamble = ScanResult.PREAMBLE_HT; 463 } else { 464 preamble = ScanResult.PREAMBLE_LEGACY; 465 } 466 } else { 467 Log.e(TAG, "Scan Results do not contain IEs - using backup method to select preamble"); 468 if (channelWidth == ScanResult.CHANNEL_WIDTH_320MHZ) { 469 preamble = ScanResult.PREAMBLE_EHT; 470 } else if (channelWidth == ScanResult.CHANNEL_WIDTH_80MHZ 471 || channelWidth == ScanResult.CHANNEL_WIDTH_160MHZ) { 472 preamble = ScanResult.PREAMBLE_VHT; 473 } else { 474 preamble = ScanResult.PREAMBLE_HT; 475 } 476 } 477 478 return new ResponderConfig.Builder() 479 .setMacAddress(macAddress) 480 .setResponderType(responderType) 481 .set80211mcSupported(supports80211mc) 482 .set80211azNtbSupported(supports80211azNtbRanging) 483 .setChannelWidth(channelWidth) 484 .setFrequencyMhz(frequency) 485 .setCenterFreq0Mhz(centerFreq0) 486 .setCenterFreq1Mhz(centerFreq1) 487 .setPreamble(preamble) 488 .build(); 489 } 490 491 /** 492 * Creates a Responder configuration from a MAC address corresponding to a Wi-Fi Aware 493 * Responder. The Responder parameters are set to defaults. 494 * @hide 495 */ 496 @SystemApi 497 @NonNull fromWifiAwarePeerMacAddressWithDefaults( @onNull MacAddress macAddress)498 public static ResponderConfig fromWifiAwarePeerMacAddressWithDefaults( 499 @NonNull MacAddress macAddress) { 500 /* Note: the parameters are those of the Aware discovery channel (channel 6). A Responder 501 * is expected to be brought up and available to negotiate a maximum accuracy channel 502 * (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware 503 * Unsolicited Publisher with Ranging enabled. 504 */ 505 return new ResponderConfig.Builder() 506 .setMacAddress(macAddress) 507 .setResponderType(RESPONDER_AWARE) 508 .build(); 509 } 510 511 /** 512 * Creates a Responder configuration from a {@link PeerHandle} corresponding to a Wi-Fi Aware 513 * Responder. The Responder parameters are set to defaults. 514 * @hide 515 */ 516 @SystemApi 517 @NonNull fromWifiAwarePeerHandleWithDefaults( @onNull PeerHandle peerHandle)518 public static ResponderConfig fromWifiAwarePeerHandleWithDefaults( 519 @NonNull PeerHandle peerHandle) { 520 /* Note: the parameters are those of the Aware discovery channel (channel 6). A Responder 521 * is expected to be brought up and available to negotiate a maximum accuracy channel 522 * (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware 523 * Unsolicited Publisher with Ranging enabled. 524 */ 525 return new ResponderConfig.Builder() 526 .setPeerHandle(peerHandle) 527 .setResponderType(RESPONDER_AWARE) 528 .build(); 529 } 530 isResponderTypeSupported(@esponderType int responderType)531 private static boolean isResponderTypeSupported(@ResponderType int responderType) { 532 switch (responderType) { 533 case RESPONDER_AP: 534 case RESPONDER_STA: 535 case RESPONDER_AWARE: 536 break; 537 case RESPONDER_P2P_GO: 538 case RESPONDER_P2P_CLIENT: 539 default: 540 return false; 541 } 542 return true; 543 } 544 545 /** 546 * Check whether the Responder configuration is valid. 547 * 548 * @return true if valid, false otherwise. 549 * 550 * @hide 551 */ isValid(boolean awareSupported)552 public boolean isValid(boolean awareSupported) { 553 if (!isResponderTypeSupported(responderType)) return false; 554 if (macAddress == null && peerHandle == null || macAddress != null && peerHandle != null) { 555 return false; 556 } 557 if (!awareSupported && responderType == RESPONDER_AWARE) { 558 return false; 559 } 560 return true; 561 } 562 563 /** 564 * @return the MAC address of the responder 565 */ 566 @Nullable getMacAddress()567 public MacAddress getMacAddress() { 568 return macAddress; 569 } 570 571 /** 572 * @return the peer handle of the responder 573 * 574 * @hide 575 */ 576 @Nullable getPeerHandle()577 public PeerHandle getPeerHandle() { 578 return peerHandle; 579 } 580 581 /** 582 * @return true if the Responder supports the 802.11mc protocol, false otherwise. 583 */ is80211mcSupported()584 public boolean is80211mcSupported() { 585 return supports80211mc; 586 } 587 588 /** 589 * @return true if the Responder supports the 802.11az non-trigger based ranging protocol, 590 * false otherwise. 591 */ 592 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) is80211azNtbSupported()593 public boolean is80211azNtbSupported() { 594 return supports80211azNtb; 595 } 596 597 /** 598 * AP Channel bandwidth; one of {@link ScanResult#CHANNEL_WIDTH_20MHZ}, 599 * {@link ScanResult#CHANNEL_WIDTH_40MHZ}, 600 * {@link ScanResult#CHANNEL_WIDTH_80MHZ}, {@link ScanResult#CHANNEL_WIDTH_160MHZ}, 601 * {@link ScanResult #CHANNEL_WIDTH_80MHZ_PLUS_MHZ} or {@link ScanResult#CHANNEL_WIDTH_320MHZ}. 602 * 603 * @return the bandwidth repsentation of the Wi-Fi channel 604 */ getChannelWidth()605 public @WifiAnnotations.ChannelWidth int getChannelWidth() { 606 return translateFromLocalToScanResultChannelWidth(channelWidth); 607 } 608 609 /** 610 * @return the frequency in MHz of the Wi-Fi channel 611 */ 612 @IntRange(from = 0) getFrequencyMhz()613 public int getFrequencyMhz() { 614 return frequency; 615 } 616 617 /** 618 * If the Access Point (AP) bandwidth is 20 MHz, 0 MHz is returned. 619 * If the AP use 40, 80 or 160 MHz, this is the center frequency (in MHz). 620 * if the AP uses 80 + 80 MHz, this is the center frequency of the first segment (in MHz). 621 * 622 * @return the center frequency in MHz of the first channel segment 623 */ 624 @IntRange(from = 0) getCenterFreq0Mhz()625 public int getCenterFreq0Mhz() { 626 return centerFreq0; 627 } 628 629 /** 630 * If the Access Point (AP) bandwidth is 80 + 80 MHz, this param is not used and returns 0. 631 * If the AP uses 80 + 80 MHz, this is the center frequency of the second segment in MHz. 632 * 633 * @return the center frequency in MHz of the second channel segment (if used) 634 */ 635 @IntRange(from = 0) getCenterFreq1Mhz()636 public int getCenterFreq1Mhz() { 637 return centerFreq1; 638 } 639 640 /** 641 * Get the preamble type of the channel. 642 * 643 * @return the preamble used for this channel 644 */ getPreamble()645 public @WifiAnnotations.PreambleType int getPreamble() { 646 return translateFromLocalToScanResultPreamble(preamble); 647 } 648 649 /** 650 * Get responder type. 651 * @see Builder#setResponderType(int) 652 * @return The type of this responder 653 */ getResponderType()654 public @ResponderType int getResponderType() { 655 return responderType; 656 } 657 658 /** 659 * Gets the minimum time between IEEE 802.11az non-trigger based ranging measurements in 660 * microseconds for the responder. 661 * 662 * @hide 663 */ getNtbMinTimeBetweenMeasurementsMicros()664 public long getNtbMinTimeBetweenMeasurementsMicros() { 665 return mNtbMinMeasurementTime; 666 } 667 668 /** 669 * Gets the maximum time between IEEE 802.11az non-trigger based ranging measurements in 670 * microseconds for the responder. 671 * 672 * @hide 673 */ getNtbMaxTimeBetweenMeasurementsMicros()674 public long getNtbMaxTimeBetweenMeasurementsMicros() { 675 return mNtbMaxMeasurementTime; 676 } 677 678 /** 679 * @hide 680 */ setNtbMinTimeBetweenMeasurementsMicros(long ntbMinMeasurementTime)681 public void setNtbMinTimeBetweenMeasurementsMicros(long ntbMinMeasurementTime) { 682 this.mNtbMinMeasurementTime = ntbMinMeasurementTime; 683 } 684 685 /** 686 * @hide 687 */ setNtbMaxTimeBetweenMeasurementsMicros(long ntbMaxMeasurementTime)688 public void setNtbMaxTimeBetweenMeasurementsMicros(long ntbMaxMeasurementTime) { 689 this.mNtbMaxMeasurementTime = ntbMaxMeasurementTime; 690 } 691 692 /** 693 * Builder class used to construct {@link ResponderConfig} objects. 694 */ 695 public static final class Builder { 696 private MacAddress mMacAddress; 697 private PeerHandle mPeerHandle; 698 private @ResponderType int mResponderType = RESPONDER_AP; 699 private boolean mSupports80211Mc = true; 700 private boolean mSupports80211azNtb = false; 701 private @ChannelWidth int mChannelWidth = CHANNEL_WIDTH_20MHZ; 702 private int mFrequency = 0; 703 private int mCenterFreq0 = 0; 704 private int mCenterFreq1 = 0; 705 private @PreambleType int mPreamble = PREAMBLE_LEGACY; 706 private long mNtbMinMeasurementTime = DEFAULT_NTB_MIN_TIME_BETWEEN_MEASUREMENTS_MICROS; 707 private long mNtbMaxMeasurementTime = DEFAULT_NTB_MAX_TIME_BETWEEN_MEASUREMENTS_MICROS; 708 709 /** 710 * Sets the Responder MAC Address. 711 * 712 * @param macAddress the phyical address of the responder 713 * @return the builder to facilitate chaining 714 * {@code builder.setXXX(..).setXXX(..)}. 715 */ 716 @NonNull setMacAddress(@onNull MacAddress macAddress)717 public Builder setMacAddress(@NonNull MacAddress macAddress) { 718 this.mMacAddress = macAddress; 719 return this; 720 } 721 722 /** 723 * Sets the Responder Peer handle. 724 * 725 * @param peerHandle Peer handle of the resposnde 726 * @return the builder to facilitate chaining 727 * {@code builder.setXXX(..).setXXX(..)}. 728 * @hide 729 */ 730 @NonNull setPeerHandle(@onNull PeerHandle peerHandle)731 public Builder setPeerHandle(@NonNull PeerHandle peerHandle) { 732 this.mPeerHandle = peerHandle; 733 return this; 734 } 735 736 /** 737 * Sets an indication the access point can to respond to the two-sided Wi-Fi RTT protocol, 738 * but, if false, indicates only one-sided Wi-Fi RTT is possible. 739 * 740 * @param supports80211mc the ability to support the Wi-Fi RTT protocol 741 * @return the builder to facilitate chaining 742 * {@code builder.setXXX(..).setXXX(..)}. 743 */ 744 @NonNull set80211mcSupported(boolean supports80211mc)745 public Builder set80211mcSupported(boolean supports80211mc) { 746 this.mSupports80211Mc = supports80211mc; 747 return this; 748 } 749 750 /** 751 * Sets an indication the access point can to respond to the IEEE 802.11az non-trigger 752 * based ranging protocol, but, if false, indicates only IEEE 802.11mc or one-sided Wi-Fi 753 * RTT is possible. 754 * 755 * @param supports80211azNtb the ability to support the IEEE 802.11az non-trigger based 756 * ranging protocol 757 * @return the builder to facilitate chaining 758 * {@code builder.setXXX(..).setXXX(..)}. 759 */ 760 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 761 @NonNull set80211azNtbSupported(boolean supports80211azNtb)762 public Builder set80211azNtbSupported(boolean supports80211azNtb) { 763 this.mSupports80211azNtb = supports80211azNtb; 764 return this; 765 } 766 767 /** 768 * Sets the channel bandwidth in MHz. 769 * 770 * @param channelWidth the bandwidth of the channel in MHz 771 * @return the builder to facilitate chaining 772 * {@code builder.setXXX(..).setXXX(..)}. 773 */ 774 @NonNull setChannelWidth(@ifiAnnotations.ChannelWidth int channelWidth)775 public Builder setChannelWidth(@WifiAnnotations.ChannelWidth int channelWidth) { 776 this.mChannelWidth = translateFromScanResultToLocalChannelWidth(channelWidth); 777 return this; 778 } 779 780 /** 781 * Sets the frequency of the channel in MHz. 782 * <p> 783 * Note: The frequency is used as a hint, and the underlying WiFi subsystem may use it, or 784 * select an alternate if its own connectivity scans have determined the frequency of the 785 * access point has changed. 786 * </p> 787 * 788 * @param frequency the frequency of the channel in MHz 789 * @return the builder to facilitate chaining 790 * {@code builder.setXXX(..).setXXX(..)}. 791 */ 792 @NonNull setFrequencyMhz(@ntRangefrom = 0) int frequency)793 public Builder setFrequencyMhz(@IntRange(from = 0) int frequency) { 794 this.mFrequency = frequency; 795 return this; 796 } 797 798 /** 799 * Sets the center frequency in MHz of the first segment of the channel. 800 * <p> 801 * Note: The frequency is used as a hint, and the underlying WiFi subsystem may use it, or 802 * select an alternate if its own connectivity scans have determined the frequency of the 803 * access point has changed. 804 * </p> 805 * 806 * @param centerFreq0 the center frequency in MHz of first channel segment 807 * @return the builder to facilitate chaining 808 * {@code builder.setXXX(..).setXXX(..)}. 809 */ 810 @NonNull setCenterFreq0Mhz(@ntRangefrom = 0) int centerFreq0)811 public Builder setCenterFreq0Mhz(@IntRange(from = 0) int centerFreq0) { 812 this.mCenterFreq0 = centerFreq0; 813 return this; 814 } 815 816 /** 817 * Sets the center frequency in MHz of the second segment of the channel, if used. 818 * <p> 819 * Note: The frequency is used as a hint, and the underlying WiFi subsystem may use it, or 820 * select an alternate if its own connectivity scans have determined the frequency of the 821 * access point has changed. 822 * </p> 823 * 824 * @param centerFreq1 the center frequency in MHz of second channel segment 825 * @return the builder to facilitate chaining 826 * {@code builder.setXXX(..).setXXX(..)}. 827 */ 828 @NonNull setCenterFreq1Mhz(@ntRangefrom = 0) int centerFreq1)829 public Builder setCenterFreq1Mhz(@IntRange(from = 0) int centerFreq1) { 830 this.mCenterFreq1 = centerFreq1; 831 return this; 832 } 833 834 /** 835 * Sets the preamble encoding for the protocol. 836 * 837 * @param preamble the preamble encoding 838 * @return the builder to facilitate chaining 839 * {@code builder.setXXX(..).setXXX(..)}. 840 */ 841 @NonNull setPreamble(@ifiAnnotations.PreambleType int preamble)842 public Builder setPreamble(@WifiAnnotations.PreambleType int preamble) { 843 this.mPreamble = translateFromScanResultToLocalPreamble(preamble); 844 return this; 845 } 846 847 /** 848 * Sets the responder type, can be {@link #RESPONDER_AP} or {@link #RESPONDER_STA} or 849 * {@link #RESPONDER_AWARE} 850 * 851 * @param responderType the type of the responder, if not set defaults to 852 * {@link #RESPONDER_AP} 853 * @return the builder to facilitate chaining {@code builder.setXXX(..).setXXX(..)}. 854 */ 855 @NonNull setResponderType(@esponderType int responderType)856 public Builder setResponderType(@ResponderType int responderType) { 857 if (!isResponderTypeSupported(responderType)) { 858 throw new IllegalArgumentException("invalid responder type " + responderType); 859 } 860 mResponderType = responderType; 861 return this; 862 } 863 864 /** 865 * Sets the minimum time between IEEE 802.11az non-trigger based ranging measurements in 866 * microseconds for the responder. 867 * 868 * Note: This should be a multiple of 100 microseconds as per IEEE 802.11 az standard. 869 * 870 * @param ntbMinMeasurementTime Minimum time between non-trigger based IEEE 802.11az 871 * ranging measurements in units of 100 microseconds. Range of 872 * values (0, 419430400). 873 * @hide 874 */ setNtbMinTimeBetweenMeasurementsMicros(long ntbMinMeasurementTime)875 public Builder setNtbMinTimeBetweenMeasurementsMicros(long ntbMinMeasurementTime) { 876 if (mNtbMinMeasurementTime == 0 || mNtbMinMeasurementTime >= 419430400) { 877 throw new IllegalArgumentException( 878 "Should be a non-zero number less than 419430400 microseconds"); 879 } 880 if (mNtbMinMeasurementTime % 100 != 0) { 881 throw new IllegalArgumentException("Should be a multiple of 100 microseconds"); 882 } 883 mNtbMinMeasurementTime = ntbMinMeasurementTime; 884 return this; 885 } 886 887 /** 888 * Sets the maximum time between IEEE 802.11az non-trigger based ranging measurements in 889 * microseconds for the responder. 890 * 891 * Note: This should be a multiple of 10000 microseconds (10 milliseconds) as per 892 * IEEE 802.11 az standard. 893 * 894 * @param ntbMaxMeasurementTime Maximum time between non-trigger based IEEE 802.11az 895 * ranging measurements in units of 10000 microseconds. Range 896 * of values (0, 5242880000). 897 * @hide 898 */ setNtbMaxTimeBetweenMeasurementsMicros(long ntbMaxMeasurementTime)899 public Builder setNtbMaxTimeBetweenMeasurementsMicros(long ntbMaxMeasurementTime) { 900 if (mNtbMaxMeasurementTime % 10000 != 0) { 901 throw new IllegalArgumentException("Should be a multiple of 10000 microseconds"); 902 } 903 if (mNtbMaxMeasurementTime == 0 || mNtbMaxMeasurementTime >= 5242880000L) { 904 throw new IllegalArgumentException( 905 "Should be a non-zero number less than 5242880000 microseconds"); 906 } 907 mNtbMaxMeasurementTime = ntbMaxMeasurementTime; 908 return this; 909 } 910 911 /** 912 * Build {@link ResponderConfig} given the current configurations made on the builder. 913 * @return an instance of {@link ResponderConfig} 914 */ 915 @NonNull build()916 public ResponderConfig build() { 917 if ((mMacAddress == null && mPeerHandle == null) 918 || (mMacAddress != null && mPeerHandle != null)) { 919 throw new IllegalArgumentException( 920 "Invalid ResponderConfig - must specify a MAC address or peer handle but " 921 + "not both"); 922 } 923 // For Aware, use supported default values 924 if (mResponderType == RESPONDER_AWARE) { 925 mSupports80211Mc = true; 926 mFrequency = AWARE_BAND_2_DISCOVERY_CHANNEL; 927 mChannelWidth = CHANNEL_WIDTH_20MHZ; 928 mPreamble = PREAMBLE_HT; 929 } 930 return new ResponderConfig(this); 931 } 932 } 933 934 @Override describeContents()935 public int describeContents() { 936 return 0; 937 } 938 939 @Override writeToParcel(@onNull Parcel dest, int flags)940 public void writeToParcel(@NonNull Parcel dest, int flags) { 941 if (macAddress == null) { 942 dest.writeBoolean(false); 943 } else { 944 dest.writeBoolean(true); 945 macAddress.writeToParcel(dest, flags); 946 } 947 if (peerHandle == null) { 948 dest.writeBoolean(false); 949 } else { 950 dest.writeBoolean(true); 951 dest.writeInt(peerHandle.peerId); 952 } 953 dest.writeInt(responderType); 954 dest.writeBoolean(supports80211mc); 955 dest.writeBoolean(supports80211azNtb); 956 dest.writeInt(channelWidth); 957 dest.writeInt(frequency); 958 dest.writeInt(centerFreq0); 959 dest.writeInt(centerFreq1); 960 dest.writeInt(preamble); 961 dest.writeLong(mNtbMinMeasurementTime); 962 dest.writeLong(mNtbMaxMeasurementTime); 963 } 964 965 public static final @android.annotation.NonNull Creator<ResponderConfig> CREATOR = new Creator<ResponderConfig>() { 966 @Override 967 public ResponderConfig[] newArray(int size) { 968 return new ResponderConfig[size]; 969 } 970 971 @Override 972 public ResponderConfig createFromParcel(Parcel in) { 973 boolean macAddressPresent = in.readBoolean(); 974 MacAddress macAddress = null; 975 if (macAddressPresent) { 976 macAddress = MacAddress.CREATOR.createFromParcel(in); 977 } 978 boolean peerHandlePresent = in.readBoolean(); 979 PeerHandle peerHandle = null; 980 if (peerHandlePresent) { 981 peerHandle = new PeerHandle(in.readInt()); 982 } 983 984 return new ResponderConfig.Builder() 985 .setMacAddress(macAddress) 986 .setPeerHandle(peerHandle) 987 .setResponderType(in.readInt()) 988 .set80211mcSupported(in.readBoolean()) 989 .set80211azNtbSupported(in.readBoolean()) 990 .setChannelWidth(in.readInt()) 991 .setFrequencyMhz(in.readInt()) 992 .setCenterFreq0Mhz(in.readInt()) 993 .setCenterFreq1Mhz(in.readInt()) 994 .setPreamble(in.readInt()) 995 .setNtbMinTimeBetweenMeasurementsMicros(in.readLong()) 996 .setNtbMaxTimeBetweenMeasurementsMicros(in.readLong()) 997 .build(); 998 } 999 }; 1000 1001 @Override equals(@ullable Object o)1002 public boolean equals(@Nullable Object o) { 1003 if (this == o) { 1004 return true; 1005 } 1006 1007 if (!(o instanceof ResponderConfig)) { 1008 return false; 1009 } 1010 1011 ResponderConfig lhs = (ResponderConfig) o; 1012 1013 return Objects.equals(macAddress, lhs.macAddress) && Objects.equals(peerHandle, 1014 lhs.peerHandle) && responderType == lhs.responderType 1015 && supports80211mc == lhs.supports80211mc && channelWidth == lhs.channelWidth 1016 && frequency == lhs.frequency && centerFreq0 == lhs.centerFreq0 1017 && centerFreq1 == lhs.centerFreq1 && preamble == lhs.preamble 1018 && supports80211azNtb == lhs.supports80211azNtb 1019 && mNtbMinMeasurementTime == lhs.mNtbMinMeasurementTime 1020 && mNtbMaxMeasurementTime == lhs.mNtbMaxMeasurementTime; 1021 } 1022 1023 @Override hashCode()1024 public int hashCode() { 1025 return Objects.hash(macAddress, peerHandle, responderType, supports80211mc, channelWidth, 1026 frequency, centerFreq0, centerFreq1, preamble, supports80211azNtb, 1027 mNtbMinMeasurementTime, mNtbMaxMeasurementTime); 1028 } 1029 1030 @Override toString()1031 public String toString() { 1032 return new StringBuffer("ResponderConfig: macAddress=").append(macAddress) 1033 .append(", peerHandle=").append(peerHandle == null ? "<null>" : peerHandle.peerId) 1034 .append(", responderType=").append(responderType) 1035 .append(", supports80211mc=").append(supports80211mc) 1036 .append(", channelWidth=").append(channelWidth) 1037 .append(", frequency=").append(frequency) 1038 .append(", centerFreq0=").append(centerFreq0) 1039 .append(", centerFreq1=").append(centerFreq1) 1040 .append(", preamble=").append(preamble) 1041 .append(", supports80211azNtb=").append(supports80211azNtb) 1042 .append(", mNtbMinMeasurementTime ").append(mNtbMinMeasurementTime) 1043 .append(", mNtbMaxMeasurementTime ").append(mNtbMaxMeasurementTime) 1044 .toString(); 1045 } 1046 1047 /** 1048 * Translate an SDK channel width encoding to a local channel width encoding 1049 * 1050 * @param scanResultChannelWidth the {@link ScanResult} defined channel width encoding 1051 * @return the translated channel width encoding 1052 * 1053 * @hide 1054 */ translateFromScanResultToLocalChannelWidth( @ifiAnnotations.ChannelWidth int scanResultChannelWidth)1055 static int translateFromScanResultToLocalChannelWidth( 1056 @WifiAnnotations.ChannelWidth int scanResultChannelWidth) { 1057 switch (scanResultChannelWidth) { 1058 case ScanResult.CHANNEL_WIDTH_20MHZ: 1059 return CHANNEL_WIDTH_20MHZ; 1060 case ScanResult.CHANNEL_WIDTH_40MHZ: 1061 return CHANNEL_WIDTH_40MHZ; 1062 case ScanResult.CHANNEL_WIDTH_80MHZ: 1063 return CHANNEL_WIDTH_80MHZ; 1064 case ScanResult.CHANNEL_WIDTH_160MHZ: 1065 return CHANNEL_WIDTH_160MHZ; 1066 case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: 1067 return CHANNEL_WIDTH_80MHZ_PLUS_MHZ; 1068 case ScanResult.CHANNEL_WIDTH_320MHZ: 1069 return CHANNEL_WIDTH_320MHZ; 1070 default: 1071 throw new IllegalArgumentException( 1072 "translateFromScanResultChannelWidth: bad " + scanResultChannelWidth); 1073 } 1074 } 1075 1076 /** 1077 * Translate the local channel width encoding to the SDK channel width encoding. 1078 * 1079 * @param localChannelWidth the locally defined channel width encoding 1080 * @return the translated channel width encoding 1081 * 1082 * @hide 1083 */ translateFromLocalToScanResultChannelWidth(@hannelWidth int localChannelWidth)1084 static int translateFromLocalToScanResultChannelWidth(@ChannelWidth int localChannelWidth) { 1085 switch (localChannelWidth) { 1086 case CHANNEL_WIDTH_20MHZ: 1087 return ScanResult.CHANNEL_WIDTH_20MHZ; 1088 case CHANNEL_WIDTH_40MHZ: 1089 return ScanResult.CHANNEL_WIDTH_40MHZ; 1090 case CHANNEL_WIDTH_80MHZ: 1091 return ScanResult.CHANNEL_WIDTH_80MHZ; 1092 case CHANNEL_WIDTH_160MHZ: 1093 return ScanResult.CHANNEL_WIDTH_160MHZ; 1094 case CHANNEL_WIDTH_80MHZ_PLUS_MHZ: 1095 return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; 1096 case CHANNEL_WIDTH_320MHZ: 1097 return ScanResult.CHANNEL_WIDTH_320MHZ; 1098 default: 1099 throw new IllegalArgumentException( 1100 "translateFromLocalChannelWidth: bad " + localChannelWidth); 1101 } 1102 } 1103 1104 /** 1105 * Translate the {@link ScanResult} preamble encoding to the local preamble encoding. 1106 * 1107 * @param scanResultPreamble the channel width supplied 1108 * @return the local encoding of the Preamble 1109 * 1110 * @hide 1111 */ translateFromScanResultToLocalPreamble( @ifiAnnotations.PreambleType int scanResultPreamble)1112 static int translateFromScanResultToLocalPreamble( 1113 @WifiAnnotations.PreambleType int scanResultPreamble) { 1114 switch (scanResultPreamble) { 1115 case ScanResult.PREAMBLE_LEGACY: 1116 return PREAMBLE_LEGACY; 1117 case ScanResult.PREAMBLE_HT: 1118 return PREAMBLE_HT; 1119 case ScanResult.PREAMBLE_VHT: 1120 return PREAMBLE_VHT; 1121 case ScanResult.PREAMBLE_HE: 1122 return PREAMBLE_HE; 1123 case ScanResult.PREAMBLE_EHT: 1124 return PREAMBLE_EHT; 1125 default: 1126 throw new IllegalArgumentException( 1127 "translateFromScanResultPreamble: bad " + scanResultPreamble); 1128 } 1129 } 1130 1131 /** 1132 * Translate the local preamble encoding to the {@link ScanResult} preamble encoding. 1133 * 1134 * @param localPreamble the local preamble encoding 1135 * @return the {@link ScanResult} encoding of the Preamble 1136 * 1137 * @hide 1138 */ translateFromLocalToScanResultPreamble(@reambleType int localPreamble)1139 static int translateFromLocalToScanResultPreamble(@PreambleType int localPreamble) { 1140 switch (localPreamble) { 1141 case PREAMBLE_LEGACY: 1142 return ScanResult.PREAMBLE_LEGACY; 1143 case PREAMBLE_HT: 1144 return ScanResult.PREAMBLE_HT; 1145 case PREAMBLE_VHT: 1146 return ScanResult.PREAMBLE_VHT; 1147 case PREAMBLE_HE: 1148 return ScanResult.PREAMBLE_HE; 1149 case PREAMBLE_EHT: 1150 return ScanResult.PREAMBLE_EHT; 1151 default: 1152 throw new IllegalArgumentException( 1153 "translateFromLocalPreamble: bad " + localPreamble); 1154 } 1155 } 1156 } 1157