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