/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.server.wifi;

import android.content.Context;
import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetworkCallback;
import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiEnterpriseConfig;
import android.net.wifi.WifiEnterpriseConfig.Ocsp;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
import android.util.MutableBoolean;

import com.android.internal.annotations.VisibleForTesting;
import com.android.server.wifi.util.ArrayUtils;
import com.android.server.wifi.util.GeneralUtil.Mutable;
import com.android.server.wifi.util.NativeUtil;
import com.android.wifi.resources.R;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.annotation.concurrent.ThreadSafe;


/**
 * Wrapper class for ISupplicantStaNetwork HAL calls. Gets and sets supplicant sta network variables
 * and interacts with networks.
 * Public fields should be treated as invalid until their 'get' method is called, which will set the
 * value if it returns true
 * To maintain thread-safety, the locking protocol is that every non-static method (regardless of
 * access level) acquires mLock.
 */
@ThreadSafe
public class SupplicantStaNetworkHal {
    private static final String TAG = "SupplicantStaNetworkHal";
    @VisibleForTesting
    public static final String ID_STRING_KEY_FQDN = "fqdn";
    @VisibleForTesting
    public static final String ID_STRING_KEY_CREATOR_UID = "creatorUid";
    @VisibleForTesting
    public static final String ID_STRING_KEY_CONFIG_KEY = "configKey";

    /**
     * Regex pattern for extracting the GSM sim authentication response params from a string.
     * Matches a strings like the following: "[:<kc_value>:<sres_value>]";
     */
    private static final Pattern GSM_AUTH_RESPONSE_PARAMS_PATTERN =
            Pattern.compile(":([0-9a-fA-F]+):([0-9a-fA-F]+)");
    /**
     * Regex pattern for extracting the UMTS sim authentication response params from a string.
     * Matches a strings like the following: ":<ik_value>:<ck_value>:<res_value>";
     */
    private static final Pattern UMTS_AUTH_RESPONSE_PARAMS_PATTERN =
            Pattern.compile("^:([0-9a-fA-F]+):([0-9a-fA-F]+):([0-9a-fA-F]+)$");
    /**
     * Regex pattern for extracting the UMTS sim auts response params from a string.
     * Matches a strings like the following: ":<auts_value>";
     */
    private static final Pattern UMTS_AUTS_RESPONSE_PARAMS_PATTERN =
            Pattern.compile("^:([0-9a-fA-F]+)$");

    private final Object mLock = new Object();
    private final Context mContext;
    private final String mIfaceName;
    private final WifiMonitor mWifiMonitor;
    private ISupplicantStaNetwork mISupplicantStaNetwork;
    private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback;

    private boolean mVerboseLoggingEnabled = false;
    // Network variables read from wpa_supplicant.
    private int mNetworkId;
    private ArrayList<Byte> mSsid;
    private byte[/* 6 */] mBssid;
    private boolean mScanSsid;
    private int mKeyMgmtMask;
    private int mProtoMask;
    private int mAuthAlgMask;
    private int mGroupCipherMask;
    private int mPairwiseCipherMask;
    private int mGroupMgmtCipherMask;
    private String mPskPassphrase;
    private String mSaePassword;
    private String mSaePasswordId;
    private byte[] mPsk;
    private ArrayList<Byte> mWepKey;
    private int mWepTxKeyIdx;
    private boolean mRequirePmf;
    private String mIdStr;
    private int mEapMethod;
    private int mEapPhase2Method;
    private ArrayList<Byte> mEapIdentity;
    private ArrayList<Byte> mEapAnonymousIdentity;
    private ArrayList<Byte> mEapPassword;
    private String mEapCACert;
    private String mEapCAPath;
    private String mEapClientCert;
    private String mEapPrivateKeyId;
    private String mEapSubjectMatch;
    private String mEapAltSubjectMatch;
    private boolean mEapEngine;
    private String mEapEngineID;
    private String mEapDomainSuffixMatch;
    private @Ocsp int mOcsp;
    private String mWapiCertSuite;

    SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork, String ifaceName,
            Context context, WifiMonitor monitor) {
        mISupplicantStaNetwork = iSupplicantStaNetwork;
        mContext = context;
        mIfaceName = ifaceName;
        mWifiMonitor = monitor;
    }

    /**
     * Enable/Disable verbose logging.
     *
     * @param enable true to enable, false to disable.
     */
    void enableVerboseLogging(boolean enable) {
        synchronized (mLock) {
            mVerboseLoggingEnabled = enable;
        }
    }

    /**
     * Read network variables from wpa_supplicant into the provided WifiConfiguration object.
     *
     * @param config        WifiConfiguration object to be populated.
     * @param networkExtras Map of network extras parsed from wpa_supplicant.
     * @return true if succeeds, false otherwise.
     * @throws IllegalArgumentException on malformed configuration params.
     */
    @VisibleForTesting
    public boolean loadWifiConfiguration(WifiConfiguration config,
            Map<String, String> networkExtras) {
        synchronized (mLock) {
            if (config == null) return false;
            /** SSID */
            config.SSID = null;
            if (getSsid() && !ArrayUtils.isEmpty(mSsid)) {
                config.SSID = NativeUtil.encodeSsid(mSsid);
            } else {
                Log.e(TAG, "failed to read ssid");
                return false;
            }
            /** Network Id */
            config.networkId = -1;
            if (getId()) {
                config.networkId = mNetworkId;
            } else {
                Log.e(TAG, "getId failed");
                return false;
            }
            /** BSSID */
            config.getNetworkSelectionStatus().setNetworkSelectionBSSID(null);
            if (getBssid() && !ArrayUtils.isEmpty(mBssid)) {
                config.getNetworkSelectionStatus().setNetworkSelectionBSSID(
                        NativeUtil.macAddressFromByteArray(mBssid));
            }
            /** Scan SSID (Is Hidden Network?) */
            config.hiddenSSID = false;
            if (getScanSsid()) {
                config.hiddenSSID = mScanSsid;
            }
            /** Require PMF*/
            config.requirePmf = false;
            if (getRequirePmf()) {
                config.requirePmf = mRequirePmf;
            }
            /** WEP keys **/
            config.wepTxKeyIndex = -1;
            if (getWepTxKeyIdx()) {
                config.wepTxKeyIndex = mWepTxKeyIdx;
            }
            for (int i = 0; i < 4; i++) {
                config.wepKeys[i] = null;
                if (getWepKey(i) && !ArrayUtils.isEmpty(mWepKey)) {
                    config.wepKeys[i] = NativeUtil.bytesToHexOrQuotedString(mWepKey);
                }
            }

            /** allowedKeyManagement */
            if (getKeyMgmt()) {
                BitSet keyMgmtMask = supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask);
                config.allowedKeyManagement = removeFastTransitionFlags(keyMgmtMask);
                config.allowedKeyManagement = removeSha256KeyMgmtFlags(config.allowedKeyManagement);
            }
            /** allowedProtocols */
            if (getProto()) {
                config.allowedProtocols =
                        supplicantToWifiConfigurationProtoMask(mProtoMask);
            }
            /** allowedAuthAlgorithms */
            if (getAuthAlg()) {
                config.allowedAuthAlgorithms =
                        supplicantToWifiConfigurationAuthAlgMask(mAuthAlgMask);
            }
            /** allowedGroupCiphers */
            if (getGroupCipher()) {
                config.allowedGroupCiphers =
                        supplicantToWifiConfigurationGroupCipherMask(mGroupCipherMask);
            }
            /** allowedPairwiseCiphers */
            if (getPairwiseCipher()) {
                config.allowedPairwiseCiphers =
                        supplicantToWifiConfigurationPairwiseCipherMask(mPairwiseCipherMask);
            }
            /** allowedPairwiseCiphers */
            if (getGroupMgmtCipher()) {
                config.allowedGroupManagementCiphers =
                        supplicantToWifiConfigurationGroupMgmtCipherMask(mGroupMgmtCipherMask);
            }

            /** PSK pass phrase */
            config.preSharedKey = null;
            if (getPskPassphrase() && !TextUtils.isEmpty(mPskPassphrase)) {
                if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WAPI_PSK)) {
                    config.preSharedKey = mPskPassphrase;
                } else {
                    config.preSharedKey = NativeUtil.addEnclosingQuotes(mPskPassphrase);
                }
            } else if (getPsk() && !ArrayUtils.isEmpty(mPsk)) {
                config.preSharedKey = NativeUtil.hexStringFromByteArray(mPsk);
            } /* Do not read SAE password */

            /** metadata: idstr */
            if (getIdStr() && !TextUtils.isEmpty(mIdStr)) {
                Map<String, String> metadata = parseNetworkExtra(mIdStr);
                networkExtras.putAll(metadata);
            } else {
                Log.w(TAG, "getIdStr failed or empty");
            }

            /** WAPI Cert Suite */
            if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WAPI_CERT)) {
                if (config.enterpriseConfig == null) {
                    return false;
                }
                config.enterpriseConfig.setEapMethod(
                        WifiEnterpriseConfig.Eap.WAPI_CERT);
                /** WAPI Certificate Suite. */
                if (getWapiCertSuite() && !TextUtils.isEmpty(mWapiCertSuite)) {
                    config.enterpriseConfig.setWapiCertSuite(mWapiCertSuite);
                }
                return true;
            }
            return loadWifiEnterpriseConfig(config.SSID, config.enterpriseConfig);
        }
    }

    /**
     * Save an entire WifiConfiguration to wpa_supplicant via HIDL.
     *
     * @param config WifiConfiguration object to be saved.
     * @return true if succeeds, false otherwise.
     * @throws IllegalArgumentException on malformed configuration params.
     */
    public boolean saveWifiConfiguration(WifiConfiguration config) {
        synchronized (mLock) {
            if (config == null) return false;
            /** SSID */
            if (config.SSID != null) {
                if (!setSsid(NativeUtil.decodeSsid(config.SSID))) {
                    Log.e(TAG, "failed to set SSID: " + config.SSID);
                    return false;
                }
            }
            /** BSSID */
            String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
            if (bssidStr != null) {
                byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr);
                if (!setBssid(bssid)) {
                    Log.e(TAG, "failed to set BSSID: " + bssidStr);
                    return false;
                }
            }
            /** HiddenSSID */
            if (!setScanSsid(config.hiddenSSID)) {
                Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID);
                return false;
            }

            /** RequirePMF */
            if (!setRequirePmf(config.requirePmf)) {
                Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePmf);
                return false;
            }
            /** Key Management Scheme */
            if (config.allowedKeyManagement.cardinality() != 0) {
                // Add FT flags if supported.
                BitSet keyMgmtMask = addFastTransitionFlags(config.allowedKeyManagement);
                // Add SHA256 key management flags.
                keyMgmtMask = addSha256KeyMgmtFlags(keyMgmtMask);
                if (!setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(keyMgmtMask))) {
                    Log.e(TAG, "failed to set Key Management");
                    return false;
                }
                // Check and set SuiteB configurations.
                if (keyMgmtMask.get(WifiConfiguration.KeyMgmt.SUITE_B_192)
                        && !saveSuiteBConfig(config)) {
                    Log.e(TAG, "Failed to set Suite-B-192 configuration");
                    return false;
                }
            }
            /** Security Protocol */
            if (config.allowedProtocols.cardinality() != 0
                    && !setProto(wifiConfigurationToSupplicantProtoMask(config.allowedProtocols))) {
                Log.e(TAG, "failed to set Security Protocol");
                return false;
            }
            /** Auth Algorithm */
            if (config.allowedAuthAlgorithms.cardinality() != 0
                    && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask(
                    config.allowedAuthAlgorithms))) {
                Log.e(TAG, "failed to set AuthAlgorithm");
                return false;
            }
            /** Group Cipher */
            if (config.allowedGroupCiphers.cardinality() != 0
                    && (!setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
                    config.allowedGroupCiphers)))) {
                Log.e(TAG, "failed to set Group Cipher");
                return false;
            }
            /** Pairwise Cipher*/
            if (config.allowedPairwiseCiphers.cardinality() != 0
                    && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
                    config.allowedPairwiseCiphers))) {
                Log.e(TAG, "failed to set PairwiseCipher");
                return false;
            }
            /** Pre Shared Key */
            // For PSK, this can either be quoted ASCII passphrase or hex string for raw psk.
            // For SAE, password must be a quoted ASCII string
            if (config.preSharedKey != null) {
                if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WAPI_PSK)) {
                    if (!setPskPassphrase(config.preSharedKey)) {
                        Log.e(TAG, "failed to set wapi psk passphrase");
                        return false;
                    }
                } else if (config.preSharedKey.startsWith("\"")) {
                    if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
                        /* WPA3 case, field is SAE Password */
                        if (!setSaePassword(
                                NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
                            Log.e(TAG, "failed to set sae password");
                            return false;
                        }
                    } else {
                        if (!setPskPassphrase(
                                NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
                            Log.e(TAG, "failed to set psk passphrase");
                            return false;
                        }
                    }
                } else {
                    if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
                        return false;
                    }
                    if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) {
                        Log.e(TAG, "failed to set psk");
                        return false;
                    }
                }
            }
            /** Wep Keys */
            boolean hasSetKey = false;
            if (config.wepKeys != null) {
                for (int i = 0; i < config.wepKeys.length; i++) {
                    if (config.wepKeys[i] != null) {
                        if (!setWepKey(
                                i, NativeUtil.hexOrQuotedStringToBytes(config.wepKeys[i]))) {
                            Log.e(TAG, "failed to set wep_key " + i);
                            return false;
                        }
                        hasSetKey = true;
                    }
                }
            }
            /** Wep Tx Key Idx */
            if (hasSetKey) {
                if (!setWepTxKeyIdx(config.wepTxKeyIndex)) {
                    Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
                    return false;
                }
            }
            /** metadata: FQDN + ConfigKey + CreatorUid */
            final Map<String, String> metadata = new HashMap<String, String>();
            if (config.isPasspoint()) {
                metadata.put(ID_STRING_KEY_FQDN, config.FQDN);
            }
            metadata.put(ID_STRING_KEY_CONFIG_KEY, config.getKey());
            metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid));
            if (!setIdStr(createNetworkExtra(metadata))) {
                Log.e(TAG, "failed to set id string");
                return false;
            }
            /** UpdateIdentifier */
            if (config.updateIdentifier != null
                    && !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) {
                Log.e(TAG, "failed to set update identifier");
                return false;
            }
            // Finish here if no EAP config to set
            if (config.enterpriseConfig != null
                    && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
                if (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.WAPI_CERT) {
                    /** WAPI certificate suite name*/
                    String param = config.enterpriseConfig
                            .getFieldValue(WifiEnterpriseConfig.WAPI_CERT_SUITE_KEY);
                    if (!TextUtils.isEmpty(param) && !setWapiCertSuite(param)) {
                        Log.e(TAG, config.SSID + ": failed to set WAPI certificate suite: "
                                + param);
                        return false;
                    }
                    return true;
                } else if (!saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig)) {
                    return false;
                }
            }

            // Now that the network is configured fully, start listening for callback events.
            mISupplicantStaNetworkCallback =
                    new SupplicantStaNetworkHalCallback(config.networkId, config.SSID);
            if (!registerCallback(mISupplicantStaNetworkCallback)) {
                Log.e(TAG, "Failed to register callback");
                return false;
            }
            return true;
        }
    }

    /**
     * Read network variables from wpa_supplicant into the provided WifiEnterpriseConfig object.
     *
     * @param ssid      SSID of the network. (Used for logging purposes only)
     * @param eapConfig WifiEnterpriseConfig object to be populated.
     * @return true if succeeds, false otherwise.
     */
    private boolean loadWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) {
        synchronized (mLock) {
            if (eapConfig == null) return false;
            /** EAP method */
            if (getEapMethod()) {
                eapConfig.setEapMethod(supplicantToWifiConfigurationEapMethod(mEapMethod));
            } else {
                // Invalid eap method could be because it's not an enterprise config.
                Log.e(TAG, "failed to get eap method. Assumimg not an enterprise network");
                return true;
            }
            /** EAP Phase 2 method */
            if (getEapPhase2Method()) {
                eapConfig.setPhase2Method(
                        supplicantToWifiConfigurationEapPhase2Method(mEapPhase2Method));
            } else {
                // We cannot have an invalid eap phase 2 method. Return failure.
                Log.e(TAG, "failed to get eap phase2 method");
                return false;
            }
            /** EAP Identity */
            if (getEapIdentity() && !ArrayUtils.isEmpty(mEapIdentity)) {
                eapConfig.setFieldValue(
                        WifiEnterpriseConfig.IDENTITY_KEY,
                        NativeUtil.stringFromByteArrayList(mEapIdentity));
            }
            /** EAP Anonymous Identity */
            if (getEapAnonymousIdentity() && !ArrayUtils.isEmpty(mEapAnonymousIdentity)) {
                eapConfig.setFieldValue(
                        WifiEnterpriseConfig.ANON_IDENTITY_KEY,
                        NativeUtil.stringFromByteArrayList(mEapAnonymousIdentity));
            }
            /** EAP Password */
            if (getEapPassword() && !ArrayUtils.isEmpty(mEapPassword)) {
                eapConfig.setFieldValue(
                        WifiEnterpriseConfig.PASSWORD_KEY,
                        NativeUtil.stringFromByteArrayList(mEapPassword));
            }
            /** EAP Client Cert */
            if (getEapClientCert() && !TextUtils.isEmpty(mEapClientCert)) {
                eapConfig.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, mEapClientCert);
            }
            /** EAP CA Cert */
            if (getEapCACert() && !TextUtils.isEmpty(mEapCACert)) {
                eapConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, mEapCACert);
            }
            /** EAP OCSP type */
            if (getOcsp()) {
                eapConfig.setOcsp(mOcsp);
            }
            /** EAP Subject Match */
            if (getEapSubjectMatch() && !TextUtils.isEmpty(mEapSubjectMatch)) {
                eapConfig.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, mEapSubjectMatch);
            }
            /** EAP Engine ID */
            if (getEapEngineID() && !TextUtils.isEmpty(mEapEngineID)) {
                eapConfig.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, mEapEngineID);
            }
            /** EAP Engine. Set this only if the engine id is non null. */
            if (getEapEngine() && !TextUtils.isEmpty(mEapEngineID)) {
                eapConfig.setFieldValue(
                        WifiEnterpriseConfig.ENGINE_KEY,
                        mEapEngine
                                ? WifiEnterpriseConfig.ENGINE_ENABLE
                                : WifiEnterpriseConfig.ENGINE_DISABLE);
            }
            /** EAP Private Key */
            if (getEapPrivateKeyId() && !TextUtils.isEmpty(mEapPrivateKeyId)) {
                eapConfig.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, mEapPrivateKeyId);
            }
            /** EAP Alt Subject Match */
            if (getEapAltSubjectMatch() && !TextUtils.isEmpty(mEapAltSubjectMatch)) {
                eapConfig.setFieldValue(
                        WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, mEapAltSubjectMatch);
            }
            /** EAP Domain Suffix Match */
            if (getEapDomainSuffixMatch() && !TextUtils.isEmpty(mEapDomainSuffixMatch)) {
                eapConfig.setFieldValue(
                        WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, mEapDomainSuffixMatch);
            }
            /** EAP CA Path*/
            if (getEapCAPath() && !TextUtils.isEmpty(mEapCAPath)) {
                eapConfig.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, mEapCAPath);
            }
            return true;
        }
    }

    /**
     * Save network variables from the provided SuiteB configuration to wpa_supplicant.
     *
     * @param config WifiConfiguration object to be saved
     * @return true if succeeds, false otherwise.
     */
    private boolean saveSuiteBConfig(WifiConfiguration config) {
        /** Group Cipher **/
        if (config.allowedGroupCiphers.cardinality() != 0
                && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
                config.allowedGroupCiphers))) {
            Log.e(TAG, "failed to set Group Cipher");
            return false;
        }
        /** Pairwise Cipher*/
        if (config.allowedPairwiseCiphers.cardinality() != 0
                && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
                config.allowedPairwiseCiphers))) {
            Log.e(TAG, "failed to set PairwiseCipher");
            return false;
        }
        /** GroupMgmt Cipher */
        if (config.allowedGroupManagementCiphers.cardinality() != 0
                && !setGroupMgmtCipher(wifiConfigurationToSupplicantGroupMgmtCipherMask(
                config.allowedGroupManagementCiphers))) {
            Log.e(TAG, "failed to set GroupMgmtCipher");
            return false;
        }

        if (config.allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)) {
            if (!enableTlsSuiteBEapPhase1Param(true)) {
                Log.e(TAG, "failed to set TLSSuiteB");
                return false;
            }
        } else if (config.allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)) {
            if (!enableSuiteBEapOpenSslCiphers()) {
                Log.e(TAG, "failed to set OpensslCipher");
                return false;
            }
        }

        return true;
    }

    /**
     * Save network variables from the provided WifiEnterpriseConfig object to wpa_supplicant.
     *
     * @param ssid      SSID of the network. (Used for logging purposes only)
     * @param eapConfig WifiEnterpriseConfig object to be saved.
     * @return true if succeeds, false otherwise.
     */
    private boolean saveWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) {
        synchronized (mLock) {
            if (eapConfig == null) return false;
            /** EAP method */
            if (!setEapMethod(wifiConfigurationToSupplicantEapMethod(eapConfig.getEapMethod()))) {
                Log.e(TAG, ssid + ": failed to set eap method: " + eapConfig.getEapMethod());
                return false;
            }
            /** EAP Phase 2 method */
            if (!setEapPhase2Method(wifiConfigurationToSupplicantEapPhase2Method(
                    eapConfig.getPhase2Method()))) {
                Log.e(TAG, ssid + ": failed to set eap phase 2 method: "
                        + eapConfig.getPhase2Method());
                return false;
            }
            String eapParam = null;
            /** EAP Identity */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY);
            if (!TextUtils.isEmpty(eapParam)
                    && !setEapIdentity(NativeUtil.stringToByteArrayList(eapParam))) {
                Log.e(TAG, ssid + ": failed to set eap identity: " + eapParam);
                return false;
            }
            /** EAP Anonymous Identity */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY);
            if (!TextUtils.isEmpty(eapParam)
                    && !setEapAnonymousIdentity(NativeUtil.stringToByteArrayList(eapParam))) {
                Log.e(TAG, ssid + ": failed to set eap anonymous identity: " + eapParam);
                return false;
            }
            /** EAP Password */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY);
            if (!TextUtils.isEmpty(eapParam)
                    && !setEapPassword(NativeUtil.stringToByteArrayList(eapParam))) {
                Log.e(TAG, ssid + ": failed to set eap password");
                return false;
            }
            /** EAP Client Cert */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapClientCert(eapParam)) {
                Log.e(TAG, ssid + ": failed to set eap client cert: " + eapParam);
                return false;
            }
            /** EAP CA Cert */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapCACert(eapParam)) {
                Log.e(TAG, ssid + ": failed to set eap ca cert: " + eapParam);
                return false;
            }
            /** EAP Subject Match */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapSubjectMatch(eapParam)) {
                Log.e(TAG, ssid + ": failed to set eap subject match: " + eapParam);
                return false;
            }
            /** EAP Engine ID */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapEngineID(eapParam)) {
                Log.e(TAG, ssid + ": failed to set eap engine id: " + eapParam);
                return false;
            }
            /** EAP Engine */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapEngine(
                    eapParam.equals(WifiEnterpriseConfig.ENGINE_ENABLE) ? true : false)) {
                Log.e(TAG, ssid + ": failed to set eap engine: " + eapParam);
                return false;
            }
            /** EAP Private Key */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapPrivateKeyId(eapParam)) {
                Log.e(TAG, ssid + ": failed to set eap private key: " + eapParam);
                return false;
            }
            /** EAP Alt Subject Match */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapAltSubjectMatch(eapParam)) {
                Log.e(TAG, ssid + ": failed to set eap alt subject match: " + eapParam);
                return false;
            }
            /** EAP Domain Suffix Match */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapDomainSuffixMatch(eapParam)) {
                Log.e(TAG, ssid + ": failed to set eap domain suffix match: " + eapParam);
                return false;
            }
            /** EAP CA Path*/
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY);
            if (!TextUtils.isEmpty(eapParam) && !setEapCAPath(eapParam)) {
                Log.e(TAG, ssid + ": failed to set eap ca path: " + eapParam);
                return false;
            }

            /** EAP Proactive Key Caching */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.OPP_KEY_CACHING);
            if (!TextUtils.isEmpty(eapParam)
                    && !setEapProactiveKeyCaching(eapParam.equals("1") ? true : false)) {
                Log.e(TAG, ssid + ": failed to set proactive key caching: " + eapParam);
                return false;
            }

            /**
             * OCSP (Online Certificate Status Protocol)
             * For older HAL compatibility, omit this step to avoid breaking
             * connection flow.
             */
            if (getV1_3StaNetwork() != null && !setOcsp(eapConfig.getOcsp())) {
                Log.e(TAG, "failed to set ocsp");
                return false;
            }
            /** EAP ERP */
            eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.EAP_ERP);
            if (!TextUtils.isEmpty(eapParam) && eapParam.equals("1")) {
                if (!setEapErp(true)) {
                    Log.e(TAG, ssid + ": failed to set eap erp");
                    return false;
                }
            }


            return true;
        }
    }

    private android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork getV1_2StaNetwork() {
        synchronized (mLock) {
            return getSupplicantStaNetworkForV1_2Mockable();
        }
    }

    private android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork getV1_3StaNetwork() {
        synchronized (mLock) {
            return getSupplicantStaNetworkForV1_3Mockable();
        }
    }

    /**
     * Maps WifiConfiguration Key Management BitSet to Supplicant HIDL bitmask int
     * TODO(b/32571829): Update mapping when fast transition keys are added
     *
     * @return bitmask int describing the allowed Key Management schemes, readable by the Supplicant
     * HIDL hal
     */
    private static int wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt) {
        int mask = 0;
        for (int bit = keyMgmt.nextSetBit(0); bit != -1;
                bit = keyMgmt.nextSetBit(bit + 1)) {
            switch (bit) {
                case WifiConfiguration.KeyMgmt.NONE:
                    mask |= ISupplicantStaNetwork.KeyMgmtMask.NONE;
                    break;
                case WifiConfiguration.KeyMgmt.WPA_PSK:
                    mask |= ISupplicantStaNetwork.KeyMgmtMask.WPA_PSK;
                    break;
                case WifiConfiguration.KeyMgmt.WPA_EAP:
                    mask |= ISupplicantStaNetwork.KeyMgmtMask.WPA_EAP;
                    break;
                case WifiConfiguration.KeyMgmt.IEEE8021X:
                    mask |= ISupplicantStaNetwork.KeyMgmtMask.IEEE8021X;
                    break;
                case WifiConfiguration.KeyMgmt.OSEN:
                    mask |= ISupplicantStaNetwork.KeyMgmtMask.OSEN;
                    break;
                case WifiConfiguration.KeyMgmt.FT_PSK:
                    mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_PSK;
                    break;
                case WifiConfiguration.KeyMgmt.FT_EAP:
                    mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_EAP;
                    break;
                case WifiConfiguration.KeyMgmt.OWE:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
                            .OWE;
                    break;
                case WifiConfiguration.KeyMgmt.SAE:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
                            .SAE;
                    break;
                case WifiConfiguration.KeyMgmt.SUITE_B_192:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
                            .SUITE_B_192;
                    break;
                case WifiConfiguration.KeyMgmt.WPA_PSK_SHA256:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
                            .WPA_PSK_SHA256;
                    break;
                case WifiConfiguration.KeyMgmt.WPA_EAP_SHA256:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
                            .WPA_EAP_SHA256;
                    break;
                case WifiConfiguration.KeyMgmt.WAPI_PSK:
                    mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
                            .WAPI_PSK;
                    break;
                case WifiConfiguration.KeyMgmt.WAPI_CERT:
                    mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
                            .WAPI_CERT;
                    break;
                case WifiConfiguration.KeyMgmt.FILS_SHA256:
                    mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
                            .FILS_SHA256;
                    break;
                case WifiConfiguration.KeyMgmt.FILS_SHA384:
                    mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
                            .FILS_SHA384;
                    break;
                case WifiConfiguration.KeyMgmt.WPA2_PSK: // This should never happen
                default:
                    throw new IllegalArgumentException(
                            "Invalid protoMask bit in keyMgmt: " + bit);
            }
        }
        return mask;
    }

    private static int wifiConfigurationToSupplicantProtoMask(BitSet protoMask) {
        int mask = 0;
        for (int bit = protoMask.nextSetBit(0); bit != -1;
                bit = protoMask.nextSetBit(bit + 1)) {
            switch (bit) {
                case WifiConfiguration.Protocol.WPA:
                    mask |= ISupplicantStaNetwork.ProtoMask.WPA;
                    break;
                case WifiConfiguration.Protocol.RSN:
                    mask |= ISupplicantStaNetwork.ProtoMask.RSN;
                    break;
                case WifiConfiguration.Protocol.OSEN:
                    mask |= ISupplicantStaNetwork.ProtoMask.OSEN;
                    break;
                case WifiConfiguration.Protocol.WAPI:
                    mask |= android.hardware.wifi.supplicant.V1_3
                            .ISupplicantStaNetwork.ProtoMask.WAPI;
                    break;
                default:
                    throw new IllegalArgumentException(
                            "Invalid protoMask bit in wificonfig: " + bit);
            }
        }
        return mask;
    }

    private static int wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask) {
        int mask = 0;
        for (int bit = authAlgMask.nextSetBit(0); bit != -1;
                bit = authAlgMask.nextSetBit(bit + 1)) {
            switch (bit) {
                case WifiConfiguration.AuthAlgorithm.OPEN:
                    mask |= ISupplicantStaNetwork.AuthAlgMask.OPEN;
                    break;
                case WifiConfiguration.AuthAlgorithm.SHARED:
                    mask |= ISupplicantStaNetwork.AuthAlgMask.SHARED;
                    break;
                case WifiConfiguration.AuthAlgorithm.LEAP:
                    mask |= ISupplicantStaNetwork.AuthAlgMask.LEAP;
                    break;
                case WifiConfiguration.AuthAlgorithm.SAE:
                    mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.AuthAlgMask
                            .SAE;
                    break;
                default:
                    throw new IllegalArgumentException(
                            "Invalid authAlgMask bit in wificonfig: " + bit);
            }
        }
        return mask;
    }

    private static int wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask) {
        int mask = 0;
        for (int bit = groupCipherMask.nextSetBit(0); bit != -1; bit =
                groupCipherMask.nextSetBit(bit + 1)) {
            switch (bit) {
                case WifiConfiguration.GroupCipher.WEP40:
                    mask |= ISupplicantStaNetwork.GroupCipherMask.WEP40;
                    break;
                case WifiConfiguration.GroupCipher.WEP104:
                    mask |= ISupplicantStaNetwork.GroupCipherMask.WEP104;
                    break;
                case WifiConfiguration.GroupCipher.TKIP:
                    mask |= ISupplicantStaNetwork.GroupCipherMask.TKIP;
                    break;
                case WifiConfiguration.GroupCipher.CCMP:
                    mask |= ISupplicantStaNetwork.GroupCipherMask.CCMP;
                    break;
                case WifiConfiguration.GroupCipher.GTK_NOT_USED:
                    mask |= ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED;
                    break;
                case WifiConfiguration.GroupCipher.GCMP_256:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                            .GroupCipherMask.GCMP_256;
                    break;
                case WifiConfiguration.GroupCipher.SMS4:
                    mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
                                .GroupCipherMask.SMS4;
                    break;
                default:
                    throw new IllegalArgumentException(
                            "Invalid GroupCipherMask bit in wificonfig: " + bit);
            }
        }
        return mask;
    }

    private static int wifiConfigurationToSupplicantGroupMgmtCipherMask(BitSet
            groupMgmtCipherMask) {
        int mask = 0;

        for (int bit = groupMgmtCipherMask.nextSetBit(0); bit != -1; bit =
                groupMgmtCipherMask.nextSetBit(bit + 1)) {
            switch (bit) {
                case WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                            .GroupMgmtCipherMask.BIP_CMAC_256;
                    break;
                case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                            .GroupMgmtCipherMask.BIP_GMAC_128;
                    break;
                case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                            .GroupMgmtCipherMask.BIP_GMAC_256;
                    break;
                default:
                    throw new IllegalArgumentException(
                            "Invalid GroupMgmtCipherMask bit in wificonfig: " + bit);
            }
        }
        return mask;
    }

    private static int wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask) {
        int mask = 0;
        for (int bit = pairwiseCipherMask.nextSetBit(0); bit != -1;
                bit = pairwiseCipherMask.nextSetBit(bit + 1)) {
            switch (bit) {
                case WifiConfiguration.PairwiseCipher.NONE:
                    mask |= ISupplicantStaNetwork.PairwiseCipherMask.NONE;
                    break;
                case WifiConfiguration.PairwiseCipher.TKIP:
                    mask |= ISupplicantStaNetwork.PairwiseCipherMask.TKIP;
                    break;
                case WifiConfiguration.PairwiseCipher.CCMP:
                    mask |= ISupplicantStaNetwork.PairwiseCipherMask.CCMP;
                    break;
                case WifiConfiguration.PairwiseCipher.GCMP_256:
                    mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                            .PairwiseCipherMask.GCMP_256;
                    break;
                case WifiConfiguration.PairwiseCipher.SMS4:
                    mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
                            .PairwiseCipherMask.SMS4;
                    break;
                default:
                    throw new IllegalArgumentException(
                            "Invalid pairwiseCipherMask bit in wificonfig: " + bit);
            }
        }
        return mask;
    }

    private static int supplicantToWifiConfigurationEapMethod(int value) {
        switch (value) {
            case ISupplicantStaNetwork.EapMethod.PEAP:
                return WifiEnterpriseConfig.Eap.PEAP;
            case ISupplicantStaNetwork.EapMethod.TLS:
                return WifiEnterpriseConfig.Eap.TLS;
            case ISupplicantStaNetwork.EapMethod.TTLS:
                return WifiEnterpriseConfig.Eap.TTLS;
            case ISupplicantStaNetwork.EapMethod.PWD:
                return WifiEnterpriseConfig.Eap.PWD;
            case ISupplicantStaNetwork.EapMethod.SIM:
                return WifiEnterpriseConfig.Eap.SIM;
            case ISupplicantStaNetwork.EapMethod.AKA:
                return WifiEnterpriseConfig.Eap.AKA;
            case ISupplicantStaNetwork.EapMethod.AKA_PRIME:
                return WifiEnterpriseConfig.Eap.AKA_PRIME;
            case ISupplicantStaNetwork.EapMethod.WFA_UNAUTH_TLS:
                return WifiEnterpriseConfig.Eap.UNAUTH_TLS;
            // WifiEnterpriseConfig.Eap.NONE:
            default:
                Log.e(TAG, "invalid eap method value from supplicant: " + value);
                return -1;
        }
    }

    private static int supplicantToWifiConfigurationEapPhase2Method(int value) {
        switch (value) {
            case ISupplicantStaNetwork.EapPhase2Method.NONE:
                return WifiEnterpriseConfig.Phase2.NONE;
            case ISupplicantStaNetwork.EapPhase2Method.PAP:
                return WifiEnterpriseConfig.Phase2.PAP;
            case ISupplicantStaNetwork.EapPhase2Method.MSPAP:
                return WifiEnterpriseConfig.Phase2.MSCHAP;
            case ISupplicantStaNetwork.EapPhase2Method.MSPAPV2:
                return WifiEnterpriseConfig.Phase2.MSCHAPV2;
            case ISupplicantStaNetwork.EapPhase2Method.GTC:
                return WifiEnterpriseConfig.Phase2.GTC;
            case ISupplicantStaNetwork.EapPhase2Method.SIM:
                return WifiEnterpriseConfig.Phase2.SIM;
            case ISupplicantStaNetwork.EapPhase2Method.AKA:
                return WifiEnterpriseConfig.Phase2.AKA;
            case ISupplicantStaNetwork.EapPhase2Method.AKA_PRIME:
                return WifiEnterpriseConfig.Phase2.AKA_PRIME;
            default:
                Log.e(TAG, "invalid eap phase2 method value from supplicant: " + value);
                return -1;
        }
    }

    private static int supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask,
            int supplicantValue, BitSet bitset,
            int bitSetPosition) {
        bitset.set(bitSetPosition, (supplicantMask & supplicantValue) == supplicantValue);
        int modifiedSupplicantMask = supplicantMask & ~supplicantValue;
        return modifiedSupplicantMask;
    }

    private static BitSet supplicantToWifiConfigurationKeyMgmtMask(int mask) {
        BitSet bitset = new BitSet();
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.KeyMgmtMask.NONE, bitset,
                WifiConfiguration.KeyMgmt.NONE);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.KeyMgmtMask.WPA_PSK, bitset,
                WifiConfiguration.KeyMgmt.WPA_PSK);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.KeyMgmtMask.WPA_EAP, bitset,
                WifiConfiguration.KeyMgmt.WPA_EAP);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.KeyMgmtMask.IEEE8021X, bitset,
                WifiConfiguration.KeyMgmt.IEEE8021X);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.KeyMgmtMask.OSEN, bitset,
                WifiConfiguration.KeyMgmt.OSEN);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.KeyMgmtMask.FT_PSK, bitset,
                WifiConfiguration.KeyMgmt.FT_PSK);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.KeyMgmtMask.FT_EAP, bitset,
                WifiConfiguration.KeyMgmt.FT_EAP);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask.SAE,
                bitset, WifiConfiguration.KeyMgmt.SAE);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask.OWE,
                bitset, WifiConfiguration.KeyMgmt.OWE);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
                        .SUITE_B_192, bitset, WifiConfiguration.KeyMgmt.SUITE_B_192);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
                        .WPA_PSK_SHA256, bitset, WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
                        .WPA_EAP_SHA256, bitset, WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
                        .WAPI_PSK, bitset, WifiConfiguration.KeyMgmt.WAPI_PSK);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
                        .WAPI_CERT, bitset, WifiConfiguration.KeyMgmt.WAPI_CERT);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
                      .FILS_SHA256, bitset, WifiConfiguration.KeyMgmt.FILS_SHA256);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
                      .FILS_SHA384, bitset, WifiConfiguration.KeyMgmt.FILS_SHA384);
        if (mask != 0) {
            throw new IllegalArgumentException(
                    "invalid key mgmt mask from supplicant: " + mask);
        }
        return bitset;
    }

    private static BitSet supplicantToWifiConfigurationProtoMask(int mask) {
        BitSet bitset = new BitSet();
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.ProtoMask.WPA, bitset,
                WifiConfiguration.Protocol.WPA);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.ProtoMask.RSN, bitset,
                WifiConfiguration.Protocol.RSN);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.ProtoMask.OSEN, bitset,
                WifiConfiguration.Protocol.OSEN);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.ProtoMask.WAPI,
                bitset, WifiConfiguration.Protocol.WAPI);
        if (mask != 0) {
            throw new IllegalArgumentException(
                    "invalid proto mask from supplicant: " + mask);
        }
        return bitset;
    }

    private static BitSet supplicantToWifiConfigurationAuthAlgMask(int mask) {
        BitSet bitset = new BitSet();
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.AuthAlgMask.OPEN, bitset,
                WifiConfiguration.AuthAlgorithm.OPEN);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.AuthAlgMask.SHARED, bitset,
                WifiConfiguration.AuthAlgorithm.SHARED);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.AuthAlgMask.LEAP, bitset,
                WifiConfiguration.AuthAlgorithm.LEAP);
        mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
                android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.AuthAlgMask
                        .SAE, bitset, WifiConfiguration.AuthAlgorithm.SAE);
        if (mask != 0) {
            throw new IllegalArgumentException(
                    "invalid auth alg mask from supplicant: " + mask);
        }
        return bitset;
    }

    private static BitSet supplicantToWifiConfigurationGroupCipherMask(int mask) {
        BitSet bitset = new BitSet();
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.GroupCipherMask.WEP40, bitset,
                WifiConfiguration.GroupCipher.WEP40);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.GroupCipherMask.WEP104, bitset,
                WifiConfiguration.GroupCipher.WEP104);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.GroupCipherMask.TKIP, bitset,
                WifiConfiguration.GroupCipher.TKIP);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.GroupCipherMask.CCMP, bitset,
                WifiConfiguration.GroupCipher.CCMP);
        mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        .GroupCipherMask.GCMP_256, bitset, WifiConfiguration.GroupCipher.GCMP_256);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED, bitset,
                WifiConfiguration.GroupCipher.GTK_NOT_USED);
        mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
                android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.GroupCipherMask
                        .SMS4, bitset, WifiConfiguration.GroupCipher.SMS4);
        if (mask != 0) {
            throw new IllegalArgumentException(
                    "invalid group cipher mask from supplicant: " + mask);
        }
        return bitset;
    }

    private static BitSet supplicantToWifiConfigurationGroupMgmtCipherMask(int mask) {
        BitSet bitset = new BitSet();
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        .GroupMgmtCipherMask.BIP_GMAC_128, bitset,
                WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        .GroupMgmtCipherMask.BIP_GMAC_256, bitset,
                WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        .GroupMgmtCipherMask.BIP_CMAC_256, bitset,
                WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256);
        if (mask != 0) {
            throw new IllegalArgumentException(
                    "invalid group mgmt cipher mask from supplicant: " + mask);
        }
        return bitset;
    }

    private static BitSet supplicantToWifiConfigurationPairwiseCipherMask(int mask) {
        BitSet bitset = new BitSet();
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.PairwiseCipherMask.NONE, bitset,
                WifiConfiguration.PairwiseCipher.NONE);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.PairwiseCipherMask.TKIP, bitset,
                WifiConfiguration.PairwiseCipher.TKIP);
        mask = supplicantMaskValueToWifiConfigurationBitSet(
                mask, ISupplicantStaNetwork.PairwiseCipherMask.CCMP, bitset,
                WifiConfiguration.PairwiseCipher.CCMP);
        mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.PairwiseCipherMask
                        .GCMP_256, bitset,
                WifiConfiguration.PairwiseCipher.GCMP_256);
        mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
                android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.PairwiseCipherMask
                        .SMS4, bitset,
                WifiConfiguration.PairwiseCipher.SMS4);
        if (mask != 0) {
            throw new IllegalArgumentException(
                    "invalid pairwise cipher mask from supplicant: " + mask);
        }
        return bitset;
    }

    private static int wifiConfigurationToSupplicantEapMethod(int value) {
        switch (value) {
            case WifiEnterpriseConfig.Eap.PEAP:
                return ISupplicantStaNetwork.EapMethod.PEAP;
            case WifiEnterpriseConfig.Eap.TLS:
                return ISupplicantStaNetwork.EapMethod.TLS;
            case WifiEnterpriseConfig.Eap.TTLS:
                return ISupplicantStaNetwork.EapMethod.TTLS;
            case WifiEnterpriseConfig.Eap.PWD:
                return ISupplicantStaNetwork.EapMethod.PWD;
            case WifiEnterpriseConfig.Eap.SIM:
                return ISupplicantStaNetwork.EapMethod.SIM;
            case WifiEnterpriseConfig.Eap.AKA:
                return ISupplicantStaNetwork.EapMethod.AKA;
            case WifiEnterpriseConfig.Eap.AKA_PRIME:
                return ISupplicantStaNetwork.EapMethod.AKA_PRIME;
            case WifiEnterpriseConfig.Eap.UNAUTH_TLS:
                return ISupplicantStaNetwork.EapMethod.WFA_UNAUTH_TLS;
            // WifiEnterpriseConfig.Eap.NONE:
            default:
                Log.e(TAG, "invalid eap method value from WifiConfiguration: " + value);
                return -1;
        }
    }

    private static int wifiConfigurationToSupplicantEapPhase2Method(int value) {
        switch (value) {
            case WifiEnterpriseConfig.Phase2.NONE:
                return ISupplicantStaNetwork.EapPhase2Method.NONE;
            case WifiEnterpriseConfig.Phase2.PAP:
                return ISupplicantStaNetwork.EapPhase2Method.PAP;
            case WifiEnterpriseConfig.Phase2.MSCHAP:
                return ISupplicantStaNetwork.EapPhase2Method.MSPAP;
            case WifiEnterpriseConfig.Phase2.MSCHAPV2:
                return ISupplicantStaNetwork.EapPhase2Method.MSPAPV2;
            case WifiEnterpriseConfig.Phase2.GTC:
                return ISupplicantStaNetwork.EapPhase2Method.GTC;
            case WifiEnterpriseConfig.Phase2.SIM:
                return ISupplicantStaNetwork.EapPhase2Method.SIM;
            case WifiEnterpriseConfig.Phase2.AKA:
                return ISupplicantStaNetwork.EapPhase2Method.AKA;
            case WifiEnterpriseConfig.Phase2.AKA_PRIME:
                return ISupplicantStaNetwork.EapPhase2Method.AKA_PRIME;
            default:
                Log.e(TAG, "invalid eap phase2 method value from WifiConfiguration: " + value);
                return -1;
        }
    }

    /** See ISupplicantNetwork.hal for documentation */
    private boolean getId() {
        synchronized (mLock) {
            final String methodStr = "getId";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getId((SupplicantStatus status, int idValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mNetworkId = idValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean registerCallback(ISupplicantStaNetworkCallback callback) {
        synchronized (mLock) {
            final String methodStr = "registerCallback";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.registerCallback(callback);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setSsid(java.util.ArrayList<Byte> ssid) {
        synchronized (mLock) {
            final String methodStr = "setSsid";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setSsid(ssid);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /**
     * Set the BSSID for this network.
     *
     * @param bssidStr MAC address in "XX:XX:XX:XX:XX:XX" form or "any" to reset the mac address.
     * @return true if it succeeds, false otherwise.
     */
    public boolean setBssid(String bssidStr) {
        synchronized (mLock) {
            try {
                return setBssid(NativeUtil.macAddressToByteArray(bssidStr));
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Illegal argument " + bssidStr, e);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setBssid(byte[/* 6 */] bssid) {
        synchronized (mLock) {
            final String methodStr = "setBssid";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setBssid(bssid);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setScanSsid(boolean enable) {
        synchronized (mLock) {
            final String methodStr = "setScanSsid";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setScanSsid(enable);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setKeyMgmt(int keyMgmtMask) {
        synchronized (mLock) {
            final String methodStr = "setKeyMgmt";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status;
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        iSupplicantStaNetworkV12;
                iSupplicantStaNetworkV12 = getV1_2StaNetwork();

                if (getV1_3StaNetwork() != null) {
                    /* Support for new key management types:
                     * WAPI_PSK, WAPI_CERT
                     * Requires HAL v1.3 or higher */
                    status = getV1_3StaNetwork().setKeyMgmt_1_3(keyMgmtMask);
                } else if (iSupplicantStaNetworkV12 != null) {
                    /* Support for new key management types;
                     * SAE, OWE, WPA_PSK_SHA256, WPA_EAP_SHA256
                     * Requires HAL v1.2 or higher */
                    status = iSupplicantStaNetworkV12.setKeyMgmt_1_2(keyMgmtMask);
                } else {
                    status = mISupplicantStaNetwork.setKeyMgmt(keyMgmtMask);
                }
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setProto(int protoMask) {
        synchronized (mLock) {
            final String methodStr = "setProto";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status;
                if (null != getV1_3StaNetwork()) {
                    /* Support for new proto types: WAPI
                     * Requires HAL v1.3 or higher
                     */
                    status = getV1_3StaNetwork().setProto_1_3(protoMask);
                } else {
                    status = mISupplicantStaNetwork.setProto(protoMask);
                }
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setAuthAlg(int authAlgMask) {
        synchronized (mLock) {
            final String methodStr = "setAuthAlg";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status;
                if (null != getV1_3StaNetwork()) {
                    /* Support for SAE Authentication algorithm requires HAL v1.3 or higher */
                    status = getV1_3StaNetwork().setAuthAlg_1_3(authAlgMask);
                } else {
                    status = mISupplicantStaNetwork.setAuthAlg(authAlgMask);
                }
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setGroupCipher(int groupCipherMask) {
        synchronized (mLock) {
            final String methodStr = "setGroupCipher";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status;
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        iSupplicantStaNetworkV12;
                iSupplicantStaNetworkV12 = getV1_2StaNetwork();
                if (null != getV1_3StaNetwork()) {
                    /* Support for new key group cipher types for SMS4
                     * Requires HAL v1.3 or higher */
                    status = getV1_3StaNetwork().setGroupCipher_1_3(groupCipherMask);
                } else if (iSupplicantStaNetworkV12 != null) {
                    /* Support for new key group cipher types for SuiteB
                     * Requires HAL v1.2 or higher */
                    status = iSupplicantStaNetworkV12.setGroupCipher_1_2(groupCipherMask);
                } else {
                    // Clear GCMP_256 group cipher which is not supported before v1.2
                    groupCipherMask &= ~android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                            .GroupCipherMask.GCMP_256;
                    status = mISupplicantStaNetwork.setGroupCipher(
                            groupCipherMask);
                }
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean enableTlsSuiteBEapPhase1Param(boolean enable) {
        synchronized (mLock) {
            final String methodStr = "setEapPhase1Params";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        iSupplicantStaNetworkV12;

                iSupplicantStaNetworkV12 = getV1_2StaNetwork();
                if (iSupplicantStaNetworkV12 != null) {
                    /* Support for for SuiteB
                     * Requires HAL v1.2 or higher */
                    SupplicantStatus status = iSupplicantStaNetworkV12
                            .enableTlsSuiteBEapPhase1Param(enable);
                    return checkStatusAndLogFailure(status, methodStr);
                } else {
                    Log.e(TAG, "Supplicant HAL version does not support " + methodStr);
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean enableSuiteBEapOpenSslCiphers() {
        synchronized (mLock) {
            final String methodStr = "setEapOpenSslCiphers";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        iSupplicantStaNetworkV12;

                iSupplicantStaNetworkV12 = getV1_2StaNetwork();
                if (iSupplicantStaNetworkV12 != null) {
                    /* Support for for SuiteB
                     * Requires HAL v1.2 or higher */
                    SupplicantStatus status = iSupplicantStaNetworkV12
                            .enableSuiteBEapOpenSslCiphers();
                    return checkStatusAndLogFailure(status, methodStr);
                } else {
                    Log.e(TAG, "Supplicant HAL version does not support " + methodStr);
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setPairwiseCipher(int pairwiseCipherMask) {
        synchronized (mLock) {
            final String methodStr = "setPairwiseCipher";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status;
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        iSupplicantStaNetworkV12;
                iSupplicantStaNetworkV12 = getV1_2StaNetwork();
                if (null != getV1_3StaNetwork()) {
                    /* Support for new key pairwise cipher types for SMS4
                     * Requires HAL v1.3 or higher */
                    status = getV1_3StaNetwork().setPairwiseCipher_1_3(pairwiseCipherMask);
                } else if (iSupplicantStaNetworkV12 != null) {
                    /* Support for new key pairwise cipher types for SuiteB
                     * Requires HAL v1.2 or higher */
                    status = iSupplicantStaNetworkV12.setPairwiseCipher_1_2(pairwiseCipherMask);
                } else {
                    // Clear GCMP_256 pairwise cipher which is not supported before v1.2
                    pairwiseCipherMask &= ~android.hardware.wifi.supplicant.V1_2
                            .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_256;
                    status =
                            mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask);
                }
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setGroupMgmtCipher(int groupMgmtCipherMask) {
        synchronized (mLock) {
            final String methodStr = "setGroupMgmtCipher";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        iSupplicantStaNetworkV12;

                iSupplicantStaNetworkV12 = getV1_2StaNetwork();
                if (iSupplicantStaNetworkV12 != null) {
                    /* Support for new key pairwise cipher types for SuiteB
                     * Requires HAL v1.2 or higher */
                    SupplicantStatus status = iSupplicantStaNetworkV12
                            .setGroupMgmtCipher(groupMgmtCipherMask);
                    return checkStatusAndLogFailure(status, methodStr);
                } else {
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setPskPassphrase(String psk) {
        synchronized (mLock) {
            final String methodStr = "setPskPassphrase";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setPskPassphrase(psk);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setPsk(byte[] psk) {
        synchronized (mLock) {
            final String methodStr = "setPsk";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setPsk(psk);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            } catch (ArrayIndexOutOfBoundsException e) {
                Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + e);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setWepKey(int keyIdx, java.util.ArrayList<Byte> wepKey) {
        synchronized (mLock) {
            final String methodStr = "setWepKey";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setWepKey(keyIdx, wepKey);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setWepTxKeyIdx(int keyIdx) {
        synchronized (mLock) {
            final String methodStr = "setWepTxKeyIdx";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setWepTxKeyIdx(keyIdx);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setRequirePmf(boolean enable) {
        synchronized (mLock) {
            final String methodStr = "setRequirePmf";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setRequirePmf(enable);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setUpdateIdentifier(int identifier) {
        synchronized (mLock) {
            final String methodStr = "setUpdateIdentifier";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setUpdateIdentifier(identifier);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setWapiCertSuite(String certSuite) {
        synchronized (mLock) {
            final String methodStr = "setWapiCertSuite";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                if (null != getV1_3StaNetwork()) {
                    /* Requires HAL v1.3 or higher */
                    SupplicantStatus status = getV1_3StaNetwork().setWapiCertSuite(certSuite);
                    return checkStatusAndLogFailure(status, methodStr);
                } else {
                    Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapMethod(int method) {
        synchronized (mLock) {
            final String methodStr = "setEapMethod";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapMethod(method);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapPhase2Method(int method) {
        synchronized (mLock) {
            final String methodStr = "setEapPhase2Method";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapPhase2Method(method);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapIdentity(java.util.ArrayList<Byte> identity) {
        synchronized (mLock) {
            final String methodStr = "setEapIdentity";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapIdentity(identity);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapAnonymousIdentity(java.util.ArrayList<Byte> identity) {
        synchronized (mLock) {
            final String methodStr = "setEapAnonymousIdentity";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapAnonymousIdentity(identity);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapPassword(java.util.ArrayList<Byte> password) {
        synchronized (mLock) {
            final String methodStr = "setEapPassword";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapPassword(password);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapCACert(String path) {
        synchronized (mLock) {
            final String methodStr = "setEapCACert";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapCACert(path);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapCAPath(String path) {
        synchronized (mLock) {
            final String methodStr = "setEapCAPath";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapCAPath(path);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapClientCert(String path) {
        synchronized (mLock) {
            final String methodStr = "setEapClientCert";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapClientCert(path);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapPrivateKeyId(String id) {
        synchronized (mLock) {
            final String methodStr = "setEapPrivateKeyId";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapPrivateKeyId(id);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapSubjectMatch(String match) {
        synchronized (mLock) {
            final String methodStr = "setEapSubjectMatch";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapSubjectMatch(match);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapAltSubjectMatch(String match) {
        synchronized (mLock) {
            final String methodStr = "setEapAltSubjectMatch";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapAltSubjectMatch(match);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapEngine(boolean enable) {
        synchronized (mLock) {
            final String methodStr = "setEapEngine";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapEngine(enable);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapEngineID(String id) {
        synchronized (mLock) {
            final String methodStr = "setEapEngineID";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapEngineID(id);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapDomainSuffixMatch(String match) {
        synchronized (mLock) {
            final String methodStr = "setEapDomainSuffixMatch";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setEapDomainSuffixMatch(match);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapProactiveKeyCaching(boolean enable) {
        synchronized (mLock) {
            final String methodStr = "setEapProactiveKeyCaching";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setProactiveKeyCaching(enable);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setIdStr(String idString) {
        synchronized (mLock) {
            final String methodStr = "setIdStr";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.setIdStr(idString);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setSaePassword(String saePassword) {
        synchronized (mLock) {
            final String methodStr = "setSaePassword";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                        iSupplicantStaNetworkV12;

                iSupplicantStaNetworkV12 = getV1_2StaNetwork();
                if (iSupplicantStaNetworkV12 != null) {
                    /* Support for SAE Requires HAL v1.2 or higher */
                    SupplicantStatus status = iSupplicantStaNetworkV12.setSaePassword(saePassword);
                    return checkStatusAndLogFailure(status, methodStr);
                } else {
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setEapErp(boolean enable) {
        synchronized (mLock) {
            final String methodStr = "setEapErp";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
                        iSupplicantStaNetworkV13;

                iSupplicantStaNetworkV13 = getV1_3StaNetwork();
                if (iSupplicantStaNetworkV13 != null) {
                    /* Support for set ERP Requires HAL v1.3 or higher */
                    SupplicantStatus status =  iSupplicantStaNetworkV13.setEapErp(enable);
                    return checkStatusAndLogFailure(status, methodStr);
                } else {
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getSsid() {
        synchronized (mLock) {
            final String methodStr = "getSsid";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getSsid((SupplicantStatus status,
                        java.util.ArrayList<Byte> ssidValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mSsid = ssidValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getBssid() {
        synchronized (mLock) {
            final String methodStr = "getBssid";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getBssid((SupplicantStatus status,
                        byte[/* 6 */] bssidValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mBssid = bssidValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getScanSsid() {
        synchronized (mLock) {
            final String methodStr = "getScanSsid";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getScanSsid((SupplicantStatus status,
                        boolean enabledValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mScanSsid = enabledValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getKeyMgmt() {
        synchronized (mLock) {
            final String methodStr = "getKeyMgmt";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            if (getV1_3StaNetwork() != null) {
                return getKeyMgmt_1_3();
            } else {
                try {
                    MutableBoolean statusOk = new MutableBoolean(false);
                    mISupplicantStaNetwork.getKeyMgmt((SupplicantStatus status,
                            int keyMgmtMaskValue) -> {
                        statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                        if (statusOk.value) {
                            this.mKeyMgmtMask = keyMgmtMaskValue;
                        } else {
                            checkStatusAndLogFailure(status, methodStr);
                        }
                    });
                    return statusOk.value;
                } catch (RemoteException e) {
                    handleRemoteException(e, methodStr);
                    return false;
                }
            }
        }
    }

    private boolean getKeyMgmt_1_3() {
        synchronized (mLock) {
            final String methodStr = "getKeyMgmt_1_3";
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                getV1_3StaNetwork().getKeyMgmt_1_3((SupplicantStatus status,
                        int keyMgmtMaskValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mKeyMgmtMask = keyMgmtMaskValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getProto() {
        synchronized (mLock) {
            final String methodStr = "getProto";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            if (getV1_3StaNetwork() != null) {
                return getProto_1_3();
            } else {
                try {
                    MutableBoolean statusOk = new MutableBoolean(false);
                    mISupplicantStaNetwork.getProto(
                            (SupplicantStatus status, int protoMaskValue) -> {
                            statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                            if (statusOk.value) {
                                this.mProtoMask = protoMaskValue;
                            } else {
                                checkStatusAndLogFailure(status, methodStr);
                            }
                        });
                    return statusOk.value;
                } catch (RemoteException e) {
                    handleRemoteException(e, methodStr);
                    return false;
                }
            }
        }
    }

    private boolean getProto_1_3() {
        synchronized (mLock) {
            final String methodStr = "getProto_1_3";
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                getV1_3StaNetwork().getProto((SupplicantStatus status, int protoMaskValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mProtoMask = protoMaskValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getAuthAlg() {
        synchronized (mLock) {
            final String methodStr = "getAuthAlg";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            if (getV1_3StaNetwork() != null) {
                return getAuthAlg_1_3();
            }
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getAuthAlg((SupplicantStatus status,
                        int authAlgMaskValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mAuthAlgMask = authAlgMaskValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    private boolean getAuthAlg_1_3() {
        final String methodStr = "getAuthAlg_1_3";
        try {
            MutableBoolean statusOk = new MutableBoolean(false);
            getV1_3StaNetwork().getAuthAlg_1_3((SupplicantStatus status,
                    int authAlgMaskValue) -> {
                statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                if (statusOk.value) {
                    this.mAuthAlgMask = authAlgMaskValue;
                } else {
                    checkStatusAndLogFailure(status, methodStr);
                }
            });
            return statusOk.value;
        } catch (RemoteException e) {
            handleRemoteException(e, methodStr);
            return false;
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getGroupCipher() {
        synchronized (mLock) {
            final String methodStr = "getGroupCipher";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            if (getV1_3StaNetwork() != null) {
                return getGroupCipher_1_3();
            } else {
                try {
                    MutableBoolean statusOk = new MutableBoolean(false);
                    mISupplicantStaNetwork.getGroupCipher((SupplicantStatus status,
                            int groupCipherMaskValue) -> {
                        statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                        if (statusOk.value) {
                            this.mGroupCipherMask = groupCipherMaskValue;
                        } else {
                            checkStatusAndLogFailure(status, methodStr);
                        }
                    });
                    return statusOk.value;
                } catch (RemoteException e) {
                    handleRemoteException(e, methodStr);
                    return false;
                }
            }
        }
    }

    private boolean getGroupCipher_1_3() {
        synchronized (mLock) {
            final String methodStr = "getGroupCipher_1_3";
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                getV1_3StaNetwork().getGroupCipher((SupplicantStatus status,
                        int groupCipherMaskValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mGroupCipherMask = groupCipherMaskValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getPairwiseCipher() {
        synchronized (mLock) {
            final String methodStr = "getPairwiseCipher";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            if (getV1_3StaNetwork() != null) {
                return getPairwiseCipher_1_3();
            } else {
                try {
                    MutableBoolean statusOk = new MutableBoolean(false);
                    mISupplicantStaNetwork.getPairwiseCipher((SupplicantStatus status,
                            int pairwiseCipherMaskValue) -> {
                        statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                        if (statusOk.value) {
                            this.mPairwiseCipherMask = pairwiseCipherMaskValue;
                        } else {
                            checkStatusAndLogFailure(status, methodStr);
                        }
                    });
                    return statusOk.value;
                } catch (RemoteException e) {
                    handleRemoteException(e, methodStr);
                    return false;
                }
            }
        }
    }

    private boolean getPairwiseCipher_1_3() {
        synchronized (mLock) {
            final String methodStr = "getPairwiseCipher_1_3";
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                getV1_3StaNetwork().getPairwiseCipher((SupplicantStatus status,
                        int pairwiseCipherMaskValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mPairwiseCipherMask = pairwiseCipherMaskValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getGroupMgmtCipher() {
        synchronized (mLock) {
            final String methodStr = "getGroupMgmtCipher";
            android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                    iSupplicantStaNetworkV12;

            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                iSupplicantStaNetworkV12 = getV1_2StaNetwork();
                if (iSupplicantStaNetworkV12 != null) {
                    MutableBoolean statusOk = new MutableBoolean(false);
                    iSupplicantStaNetworkV12.getGroupMgmtCipher((SupplicantStatus status,
                            int groupMgmtCipherMaskValue) -> {
                        statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                        if (statusOk.value) {
                            this.mGroupMgmtCipherMask = groupMgmtCipherMaskValue;
                        }
                        checkStatusAndLogFailure(status, methodStr);
                    });
                    return statusOk.value;
                } else {
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getPskPassphrase() {
        synchronized (mLock) {
            final String methodStr = "getPskPassphrase";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getPskPassphrase((SupplicantStatus status,
                        String pskValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mPskPassphrase = pskValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getSaePassword() {
        synchronized (mLock) {
            final String methodStr = "getSaePassword";
            android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                    iSupplicantStaNetworkV12;

            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                iSupplicantStaNetworkV12 = getV1_2StaNetwork();
                if (iSupplicantStaNetworkV12 != null) {
                    MutableBoolean statusOk = new MutableBoolean(false);
                    iSupplicantStaNetworkV12.getSaePassword((SupplicantStatus status,
                            String saePassword) -> {
                        statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                        if (statusOk.value) {
                            this.mSaePassword = saePassword;
                        }
                        checkStatusAndLogFailure(status, methodStr);
                    });
                    return statusOk.value;
                } else {
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getPsk() {
        synchronized (mLock) {
            final String methodStr = "getPsk";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getPsk((SupplicantStatus status, byte[] pskValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mPsk = pskValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getWepKey(int keyIdx) {
        synchronized (mLock) {
            final String methodStr = "keyIdx";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getWepKey(keyIdx, (SupplicantStatus status,
                        java.util.ArrayList<Byte> wepKeyValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mWepKey = wepKeyValue;
                    } else {
                        Log.e(TAG, methodStr + ",  failed: " + status.debugMessage);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getWepTxKeyIdx() {
        synchronized (mLock) {
            final String methodStr = "getWepTxKeyIdx";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getWepTxKeyIdx((SupplicantStatus status,
                        int keyIdxValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mWepTxKeyIdx = keyIdxValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getRequirePmf() {
        synchronized (mLock) {
            final String methodStr = "getRequirePmf";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getRequirePmf((SupplicantStatus status,
                        boolean enabledValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mRequirePmf = enabledValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getWapiCertSuite() {
        synchronized (mLock) {
            final String methodStr = "getWapiCertSuite";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
                        iSupplicantStaNetworkV13;
                iSupplicantStaNetworkV13 = getV1_3StaNetwork();
                if (iSupplicantStaNetworkV13 != null) {
                    MutableBoolean statusOk = new MutableBoolean(false);
                    iSupplicantStaNetworkV13.getWapiCertSuite((SupplicantStatus status,
                            String suiteValue) -> {
                        statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                        if (statusOk.value) {
                            mWapiCertSuite = suiteValue;
                        } else {
                            checkStatusAndLogFailure(status, methodStr);
                        }
                    });
                    return statusOk.value;
                } else {
                    Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapMethod() {
        synchronized (mLock) {
            final String methodStr = "getEapMethod";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapMethod((SupplicantStatus status,
                        int methodValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapMethod = methodValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapPhase2Method() {
        synchronized (mLock) {
            final String methodStr = "getEapPhase2Method";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapPhase2Method((SupplicantStatus status,
                        int methodValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapPhase2Method = methodValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapIdentity() {
        synchronized (mLock) {
            final String methodStr = "getEapIdentity";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapIdentity((SupplicantStatus status,
                        ArrayList<Byte> identityValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapIdentity = identityValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapAnonymousIdentity() {
        synchronized (mLock) {
            final String methodStr = "getEapAnonymousIdentity";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapAnonymousIdentity((SupplicantStatus status,
                        ArrayList<Byte> identityValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapAnonymousIdentity = identityValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /**
     * A wrapping method for getEapAnonymousIdentity().
     * This get anonymous identity from supplicant and returns it as a string.
     *
     * @return anonymous identity string if succeeds, null otherwise.
     */
    public String fetchEapAnonymousIdentity() {
        synchronized (mLock) {
            if (!getEapAnonymousIdentity()) {
                return null;
            }
            return NativeUtil.stringFromByteArrayList(mEapAnonymousIdentity);
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapPassword() {
        synchronized (mLock) {
            final String methodStr = "getEapPassword";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapPassword((SupplicantStatus status,
                        ArrayList<Byte> passwordValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapPassword = passwordValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapCACert() {
        synchronized (mLock) {
            final String methodStr = "getEapCACert";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapCACert((SupplicantStatus status, String pathValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapCACert = pathValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapCAPath() {
        synchronized (mLock) {
            final String methodStr = "getEapCAPath";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapCAPath((SupplicantStatus status, String pathValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapCAPath = pathValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapClientCert() {
        synchronized (mLock) {
            final String methodStr = "getEapClientCert";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapClientCert((SupplicantStatus status,
                        String pathValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapClientCert = pathValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapPrivateKeyId() {
        synchronized (mLock) {
            final String methodStr = "getEapPrivateKeyId";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapPrivateKeyId((SupplicantStatus status,
                        String idValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapPrivateKeyId = idValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapSubjectMatch() {
        synchronized (mLock) {
            final String methodStr = "getEapSubjectMatch";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapSubjectMatch((SupplicantStatus status,
                        String matchValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapSubjectMatch = matchValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapAltSubjectMatch() {
        synchronized (mLock) {
            final String methodStr = "getEapAltSubjectMatch";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapAltSubjectMatch((SupplicantStatus status,
                        String matchValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapAltSubjectMatch = matchValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapEngine() {
        synchronized (mLock) {
            final String methodStr = "getEapEngine";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapEngine((SupplicantStatus status,
                        boolean enabledValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapEngine = enabledValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapEngineID() {
        synchronized (mLock) {
            final String methodStr = "getEapEngineID";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapEngineID((SupplicantStatus status, String idValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapEngineID = idValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getEapDomainSuffixMatch() {
        synchronized (mLock) {
            final String methodStr = "getEapDomainSuffixMatch";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getEapDomainSuffixMatch((SupplicantStatus status,
                        String matchValue) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mEapDomainSuffixMatch = matchValue;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getIdStr() {
        synchronized (mLock) {
            final String methodStr = "getIdStr";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                MutableBoolean statusOk = new MutableBoolean(false);
                mISupplicantStaNetwork.getIdStr((SupplicantStatus status, String idString) -> {
                    statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                    if (statusOk.value) {
                        this.mIdStr = idString;
                    } else {
                        checkStatusAndLogFailure(status, methodStr);
                    }
                });
                return statusOk.value;
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean enable(boolean noConnect) {
        synchronized (mLock) {
            final String methodStr = "enable";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.enable(noConnect);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean disable() {
        synchronized (mLock) {
            final String methodStr = "disable";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.disable();
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /**
     * Trigger a connection to this network.
     *
     * @return true if it succeeds, false otherwise.
     */
    public boolean select() {
        synchronized (mLock) {
            final String methodStr = "select";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.select();
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /**
     * Send GSM auth response.
     *
     * @param paramsStr Response params as a string.
     * @return true if succeeds, false otherwise.
     */
    public boolean sendNetworkEapSimGsmAuthResponse(String paramsStr) {
        synchronized (mLock) {
            try {
                Matcher match = GSM_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
                ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params =
                        new ArrayList<>();
                while (match.find()) {
                    if (match.groupCount() != 2) {
                        Log.e(TAG, "Malformed gsm auth response params: " + paramsStr);
                        return false;
                    }
                    ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams param =
                            new ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams();
                    byte[] kc = NativeUtil.hexStringToByteArray(match.group(1));
                    if (kc == null || kc.length != param.kc.length) {
                        Log.e(TAG, "Invalid kc value: " + match.group(1));
                        return false;
                    }
                    byte[] sres = NativeUtil.hexStringToByteArray(match.group(2));
                    if (sres == null || sres.length != param.sres.length) {
                        Log.e(TAG, "Invalid sres value: " + match.group(2));
                        return false;
                    }
                    System.arraycopy(kc, 0, param.kc, 0, param.kc.length);
                    System.arraycopy(sres, 0, param.sres, 0, param.sres.length);
                    params.add(param);
                }
                // The number of kc/sres pairs can either be 2 or 3 depending on the request.
                if (params.size() > 3 || params.size() < 2) {
                    Log.e(TAG, "Malformed gsm auth response params: " + paramsStr);
                    return false;
                }
                return sendNetworkEapSimGsmAuthResponse(params);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Illegal argument " + paramsStr, e);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean sendNetworkEapSimGsmAuthResponse(
            ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params) {
        synchronized (mLock) {
            final String methodStr = "sendNetworkEapSimGsmAuthResponse";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status =
                        mISupplicantStaNetwork.sendNetworkEapSimGsmAuthResponse(params);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    public boolean sendNetworkEapSimGsmAuthFailure() {
        synchronized (mLock) {
            final String methodStr = "sendNetworkEapSimGsmAuthFailure";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimGsmAuthFailure();
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /**
     * Send UMTS auth response.
     *
     * @param paramsStr Response params as a string.
     * @return true if succeeds, false otherwise.
     */
    public boolean sendNetworkEapSimUmtsAuthResponse(String paramsStr) {
        synchronized (mLock) {
            try {
                Matcher match = UMTS_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
                if (!match.find() || match.groupCount() != 3) {
                    Log.e(TAG, "Malformed umts auth response params: " + paramsStr);
                    return false;
                }
                ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params =
                        new ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams();
                byte[] ik = NativeUtil.hexStringToByteArray(match.group(1));
                if (ik == null || ik.length != params.ik.length) {
                    Log.e(TAG, "Invalid ik value: " + match.group(1));
                    return false;
                }
                byte[] ck = NativeUtil.hexStringToByteArray(match.group(2));
                if (ck == null || ck.length != params.ck.length) {
                    Log.e(TAG, "Invalid ck value: " + match.group(2));
                    return false;
                }
                byte[] res = NativeUtil.hexStringToByteArray(match.group(3));
                if (res == null || res.length == 0) {
                    Log.e(TAG, "Invalid res value: " + match.group(3));
                    return false;
                }
                System.arraycopy(ik, 0, params.ik, 0, params.ik.length);
                System.arraycopy(ck, 0, params.ck, 0, params.ck.length);
                for (byte b : res) {
                    params.res.add(b);
                }
                return sendNetworkEapSimUmtsAuthResponse(params);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Illegal argument " + paramsStr, e);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean sendNetworkEapSimUmtsAuthResponse(
            ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params) {
        synchronized (mLock) {
            final String methodStr = "sendNetworkEapSimUmtsAuthResponse";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status =
                        mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthResponse(params);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /**
     * Send UMTS auts response.
     *
     * @param paramsStr Response params as a string.
     * @return true if succeeds, false otherwise.
     */
    public boolean sendNetworkEapSimUmtsAutsResponse(String paramsStr) {
        synchronized (mLock) {
            try {
                Matcher match = UMTS_AUTS_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
                if (!match.find() || match.groupCount() != 1) {
                    Log.e(TAG, "Malformed umts auts response params: " + paramsStr);
                    return false;
                }
                byte[] auts = NativeUtil.hexStringToByteArray(match.group(1));
                if (auts == null || auts.length != 14) {
                    Log.e(TAG, "Invalid auts value: " + match.group(1));
                    return false;
                }
                return sendNetworkEapSimUmtsAutsResponse(auts);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Illegal argument " + paramsStr, e);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean sendNetworkEapSimUmtsAutsResponse(byte[/* 14 */] auts) {
        synchronized (mLock) {
            final String methodStr = "sendNetworkEapSimUmtsAutsResponse";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status =
                        mISupplicantStaNetwork.sendNetworkEapSimUmtsAutsResponse(auts);
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    public boolean sendNetworkEapSimUmtsAuthFailure() {
        synchronized (mLock) {
            final String methodStr = "sendNetworkEapSimUmtsAuthFailure";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthFailure();
                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /**
     * Method to mock out the V1_1 ISupplicantStaNetwork retrieval in unit tests.
     *
     * @return 1.1 ISupplicantStaNetwork object if the device is running the 1.1 supplicant hal
     * service, null otherwise.
     */
    protected android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork
    getSupplicantStaNetworkForV1_1Mockable() {
        if (mISupplicantStaNetwork == null) return null;
        return android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork.castFrom(
                mISupplicantStaNetwork);
    }

    /**
     * Method to mock out the V1_2 ISupplicantStaNetwork retrieval in unit tests.
     *
     * @return 1.2 ISupplicantStaNetwork object if the device is running the 1.2 supplicant hal
     * service, null otherwise.
     */
    protected android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
            getSupplicantStaNetworkForV1_2Mockable() {
        if (mISupplicantStaNetwork == null) return null;
        return android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.castFrom(
                mISupplicantStaNetwork);
    }

    /**
     * Method to mock out the V1_3 ISupplicantStaNetwork retrieval in unit tests.
     *
     * @return 1.3 ISupplicantStaNetwork object if the device is running the 1.3 supplicant hal
     * service, null otherwise.
     */
    protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
            getSupplicantStaNetworkForV1_3Mockable() {
        if (mISupplicantStaNetwork == null) return null;
        return android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.castFrom(
                mISupplicantStaNetwork);
    }

    /**
     * Send eap identity response.
     *
     * @param identityStr          identity used for EAP-Identity
     * @param encryptedIdentityStr encrypted identity used for EAP-AKA/EAP-SIM
     * @return true if succeeds, false otherwise.
     */
    public boolean sendNetworkEapIdentityResponse(String identityStr,
            String encryptedIdentityStr) {
        synchronized (mLock) {
            try {
                ArrayList<Byte> unencryptedIdentity =
                        NativeUtil.stringToByteArrayList(identityStr);
                ArrayList<Byte> encryptedIdentity = null;
                if (!TextUtils.isEmpty(encryptedIdentityStr)) {
                    encryptedIdentity = NativeUtil.stringToByteArrayList(encryptedIdentityStr);
                }
                return sendNetworkEapIdentityResponse(unencryptedIdentity, encryptedIdentity);
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "Illegal argument " + identityStr + "," + encryptedIdentityStr, e);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean sendNetworkEapIdentityResponse(ArrayList<Byte> unencryptedIdentity,
            ArrayList<Byte> encryptedIdentity) {
        synchronized (mLock) {
            final String methodStr = "sendNetworkEapIdentityResponse";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
            try {
                SupplicantStatus status;
                android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork
                        iSupplicantStaNetworkV11 =
                        getSupplicantStaNetworkForV1_1Mockable();

                if (iSupplicantStaNetworkV11 != null && encryptedIdentity != null) {
                    status = iSupplicantStaNetworkV11.sendNetworkEapIdentityResponse_1_1(
                            unencryptedIdentity, encryptedIdentity);
                } else {
                    status = mISupplicantStaNetwork.sendNetworkEapIdentityResponse(
                            unencryptedIdentity);
                }

                return checkStatusAndLogFailure(status, methodStr);
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean setOcsp(@Ocsp int ocsp) {
        synchronized (mLock) {
            final String methodStr = "setOcsp";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;

            int halOcspValue = android.hardware.wifi.supplicant.V1_3.OcspType.NONE;
            switch (ocsp) {
                case WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS:
                    halOcspValue = android.hardware.wifi.supplicant.V1_3
                            .OcspType.REQUEST_CERT_STATUS;
                    break;
                case WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS:
                    halOcspValue = android.hardware.wifi.supplicant.V1_3
                            .OcspType.REQUIRE_CERT_STATUS;
                    break;
                case WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS:
                    halOcspValue = android.hardware.wifi.supplicant.V1_3
                            .OcspType.REQUIRE_ALL_CERTS_STATUS;
                    break;
            }
            try {
                android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
                        iSupplicantStaNetworkV13;

                iSupplicantStaNetworkV13 = getV1_3StaNetwork();
                if (iSupplicantStaNetworkV13 != null) {
                    /* Support for OCSP Requires HAL v1.3 or higher */
                    SupplicantStatus status = iSupplicantStaNetworkV13
                            .setOcsp(halOcspValue);
                    return checkStatusAndLogFailure(status, methodStr);
                } else {
                    Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private boolean getOcsp() {
        synchronized (mLock) {
            final String methodStr = "getOcsp";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;

            try {
                android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
                        iSupplicantStaNetworkV13;
                iSupplicantStaNetworkV13 = getV1_3StaNetwork();
                if (iSupplicantStaNetworkV13 != null) {
                    MutableBoolean statusOk = new MutableBoolean(false);
                    iSupplicantStaNetworkV13.getOcsp((SupplicantStatus status,
                            int halOcspValue) -> {
                        statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
                        if (statusOk.value) {
                            mOcsp = WifiEnterpriseConfig.OCSP_NONE;
                            switch (halOcspValue) {
                                case android.hardware.wifi.supplicant.V1_3
                                        .OcspType.REQUEST_CERT_STATUS:
                                    mOcsp = WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS;
                                    break;
                                case android.hardware.wifi.supplicant.V1_3
                                        .OcspType.REQUIRE_CERT_STATUS:
                                    mOcsp = WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS;
                                    break;
                                case android.hardware.wifi.supplicant.V1_3
                                        .OcspType.REQUIRE_ALL_CERTS_STATUS:
                                    mOcsp = WifiEnterpriseConfig
                                            .OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS;
                                    break;
                                default:
                                    Log.e(TAG, "Invalid HAL OCSP value " + halOcspValue);
                                    break;
                            }
                        } else {
                            checkStatusAndLogFailure(status, methodStr);
                        }
                    });
                    return statusOk.value;
                } else {
                    Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    public boolean setPmkCache(ArrayList<Byte> serializedEntry) {
        synchronized (mLock) {
            final String methodStr = "setPmkCache";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;

            try {
                android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
                        iSupplicantStaNetworkV13;

                iSupplicantStaNetworkV13 = getV1_3StaNetwork();
                if (iSupplicantStaNetworkV13 != null) {
                    SupplicantStatus status = iSupplicantStaNetworkV13
                            .setPmkCache(serializedEntry);
                    return checkStatusAndLogFailure(status, methodStr);
                } else {
                    Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
                    return false;
                }
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
                return false;
            }
        }
    }

    /**
     * Retrieve the NFC token for this network.
     *
     * @return Hex string corresponding to the NFC token or null for failure.
     */
    public String getWpsNfcConfigurationToken() {
        synchronized (mLock) {
            ArrayList<Byte> token = getWpsNfcConfigurationTokenInternal();
            if (token == null) {
                return null;
            }
            return NativeUtil.hexStringFromByteArray(NativeUtil.byteArrayFromArrayList(token));
        }
    }

    /** See ISupplicantStaNetwork.hal for documentation */
    private ArrayList<Byte> getWpsNfcConfigurationTokenInternal() {
        synchronized (mLock) {
            final String methodStr = "getWpsNfcConfigurationToken";
            if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return null;
            final Mutable<ArrayList<Byte>> gotToken = new Mutable<>();
            try {
                mISupplicantStaNetwork.getWpsNfcConfigurationToken(
                        (SupplicantStatus status, ArrayList<Byte> token) -> {
                            if (checkStatusAndLogFailure(status, methodStr)) {
                                gotToken.value = token;
                            }
                        });
            } catch (RemoteException e) {
                handleRemoteException(e, methodStr);
            }
            return gotToken.value;
        }
    }

    /**
     * Returns true if provided status code is SUCCESS, logs debug message and returns false
     * otherwise
     */
    private boolean checkStatusAndLogFailure(SupplicantStatus status, final String methodStr) {
        synchronized (mLock) {
            if (status.code != SupplicantStatusCode.SUCCESS) {
                Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + status);
                return false;
            } else {
                if (mVerboseLoggingEnabled) {
                    Log.d(TAG, "ISupplicantStaNetwork." + methodStr + " succeeded");
                }
                return true;
            }
        }
    }

    /**
     * Helper function to log callbacks.
     */
    private void logCallback(final String methodStr) {
        synchronized (mLock) {
            if (mVerboseLoggingEnabled) {
                Log.d(TAG, "ISupplicantStaNetworkCallback." + methodStr + " received");
            }
        }
    }

    /**
     * Returns false if ISupplicantStaNetwork is null, and logs failure of methodStr
     */
    private boolean checkISupplicantStaNetworkAndLogFailure(final String methodStr) {
        synchronized (mLock) {
            if (mISupplicantStaNetwork == null) {
                Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaNetwork is null");
                return false;
            }
            return true;
        }
    }

    private void handleRemoteException(RemoteException e, String methodStr) {
        synchronized (mLock) {
            mISupplicantStaNetwork = null;
            Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed with exception", e);
        }
    }

    /**
     * Adds FT flags for networks if the device supports it.
     */
    private BitSet addFastTransitionFlags(BitSet keyManagementFlags) {
        synchronized (mLock) {
            if (!mContext.getResources().getBoolean(
                    R.bool.config_wifi_fast_bss_transition_enabled)) {
                return keyManagementFlags;
            }
            BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
            if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
                modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_PSK);
            }
            if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
                modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_EAP);
            }
            return modifiedFlags;
        }
    }

    /**
     * Removes FT flags for networks if the device supports it.
     */
    private BitSet removeFastTransitionFlags(BitSet keyManagementFlags) {
        synchronized (mLock) {
            BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
            modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_PSK);
            modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_EAP);
            return modifiedFlags;
        }
    }

     /**
     * Adds SHA256 key management flags for networks.
     */
    private BitSet addSha256KeyMgmtFlags(BitSet keyManagementFlags) {
        synchronized (mLock) {
            BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
            android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
                    iSupplicantStaNetworkV12;
            iSupplicantStaNetworkV12 = getV1_2StaNetwork();
            if (iSupplicantStaNetworkV12 == null) {
                // SHA256 key management requires HALv1.2 or higher
                return modifiedFlags;
            }

            if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
                modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
            }
            if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
                modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
            }
            return modifiedFlags;
        }
    }

    /**
     * Removes SHA256 key management flags for networks.
     */
    private BitSet removeSha256KeyMgmtFlags(BitSet keyManagementFlags) {
        synchronized (mLock) {
            BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
            modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
            modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
            return modifiedFlags;
        }
    }

    /**
     * Creates the JSON encoded network extra using the map of string key, value pairs.
     */
    public static String createNetworkExtra(Map<String, String> values) {
        final String encoded;
        try {
            encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8");
        } catch (NullPointerException e) {
            Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
            return null;
        } catch (UnsupportedEncodingException e) {
            Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
            return null;
        }
        return encoded;
    }

    /**
     * Parse the network extra JSON encoded string to a map of string key, value pairs.
     */
    public static Map<String, String> parseNetworkExtra(String encoded) {
        if (TextUtils.isEmpty(encoded)) {
            return null;
        }
        try {
            // This method reads a JSON dictionary that was written by setNetworkExtra(). However,
            // on devices that upgraded from Marshmallow, it may encounter a legacy value instead -
            // an FQDN stored as a plain string. If such a value is encountered, the JSONObject
            // constructor will thrown a JSONException and the method will return null.
            final JSONObject json = new JSONObject(URLDecoder.decode(encoded, "UTF-8"));
            final Map<String, String> values = new HashMap<>();
            final Iterator<?> it = json.keys();
            while (it.hasNext()) {
                final String key = (String) it.next();
                final Object value = json.get(key);
                if (value instanceof String) {
                    values.put(key, (String) value);
                }
            }
            return values;
        } catch (UnsupportedEncodingException e) {
            Log.e(TAG, "Unable to deserialize networkExtra: " + e.toString());
            return null;
        } catch (JSONException e) {
            // This is not necessarily an error. This exception will also occur if we encounter a
            // legacy FQDN stored as a plain string. We want to return null in this case as no JSON
            // dictionary of extras was found.
            return null;
        }
    }

    private class SupplicantStaNetworkHalCallback extends ISupplicantStaNetworkCallback.Stub {
        /**
         * Current configured network's framework network id.
         */
        private final int mFramewokNetworkId;
        /**
         * Current configured network's ssid.
         */
        private final String mSsid;

        SupplicantStaNetworkHalCallback(int framewokNetworkId, String ssid) {
            mFramewokNetworkId = framewokNetworkId;
            mSsid = ssid;
        }

        @Override
        public void onNetworkEapSimGsmAuthRequest(
                ISupplicantStaNetworkCallback.NetworkRequestEapSimGsmAuthParams params) {
            synchronized (mLock) {
                logCallback("onNetworkEapSimGsmAuthRequest");
                String[] data = new String[params.rands.size()];
                int i = 0;
                for (byte[] rand : params.rands) {
                    data[i++] = NativeUtil.hexStringFromByteArray(rand);
                }
                mWifiMonitor.broadcastNetworkGsmAuthRequestEvent(
                        mIfaceName, mFramewokNetworkId, mSsid, data);
            }
        }

        @Override
        public void onNetworkEapSimUmtsAuthRequest(
                ISupplicantStaNetworkCallback.NetworkRequestEapSimUmtsAuthParams params) {
            synchronized (mLock) {
                logCallback("onNetworkEapSimUmtsAuthRequest");
                String randHex = NativeUtil.hexStringFromByteArray(params.rand);
                String autnHex = NativeUtil.hexStringFromByteArray(params.autn);
                String[] data = {randHex, autnHex};
                mWifiMonitor.broadcastNetworkUmtsAuthRequestEvent(
                        mIfaceName, mFramewokNetworkId, mSsid, data);
            }
        }

        @Override
        public void onNetworkEapIdentityRequest() {
            synchronized (mLock) {
                logCallback("onNetworkEapIdentityRequest");
                mWifiMonitor.broadcastNetworkIdentityRequestEvent(
                        mIfaceName, mFramewokNetworkId, mSsid);
            }
        }
    }
}
