/*
 * 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.SystemApi;
import android.net.IpConfiguration;
import android.net.IpConfiguration.ProxySettings;
import android.net.IpConfiguration.IpAssignment;
import android.net.ProxyInfo;
import android.net.StaticIpConfiguration;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.annotation.SystemApi;

import java.util.HashMap;
import java.util.BitSet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * A class representing a configured Wi-Fi network, including the
 * security configuration.
 */
public class WifiConfiguration implements Parcelable {
    private static final String TAG = "WifiConfiguration";
    /** {@hide} */
    public static final String ssidVarName = "ssid";
    /** {@hide} */
    public static final String bssidVarName = "bssid";
    /** {@hide} */
    public static final String pskVarName = "psk";
    /** {@hide} */
    public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" };
    /** {@hide} */
    public static final String wepTxKeyIdxVarName = "wep_tx_keyidx";
    /** {@hide} */
    public static final String priorityVarName = "priority";
    /** {@hide} */
    public static final String hiddenSSIDVarName = "scan_ssid";
    /** {@hide} */
    public static final String pmfVarName = "ieee80211w";
    /** {@hide} */
    public static final String updateIdentiferVarName = "update_identifier";
    /** {@hide} */
    public static final int INVALID_NETWORK_ID = -1;
    /**
     * Recognized key management schemes.
     */
    public static class KeyMgmt {
        private KeyMgmt() { }

        /** WPA is not used; plaintext or static WEP could be used. */
        public static final int NONE = 0;
        /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */
        public static final int WPA_PSK = 1;
        /** WPA using EAP authentication. Generally used with an external authentication server. */
        public static final int WPA_EAP = 2;
        /** IEEE 802.1X using EAP authentication and (optionally) dynamically
         * generated WEP keys. */
        public static final int IEEE8021X = 3;

        /** WPA2 pre-shared key for use with soft access point
          * (requires {@code preSharedKey} to be specified).
          * @hide
          */
        public static final int WPA2_PSK = 4;

        public static final String varName = "key_mgmt";

        public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X",
                "WPA2_PSK" };
    }

    /**
     * Recognized security protocols.
     */
    public static class Protocol {
        private Protocol() { }

        /** WPA/IEEE 802.11i/D3.0 */
        public static final int WPA = 0;
        /** WPA2/IEEE 802.11i */
        public static final int RSN = 1;

        public static final String varName = "proto";

        public static final String[] strings = { "WPA", "RSN" };
    }

    /**
     * Recognized IEEE 802.11 authentication algorithms.
     */
    public static class AuthAlgorithm {
        private AuthAlgorithm() { }

        /** Open System authentication (required for WPA/WPA2) */
        public static final int OPEN = 0;
        /** Shared Key authentication (requires static WEP keys) */
        public static final int SHARED = 1;
        /** LEAP/Network EAP (only used with LEAP) */
        public static final int LEAP = 2;

        public static final String varName = "auth_alg";

        public static final String[] strings = { "OPEN", "SHARED", "LEAP" };
    }

    /**
     * Recognized pairwise ciphers for WPA.
     */
    public static class PairwiseCipher {
        private PairwiseCipher() { }

        /** Use only Group keys (deprecated) */
        public static final int NONE = 0;
        /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */
        public static final int TKIP = 1;
        /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
        public static final int CCMP = 2;

        public static final String varName = "pairwise";

        public static final String[] strings = { "NONE", "TKIP", "CCMP" };
    }

    /**
     * Recognized group ciphers.
     * <pre>
     * CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0]
     * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
     * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
     * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
     * </pre>
     */
    public static class GroupCipher {
        private GroupCipher() { }

        /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) */
        public static final int WEP40 = 0;
        /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key */
        public static final int WEP104 = 1;
        /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */
        public static final int TKIP = 2;
        /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
        public static final int CCMP = 3;

        public static final String varName = "group";

        public static final String[] strings = { "WEP40", "WEP104", "TKIP", "CCMP" };
    }

    /** Possible status of a network configuration. */
    public static class Status {
        private Status() { }

        /** this is the network we are currently connected to */
        public static final int CURRENT = 0;
        /** supplicant will not attempt to use this network */
        public static final int DISABLED = 1;
        /** supplicant will consider this network available for association */
        public static final int ENABLED = 2;

        public static final String[] strings = { "current", "disabled", "enabled" };
    }

    /** @hide */
    public static final int DISABLED_UNKNOWN_REASON                         = 0;
    /** @hide */
    public static final int DISABLED_DNS_FAILURE                            = 1;
    /** @hide */
    public static final int DISABLED_DHCP_FAILURE                           = 2;
    /** @hide */
    public static final int DISABLED_AUTH_FAILURE                           = 3;
    /** @hide */
    public static final int DISABLED_ASSOCIATION_REJECT                     = 4;
    /** @hide */
    public static final int DISABLED_BY_WIFI_MANAGER                        = 5;

    /**
     * The ID number that the supplicant uses to identify this
     * network configuration entry. This must be passed as an argument
     * to most calls into the supplicant.
     */
    public int networkId;

    /**
     * The current status of this network configuration entry.
     * @see Status
     */
    public int status;

    /**
     * The configuration needs to be written to networkHistory.txt
     * @hide
     */
    public boolean dirty;

    /**
     * The code referring to a reason for disabling the network
     * Valid when {@link #status} == Status.DISABLED
     * @hide
     */
    public int disableReason;

    /**
     * The network's SSID. Can either be an ASCII string,
     * which must be enclosed in double quotation marks
     * (e.g., {@code "MyNetwork"}, or a string of
     * hex digits,which are not enclosed in quotes
     * (e.g., {@code 01a243f405}).
     */
    public String SSID;
    /**
     * When set, this network configuration entry should only be used when
     * associating with the AP having the specified BSSID. The value is
     * a string in the format of an Ethernet MAC address, e.g.,
     * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit.
     */
    public String BSSID;
    /**
     * Fully qualified domain name (FQDN) of AAA server or RADIUS server
     * e.g. {@code "mail.example.com"}.
     */
    public String FQDN;
    /**
     * Network access identifier (NAI) realm, for Passpoint credential.
     * e.g. {@code "myhost.example.com"}.
     * @hide
     */
    public String naiRealm;

    /**
     * Pre-shared key for use with WPA-PSK.
     * <p/>
     * When the value of this key is read, the actual key is
     * not returned, just a "*" if the key has a value, or the null
     * string otherwise.
     */
    public String preSharedKey;
    /**
     * Up to four WEP keys. Either an ASCII string enclosed in double
     * quotation marks (e.g., {@code "abcdef"} or a string
     * of hex digits (e.g., {@code 0102030405}).
     * <p/>
     * When the value of one of these keys is read, the actual key is
     * not returned, just a "*" if the key has a value, or the null
     * string otherwise.
     */
    public String[] wepKeys;

    /** Default WEP key index, ranging from 0 to 3. */
    public int wepTxKeyIndex;

    /**
     * Priority determines the preference given to a network by {@code wpa_supplicant}
     * when choosing an access point with which to associate.
     */
    public int priority;

    /**
     * This is a network that does not broadcast its SSID, so an
     * SSID-specific probe request must be used for scans.
     */
    public boolean hiddenSSID;

    /**
     * This is a network that requries Protected Management Frames (PMF).
     * @hide
     */
    public boolean requirePMF;

    /**
     * Update identifier, for Passpoint network.
     * @hide
     */
    public String updateIdentifier;

    /**
     * The set of key management protocols supported by this configuration.
     * See {@link KeyMgmt} for descriptions of the values.
     * Defaults to WPA-PSK WPA-EAP.
     */
    public BitSet allowedKeyManagement;
    /**
     * The set of security protocols supported by this configuration.
     * See {@link Protocol} for descriptions of the values.
     * Defaults to WPA RSN.
     */
    public BitSet allowedProtocols;
    /**
     * The set of authentication protocols supported by this configuration.
     * See {@link AuthAlgorithm} for descriptions of the values.
     * Defaults to automatic selection.
     */
    public BitSet allowedAuthAlgorithms;
    /**
     * The set of pairwise ciphers for WPA supported by this configuration.
     * See {@link PairwiseCipher} for descriptions of the values.
     * Defaults to CCMP TKIP.
     */
    public BitSet allowedPairwiseCiphers;
    /**
     * The set of group ciphers supported by this configuration.
     * See {@link GroupCipher} for descriptions of the values.
     * Defaults to CCMP TKIP WEP104 WEP40.
     */
    public BitSet allowedGroupCiphers;
    /**
     * The enterprise configuration details specifying the EAP method,
     * certificates and other settings associated with the EAP.
     */
    public WifiEnterpriseConfig enterpriseConfig;

    /**
     * @hide
     */
    private IpConfiguration mIpConfiguration;

    /**
     * @hide
     * dhcp server MAC address if known
     */
    public String dhcpServer;

    /**
     * @hide
     * default Gateway MAC address if known
     */
    public String defaultGwMacAddress;

    /**
     * @hide
     * last failure
     */
    public String lastFailure;

    /**
     * @hide
     * last time we connected, this configuration had no internet access
     */
    public boolean noInternetAccess;

    /**
     * @hide
     * Uid of app creating the configuration
     */
    @SystemApi
    public int creatorUid;

    /**
     * @hide
     * Uid of last app issuing a connection related command
     */
    public int lastConnectUid;

    /**
     * @hide
     * Uid of last app modifying the configuration
     */
    @SystemApi
    public int lastUpdateUid;

    /**
     * @hide
     * Uid used by autoJoin
     */
    public String autoJoinBSSID;

    /**
     * @hide
     * BSSID list on which this configuration was seen.
     * TODO: prevent this list to grow infinitely, age-out the results
     */
    public HashMap<String, ScanResult> scanResultCache;

    /** The Below RSSI thresholds are used to configure AutoJoin
     *  - GOOD/LOW/BAD thresholds are used so as to calculate link score
     *  - UNWANTED_SOFT are used by the blacklisting logic so as to handle
     *  the unwanted network message coming from CS
     *  - UNBLACKLIST thresholds are used so as to tweak the speed at which
     *  the network is unblacklisted (i.e. if
     *          it is seen with good RSSI, it is blacklisted faster)
     *  - INITIAL_AUTOJOIN_ATTEMPT, used to determine how close from
     *  the network we need to be before autojoin kicks in
     */
    /** @hide **/
    public static int INVALID_RSSI = -127;

    /** @hide **/
    public static int UNWANTED_BLACKLIST_SOFT_RSSI_24 = -80;

    /** @hide **/
    public static int UNWANTED_BLACKLIST_SOFT_RSSI_5 = -70;

    /** @hide **/
    public static int GOOD_RSSI_24 = -65;

    /** @hide **/
    public static int LOW_RSSI_24 = -77;

    /** @hide **/
    public static int BAD_RSSI_24 = -87;

    /** @hide **/
    public static int GOOD_RSSI_5 = -60;

    /** @hide **/
    public static int LOW_RSSI_5 = -72;

    /** @hide **/
    public static int BAD_RSSI_5 = -82;

    /** @hide **/
    public static int UNWANTED_BLACKLIST_SOFT_BUMP = 4;

    /** @hide **/
    public static int UNWANTED_BLACKLIST_HARD_BUMP = 8;

    /** @hide **/
    public static int UNBLACKLIST_THRESHOLD_24_SOFT = -77;

    /** @hide **/
    public static int UNBLACKLIST_THRESHOLD_24_HARD = -68;

    /** @hide **/
    public static int UNBLACKLIST_THRESHOLD_5_SOFT = -63;

    /** @hide **/
    public static int UNBLACKLIST_THRESHOLD_5_HARD = -56;

    /** @hide **/
    public static int INITIAL_AUTO_JOIN_ATTEMPT_MIN_24 = -80;

    /** @hide **/
    public static int INITIAL_AUTO_JOIN_ATTEMPT_MIN_5 = -70;

    /** @hide
     * 5GHz band is prefered low over 2.4 if the 5GHz RSSI is higher than this threshold */
    public static int A_BAND_PREFERENCE_RSSI_THRESHOLD = -65;

    /** @hide
     * 5GHz band is penalized if the 5GHz RSSI is lower than this threshold **/
    public static int G_BAND_PREFERENCE_RSSI_THRESHOLD = -75;

    /** @hide
     * Boost given to RSSI on a home network for the purpose of calculating the score
     * This adds stickiness to home networks, as defined by:
     * - less than 4 known BSSIDs
     * - PSK only
     * - TODO: add a test to verify that all BSSIDs are behind same gateway
     ***/
    public static int HOME_NETWORK_RSSI_BOOST = 5;

    /** @hide
     * RSSI boost for configuration which use autoJoinUseAggressiveJoinAttemptThreshold
     * To be more aggressive when initially attempting to auto join
     */
    public static int MAX_INITIAL_AUTO_JOIN_RSSI_BOOST = 8;

    /**
     * @hide
     * A summary of the RSSI and Band status for that configuration
     * This is used as a temporary value by the auto-join controller
     */
    public final class Visibility {
        public int rssi5;   // strongest 5GHz RSSI
        public int rssi24;  // strongest 2.4GHz RSSI
        public int num5;    // number of BSSIDs on 5GHz
        public int num24;   // number of BSSIDs on 2.4GHz
        public long age5;   // timestamp of the strongest 5GHz BSSID (last time it was seen)
        public long age24;  // timestamp of the strongest 2.4GHz BSSID (last time it was seen)
        public String BSSID24;
        public String BSSID5;

        public Visibility() {
            rssi5 = INVALID_RSSI;
            rssi24 = INVALID_RSSI;
        }

        public Visibility(Visibility source) {
            rssi5 = source.rssi5;
            rssi24 = source.rssi24;
            age24 = source.age24;
            age5 = source.age5;
            num24 = source.num24;
            num5 = source.num5;
            BSSID5 = source.BSSID5;
            BSSID24 = source.BSSID24;
        }

        @Override
        public String toString() {
            StringBuilder sbuf = new StringBuilder();
            sbuf.append("[");
            if (rssi24 > INVALID_RSSI) {
                sbuf.append(Integer.toString(rssi24));
                sbuf.append(",");
                sbuf.append(Integer.toString(num24));
                if (BSSID24 != null) sbuf.append(",").append(BSSID24);
            } else {
                sbuf.append("*");
            }
            sbuf.append(" - ");
            if (rssi5 > INVALID_RSSI) {
                sbuf.append(Integer.toString(rssi5));
                sbuf.append(",");
                sbuf.append(Integer.toString(num5));
                if (BSSID5 != null) sbuf.append(",").append(BSSID5);
            }
            sbuf.append("]");
            return sbuf.toString();
        }
    }

    /** @hide
     * Cache the visibility status of this configuration.
     * Visibility can change at any time depending on scan results availability.
     * Owner of the WifiConfiguration is responsible to set this field based on
     * recent scan results.
     ***/
    public Visibility visibility;

    /** @hide
     * calculate and set Visibility for that configuration.
     *
     * age in milliseconds: we will consider only ScanResults that are more recent,
     * i.e. younger.
     ***/
    public Visibility setVisibility(long age) {
        if (scanResultCache == null) {
            visibility = null;
            return null;
        }

        Visibility status = new Visibility();

        long now_ms = System.currentTimeMillis();
        for(ScanResult result : scanResultCache.values()) {
            if (result.seen == 0)
                continue;

            if (result.is5GHz()) {
                //strictly speaking: [4915, 5825]
                //number of known BSSID on 5GHz band
                status.num5 = status.num5 + 1;
            } else if (result.is24GHz()) {
                //strictly speaking: [2412, 2482]
                //number of known BSSID on 2.4Ghz band
                status.num24 = status.num24 + 1;
            }

            if ((now_ms - result.seen) > age) continue;

            if (result.is5GHz()) {
                if (result.level > status.rssi5) {
                    status.rssi5 = result.level;
                    status.age5 = result.seen;
                    status.BSSID5 = result.BSSID;
                }
            } else if (result.is24GHz()) {
                if (result.level > status.rssi24) {
                    status.rssi24 = result.level;
                    status.age24 = result.seen;
                    status.BSSID24 = result.BSSID;
                }
            }
        }
        visibility = status;
        return status;
    }

    /** @hide */
    public static final int AUTO_JOIN_ENABLED                   = 0;
    /**
     * if this is set, the WifiConfiguration cannot use linkages so as to bump
     * it's relative priority.
     * - status between and 128 indicate various level of blacklisting depending
     * on the severity or frequency of the connection error
     * - deleted status indicates that the user is deleting the configuration, and so
     * although it may have been self added we will not re-self-add it, ignore it,
     * not return it to applications, and not connect to it
     * */

    /** @hide
     * network was temporary disabled due to bad connection, most likely due
     * to weak RSSI */
    public static final int AUTO_JOIN_TEMPORARY_DISABLED  = 1;
    /** @hide
     * network was temporary disabled due to bad connection, which cant be attributed
     * to weak RSSI */
    public static final int AUTO_JOIN_TEMPORARY_DISABLED_LINK_ERRORS  = 32;
    /** @hide */
    public static final int AUTO_JOIN_TEMPORARY_DISABLED_AT_SUPPLICANT  = 64;
    /** @hide */
    public static final int AUTO_JOIN_DISABLED_ON_AUTH_FAILURE  = 128;
    /** @hide */
    public static final int AUTO_JOIN_DISABLED_NO_CREDENTIALS = 160;
    /** @hide */
    public static final int AUTO_JOIN_DISABLED_USER_ACTION = 161;

    /** @hide */
    public static final int AUTO_JOIN_DELETED  = 200;

    /**
     * @hide
     */
    public int autoJoinStatus;

    /**
     * @hide
     * Number of connection failures
     */
    public int numConnectionFailures;

    /**
     * @hide
     * Number of IP config failures
     */
    public int numIpConfigFailures;

    /**
     * @hide
     * Number of Auth failures
     */
    public int numAuthFailures;

    /**
     * @hide
     * Last time we blacklisted the configuration
     */
    public long blackListTimestamp;

    /**
     * @hide
     * Last time the system was connected to this configuration.
     */
    public long lastConnected;

    /**
     * @hide
     * Last time the system tried to connect and failed.
     */
    public long lastConnectionFailure;

    /**
     * @hide
     * Last time the system was disconnected to this configuration.
     */
    public long lastDisconnected;

    /**
     * Set if the configuration was self added by the framework
     * This boolean is cleared if we get a connect/save/ update or
     * any wifiManager command that indicate the user interacted with the configuration
     * since we will now consider that the configuration belong to him.
     * @hide
     */
    public boolean selfAdded;

    /**
     * Set if the configuration was self added by the framework
     * This boolean is set once and never cleared. It is used
     * so as we never loose track of who created the
     * configuration in the first place.
     * @hide
     */
    public boolean didSelfAdd;

    /**
     * Peer WifiConfiguration this WifiConfiguration was added for
     * @hide
     */
    public String peerWifiConfiguration;

    /**
     * @hide
     * Indicate that a WifiConfiguration is temporary and should not be saved
     * nor considered by AutoJoin.
     */
    public boolean ephemeral;

    /**
     * @hide
     * Indicate that we didn't auto-join because rssi was too low
     */
    public boolean autoJoinBailedDueToLowRssi;

    /**
     * @hide
     * AutoJoin even though RSSI is 10dB below threshold
     */
    public int autoJoinUseAggressiveJoinAttemptThreshold;

    /**
     * @hide
     * Number of time the scorer overrode a the priority based choice, when comparing two
     * WifiConfigurations, note that since comparing WifiConfiguration happens very often
     * potentially at every scan, this number might become very large, even on an idle
     * system.
     */
    @SystemApi
    public int numScorerOverride;

    /**
     * @hide
     * Number of time the scorer overrode a the priority based choice, and the comparison
     * triggered a network switch
     */
    @SystemApi
    public int numScorerOverrideAndSwitchedNetwork;

    /**
     * @hide
     * Number of time we associated to this configuration.
     */
    @SystemApi
    public int numAssociation;

    /**
     * @hide
     * Number of time user disabled WiFi while associated to this configuration with Low RSSI.
     */
    public int numUserTriggeredWifiDisableLowRSSI;

    /**
     * @hide
     * Number of time user disabled WiFi while associated to this configuration with Bad RSSI.
     */
    public int numUserTriggeredWifiDisableBadRSSI;

    /**
     * @hide
     * Number of time user disabled WiFi while associated to this configuration
     * and RSSI was not HIGH.
     */
    public int numUserTriggeredWifiDisableNotHighRSSI;

    /**
     * @hide
     * Number of ticks associated to this configuration with Low RSSI.
     */
    public int numTicksAtLowRSSI;

    /**
     * @hide
     * Number of ticks associated to this configuration with Bad RSSI.
     */
    public int numTicksAtBadRSSI;

    /**
     * @hide
     * Number of ticks associated to this configuration
     * and RSSI was not HIGH.
     */
    public int numTicksAtNotHighRSSI;
    /**
     * @hide
     * Number of time user (WifiManager) triggered association to this configuration.
     * TODO: count this only for Wifi Settings uuid, so as to not count 3rd party apps
     */
    public int numUserTriggeredJoinAttempts;

    /**
     * @hide
     * Connect choices
     *
     * remember the keys identifying the known WifiConfiguration over which this configuration
     * was preferred by user or a "WiFi Network Management app", that is,
     * a WifiManager.CONNECT_NETWORK or SELECT_NETWORK was received while this configuration
     * was visible to the user:
     * configKey is : "SSID"-WEP-WPA_PSK-WPA_EAP
     *
     * The integer represents the configuration's RSSI at that time (useful?)
     *
     * The overall auto-join algorithm make use of past connect choice so as to sort configuration,
     * the exact algorithm still fluctuating as of 5/7/2014
     *
     */
    public HashMap<String, Integer> connectChoices;

    /**
     * @hide
     * Linked Configurations: represent the set of Wificonfigurations that are equivalent
     * regarding roaming and auto-joining.
     * The linked configuration may or may not have same SSID, and may or may not have same
     * credentials.
     * For instance, linked configurations will have same defaultGwMacAddress or same dhcp server.
     */
    public HashMap<String, Integer>  linkedConfigurations;

    public WifiConfiguration() {
        networkId = INVALID_NETWORK_ID;
        SSID = null;
        BSSID = null;
        FQDN = null;
        naiRealm = null;
        priority = 0;
        hiddenSSID = false;
        disableReason = DISABLED_UNKNOWN_REASON;
        allowedKeyManagement = new BitSet();
        allowedProtocols = new BitSet();
        allowedAuthAlgorithms = new BitSet();
        allowedPairwiseCiphers = new BitSet();
        allowedGroupCiphers = new BitSet();
        wepKeys = new String[4];
        for (int i = 0; i < wepKeys.length; i++) {
            wepKeys[i] = null;
        }
        enterpriseConfig = new WifiEnterpriseConfig();
        autoJoinStatus = AUTO_JOIN_ENABLED;
        selfAdded = false;
        didSelfAdd = false;
        ephemeral = false;
        noInternetAccess = false;
        mIpConfiguration = new IpConfiguration();
    }

    /**
     * indicates whether the configuration is valid
     * @return true if valid, false otherwise
     * @hide
     */
    public boolean isValid() {

        if (allowedKeyManagement == null)
            return false;

        if (allowedKeyManagement.cardinality() > 1) {
            if (allowedKeyManagement.cardinality() != 2) {
                return false;
            }
            if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) == false) {
                return false;
            }
            if ((allowedKeyManagement.get(KeyMgmt.IEEE8021X) == false)
                    && (allowedKeyManagement.get(KeyMgmt.WPA_PSK) == false)) {
                return false;
            }
        }

        // TODO: Add more checks
        return true;
    }

    /**
     * Helper function, identify if a configuration is linked
     * @hide
     */
    public boolean isLinked(WifiConfiguration config) {
        if (config.linkedConfigurations != null && linkedConfigurations != null) {
            if (config.linkedConfigurations.get(configKey()) != null
                    && linkedConfigurations.get(config.configKey()) != null) {
                return true;
            }
        }
        return  false;
    }

    /**
     * most recent time we have seen this configuration
     * @return most recent scanResult
     * @hide
     */
    public ScanResult lastSeen() {
        ScanResult mostRecent = null;

        if (scanResultCache == null) {
            return null;
        }

        for (ScanResult result : scanResultCache.values()) {
            if (mostRecent == null) {
                if (result.seen != 0)
                   mostRecent = result;
            } else {
                if (result.seen > mostRecent.seen) {
                   mostRecent = result;
                }
            }
        }
        return mostRecent;
    }

    /** @hide **/
    public void setAutoJoinStatus(int status) {
        if (status < 0) status = 0;
        if (status == 0) {
            blackListTimestamp = 0;
        }  else if (status > autoJoinStatus) {
            blackListTimestamp = System.currentTimeMillis();
        }
        if (status != autoJoinStatus) {
            autoJoinStatus = status;
            dirty = true;
        }
    }

    /* @hide */
    private ArrayList<ScanResult> sortScanResults() {
        ArrayList<ScanResult> list = new ArrayList<ScanResult>(this.scanResultCache.values());
        if (list.size() != 0) {
            Collections.sort(list, new Comparator() {
                public int compare(Object o1, Object o2) {
                    ScanResult a = (ScanResult)o1;
                    ScanResult b = (ScanResult)o2;
                    if (a.numIpConfigFailures > b.numIpConfigFailures) {
                        return 1;
                    }
                    if (a.numIpConfigFailures < b.numIpConfigFailures) {
                        return -1;
                    }
                    if (a.seen > b.seen) {
                        return -1;
                    }
                    if (a.seen < b.seen) {
                        return 1;
                    }
                    if (a.level > b.level) {
                        return -1;
                    }
                    if (a.level < b.level) {
                        return 1;
                    }
                    return a.BSSID.compareTo(b.BSSID);
                }
            });
        }
        return list;
    }

    @Override
    public String toString() {
        StringBuilder sbuf = new StringBuilder();
        if (this.status == WifiConfiguration.Status.CURRENT) {
            sbuf.append("* ");
        } else if (this.status == WifiConfiguration.Status.DISABLED) {
            sbuf.append("- DSBLE ");
        }
        sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID).
                append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN).
                append(" REALM: ").append(this.naiRealm).append(" PRIO: ").append(this.priority).
                append('\n');
        if (this.numConnectionFailures > 0) {
            sbuf.append(" numConnectFailures ").append(this.numConnectionFailures).append("\n");
        }
        if (this.numIpConfigFailures > 0) {
            sbuf.append(" numIpConfigFailures ").append(this.numIpConfigFailures).append("\n");
        }
        if (this.numAuthFailures > 0) {
            sbuf.append(" numAuthFailures ").append(this.numAuthFailures).append("\n");
        }
        if (this.autoJoinStatus > 0) {
            sbuf.append(" autoJoinStatus ").append(this.autoJoinStatus).append("\n");
        }
        if (this.disableReason > 0) {
            sbuf.append(" disableReason ").append(this.disableReason).append("\n");
        }
        if (this.numAssociation > 0) {
            sbuf.append(" numAssociation ").append(this.numAssociation).append("\n");
        }
        if (this.didSelfAdd) sbuf.append(" didSelfAdd");
        if (this.selfAdded) sbuf.append(" selfAdded");
        if (this.noInternetAccess) sbuf.append(" noInternetAccess");
        if (this.didSelfAdd || this.selfAdded || this.noInternetAccess) {
            sbuf.append("\n");
        }
        sbuf.append(" KeyMgmt:");
        for (int k = 0; k < this.allowedKeyManagement.size(); k++) {
            if (this.allowedKeyManagement.get(k)) {
                sbuf.append(" ");
                if (k < KeyMgmt.strings.length) {
                    sbuf.append(KeyMgmt.strings[k]);
                } else {
                    sbuf.append("??");
                }
            }
        }
        sbuf.append(" Protocols:");
        for (int p = 0; p < this.allowedProtocols.size(); p++) {
            if (this.allowedProtocols.get(p)) {
                sbuf.append(" ");
                if (p < Protocol.strings.length) {
                    sbuf.append(Protocol.strings[p]);
                } else {
                    sbuf.append("??");
                }
            }
        }
        sbuf.append('\n');
        sbuf.append(" AuthAlgorithms:");
        for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) {
            if (this.allowedAuthAlgorithms.get(a)) {
                sbuf.append(" ");
                if (a < AuthAlgorithm.strings.length) {
                    sbuf.append(AuthAlgorithm.strings[a]);
                } else {
                    sbuf.append("??");
                }
            }
        }
        sbuf.append('\n');
        sbuf.append(" PairwiseCiphers:");
        for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) {
            if (this.allowedPairwiseCiphers.get(pc)) {
                sbuf.append(" ");
                if (pc < PairwiseCipher.strings.length) {
                    sbuf.append(PairwiseCipher.strings[pc]);
                } else {
                    sbuf.append("??");
                }
            }
        }
        sbuf.append('\n');
        sbuf.append(" GroupCiphers:");
        for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) {
            if (this.allowedGroupCiphers.get(gc)) {
                sbuf.append(" ");
                if (gc < GroupCipher.strings.length) {
                    sbuf.append(GroupCipher.strings[gc]);
                } else {
                    sbuf.append("??");
                }
            }
        }
        sbuf.append('\n').append(" PSK: ");
        if (this.preSharedKey != null) {
            sbuf.append('*');
        }
        sbuf.append("\nEnterprise config:\n");
        sbuf.append(enterpriseConfig);

        sbuf.append("IP config:\n");
        sbuf.append(mIpConfiguration.toString());

        if (this.creatorUid != 0)  sbuf.append(" uid=" + Integer.toString(creatorUid));
        if (this.autoJoinBSSID != null) sbuf.append(" autoJoinBSSID=" + autoJoinBSSID);
        long now_ms = System.currentTimeMillis();
        if (this.blackListTimestamp != 0) {
            sbuf.append('\n');
            long diff = now_ms - this.blackListTimestamp;
            if (diff <= 0) {
                sbuf.append(" blackListed since <incorrect>");
            } else {
                sbuf.append(" blackListed: ").append(Long.toString(diff/1000)).append( "sec");
            }
        }
        if (this.lastConnected != 0) {
            sbuf.append('\n');
            long diff = now_ms - this.lastConnected;
            if (diff <= 0) {
                sbuf.append("lastConnected since <incorrect>");
            } else {
                sbuf.append("lastConnected: ").append(Long.toString(diff/1000)).append( "sec");
            }
        }
        if (this.lastConnectionFailure != 0) {
            sbuf.append('\n');
            long diff = now_ms - this.lastConnectionFailure;
            if (diff <= 0) {
                sbuf.append("lastConnectionFailure since <incorrect>");
            } else {
                sbuf.append("lastConnectionFailure: ").append(Long.toString(diff/1000));
                sbuf.append( "sec");
            }
        }
        sbuf.append('\n');
        if (this.linkedConfigurations != null) {
            for(String key : this.linkedConfigurations.keySet()) {
                sbuf.append(" linked: ").append(key);
                sbuf.append('\n');
            }
        }
        if (this.connectChoices != null) {
            for(String key : this.connectChoices.keySet()) {
                Integer choice = this.connectChoices.get(key);
                if (choice != null) {
                    sbuf.append(" choice: ").append(key);
                    sbuf.append(" = ").append(choice);
                    sbuf.append('\n');
                }
            }
        }
        if (this.scanResultCache != null) {
            sbuf.append("Scan Cache:  ").append('\n');
            ArrayList<ScanResult> list = sortScanResults();
            if (list.size() > 0) {
                for (ScanResult result : list) {
                    long milli = now_ms - result.seen;
                    long ageSec = 0;
                    long ageMin = 0;
                    long ageHour = 0;
                    long ageMilli = 0;
                    long ageDay = 0;
                    if (now_ms > result.seen && result.seen > 0) {
                        ageMilli = milli % 1000;
                        ageSec   = (milli / 1000) % 60;
                        ageMin   = (milli / (60*1000)) % 60;
                        ageHour  = (milli / (60*60*1000)) % 24;
                        ageDay   = (milli / (24*60*60*1000));
                    }
                    sbuf.append("{").append(result.BSSID).append(",").append(result.frequency);
                    sbuf.append(",").append(String.format("%3d", result.level));
                    if (result.autoJoinStatus > 0) {
                        sbuf.append(",st=").append(result.autoJoinStatus);
                    }
                    if (ageSec > 0 || ageMilli > 0) {
                        sbuf.append(String.format(",%4d.%02d.%02d.%02d.%03dms", ageDay,
                                ageHour, ageMin, ageSec, ageMilli));
                    }
                    if (result.numIpConfigFailures > 0) {
                        sbuf.append(",ipfail=");
                        sbuf.append(result.numIpConfigFailures);
                    }
                    sbuf.append("} ");
                }
                sbuf.append('\n');
            }
        }
        sbuf.append("triggeredLow: ").append(this.numUserTriggeredWifiDisableLowRSSI);
        sbuf.append(" triggeredBad: ").append(this.numUserTriggeredWifiDisableBadRSSI);
        sbuf.append(" triggeredNotHigh: ").append(this.numUserTriggeredWifiDisableNotHighRSSI);
        sbuf.append('\n');
        sbuf.append("ticksLow: ").append(this.numTicksAtLowRSSI);
        sbuf.append(" ticksBad: ").append(this.numTicksAtBadRSSI);
        sbuf.append(" ticksNotHigh: ").append(this.numTicksAtNotHighRSSI);
        sbuf.append('\n');
        sbuf.append("triggeredJoin: ").append(this.numUserTriggeredJoinAttempts);
        sbuf.append('\n');
        sbuf.append("autoJoinBailedDueToLowRssi: ").append(this.autoJoinBailedDueToLowRssi);
        sbuf.append('\n');
        sbuf.append("autoJoinUseAggressiveJoinAttemptThreshold: ");
        sbuf.append(this.autoJoinUseAggressiveJoinAttemptThreshold);
        sbuf.append('\n');

        return sbuf.toString();
    }

    /**
     * Construct a WifiConfiguration from a scanned network
     * @param scannedAP the scan result used to construct the config entry
     * TODO: figure out whether this is a useful way to construct a new entry.
     *
    public WifiConfiguration(ScanResult scannedAP) {
        networkId = -1;
        SSID = scannedAP.SSID;
        BSSID = scannedAP.BSSID;
    }
    */

    /** {@hide} */
    public String getPrintableSsid() {
        if (SSID == null) return "";
        final int length = SSID.length();
        if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') {
            return SSID.substring(1, length - 1);
        }

        /** The ascii-encoded string format is P"<ascii-encoded-string>"
         * The decoding is implemented in the supplicant for a newly configured
         * network.
         */
        if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') &&
                (SSID.charAt(length-1) == '"')) {
            WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded(
                    SSID.substring(2, length - 1));
            return wifiSsid.toString();
        }
        return SSID;
    }

    /**
     * Get an identifier for associating credentials with this config
     * @param current configuration contains values for additional fields
     *                that are not part of this configuration. Used
     *                when a config with some fields is passed by an application.
     * @throws IllegalStateException if config is invalid for key id generation
     * @hide
     */
    public String getKeyIdForCredentials(WifiConfiguration current) {
        String keyMgmt = null;

        try {
            // Get current config details for fields that are not initialized
            if (TextUtils.isEmpty(SSID)) SSID = current.SSID;
            if (allowedKeyManagement.cardinality() == 0) {
                allowedKeyManagement = current.allowedKeyManagement;
            }
            if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
                keyMgmt = KeyMgmt.strings[KeyMgmt.WPA_EAP];
            }
            if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
                keyMgmt += KeyMgmt.strings[KeyMgmt.IEEE8021X];
            }

            if (TextUtils.isEmpty(keyMgmt)) {
                throw new IllegalStateException("Not an EAP network");
            }

            return trimStringForKeyId(SSID) + "_" + keyMgmt + "_" +
                    trimStringForKeyId(enterpriseConfig.getKeyId(current != null ?
                            current.enterpriseConfig : null));
        } catch (NullPointerException e) {
            throw new IllegalStateException("Invalid config details");
        }
    }

    private String trimStringForKeyId(String string) {
        // Remove quotes and spaces
        return string.replace("\"", "").replace(" ", "");
    }

    private static BitSet readBitSet(Parcel src) {
        int cardinality = src.readInt();

        BitSet set = new BitSet();
        for (int i = 0; i < cardinality; i++) {
            set.set(src.readInt());
        }

        return set;
    }

    private static void writeBitSet(Parcel dest, BitSet set) {
        int nextSetBit = -1;

        dest.writeInt(set.cardinality());

        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
            dest.writeInt(nextSetBit);
        }
    }

    /** @hide */
    public int getAuthType() {
        if (isValid() == false) {
            throw new IllegalStateException("Invalid configuration");
        }
        if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
            return KeyMgmt.WPA_PSK;
        } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) {
            return KeyMgmt.WPA2_PSK;
        } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
            return KeyMgmt.WPA_EAP;
        } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
            return KeyMgmt.IEEE8021X;
        }
        return KeyMgmt.NONE;
    }

    /* @hide
     * Cache the config key, this seems useful as a speed up since a lot of
     * lookups in the config store are done and based on this key.
     */
    String mCachedConfigKey;

    /** @hide
     *  return the string used to calculate the hash in WifiConfigStore
     *  and uniquely identify this WifiConfiguration
     */
    public String configKey(boolean allowCached) {
        String key;
        if (allowCached && mCachedConfigKey != null) {
            key = mCachedConfigKey;
        } else {
            if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
                key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
            } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
                    allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
                key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
            } else if (wepKeys[0] != null) {
                key = SSID + "WEP";
            } else {
                key = SSID + KeyMgmt.strings[KeyMgmt.NONE];
            }
            mCachedConfigKey = key;
        }
        return key;
    }

    /** @hide
     * get configKey, force calculating the config string
     */
    public String configKey() {
        return configKey(false);
    }

    /** @hide
     * return the config key string based on a scan result
     */
    static public String configKey(ScanResult result) {
        String key = "\"" + result.SSID + "\"";

        if (result.capabilities.contains("WEP")) {
            key = key + "-WEP";
        }

        if (result.capabilities.contains("PSK")) {
            key = key + "-" + KeyMgmt.strings[KeyMgmt.WPA_PSK];
        }

        if (result.capabilities.contains("EAP")) {
            key = key + "-" + KeyMgmt.strings[KeyMgmt.WPA_EAP];
        }

        return key;
    }

    /** @hide */
    public IpConfiguration getIpConfiguration() {
        return mIpConfiguration;
    }

    /** @hide */
    public void setIpConfiguration(IpConfiguration ipConfiguration) {
        mIpConfiguration = ipConfiguration;
    }

    /** @hide */
    public StaticIpConfiguration getStaticIpConfiguration() {
        return mIpConfiguration.getStaticIpConfiguration();
    }

    /** @hide */
    public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) {
        mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration);
    }

    /** @hide */
    public IpConfiguration.IpAssignment getIpAssignment() {
        return mIpConfiguration.ipAssignment;
    }

    /** @hide */
    public void setIpAssignment(IpConfiguration.IpAssignment ipAssignment) {
        mIpConfiguration.ipAssignment = ipAssignment;
    }

    /** @hide */
    public IpConfiguration.ProxySettings getProxySettings() {
        return mIpConfiguration.proxySettings;
    }

    /** @hide */
    public void setProxySettings(IpConfiguration.ProxySettings proxySettings) {
        mIpConfiguration.proxySettings = proxySettings;
    }

    /** @hide */
    public ProxyInfo getHttpProxy() {
        return mIpConfiguration.httpProxy;
    }

    /** @hide */
    public void setHttpProxy(ProxyInfo httpProxy) {
        mIpConfiguration.httpProxy = httpProxy;
    }

    /** @hide */
    public void setProxy(ProxySettings settings, ProxyInfo proxy) {
        mIpConfiguration.proxySettings = settings;
        mIpConfiguration.httpProxy = proxy;
    }

    /** Implement the Parcelable interface {@hide} */
    public int describeContents() {
        return 0;
    }

    /** copy constructor {@hide} */
    public WifiConfiguration(WifiConfiguration source) {
        if (source != null) {
            networkId = source.networkId;
            status = source.status;
            disableReason = source.disableReason;
            disableReason = source.disableReason;
            SSID = source.SSID;
            BSSID = source.BSSID;
            FQDN = source.FQDN;
            naiRealm = source.naiRealm;
            preSharedKey = source.preSharedKey;

            wepKeys = new String[4];
            for (int i = 0; i < wepKeys.length; i++) {
                wepKeys[i] = source.wepKeys[i];
            }

            wepTxKeyIndex = source.wepTxKeyIndex;
            priority = source.priority;
            hiddenSSID = source.hiddenSSID;
            allowedKeyManagement   = (BitSet) source.allowedKeyManagement.clone();
            allowedProtocols       = (BitSet) source.allowedProtocols.clone();
            allowedAuthAlgorithms  = (BitSet) source.allowedAuthAlgorithms.clone();
            allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone();
            allowedGroupCiphers    = (BitSet) source.allowedGroupCiphers.clone();

            enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig);

            defaultGwMacAddress = source.defaultGwMacAddress;

            mIpConfiguration = new IpConfiguration(source.mIpConfiguration);

            if ((source.scanResultCache != null) && (source.scanResultCache.size() > 0)) {
                scanResultCache = new HashMap<String, ScanResult>();
                scanResultCache.putAll(source.scanResultCache);
            }

            if ((source.connectChoices != null) && (source.connectChoices.size() > 0)) {
                connectChoices = new HashMap<String, Integer>();
                connectChoices.putAll(source.connectChoices);
            }

            if ((source.linkedConfigurations != null)
                    && (source.linkedConfigurations.size() > 0)) {
                linkedConfigurations = new HashMap<String, Integer>();
                linkedConfigurations.putAll(source.linkedConfigurations);
            }
            mCachedConfigKey = null; //force null configKey
            autoJoinStatus = source.autoJoinStatus;
            selfAdded = source.selfAdded;
            noInternetAccess = source.noInternetAccess;
            if (source.visibility != null) {
                visibility = new Visibility(source.visibility);
            }

            lastFailure = source.lastFailure;
            didSelfAdd = source.didSelfAdd;
            lastConnectUid = source.lastConnectUid;
            lastUpdateUid = source.lastUpdateUid;
            creatorUid = source.creatorUid;
            peerWifiConfiguration = source.peerWifiConfiguration;
            blackListTimestamp = source.blackListTimestamp;
            lastConnected = source.lastConnected;
            lastDisconnected = source.lastDisconnected;
            lastConnectionFailure = source.lastConnectionFailure;
            numConnectionFailures = source.numConnectionFailures;
            numIpConfigFailures = source.numIpConfigFailures;
            numAuthFailures = source.numAuthFailures;
            numScorerOverride = source.numScorerOverride;
            numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork;
            numAssociation = source.numAssociation;
            numUserTriggeredWifiDisableLowRSSI = source.numUserTriggeredWifiDisableLowRSSI;
            numUserTriggeredWifiDisableBadRSSI = source.numUserTriggeredWifiDisableBadRSSI;
            numUserTriggeredWifiDisableNotHighRSSI = source.numUserTriggeredWifiDisableNotHighRSSI;
            numTicksAtLowRSSI = source.numTicksAtLowRSSI;
            numTicksAtBadRSSI = source.numTicksAtBadRSSI;
            numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI;
            numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts;
            autoJoinBSSID = source.autoJoinBSSID;
            autoJoinUseAggressiveJoinAttemptThreshold
                    = source.autoJoinUseAggressiveJoinAttemptThreshold;
            autoJoinBailedDueToLowRssi = source.autoJoinBailedDueToLowRssi;
            dirty = source.dirty;
        }
    }

    /** {@hide} */
    //public static final int NOTHING_TAG = 0;
    /** {@hide} */
    //public static final int SCAN_CACHE_TAG = 1;

    /** Implement the Parcelable interface {@hide} */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(networkId);
        dest.writeInt(status);
        dest.writeInt(disableReason);
        dest.writeString(SSID);
        dest.writeString(BSSID);
        dest.writeString(autoJoinBSSID);
        dest.writeString(FQDN);
        dest.writeString(naiRealm);
        dest.writeString(preSharedKey);
        for (String wepKey : wepKeys) {
            dest.writeString(wepKey);
        }
        dest.writeInt(wepTxKeyIndex);
        dest.writeInt(priority);
        dest.writeInt(hiddenSSID ? 1 : 0);
        dest.writeInt(requirePMF ? 1 : 0);
        dest.writeString(updateIdentifier);

        writeBitSet(dest, allowedKeyManagement);
        writeBitSet(dest, allowedProtocols);
        writeBitSet(dest, allowedAuthAlgorithms);
        writeBitSet(dest, allowedPairwiseCiphers);
        writeBitSet(dest, allowedGroupCiphers);

        dest.writeParcelable(enterpriseConfig, flags);

        dest.writeParcelable(mIpConfiguration, flags);
        dest.writeString(dhcpServer);
        dest.writeString(defaultGwMacAddress);
        dest.writeInt(autoJoinStatus);
        dest.writeInt(selfAdded ? 1 : 0);
        dest.writeInt(didSelfAdd ? 1 : 0);
        dest.writeInt(noInternetAccess ? 1 : 0);
        dest.writeInt(creatorUid);
        dest.writeInt(lastConnectUid);
        dest.writeInt(lastUpdateUid);
        dest.writeLong(blackListTimestamp);
        dest.writeLong(lastConnectionFailure);
        dest.writeInt(numConnectionFailures);
        dest.writeInt(numIpConfigFailures);
        dest.writeInt(numAuthFailures);
        dest.writeInt(numScorerOverride);
        dest.writeInt(numScorerOverrideAndSwitchedNetwork);
        dest.writeInt(numAssociation);
        dest.writeInt(numUserTriggeredWifiDisableLowRSSI);
        dest.writeInt(numUserTriggeredWifiDisableBadRSSI);
        dest.writeInt(numUserTriggeredWifiDisableNotHighRSSI);
        dest.writeInt(numTicksAtLowRSSI);
        dest.writeInt(numTicksAtBadRSSI);
        dest.writeInt(numTicksAtNotHighRSSI);
        dest.writeInt(numUserTriggeredJoinAttempts);
        dest.writeInt(autoJoinUseAggressiveJoinAttemptThreshold);
        dest.writeInt(autoJoinBailedDueToLowRssi ? 1 : 0);
    }

    /** Implement the Parcelable interface {@hide} */
    public static final Creator<WifiConfiguration> CREATOR =
        new Creator<WifiConfiguration>() {
            public WifiConfiguration createFromParcel(Parcel in) {
                WifiConfiguration config = new WifiConfiguration();
                config.networkId = in.readInt();
                config.status = in.readInt();
                config.disableReason = in.readInt();
                config.SSID = in.readString();
                config.BSSID = in.readString();
                config.autoJoinBSSID = in.readString();
                config.FQDN = in.readString();
                config.naiRealm = in.readString();
                config.preSharedKey = in.readString();
                for (int i = 0; i < config.wepKeys.length; i++) {
                    config.wepKeys[i] = in.readString();
                }
                config.wepTxKeyIndex = in.readInt();
                config.priority = in.readInt();
                config.hiddenSSID = in.readInt() != 0;
                config.requirePMF = in.readInt() != 0;
                config.updateIdentifier = in.readString();

                config.allowedKeyManagement   = readBitSet(in);
                config.allowedProtocols       = readBitSet(in);
                config.allowedAuthAlgorithms  = readBitSet(in);
                config.allowedPairwiseCiphers = readBitSet(in);
                config.allowedGroupCiphers    = readBitSet(in);

                config.enterpriseConfig = in.readParcelable(null);

                config.mIpConfiguration = in.readParcelable(null);
                config.dhcpServer = in.readString();
                config.defaultGwMacAddress = in.readString();
                config.autoJoinStatus = in.readInt();
                config.selfAdded = in.readInt() != 0;
                config.didSelfAdd = in.readInt() != 0;
                config.noInternetAccess = in.readInt() != 0;
                config.creatorUid = in.readInt();
                config.lastConnectUid = in.readInt();
                config.lastUpdateUid = in.readInt();
                config.blackListTimestamp = in.readLong();
                config.lastConnectionFailure = in.readLong();
                config.numConnectionFailures = in.readInt();
                config.numIpConfigFailures = in.readInt();
                config.numAuthFailures = in.readInt();
                config.numScorerOverride = in.readInt();
                config.numScorerOverrideAndSwitchedNetwork = in.readInt();
                config.numAssociation = in.readInt();
                config.numUserTriggeredWifiDisableLowRSSI = in.readInt();
                config.numUserTriggeredWifiDisableBadRSSI = in.readInt();
                config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt();
                config.numTicksAtLowRSSI = in.readInt();
                config.numTicksAtBadRSSI = in.readInt();
                config.numTicksAtNotHighRSSI = in.readInt();
                config.numUserTriggeredJoinAttempts = in.readInt();
                config.autoJoinUseAggressiveJoinAttemptThreshold = in.readInt();
                config.autoJoinBailedDueToLowRssi = in.readInt() != 0;
                return config;
            }

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