diff options
Diffstat (limited to 'android/net/wifi/rtt/ResponderConfig.java')
-rw-r--r-- | android/net/wifi/rtt/ResponderConfig.java | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/android/net/wifi/rtt/ResponderConfig.java b/android/net/wifi/rtt/ResponderConfig.java new file mode 100644 index 00000000..c3e10074 --- /dev/null +++ b/android/net/wifi/rtt/ResponderConfig.java @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.rtt; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.net.MacAddress; +import android.net.wifi.ScanResult; +import android.net.wifi.aware.PeerHandle; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +/** + * Defines the configuration of an IEEE 802.11mc Responder. The Responder may be an Access Point + * (AP), a Wi-Fi Aware device, or a manually configured Responder. + * <p> + * A Responder configuration may be constructed from a {@link ScanResult} or manually (with the + * data obtained out-of-band from a peer). + * + * @hide (@SystemApi) + */ +public final class ResponderConfig implements Parcelable { + private static final int AWARE_BAND_2_DISCOVERY_CHANNEL = 2437; + + /** @hide */ + @IntDef({RESPONDER_AP, RESPONDER_STA, RESPONDER_P2P_GO, RESPONDER_P2P_CLIENT, RESPONDER_AWARE}) + @Retention(RetentionPolicy.SOURCE) + public @interface ResponderType { + } + + /** + * Responder is an AP. + */ + public static final int RESPONDER_AP = 0; + /** + * Responder is a STA. + */ + public static final int RESPONDER_STA = 1; + /** + * Responder is a Wi-Fi Direct Group Owner (GO). + */ + public static final int RESPONDER_P2P_GO = 2; + /** + * Responder is a Wi-Fi Direct Group Client. + */ + public static final int RESPONDER_P2P_CLIENT = 3; + /** + * Responder is a Wi-Fi Aware device. + */ + public static final int RESPONDER_AWARE = 4; + + + /** @hide */ + @IntDef({ + CHANNEL_WIDTH_20MHZ, CHANNEL_WIDTH_40MHZ, CHANNEL_WIDTH_80MHZ, CHANNEL_WIDTH_160MHZ, + CHANNEL_WIDTH_80MHZ_PLUS_MHZ}) + @Retention(RetentionPolicy.SOURCE) + public @interface ChannelWidth { + } + + /** + * Channel bandwidth is 20 MHZ + */ + public static final int CHANNEL_WIDTH_20MHZ = 0; + /** + * Channel bandwidth is 40 MHZ + */ + public static final int CHANNEL_WIDTH_40MHZ = 1; + /** + * Channel bandwidth is 80 MHZ + */ + public static final int CHANNEL_WIDTH_80MHZ = 2; + /** + * Channel bandwidth is 160 MHZ + */ + public static final int CHANNEL_WIDTH_160MHZ = 3; + /** + * Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ + */ + public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; + + /** @hide */ + @IntDef({PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT}) + @Retention(RetentionPolicy.SOURCE) + public @interface PreambleType { + } + + /** + * Preamble type: Legacy. + */ + public static final int PREAMBLE_LEGACY = 0; + + /** + * Preamble type: HT. + */ + public static final int PREAMBLE_HT = 1; + + /** + * Preamble type: VHT. + */ + public static final int PREAMBLE_VHT = 2; + + + /** + * The MAC address of the Responder. Will be null if a Wi-Fi Aware peer identifier (the + * peerHandle field) ise used to identify the Responder. + */ + public final MacAddress macAddress; + + /** + * The peer identifier of a Wi-Fi Aware Responder. Will be null if a MAC Address (the macAddress + * field) is used to identify the Responder. + */ + public final PeerHandle peerHandle; + + /** + * The device type of the Responder. + */ + public final int responderType; + + /** + * Indicates whether the Responder device supports IEEE 802.11mc. + */ + public final boolean supports80211mc; + + /** + * Responder channel bandwidth, specified using {@link ChannelWidth}. + */ + public final int channelWidth; + + /** + * The primary 20 MHz frequency (in MHz) of the channel of the Responder. + */ + public final int frequency; + + /** + * Not used if the {@link #channelWidth} is 20 MHz. If the Responder uses 40, 80 or 160 MHz, + * this is the center frequency (in MHz), if the Responder uses 80 + 80 MHz, this is the + * center frequency of the first segment (in MHz). + */ + public final int centerFreq0; + + /** + * Only used if the {@link #channelWidth} is 80 + 80 MHz. If the Responder uses 80 + 80 MHz, + * this is the center frequency of the second segment (in MHz). + */ + public final int centerFreq1; + + /** + * The preamble used by the Responder, specified using {@link PreambleType}. + */ + public final int preamble; + + /** + * Constructs Responder configuration, using a MAC address to identify the Responder. + * + * @param macAddress The MAC address of the Responder. + * @param responderType The type of the responder device, specified using + * {@link ResponderType}. + * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc. + * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}. + * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder. + * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses + * 40, 80 or 160 MHz, this is the center frequency (in MHz), if the + * Responder uses 80 + 80 MHz, this is the center frequency of the first + * segment (in MHz). + * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the + * Responder + * uses 80 + 80 MHz, this is the center frequency of the second segment + * (in + * MHz). + * @param preamble The preamble used by the Responder, specified using + * {@link PreambleType}. + */ + public ResponderConfig(@NonNull MacAddress macAddress, @ResponderType int responderType, + boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0, + int centerFreq1, @PreambleType int preamble) { + if (macAddress == null) { + throw new IllegalArgumentException( + "Invalid ResponderConfig - must specify a MAC address"); + } + this.macAddress = macAddress; + this.peerHandle = null; + this.responderType = responderType; + this.supports80211mc = supports80211mc; + this.channelWidth = channelWidth; + this.frequency = frequency; + this.centerFreq0 = centerFreq0; + this.centerFreq1 = centerFreq1; + this.preamble = preamble; + } + + /** + * Constructs Responder configuration, using a Wi-Fi Aware PeerHandle to identify the Responder. + * + * @param peerHandle The Wi-Fi Aware peer identifier of the Responder. + * @param responderType The type of the responder device, specified using + * {@link ResponderType}. + * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc. + * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}. + * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder. + * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses + * 40, 80 or 160 MHz, this is the center frequency (in MHz), if the + * Responder uses 80 + 80 MHz, this is the center frequency of the first + * segment (in MHz). + * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the + * Responder + * uses 80 + 80 MHz, this is the center frequency of the second segment + * (in + * MHz). + * @param preamble The preamble used by the Responder, specified using + * {@link PreambleType}. + */ + public ResponderConfig(@NonNull PeerHandle peerHandle, @ResponderType int responderType, + boolean supports80211mc, @ChannelWidth int channelWidth, int frequency, int centerFreq0, + int centerFreq1, @PreambleType int preamble) { + this.macAddress = null; + this.peerHandle = peerHandle; + this.responderType = responderType; + this.supports80211mc = supports80211mc; + this.channelWidth = channelWidth; + this.frequency = frequency; + this.centerFreq0 = centerFreq0; + this.centerFreq1 = centerFreq1; + this.preamble = preamble; + } + + /** + * Constructs Responder configuration. This is an internal-only constructor which specifies both + * a MAC address and a Wi-Fi PeerHandle to identify the Responder. + * + * @param macAddress The MAC address of the Responder. + * @param peerHandle The Wi-Fi Aware peer identifier of the Responder. + * @param responderType The type of the responder device, specified using + * {@link ResponderType}. + * @param supports80211mc Indicates whether the responder supports IEEE 802.11mc. + * @param channelWidth Responder channel bandwidth, specified using {@link ChannelWidth}. + * @param frequency The primary 20 MHz frequency (in MHz) of the channel of the Responder. + * @param centerFreq0 Not used if the {@code channelWidth} is 20 MHz. If the Responder uses + * 40, 80 or 160 MHz, this is the center frequency (in MHz), if the + * Responder uses 80 + 80 MHz, this is the center frequency of the first + * segment (in MHz). + * @param centerFreq1 Only used if the {@code channelWidth} is 80 + 80 MHz. If the + * Responder + * uses 80 + 80 MHz, this is the center frequency of the second segment + * (in + * MHz). + * @param preamble The preamble used by the Responder, specified using + * {@link PreambleType}. + * @hide + */ + public ResponderConfig(@NonNull MacAddress macAddress, @NonNull PeerHandle peerHandle, + @ResponderType int responderType, boolean supports80211mc, + @ChannelWidth int channelWidth, int frequency, int centerFreq0, int centerFreq1, + @PreambleType int preamble) { + this.macAddress = macAddress; + this.peerHandle = peerHandle; + this.responderType = responderType; + this.supports80211mc = supports80211mc; + this.channelWidth = channelWidth; + this.frequency = frequency; + this.centerFreq0 = centerFreq0; + this.centerFreq1 = centerFreq1; + this.preamble = preamble; + } + + /** + * Creates a Responder configuration from a {@link ScanResult} corresponding to an Access + * Point (AP), which can be obtained from {@link android.net.wifi.WifiManager#getScanResults()}. + */ + public static ResponderConfig fromScanResult(ScanResult scanResult) { + MacAddress macAddress = MacAddress.fromString(scanResult.BSSID); + int responderType = RESPONDER_AP; + boolean supports80211mc = scanResult.is80211mcResponder(); + int channelWidth = translcateScanResultChannelWidth(scanResult.channelWidth); + int frequency = scanResult.frequency; + int centerFreq0 = scanResult.centerFreq0; + int centerFreq1 = scanResult.centerFreq1; + + // TODO: b/68936111 - extract preamble info from IE + int preamble; + if (channelWidth == CHANNEL_WIDTH_80MHZ || channelWidth == CHANNEL_WIDTH_160MHZ) { + preamble = PREAMBLE_VHT; + } else { + preamble = PREAMBLE_HT; + } + + return new ResponderConfig(macAddress, responderType, supports80211mc, channelWidth, + frequency, centerFreq0, centerFreq1, preamble); + } + + /** + * Creates a Responder configuration from a MAC address corresponding to a Wi-Fi Aware + * Responder. The Responder parameters are set to defaults. + */ + public static ResponderConfig fromWifiAwarePeerMacAddressWithDefaults(MacAddress macAddress) { + /* Note: the parameters are those of the Aware discovery channel (channel 6). A Responder + * is expected to be brought up and available to negotiate a maximum accuracy channel + * (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware + * Unsolicited Publisher with Ranging enabled. + */ + return new ResponderConfig(macAddress, RESPONDER_AWARE, true, CHANNEL_WIDTH_20MHZ, + AWARE_BAND_2_DISCOVERY_CHANNEL, 0, 0, PREAMBLE_HT); + } + + /** + * Creates a Responder configuration from a {@link PeerHandle} corresponding to a Wi-Fi Aware + * Responder. The Responder parameters are set to defaults. + */ + public static ResponderConfig fromWifiAwarePeerHandleWithDefaults(PeerHandle peerHandle) { + /* Note: the parameters are those of the Aware discovery channel (channel 6). A Responder + * is expected to be brought up and available to negotiate a maximum accuracy channel + * (i.e. Band 5 @ 80MHz). A Responder is brought up on the peer by starting an Aware + * Unsolicited Publisher with Ranging enabled. + */ + return new ResponderConfig(peerHandle, RESPONDER_AWARE, true, CHANNEL_WIDTH_20MHZ, + AWARE_BAND_2_DISCOVERY_CHANNEL, 0, 0, PREAMBLE_HT); + } + + /** + * Check whether the Responder configuration is valid. + * + * @return true if valid, false otherwise. + * @hide + */ + public boolean isValid(boolean awareSupported) { + if (macAddress == null && peerHandle == null || macAddress != null && peerHandle != null) { + return false; + } + if (!awareSupported && responderType == RESPONDER_AWARE) { + return false; + } + + return true; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + if (macAddress == null) { + dest.writeBoolean(false); + } else { + dest.writeBoolean(true); + macAddress.writeToParcel(dest, flags); + } + if (peerHandle == null) { + dest.writeBoolean(false); + } else { + dest.writeBoolean(true); + dest.writeInt(peerHandle.peerId); + } + dest.writeInt(responderType); + dest.writeInt(supports80211mc ? 1 : 0); + dest.writeInt(channelWidth); + dest.writeInt(frequency); + dest.writeInt(centerFreq0); + dest.writeInt(centerFreq1); + dest.writeInt(preamble); + } + + public static final Creator<ResponderConfig> CREATOR = new Creator<ResponderConfig>() { + @Override + public ResponderConfig[] newArray(int size) { + return new ResponderConfig[size]; + } + + @Override + public ResponderConfig createFromParcel(Parcel in) { + boolean macAddressPresent = in.readBoolean(); + MacAddress macAddress = null; + if (macAddressPresent) { + macAddress = MacAddress.CREATOR.createFromParcel(in); + } + boolean peerHandlePresent = in.readBoolean(); + PeerHandle peerHandle = null; + if (peerHandlePresent) { + peerHandle = new PeerHandle(in.readInt()); + } + int responderType = in.readInt(); + boolean supports80211mc = in.readInt() == 1; + int channelWidth = in.readInt(); + int frequency = in.readInt(); + int centerFreq0 = in.readInt(); + int centerFreq1 = in.readInt(); + int preamble = in.readInt(); + + if (peerHandle == null) { + return new ResponderConfig(macAddress, responderType, supports80211mc, channelWidth, + frequency, centerFreq0, centerFreq1, preamble); + } else { + return new ResponderConfig(peerHandle, responderType, supports80211mc, channelWidth, + frequency, centerFreq0, centerFreq1, preamble); + } + } + }; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof ResponderConfig)) { + return false; + } + + ResponderConfig lhs = (ResponderConfig) o; + + return Objects.equals(macAddress, lhs.macAddress) && Objects.equals(peerHandle, + lhs.peerHandle) && responderType == lhs.responderType + && supports80211mc == lhs.supports80211mc && channelWidth == lhs.channelWidth + && frequency == lhs.frequency && centerFreq0 == lhs.centerFreq0 + && centerFreq1 == lhs.centerFreq1 && preamble == lhs.preamble; + } + + @Override + public int hashCode() { + return Objects.hash(macAddress, peerHandle, responderType, supports80211mc, channelWidth, + frequency, centerFreq0, centerFreq1, preamble); + } + + /** @hide */ + @Override + public String toString() { + return new StringBuffer("ResponderConfig: macAddress=").append(macAddress).append( + ", peerHandle=").append(peerHandle == null ? "<null>" : peerHandle.peerId).append( + ", responderType=").append(responderType).append(", supports80211mc=").append( + supports80211mc).append(", channelWidth=").append(channelWidth).append( + ", frequency=").append(frequency).append(", centerFreq0=").append( + centerFreq0).append(", centerFreq1=").append(centerFreq1).append( + ", preamble=").append(preamble).toString(); + } + + /** @hide */ + static int translcateScanResultChannelWidth(int scanResultChannelWidth) { + switch (scanResultChannelWidth) { + case ScanResult.CHANNEL_WIDTH_20MHZ: + return CHANNEL_WIDTH_20MHZ; + case ScanResult.CHANNEL_WIDTH_40MHZ: + return CHANNEL_WIDTH_40MHZ; + case ScanResult.CHANNEL_WIDTH_80MHZ: + return CHANNEL_WIDTH_80MHZ; + case ScanResult.CHANNEL_WIDTH_160MHZ: + return CHANNEL_WIDTH_160MHZ; + case ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: + return CHANNEL_WIDTH_80MHZ_PLUS_MHZ; + default: + throw new IllegalArgumentException( + "translcateScanResultChannelWidth: bad " + scanResultChannelWidth); + } + } +} |