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