Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.server.wifi;
     17 
     18 import android.content.Context;
     19 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork;
     20 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetworkCallback;
     21 import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
     22 import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
     23 import android.net.wifi.WifiConfiguration;
     24 import android.net.wifi.WifiEnterpriseConfig;
     25 import android.os.HidlSupport.Mutable;
     26 import android.os.RemoteException;
     27 import android.text.TextUtils;
     28 import android.util.Log;
     29 import android.util.MutableBoolean;
     30 
     31 import com.android.internal.R;
     32 import com.android.internal.annotations.VisibleForTesting;
     33 import com.android.internal.util.ArrayUtils;
     34 import com.android.server.wifi.util.NativeUtil;
     35 
     36 import org.json.JSONException;
     37 import org.json.JSONObject;
     38 
     39 import java.io.UnsupportedEncodingException;
     40 import java.net.URLDecoder;
     41 import java.net.URLEncoder;
     42 import java.util.ArrayList;
     43 import java.util.BitSet;
     44 import java.util.HashMap;
     45 import java.util.Iterator;
     46 import java.util.Map;
     47 import java.util.regex.Matcher;
     48 import java.util.regex.Pattern;
     49 
     50 import javax.annotation.concurrent.ThreadSafe;
     51 
     52 
     53 /**
     54  * Wrapper class for ISupplicantStaNetwork HAL calls. Gets and sets supplicant sta network variables
     55  * and interacts with networks.
     56  * Public fields should be treated as invalid until their 'get' method is called, which will set the
     57  * value if it returns true
     58  * To maintain thread-safety, the locking protocol is that every non-static method (regardless of
     59  * access level) acquires mLock.
     60  */
     61 @ThreadSafe
     62 public class SupplicantStaNetworkHal {
     63     private static final String TAG = "SupplicantStaNetworkHal";
     64     @VisibleForTesting
     65     public static final String ID_STRING_KEY_FQDN = "fqdn";
     66     @VisibleForTesting
     67     public static final String ID_STRING_KEY_CREATOR_UID = "creatorUid";
     68     @VisibleForTesting
     69     public static final String ID_STRING_KEY_CONFIG_KEY = "configKey";
     70 
     71     /**
     72      * Regex pattern for extracting the GSM sim authentication response params from a string.
     73      * Matches a strings like the following: "[:<kc_value>:<sres_value>]";
     74      */
     75     private static final Pattern GSM_AUTH_RESPONSE_PARAMS_PATTERN =
     76             Pattern.compile(":([0-9a-fA-F]+):([0-9a-fA-F]+)");
     77     /**
     78      * Regex pattern for extracting the UMTS sim authentication response params from a string.
     79      * Matches a strings like the following: ":<ik_value>:<ck_value>:<res_value>";
     80      */
     81     private static final Pattern UMTS_AUTH_RESPONSE_PARAMS_PATTERN =
     82             Pattern.compile("^:([0-9a-fA-F]+):([0-9a-fA-F]+):([0-9a-fA-F]+)$");
     83     /**
     84      * Regex pattern for extracting the UMTS sim auts response params from a string.
     85      * Matches a strings like the following: ":<auts_value>";
     86      */
     87     private static final Pattern UMTS_AUTS_RESPONSE_PARAMS_PATTERN =
     88             Pattern.compile("^:([0-9a-fA-F]+)$");
     89 
     90     private final Object mLock = new Object();
     91     private final String mIfaceName;
     92     private final WifiMonitor mWifiMonitor;
     93     private ISupplicantStaNetwork mISupplicantStaNetwork;
     94     private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback;
     95 
     96     private boolean mVerboseLoggingEnabled = false;
     97     // Indicates whether the system is capable of 802.11r fast BSS transition.
     98     private boolean mSystemSupportsFastBssTransition = false;
     99 
    100     // Network variables read from wpa_supplicant.
    101     private int mNetworkId;
    102     private ArrayList<Byte> mSsid;
    103     private byte[/* 6 */] mBssid;
    104     private boolean mScanSsid;
    105     private int mKeyMgmtMask;
    106     private int mProtoMask;
    107     private int mAuthAlgMask;
    108     private int mGroupCipherMask;
    109     private int mPairwiseCipherMask;
    110     private String mPskPassphrase;
    111     private byte[] mPsk;
    112     private ArrayList<Byte> mWepKey;
    113     private int mWepTxKeyIdx;
    114     private boolean mRequirePmf;
    115     private String mIdStr;
    116     private int mEapMethod;
    117     private int mEapPhase2Method;
    118     private ArrayList<Byte> mEapIdentity;
    119     private ArrayList<Byte> mEapAnonymousIdentity;
    120     private ArrayList<Byte> mEapPassword;
    121     private String mEapCACert;
    122     private String mEapCAPath;
    123     private String mEapClientCert;
    124     private String mEapPrivateKeyId;
    125     private String mEapSubjectMatch;
    126     private String mEapAltSubjectMatch;
    127     private boolean mEapEngine;
    128     private String mEapEngineID;
    129     private String mEapDomainSuffixMatch;
    130 
    131     SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork, String ifaceName,
    132                             Context context, WifiMonitor monitor) {
    133         mISupplicantStaNetwork = iSupplicantStaNetwork;
    134         mIfaceName = ifaceName;
    135         mWifiMonitor = monitor;
    136         mSystemSupportsFastBssTransition =
    137                 context.getResources().getBoolean(R.bool.config_wifi_fast_bss_transition_enabled);
    138     }
    139 
    140     /**
    141      * Enable/Disable verbose logging.
    142      *
    143      * @param enable true to enable, false to disable.
    144      */
    145     void enableVerboseLogging(boolean enable) {
    146         synchronized (mLock) {
    147             mVerboseLoggingEnabled = enable;
    148         }
    149     }
    150 
    151     /**
    152      * Read network variables from wpa_supplicant into the provided WifiConfiguration object.
    153      *
    154      * @param config        WifiConfiguration object to be populated.
    155      * @param networkExtras Map of network extras parsed from wpa_supplicant.
    156      * @return true if succeeds, false otherwise.
    157      * @throws IllegalArgumentException on malformed configuration params.
    158      */
    159     public boolean loadWifiConfiguration(WifiConfiguration config,
    160                                          Map<String, String> networkExtras) {
    161         synchronized (mLock) {
    162             if (config == null) return false;
    163             /** SSID */
    164             config.SSID = null;
    165             if (getSsid() && !ArrayUtils.isEmpty(mSsid)) {
    166                 config.SSID = NativeUtil.encodeSsid(mSsid);
    167             } else {
    168                 Log.e(TAG, "failed to read ssid");
    169                 return false;
    170             }
    171             /** Network Id */
    172             config.networkId = -1;
    173             if (getId()) {
    174                 config.networkId = mNetworkId;
    175             } else {
    176                 Log.e(TAG, "getId failed");
    177                 return false;
    178             }
    179             /** BSSID */
    180             config.getNetworkSelectionStatus().setNetworkSelectionBSSID(null);
    181             if (getBssid() && !ArrayUtils.isEmpty(mBssid)) {
    182                 config.getNetworkSelectionStatus().setNetworkSelectionBSSID(
    183                         NativeUtil.macAddressFromByteArray(mBssid));
    184             }
    185             /** Scan SSID (Is Hidden Network?) */
    186             config.hiddenSSID = false;
    187             if (getScanSsid()) {
    188                 config.hiddenSSID = mScanSsid;
    189             }
    190             /** Require PMF*/
    191             config.requirePMF = false;
    192             if (getRequirePmf()) {
    193                 config.requirePMF = mRequirePmf;
    194             }
    195             /** WEP keys **/
    196             config.wepTxKeyIndex = -1;
    197             if (getWepTxKeyIdx()) {
    198                 config.wepTxKeyIndex = mWepTxKeyIdx;
    199             }
    200             for (int i = 0; i < 4; i++) {
    201                 config.wepKeys[i] = null;
    202                 if (getWepKey(i) && !ArrayUtils.isEmpty(mWepKey)) {
    203                     config.wepKeys[i] = NativeUtil.bytesToHexOrQuotedString(mWepKey);
    204                 }
    205             }
    206             /** PSK pass phrase */
    207             config.preSharedKey = null;
    208             if (getPskPassphrase() && !TextUtils.isEmpty(mPskPassphrase)) {
    209                 config.preSharedKey = NativeUtil.addEnclosingQuotes(mPskPassphrase);
    210             } else if (getPsk() && !ArrayUtils.isEmpty(mPsk)) {
    211                 config.preSharedKey = NativeUtil.hexStringFromByteArray(mPsk);
    212             }
    213             /** allowedKeyManagement */
    214             if (getKeyMgmt()) {
    215                 BitSet keyMgmtMask = supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask);
    216                 config.allowedKeyManagement = removeFastTransitionFlags(keyMgmtMask);
    217             }
    218             /** allowedProtocols */
    219             if (getProto()) {
    220                 config.allowedProtocols =
    221                         supplicantToWifiConfigurationProtoMask(mProtoMask);
    222             }
    223             /** allowedAuthAlgorithms */
    224             if (getAuthAlg()) {
    225                 config.allowedAuthAlgorithms =
    226                         supplicantToWifiConfigurationAuthAlgMask(mAuthAlgMask);
    227             }
    228             /** allowedGroupCiphers */
    229             if (getGroupCipher()) {
    230                 config.allowedGroupCiphers =
    231                         supplicantToWifiConfigurationGroupCipherMask(mGroupCipherMask);
    232             }
    233             /** allowedPairwiseCiphers */
    234             if (getPairwiseCipher()) {
    235                 config.allowedPairwiseCiphers =
    236                         supplicantToWifiConfigurationPairwiseCipherMask(mPairwiseCipherMask);
    237             }
    238             /** metadata: idstr */
    239             if (getIdStr() && !TextUtils.isEmpty(mIdStr)) {
    240                 Map<String, String> metadata = parseNetworkExtra(mIdStr);
    241                 networkExtras.putAll(metadata);
    242             } else {
    243                 Log.w(TAG, "getIdStr failed or empty");
    244             }
    245             return loadWifiEnterpriseConfig(config.SSID, config.enterpriseConfig);
    246         }
    247     }
    248 
    249     /**
    250      * Save an entire WifiConfiguration to wpa_supplicant via HIDL.
    251      *
    252      * @param config WifiConfiguration object to be saved.
    253      * @return true if succeeds, false otherwise.
    254      * @throws IllegalArgumentException on malformed configuration params.
    255      */
    256     public boolean saveWifiConfiguration(WifiConfiguration config) {
    257         synchronized (mLock) {
    258             if (config == null) return false;
    259             /** SSID */
    260             if (config.SSID != null) {
    261                 if (!setSsid(NativeUtil.decodeSsid(config.SSID))) {
    262                     Log.e(TAG, "failed to set SSID: " + config.SSID);
    263                     return false;
    264                 }
    265             }
    266             /** BSSID */
    267             String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
    268             if (bssidStr != null) {
    269                 byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr);
    270                 if (!setBssid(bssid)) {
    271                     Log.e(TAG, "failed to set BSSID: " + bssidStr);
    272                     return false;
    273                 }
    274             }
    275             /** Pre Shared Key */
    276             // This can either be quoted ASCII passphrase or hex string for raw psk.
    277             if (config.preSharedKey != null) {
    278                 if (config.preSharedKey.startsWith("\"")) {
    279                     if (!setPskPassphrase(NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
    280                         Log.e(TAG, "failed to set psk passphrase");
    281                         return false;
    282                     }
    283                 } else {
    284                     if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) {
    285                         Log.e(TAG, "failed to set psk");
    286                         return false;
    287                     }
    288                 }
    289             }
    290 
    291             /** Wep Keys */
    292             boolean hasSetKey = false;
    293             if (config.wepKeys != null) {
    294                 for (int i = 0; i < config.wepKeys.length; i++) {
    295                     if (config.wepKeys[i] != null) {
    296                         if (!setWepKey(
    297                                 i, NativeUtil.hexOrQuotedStringToBytes(config.wepKeys[i]))) {
    298                             Log.e(TAG, "failed to set wep_key " + i);
    299                             return false;
    300                         }
    301                         hasSetKey = true;
    302                     }
    303                 }
    304             }
    305             /** Wep Tx Key Idx */
    306             if (hasSetKey) {
    307                 if (!setWepTxKeyIdx(config.wepTxKeyIndex)) {
    308                     Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
    309                     return false;
    310                 }
    311             }
    312             /** HiddenSSID */
    313             if (!setScanSsid(config.hiddenSSID)) {
    314                 Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID);
    315                 return false;
    316             }
    317             /** RequirePMF */
    318             if (!setRequirePmf(config.requirePMF)) {
    319                 Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePMF);
    320                 return false;
    321             }
    322             /** Key Management Scheme */
    323             if (config.allowedKeyManagement.cardinality() != 0) {
    324                 // Add FT flags if supported.
    325                 BitSet keyMgmtMask = addFastTransitionFlags(config.allowedKeyManagement);
    326                 if (!setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(keyMgmtMask))) {
    327                     Log.e(TAG, "failed to set Key Management");
    328                     return false;
    329                 }
    330             }
    331             /** Security Protocol */
    332             if (config.allowedProtocols.cardinality() != 0
    333                     && !setProto(wifiConfigurationToSupplicantProtoMask(config.allowedProtocols))) {
    334                 Log.e(TAG, "failed to set Security Protocol");
    335                 return false;
    336             }
    337             /** Auth Algorithm */
    338             if (config.allowedAuthAlgorithms.cardinality() != 0
    339                     && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask(
    340                     config.allowedAuthAlgorithms))) {
    341                 Log.e(TAG, "failed to set AuthAlgorithm");
    342                 return false;
    343             }
    344             /** Group Cipher */
    345             if (config.allowedGroupCiphers.cardinality() != 0
    346                     && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
    347                     config.allowedGroupCiphers))) {
    348                 Log.e(TAG, "failed to set Group Cipher");
    349                 return false;
    350             }
    351             /** Pairwise Cipher*/
    352             if (config.allowedPairwiseCiphers.cardinality() != 0
    353                     && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
    354                     config.allowedPairwiseCiphers))) {
    355                 Log.e(TAG, "failed to set PairwiseCipher");
    356                 return false;
    357             }
    358             /** metadata: FQDN + ConfigKey + CreatorUid */
    359             final Map<String, String> metadata = new HashMap<String, String>();
    360             if (config.isPasspoint()) {
    361                 metadata.put(ID_STRING_KEY_FQDN, config.FQDN);
    362             }
    363             metadata.put(ID_STRING_KEY_CONFIG_KEY, config.configKey());
    364             metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid));
    365             if (!setIdStr(createNetworkExtra(metadata))) {
    366                 Log.e(TAG, "failed to set id string");
    367                 return false;
    368             }
    369             /** UpdateIdentifier */
    370             if (config.updateIdentifier != null
    371                     && !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) {
    372                 Log.e(TAG, "failed to set update identifier");
    373                 return false;
    374             }
    375             // Finish here if no EAP config to set
    376             if (config.enterpriseConfig != null
    377                     && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
    378                 if (!saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig)) {
    379                     return false;
    380                 }
    381             }
    382 
    383             // Now that the network is configured fully, start listening for callback events.
    384             mISupplicantStaNetworkCallback =
    385                     new SupplicantStaNetworkHalCallback(config.networkId, config.SSID);
    386             if (!registerCallback(mISupplicantStaNetworkCallback)) {
    387                 Log.e(TAG, "Failed to register callback");
    388                 return false;
    389             }
    390             return true;
    391         }
    392     }
    393 
    394     /**
    395      * Read network variables from wpa_supplicant into the provided WifiEnterpriseConfig object.
    396      *
    397      * @param ssid SSID of the network. (Used for logging purposes only)
    398      * @param eapConfig WifiEnterpriseConfig object to be populated.
    399      * @return true if succeeds, false otherwise.
    400      */
    401     private boolean loadWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) {
    402         synchronized (mLock) {
    403             if (eapConfig == null) return false;
    404             /** EAP method */
    405             if (getEapMethod()) {
    406                 eapConfig.setEapMethod(supplicantToWifiConfigurationEapMethod(mEapMethod));
    407             } else {
    408                 // Invalid eap method could be because it's not an enterprise config.
    409                 Log.e(TAG, "failed to get eap method. Assumimg not an enterprise network");
    410                 return true;
    411             }
    412             /** EAP Phase 2 method */
    413             if (getEapPhase2Method()) {
    414                 eapConfig.setPhase2Method(
    415                         supplicantToWifiConfigurationEapPhase2Method(mEapPhase2Method));
    416             } else {
    417                 // We cannot have an invalid eap phase 2 method. Return failure.
    418                 Log.e(TAG, "failed to get eap phase2 method");
    419                 return false;
    420             }
    421             /** EAP Identity */
    422             if (getEapIdentity() && !ArrayUtils.isEmpty(mEapIdentity)) {
    423                 eapConfig.setFieldValue(
    424                         WifiEnterpriseConfig.IDENTITY_KEY,
    425                         NativeUtil.stringFromByteArrayList(mEapIdentity));
    426             }
    427             /** EAP Anonymous Identity */
    428             if (getEapAnonymousIdentity() && !ArrayUtils.isEmpty(mEapAnonymousIdentity)) {
    429                 eapConfig.setFieldValue(
    430                         WifiEnterpriseConfig.ANON_IDENTITY_KEY,
    431                         NativeUtil.stringFromByteArrayList(mEapAnonymousIdentity));
    432             }
    433             /** EAP Password */
    434             if (getEapPassword() && !ArrayUtils.isEmpty(mEapPassword)) {
    435                 eapConfig.setFieldValue(
    436                         WifiEnterpriseConfig.PASSWORD_KEY,
    437                         NativeUtil.stringFromByteArrayList(mEapPassword));
    438             }
    439             /** EAP Client Cert */
    440             if (getEapClientCert() && !TextUtils.isEmpty(mEapClientCert)) {
    441                 eapConfig.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, mEapClientCert);
    442             }
    443             /** EAP CA Cert */
    444             if (getEapCACert() && !TextUtils.isEmpty(mEapCACert)) {
    445                 eapConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, mEapCACert);
    446             }
    447             /** EAP Subject Match */
    448             if (getEapSubjectMatch() && !TextUtils.isEmpty(mEapSubjectMatch)) {
    449                 eapConfig.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, mEapSubjectMatch);
    450             }
    451             /** EAP Engine ID */
    452             if (getEapEngineID() && !TextUtils.isEmpty(mEapEngineID)) {
    453                 eapConfig.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, mEapEngineID);
    454             }
    455             /** EAP Engine. Set this only if the engine id is non null. */
    456             if (getEapEngine() && !TextUtils.isEmpty(mEapEngineID)) {
    457                 eapConfig.setFieldValue(
    458                         WifiEnterpriseConfig.ENGINE_KEY,
    459                         mEapEngine
    460                                 ? WifiEnterpriseConfig.ENGINE_ENABLE
    461                                 : WifiEnterpriseConfig.ENGINE_DISABLE);
    462             }
    463             /** EAP Private Key */
    464             if (getEapPrivateKeyId() && !TextUtils.isEmpty(mEapPrivateKeyId)) {
    465                 eapConfig.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, mEapPrivateKeyId);
    466             }
    467             /** EAP Alt Subject Match */
    468             if (getEapAltSubjectMatch() && !TextUtils.isEmpty(mEapAltSubjectMatch)) {
    469                 eapConfig.setFieldValue(
    470                         WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, mEapAltSubjectMatch);
    471             }
    472             /** EAP Domain Suffix Match */
    473             if (getEapDomainSuffixMatch() && !TextUtils.isEmpty(mEapDomainSuffixMatch)) {
    474                 eapConfig.setFieldValue(
    475                         WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, mEapDomainSuffixMatch);
    476             }
    477             /** EAP CA Path*/
    478             if (getEapCAPath() && !TextUtils.isEmpty(mEapCAPath)) {
    479                 eapConfig.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, mEapCAPath);
    480             }
    481             return true;
    482         }
    483     }
    484 
    485     /**
    486      * Save network variables from the provided WifiEnterpriseConfig object to wpa_supplicant.
    487      *
    488      * @param ssid SSID of the network. (Used for logging purposes only)
    489      * @param eapConfig WifiEnterpriseConfig object to be saved.
    490      * @return true if succeeds, false otherwise.
    491      */
    492     private boolean saveWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) {
    493         synchronized (mLock) {
    494             if (eapConfig == null) return false;
    495             /** EAP method */
    496             if (!setEapMethod(wifiConfigurationToSupplicantEapMethod(eapConfig.getEapMethod()))) {
    497                 Log.e(TAG, ssid + ": failed to set eap method: " + eapConfig.getEapMethod());
    498                 return false;
    499             }
    500             /** EAP Phase 2 method */
    501             if (!setEapPhase2Method(wifiConfigurationToSupplicantEapPhase2Method(
    502                     eapConfig.getPhase2Method()))) {
    503                 Log.e(TAG, ssid + ": failed to set eap phase 2 method: "
    504                         + eapConfig.getPhase2Method());
    505                 return false;
    506             }
    507             String eapParam = null;
    508             /** EAP Identity */
    509             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY);
    510             if (!TextUtils.isEmpty(eapParam)
    511                     && !setEapIdentity(NativeUtil.stringToByteArrayList(eapParam))) {
    512                 Log.e(TAG, ssid + ": failed to set eap identity: " + eapParam);
    513                 return false;
    514             }
    515             /** EAP Anonymous Identity */
    516             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY);
    517             if (!TextUtils.isEmpty(eapParam)
    518                     && !setEapAnonymousIdentity(NativeUtil.stringToByteArrayList(eapParam))) {
    519                 Log.e(TAG, ssid + ": failed to set eap anonymous identity: " + eapParam);
    520                 return false;
    521             }
    522             /** EAP Password */
    523             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY);
    524             if (!TextUtils.isEmpty(eapParam)
    525                     && !setEapPassword(NativeUtil.stringToByteArrayList(eapParam))) {
    526                 Log.e(TAG, ssid + ": failed to set eap password");
    527                 return false;
    528             }
    529             /** EAP Client Cert */
    530             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY);
    531             if (!TextUtils.isEmpty(eapParam) && !setEapClientCert(eapParam)) {
    532                 Log.e(TAG, ssid + ": failed to set eap client cert: " + eapParam);
    533                 return false;
    534             }
    535             /** EAP CA Cert */
    536             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY);
    537             if (!TextUtils.isEmpty(eapParam) && !setEapCACert(eapParam)) {
    538                 Log.e(TAG, ssid + ": failed to set eap ca cert: " + eapParam);
    539                 return false;
    540             }
    541             /** EAP Subject Match */
    542             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY);
    543             if (!TextUtils.isEmpty(eapParam) && !setEapSubjectMatch(eapParam)) {
    544                 Log.e(TAG, ssid + ": failed to set eap subject match: " + eapParam);
    545                 return false;
    546             }
    547             /** EAP Engine ID */
    548             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY);
    549             if (!TextUtils.isEmpty(eapParam) && !setEapEngineID(eapParam)) {
    550                 Log.e(TAG, ssid + ": failed to set eap engine id: " + eapParam);
    551                 return false;
    552             }
    553             /** EAP Engine */
    554             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY);
    555             if (!TextUtils.isEmpty(eapParam) && !setEapEngine(
    556                     eapParam.equals(WifiEnterpriseConfig.ENGINE_ENABLE) ? true : false)) {
    557                 Log.e(TAG, ssid + ": failed to set eap engine: " + eapParam);
    558                 return false;
    559             }
    560             /** EAP Private Key */
    561             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY);
    562             if (!TextUtils.isEmpty(eapParam) && !setEapPrivateKeyId(eapParam)) {
    563                 Log.e(TAG, ssid + ": failed to set eap private key: " + eapParam);
    564                 return false;
    565             }
    566             /** EAP Alt Subject Match */
    567             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY);
    568             if (!TextUtils.isEmpty(eapParam) && !setEapAltSubjectMatch(eapParam)) {
    569                 Log.e(TAG, ssid + ": failed to set eap alt subject match: " + eapParam);
    570                 return false;
    571             }
    572             /** EAP Domain Suffix Match */
    573             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY);
    574             if (!TextUtils.isEmpty(eapParam) && !setEapDomainSuffixMatch(eapParam)) {
    575                 Log.e(TAG, ssid + ": failed to set eap domain suffix match: " + eapParam);
    576                 return false;
    577             }
    578             /** EAP CA Path*/
    579             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY);
    580             if (!TextUtils.isEmpty(eapParam) && !setEapCAPath(eapParam)) {
    581                 Log.e(TAG, ssid + ": failed to set eap ca path: " + eapParam);
    582                 return false;
    583             }
    584 
    585             /** EAP Proactive Key Caching */
    586             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.OPP_KEY_CACHING);
    587             if (!TextUtils.isEmpty(eapParam)
    588                     && !setEapProactiveKeyCaching(eapParam.equals("1") ? true : false)) {
    589                 Log.e(TAG, ssid + ": failed to set proactive key caching: " + eapParam);
    590                 return false;
    591             }
    592             return true;
    593         }
    594     }
    595 
    596     /**
    597      * Maps WifiConfiguration Key Management BitSet to Supplicant HIDL bitmask int
    598      * TODO(b/32571829): Update mapping when fast transition keys are added
    599      * @return bitmask int describing the allowed Key Management schemes, readable by the Supplicant
    600      *         HIDL hal
    601      */
    602     private static int wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt) {
    603         int mask = 0;
    604         for (int bit = keyMgmt.nextSetBit(0); bit != -1; bit = keyMgmt.nextSetBit(bit + 1)) {
    605             switch (bit) {
    606                 case WifiConfiguration.KeyMgmt.NONE:
    607                     mask |= ISupplicantStaNetwork.KeyMgmtMask.NONE;
    608                     break;
    609                 case WifiConfiguration.KeyMgmt.WPA_PSK:
    610                     mask |= ISupplicantStaNetwork.KeyMgmtMask.WPA_PSK;
    611                     break;
    612                 case WifiConfiguration.KeyMgmt.WPA_EAP:
    613                     mask |= ISupplicantStaNetwork.KeyMgmtMask.WPA_EAP;
    614                     break;
    615                 case WifiConfiguration.KeyMgmt.IEEE8021X:
    616                     mask |= ISupplicantStaNetwork.KeyMgmtMask.IEEE8021X;
    617                     break;
    618                 case WifiConfiguration.KeyMgmt.OSEN:
    619                     mask |= ISupplicantStaNetwork.KeyMgmtMask.OSEN;
    620                     break;
    621                 case WifiConfiguration.KeyMgmt.FT_PSK:
    622                     mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_PSK;
    623                     break;
    624                 case WifiConfiguration.KeyMgmt.FT_EAP:
    625                     mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_EAP;
    626                     break;
    627                 case WifiConfiguration.KeyMgmt.WPA2_PSK: // This should never happen
    628                 default:
    629                     throw new IllegalArgumentException(
    630                             "Invalid protoMask bit in keyMgmt: " + bit);
    631             }
    632         }
    633         return mask;
    634     }
    635 
    636     private static int wifiConfigurationToSupplicantProtoMask(BitSet protoMask) {
    637         int mask = 0;
    638         for (int bit = protoMask.nextSetBit(0); bit != -1; bit = protoMask.nextSetBit(bit + 1)) {
    639             switch (bit) {
    640                 case WifiConfiguration.Protocol.WPA:
    641                     mask |= ISupplicantStaNetwork.ProtoMask.WPA;
    642                     break;
    643                 case WifiConfiguration.Protocol.RSN:
    644                     mask |= ISupplicantStaNetwork.ProtoMask.RSN;
    645                     break;
    646                 case WifiConfiguration.Protocol.OSEN:
    647                     mask |= ISupplicantStaNetwork.ProtoMask.OSEN;
    648                     break;
    649                 default:
    650                     throw new IllegalArgumentException(
    651                             "Invalid protoMask bit in wificonfig: " + bit);
    652             }
    653         }
    654         return mask;
    655     };
    656 
    657     private static int wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask) {
    658         int mask = 0;
    659         for (int bit = authAlgMask.nextSetBit(0); bit != -1;
    660                 bit = authAlgMask.nextSetBit(bit + 1)) {
    661             switch (bit) {
    662                 case WifiConfiguration.AuthAlgorithm.OPEN:
    663                     mask |= ISupplicantStaNetwork.AuthAlgMask.OPEN;
    664                     break;
    665                 case WifiConfiguration.AuthAlgorithm.SHARED:
    666                     mask |= ISupplicantStaNetwork.AuthAlgMask.SHARED;
    667                     break;
    668                 case WifiConfiguration.AuthAlgorithm.LEAP:
    669                     mask |= ISupplicantStaNetwork.AuthAlgMask.LEAP;
    670                     break;
    671                 default:
    672                     throw new IllegalArgumentException(
    673                             "Invalid authAlgMask bit in wificonfig: " + bit);
    674             }
    675         }
    676         return mask;
    677     };
    678 
    679     private static int wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask) {
    680         int mask = 0;
    681         for (int bit = groupCipherMask.nextSetBit(0); bit != -1; bit =
    682                 groupCipherMask.nextSetBit(bit + 1)) {
    683             switch (bit) {
    684                 case WifiConfiguration.GroupCipher.WEP40:
    685                     mask |= ISupplicantStaNetwork.GroupCipherMask.WEP40;
    686                     break;
    687                 case WifiConfiguration.GroupCipher.WEP104:
    688                     mask |= ISupplicantStaNetwork.GroupCipherMask.WEP104;
    689                     break;
    690                 case WifiConfiguration.GroupCipher.TKIP:
    691                     mask |= ISupplicantStaNetwork.GroupCipherMask.TKIP;
    692                     break;
    693                 case WifiConfiguration.GroupCipher.CCMP:
    694                     mask |= ISupplicantStaNetwork.GroupCipherMask.CCMP;
    695                     break;
    696                 case WifiConfiguration.GroupCipher.GTK_NOT_USED:
    697                     mask |= ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED;
    698                     break;
    699                 default:
    700                     throw new IllegalArgumentException(
    701                             "Invalid GroupCipherMask bit in wificonfig: " + bit);
    702             }
    703         }
    704         return mask;
    705     };
    706 
    707     private static int wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask) {
    708         int mask = 0;
    709         for (int bit = pairwiseCipherMask.nextSetBit(0); bit != -1;
    710                 bit = pairwiseCipherMask.nextSetBit(bit + 1)) {
    711             switch (bit) {
    712                 case WifiConfiguration.PairwiseCipher.NONE:
    713                     mask |= ISupplicantStaNetwork.PairwiseCipherMask.NONE;
    714                     break;
    715                 case WifiConfiguration.PairwiseCipher.TKIP:
    716                     mask |= ISupplicantStaNetwork.PairwiseCipherMask.TKIP;
    717                     break;
    718                 case WifiConfiguration.PairwiseCipher.CCMP:
    719                     mask |= ISupplicantStaNetwork.PairwiseCipherMask.CCMP;
    720                     break;
    721                 default:
    722                     throw new IllegalArgumentException(
    723                             "Invalid pairwiseCipherMask bit in wificonfig: " + bit);
    724             }
    725         }
    726         return mask;
    727     };
    728 
    729     private static int supplicantToWifiConfigurationEapMethod(int value) {
    730         switch (value) {
    731             case ISupplicantStaNetwork.EapMethod.PEAP:
    732                 return WifiEnterpriseConfig.Eap.PEAP;
    733             case ISupplicantStaNetwork.EapMethod.TLS:
    734                 return WifiEnterpriseConfig.Eap.TLS;
    735             case ISupplicantStaNetwork.EapMethod.TTLS:
    736                 return WifiEnterpriseConfig.Eap.TTLS;
    737             case ISupplicantStaNetwork.EapMethod.PWD:
    738                 return WifiEnterpriseConfig.Eap.PWD;
    739             case ISupplicantStaNetwork.EapMethod.SIM:
    740                 return WifiEnterpriseConfig.Eap.SIM;
    741             case ISupplicantStaNetwork.EapMethod.AKA:
    742                 return WifiEnterpriseConfig.Eap.AKA;
    743             case ISupplicantStaNetwork.EapMethod.AKA_PRIME:
    744                 return WifiEnterpriseConfig.Eap.AKA_PRIME;
    745             case ISupplicantStaNetwork.EapMethod.WFA_UNAUTH_TLS:
    746                 return WifiEnterpriseConfig.Eap.UNAUTH_TLS;
    747             // WifiEnterpriseConfig.Eap.NONE:
    748             default:
    749                 Log.e(TAG, "invalid eap method value from supplicant: " + value);
    750                 return -1;
    751         }
    752     };
    753 
    754     private static int supplicantToWifiConfigurationEapPhase2Method(int value) {
    755         switch (value) {
    756             case ISupplicantStaNetwork.EapPhase2Method.NONE:
    757                 return WifiEnterpriseConfig.Phase2.NONE;
    758             case ISupplicantStaNetwork.EapPhase2Method.PAP:
    759                 return WifiEnterpriseConfig.Phase2.PAP;
    760             case ISupplicantStaNetwork.EapPhase2Method.MSPAP:
    761                 return WifiEnterpriseConfig.Phase2.MSCHAP;
    762             case ISupplicantStaNetwork.EapPhase2Method.MSPAPV2:
    763                 return WifiEnterpriseConfig.Phase2.MSCHAPV2;
    764             case ISupplicantStaNetwork.EapPhase2Method.GTC:
    765                 return WifiEnterpriseConfig.Phase2.GTC;
    766             case ISupplicantStaNetwork.EapPhase2Method.SIM:
    767                 return WifiEnterpriseConfig.Phase2.SIM;
    768             case ISupplicantStaNetwork.EapPhase2Method.AKA:
    769                 return WifiEnterpriseConfig.Phase2.AKA;
    770             case ISupplicantStaNetwork.EapPhase2Method.AKA_PRIME:
    771                 return WifiEnterpriseConfig.Phase2.AKA_PRIME;
    772             default:
    773                 Log.e(TAG, "invalid eap phase2 method value from supplicant: " + value);
    774                 return -1;
    775         }
    776     };
    777 
    778     private static int supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask,
    779                                                              int supplicantValue, BitSet bitset,
    780                                                              int bitSetPosition) {
    781         bitset.set(bitSetPosition, (supplicantMask & supplicantValue) == supplicantValue);
    782         int modifiedSupplicantMask = supplicantMask & ~supplicantValue;
    783         return modifiedSupplicantMask;
    784     }
    785 
    786     private static BitSet supplicantToWifiConfigurationKeyMgmtMask(int mask) {
    787         BitSet bitset = new BitSet();
    788         mask = supplicantMaskValueToWifiConfigurationBitSet(
    789                 mask, ISupplicantStaNetwork.KeyMgmtMask.NONE, bitset,
    790                 WifiConfiguration.KeyMgmt.NONE);
    791         mask = supplicantMaskValueToWifiConfigurationBitSet(
    792                 mask, ISupplicantStaNetwork.KeyMgmtMask.WPA_PSK, bitset,
    793                 WifiConfiguration.KeyMgmt.WPA_PSK);
    794         mask = supplicantMaskValueToWifiConfigurationBitSet(
    795                 mask, ISupplicantStaNetwork.KeyMgmtMask.WPA_EAP, bitset,
    796                 WifiConfiguration.KeyMgmt.WPA_EAP);
    797         mask = supplicantMaskValueToWifiConfigurationBitSet(
    798                 mask, ISupplicantStaNetwork.KeyMgmtMask.IEEE8021X, bitset,
    799                 WifiConfiguration.KeyMgmt.IEEE8021X);
    800         mask = supplicantMaskValueToWifiConfigurationBitSet(
    801                 mask, ISupplicantStaNetwork.KeyMgmtMask.OSEN, bitset,
    802                 WifiConfiguration.KeyMgmt.OSEN);
    803         mask = supplicantMaskValueToWifiConfigurationBitSet(
    804                 mask, ISupplicantStaNetwork.KeyMgmtMask.FT_PSK, bitset,
    805                 WifiConfiguration.KeyMgmt.FT_PSK);
    806         mask = supplicantMaskValueToWifiConfigurationBitSet(
    807                 mask, ISupplicantStaNetwork.KeyMgmtMask.FT_EAP, bitset,
    808                 WifiConfiguration.KeyMgmt.FT_EAP);
    809         if (mask != 0) {
    810             throw new IllegalArgumentException(
    811                     "invalid key mgmt mask from supplicant: " + mask);
    812         }
    813         return bitset;
    814     }
    815 
    816     private static BitSet supplicantToWifiConfigurationProtoMask(int mask) {
    817         BitSet bitset = new BitSet();
    818         mask = supplicantMaskValueToWifiConfigurationBitSet(
    819                 mask, ISupplicantStaNetwork.ProtoMask.WPA, bitset,
    820                 WifiConfiguration.Protocol.WPA);
    821         mask = supplicantMaskValueToWifiConfigurationBitSet(
    822                 mask, ISupplicantStaNetwork.ProtoMask.RSN, bitset,
    823                 WifiConfiguration.Protocol.RSN);
    824         mask = supplicantMaskValueToWifiConfigurationBitSet(
    825                 mask, ISupplicantStaNetwork.ProtoMask.OSEN, bitset,
    826                 WifiConfiguration.Protocol.OSEN);
    827         if (mask != 0) {
    828             throw new IllegalArgumentException(
    829                     "invalid proto mask from supplicant: " + mask);
    830         }
    831         return bitset;
    832     };
    833 
    834     private static BitSet supplicantToWifiConfigurationAuthAlgMask(int mask) {
    835         BitSet bitset = new BitSet();
    836         mask = supplicantMaskValueToWifiConfigurationBitSet(
    837                 mask, ISupplicantStaNetwork.AuthAlgMask.OPEN, bitset,
    838                 WifiConfiguration.AuthAlgorithm.OPEN);
    839         mask = supplicantMaskValueToWifiConfigurationBitSet(
    840                 mask, ISupplicantStaNetwork.AuthAlgMask.SHARED, bitset,
    841                 WifiConfiguration.AuthAlgorithm.SHARED);
    842         mask = supplicantMaskValueToWifiConfigurationBitSet(
    843                 mask, ISupplicantStaNetwork.AuthAlgMask.LEAP, bitset,
    844                 WifiConfiguration.AuthAlgorithm.LEAP);
    845         if (mask != 0) {
    846             throw new IllegalArgumentException(
    847                     "invalid auth alg mask from supplicant: " + mask);
    848         }
    849         return bitset;
    850     };
    851 
    852     private static BitSet supplicantToWifiConfigurationGroupCipherMask(int mask) {
    853         BitSet bitset = new BitSet();
    854         mask = supplicantMaskValueToWifiConfigurationBitSet(
    855                 mask, ISupplicantStaNetwork.GroupCipherMask.WEP40, bitset,
    856                 WifiConfiguration.GroupCipher.WEP40);
    857         mask = supplicantMaskValueToWifiConfigurationBitSet(
    858                 mask, ISupplicantStaNetwork.GroupCipherMask.WEP104, bitset,
    859                 WifiConfiguration.GroupCipher.WEP104);
    860         mask = supplicantMaskValueToWifiConfigurationBitSet(
    861                 mask, ISupplicantStaNetwork.GroupCipherMask.TKIP, bitset,
    862                 WifiConfiguration.GroupCipher.TKIP);
    863         mask = supplicantMaskValueToWifiConfigurationBitSet(
    864                 mask, ISupplicantStaNetwork.GroupCipherMask.CCMP, bitset,
    865                 WifiConfiguration.GroupCipher.CCMP);
    866         mask = supplicantMaskValueToWifiConfigurationBitSet(
    867                 mask, ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED, bitset,
    868                 WifiConfiguration.GroupCipher.GTK_NOT_USED);
    869         if (mask != 0) {
    870             throw new IllegalArgumentException(
    871                     "invalid group cipher mask from supplicant: " + mask);
    872         }
    873         return bitset;
    874     };
    875 
    876     private static BitSet supplicantToWifiConfigurationPairwiseCipherMask(int mask) {
    877         BitSet bitset = new BitSet();
    878         mask = supplicantMaskValueToWifiConfigurationBitSet(
    879                 mask, ISupplicantStaNetwork.PairwiseCipherMask.NONE, bitset,
    880                 WifiConfiguration.PairwiseCipher.NONE);
    881         mask = supplicantMaskValueToWifiConfigurationBitSet(
    882                 mask, ISupplicantStaNetwork.PairwiseCipherMask.TKIP, bitset,
    883                 WifiConfiguration.PairwiseCipher.TKIP);
    884         mask = supplicantMaskValueToWifiConfigurationBitSet(
    885                 mask, ISupplicantStaNetwork.PairwiseCipherMask.CCMP, bitset,
    886                 WifiConfiguration.PairwiseCipher.CCMP);
    887         if (mask != 0) {
    888             throw new IllegalArgumentException(
    889                     "invalid pairwise cipher mask from supplicant: " + mask);
    890         }
    891         return bitset;
    892     };
    893 
    894     private static int wifiConfigurationToSupplicantEapMethod(int value) {
    895         switch (value) {
    896             case WifiEnterpriseConfig.Eap.PEAP:
    897                 return ISupplicantStaNetwork.EapMethod.PEAP;
    898             case WifiEnterpriseConfig.Eap.TLS:
    899                 return ISupplicantStaNetwork.EapMethod.TLS;
    900             case WifiEnterpriseConfig.Eap.TTLS:
    901                 return ISupplicantStaNetwork.EapMethod.TTLS;
    902             case WifiEnterpriseConfig.Eap.PWD:
    903                 return ISupplicantStaNetwork.EapMethod.PWD;
    904             case WifiEnterpriseConfig.Eap.SIM:
    905                 return ISupplicantStaNetwork.EapMethod.SIM;
    906             case WifiEnterpriseConfig.Eap.AKA:
    907                 return ISupplicantStaNetwork.EapMethod.AKA;
    908             case WifiEnterpriseConfig.Eap.AKA_PRIME:
    909                 return ISupplicantStaNetwork.EapMethod.AKA_PRIME;
    910             case WifiEnterpriseConfig.Eap.UNAUTH_TLS:
    911                 return ISupplicantStaNetwork.EapMethod.WFA_UNAUTH_TLS;
    912             // WifiEnterpriseConfig.Eap.NONE:
    913             default:
    914                 Log.e(TAG, "invalid eap method value from WifiConfiguration: " + value);
    915                 return -1;
    916         }
    917     };
    918 
    919     private static int wifiConfigurationToSupplicantEapPhase2Method(int value) {
    920         switch (value) {
    921             case WifiEnterpriseConfig.Phase2.NONE:
    922                 return ISupplicantStaNetwork.EapPhase2Method.NONE;
    923             case WifiEnterpriseConfig.Phase2.PAP:
    924                 return ISupplicantStaNetwork.EapPhase2Method.PAP;
    925             case WifiEnterpriseConfig.Phase2.MSCHAP:
    926                 return ISupplicantStaNetwork.EapPhase2Method.MSPAP;
    927             case WifiEnterpriseConfig.Phase2.MSCHAPV2:
    928                 return ISupplicantStaNetwork.EapPhase2Method.MSPAPV2;
    929             case WifiEnterpriseConfig.Phase2.GTC:
    930                 return ISupplicantStaNetwork.EapPhase2Method.GTC;
    931             case WifiEnterpriseConfig.Phase2.SIM:
    932                 return ISupplicantStaNetwork.EapPhase2Method.SIM;
    933             case WifiEnterpriseConfig.Phase2.AKA:
    934                 return ISupplicantStaNetwork.EapPhase2Method.AKA;
    935             case WifiEnterpriseConfig.Phase2.AKA_PRIME:
    936                 return ISupplicantStaNetwork.EapPhase2Method.AKA_PRIME;
    937             default:
    938                 Log.e(TAG, "invalid eap phase2 method value from WifiConfiguration: " + value);
    939                 return -1;
    940         }
    941     };
    942 
    943     /** See ISupplicantNetwork.hal for documentation */
    944     private boolean getId() {
    945         synchronized (mLock) {
    946             final String methodStr = "getId";
    947             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
    948             try {
    949                 MutableBoolean statusOk = new MutableBoolean(false);
    950                 mISupplicantStaNetwork.getId((SupplicantStatus status, int idValue) -> {
    951                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
    952                     if (statusOk.value) {
    953                         this.mNetworkId = idValue;
    954                     } else {
    955                         checkStatusAndLogFailure(status, methodStr);
    956                     }
    957                 });
    958                 return statusOk.value;
    959             } catch (RemoteException e) {
    960                 handleRemoteException(e, methodStr);
    961                 return false;
    962             }
    963         }
    964     }
    965 
    966     /** See ISupplicantStaNetwork.hal for documentation */
    967     private boolean registerCallback(ISupplicantStaNetworkCallback callback) {
    968         synchronized (mLock) {
    969             final String methodStr = "registerCallback";
    970             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
    971             try {
    972                 SupplicantStatus status =  mISupplicantStaNetwork.registerCallback(callback);
    973                 return checkStatusAndLogFailure(status, methodStr);
    974             } catch (RemoteException e) {
    975                 handleRemoteException(e, methodStr);
    976                 return false;
    977             }
    978         }
    979     }
    980 
    981     /** See ISupplicantStaNetwork.hal for documentation */
    982     private boolean setSsid(java.util.ArrayList<Byte> ssid) {
    983         synchronized (mLock) {
    984             final String methodStr = "setSsid";
    985             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
    986             try {
    987                 SupplicantStatus status =  mISupplicantStaNetwork.setSsid(ssid);
    988                 return checkStatusAndLogFailure(status, methodStr);
    989             } catch (RemoteException e) {
    990                 handleRemoteException(e, methodStr);
    991                 return false;
    992             }
    993         }
    994     }
    995 
    996     /**
    997      * Set the BSSID for this network.
    998      *
    999      * @param bssidStr MAC address in "XX:XX:XX:XX:XX:XX" form or "any" to reset the mac address.
   1000      * @return true if it succeeds, false otherwise.
   1001      */
   1002     public boolean setBssid(String bssidStr) {
   1003         synchronized (mLock) {
   1004             try {
   1005                 return setBssid(NativeUtil.macAddressToByteArray(bssidStr));
   1006             } catch (IllegalArgumentException e) {
   1007                 Log.e(TAG, "Illegal argument " + bssidStr, e);
   1008                 return false;
   1009             }
   1010         }
   1011     }
   1012 
   1013     /** See ISupplicantStaNetwork.hal for documentation */
   1014     private boolean setBssid(byte[/* 6 */] bssid) {
   1015         synchronized (mLock) {
   1016             final String methodStr = "setBssid";
   1017             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1018             try {
   1019                 SupplicantStatus status =  mISupplicantStaNetwork.setBssid(bssid);
   1020                 return checkStatusAndLogFailure(status, methodStr);
   1021             } catch (RemoteException e) {
   1022                 handleRemoteException(e, methodStr);
   1023                 return false;
   1024             }
   1025         }
   1026     }
   1027     /** See ISupplicantStaNetwork.hal for documentation */
   1028     private boolean setScanSsid(boolean enable) {
   1029         synchronized (mLock) {
   1030             final String methodStr = "setScanSsid";
   1031             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1032             try {
   1033                 SupplicantStatus status =  mISupplicantStaNetwork.setScanSsid(enable);
   1034                 return checkStatusAndLogFailure(status, methodStr);
   1035             } catch (RemoteException e) {
   1036                 handleRemoteException(e, methodStr);
   1037                 return false;
   1038             }
   1039         }
   1040     }
   1041     /** See ISupplicantStaNetwork.hal for documentation */
   1042     private boolean setKeyMgmt(int keyMgmtMask) {
   1043         synchronized (mLock) {
   1044             final String methodStr = "setKeyMgmt";
   1045             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1046             try {
   1047                 SupplicantStatus status =  mISupplicantStaNetwork.setKeyMgmt(keyMgmtMask);
   1048                 return checkStatusAndLogFailure(status, methodStr);
   1049             } catch (RemoteException e) {
   1050                 handleRemoteException(e, methodStr);
   1051                 return false;
   1052             }
   1053         }
   1054     }
   1055     /** See ISupplicantStaNetwork.hal for documentation */
   1056     private boolean setProto(int protoMask) {
   1057         synchronized (mLock) {
   1058             final String methodStr = "setProto";
   1059             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1060             try {
   1061                 SupplicantStatus status =  mISupplicantStaNetwork.setProto(protoMask);
   1062                 return checkStatusAndLogFailure(status, methodStr);
   1063             } catch (RemoteException e) {
   1064                 handleRemoteException(e, methodStr);
   1065                 return false;
   1066             }
   1067         }
   1068     }
   1069     /** See ISupplicantStaNetwork.hal for documentation */
   1070     private boolean setAuthAlg(int authAlgMask) {
   1071         synchronized (mLock) {
   1072             final String methodStr = "setAuthAlg";
   1073             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1074             try {
   1075                 SupplicantStatus status =  mISupplicantStaNetwork.setAuthAlg(authAlgMask);
   1076                 return checkStatusAndLogFailure(status, methodStr);
   1077             } catch (RemoteException e) {
   1078                 handleRemoteException(e, methodStr);
   1079                 return false;
   1080             }
   1081         }
   1082     }
   1083     /** See ISupplicantStaNetwork.hal for documentation */
   1084     private boolean setGroupCipher(int groupCipherMask) {
   1085         synchronized (mLock) {
   1086             final String methodStr = "setGroupCipher";
   1087             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1088             try {
   1089                 SupplicantStatus status =  mISupplicantStaNetwork.setGroupCipher(groupCipherMask);
   1090                 return checkStatusAndLogFailure(status, methodStr);
   1091             } catch (RemoteException e) {
   1092                 handleRemoteException(e, methodStr);
   1093                 return false;
   1094             }
   1095         }
   1096     }
   1097     /** See ISupplicantStaNetwork.hal for documentation */
   1098     private boolean setPairwiseCipher(int pairwiseCipherMask) {
   1099         synchronized (mLock) {
   1100             final String methodStr = "setPairwiseCipher";
   1101             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1102             try {
   1103                 SupplicantStatus status =
   1104                         mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask);
   1105                 return checkStatusAndLogFailure(status, methodStr);
   1106             } catch (RemoteException e) {
   1107                 handleRemoteException(e, methodStr);
   1108                 return false;
   1109             }
   1110         }
   1111     }
   1112     /** See ISupplicantStaNetwork.hal for documentation */
   1113     private boolean setPskPassphrase(String psk) {
   1114         synchronized (mLock) {
   1115             final String methodStr = "setPskPassphrase";
   1116             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1117             try {
   1118                 SupplicantStatus status =  mISupplicantStaNetwork.setPskPassphrase(psk);
   1119                 return checkStatusAndLogFailure(status, methodStr);
   1120             } catch (RemoteException e) {
   1121                 handleRemoteException(e, methodStr);
   1122                 return false;
   1123             }
   1124         }
   1125     }
   1126     /** See ISupplicantStaNetwork.hal for documentation */
   1127     private boolean setPsk(byte[] psk) {
   1128         synchronized (mLock) {
   1129             final String methodStr = "setPsk";
   1130             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1131             try {
   1132                 SupplicantStatus status =  mISupplicantStaNetwork.setPsk(psk);
   1133                 return checkStatusAndLogFailure(status, methodStr);
   1134             } catch (RemoteException e) {
   1135                 handleRemoteException(e, methodStr);
   1136                 return false;
   1137             }
   1138         }
   1139     }
   1140     /** See ISupplicantStaNetwork.hal for documentation */
   1141     private boolean setWepKey(int keyIdx, java.util.ArrayList<Byte> wepKey) {
   1142         synchronized (mLock) {
   1143             final String methodStr = "setWepKey";
   1144             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1145             try {
   1146                 SupplicantStatus status =  mISupplicantStaNetwork.setWepKey(keyIdx, wepKey);
   1147                 return checkStatusAndLogFailure(status, methodStr);
   1148             } catch (RemoteException e) {
   1149                 handleRemoteException(e, methodStr);
   1150                 return false;
   1151             }
   1152         }
   1153     }
   1154     /** See ISupplicantStaNetwork.hal for documentation */
   1155     private boolean setWepTxKeyIdx(int keyIdx) {
   1156         synchronized (mLock) {
   1157             final String methodStr = "setWepTxKeyIdx";
   1158             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1159             try {
   1160                 SupplicantStatus status =  mISupplicantStaNetwork.setWepTxKeyIdx(keyIdx);
   1161                 return checkStatusAndLogFailure(status, methodStr);
   1162             } catch (RemoteException e) {
   1163                 handleRemoteException(e, methodStr);
   1164                 return false;
   1165             }
   1166         }
   1167     }
   1168     /** See ISupplicantStaNetwork.hal for documentation */
   1169     private boolean setRequirePmf(boolean enable) {
   1170         synchronized (mLock) {
   1171             final String methodStr = "setRequirePmf";
   1172             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1173             try {
   1174                 SupplicantStatus status =  mISupplicantStaNetwork.setRequirePmf(enable);
   1175                 return checkStatusAndLogFailure(status, methodStr);
   1176             } catch (RemoteException e) {
   1177                 handleRemoteException(e, methodStr);
   1178                 return false;
   1179             }
   1180         }
   1181     }
   1182     /** See ISupplicantStaNetwork.hal for documentation */
   1183     private boolean setUpdateIdentifier(int identifier) {
   1184         synchronized (mLock) {
   1185             final String methodStr = "setUpdateIdentifier";
   1186             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1187             try {
   1188                 SupplicantStatus status =  mISupplicantStaNetwork.setUpdateIdentifier(identifier);
   1189                 return checkStatusAndLogFailure(status, methodStr);
   1190             } catch (RemoteException e) {
   1191                 handleRemoteException(e, methodStr);
   1192                 return false;
   1193             }
   1194         }
   1195     }
   1196     /** See ISupplicantStaNetwork.hal for documentation */
   1197     private boolean setEapMethod(int method) {
   1198         synchronized (mLock) {
   1199             final String methodStr = "setEapMethod";
   1200             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1201             try {
   1202                 SupplicantStatus status =  mISupplicantStaNetwork.setEapMethod(method);
   1203                 return checkStatusAndLogFailure(status, methodStr);
   1204             } catch (RemoteException e) {
   1205                 handleRemoteException(e, methodStr);
   1206                 return false;
   1207             }
   1208         }
   1209     }
   1210     /** See ISupplicantStaNetwork.hal for documentation */
   1211     private boolean setEapPhase2Method(int method) {
   1212         synchronized (mLock) {
   1213             final String methodStr = "setEapPhase2Method";
   1214             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1215             try {
   1216                 SupplicantStatus status =  mISupplicantStaNetwork.setEapPhase2Method(method);
   1217                 return checkStatusAndLogFailure(status, methodStr);
   1218             } catch (RemoteException e) {
   1219                 handleRemoteException(e, methodStr);
   1220                 return false;
   1221             }
   1222         }
   1223     }
   1224     /** See ISupplicantStaNetwork.hal for documentation */
   1225     private boolean setEapIdentity(java.util.ArrayList<Byte> identity) {
   1226         synchronized (mLock) {
   1227             final String methodStr = "setEapIdentity";
   1228             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1229             try {
   1230                 SupplicantStatus status =  mISupplicantStaNetwork.setEapIdentity(identity);
   1231                 return checkStatusAndLogFailure(status, methodStr);
   1232             } catch (RemoteException e) {
   1233                 handleRemoteException(e, methodStr);
   1234                 return false;
   1235             }
   1236         }
   1237     }
   1238     /** See ISupplicantStaNetwork.hal for documentation */
   1239     private boolean setEapAnonymousIdentity(java.util.ArrayList<Byte> identity) {
   1240         synchronized (mLock) {
   1241             final String methodStr = "setEapAnonymousIdentity";
   1242             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1243             try {
   1244                 SupplicantStatus status =  mISupplicantStaNetwork.setEapAnonymousIdentity(identity);
   1245                 return checkStatusAndLogFailure(status, methodStr);
   1246             } catch (RemoteException e) {
   1247                 handleRemoteException(e, methodStr);
   1248                 return false;
   1249             }
   1250         }
   1251     }
   1252     /** See ISupplicantStaNetwork.hal for documentation */
   1253     private boolean setEapPassword(java.util.ArrayList<Byte> password) {
   1254         synchronized (mLock) {
   1255             final String methodStr = "setEapPassword";
   1256             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1257             try {
   1258                 SupplicantStatus status =  mISupplicantStaNetwork.setEapPassword(password);
   1259                 return checkStatusAndLogFailure(status, methodStr);
   1260             } catch (RemoteException e) {
   1261                 handleRemoteException(e, methodStr);
   1262                 return false;
   1263             }
   1264         }
   1265     }
   1266     /** See ISupplicantStaNetwork.hal for documentation */
   1267     private boolean setEapCACert(String path) {
   1268         synchronized (mLock) {
   1269             final String methodStr = "setEapCACert";
   1270             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1271             try {
   1272                 SupplicantStatus status =  mISupplicantStaNetwork.setEapCACert(path);
   1273                 return checkStatusAndLogFailure(status, methodStr);
   1274             } catch (RemoteException e) {
   1275                 handleRemoteException(e, methodStr);
   1276                 return false;
   1277             }
   1278         }
   1279     }
   1280     /** See ISupplicantStaNetwork.hal for documentation */
   1281     private boolean setEapCAPath(String path) {
   1282         synchronized (mLock) {
   1283             final String methodStr = "setEapCAPath";
   1284             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1285             try {
   1286                 SupplicantStatus status =  mISupplicantStaNetwork.setEapCAPath(path);
   1287                 return checkStatusAndLogFailure(status, methodStr);
   1288             } catch (RemoteException e) {
   1289                 handleRemoteException(e, methodStr);
   1290                 return false;
   1291             }
   1292         }
   1293     }
   1294     /** See ISupplicantStaNetwork.hal for documentation */
   1295     private boolean setEapClientCert(String path) {
   1296         synchronized (mLock) {
   1297             final String methodStr = "setEapClientCert";
   1298             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1299             try {
   1300                 SupplicantStatus status =  mISupplicantStaNetwork.setEapClientCert(path);
   1301                 return checkStatusAndLogFailure(status, methodStr);
   1302             } catch (RemoteException e) {
   1303                 handleRemoteException(e, methodStr);
   1304                 return false;
   1305             }
   1306         }
   1307     }
   1308     /** See ISupplicantStaNetwork.hal for documentation */
   1309     private boolean setEapPrivateKeyId(String id) {
   1310         synchronized (mLock) {
   1311             final String methodStr = "setEapPrivateKeyId";
   1312             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1313             try {
   1314                 SupplicantStatus status =  mISupplicantStaNetwork.setEapPrivateKeyId(id);
   1315                 return checkStatusAndLogFailure(status, methodStr);
   1316             } catch (RemoteException e) {
   1317                 handleRemoteException(e, methodStr);
   1318                 return false;
   1319             }
   1320         }
   1321     }
   1322     /** See ISupplicantStaNetwork.hal for documentation */
   1323     private boolean setEapSubjectMatch(String match) {
   1324         synchronized (mLock) {
   1325             final String methodStr = "setEapSubjectMatch";
   1326             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1327             try {
   1328                 SupplicantStatus status =  mISupplicantStaNetwork.setEapSubjectMatch(match);
   1329                 return checkStatusAndLogFailure(status, methodStr);
   1330             } catch (RemoteException e) {
   1331                 handleRemoteException(e, methodStr);
   1332                 return false;
   1333             }
   1334         }
   1335     }
   1336     /** See ISupplicantStaNetwork.hal for documentation */
   1337     private boolean setEapAltSubjectMatch(String match) {
   1338         synchronized (mLock) {
   1339             final String methodStr = "setEapAltSubjectMatch";
   1340             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1341             try {
   1342                 SupplicantStatus status =  mISupplicantStaNetwork.setEapAltSubjectMatch(match);
   1343                 return checkStatusAndLogFailure(status, methodStr);
   1344             } catch (RemoteException e) {
   1345                 handleRemoteException(e, methodStr);
   1346                 return false;
   1347             }
   1348         }
   1349     }
   1350     /** See ISupplicantStaNetwork.hal for documentation */
   1351     private boolean setEapEngine(boolean enable) {
   1352         synchronized (mLock) {
   1353             final String methodStr = "setEapEngine";
   1354             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1355             try {
   1356                 SupplicantStatus status =  mISupplicantStaNetwork.setEapEngine(enable);
   1357                 return checkStatusAndLogFailure(status, methodStr);
   1358             } catch (RemoteException e) {
   1359                 handleRemoteException(e, methodStr);
   1360                 return false;
   1361             }
   1362         }
   1363     }
   1364     /** See ISupplicantStaNetwork.hal for documentation */
   1365     private boolean setEapEngineID(String id) {
   1366         synchronized (mLock) {
   1367             final String methodStr = "setEapEngineID";
   1368             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1369             try {
   1370                 SupplicantStatus status =  mISupplicantStaNetwork.setEapEngineID(id);
   1371                 return checkStatusAndLogFailure(status, methodStr);
   1372             } catch (RemoteException e) {
   1373                 handleRemoteException(e, methodStr);
   1374                 return false;
   1375             }
   1376         }
   1377     }
   1378     /** See ISupplicantStaNetwork.hal for documentation */
   1379     private boolean setEapDomainSuffixMatch(String match) {
   1380         synchronized (mLock) {
   1381             final String methodStr = "setEapDomainSuffixMatch";
   1382             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1383             try {
   1384                 SupplicantStatus status =  mISupplicantStaNetwork.setEapDomainSuffixMatch(match);
   1385                 return checkStatusAndLogFailure(status, methodStr);
   1386             } catch (RemoteException e) {
   1387                 handleRemoteException(e, methodStr);
   1388                 return false;
   1389             }
   1390         }
   1391     }
   1392     /** See ISupplicantStaNetwork.hal for documentation */
   1393     private boolean setEapProactiveKeyCaching(boolean enable) {
   1394         synchronized (mLock) {
   1395             final String methodStr = "setEapProactiveKeyCaching";
   1396             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1397             try {
   1398                 SupplicantStatus status =  mISupplicantStaNetwork.setProactiveKeyCaching(enable);
   1399                 return checkStatusAndLogFailure(status, methodStr);
   1400             } catch (RemoteException e) {
   1401                 handleRemoteException(e, methodStr);
   1402                 return false;
   1403             }
   1404         }
   1405     }
   1406     /** See ISupplicantStaNetwork.hal for documentation */
   1407     private boolean setIdStr(String idString) {
   1408         synchronized (mLock) {
   1409             final String methodStr = "setIdStr";
   1410             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1411             try {
   1412                 SupplicantStatus status =  mISupplicantStaNetwork.setIdStr(idString);
   1413                 return checkStatusAndLogFailure(status, methodStr);
   1414             } catch (RemoteException e) {
   1415                 handleRemoteException(e, methodStr);
   1416                 return false;
   1417             }
   1418         }
   1419     }
   1420     /** See ISupplicantStaNetwork.hal for documentation */
   1421     private boolean getSsid() {
   1422         synchronized (mLock) {
   1423             final String methodStr = "getSsid";
   1424             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1425             try {
   1426                 MutableBoolean statusOk = new MutableBoolean(false);
   1427                 mISupplicantStaNetwork.getSsid((SupplicantStatus status,
   1428                         java.util.ArrayList<Byte> ssidValue) -> {
   1429                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1430                     if (statusOk.value) {
   1431                         this.mSsid = ssidValue;
   1432                     } else {
   1433                         checkStatusAndLogFailure(status, methodStr);
   1434                     }
   1435                 });
   1436                 return statusOk.value;
   1437             } catch (RemoteException e) {
   1438                 handleRemoteException(e, methodStr);
   1439                 return false;
   1440             }
   1441         }
   1442     }
   1443     /** See ISupplicantStaNetwork.hal for documentation */
   1444     private boolean getBssid() {
   1445         synchronized (mLock) {
   1446             final String methodStr = "getBssid";
   1447             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1448             try {
   1449                 MutableBoolean statusOk = new MutableBoolean(false);
   1450                 mISupplicantStaNetwork.getBssid((SupplicantStatus status,
   1451                         byte[/* 6 */] bssidValue) -> {
   1452                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1453                     if (statusOk.value) {
   1454                         this.mBssid = bssidValue;
   1455                     } else {
   1456                         checkStatusAndLogFailure(status, methodStr);
   1457                     }
   1458                 });
   1459                 return statusOk.value;
   1460             } catch (RemoteException e) {
   1461                 handleRemoteException(e, methodStr);
   1462                 return false;
   1463             }
   1464         }
   1465     }
   1466     /** See ISupplicantStaNetwork.hal for documentation */
   1467     private boolean getScanSsid() {
   1468         synchronized (mLock) {
   1469             final String methodStr = "getScanSsid";
   1470             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1471             try {
   1472                 MutableBoolean statusOk = new MutableBoolean(false);
   1473                 mISupplicantStaNetwork.getScanSsid((SupplicantStatus status,
   1474                         boolean enabledValue) -> {
   1475                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1476                     if (statusOk.value) {
   1477                         this.mScanSsid = enabledValue;
   1478                     } else {
   1479                         checkStatusAndLogFailure(status, methodStr);
   1480                     }
   1481                 });
   1482                 return statusOk.value;
   1483             } catch (RemoteException e) {
   1484                 handleRemoteException(e, methodStr);
   1485                 return false;
   1486             }
   1487         }
   1488     }
   1489     /** See ISupplicantStaNetwork.hal for documentation */
   1490     private boolean getKeyMgmt() {
   1491         synchronized (mLock) {
   1492             final String methodStr = "getKeyMgmt";
   1493             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1494             try {
   1495                 MutableBoolean statusOk = new MutableBoolean(false);
   1496                 mISupplicantStaNetwork.getKeyMgmt((SupplicantStatus status,
   1497                         int keyMgmtMaskValue) -> {
   1498                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1499                     if (statusOk.value) {
   1500                         this.mKeyMgmtMask = keyMgmtMaskValue;
   1501                     } else {
   1502                         checkStatusAndLogFailure(status, methodStr);
   1503                     }
   1504                 });
   1505                 return statusOk.value;
   1506             } catch (RemoteException e) {
   1507                 handleRemoteException(e, methodStr);
   1508                 return false;
   1509             }
   1510         }
   1511     }
   1512     /** See ISupplicantStaNetwork.hal for documentation */
   1513     private boolean getProto() {
   1514         synchronized (mLock) {
   1515             final String methodStr = "getProto";
   1516             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1517             try {
   1518                 MutableBoolean statusOk = new MutableBoolean(false);
   1519                 mISupplicantStaNetwork.getProto((SupplicantStatus status, int protoMaskValue) -> {
   1520                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1521                     if (statusOk.value) {
   1522                         this.mProtoMask = protoMaskValue;
   1523                     } else {
   1524                         checkStatusAndLogFailure(status, methodStr);
   1525                     }
   1526                 });
   1527                 return statusOk.value;
   1528             } catch (RemoteException e) {
   1529                 handleRemoteException(e, methodStr);
   1530                 return false;
   1531             }
   1532         }
   1533     }
   1534     /** See ISupplicantStaNetwork.hal for documentation */
   1535     private boolean getAuthAlg() {
   1536         synchronized (mLock) {
   1537             final String methodStr = "getAuthAlg";
   1538             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1539             try {
   1540                 MutableBoolean statusOk = new MutableBoolean(false);
   1541                 mISupplicantStaNetwork.getAuthAlg((SupplicantStatus status,
   1542                         int authAlgMaskValue) -> {
   1543                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1544                     if (statusOk.value) {
   1545                         this.mAuthAlgMask = authAlgMaskValue;
   1546                     } else {
   1547                         checkStatusAndLogFailure(status, methodStr);
   1548                     }
   1549                 });
   1550                 return statusOk.value;
   1551             } catch (RemoteException e) {
   1552                 handleRemoteException(e, methodStr);
   1553                 return false;
   1554             }
   1555         }
   1556     }
   1557     /** See ISupplicantStaNetwork.hal for documentation */
   1558     private boolean getGroupCipher() {
   1559         synchronized (mLock) {
   1560             final String methodStr = "getGroupCipher";
   1561             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1562             try {
   1563                 MutableBoolean statusOk = new MutableBoolean(false);
   1564                 mISupplicantStaNetwork.getGroupCipher((SupplicantStatus status,
   1565                         int groupCipherMaskValue) -> {
   1566                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1567                     if (statusOk.value) {
   1568                         this.mGroupCipherMask = groupCipherMaskValue;
   1569                     } else {
   1570                         checkStatusAndLogFailure(status, methodStr);
   1571                     }
   1572                 });
   1573                 return statusOk.value;
   1574             } catch (RemoteException e) {
   1575                 handleRemoteException(e, methodStr);
   1576                 return false;
   1577             }
   1578         }
   1579     }
   1580     /** See ISupplicantStaNetwork.hal for documentation */
   1581     private boolean getPairwiseCipher() {
   1582         synchronized (mLock) {
   1583             final String methodStr = "getPairwiseCipher";
   1584             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1585             try {
   1586                 MutableBoolean statusOk = new MutableBoolean(false);
   1587                 mISupplicantStaNetwork.getPairwiseCipher((SupplicantStatus status,
   1588                         int pairwiseCipherMaskValue) -> {
   1589                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1590                     if (statusOk.value) {
   1591                         this.mPairwiseCipherMask = pairwiseCipherMaskValue;
   1592                     } else {
   1593                         checkStatusAndLogFailure(status, methodStr);
   1594                     }
   1595                 });
   1596                 return statusOk.value;
   1597             } catch (RemoteException e) {
   1598                 handleRemoteException(e, methodStr);
   1599                 return false;
   1600             }
   1601         }
   1602     }
   1603     /** See ISupplicantStaNetwork.hal for documentation */
   1604     private boolean getPskPassphrase() {
   1605         synchronized (mLock) {
   1606             final String methodStr = "getPskPassphrase";
   1607             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1608             try {
   1609                 MutableBoolean statusOk = new MutableBoolean(false);
   1610                 mISupplicantStaNetwork.getPskPassphrase((SupplicantStatus status,
   1611                         String pskValue) -> {
   1612                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1613                     if (statusOk.value) {
   1614                         this.mPskPassphrase = pskValue;
   1615                     } else {
   1616                         checkStatusAndLogFailure(status, methodStr);
   1617                     }
   1618                 });
   1619                 return statusOk.value;
   1620             } catch (RemoteException e) {
   1621                 handleRemoteException(e, methodStr);
   1622                 return false;
   1623             }
   1624         }
   1625     }
   1626     /** See ISupplicantStaNetwork.hal for documentation */
   1627     private boolean getPsk() {
   1628         synchronized (mLock) {
   1629             final String methodStr = "getPsk";
   1630             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1631             try {
   1632                 MutableBoolean statusOk = new MutableBoolean(false);
   1633                 mISupplicantStaNetwork.getPsk((SupplicantStatus status, byte[] pskValue) -> {
   1634                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1635                     if (statusOk.value) {
   1636                         this.mPsk = pskValue;
   1637                     } else {
   1638                         checkStatusAndLogFailure(status, methodStr);
   1639                     }
   1640                 });
   1641                 return statusOk.value;
   1642             } catch (RemoteException e) {
   1643                 handleRemoteException(e, methodStr);
   1644                 return false;
   1645             }
   1646         }
   1647     }
   1648     /** See ISupplicantStaNetwork.hal for documentation */
   1649     private boolean getWepKey(int keyIdx) {
   1650         synchronized (mLock) {
   1651             final String methodStr = "keyIdx";
   1652             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1653             try {
   1654                 MutableBoolean statusOk = new MutableBoolean(false);
   1655                 mISupplicantStaNetwork.getWepKey(keyIdx, (SupplicantStatus status,
   1656                         java.util.ArrayList<Byte> wepKeyValue) -> {
   1657                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1658                     if (statusOk.value) {
   1659                         this.mWepKey = wepKeyValue;
   1660                     } else {
   1661                         Log.e(TAG, methodStr + ",  failed: " + status.debugMessage);
   1662                     }
   1663                 });
   1664                 return statusOk.value;
   1665             } catch (RemoteException e) {
   1666                 handleRemoteException(e, methodStr);
   1667                 return false;
   1668             }
   1669         }
   1670     }
   1671     /** See ISupplicantStaNetwork.hal for documentation */
   1672     private boolean getWepTxKeyIdx() {
   1673         synchronized (mLock) {
   1674             final String methodStr = "getWepTxKeyIdx";
   1675             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1676             try {
   1677                 MutableBoolean statusOk = new MutableBoolean(false);
   1678                 mISupplicantStaNetwork.getWepTxKeyIdx((SupplicantStatus status,
   1679                         int keyIdxValue) -> {
   1680                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1681                     if (statusOk.value) {
   1682                         this.mWepTxKeyIdx = keyIdxValue;
   1683                     } else {
   1684                         checkStatusAndLogFailure(status, methodStr);
   1685                     }
   1686                 });
   1687                 return statusOk.value;
   1688             } catch (RemoteException e) {
   1689                 handleRemoteException(e, methodStr);
   1690                 return false;
   1691             }
   1692         }
   1693     }
   1694     /** See ISupplicantStaNetwork.hal for documentation */
   1695     private boolean getRequirePmf() {
   1696         synchronized (mLock) {
   1697             final String methodStr = "getRequirePmf";
   1698             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1699             try {
   1700                 MutableBoolean statusOk = new MutableBoolean(false);
   1701                 mISupplicantStaNetwork.getRequirePmf((SupplicantStatus status,
   1702                         boolean enabledValue) -> {
   1703                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1704                     if (statusOk.value) {
   1705                         this.mRequirePmf = enabledValue;
   1706                     } else {
   1707                         checkStatusAndLogFailure(status, methodStr);
   1708                     }
   1709                 });
   1710                 return statusOk.value;
   1711             } catch (RemoteException e) {
   1712                 handleRemoteException(e, methodStr);
   1713                 return false;
   1714             }
   1715         }
   1716     }
   1717     /** See ISupplicantStaNetwork.hal for documentation */
   1718     private boolean getEapMethod() {
   1719         synchronized (mLock) {
   1720             final String methodStr = "getEapMethod";
   1721             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1722             try {
   1723                 MutableBoolean statusOk = new MutableBoolean(false);
   1724                 mISupplicantStaNetwork.getEapMethod((SupplicantStatus status,
   1725                         int methodValue) -> {
   1726                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1727                     if (statusOk.value) {
   1728                         this.mEapMethod = methodValue;
   1729                     } else {
   1730                         checkStatusAndLogFailure(status, methodStr);
   1731                     }
   1732                 });
   1733                 return statusOk.value;
   1734             } catch (RemoteException e) {
   1735                 handleRemoteException(e, methodStr);
   1736                 return false;
   1737             }
   1738         }
   1739     }
   1740     /** See ISupplicantStaNetwork.hal for documentation */
   1741     private boolean getEapPhase2Method() {
   1742         synchronized (mLock) {
   1743             final String methodStr = "getEapPhase2Method";
   1744             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1745             try {
   1746                 MutableBoolean statusOk = new MutableBoolean(false);
   1747                 mISupplicantStaNetwork.getEapPhase2Method((SupplicantStatus status,
   1748                         int methodValue) -> {
   1749                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1750                     if (statusOk.value) {
   1751                         this.mEapPhase2Method = methodValue;
   1752                     } else {
   1753                         checkStatusAndLogFailure(status, methodStr);
   1754                     }
   1755                 });
   1756                 return statusOk.value;
   1757             } catch (RemoteException e) {
   1758                 handleRemoteException(e, methodStr);
   1759                 return false;
   1760             }
   1761         }
   1762     }
   1763     /** See ISupplicantStaNetwork.hal for documentation */
   1764     private boolean getEapIdentity() {
   1765         synchronized (mLock) {
   1766             final String methodStr = "getEapIdentity";
   1767             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1768             try {
   1769                 MutableBoolean statusOk = new MutableBoolean(false);
   1770                 mISupplicantStaNetwork.getEapIdentity((SupplicantStatus status,
   1771                         ArrayList<Byte> identityValue) -> {
   1772                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1773                     if (statusOk.value) {
   1774                         this.mEapIdentity = identityValue;
   1775                     } else {
   1776                         checkStatusAndLogFailure(status, methodStr);
   1777                     }
   1778                 });
   1779                 return statusOk.value;
   1780             } catch (RemoteException e) {
   1781                 handleRemoteException(e, methodStr);
   1782                 return false;
   1783             }
   1784         }
   1785     }
   1786     /** See ISupplicantStaNetwork.hal for documentation */
   1787     private boolean getEapAnonymousIdentity() {
   1788         synchronized (mLock) {
   1789             final String methodStr = "getEapAnonymousIdentity";
   1790             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1791             try {
   1792                 MutableBoolean statusOk = new MutableBoolean(false);
   1793                 mISupplicantStaNetwork.getEapAnonymousIdentity((SupplicantStatus status,
   1794                         ArrayList<Byte> identityValue) -> {
   1795                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1796                     if (statusOk.value) {
   1797                         this.mEapAnonymousIdentity = identityValue;
   1798                     } else {
   1799                         checkStatusAndLogFailure(status, methodStr);
   1800                     }
   1801                 });
   1802                 return statusOk.value;
   1803             } catch (RemoteException e) {
   1804                 handleRemoteException(e, methodStr);
   1805                 return false;
   1806             }
   1807         }
   1808     }
   1809 
   1810     /**
   1811      * A wrapping method for getEapAnonymousIdentity().
   1812      * This get anonymous identity from supplicant and returns it as a string.
   1813      *
   1814      * @return anonymous identity string if succeeds, null otherwise.
   1815      */
   1816     public String fetchEapAnonymousIdentity() {
   1817         synchronized (mLock) {
   1818             if (!getEapAnonymousIdentity()) {
   1819                 return null;
   1820             }
   1821             return NativeUtil.stringFromByteArrayList(mEapAnonymousIdentity);
   1822         }
   1823     }
   1824 
   1825     /** See ISupplicantStaNetwork.hal for documentation */
   1826     private boolean getEapPassword() {
   1827         synchronized (mLock) {
   1828             final String methodStr = "getEapPassword";
   1829             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1830             try {
   1831                 MutableBoolean statusOk = new MutableBoolean(false);
   1832                 mISupplicantStaNetwork.getEapPassword((SupplicantStatus status,
   1833                         ArrayList<Byte> passwordValue) -> {
   1834                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1835                     if (statusOk.value) {
   1836                         this.mEapPassword = passwordValue;
   1837                     } else {
   1838                         checkStatusAndLogFailure(status, methodStr);
   1839                     }
   1840                 });
   1841                 return statusOk.value;
   1842             } catch (RemoteException e) {
   1843                 handleRemoteException(e, methodStr);
   1844                 return false;
   1845             }
   1846         }
   1847     }
   1848     /** See ISupplicantStaNetwork.hal for documentation */
   1849     private boolean getEapCACert() {
   1850         synchronized (mLock) {
   1851             final String methodStr = "getEapCACert";
   1852             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1853             try {
   1854                 MutableBoolean statusOk = new MutableBoolean(false);
   1855                 mISupplicantStaNetwork.getEapCACert((SupplicantStatus status, String pathValue) -> {
   1856                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1857                     if (statusOk.value) {
   1858                         this.mEapCACert = pathValue;
   1859                     } else {
   1860                         checkStatusAndLogFailure(status, methodStr);
   1861                     }
   1862                 });
   1863                 return statusOk.value;
   1864             } catch (RemoteException e) {
   1865                 handleRemoteException(e, methodStr);
   1866                 return false;
   1867             }
   1868         }
   1869     }
   1870     /** See ISupplicantStaNetwork.hal for documentation */
   1871     private boolean getEapCAPath() {
   1872         synchronized (mLock) {
   1873             final String methodStr = "getEapCAPath";
   1874             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1875             try {
   1876                 MutableBoolean statusOk = new MutableBoolean(false);
   1877                 mISupplicantStaNetwork.getEapCAPath((SupplicantStatus status, String pathValue) -> {
   1878                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1879                     if (statusOk.value) {
   1880                         this.mEapCAPath = pathValue;
   1881                     } else {
   1882                         checkStatusAndLogFailure(status, methodStr);
   1883                     }
   1884                 });
   1885                 return statusOk.value;
   1886             } catch (RemoteException e) {
   1887                 handleRemoteException(e, methodStr);
   1888                 return false;
   1889             }
   1890         }
   1891     }
   1892     /** See ISupplicantStaNetwork.hal for documentation */
   1893     private boolean getEapClientCert() {
   1894         synchronized (mLock) {
   1895             final String methodStr = "getEapClientCert";
   1896             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1897             try {
   1898                 MutableBoolean statusOk = new MutableBoolean(false);
   1899                 mISupplicantStaNetwork.getEapClientCert((SupplicantStatus status,
   1900                         String pathValue) -> {
   1901                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1902                     if (statusOk.value) {
   1903                         this.mEapClientCert = pathValue;
   1904                     } else {
   1905                         checkStatusAndLogFailure(status, methodStr);
   1906                     }
   1907                 });
   1908                 return statusOk.value;
   1909             } catch (RemoteException e) {
   1910                 handleRemoteException(e, methodStr);
   1911                 return false;
   1912             }
   1913         }
   1914     }
   1915     /** See ISupplicantStaNetwork.hal for documentation */
   1916     private boolean getEapPrivateKeyId() {
   1917         synchronized (mLock) {
   1918             final String methodStr = "getEapPrivateKeyId";
   1919             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1920             try {
   1921                 MutableBoolean statusOk = new MutableBoolean(false);
   1922                 mISupplicantStaNetwork.getEapPrivateKeyId((SupplicantStatus status,
   1923                         String idValue) -> {
   1924                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1925                     if (statusOk.value) {
   1926                         this.mEapPrivateKeyId = idValue;
   1927                     } else {
   1928                         checkStatusAndLogFailure(status, methodStr);
   1929                     }
   1930                 });
   1931                 return statusOk.value;
   1932             } catch (RemoteException e) {
   1933                 handleRemoteException(e, methodStr);
   1934                 return false;
   1935             }
   1936         }
   1937     }
   1938     /** See ISupplicantStaNetwork.hal for documentation */
   1939     private boolean getEapSubjectMatch() {
   1940         synchronized (mLock) {
   1941             final String methodStr = "getEapSubjectMatch";
   1942             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1943             try {
   1944                 MutableBoolean statusOk = new MutableBoolean(false);
   1945                 mISupplicantStaNetwork.getEapSubjectMatch((SupplicantStatus status,
   1946                         String matchValue) -> {
   1947                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1948                     if (statusOk.value) {
   1949                         this.mEapSubjectMatch = matchValue;
   1950                     } else {
   1951                         checkStatusAndLogFailure(status, methodStr);
   1952                     }
   1953                 });
   1954                 return statusOk.value;
   1955             } catch (RemoteException e) {
   1956                 handleRemoteException(e, methodStr);
   1957                 return false;
   1958             }
   1959         }
   1960     }
   1961     /** See ISupplicantStaNetwork.hal for documentation */
   1962     private boolean getEapAltSubjectMatch() {
   1963         synchronized (mLock) {
   1964             final String methodStr = "getEapAltSubjectMatch";
   1965             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1966             try {
   1967                 MutableBoolean statusOk = new MutableBoolean(false);
   1968                 mISupplicantStaNetwork.getEapAltSubjectMatch((SupplicantStatus status,
   1969                         String matchValue) -> {
   1970                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1971                     if (statusOk.value) {
   1972                         this.mEapAltSubjectMatch = matchValue;
   1973                     } else {
   1974                         checkStatusAndLogFailure(status, methodStr);
   1975                     }
   1976                 });
   1977                 return statusOk.value;
   1978             } catch (RemoteException e) {
   1979                 handleRemoteException(e, methodStr);
   1980                 return false;
   1981             }
   1982         }
   1983     }
   1984     /** See ISupplicantStaNetwork.hal for documentation */
   1985     private boolean getEapEngine() {
   1986         synchronized (mLock) {
   1987             final String methodStr = "getEapEngine";
   1988             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   1989             try {
   1990                 MutableBoolean statusOk = new MutableBoolean(false);
   1991                 mISupplicantStaNetwork.getEapEngine((SupplicantStatus status,
   1992                         boolean enabledValue) -> {
   1993                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   1994                     if (statusOk.value) {
   1995                         this.mEapEngine = enabledValue;
   1996                     } else {
   1997                         checkStatusAndLogFailure(status, methodStr);
   1998                     }
   1999                 });
   2000                 return statusOk.value;
   2001             } catch (RemoteException e) {
   2002                 handleRemoteException(e, methodStr);
   2003                 return false;
   2004             }
   2005         }
   2006     }
   2007     /** See ISupplicantStaNetwork.hal for documentation */
   2008     private boolean getEapEngineID() {
   2009         synchronized (mLock) {
   2010             final String methodStr = "getEapEngineID";
   2011             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2012             try {
   2013                 MutableBoolean statusOk = new MutableBoolean(false);
   2014                 mISupplicantStaNetwork.getEapEngineID((SupplicantStatus status, String idValue) -> {
   2015                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   2016                     if (statusOk.value) {
   2017                         this.mEapEngineID = idValue;
   2018                     } else {
   2019                         checkStatusAndLogFailure(status, methodStr);
   2020                     }
   2021                 });
   2022                 return statusOk.value;
   2023             } catch (RemoteException e) {
   2024                 handleRemoteException(e, methodStr);
   2025                 return false;
   2026             }
   2027         }
   2028     }
   2029     /** See ISupplicantStaNetwork.hal for documentation */
   2030     private boolean getEapDomainSuffixMatch() {
   2031         synchronized (mLock) {
   2032             final String methodStr = "getEapDomainSuffixMatch";
   2033             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2034             try {
   2035                 MutableBoolean statusOk = new MutableBoolean(false);
   2036                 mISupplicantStaNetwork.getEapDomainSuffixMatch((SupplicantStatus status,
   2037                         String matchValue) -> {
   2038                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   2039                     if (statusOk.value) {
   2040                         this.mEapDomainSuffixMatch = matchValue;
   2041                     } else {
   2042                         checkStatusAndLogFailure(status, methodStr);
   2043                     }
   2044                 });
   2045                 return statusOk.value;
   2046             } catch (RemoteException e) {
   2047                 handleRemoteException(e, methodStr);
   2048                 return false;
   2049             }
   2050         }
   2051     }
   2052     /** See ISupplicantStaNetwork.hal for documentation */
   2053     private boolean getIdStr() {
   2054         synchronized (mLock) {
   2055             final String methodStr = "getIdStr";
   2056             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2057             try {
   2058                 MutableBoolean statusOk = new MutableBoolean(false);
   2059                 mISupplicantStaNetwork.getIdStr((SupplicantStatus status, String idString) -> {
   2060                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
   2061                     if (statusOk.value) {
   2062                         this.mIdStr = idString;
   2063                     } else {
   2064                         checkStatusAndLogFailure(status, methodStr);
   2065                     }
   2066                 });
   2067                 return statusOk.value;
   2068             } catch (RemoteException e) {
   2069                 handleRemoteException(e, methodStr);
   2070                 return false;
   2071             }
   2072         }
   2073     }
   2074     /** See ISupplicantStaNetwork.hal for documentation */
   2075     private boolean enable(boolean noConnect) {
   2076         synchronized (mLock) {
   2077             final String methodStr = "enable";
   2078             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2079             try {
   2080                 SupplicantStatus status =  mISupplicantStaNetwork.enable(noConnect);
   2081                 return checkStatusAndLogFailure(status, methodStr);
   2082             } catch (RemoteException e) {
   2083                 handleRemoteException(e, methodStr);
   2084                 return false;
   2085             }
   2086         }
   2087     }
   2088     /** See ISupplicantStaNetwork.hal for documentation */
   2089     private boolean disable() {
   2090         synchronized (mLock) {
   2091             final String methodStr = "disable";
   2092             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2093             try {
   2094                 SupplicantStatus status =  mISupplicantStaNetwork.disable();
   2095                 return checkStatusAndLogFailure(status, methodStr);
   2096             } catch (RemoteException e) {
   2097                 handleRemoteException(e, methodStr);
   2098                 return false;
   2099             }
   2100         }
   2101     }
   2102 
   2103     /**
   2104      * Trigger a connection to this network.
   2105      *
   2106      * @return true if it succeeds, false otherwise.
   2107      */
   2108     public boolean select() {
   2109         synchronized (mLock) {
   2110             final String methodStr = "select";
   2111             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2112             try {
   2113                 SupplicantStatus status =  mISupplicantStaNetwork.select();
   2114                 return checkStatusAndLogFailure(status, methodStr);
   2115             } catch (RemoteException e) {
   2116                 handleRemoteException(e, methodStr);
   2117                 return false;
   2118             }
   2119         }
   2120     }
   2121 
   2122     /**
   2123      * Send GSM auth response.
   2124      *
   2125      * @param paramsStr Response params as a string.
   2126      * @return true if succeeds, false otherwise.
   2127      */
   2128     public boolean sendNetworkEapSimGsmAuthResponse(String paramsStr) {
   2129         synchronized (mLock) {
   2130             try {
   2131                 Matcher match = GSM_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
   2132                 ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params =
   2133                         new ArrayList<>();
   2134                 while (match.find()) {
   2135                     if (match.groupCount() != 2) {
   2136                         Log.e(TAG, "Malformed gsm auth response params: " + paramsStr);
   2137                         return false;
   2138                     }
   2139                     ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams param =
   2140                             new ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams();
   2141                     byte[] kc = NativeUtil.hexStringToByteArray(match.group(1));
   2142                     if (kc == null || kc.length != param.kc.length) {
   2143                         Log.e(TAG, "Invalid kc value: " + match.group(1));
   2144                         return false;
   2145                     }
   2146                     byte[] sres = NativeUtil.hexStringToByteArray(match.group(2));
   2147                     if (sres == null || sres.length != param.sres.length) {
   2148                         Log.e(TAG, "Invalid sres value: " + match.group(2));
   2149                         return false;
   2150                     }
   2151                     System.arraycopy(kc, 0, param.kc, 0, param.kc.length);
   2152                     System.arraycopy(sres, 0, param.sres, 0, param.sres.length);
   2153                     params.add(param);
   2154                 }
   2155                 // The number of kc/sres pairs can either be 2 or 3 depending on the request.
   2156                 if (params.size() > 3 || params.size() < 2) {
   2157                     Log.e(TAG, "Malformed gsm auth response params: " + paramsStr);
   2158                     return false;
   2159                 }
   2160                 return sendNetworkEapSimGsmAuthResponse(params);
   2161             } catch (IllegalArgumentException e) {
   2162                 Log.e(TAG, "Illegal argument " + paramsStr, e);
   2163                 return false;
   2164             }
   2165         }
   2166     }
   2167 
   2168     /** See ISupplicantStaNetwork.hal for documentation */
   2169     private boolean sendNetworkEapSimGsmAuthResponse(
   2170             ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params) {
   2171         synchronized (mLock) {
   2172             final String methodStr = "sendNetworkEapSimGsmAuthResponse";
   2173             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2174             try {
   2175                 SupplicantStatus status =
   2176                         mISupplicantStaNetwork.sendNetworkEapSimGsmAuthResponse(params);
   2177                 return checkStatusAndLogFailure(status, methodStr);
   2178             } catch (RemoteException e) {
   2179                 handleRemoteException(e, methodStr);
   2180                 return false;
   2181             }
   2182         }
   2183     }
   2184     /** See ISupplicantStaNetwork.hal for documentation */
   2185     public boolean sendNetworkEapSimGsmAuthFailure() {
   2186         synchronized (mLock) {
   2187             final String methodStr = "sendNetworkEapSimGsmAuthFailure";
   2188             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2189             try {
   2190                 SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimGsmAuthFailure();
   2191                 return checkStatusAndLogFailure(status, methodStr);
   2192             } catch (RemoteException e) {
   2193                 handleRemoteException(e, methodStr);
   2194                 return false;
   2195             }
   2196         }
   2197     }
   2198     /**
   2199      * Send UMTS auth response.
   2200      *
   2201      * @param paramsStr Response params as a string.
   2202      * @return true if succeeds, false otherwise.
   2203      */
   2204     public boolean sendNetworkEapSimUmtsAuthResponse(String paramsStr) {
   2205         synchronized (mLock) {
   2206             try {
   2207                 Matcher match = UMTS_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
   2208                 if (!match.find() || match.groupCount() != 3) {
   2209                     Log.e(TAG, "Malformed umts auth response params: " + paramsStr);
   2210                     return false;
   2211                 }
   2212                 ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params =
   2213                         new ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams();
   2214                 byte[] ik = NativeUtil.hexStringToByteArray(match.group(1));
   2215                 if (ik == null || ik.length != params.ik.length) {
   2216                     Log.e(TAG, "Invalid ik value: " + match.group(1));
   2217                     return false;
   2218                 }
   2219                 byte[] ck = NativeUtil.hexStringToByteArray(match.group(2));
   2220                 if (ck == null || ck.length != params.ck.length) {
   2221                     Log.e(TAG, "Invalid ck value: " + match.group(2));
   2222                     return false;
   2223                 }
   2224                 byte[] res = NativeUtil.hexStringToByteArray(match.group(3));
   2225                 if (res == null || res.length == 0) {
   2226                     Log.e(TAG, "Invalid res value: " + match.group(3));
   2227                     return false;
   2228                 }
   2229                 System.arraycopy(ik, 0, params.ik, 0, params.ik.length);
   2230                 System.arraycopy(ck, 0, params.ck, 0, params.ck.length);
   2231                 for (byte b : res) {
   2232                     params.res.add(b);
   2233                 }
   2234                 return sendNetworkEapSimUmtsAuthResponse(params);
   2235             } catch (IllegalArgumentException e) {
   2236                 Log.e(TAG, "Illegal argument " + paramsStr, e);
   2237                 return false;
   2238             }
   2239         }
   2240     }
   2241 
   2242     /** See ISupplicantStaNetwork.hal for documentation */
   2243     private boolean sendNetworkEapSimUmtsAuthResponse(
   2244             ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params) {
   2245         synchronized (mLock) {
   2246             final String methodStr = "sendNetworkEapSimUmtsAuthResponse";
   2247             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2248             try {
   2249                 SupplicantStatus status =
   2250                         mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthResponse(params);
   2251                 return checkStatusAndLogFailure(status, methodStr);
   2252             } catch (RemoteException e) {
   2253                 handleRemoteException(e, methodStr);
   2254                 return false;
   2255             }
   2256         }
   2257     }
   2258     /**
   2259      * Send UMTS auts response.
   2260      *
   2261      * @param paramsStr Response params as a string.
   2262      * @return true if succeeds, false otherwise.
   2263      */
   2264     public boolean sendNetworkEapSimUmtsAutsResponse(String paramsStr) {
   2265         synchronized (mLock) {
   2266             try {
   2267                 Matcher match = UMTS_AUTS_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
   2268                 if (!match.find() || match.groupCount() != 1) {
   2269                     Log.e(TAG, "Malformed umts auts response params: " + paramsStr);
   2270                     return false;
   2271                 }
   2272                 byte[] auts = NativeUtil.hexStringToByteArray(match.group(1));
   2273                 if (auts == null || auts.length != 14) {
   2274                     Log.e(TAG, "Invalid auts value: " + match.group(1));
   2275                     return false;
   2276                 }
   2277                 return sendNetworkEapSimUmtsAutsResponse(auts);
   2278             } catch (IllegalArgumentException e) {
   2279                 Log.e(TAG, "Illegal argument " + paramsStr, e);
   2280                 return false;
   2281             }
   2282         }
   2283     }
   2284     /** See ISupplicantStaNetwork.hal for documentation */
   2285     private boolean sendNetworkEapSimUmtsAutsResponse(byte[/* 14 */] auts) {
   2286         synchronized (mLock) {
   2287             final String methodStr = "sendNetworkEapSimUmtsAutsResponse";
   2288             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2289             try {
   2290                 SupplicantStatus status =
   2291                         mISupplicantStaNetwork.sendNetworkEapSimUmtsAutsResponse(auts);
   2292                 return checkStatusAndLogFailure(status, methodStr);
   2293             } catch (RemoteException e) {
   2294                 handleRemoteException(e, methodStr);
   2295                 return false;
   2296             }
   2297         }
   2298     }
   2299     /** See ISupplicantStaNetwork.hal for documentation */
   2300     public boolean sendNetworkEapSimUmtsAuthFailure() {
   2301         synchronized (mLock) {
   2302             final String methodStr = "sendNetworkEapSimUmtsAuthFailure";
   2303             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2304             try {
   2305                 SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthFailure();
   2306                 return checkStatusAndLogFailure(status, methodStr);
   2307             } catch (RemoteException e) {
   2308                 handleRemoteException(e, methodStr);
   2309                 return false;
   2310             }
   2311         }
   2312     }
   2313 
   2314     /**
   2315      * Method to mock out the V1_1 ISupplicantStaNetwork retrieval in unit tests.
   2316      *
   2317      * @return 1.1 ISupplicantStaNetwork object if the device is running the 1.1 supplicant hal
   2318      * service, null otherwise.
   2319      */
   2320     protected android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork
   2321     getSupplicantStaNetworkForV1_1Mockable() {
   2322         if (mISupplicantStaNetwork == null) return null;
   2323         return android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork.castFrom(
   2324                 mISupplicantStaNetwork);
   2325     }
   2326 
   2327     /**
   2328      * Send eap identity response.
   2329      *
   2330      * @param identityStr identity used for EAP-Identity
   2331      * @param encryptedIdentityStr encrypted identity used for EAP-AKA/EAP-SIM
   2332      * @return true if succeeds, false otherwise.
   2333      */
   2334     public boolean sendNetworkEapIdentityResponse(String identityStr,
   2335                                                   String encryptedIdentityStr) {
   2336         synchronized (mLock) {
   2337             try {
   2338                 ArrayList<Byte> unencryptedIdentity =
   2339                         NativeUtil.stringToByteArrayList(identityStr);
   2340                 ArrayList<Byte> encryptedIdentity = null;
   2341                 if (!TextUtils.isEmpty(encryptedIdentityStr)) {
   2342                     encryptedIdentity = NativeUtil.stringToByteArrayList(encryptedIdentityStr);
   2343                 }
   2344                 return sendNetworkEapIdentityResponse(unencryptedIdentity, encryptedIdentity);
   2345             } catch (IllegalArgumentException e) {
   2346                 Log.e(TAG, "Illegal argument " + identityStr + "," + encryptedIdentityStr, e);
   2347                 return false;
   2348             }
   2349         }
   2350     }
   2351     /** See ISupplicantStaNetwork.hal for documentation */
   2352     private boolean sendNetworkEapIdentityResponse(ArrayList<Byte> unencryptedIdentity,
   2353                                                    ArrayList<Byte> encryptedIdentity) {
   2354         synchronized (mLock) {
   2355             final String methodStr = "sendNetworkEapIdentityResponse";
   2356             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
   2357             try {
   2358                 SupplicantStatus status;
   2359                 android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork
   2360                         iSupplicantStaNetworkV11 =
   2361                         getSupplicantStaNetworkForV1_1Mockable();
   2362 
   2363                 if (iSupplicantStaNetworkV11 != null && encryptedIdentity != null) {
   2364                     status = iSupplicantStaNetworkV11.sendNetworkEapIdentityResponse_1_1(
   2365                             unencryptedIdentity, encryptedIdentity);
   2366                 } else {
   2367                     status = mISupplicantStaNetwork.sendNetworkEapIdentityResponse(
   2368                             unencryptedIdentity);
   2369                 }
   2370 
   2371                 return checkStatusAndLogFailure(status, methodStr);
   2372             } catch (RemoteException e) {
   2373                 handleRemoteException(e, methodStr);
   2374                 return false;
   2375             }
   2376         }
   2377     }
   2378 
   2379     /**
   2380      * Retrieve the NFC token for this network.
   2381      *
   2382      * @return Hex string corresponding to the NFC token or null for failure.
   2383      */
   2384     public String getWpsNfcConfigurationToken() {
   2385         synchronized (mLock) {
   2386             ArrayList<Byte> token = getWpsNfcConfigurationTokenInternal();
   2387             if (token == null) {
   2388                 return null;
   2389             }
   2390             return NativeUtil.hexStringFromByteArray(NativeUtil.byteArrayFromArrayList(token));
   2391         }
   2392     }
   2393 
   2394     /** See ISupplicantStaNetwork.hal for documentation */
   2395     private ArrayList<Byte> getWpsNfcConfigurationTokenInternal() {
   2396         synchronized (mLock) {
   2397             final String methodStr = "getWpsNfcConfigurationToken";
   2398             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return null;
   2399             final Mutable<ArrayList<Byte>> gotToken = new Mutable<>();
   2400             try {
   2401                 mISupplicantStaNetwork.getWpsNfcConfigurationToken(
   2402                         (SupplicantStatus status, ArrayList<Byte> token) -> {
   2403                             if (checkStatusAndLogFailure(status, methodStr)) {
   2404                                 gotToken.value = token;
   2405                             }
   2406                         });
   2407             } catch (RemoteException e) {
   2408                 handleRemoteException(e, methodStr);
   2409             }
   2410             return gotToken.value;
   2411         }
   2412     }
   2413 
   2414     /**
   2415      * Returns true if provided status code is SUCCESS, logs debug message and returns false
   2416      * otherwise
   2417      */
   2418     private boolean checkStatusAndLogFailure(SupplicantStatus status, final String methodStr) {
   2419         synchronized (mLock) {
   2420             if (status.code != SupplicantStatusCode.SUCCESS) {
   2421                 Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + status);
   2422                 return false;
   2423             } else {
   2424                 if (mVerboseLoggingEnabled) {
   2425                     Log.d(TAG, "ISupplicantStaNetwork." + methodStr + " succeeded");
   2426                 }
   2427                 return true;
   2428             }
   2429         }
   2430     }
   2431 
   2432     /**
   2433      * Helper function to log callbacks.
   2434      */
   2435     private void logCallback(final String methodStr) {
   2436         synchronized (mLock) {
   2437             if (mVerboseLoggingEnabled) {
   2438                 Log.d(TAG, "ISupplicantStaNetworkCallback." + methodStr + " received");
   2439             }
   2440         }
   2441     }
   2442 
   2443     /**
   2444      * Returns false if ISupplicantStaNetwork is null, and logs failure of methodStr
   2445      */
   2446     private boolean checkISupplicantStaNetworkAndLogFailure(final String methodStr) {
   2447         synchronized (mLock) {
   2448             if (mISupplicantStaNetwork == null) {
   2449                 Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaNetwork is null");
   2450                 return false;
   2451             }
   2452             return true;
   2453         }
   2454     }
   2455 
   2456     private void handleRemoteException(RemoteException e, String methodStr) {
   2457         synchronized (mLock) {
   2458             mISupplicantStaNetwork = null;
   2459             Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed with exception", e);
   2460         }
   2461     }
   2462 
   2463     /**
   2464      * Adds FT flags for networks if the device supports it.
   2465      */
   2466     private BitSet addFastTransitionFlags(BitSet keyManagementFlags) {
   2467         synchronized (mLock) {
   2468             if (!mSystemSupportsFastBssTransition) {
   2469                 return keyManagementFlags;
   2470             }
   2471             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
   2472             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
   2473                 modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_PSK);
   2474             }
   2475             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
   2476                 modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_EAP);
   2477             }
   2478             return modifiedFlags;
   2479         }
   2480     }
   2481 
   2482     /**
   2483      * Removes FT flags for networks if the device supports it.
   2484      */
   2485     private BitSet removeFastTransitionFlags(BitSet keyManagementFlags) {
   2486         synchronized (mLock) {
   2487             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
   2488             modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_PSK);
   2489             modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_EAP);
   2490             return modifiedFlags;
   2491         }
   2492     }
   2493 
   2494     /**
   2495      * Creates the JSON encoded network extra using the map of string key, value pairs.
   2496      */
   2497     public static String createNetworkExtra(Map<String, String> values) {
   2498         final String encoded;
   2499         try {
   2500             encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8");
   2501         } catch (NullPointerException e) {
   2502             Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
   2503             return null;
   2504         } catch (UnsupportedEncodingException e) {
   2505             Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
   2506             return null;
   2507         }
   2508         return encoded;
   2509     }
   2510 
   2511     /**
   2512      * Parse the network extra JSON encoded string to a map of string key, value pairs.
   2513      */
   2514     public static Map<String, String> parseNetworkExtra(String encoded) {
   2515         if (TextUtils.isEmpty(encoded)) {
   2516             return null;
   2517         }
   2518         try {
   2519             // This method reads a JSON dictionary that was written by setNetworkExtra(). However,
   2520             // on devices that upgraded from Marshmallow, it may encounter a legacy value instead -
   2521             // an FQDN stored as a plain string. If such a value is encountered, the JSONObject
   2522             // constructor will thrown a JSONException and the method will return null.
   2523             final JSONObject json = new JSONObject(URLDecoder.decode(encoded, "UTF-8"));
   2524             final Map<String, String> values = new HashMap<>();
   2525             final Iterator<?> it = json.keys();
   2526             while (it.hasNext()) {
   2527                 final String key = (String) it.next();
   2528                 final Object value = json.get(key);
   2529                 if (value instanceof String) {
   2530                     values.put(key, (String) value);
   2531                 }
   2532             }
   2533             return values;
   2534         } catch (UnsupportedEncodingException e) {
   2535             Log.e(TAG, "Unable to deserialize networkExtra: " + e.toString());
   2536             return null;
   2537         } catch (JSONException e) {
   2538             // This is not necessarily an error. This exception will also occur if we encounter a
   2539             // legacy FQDN stored as a plain string. We want to return null in this case as no JSON
   2540             // dictionary of extras was found.
   2541             return null;
   2542         }
   2543     }
   2544 
   2545     private class SupplicantStaNetworkHalCallback extends ISupplicantStaNetworkCallback.Stub {
   2546         /**
   2547          * Current configured network's framework network id.
   2548          */
   2549         private final int mFramewokNetworkId;
   2550         /**
   2551          * Current configured network's ssid.
   2552          */
   2553         private final String mSsid;
   2554 
   2555         SupplicantStaNetworkHalCallback(int framewokNetworkId, String ssid) {
   2556             mFramewokNetworkId = framewokNetworkId;
   2557             mSsid = ssid;
   2558         }
   2559 
   2560         @Override
   2561         public void onNetworkEapSimGsmAuthRequest(
   2562                 ISupplicantStaNetworkCallback.NetworkRequestEapSimGsmAuthParams params) {
   2563             synchronized (mLock) {
   2564                 logCallback("onNetworkEapSimGsmAuthRequest");
   2565                 String[] data = new String[params.rands.size()];
   2566                 int i = 0;
   2567                 for (byte[] rand : params.rands) {
   2568                     data[i++] = NativeUtil.hexStringFromByteArray(rand);
   2569                 }
   2570                 mWifiMonitor.broadcastNetworkGsmAuthRequestEvent(
   2571                         mIfaceName, mFramewokNetworkId, mSsid, data);
   2572             }
   2573         }
   2574 
   2575         @Override
   2576         public void onNetworkEapSimUmtsAuthRequest(
   2577                 ISupplicantStaNetworkCallback.NetworkRequestEapSimUmtsAuthParams params) {
   2578             synchronized (mLock) {
   2579                 logCallback("onNetworkEapSimUmtsAuthRequest");
   2580                 String randHex = NativeUtil.hexStringFromByteArray(params.rand);
   2581                 String autnHex = NativeUtil.hexStringFromByteArray(params.autn);
   2582                 String[] data = {randHex, autnHex};
   2583                 mWifiMonitor.broadcastNetworkUmtsAuthRequestEvent(
   2584                         mIfaceName, mFramewokNetworkId, mSsid, data);
   2585             }
   2586         }
   2587 
   2588         @Override
   2589         public void onNetworkEapIdentityRequest() {
   2590             synchronized (mLock) {
   2591                 logCallback("onNetworkEapIdentityRequest");
   2592                 mWifiMonitor.broadcastNetworkIdentityRequestEvent(
   2593                         mIfaceName, mFramewokNetworkId, mSsid);
   2594             }
   2595         }
   2596     }
   2597 }
   2598