/* * Copyright (C) 2008 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; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.net.wifi.WifiAnnotations.ChannelWidth; import android.net.wifi.WifiAnnotations.WifiStandard; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import com.android.modules.utils.build.SdkLevel; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; /** * Describes information about a detected access point. In addition * to the attributes described here, the supplicant keeps track of * {@code quality}, {@code noise}, and {@code maxbitrate} attributes, * but does not currently report them to external clients. */ public final class ScanResult implements Parcelable { /** * The network name. */ public String SSID; /** * Ascii encoded SSID. This will replace SSID when we deprecate it. @hide */ @UnsupportedAppUsage public WifiSsid wifiSsid; /** * The address of the access point. */ public String BSSID; /** * The HESSID from the beacon. * @hide */ @UnsupportedAppUsage public long hessid; /** * The ANQP Domain ID from the Hotspot 2.0 Indication element, if present. * @hide */ @UnsupportedAppUsage public int anqpDomainId; /* * This field is equivalent to the |flags|, rather than the |capabilities| field * of the per-BSS scan results returned by WPA supplicant. See the definition of * |struct wpa_bss| in wpa_supplicant/bss.h for more details. */ /** * Describes the authentication, key management, and encryption schemes * supported by the access point. */ public String capabilities; /** * The interface name on which the scan result was received. * @hide */ public String ifaceName; /** * @hide * No security protocol. */ @SystemApi public static final int PROTOCOL_NONE = 0; /** * @hide * Security protocol type: WPA version 1. */ @SystemApi public static final int PROTOCOL_WPA = 1; /** * @hide * Security protocol type: RSN, for WPA version 2, and version 3. */ @SystemApi public static final int PROTOCOL_RSN = 2; /** * @hide * Security protocol type: * OSU Server-only authenticated layer 2 Encryption Network. * Used for Hotspot 2.0. */ @SystemApi public static final int PROTOCOL_OSEN = 3; /** * @hide * Security protocol type: WAPI. */ @SystemApi public static final int PROTOCOL_WAPI = 4; /** * @hide * No security key management scheme. */ @SystemApi public static final int KEY_MGMT_NONE = 0; /** * @hide * Security key management scheme: PSK. */ @SystemApi public static final int KEY_MGMT_PSK = 1; /** * @hide * Security key management scheme: EAP. */ @SystemApi public static final int KEY_MGMT_EAP = 2; /** * @hide * Security key management scheme: FT_PSK. */ @SystemApi public static final int KEY_MGMT_FT_PSK = 3; /** * @hide * Security key management scheme: FT_EAP. */ @SystemApi public static final int KEY_MGMT_FT_EAP = 4; /** * @hide * Security key management scheme: PSK_SHA256 */ @SystemApi public static final int KEY_MGMT_PSK_SHA256 = 5; /** * @hide * Security key management scheme: EAP_SHA256. */ @SystemApi public static final int KEY_MGMT_EAP_SHA256 = 6; /** * @hide * Security key management scheme: OSEN. * Used for Hotspot 2.0. */ @SystemApi public static final int KEY_MGMT_OSEN = 7; /** * @hide * Security key management scheme: SAE. */ @SystemApi public static final int KEY_MGMT_SAE = 8; /** * @hide * Security key management scheme: OWE. */ @SystemApi public static final int KEY_MGMT_OWE = 9; /** * @hide * Security key management scheme: SUITE_B_192. */ @SystemApi public static final int KEY_MGMT_EAP_SUITE_B_192 = 10; /** * @hide * Security key management scheme: FT_SAE. */ @SystemApi public static final int KEY_MGMT_FT_SAE = 11; /** * @hide * Security key management scheme: OWE in transition mode. */ @SystemApi public static final int KEY_MGMT_OWE_TRANSITION = 12; /** * @hide * Security key management scheme: WAPI_PSK. */ @SystemApi public static final int KEY_MGMT_WAPI_PSK = 13; /** * @hide * Security key management scheme: WAPI_CERT. */ @SystemApi public static final int KEY_MGMT_WAPI_CERT = 14; /** * @hide * Security key management scheme: FILS_SHA256. */ public static final int KEY_MGMT_FILS_SHA256 = 15; /** * @hide * Security key management scheme: FILS_SHA384. */ public static final int KEY_MGMT_FILS_SHA384 = 16; /** * @hide * Security key management scheme: any unknown AKM. */ public static final int KEY_MGMT_UNKNOWN = 17; /** * @hide * No cipher suite. */ @SystemApi public static final int CIPHER_NONE = 0; /** * @hide * No group addressed, only used for group data cipher. */ @SystemApi public static final int CIPHER_NO_GROUP_ADDRESSED = 1; /** * @hide * Cipher suite: TKIP */ @SystemApi public static final int CIPHER_TKIP = 2; /** * @hide * Cipher suite: CCMP */ @SystemApi public static final int CIPHER_CCMP = 3; /** * @hide * Cipher suite: GCMP */ @SystemApi public static final int CIPHER_GCMP_256 = 4; /** * @hide * Cipher suite: SMS4 */ @SystemApi public static final int CIPHER_SMS4 = 5; /** * @hide * Cipher suite: GCMP_128 */ @SystemApi public static final int CIPHER_GCMP_128 = 6; /** * @hide * Cipher suite: BIP_GMAC_128 */ @SystemApi public static final int CIPHER_BIP_GMAC_128 = 7; /** * @hide * Cipher suite: BIP_GMAC_256 */ @SystemApi public static final int CIPHER_BIP_GMAC_256 = 8; /** * @hide * Cipher suite: BIP_CMAC_256 */ @SystemApi public static final int CIPHER_BIP_CMAC_256 = 9; /** * The detected signal level in dBm, also known as the RSSI. * *
Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into
* an absolute signal level which can be displayed to a user.
*/
public int level;
/**
* The primary 20 MHz frequency (in MHz) of the channel over which the client is communicating
* with the access point.
*/
public int frequency;
/**
* AP Channel bandwidth is 20 MHZ
*/
public static final int CHANNEL_WIDTH_20MHZ = 0;
/**
* AP Channel bandwidth is 40 MHZ
*/
public static final int CHANNEL_WIDTH_40MHZ = 1;
/**
* AP Channel bandwidth is 80 MHZ
*/
public static final int CHANNEL_WIDTH_80MHZ = 2;
/**
* AP Channel bandwidth is 160 MHZ
*/
public static final int CHANNEL_WIDTH_160MHZ = 3;
/**
* AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ
*/
public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4;
/**
* Wi-Fi unknown standard
*/
public static final int WIFI_STANDARD_UNKNOWN = 0;
/**
* Wi-Fi 802.11a/b/g
*/
public static final int WIFI_STANDARD_LEGACY = 1;
/**
* Wi-Fi 802.11n
*/
public static final int WIFI_STANDARD_11N = 4;
/**
* Wi-Fi 802.11ac
*/
public static final int WIFI_STANDARD_11AC = 5;
/**
* Wi-Fi 802.11ax
*/
public static final int WIFI_STANDARD_11AX = 6;
/**
* Wi-Fi 802.11ad
*/
public static final int WIFI_STANDARD_11AD = 7;
/**
* Wi-Fi 2.4 GHz band.
*/
public static final int WIFI_BAND_24_GHZ = WifiScanner.WIFI_BAND_24_GHZ;
/**
* Wi-Fi 5 GHz band.
*/
public static final int WIFI_BAND_5_GHZ = WifiScanner.WIFI_BAND_5_GHZ;
/**
* Wi-Fi 6 GHz band.
*/
public static final int WIFI_BAND_6_GHZ = WifiScanner.WIFI_BAND_6_GHZ;
/**
* Wi-Fi 60 GHz band.
*/
public static final int WIFI_BAND_60_GHZ = WifiScanner.WIFI_BAND_60_GHZ;
/**
* @hide
*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"WIFI_BAND_"}, value = {
UNSPECIFIED,
WIFI_BAND_24_GHZ,
WIFI_BAND_5_GHZ,
WIFI_BAND_6_GHZ,
WIFI_BAND_60_GHZ})
public @interface WifiBand {};
/**
* AP wifi standard.
*/
private @WifiStandard int mWifiStandard;
/**
* return the AP wifi standard.
*/
public @WifiStandard int getWifiStandard() {
return mWifiStandard;
}
/**
* sets the AP wifi standard.
* @hide
*/
public void setWifiStandard(@WifiStandard int standard) {
mWifiStandard = standard;
}
/**
* Convert Wi-Fi standard to string
*/
private static @Nullable String wifiStandardToString(@WifiStandard int standard) {
switch(standard) {
case WIFI_STANDARD_LEGACY:
return "legacy";
case WIFI_STANDARD_11N:
return "11n";
case WIFI_STANDARD_11AC:
return "11ac";
case WIFI_STANDARD_11AX:
return "11ax";
case WIFI_STANDARD_11AD:
return "11ad";
case WIFI_STANDARD_UNKNOWN:
return "unknown";
}
return null;
}
/**
* AP Channel bandwidth; one of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ},
* {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ}
* or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}.
*/
public @ChannelWidth int channelWidth;
/**
* Not used if the AP bandwidth is 20 MHz
* If the AP use 40, 80 or 160 MHz, this is the center frequency (in MHz)
* if the AP use 80 + 80 MHz, this is the center frequency of the first segment (in MHz)
*/
public int centerFreq0;
/**
* Only used if the AP bandwidth is 80 + 80 MHz
* if the AP use 80 + 80 MHz, this is the center frequency of the second segment (in MHz)
*/
public int centerFreq1;
/**
* @deprecated use is80211mcResponder() instead
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public boolean is80211McRTTResponder;
/**
* timestamp in microseconds (since boot) when
* this result was last seen.
*/
public long timestamp;
/**
* Timestamp representing date when this result was last seen, in milliseconds from 1970
* {@hide}
*/
@UnsupportedAppUsage
public long seen;
/**
* On devices with multiple hardware radio chains, this class provides metadata about
* each radio chain that was used to receive this scan result (probe response or beacon).
* {@hide}
*/
public static class RadioChainInfo {
/** Vendor defined id for a radio chain. */
public int id;
/** Detected signal level in dBm (also known as the RSSI) on this radio chain. */
public int level;
@Override
public String toString() {
return "RadioChainInfo: id=" + id + ", level=" + level;
}
@Override
public boolean equals(Object otherObj) {
if (this == otherObj) {
return true;
}
if (!(otherObj instanceof RadioChainInfo)) {
return false;
}
RadioChainInfo other = (RadioChainInfo) otherObj;
return id == other.id && level == other.level;
}
@Override
public int hashCode() {
return Objects.hash(id, level);
}
};
/**
* Information about the list of the radio chains used to receive this scan result
* (probe response or beacon).
*
* For Example: On devices with 2 hardware radio chains, this list could hold 1 or 2
* entries based on whether this scan result was received using one or both the chains.
* {@hide}
*/
public RadioChainInfo[] radioChainInfos;
/**
* Status indicating the scan result does not correspond to a user's saved configuration
* @hide
* @removed
*/
@SystemApi
public boolean untrusted;
/**
* Number of time autojoin used it
* @hide
*/
@UnsupportedAppUsage
public int numUsage;
/**
* The approximate distance to the AP in centimeter, if available. Else
* {@link #UNSPECIFIED}.
* {@hide}
*/
@UnsupportedAppUsage
public int distanceCm;
/**
* The standard deviation of the distance to the access point, if available.
* Else {@link #UNSPECIFIED}.
* {@hide}
*/
@UnsupportedAppUsage
public int distanceSdCm;
/** {@hide} */
public static final long FLAG_PASSPOINT_NETWORK = 0x0000000000000001;
/** {@hide} */
public static final long FLAG_80211mc_RESPONDER = 0x0000000000000002;
/*
* These flags are specific to the ScanResult class, and are not related to the |flags|
* field of the per-BSS scan results from WPA supplicant.
*/
/**
* Defines flags; such as {@link #FLAG_PASSPOINT_NETWORK}.
* {@hide}
*/
@UnsupportedAppUsage
public long flags;
/**
* sets a flag in {@link #flags} field
* @param flag flag to set
* @hide
*/
public void setFlag(long flag) {
flags |= flag;
}
/**
* clears a flag in {@link #flags} field
* @param flag flag to set
* @hide
*/
public void clearFlag(long flag) {
flags &= ~flag;
}
public boolean is80211mcResponder() {
return (flags & FLAG_80211mc_RESPONDER) != 0;
}
public boolean isPasspointNetwork() {
return (flags & FLAG_PASSPOINT_NETWORK) != 0;
}
/**
* Indicates venue name (such as 'San Francisco Airport') published by access point; only
* available on Passpoint network and if published by access point.
* @deprecated - This information is not provided
*/
@Deprecated
public CharSequence venueName;
/**
* Indicates Passpoint operator name published by access point.
* @deprecated - Use {@link WifiInfo#getPasspointProviderFriendlyName()}
*/
@Deprecated
public CharSequence operatorFriendlyName;
/**
* The unspecified value.
*/
public final static int UNSPECIFIED = -1;
/**
* 2.4 GHz band first channel number
* @hide
*/
public static final int BAND_24_GHZ_FIRST_CH_NUM = 1;
/**
* 2.4 GHz band last channel number
* @hide
*/
public static final int BAND_24_GHZ_LAST_CH_NUM = 14;
/**
* 2.4 GHz band frequency of first channel in MHz
* @hide
*/
public static final int BAND_24_GHZ_START_FREQ_MHZ = 2412;
/**
* 2.4 GHz band frequency of last channel in MHz
* @hide
*/
public static final int BAND_24_GHZ_END_FREQ_MHZ = 2484;
/**
* 5 GHz band first channel number
* @hide
*/
public static final int BAND_5_GHZ_FIRST_CH_NUM = 32;
/**
* 5 GHz band last channel number
* @hide
*/
public static final int BAND_5_GHZ_LAST_CH_NUM = 177;
/**
* 5 GHz band frequency of first channel in MHz
* @hide
*/
public static final int BAND_5_GHZ_START_FREQ_MHZ = 5160;
/**
* 5 GHz band frequency of last channel in MHz
* @hide
*/
public static final int BAND_5_GHZ_END_FREQ_MHZ = 5885;
/**
* 6 GHz band first channel number
* @hide
*/
public static final int BAND_6_GHZ_FIRST_CH_NUM = 1;
/**
* 6 GHz band last channel number
* @hide
*/
public static final int BAND_6_GHZ_LAST_CH_NUM = 233;
/**
* 6 GHz band frequency of first channel in MHz
* @hide
*/
public static final int BAND_6_GHZ_START_FREQ_MHZ = 5955;
/**
* 6 GHz band frequency of last channel in MHz
* @hide
*/
public static final int BAND_6_GHZ_END_FREQ_MHZ = 7115;
/**
* The center frequency of the first 6Ghz preferred scanning channel, as defined by
* IEEE802.11ax draft 7.0 section 26.17.2.3.3.
* @hide
*/
public static final int BAND_6_GHZ_PSC_START_MHZ = 5975;
/**
* The number of MHz to increment in order to get the next 6Ghz preferred scanning channel
* as defined by IEEE802.11ax draft 7.0 section 26.17.2.3.3.
* @hide
*/
public static final int BAND_6_GHZ_PSC_STEP_SIZE_MHZ = 80;
/**
* 6 GHz band operating class 136 channel 2 center frequency in MHz
* @hide
*/
public static final int BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ = 5935;
/**
* 60 GHz band first channel number
* @hide
*/
public static final int BAND_60_GHZ_FIRST_CH_NUM = 1;
/**
* 60 GHz band last channel number
* @hide
*/
public static final int BAND_60_GHZ_LAST_CH_NUM = 6;
/**
* 60 GHz band frequency of first channel in MHz
* @hide
*/
public static final int BAND_60_GHZ_START_FREQ_MHZ = 58320;
/**
* 60 GHz band frequency of last channel in MHz
* @hide
*/
public static final int BAND_60_GHZ_END_FREQ_MHZ = 70200;
/**
* Utility function to check if a frequency within 2.4 GHz band
* @param freqMhz frequency in MHz
* @return true if within 2.4GHz, false otherwise
*
* @hide
*/
public static boolean is24GHz(int freqMhz) {
return freqMhz >= BAND_24_GHZ_START_FREQ_MHZ && freqMhz <= BAND_24_GHZ_END_FREQ_MHZ;
}
/**
* Utility function to check if a frequency within 5 GHz band
* @param freqMhz frequency in MHz
* @return true if within 5GHz, false otherwise
*
* @hide
*/
public static boolean is5GHz(int freqMhz) {
return freqMhz >= BAND_5_GHZ_START_FREQ_MHZ && freqMhz <= BAND_5_GHZ_END_FREQ_MHZ;
}
/**
* Utility function to check if a frequency within 6 GHz band
* @param freqMhz
* @return true if within 6GHz, false otherwise
*
* @hide
*/
public static boolean is6GHz(int freqMhz) {
if (freqMhz == BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ) {
return true;
}
return (freqMhz >= BAND_6_GHZ_START_FREQ_MHZ && freqMhz <= BAND_6_GHZ_END_FREQ_MHZ);
}
/**
* Utility function to check if a frequency is 6Ghz PSC channel.
* @param freqMhz
* @return true if the frequency is 6GHz PSC, false otherwise
*
* @hide
*/
public static boolean is6GHzPsc(int freqMhz) {
if (!ScanResult.is6GHz(freqMhz)) {
return false;
}
return (freqMhz - BAND_6_GHZ_PSC_START_MHZ) % BAND_6_GHZ_PSC_STEP_SIZE_MHZ == 0;
}
/**
* Utility function to check if a frequency within 60 GHz band
* @param freqMhz
* @return true if within 60GHz, false otherwise
*
* @hide
*/
public static boolean is60GHz(int freqMhz) {
return freqMhz >= BAND_60_GHZ_START_FREQ_MHZ && freqMhz <= BAND_60_GHZ_END_FREQ_MHZ;
}
/**
* Utility function to convert Wi-Fi channel number to frequency in MHz.
*
* Reference the Wi-Fi channel numbering and the channelization in IEEE 802.11-2016
* specifications, section 17.3.8.4.2, 17.3.8.4.3 and Table 15-6.
*
* See also {@link #convertFrequencyMhzToChannelIfSupported(int)}.
*
* @param channel number to convert.
* @param band of channel to convert. One of the following bands:
* {@link #WIFI_BAND_24_GHZ}, {@link #WIFI_BAND_5_GHZ},
* {@link #WIFI_BAND_6_GHZ}, {@link #WIFI_BAND_60_GHZ}.
* @return center frequency in Mhz of the channel, {@link #UNSPECIFIED} if no match
*/
public static int convertChannelToFrequencyMhzIfSupported(int channel, @WifiBand int band) {
if (band == WIFI_BAND_24_GHZ) {
// Special case
if (channel == 14) {
return 2484;
} else if (channel >= BAND_24_GHZ_FIRST_CH_NUM && channel <= BAND_24_GHZ_LAST_CH_NUM) {
return ((channel - BAND_24_GHZ_FIRST_CH_NUM) * 5) + BAND_24_GHZ_START_FREQ_MHZ;
} else {
return UNSPECIFIED;
}
}
if (band == WIFI_BAND_5_GHZ) {
if (channel >= BAND_5_GHZ_FIRST_CH_NUM && channel <= BAND_5_GHZ_LAST_CH_NUM) {
return ((channel - BAND_5_GHZ_FIRST_CH_NUM) * 5) + BAND_5_GHZ_START_FREQ_MHZ;
} else {
return UNSPECIFIED;
}
}
if (band == WIFI_BAND_6_GHZ) {
if (channel >= BAND_6_GHZ_FIRST_CH_NUM && channel <= BAND_6_GHZ_LAST_CH_NUM) {
if (channel == 2) {
return BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ;
}
return ((channel - BAND_6_GHZ_FIRST_CH_NUM) * 5) + BAND_6_GHZ_START_FREQ_MHZ;
} else {
return UNSPECIFIED;
}
}
if (band == WIFI_BAND_60_GHZ) {
if (channel >= BAND_60_GHZ_FIRST_CH_NUM && channel <= BAND_60_GHZ_LAST_CH_NUM) {
return ((channel - BAND_60_GHZ_FIRST_CH_NUM) * 2160) + BAND_60_GHZ_START_FREQ_MHZ;
} else {
return UNSPECIFIED;
}
}
return UNSPECIFIED;
}
/**
* Utility function to convert frequency in MHz to channel number.
*
* See also {@link #convertChannelToFrequencyMhzIfSupported(int, int)}.
*
* @param freqMhz frequency in MHz
* @return channel number associated with given frequency, {@link #UNSPECIFIED} if no match
*/
public static int convertFrequencyMhzToChannelIfSupported(int freqMhz) {
// Special case
if (freqMhz == 2484) {
return 14;
} else if (is24GHz(freqMhz)) {
return (freqMhz - BAND_24_GHZ_START_FREQ_MHZ) / 5 + BAND_24_GHZ_FIRST_CH_NUM;
} else if (is5GHz(freqMhz)) {
return ((freqMhz - BAND_5_GHZ_START_FREQ_MHZ) / 5) + BAND_5_GHZ_FIRST_CH_NUM;
} else if (is6GHz(freqMhz)) {
if (freqMhz == BAND_6_GHZ_OP_CLASS_136_CH_2_FREQ_MHZ) {
return 2;
}
return ((freqMhz - BAND_6_GHZ_START_FREQ_MHZ) / 5) + BAND_6_GHZ_FIRST_CH_NUM;
} else if (is60GHz(freqMhz)) {
return ((freqMhz - BAND_60_GHZ_START_FREQ_MHZ) / 2160) + BAND_60_GHZ_FIRST_CH_NUM;
}
return UNSPECIFIED;
}
/**
* @hide
*/
public boolean is24GHz() {
return ScanResult.is24GHz(frequency);
}
/**
* @hide
*/
public boolean is5GHz() {
return ScanResult.is5GHz(frequency);
}
/**
* @hide
*/
public boolean is6GHz() {
return ScanResult.is6GHz(frequency);
}
/**
* @hide
*/
public boolean is6GhzPsc() {
return ScanResult.is6GHzPsc(frequency);
}
/**
* @hide
*/
public boolean is60GHz() {
return ScanResult.is60GHz(frequency);
}
/**
* @hide
* anqp lines from supplicant BSS response
*/
@UnsupportedAppUsage
public List