/*
 * 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.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.Parcel;
import android.os.Parcelable;

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;

    /**
     * @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
     * 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;

    /**
     * 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 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;

    /**
     * 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_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
    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.
     */
    public CharSequence venueName;

    /**
     * Indicates Passpoint operator name published by access point.
     */
    public CharSequence operatorFriendlyName;

    /**
     * {@hide}
     */
    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 = 173;
    /**
     * 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 = 5865;

    /**
     * 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;

    /**
     * 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;

    /**
     * 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 convert channel number/band to frequency in MHz
     * @param channel number to convert
     * @param band of channel to convert
     * @return center frequency in Mhz of the channel, {@link UNSPECIFIED} if no match
     *
     * @hide
     */
    public static int convertChannelToFrequencyMhz(int channel, @WifiScanner.WifiBand int band) {
        if (band == WifiScanner.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 == WifiScanner.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 == WifiScanner.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;
            }
        }
        return UNSPECIFIED;
    }

    /**
     * Utility function to convert frequency in MHz to channel number
     * @param freqMhz frequency in MHz
     * @return channel number associated with given frequency, {@link UNSPECIFIED} if no match
     *
     * @hide
     */
    public static int convertFrequencyMhzToChannel(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;
        }

        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
     * anqp lines from supplicant BSS response
     */
    @UnsupportedAppUsage
    public List<String> anqpLines;

    /**
     * information elements from beacon.
     */
    public static class InformationElement {
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_SSID = 0;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_SUPPORTED_RATES = 1;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_TIM = 5;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_BSS_LOAD = 11;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_ERP = 42;
        /** @hide */
        public static final int EID_HT_CAPABILITIES = 45;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_RSN = 48;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_EXTENDED_SUPPORTED_RATES = 50;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_HT_OPERATION = 61;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_INTERWORKING = 107;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_ROAMING_CONSORTIUM = 111;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_EXTENDED_CAPS = 127;
        /** @hide */
        public static final int EID_VHT_CAPABILITIES = 191;
        /** @hide */
        @UnsupportedAppUsage
        public static final int EID_VHT_OPERATION = 192;
        /** @hide */
        @UnsupportedAppUsage
        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;

        /** @hide */
        @UnsupportedAppUsage
        public int id;
        /** @hide */
        public int idExt;

        /** @hide */
        @UnsupportedAppUsage
        public byte[] bytes;

        /** @hide */
        public InformationElement() {
        }

        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();
        }
    }

    /**
     * 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));
    }

    /** ANQP response elements.
     * @hide
     */
    public AnqpInformationElement[] anqpElements;

    /** {@hide} */
    public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId,
            byte[] osuProviders, String caps, int level, int frequency, long tsf) {
        this.wifiSsid = wifiSsid;
        this.SSID = (wifiSsid != null) ? wifiSsid.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.mWifiStandard = WIFI_STANDARD_UNKNOWN;
    }

    /** {@hide} */
    public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
            long tsf, int distCm, int distSdCm) {
        this.wifiSsid = wifiSsid;
        this.SSID = (wifiSsid != null) ? wifiSsid.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.mWifiStandard = WIFI_STANDARD_UNKNOWN;
    }

    /** {@hide} */
    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.mWifiStandard = WIFI_STANDARD_UNKNOWN;
    }

    /** {@hide} */
    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;
        }
    }

    /** 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(", Radio Chain Infos: ").append(Arrays.toString(radioChainInfos));
        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) {
        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);

        if (informationElements != null) {
            dest.writeInt(informationElements.length);
            for (int i = 0; i < informationElements.length; i++) {
                dest.writeInt(informationElements[i].id);
                dest.writeInt(informationElements[i].idExt);
                dest.writeInt(informationElements[i].bytes.length);
                dest.writeByteArray(informationElements[i].bytes);
            }
        } else {
            dest.writeInt(0);
        }

        if (anqpLines != null) {
            dest.writeInt(anqpLines.size());
            for (int i = 0; i < anqpLines.size(); i++) {
                dest.writeString(anqpLines.get(i));
            }
        }
        else {
            dest.writeInt(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());
            }
        } 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);
        }
    }

    /** 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();
                int n = in.readInt();
                if (n != 0) {
                    sr.informationElements = new InformationElement[n];
                    for (int i = 0; i < n; i++) {
                        sr.informationElements[i] = new InformationElement();
                        sr.informationElements[i].id = in.readInt();
                        sr.informationElements[i].idExt = in.readInt();
                        int len = in.readInt();
                        sr.informationElements[i].bytes = new byte[len];
                        in.readByteArray(sr.informationElements[i].bytes);
                    }
                }

                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();
                    }
                }
                return sr;
            }

            public ScanResult[] newArray(int size) {
                return new ScanResult[size];
            }
        };
}
