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