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