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