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