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