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