2028 lines
64 KiB
Java
2028 lines
64 KiB
Java
![]() |
/*
|
||
|
* 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.FlaggedApi;
|
||
|
import android.annotation.IntDef;
|
||
|
import android.annotation.IntRange;
|
||
|
import android.annotation.NonNull;
|
||
|
import android.annotation.Nullable;
|
||
|
import android.annotation.SystemApi;
|
||
|
import android.compat.annotation.UnsupportedAppUsage;
|
||
|
import android.net.MacAddress;
|
||
|
import android.net.wifi.WifiAnnotations.ChannelWidth;
|
||
|
import android.net.wifi.WifiAnnotations.WifiStandard;
|
||
|
import android.net.wifi.util.ScanResultUtil;
|
||
|
import android.os.Build;
|
||
|
import android.os.Parcel;
|
||
|
import android.os.Parcelable;
|
||
|
import android.util.Log;
|
||
|
|
||
|
import com.android.modules.utils.build.SdkLevel;
|
||
|
import com.android.wifi.flags.Flags;
|
||
|
|
||
|
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 {
|
||
|
|
||
|
private static final String TAG = "ScanResult";
|
||
|
/**
|
||
|
* The network name.
|
||
|
*
|
||
|
* @deprecated Use {@link #getWifiSsid()} instead.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
public String SSID;
|
||
|
|
||
|
/**
|
||
|
* Ascii encoded SSID. This will replace SSID when we deprecate it. @hide
|
||
|
*
|
||
|
* @deprecated Use {@link #getWifiSsid()} instead.
|
||
|
*/
|
||
|
@Deprecated
|
||
|
// TODO(b/231433398): add maxTargetSdk = Build.VERSION_CODES.S
|
||
|
@UnsupportedAppUsage(publicAlternatives = "{@link #getWifiSsid()}")
|
||
|
public WifiSsid wifiSsid;
|
||
|
|
||
|
/**
|
||
|
* Set the SSID of the access point.
|
||
|
* @hide
|
||
|
*/
|
||
|
@SystemApi
|
||
|
public void setWifiSsid(@NonNull WifiSsid ssid) {
|
||
|
wifiSsid = ssid;
|
||
|
CharSequence utf8Text = wifiSsid.getUtf8Text();
|
||
|
SSID = utf8Text != null ? utf8Text.toString() : WifiManager.UNKNOWN_SSID;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The SSID of the access point.
|
||
|
*/
|
||
|
@Nullable
|
||
|
public WifiSsid getWifiSsid() {
|
||
|
return wifiSsid;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The address of the access point.
|
||
|
*/
|
||
|
public String BSSID;
|
||
|
|
||
|
/**
|
||
|
* The Multi-Link Device (MLD) address of the access point.
|
||
|
* Only applicable for Wi-Fi 7 access points, null otherwise.
|
||
|
*/
|
||
|
private MacAddress mApMldMacAddress;
|
||
|
|
||
|
/**
|
||
|
* Return the access point Multi-Link Device (MLD) MAC Address for Wi-Fi 7 access points.
|
||
|
* i.e. {@link #getWifiStandard()} returns {@link #WIFI_STANDARD_11BE}.
|
||
|
*
|
||
|
* @return MLD MAC Address for access point if exists (Wi-Fi 7 access points), null otherwise.
|
||
|
*/
|
||
|
@Nullable
|
||
|
public MacAddress getApMldMacAddress() {
|
||
|
return mApMldMacAddress;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the access point Multi-Link Device (MLD) MAC Address.
|
||
|
* @hide
|
||
|
*/
|
||
|
public void setApMldMacAddress(@Nullable MacAddress address) {
|
||
|
mApMldMacAddress = address;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The Multi-Link Operation (MLO) link id for the access point.
|
||
|
* Only applicable for Wi-Fi 7 access points.
|
||
|
*/
|
||
|
private int mApMloLinkId = MloLink.INVALID_MLO_LINK_ID;
|
||
|
|
||
|
/**
|
||
|
* Return the access point Multi-Link Operation (MLO) link-id for Wi-Fi 7 access points.
|
||
|
* i.e. when {@link #getWifiStandard()} returns {@link #WIFI_STANDARD_11BE}, otherwise return
|
||
|
* {@link MloLink#INVALID_MLO_LINK_ID}.
|
||
|
*
|
||
|
* Valid values are 0-15 as described in IEEE 802.11be Specification, section 9.4.2.295b.2.
|
||
|
*
|
||
|
* @return {@link MloLink#INVALID_MLO_LINK_ID} or a valid value (0-15).
|
||
|
*/
|
||
|
@IntRange(from = MloLink.INVALID_MLO_LINK_ID, to = MloLink.MAX_MLO_LINK_ID)
|
||
|
public int getApMloLinkId() {
|
||
|
return mApMloLinkId;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the access point Multi-Link Operation (MLO) link-id
|
||
|
* @hide
|
||
|
*/
|
||
|
public void setApMloLinkId(int linkId) {
|
||
|
mApMloLinkId = linkId;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The Multi-Link Operation (MLO) affiliated Links.
|
||
|
* Only applicable for Wi-Fi 7 access points.
|
||
|
* Note: the list of links includes the access point for this ScanResult.
|
||
|
*/
|
||
|
private List<MloLink> mAffiliatedMloLinks = Collections.emptyList();
|
||
|
|
||
|
/**
|
||
|
* Return the Multi-Link Operation (MLO) affiliated Links for Wi-Fi 7 access points.
|
||
|
* i.e. when {@link #getWifiStandard()} returns {@link #WIFI_STANDARD_11BE}.
|
||
|
*
|
||
|
* @return List of affiliated MLO links, or an empty list if access point is not Wi-Fi 7
|
||
|
*/
|
||
|
@NonNull
|
||
|
public List<MloLink> getAffiliatedMloLinks() {
|
||
|
return new ArrayList<MloLink>(mAffiliatedMloLinks);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the Multi-Link Operation (MLO) affiliated Links.
|
||
|
* Only applicable for Wi-Fi 7 access points.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public void setAffiliatedMloLinks(@NonNull List<MloLink> links) {
|
||
|
mAffiliatedMloLinks = new ArrayList<MloLink>(links);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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: DPP.
|
||
|
*/
|
||
|
public static final int KEY_MGMT_DPP = 17;
|
||
|
/**
|
||
|
* @hide
|
||
|
* Security key management scheme: SAE_EXT_KEY.
|
||
|
*/
|
||
|
public static final int KEY_MGMT_SAE_EXT_KEY = 18;
|
||
|
/**
|
||
|
* @hide
|
||
|
* Security key management scheme: FT_SAE_EXT_KEY.
|
||
|
*/
|
||
|
public static final int KEY_MGMT_FT_SAE_EXT_KEY = 19;
|
||
|
/**
|
||
|
* @hide
|
||
|
* Security key management scheme: any unknown AKM.
|
||
|
*/
|
||
|
public static final int KEY_MGMT_UNKNOWN = 20;
|
||
|
/**
|
||
|
* @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.
|
||
|
*
|
||
|
* <p>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 center frequency of 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;
|
||
|
/**
|
||
|
* AP Channel bandwidth is 320 MHZ
|
||
|
*/
|
||
|
public static final int CHANNEL_WIDTH_320MHZ = 5;
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
/**
|
||
|
* Preamble type: HE.
|
||
|
*/
|
||
|
public static final int PREAMBLE_HE = 3;
|
||
|
|
||
|
/**
|
||
|
* Preamble type: EHT.
|
||
|
*/
|
||
|
public static final int PREAMBLE_EHT = 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 802.11be
|
||
|
*/
|
||
|
public static final int WIFI_STANDARD_11BE = 8;
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
|
||
|
/**
|
||
|
* Constant used for dual 5GHz multi-internet use-case only. Not to be used for regular scan
|
||
|
* result reporting.
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int WIFI_BAND_5_GHZ_LOW = WifiScanner.WIFI_BAND_5_GHZ_LOW;
|
||
|
|
||
|
/**
|
||
|
* Constant used for dual 5GHz multi-internet use-case only. Not to be used for regular scan
|
||
|
* result reporting.
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int WIFI_BAND_5_GHZ_HIGH = WifiScanner.WIFI_BAND_5_GHZ_HIGH;
|
||
|
|
||
|
/**
|
||
|
* @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 = WIFI_STANDARD_UNKNOWN;
|
||
|
|
||
|
/**
|
||
|
* 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
|
||
|
* @hide
|
||
|
*/
|
||
|
public 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_11BE:
|
||
|
return "11be";
|
||
|
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}, {@link #CHANNEL_WIDTH_320MHZ},
|
||
|
* or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}, or {@link #CHANNEL_WIDTH_320MHZ}
|
||
|
*/
|
||
|
public @ChannelWidth int channelWidth;
|
||
|
|
||
|
/**
|
||
|
* Not used if the AP bandwidth is 20 MHz
|
||
|
* If the AP use 40, 80, 160 or 320MHz, 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;
|
||
|
|
||
|
/** @hide */
|
||
|
public static final long FLAG_80211az_NTB_RESPONDER = 0x0000000000000004;
|
||
|
|
||
|
/** @hide */
|
||
|
public static final long FLAG_TWT_RESPONDER = 0x0000000000000008;
|
||
|
/*
|
||
|
* 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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return whether AP is a IEEE802.11az Non-Trigger based Ranging Responder.
|
||
|
*/
|
||
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
||
|
public boolean is80211azNtbResponder() {
|
||
|
return (flags & FLAG_80211az_NTB_RESPONDER) != 0;
|
||
|
}
|
||
|
|
||
|
public boolean isPasspointNetwork() {
|
||
|
return (flags & FLAG_PASSPOINT_NETWORK) != 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return whether AP is Target Wake Time (TWT) Responder.
|
||
|
*/
|
||
|
@FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API)
|
||
|
public boolean isTwtResponder() {
|
||
|
return (flags & FLAG_TWT_RESPONDER) != 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;
|
||
|
/**
|
||
|
* The highest frequency in 5GHz low
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int BAND_5_GHZ_LOW_HIGHEST_FREQ_MHZ = 5320;
|
||
|
/**
|
||
|
* The lowest frequency in 5GHz high
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int BAND_5_GHZ_HIGH_LOWEST_FREQ_MHZ = 5500;
|
||
|
|
||
|
/**
|
||
|
* 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 check whether 2 frequencies are valid for multi-internet connection
|
||
|
* when dual-5GHz is supported.
|
||
|
*
|
||
|
* The allowed combinations are:
|
||
|
* - 2.4GHz + Any 5GHz
|
||
|
* - 2.4GHz + 6Ghz
|
||
|
* - 5GHz low + 5GHz high
|
||
|
* - 5GHz low + 6GHz
|
||
|
* @hide
|
||
|
*/
|
||
|
public static boolean isValidCombinedBandForDual5GHz(int freqMhz1, int freqMhz2) {
|
||
|
int band1 = toBand(freqMhz1);
|
||
|
int band2 = toBand(freqMhz2);
|
||
|
if (band1 == WIFI_BAND_24_GHZ || band2 == WIFI_BAND_24_GHZ) {
|
||
|
return band1 != band2;
|
||
|
}
|
||
|
|
||
|
// 5GHz Low : b1 36-48 b2 52-64(5320)
|
||
|
// 5GHz High : b3 100(5500)-144 b4 149-165
|
||
|
if ((freqMhz1 <= BAND_5_GHZ_LOW_HIGHEST_FREQ_MHZ
|
||
|
&& freqMhz2 >= BAND_5_GHZ_HIGH_LOWEST_FREQ_MHZ)
|
||
|
|| (freqMhz2 <= BAND_5_GHZ_LOW_HIGHEST_FREQ_MHZ
|
||
|
&& freqMhz1 >= BAND_5_GHZ_HIGH_LOWEST_FREQ_MHZ)) {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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 Operating Class into a band
|
||
|
*
|
||
|
* Use 802.11 Specification Table E-4: Global Operating Classes for decoding
|
||
|
*
|
||
|
* @param opClass operating class
|
||
|
* @param channel number
|
||
|
*
|
||
|
* @return one of {@link WifiScanner.WIFI_BAND_24_GHZ}, {@link WifiScanner.WIFI_BAND_5_GHZ}, or
|
||
|
* {@link WifiScanner.WIFI_BAND_6_GHZ} for a valid opClass, channel pair, otherwise
|
||
|
* {@link WifiScanner.WIFI_BAND_UNSPECIFIED} is returned.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static int getBandFromOpClass(int opClass, int channel) {
|
||
|
if (opClass >= 81 && opClass <= 84) {
|
||
|
if (channel >= BAND_24_GHZ_FIRST_CH_NUM && channel <= BAND_24_GHZ_LAST_CH_NUM) {
|
||
|
return WifiScanner.WIFI_BAND_24_GHZ;
|
||
|
}
|
||
|
} else if (opClass >= 115 && opClass <= 130) {
|
||
|
if (channel >= BAND_5_GHZ_FIRST_CH_NUM && channel <= BAND_5_GHZ_LAST_CH_NUM) {
|
||
|
return WifiScanner.WIFI_BAND_5_GHZ;
|
||
|
}
|
||
|
} else if (opClass >= 131 && opClass <= 137) {
|
||
|
if (channel >= BAND_6_GHZ_FIRST_CH_NUM && channel <= BAND_6_GHZ_LAST_CH_NUM) {
|
||
|
return WifiScanner.WIFI_BAND_6_GHZ;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If none of the above combinations, then return as invalid band
|
||
|
return WifiScanner.WIFI_BAND_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;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the band for the ScanResult according to its frequency.
|
||
|
* @hide
|
||
|
*/
|
||
|
@WifiBand public static int toBand(int frequency) {
|
||
|
if (ScanResult.is24GHz(frequency)) {
|
||
|
return ScanResult.WIFI_BAND_24_GHZ;
|
||
|
} else if (ScanResult.is5GHz(frequency)) {
|
||
|
return ScanResult.WIFI_BAND_5_GHZ;
|
||
|
} else if (ScanResult.is6GHz(frequency)) {
|
||
|
return ScanResult.WIFI_BAND_6_GHZ;
|
||
|
} else if (ScanResult.is60GHz(frequency)) {
|
||
|
return ScanResult.WIFI_BAND_60_GHZ;
|
||
|
}
|
||
|
return ScanResult.UNSPECIFIED;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns the band for the ScanResult according to its frequency.
|
||
|
* @hide
|
||
|
*/
|
||
|
@SystemApi
|
||
|
@WifiBand public int getBand() {
|
||
|
return ScanResult.toBand(this.frequency);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @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<String> anqpLines;
|
||
|
|
||
|
/**
|
||
|
* information elements from beacon.
|
||
|
*/
|
||
|
public static class InformationElement implements Parcelable {
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_SSID = 0;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_SUPPORTED_RATES = 1;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_TIM = 5;
|
||
|
/** @hide */
|
||
|
public static final int EID_COUNTRY = 7;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_BSS_LOAD = 11;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_ERP = 42;
|
||
|
/** @hide */
|
||
|
public static final int EID_HT_CAPABILITIES = 45;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_RSN = 48;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_EXTENDED_SUPPORTED_RATES = 50;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_HT_OPERATION = 61;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_INTERWORKING = 107;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_ROAMING_CONSORTIUM = 111;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_EXTENDED_CAPS = 127;
|
||
|
/** @hide */
|
||
|
public static final int EID_VHT_CAPABILITIES = 191;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_VHT_OPERATION = 192;
|
||
|
/** @hide */
|
||
|
public static final int EID_RNR = 201;
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public static final int EID_VSA = 221;
|
||
|
/** @hide */
|
||
|
public static final int EID_EXTENSION_PRESENT = 255;
|
||
|
|
||
|
// Extension IDs
|
||
|
/** @hide */
|
||
|
public static final int EID_EXT_HE_CAPABILITIES = 35;
|
||
|
/** @hide */
|
||
|
public static final int EID_EXT_HE_OPERATION = 36;
|
||
|
/**
|
||
|
* EHT Operation IE extension id: see IEEE 802.11be Specification section 9.4.2.1
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int EID_EXT_EHT_OPERATION = 106;
|
||
|
/**
|
||
|
* Multi-Link IE extension id: see IEEE 802.11be Specification section 9.4.2.1
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int EID_EXT_MULTI_LINK = 107;
|
||
|
/**
|
||
|
* Multi-Link IE Fragment sub element ID: see IEEE 802.11be Specification section 9.4.2.312
|
||
|
* Multi-Link element.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int EID_FRAGMENT_SUB_ELEMENT_MULTI_LINK = 254;
|
||
|
|
||
|
/**
|
||
|
* EHT Capabilities IE extension id: see IEEE 802.11be Specification section 9.4.2.1
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int EID_EXT_EHT_CAPABILITIES = 108;
|
||
|
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage
|
||
|
public int id;
|
||
|
/** @hide */
|
||
|
public int idExt;
|
||
|
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage
|
||
|
public byte[] bytes;
|
||
|
|
||
|
/** @hide */
|
||
|
public InformationElement() {
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Constructs InformationElements from beacon.
|
||
|
*
|
||
|
* @param id element id
|
||
|
* @param idExt element id extension
|
||
|
* @param bytes the body of the information element, may contain multiple elements
|
||
|
*/
|
||
|
public InformationElement(int id, int idExt, @NonNull byte[] bytes) {
|
||
|
this.id = id;
|
||
|
this.idExt = idExt;
|
||
|
this.bytes = bytes.clone();
|
||
|
}
|
||
|
|
||
|
public InformationElement(@NonNull InformationElement rhs) {
|
||
|
this.id = rhs.id;
|
||
|
this.idExt = rhs.idExt;
|
||
|
this.bytes = rhs.bytes.clone();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The element ID of the information element. Defined in the IEEE 802.11-2016 spec
|
||
|
* Table 9-77.
|
||
|
*/
|
||
|
public int getId() {
|
||
|
return id;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The element ID Extension of the information element. Defined in the IEEE 802.11-2016 spec
|
||
|
* Table 9-77.
|
||
|
*/
|
||
|
public int getIdExt() {
|
||
|
return idExt;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the specific content of the information element.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public ByteBuffer getBytes() {
|
||
|
return ByteBuffer.wrap(bytes).asReadOnlyBuffer();
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface {@hide} */
|
||
|
public int describeContents() {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface {@hide} */
|
||
|
public void writeToParcel(Parcel dest, int flags) {
|
||
|
dest.writeInt(id);
|
||
|
dest.writeInt(idExt);
|
||
|
dest.writeByteArray(bytes);
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface */
|
||
|
public static final @NonNull Creator<InformationElement> CREATOR =
|
||
|
new Creator<InformationElement>() {
|
||
|
public InformationElement createFromParcel(Parcel in) {
|
||
|
InformationElement informationElement = new InformationElement();
|
||
|
informationElement.id = in.readInt();
|
||
|
informationElement.idExt = in.readInt();
|
||
|
informationElement.bytes = in.createByteArray();
|
||
|
return informationElement;
|
||
|
}
|
||
|
|
||
|
public InformationElement[] newArray(int size) {
|
||
|
return new InformationElement[size];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
@Override
|
||
|
public boolean equals(Object that) {
|
||
|
if (this == that) return true;
|
||
|
|
||
|
// Potential API behavior change, so don't change behavior on older devices.
|
||
|
if (!SdkLevel.isAtLeastS()) return false;
|
||
|
|
||
|
if (!(that instanceof InformationElement)) return false;
|
||
|
|
||
|
InformationElement thatIE = (InformationElement) that;
|
||
|
return id == thatIE.id
|
||
|
&& idExt == thatIE.idExt
|
||
|
&& Arrays.equals(bytes, thatIE.bytes);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int hashCode() {
|
||
|
// Potential API behavior change, so don't change behavior on older devices.
|
||
|
if (!SdkLevel.isAtLeastS()) return System.identityHashCode(this);
|
||
|
|
||
|
return Objects.hash(id, idExt, Arrays.hashCode(bytes));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* information elements found in the beacon.
|
||
|
* @hide
|
||
|
*/
|
||
|
@UnsupportedAppUsage
|
||
|
public InformationElement[] informationElements;
|
||
|
/**
|
||
|
* Get all information elements found in the beacon.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public List<InformationElement> getInformationElements() {
|
||
|
return Collections.unmodifiableList(Arrays.asList(informationElements));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get all the security types supported by this ScanResult.
|
||
|
* @return array of {@code WifiInfo#SECURITY_TYPE_*}.
|
||
|
*/
|
||
|
@NonNull
|
||
|
public @WifiAnnotations.SecurityType int[] getSecurityTypes() {
|
||
|
List<SecurityParams> params = ScanResultUtil.generateSecurityParamsListFromScanResult(this);
|
||
|
int[] securityTypes = new int[params.size()];
|
||
|
for (int i = 0; i < securityTypes.length; i++) {
|
||
|
securityTypes[i] = WifiInfo.convertWifiConfigurationSecurityType(
|
||
|
params.get(i).getSecurityType());
|
||
|
}
|
||
|
return securityTypes;
|
||
|
}
|
||
|
|
||
|
/** ANQP response elements.
|
||
|
* @hide
|
||
|
*/
|
||
|
public AnqpInformationElement[] anqpElements;
|
||
|
|
||
|
/**
|
||
|
* Returns whether a WifiSsid represents a "hidden" SSID of all zero values.
|
||
|
*/
|
||
|
private boolean isHiddenSsid(@NonNull WifiSsid wifiSsid) {
|
||
|
for (byte b : wifiSsid.getBytes()) {
|
||
|
if (b != 0) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Builder class used to construct {@link ScanResult} objects.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final class Builder {
|
||
|
private WifiSsid mWifiSsid;
|
||
|
private String mBssid;
|
||
|
private long mHessid = 0;
|
||
|
private int mAnqpDomainId = 0;
|
||
|
private byte[] mOsuProviders = null;
|
||
|
private String mCaps = null;
|
||
|
private int mRssi = UNSPECIFIED;
|
||
|
private int mFrequency = UNSPECIFIED;
|
||
|
private long mTsf = 0;
|
||
|
private int mDistanceCm = UNSPECIFIED;
|
||
|
private int mDistanceSdCm = UNSPECIFIED;
|
||
|
private @ChannelWidth int mChannelWidth = ScanResult.CHANNEL_WIDTH_20MHZ;
|
||
|
private int mCenterFreq0 = UNSPECIFIED;
|
||
|
private int mCenterFreq1 = UNSPECIFIED;
|
||
|
private boolean mIs80211McRTTResponder = false;
|
||
|
private boolean mIs80211azNtbRTTResponder = false;
|
||
|
private boolean mIsTwtResponder = false;
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setHessid(long hessid) {
|
||
|
mHessid = hessid;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setOsuProviders(@Nullable byte[] osuProviders) {
|
||
|
mOsuProviders = osuProviders;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setAnqpDomainId(int anqpDomainId) {
|
||
|
mAnqpDomainId = anqpDomainId;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setCaps(@Nullable String caps) {
|
||
|
mCaps = caps;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setRssi(int rssi) {
|
||
|
mRssi = rssi;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setFrequency(int frequency) {
|
||
|
mFrequency = frequency;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setTsf(long tsf) {
|
||
|
mTsf = tsf;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setDistanceCm(int distanceCm) {
|
||
|
mDistanceCm = distanceCm;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setDistanceSdCm(int distanceSdCm) {
|
||
|
mDistanceSdCm = distanceSdCm;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setChannelWidth(@ChannelWidth int channelWidth) {
|
||
|
mChannelWidth = channelWidth;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setCenterFreq0(int centerFreq0) {
|
||
|
mCenterFreq0 = centerFreq0;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setCenterFreq1(int centerFreq1) {
|
||
|
mCenterFreq1 = centerFreq1;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setIs80211McRTTResponder(boolean is80211McRTTResponder) {
|
||
|
mIs80211McRTTResponder = is80211McRTTResponder;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setIs80211azNtbRTTResponder(boolean is80211azNtbRTTResponder) {
|
||
|
mIs80211azNtbRTTResponder = is80211azNtbRTTResponder;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@NonNull
|
||
|
public Builder setIsTwtResponder(boolean isTwtResponder) {
|
||
|
mIsTwtResponder = isTwtResponder;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
public Builder(WifiSsid wifiSsid, String bssid) {
|
||
|
mWifiSsid = wifiSsid;
|
||
|
mBssid = bssid;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
*
|
||
|
*/
|
||
|
public Builder() {
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
*/
|
||
|
public Builder setWifiSsid(WifiSsid wifiSsid) {
|
||
|
mWifiSsid = wifiSsid;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
*/
|
||
|
public Builder setBssid(String bssid) {
|
||
|
mBssid = bssid;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
*/
|
||
|
public void clear() {
|
||
|
mWifiSsid = null;
|
||
|
mBssid = null;
|
||
|
mHessid = 0;
|
||
|
mAnqpDomainId = 0;
|
||
|
mOsuProviders = null;
|
||
|
mCaps = null;
|
||
|
mRssi = UNSPECIFIED;
|
||
|
mFrequency = UNSPECIFIED;
|
||
|
mTsf = 0;
|
||
|
mDistanceCm = UNSPECIFIED;
|
||
|
mDistanceSdCm = UNSPECIFIED;
|
||
|
mChannelWidth = ScanResult.CHANNEL_WIDTH_20MHZ;
|
||
|
mCenterFreq0 = UNSPECIFIED;
|
||
|
mCenterFreq1 = UNSPECIFIED;
|
||
|
mIs80211McRTTResponder = false;
|
||
|
mIs80211azNtbRTTResponder = false;
|
||
|
mIsTwtResponder = false;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
public ScanResult build() {
|
||
|
return new ScanResult(this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
*/
|
||
|
private ScanResult(Builder builder) {
|
||
|
this.wifiSsid = builder.mWifiSsid;
|
||
|
if (wifiSsid != null && isHiddenSsid(wifiSsid)) {
|
||
|
// Retain the legacy behavior of setting SSID to "" if the SSID is all zero values.
|
||
|
this.SSID = "";
|
||
|
} else {
|
||
|
final CharSequence utf8Ssid = (wifiSsid != null) ? wifiSsid.getUtf8Text() : null;
|
||
|
this.SSID = (utf8Ssid != null) ? utf8Ssid.toString() : WifiManager.UNKNOWN_SSID;
|
||
|
}
|
||
|
this.BSSID = builder.mBssid;
|
||
|
this.hessid = builder.mHessid;
|
||
|
this.anqpDomainId = builder.mAnqpDomainId;
|
||
|
if (builder.mOsuProviders != null) {
|
||
|
this.anqpElements = new AnqpInformationElement[1];
|
||
|
this.anqpElements[0] = new AnqpInformationElement(
|
||
|
AnqpInformationElement.HOTSPOT20_VENDOR_ID,
|
||
|
AnqpInformationElement.HS_OSU_PROVIDERS, builder.mOsuProviders);
|
||
|
}
|
||
|
this.capabilities = builder.mCaps;
|
||
|
this.level = builder.mRssi;
|
||
|
this.frequency = builder.mFrequency;
|
||
|
this.timestamp = builder.mTsf;
|
||
|
this.distanceCm = builder.mDistanceCm;
|
||
|
this.distanceSdCm = builder.mDistanceSdCm;
|
||
|
this.channelWidth = builder.mChannelWidth;
|
||
|
this.centerFreq0 = builder.mCenterFreq0;
|
||
|
this.centerFreq1 = builder.mCenterFreq1;
|
||
|
this.flags = 0;
|
||
|
this.flags |= (builder.mIs80211McRTTResponder) ? FLAG_80211mc_RESPONDER : 0;
|
||
|
this.flags |= (builder.mIs80211azNtbRTTResponder) ? FLAG_80211az_NTB_RESPONDER : 0;
|
||
|
this.flags |= (builder.mIsTwtResponder) ? FLAG_TWT_RESPONDER : 0;
|
||
|
this.radioChainInfos = null;
|
||
|
this.mApMldMacAddress = null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
* @deprecated Use {@link ScanResult.Builder}
|
||
|
*/
|
||
|
public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId,
|
||
|
byte[] osuProviders, String caps, int level, int frequency, long tsf) {
|
||
|
this.wifiSsid = wifiSsid;
|
||
|
if (wifiSsid != null && isHiddenSsid(wifiSsid)) {
|
||
|
// Retain the legacy behavior of setting SSID to "" if the SSID is all zero values.
|
||
|
this.SSID = "";
|
||
|
} else {
|
||
|
final CharSequence utf8Ssid = (wifiSsid != null) ? wifiSsid.getUtf8Text() : null;
|
||
|
this.SSID = (utf8Ssid != null) ? utf8Ssid.toString() : WifiManager.UNKNOWN_SSID;
|
||
|
}
|
||
|
this.BSSID = BSSID;
|
||
|
this.hessid = hessid;
|
||
|
this.anqpDomainId = anqpDomainId;
|
||
|
if (osuProviders != null) {
|
||
|
this.anqpElements = new AnqpInformationElement[1];
|
||
|
this.anqpElements[0] =
|
||
|
new AnqpInformationElement(AnqpInformationElement.HOTSPOT20_VENDOR_ID,
|
||
|
AnqpInformationElement.HS_OSU_PROVIDERS, osuProviders);
|
||
|
}
|
||
|
this.capabilities = caps;
|
||
|
this.level = level;
|
||
|
this.frequency = frequency;
|
||
|
this.timestamp = tsf;
|
||
|
this.distanceCm = UNSPECIFIED;
|
||
|
this.distanceSdCm = UNSPECIFIED;
|
||
|
this.channelWidth = UNSPECIFIED;
|
||
|
this.centerFreq0 = UNSPECIFIED;
|
||
|
this.centerFreq1 = UNSPECIFIED;
|
||
|
this.flags = 0;
|
||
|
this.radioChainInfos = null;
|
||
|
this.mApMldMacAddress = null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
* @deprecated Use {@link ScanResult.Builder}
|
||
|
*/
|
||
|
public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
|
||
|
long tsf, int distCm, int distSdCm) {
|
||
|
this.wifiSsid = wifiSsid;
|
||
|
if (wifiSsid != null && isHiddenSsid(wifiSsid)) {
|
||
|
// Retain the legacy behavior of setting SSID to "" if the SSID is all zero values.
|
||
|
this.SSID = "";
|
||
|
} else {
|
||
|
final CharSequence utf8Ssid = (wifiSsid != null) ? wifiSsid.getUtf8Text() : null;
|
||
|
this.SSID = (utf8Ssid != null) ? utf8Ssid.toString() : WifiManager.UNKNOWN_SSID;
|
||
|
}
|
||
|
this.BSSID = BSSID;
|
||
|
this.capabilities = caps;
|
||
|
this.level = level;
|
||
|
this.frequency = frequency;
|
||
|
this.timestamp = tsf;
|
||
|
this.distanceCm = distCm;
|
||
|
this.distanceSdCm = distSdCm;
|
||
|
this.channelWidth = UNSPECIFIED;
|
||
|
this.centerFreq0 = UNSPECIFIED;
|
||
|
this.centerFreq1 = UNSPECIFIED;
|
||
|
this.flags = 0;
|
||
|
this.radioChainInfos = null;
|
||
|
this.mApMldMacAddress = null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
* @deprecated Use {@link ScanResult.Builder}
|
||
|
*/
|
||
|
public ScanResult(String Ssid, String BSSID, long hessid, int anqpDomainId, String caps,
|
||
|
int level, int frequency,
|
||
|
long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1,
|
||
|
boolean is80211McRTTResponder) {
|
||
|
this.SSID = Ssid;
|
||
|
this.BSSID = BSSID;
|
||
|
this.hessid = hessid;
|
||
|
this.anqpDomainId = anqpDomainId;
|
||
|
this.capabilities = caps;
|
||
|
this.level = level;
|
||
|
this.frequency = frequency;
|
||
|
this.timestamp = tsf;
|
||
|
this.distanceCm = distCm;
|
||
|
this.distanceSdCm = distSdCm;
|
||
|
this.channelWidth = channelWidth;
|
||
|
this.centerFreq0 = centerFreq0;
|
||
|
this.centerFreq1 = centerFreq1;
|
||
|
if (is80211McRTTResponder) {
|
||
|
this.flags = FLAG_80211mc_RESPONDER;
|
||
|
} else {
|
||
|
this.flags = 0;
|
||
|
}
|
||
|
this.radioChainInfos = null;
|
||
|
this.mApMldMacAddress = null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @hide
|
||
|
* @deprecated Use {@link ScanResult.Builder}
|
||
|
*/
|
||
|
public ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, long hessid, int anqpDomainId,
|
||
|
String caps, int level,
|
||
|
int frequency, long tsf, int distCm, int distSdCm, int channelWidth,
|
||
|
int centerFreq0, int centerFreq1, boolean is80211McRTTResponder) {
|
||
|
this(Ssid, BSSID, hessid, anqpDomainId, caps, level, frequency, tsf, distCm,
|
||
|
distSdCm, channelWidth, centerFreq0, centerFreq1, is80211McRTTResponder);
|
||
|
this.wifiSsid = wifiSsid;
|
||
|
}
|
||
|
|
||
|
/** copy constructor */
|
||
|
public ScanResult(@NonNull ScanResult source) {
|
||
|
if (source != null) {
|
||
|
wifiSsid = source.wifiSsid;
|
||
|
SSID = source.SSID;
|
||
|
BSSID = source.BSSID;
|
||
|
hessid = source.hessid;
|
||
|
anqpDomainId = source.anqpDomainId;
|
||
|
informationElements = source.informationElements;
|
||
|
anqpElements = source.anqpElements;
|
||
|
capabilities = source.capabilities;
|
||
|
level = source.level;
|
||
|
frequency = source.frequency;
|
||
|
channelWidth = source.channelWidth;
|
||
|
centerFreq0 = source.centerFreq0;
|
||
|
centerFreq1 = source.centerFreq1;
|
||
|
timestamp = source.timestamp;
|
||
|
distanceCm = source.distanceCm;
|
||
|
distanceSdCm = source.distanceSdCm;
|
||
|
seen = source.seen;
|
||
|
untrusted = source.untrusted;
|
||
|
numUsage = source.numUsage;
|
||
|
venueName = source.venueName;
|
||
|
operatorFriendlyName = source.operatorFriendlyName;
|
||
|
flags = source.flags;
|
||
|
radioChainInfos = source.radioChainInfos;
|
||
|
this.mWifiStandard = source.mWifiStandard;
|
||
|
this.ifaceName = source.ifaceName;
|
||
|
this.mApMldMacAddress = source.mApMldMacAddress;
|
||
|
this.mApMloLinkId = source.mApMloLinkId;
|
||
|
this.mAffiliatedMloLinks = source.mAffiliatedMloLinks != null
|
||
|
? new ArrayList<>(source.mAffiliatedMloLinks) : Collections.emptyList();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Construct an empty scan result. */
|
||
|
public ScanResult() {
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String toString() {
|
||
|
StringBuffer sb = new StringBuffer();
|
||
|
String none = "<none>";
|
||
|
|
||
|
sb.append("SSID: ")
|
||
|
.append(wifiSsid == null ? WifiManager.UNKNOWN_SSID : wifiSsid)
|
||
|
.append(", BSSID: ")
|
||
|
.append(BSSID == null ? none : BSSID)
|
||
|
.append(", capabilities: ")
|
||
|
.append(capabilities == null ? none : capabilities)
|
||
|
.append(", level: ")
|
||
|
.append(level)
|
||
|
.append(", frequency: ")
|
||
|
.append(frequency)
|
||
|
.append(", timestamp: ")
|
||
|
.append(timestamp);
|
||
|
sb.append(", distance: ").append((distanceCm != UNSPECIFIED ? distanceCm : "?")).
|
||
|
append("(cm)");
|
||
|
sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
|
||
|
append("(cm)");
|
||
|
|
||
|
sb.append(", passpoint: ");
|
||
|
sb.append(((flags & FLAG_PASSPOINT_NETWORK) != 0) ? "yes" : "no");
|
||
|
sb.append(", ChannelBandwidth: ").append(channelWidth);
|
||
|
sb.append(", centerFreq0: ").append(centerFreq0);
|
||
|
sb.append(", centerFreq1: ").append(centerFreq1);
|
||
|
sb.append(", standard: ").append(wifiStandardToString(mWifiStandard));
|
||
|
sb.append(", 80211mcResponder: ");
|
||
|
sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported");
|
||
|
sb.append(", 80211azNtbResponder: ");
|
||
|
sb.append(
|
||
|
((flags & FLAG_80211az_NTB_RESPONDER) != 0) ? "is supported" : "is not supported");
|
||
|
sb.append(", TWT Responder: ");
|
||
|
sb.append(((flags & FLAG_TWT_RESPONDER) != 0) ? "yes" : "no");
|
||
|
sb.append(", Radio Chain Infos: ").append(Arrays.toString(radioChainInfos));
|
||
|
sb.append(", interface name: ").append(ifaceName);
|
||
|
|
||
|
if (mApMldMacAddress != null) {
|
||
|
sb.append(", MLO Info: ")
|
||
|
.append(" AP MLD MAC Address: ")
|
||
|
.append(mApMldMacAddress.toString())
|
||
|
.append(", AP MLO Link-Id: ")
|
||
|
.append((mApMloLinkId == MloLink.INVALID_MLO_LINK_ID)
|
||
|
? "Unspecified" : mApMloLinkId)
|
||
|
.append(", AP MLO Affiliated Links: ").append(mAffiliatedMloLinks);
|
||
|
}
|
||
|
|
||
|
return sb.toString();
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface {@hide} */
|
||
|
public int describeContents() {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface {@hide} */
|
||
|
public void writeToParcel(Parcel dest, int flags) {
|
||
|
long start = dest.dataSize();
|
||
|
if (wifiSsid != null) {
|
||
|
dest.writeInt(1);
|
||
|
wifiSsid.writeToParcel(dest, flags);
|
||
|
} else {
|
||
|
dest.writeInt(0);
|
||
|
}
|
||
|
dest.writeString(SSID);
|
||
|
dest.writeString(BSSID);
|
||
|
dest.writeLong(hessid);
|
||
|
dest.writeInt(anqpDomainId);
|
||
|
dest.writeString(capabilities);
|
||
|
dest.writeInt(level);
|
||
|
dest.writeInt(frequency);
|
||
|
dest.writeLong(timestamp);
|
||
|
dest.writeInt(distanceCm);
|
||
|
dest.writeInt(distanceSdCm);
|
||
|
dest.writeInt(channelWidth);
|
||
|
dest.writeInt(centerFreq0);
|
||
|
dest.writeInt(centerFreq1);
|
||
|
dest.writeInt(mWifiStandard);
|
||
|
dest.writeLong(seen);
|
||
|
dest.writeInt(untrusted ? 1 : 0);
|
||
|
dest.writeInt(numUsage);
|
||
|
dest.writeString((venueName != null) ? venueName.toString() : "");
|
||
|
dest.writeString((operatorFriendlyName != null) ? operatorFriendlyName.toString() : "");
|
||
|
dest.writeLong(this.flags);
|
||
|
dest.writeTypedArray(informationElements, flags);
|
||
|
|
||
|
if (anqpLines != null) {
|
||
|
dest.writeInt(anqpLines.size());
|
||
|
for (int i = 0; i < anqpLines.size(); i++) {
|
||
|
dest.writeString(anqpLines.get(i));
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
dest.writeInt(0);
|
||
|
}
|
||
|
int anqpElementsPayloadSize = 0;
|
||
|
if (anqpElements != null) {
|
||
|
dest.writeInt(anqpElements.length);
|
||
|
for (AnqpInformationElement element : anqpElements) {
|
||
|
dest.writeInt(element.getVendorId());
|
||
|
dest.writeInt(element.getElementId());
|
||
|
dest.writeInt(element.getPayload().length);
|
||
|
dest.writeByteArray(element.getPayload());
|
||
|
anqpElementsPayloadSize += element.getPayload().length;
|
||
|
}
|
||
|
} else {
|
||
|
dest.writeInt(0);
|
||
|
}
|
||
|
|
||
|
if (radioChainInfos != null) {
|
||
|
dest.writeInt(radioChainInfos.length);
|
||
|
for (int i = 0; i < radioChainInfos.length; i++) {
|
||
|
dest.writeInt(radioChainInfos[i].id);
|
||
|
dest.writeInt(radioChainInfos[i].level);
|
||
|
}
|
||
|
} else {
|
||
|
dest.writeInt(0);
|
||
|
}
|
||
|
dest.writeString((ifaceName != null) ? ifaceName.toString() : "");
|
||
|
|
||
|
|
||
|
// Add MLO related attributes
|
||
|
dest.writeParcelable(mApMldMacAddress, flags);
|
||
|
dest.writeInt(mApMloLinkId);
|
||
|
dest.writeTypedList(mAffiliatedMloLinks);
|
||
|
if (dest.dataSize() - start > 10000) {
|
||
|
Log.e(
|
||
|
TAG,
|
||
|
" Abnormal ScanResult: "
|
||
|
+ this
|
||
|
+ ". The size is "
|
||
|
+ (dest.dataSize() - start)
|
||
|
+ ". The informationElements size is "
|
||
|
+ informationElements.length
|
||
|
+ ". The anqpPayload size is "
|
||
|
+ anqpElementsPayloadSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface */
|
||
|
public static final @NonNull Creator<ScanResult> CREATOR =
|
||
|
new Creator<ScanResult>() {
|
||
|
public ScanResult createFromParcel(Parcel in) {
|
||
|
WifiSsid wifiSsid = null;
|
||
|
if (in.readInt() == 1) {
|
||
|
wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
|
||
|
}
|
||
|
ScanResult sr = new ScanResult(
|
||
|
wifiSsid,
|
||
|
in.readString(), /* SSID */
|
||
|
in.readString(), /* BSSID */
|
||
|
in.readLong(), /* HESSID */
|
||
|
in.readInt(), /* ANQP Domain ID */
|
||
|
in.readString(), /* capabilities */
|
||
|
in.readInt(), /* level */
|
||
|
in.readInt(), /* frequency */
|
||
|
in.readLong(), /* timestamp */
|
||
|
in.readInt(), /* distanceCm */
|
||
|
in.readInt(), /* distanceSdCm */
|
||
|
in.readInt(), /* channelWidth */
|
||
|
in.readInt(), /* centerFreq0 */
|
||
|
in.readInt(), /* centerFreq1 */
|
||
|
false /* rtt responder,
|
||
|
fixed with flags below */
|
||
|
);
|
||
|
|
||
|
sr.mWifiStandard = in.readInt();
|
||
|
sr.seen = in.readLong();
|
||
|
sr.untrusted = in.readInt() != 0;
|
||
|
sr.numUsage = in.readInt();
|
||
|
sr.venueName = in.readString();
|
||
|
sr.operatorFriendlyName = in.readString();
|
||
|
sr.flags = in.readLong();
|
||
|
sr.informationElements = in.createTypedArray(InformationElement.CREATOR);
|
||
|
|
||
|
int n = in.readInt();
|
||
|
if (n != 0) {
|
||
|
sr.anqpLines = new ArrayList<String>();
|
||
|
for (int i = 0; i < n; i++) {
|
||
|
sr.anqpLines.add(in.readString());
|
||
|
}
|
||
|
}
|
||
|
n = in.readInt();
|
||
|
if (n != 0) {
|
||
|
sr.anqpElements = new AnqpInformationElement[n];
|
||
|
for (int i = 0; i < n; i++) {
|
||
|
int vendorId = in.readInt();
|
||
|
int elementId = in.readInt();
|
||
|
int len = in.readInt();
|
||
|
byte[] payload = new byte[len];
|
||
|
in.readByteArray(payload);
|
||
|
sr.anqpElements[i] =
|
||
|
new AnqpInformationElement(vendorId, elementId, payload);
|
||
|
}
|
||
|
}
|
||
|
n = in.readInt();
|
||
|
if (n != 0) {
|
||
|
sr.radioChainInfos = new RadioChainInfo[n];
|
||
|
for (int i = 0; i < n; i++) {
|
||
|
sr.radioChainInfos[i] = new RadioChainInfo();
|
||
|
sr.radioChainInfos[i].id = in.readInt();
|
||
|
sr.radioChainInfos[i].level = in.readInt();
|
||
|
}
|
||
|
}
|
||
|
sr.ifaceName = in.readString();
|
||
|
|
||
|
// Read MLO related attributes
|
||
|
sr.mApMldMacAddress = in.readParcelable(MacAddress.class.getClassLoader());
|
||
|
sr.mApMloLinkId = in.readInt();
|
||
|
sr.mAffiliatedMloLinks = in.createTypedArrayList(MloLink.CREATOR);
|
||
|
|
||
|
return sr;
|
||
|
}
|
||
|
public ScanResult[] newArray(int size) {
|
||
|
return new ScanResult[size];
|
||
|
}
|
||
|
};
|
||
|
}
|