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