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.net.wifi.WifiEnterpriseConfig.Ocsp;
26 import android.os.RemoteException;
27 import android.text.TextUtils;
28 import android.util.Log;
29 import android.util.MutableBoolean;
30 
31 import com.android.internal.annotations.VisibleForTesting;
32 import com.android.server.wifi.util.ArrayUtils;
33 import com.android.server.wifi.util.GeneralUtil.Mutable;
34 import com.android.server.wifi.util.NativeUtil;
35 import com.android.wifi.resources.R;
36 
37 import org.json.JSONException;
38 import org.json.JSONObject;
39 
40 import java.io.UnsupportedEncodingException;
41 import java.net.URLDecoder;
42 import java.net.URLEncoder;
43 import java.util.ArrayList;
44 import java.util.BitSet;
45 import java.util.HashMap;
46 import java.util.Iterator;
47 import java.util.Map;
48 import java.util.regex.Matcher;
49 import java.util.regex.Pattern;
50 
51 import javax.annotation.concurrent.ThreadSafe;
52 
53 
54 /**
55  * Wrapper class for ISupplicantStaNetwork HAL calls. Gets and sets supplicant sta network variables
56  * and interacts with networks.
57  * Public fields should be treated as invalid until their 'get' method is called, which will set the
58  * value if it returns true
59  * To maintain thread-safety, the locking protocol is that every non-static method (regardless of
60  * access level) acquires mLock.
61  */
62 @ThreadSafe
63 public class SupplicantStaNetworkHal {
64     private static final String TAG = "SupplicantStaNetworkHal";
65     @VisibleForTesting
66     public static final String ID_STRING_KEY_FQDN = "fqdn";
67     @VisibleForTesting
68     public static final String ID_STRING_KEY_CREATOR_UID = "creatorUid";
69     @VisibleForTesting
70     public static final String ID_STRING_KEY_CONFIG_KEY = "configKey";
71 
72     /**
73      * Regex pattern for extracting the GSM sim authentication response params from a string.
74      * Matches a strings like the following: "[:<kc_value>:<sres_value>]";
75      */
76     private static final Pattern GSM_AUTH_RESPONSE_PARAMS_PATTERN =
77             Pattern.compile(":([0-9a-fA-F]+):([0-9a-fA-F]+)");
78     /**
79      * Regex pattern for extracting the UMTS sim authentication response params from a string.
80      * Matches a strings like the following: ":<ik_value>:<ck_value>:<res_value>";
81      */
82     private static final Pattern UMTS_AUTH_RESPONSE_PARAMS_PATTERN =
83             Pattern.compile("^:([0-9a-fA-F]+):([0-9a-fA-F]+):([0-9a-fA-F]+)$");
84     /**
85      * Regex pattern for extracting the UMTS sim auts response params from a string.
86      * Matches a strings like the following: ":<auts_value>";
87      */
88     private static final Pattern UMTS_AUTS_RESPONSE_PARAMS_PATTERN =
89             Pattern.compile("^:([0-9a-fA-F]+)$");
90 
91     private final Object mLock = new Object();
92     private final Context mContext;
93     private final String mIfaceName;
94     private final WifiMonitor mWifiMonitor;
95     private ISupplicantStaNetwork mISupplicantStaNetwork;
96     private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback;
97 
98     private boolean mVerboseLoggingEnabled = false;
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 int mGroupMgmtCipherMask;
110     private String mPskPassphrase;
111     private String mSaePassword;
112     private String mSaePasswordId;
113     private byte[] mPsk;
114     private ArrayList<Byte> mWepKey;
115     private int mWepTxKeyIdx;
116     private boolean mRequirePmf;
117     private String mIdStr;
118     private int mEapMethod;
119     private int mEapPhase2Method;
120     private ArrayList<Byte> mEapIdentity;
121     private ArrayList<Byte> mEapAnonymousIdentity;
122     private ArrayList<Byte> mEapPassword;
123     private String mEapCACert;
124     private String mEapCAPath;
125     private String mEapClientCert;
126     private String mEapPrivateKeyId;
127     private String mEapSubjectMatch;
128     private String mEapAltSubjectMatch;
129     private boolean mEapEngine;
130     private String mEapEngineID;
131     private String mEapDomainSuffixMatch;
132     private @Ocsp int mOcsp;
133     private String mWapiCertSuite;
134 
SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork, String ifaceName, Context context, WifiMonitor monitor)135     SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork, String ifaceName,
136             Context context, WifiMonitor monitor) {
137         mISupplicantStaNetwork = iSupplicantStaNetwork;
138         mContext = context;
139         mIfaceName = ifaceName;
140         mWifiMonitor = monitor;
141     }
142 
143     /**
144      * Enable/Disable verbose logging.
145      *
146      * @param enable true to enable, false to disable.
147      */
enableVerboseLogging(boolean enable)148     void enableVerboseLogging(boolean enable) {
149         synchronized (mLock) {
150             mVerboseLoggingEnabled = enable;
151         }
152     }
153 
154     /**
155      * Read network variables from wpa_supplicant into the provided WifiConfiguration object.
156      *
157      * @param config        WifiConfiguration object to be populated.
158      * @param networkExtras Map of network extras parsed from wpa_supplicant.
159      * @return true if succeeds, false otherwise.
160      * @throws IllegalArgumentException on malformed configuration params.
161      */
162     @VisibleForTesting
loadWifiConfiguration(WifiConfiguration config, Map<String, String> networkExtras)163     public boolean loadWifiConfiguration(WifiConfiguration config,
164             Map<String, String> networkExtras) {
165         synchronized (mLock) {
166             if (config == null) return false;
167             /** SSID */
168             config.SSID = null;
169             if (getSsid() && !ArrayUtils.isEmpty(mSsid)) {
170                 config.SSID = NativeUtil.encodeSsid(mSsid);
171             } else {
172                 Log.e(TAG, "failed to read ssid");
173                 return false;
174             }
175             /** Network Id */
176             config.networkId = -1;
177             if (getId()) {
178                 config.networkId = mNetworkId;
179             } else {
180                 Log.e(TAG, "getId failed");
181                 return false;
182             }
183             /** BSSID */
184             config.getNetworkSelectionStatus().setNetworkSelectionBSSID(null);
185             if (getBssid() && !ArrayUtils.isEmpty(mBssid)) {
186                 config.getNetworkSelectionStatus().setNetworkSelectionBSSID(
187                         NativeUtil.macAddressFromByteArray(mBssid));
188             }
189             /** Scan SSID (Is Hidden Network?) */
190             config.hiddenSSID = false;
191             if (getScanSsid()) {
192                 config.hiddenSSID = mScanSsid;
193             }
194             /** Require PMF*/
195             config.requirePmf = false;
196             if (getRequirePmf()) {
197                 config.requirePmf = mRequirePmf;
198             }
199             /** WEP keys **/
200             config.wepTxKeyIndex = -1;
201             if (getWepTxKeyIdx()) {
202                 config.wepTxKeyIndex = mWepTxKeyIdx;
203             }
204             for (int i = 0; i < 4; i++) {
205                 config.wepKeys[i] = null;
206                 if (getWepKey(i) && !ArrayUtils.isEmpty(mWepKey)) {
207                     config.wepKeys[i] = NativeUtil.bytesToHexOrQuotedString(mWepKey);
208                 }
209             }
210 
211             /** allowedKeyManagement */
212             if (getKeyMgmt()) {
213                 BitSet keyMgmtMask = supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask);
214                 config.allowedKeyManagement = removeFastTransitionFlags(keyMgmtMask);
215                 config.allowedKeyManagement = removeSha256KeyMgmtFlags(config.allowedKeyManagement);
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             /** allowedPairwiseCiphers */
238             if (getGroupMgmtCipher()) {
239                 config.allowedGroupManagementCiphers =
240                         supplicantToWifiConfigurationGroupMgmtCipherMask(mGroupMgmtCipherMask);
241             }
242 
243             /** PSK pass phrase */
244             config.preSharedKey = null;
245             if (getPskPassphrase() && !TextUtils.isEmpty(mPskPassphrase)) {
246                 if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WAPI_PSK)) {
247                     config.preSharedKey = mPskPassphrase;
248                 } else {
249                     config.preSharedKey = NativeUtil.addEnclosingQuotes(mPskPassphrase);
250                 }
251             } else if (getPsk() && !ArrayUtils.isEmpty(mPsk)) {
252                 config.preSharedKey = NativeUtil.hexStringFromByteArray(mPsk);
253             } /* Do not read SAE password */
254 
255             /** metadata: idstr */
256             if (getIdStr() && !TextUtils.isEmpty(mIdStr)) {
257                 Map<String, String> metadata = parseNetworkExtra(mIdStr);
258                 networkExtras.putAll(metadata);
259             } else {
260                 Log.w(TAG, "getIdStr failed or empty");
261             }
262 
263             /** WAPI Cert Suite */
264             if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WAPI_CERT)) {
265                 if (config.enterpriseConfig == null) {
266                     return false;
267                 }
268                 config.enterpriseConfig.setEapMethod(
269                         WifiEnterpriseConfig.Eap.WAPI_CERT);
270                 /** WAPI Certificate Suite. */
271                 if (getWapiCertSuite() && !TextUtils.isEmpty(mWapiCertSuite)) {
272                     config.enterpriseConfig.setWapiCertSuite(mWapiCertSuite);
273                 }
274                 return true;
275             }
276             return loadWifiEnterpriseConfig(config.SSID, config.enterpriseConfig);
277         }
278     }
279 
280     /**
281      * Save an entire WifiConfiguration to wpa_supplicant via HIDL.
282      *
283      * @param config WifiConfiguration object to be saved.
284      * @return true if succeeds, false otherwise.
285      * @throws IllegalArgumentException on malformed configuration params.
286      */
saveWifiConfiguration(WifiConfiguration config)287     public boolean saveWifiConfiguration(WifiConfiguration config) {
288         synchronized (mLock) {
289             if (config == null) return false;
290             /** SSID */
291             if (config.SSID != null) {
292                 if (!setSsid(NativeUtil.decodeSsid(config.SSID))) {
293                     Log.e(TAG, "failed to set SSID: " + config.SSID);
294                     return false;
295                 }
296             }
297             /** BSSID */
298             String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
299             if (bssidStr != null) {
300                 byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr);
301                 if (!setBssid(bssid)) {
302                     Log.e(TAG, "failed to set BSSID: " + bssidStr);
303                     return false;
304                 }
305             }
306             /** HiddenSSID */
307             if (!setScanSsid(config.hiddenSSID)) {
308                 Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID);
309                 return false;
310             }
311 
312             /** RequirePMF */
313             if (!setRequirePmf(config.requirePmf)) {
314                 Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePmf);
315                 return false;
316             }
317             /** Key Management Scheme */
318             if (config.allowedKeyManagement.cardinality() != 0) {
319                 // Add FT flags if supported.
320                 BitSet keyMgmtMask = addFastTransitionFlags(config.allowedKeyManagement);
321                 // Add SHA256 key management flags.
322                 keyMgmtMask = addSha256KeyMgmtFlags(keyMgmtMask);
323                 if (!setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(keyMgmtMask))) {
324                     Log.e(TAG, "failed to set Key Management");
325                     return false;
326                 }
327                 // Check and set SuiteB configurations.
328                 if (keyMgmtMask.get(WifiConfiguration.KeyMgmt.SUITE_B_192)
329                         && !saveSuiteBConfig(config)) {
330                     Log.e(TAG, "Failed to set Suite-B-192 configuration");
331                     return false;
332                 }
333             }
334             /** Security Protocol */
335             if (config.allowedProtocols.cardinality() != 0
336                     && !setProto(wifiConfigurationToSupplicantProtoMask(config.allowedProtocols))) {
337                 Log.e(TAG, "failed to set Security Protocol");
338                 return false;
339             }
340             /** Auth Algorithm */
341             if (config.allowedAuthAlgorithms.cardinality() != 0
342                     && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask(
343                     config.allowedAuthAlgorithms))) {
344                 Log.e(TAG, "failed to set AuthAlgorithm");
345                 return false;
346             }
347             /** Group Cipher */
348             if (config.allowedGroupCiphers.cardinality() != 0
349                     && (!setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
350                     config.allowedGroupCiphers)))) {
351                 Log.e(TAG, "failed to set Group Cipher");
352                 return false;
353             }
354             /** Pairwise Cipher*/
355             if (config.allowedPairwiseCiphers.cardinality() != 0
356                     && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
357                     config.allowedPairwiseCiphers))) {
358                 Log.e(TAG, "failed to set PairwiseCipher");
359                 return false;
360             }
361             /** Pre Shared Key */
362             // For PSK, this can either be quoted ASCII passphrase or hex string for raw psk.
363             // For SAE, password must be a quoted ASCII string
364             if (config.preSharedKey != null) {
365                 if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WAPI_PSK)) {
366                     if (!setPskPassphrase(config.preSharedKey)) {
367                         Log.e(TAG, "failed to set wapi psk passphrase");
368                         return false;
369                     }
370                 } else if (config.preSharedKey.startsWith("\"")) {
371                     if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
372                         /* WPA3 case, field is SAE Password */
373                         if (!setSaePassword(
374                                 NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
375                             Log.e(TAG, "failed to set sae password");
376                             return false;
377                         }
378                     } else {
379                         if (!setPskPassphrase(
380                                 NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
381                             Log.e(TAG, "failed to set psk passphrase");
382                             return false;
383                         }
384                     }
385                 } else {
386                     if (config.allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
387                         return false;
388                     }
389                     if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) {
390                         Log.e(TAG, "failed to set psk");
391                         return false;
392                     }
393                 }
394             }
395             /** Wep Keys */
396             boolean hasSetKey = false;
397             if (config.wepKeys != null) {
398                 for (int i = 0; i < config.wepKeys.length; i++) {
399                     if (config.wepKeys[i] != null) {
400                         if (!setWepKey(
401                                 i, NativeUtil.hexOrQuotedStringToBytes(config.wepKeys[i]))) {
402                             Log.e(TAG, "failed to set wep_key " + i);
403                             return false;
404                         }
405                         hasSetKey = true;
406                     }
407                 }
408             }
409             /** Wep Tx Key Idx */
410             if (hasSetKey) {
411                 if (!setWepTxKeyIdx(config.wepTxKeyIndex)) {
412                     Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
413                     return false;
414                 }
415             }
416             /** metadata: FQDN + ConfigKey + CreatorUid */
417             final Map<String, String> metadata = new HashMap<String, String>();
418             if (config.isPasspoint()) {
419                 metadata.put(ID_STRING_KEY_FQDN, config.FQDN);
420             }
421             metadata.put(ID_STRING_KEY_CONFIG_KEY, config.getKey());
422             metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid));
423             if (!setIdStr(createNetworkExtra(metadata))) {
424                 Log.e(TAG, "failed to set id string");
425                 return false;
426             }
427             /** UpdateIdentifier */
428             if (config.updateIdentifier != null
429                     && !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) {
430                 Log.e(TAG, "failed to set update identifier");
431                 return false;
432             }
433             // Finish here if no EAP config to set
434             if (config.enterpriseConfig != null
435                     && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
436                 if (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.WAPI_CERT) {
437                     /** WAPI certificate suite name*/
438                     String param = config.enterpriseConfig
439                             .getFieldValue(WifiEnterpriseConfig.WAPI_CERT_SUITE_KEY);
440                     if (!TextUtils.isEmpty(param) && !setWapiCertSuite(param)) {
441                         Log.e(TAG, config.SSID + ": failed to set WAPI certificate suite: "
442                                 + param);
443                         return false;
444                     }
445                     return true;
446                 } else if (!saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig)) {
447                     return false;
448                 }
449             }
450 
451             // Now that the network is configured fully, start listening for callback events.
452             mISupplicantStaNetworkCallback =
453                     new SupplicantStaNetworkHalCallback(config.networkId, config.SSID);
454             if (!registerCallback(mISupplicantStaNetworkCallback)) {
455                 Log.e(TAG, "Failed to register callback");
456                 return false;
457             }
458             return true;
459         }
460     }
461 
462     /**
463      * Read network variables from wpa_supplicant into the provided WifiEnterpriseConfig object.
464      *
465      * @param ssid      SSID of the network. (Used for logging purposes only)
466      * @param eapConfig WifiEnterpriseConfig object to be populated.
467      * @return true if succeeds, false otherwise.
468      */
loadWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig)469     private boolean loadWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) {
470         synchronized (mLock) {
471             if (eapConfig == null) return false;
472             /** EAP method */
473             if (getEapMethod()) {
474                 eapConfig.setEapMethod(supplicantToWifiConfigurationEapMethod(mEapMethod));
475             } else {
476                 // Invalid eap method could be because it's not an enterprise config.
477                 Log.e(TAG, "failed to get eap method. Assumimg not an enterprise network");
478                 return true;
479             }
480             /** EAP Phase 2 method */
481             if (getEapPhase2Method()) {
482                 eapConfig.setPhase2Method(
483                         supplicantToWifiConfigurationEapPhase2Method(mEapPhase2Method));
484             } else {
485                 // We cannot have an invalid eap phase 2 method. Return failure.
486                 Log.e(TAG, "failed to get eap phase2 method");
487                 return false;
488             }
489             /** EAP Identity */
490             if (getEapIdentity() && !ArrayUtils.isEmpty(mEapIdentity)) {
491                 eapConfig.setFieldValue(
492                         WifiEnterpriseConfig.IDENTITY_KEY,
493                         NativeUtil.stringFromByteArrayList(mEapIdentity));
494             }
495             /** EAP Anonymous Identity */
496             if (getEapAnonymousIdentity() && !ArrayUtils.isEmpty(mEapAnonymousIdentity)) {
497                 eapConfig.setFieldValue(
498                         WifiEnterpriseConfig.ANON_IDENTITY_KEY,
499                         NativeUtil.stringFromByteArrayList(mEapAnonymousIdentity));
500             }
501             /** EAP Password */
502             if (getEapPassword() && !ArrayUtils.isEmpty(mEapPassword)) {
503                 eapConfig.setFieldValue(
504                         WifiEnterpriseConfig.PASSWORD_KEY,
505                         NativeUtil.stringFromByteArrayList(mEapPassword));
506             }
507             /** EAP Client Cert */
508             if (getEapClientCert() && !TextUtils.isEmpty(mEapClientCert)) {
509                 eapConfig.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, mEapClientCert);
510             }
511             /** EAP CA Cert */
512             if (getEapCACert() && !TextUtils.isEmpty(mEapCACert)) {
513                 eapConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, mEapCACert);
514             }
515             /** EAP OCSP type */
516             if (getOcsp()) {
517                 eapConfig.setOcsp(mOcsp);
518             }
519             /** EAP Subject Match */
520             if (getEapSubjectMatch() && !TextUtils.isEmpty(mEapSubjectMatch)) {
521                 eapConfig.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, mEapSubjectMatch);
522             }
523             /** EAP Engine ID */
524             if (getEapEngineID() && !TextUtils.isEmpty(mEapEngineID)) {
525                 eapConfig.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, mEapEngineID);
526             }
527             /** EAP Engine. Set this only if the engine id is non null. */
528             if (getEapEngine() && !TextUtils.isEmpty(mEapEngineID)) {
529                 eapConfig.setFieldValue(
530                         WifiEnterpriseConfig.ENGINE_KEY,
531                         mEapEngine
532                                 ? WifiEnterpriseConfig.ENGINE_ENABLE
533                                 : WifiEnterpriseConfig.ENGINE_DISABLE);
534             }
535             /** EAP Private Key */
536             if (getEapPrivateKeyId() && !TextUtils.isEmpty(mEapPrivateKeyId)) {
537                 eapConfig.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, mEapPrivateKeyId);
538             }
539             /** EAP Alt Subject Match */
540             if (getEapAltSubjectMatch() && !TextUtils.isEmpty(mEapAltSubjectMatch)) {
541                 eapConfig.setFieldValue(
542                         WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, mEapAltSubjectMatch);
543             }
544             /** EAP Domain Suffix Match */
545             if (getEapDomainSuffixMatch() && !TextUtils.isEmpty(mEapDomainSuffixMatch)) {
546                 eapConfig.setFieldValue(
547                         WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, mEapDomainSuffixMatch);
548             }
549             /** EAP CA Path*/
550             if (getEapCAPath() && !TextUtils.isEmpty(mEapCAPath)) {
551                 eapConfig.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, mEapCAPath);
552             }
553             return true;
554         }
555     }
556 
557     /**
558      * Save network variables from the provided SuiteB configuration to wpa_supplicant.
559      *
560      * @param config WifiConfiguration object to be saved
561      * @return true if succeeds, false otherwise.
562      */
saveSuiteBConfig(WifiConfiguration config)563     private boolean saveSuiteBConfig(WifiConfiguration config) {
564         /** Group Cipher **/
565         if (config.allowedGroupCiphers.cardinality() != 0
566                 && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
567                 config.allowedGroupCiphers))) {
568             Log.e(TAG, "failed to set Group Cipher");
569             return false;
570         }
571         /** Pairwise Cipher*/
572         if (config.allowedPairwiseCiphers.cardinality() != 0
573                 && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
574                 config.allowedPairwiseCiphers))) {
575             Log.e(TAG, "failed to set PairwiseCipher");
576             return false;
577         }
578         /** GroupMgmt Cipher */
579         if (config.allowedGroupManagementCiphers.cardinality() != 0
580                 && !setGroupMgmtCipher(wifiConfigurationToSupplicantGroupMgmtCipherMask(
581                 config.allowedGroupManagementCiphers))) {
582             Log.e(TAG, "failed to set GroupMgmtCipher");
583             return false;
584         }
585 
586         if (config.allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)) {
587             if (!enableTlsSuiteBEapPhase1Param(true)) {
588                 Log.e(TAG, "failed to set TLSSuiteB");
589                 return false;
590             }
591         } else if (config.allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)) {
592             if (!enableSuiteBEapOpenSslCiphers()) {
593                 Log.e(TAG, "failed to set OpensslCipher");
594                 return false;
595             }
596         }
597 
598         return true;
599     }
600 
601     /**
602      * Save network variables from the provided WifiEnterpriseConfig object to wpa_supplicant.
603      *
604      * @param ssid      SSID of the network. (Used for logging purposes only)
605      * @param eapConfig WifiEnterpriseConfig object to be saved.
606      * @return true if succeeds, false otherwise.
607      */
saveWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig)608     private boolean saveWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) {
609         synchronized (mLock) {
610             if (eapConfig == null) return false;
611             /** EAP method */
612             if (!setEapMethod(wifiConfigurationToSupplicantEapMethod(eapConfig.getEapMethod()))) {
613                 Log.e(TAG, ssid + ": failed to set eap method: " + eapConfig.getEapMethod());
614                 return false;
615             }
616             /** EAP Phase 2 method */
617             if (!setEapPhase2Method(wifiConfigurationToSupplicantEapPhase2Method(
618                     eapConfig.getPhase2Method()))) {
619                 Log.e(TAG, ssid + ": failed to set eap phase 2 method: "
620                         + eapConfig.getPhase2Method());
621                 return false;
622             }
623             String eapParam = null;
624             /** EAP Identity */
625             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY);
626             if (!TextUtils.isEmpty(eapParam)
627                     && !setEapIdentity(NativeUtil.stringToByteArrayList(eapParam))) {
628                 Log.e(TAG, ssid + ": failed to set eap identity: " + eapParam);
629                 return false;
630             }
631             /** EAP Anonymous Identity */
632             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY);
633             if (!TextUtils.isEmpty(eapParam)
634                     && !setEapAnonymousIdentity(NativeUtil.stringToByteArrayList(eapParam))) {
635                 Log.e(TAG, ssid + ": failed to set eap anonymous identity: " + eapParam);
636                 return false;
637             }
638             /** EAP Password */
639             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY);
640             if (!TextUtils.isEmpty(eapParam)
641                     && !setEapPassword(NativeUtil.stringToByteArrayList(eapParam))) {
642                 Log.e(TAG, ssid + ": failed to set eap password");
643                 return false;
644             }
645             /** EAP Client Cert */
646             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY);
647             if (!TextUtils.isEmpty(eapParam) && !setEapClientCert(eapParam)) {
648                 Log.e(TAG, ssid + ": failed to set eap client cert: " + eapParam);
649                 return false;
650             }
651             /** EAP CA Cert */
652             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY);
653             if (!TextUtils.isEmpty(eapParam) && !setEapCACert(eapParam)) {
654                 Log.e(TAG, ssid + ": failed to set eap ca cert: " + eapParam);
655                 return false;
656             }
657             /** EAP Subject Match */
658             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY);
659             if (!TextUtils.isEmpty(eapParam) && !setEapSubjectMatch(eapParam)) {
660                 Log.e(TAG, ssid + ": failed to set eap subject match: " + eapParam);
661                 return false;
662             }
663             /** EAP Engine ID */
664             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY);
665             if (!TextUtils.isEmpty(eapParam) && !setEapEngineID(eapParam)) {
666                 Log.e(TAG, ssid + ": failed to set eap engine id: " + eapParam);
667                 return false;
668             }
669             /** EAP Engine */
670             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY);
671             if (!TextUtils.isEmpty(eapParam) && !setEapEngine(
672                     eapParam.equals(WifiEnterpriseConfig.ENGINE_ENABLE) ? true : false)) {
673                 Log.e(TAG, ssid + ": failed to set eap engine: " + eapParam);
674                 return false;
675             }
676             /** EAP Private Key */
677             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY);
678             if (!TextUtils.isEmpty(eapParam) && !setEapPrivateKeyId(eapParam)) {
679                 Log.e(TAG, ssid + ": failed to set eap private key: " + eapParam);
680                 return false;
681             }
682             /** EAP Alt Subject Match */
683             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY);
684             if (!TextUtils.isEmpty(eapParam) && !setEapAltSubjectMatch(eapParam)) {
685                 Log.e(TAG, ssid + ": failed to set eap alt subject match: " + eapParam);
686                 return false;
687             }
688             /** EAP Domain Suffix Match */
689             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY);
690             if (!TextUtils.isEmpty(eapParam) && !setEapDomainSuffixMatch(eapParam)) {
691                 Log.e(TAG, ssid + ": failed to set eap domain suffix match: " + eapParam);
692                 return false;
693             }
694             /** EAP CA Path*/
695             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY);
696             if (!TextUtils.isEmpty(eapParam) && !setEapCAPath(eapParam)) {
697                 Log.e(TAG, ssid + ": failed to set eap ca path: " + eapParam);
698                 return false;
699             }
700 
701             /** EAP Proactive Key Caching */
702             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.OPP_KEY_CACHING);
703             if (!TextUtils.isEmpty(eapParam)
704                     && !setEapProactiveKeyCaching(eapParam.equals("1") ? true : false)) {
705                 Log.e(TAG, ssid + ": failed to set proactive key caching: " + eapParam);
706                 return false;
707             }
708 
709             /**
710              * OCSP (Online Certificate Status Protocol)
711              * For older HAL compatibility, omit this step to avoid breaking
712              * connection flow.
713              */
714             if (getV1_3StaNetwork() != null && !setOcsp(eapConfig.getOcsp())) {
715                 Log.e(TAG, "failed to set ocsp");
716                 return false;
717             }
718             /** EAP ERP */
719             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.EAP_ERP);
720             if (!TextUtils.isEmpty(eapParam) && eapParam.equals("1")) {
721                 if (!setEapErp(true)) {
722                     Log.e(TAG, ssid + ": failed to set eap erp");
723                     return false;
724                 }
725             }
726 
727 
728             return true;
729         }
730     }
731 
getV1_2StaNetwork()732     private android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork getV1_2StaNetwork() {
733         synchronized (mLock) {
734             return getSupplicantStaNetworkForV1_2Mockable();
735         }
736     }
737 
getV1_3StaNetwork()738     private android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork getV1_3StaNetwork() {
739         synchronized (mLock) {
740             return getSupplicantStaNetworkForV1_3Mockable();
741         }
742     }
743 
744     /**
745      * Maps WifiConfiguration Key Management BitSet to Supplicant HIDL bitmask int
746      * TODO(b/32571829): Update mapping when fast transition keys are added
747      *
748      * @return bitmask int describing the allowed Key Management schemes, readable by the Supplicant
749      * HIDL hal
750      */
wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt)751     private static int wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt) {
752         int mask = 0;
753         for (int bit = keyMgmt.nextSetBit(0); bit != -1;
754                 bit = keyMgmt.nextSetBit(bit + 1)) {
755             switch (bit) {
756                 case WifiConfiguration.KeyMgmt.NONE:
757                     mask |= ISupplicantStaNetwork.KeyMgmtMask.NONE;
758                     break;
759                 case WifiConfiguration.KeyMgmt.WPA_PSK:
760                     mask |= ISupplicantStaNetwork.KeyMgmtMask.WPA_PSK;
761                     break;
762                 case WifiConfiguration.KeyMgmt.WPA_EAP:
763                     mask |= ISupplicantStaNetwork.KeyMgmtMask.WPA_EAP;
764                     break;
765                 case WifiConfiguration.KeyMgmt.IEEE8021X:
766                     mask |= ISupplicantStaNetwork.KeyMgmtMask.IEEE8021X;
767                     break;
768                 case WifiConfiguration.KeyMgmt.OSEN:
769                     mask |= ISupplicantStaNetwork.KeyMgmtMask.OSEN;
770                     break;
771                 case WifiConfiguration.KeyMgmt.FT_PSK:
772                     mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_PSK;
773                     break;
774                 case WifiConfiguration.KeyMgmt.FT_EAP:
775                     mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_EAP;
776                     break;
777                 case WifiConfiguration.KeyMgmt.OWE:
778                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
779                             .OWE;
780                     break;
781                 case WifiConfiguration.KeyMgmt.SAE:
782                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
783                             .SAE;
784                     break;
785                 case WifiConfiguration.KeyMgmt.SUITE_B_192:
786                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
787                             .SUITE_B_192;
788                     break;
789                 case WifiConfiguration.KeyMgmt.WPA_PSK_SHA256:
790                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
791                             .WPA_PSK_SHA256;
792                     break;
793                 case WifiConfiguration.KeyMgmt.WPA_EAP_SHA256:
794                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
795                             .WPA_EAP_SHA256;
796                     break;
797                 case WifiConfiguration.KeyMgmt.WAPI_PSK:
798                     mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
799                             .WAPI_PSK;
800                     break;
801                 case WifiConfiguration.KeyMgmt.WAPI_CERT:
802                     mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
803                             .WAPI_CERT;
804                     break;
805                 case WifiConfiguration.KeyMgmt.FILS_SHA256:
806                     mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
807                             .FILS_SHA256;
808                     break;
809                 case WifiConfiguration.KeyMgmt.FILS_SHA384:
810                     mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
811                             .FILS_SHA384;
812                     break;
813                 case WifiConfiguration.KeyMgmt.WPA2_PSK: // This should never happen
814                 default:
815                     throw new IllegalArgumentException(
816                             "Invalid protoMask bit in keyMgmt: " + bit);
817             }
818         }
819         return mask;
820     }
821 
wifiConfigurationToSupplicantProtoMask(BitSet protoMask)822     private static int wifiConfigurationToSupplicantProtoMask(BitSet protoMask) {
823         int mask = 0;
824         for (int bit = protoMask.nextSetBit(0); bit != -1;
825                 bit = protoMask.nextSetBit(bit + 1)) {
826             switch (bit) {
827                 case WifiConfiguration.Protocol.WPA:
828                     mask |= ISupplicantStaNetwork.ProtoMask.WPA;
829                     break;
830                 case WifiConfiguration.Protocol.RSN:
831                     mask |= ISupplicantStaNetwork.ProtoMask.RSN;
832                     break;
833                 case WifiConfiguration.Protocol.OSEN:
834                     mask |= ISupplicantStaNetwork.ProtoMask.OSEN;
835                     break;
836                 case WifiConfiguration.Protocol.WAPI:
837                     mask |= android.hardware.wifi.supplicant.V1_3
838                             .ISupplicantStaNetwork.ProtoMask.WAPI;
839                     break;
840                 default:
841                     throw new IllegalArgumentException(
842                             "Invalid protoMask bit in wificonfig: " + bit);
843             }
844         }
845         return mask;
846     }
847 
wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask)848     private static int wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask) {
849         int mask = 0;
850         for (int bit = authAlgMask.nextSetBit(0); bit != -1;
851                 bit = authAlgMask.nextSetBit(bit + 1)) {
852             switch (bit) {
853                 case WifiConfiguration.AuthAlgorithm.OPEN:
854                     mask |= ISupplicantStaNetwork.AuthAlgMask.OPEN;
855                     break;
856                 case WifiConfiguration.AuthAlgorithm.SHARED:
857                     mask |= ISupplicantStaNetwork.AuthAlgMask.SHARED;
858                     break;
859                 case WifiConfiguration.AuthAlgorithm.LEAP:
860                     mask |= ISupplicantStaNetwork.AuthAlgMask.LEAP;
861                     break;
862                 case WifiConfiguration.AuthAlgorithm.SAE:
863                     mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.AuthAlgMask
864                             .SAE;
865                     break;
866                 default:
867                     throw new IllegalArgumentException(
868                             "Invalid authAlgMask bit in wificonfig: " + bit);
869             }
870         }
871         return mask;
872     }
873 
wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask)874     private static int wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask) {
875         int mask = 0;
876         for (int bit = groupCipherMask.nextSetBit(0); bit != -1; bit =
877                 groupCipherMask.nextSetBit(bit + 1)) {
878             switch (bit) {
879                 case WifiConfiguration.GroupCipher.WEP40:
880                     mask |= ISupplicantStaNetwork.GroupCipherMask.WEP40;
881                     break;
882                 case WifiConfiguration.GroupCipher.WEP104:
883                     mask |= ISupplicantStaNetwork.GroupCipherMask.WEP104;
884                     break;
885                 case WifiConfiguration.GroupCipher.TKIP:
886                     mask |= ISupplicantStaNetwork.GroupCipherMask.TKIP;
887                     break;
888                 case WifiConfiguration.GroupCipher.CCMP:
889                     mask |= ISupplicantStaNetwork.GroupCipherMask.CCMP;
890                     break;
891                 case WifiConfiguration.GroupCipher.GTK_NOT_USED:
892                     mask |= ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED;
893                     break;
894                 case WifiConfiguration.GroupCipher.GCMP_256:
895                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
896                             .GroupCipherMask.GCMP_256;
897                     break;
898                 case WifiConfiguration.GroupCipher.SMS4:
899                     mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
900                                 .GroupCipherMask.SMS4;
901                     break;
902                 default:
903                     throw new IllegalArgumentException(
904                             "Invalid GroupCipherMask bit in wificonfig: " + bit);
905             }
906         }
907         return mask;
908     }
909 
wifiConfigurationToSupplicantGroupMgmtCipherMask(BitSet groupMgmtCipherMask)910     private static int wifiConfigurationToSupplicantGroupMgmtCipherMask(BitSet
911             groupMgmtCipherMask) {
912         int mask = 0;
913 
914         for (int bit = groupMgmtCipherMask.nextSetBit(0); bit != -1; bit =
915                 groupMgmtCipherMask.nextSetBit(bit + 1)) {
916             switch (bit) {
917                 case WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256:
918                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
919                             .GroupMgmtCipherMask.BIP_CMAC_256;
920                     break;
921                 case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128:
922                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
923                             .GroupMgmtCipherMask.BIP_GMAC_128;
924                     break;
925                 case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256:
926                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
927                             .GroupMgmtCipherMask.BIP_GMAC_256;
928                     break;
929                 default:
930                     throw new IllegalArgumentException(
931                             "Invalid GroupMgmtCipherMask bit in wificonfig: " + bit);
932             }
933         }
934         return mask;
935     }
936 
wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask)937     private static int wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask) {
938         int mask = 0;
939         for (int bit = pairwiseCipherMask.nextSetBit(0); bit != -1;
940                 bit = pairwiseCipherMask.nextSetBit(bit + 1)) {
941             switch (bit) {
942                 case WifiConfiguration.PairwiseCipher.NONE:
943                     mask |= ISupplicantStaNetwork.PairwiseCipherMask.NONE;
944                     break;
945                 case WifiConfiguration.PairwiseCipher.TKIP:
946                     mask |= ISupplicantStaNetwork.PairwiseCipherMask.TKIP;
947                     break;
948                 case WifiConfiguration.PairwiseCipher.CCMP:
949                     mask |= ISupplicantStaNetwork.PairwiseCipherMask.CCMP;
950                     break;
951                 case WifiConfiguration.PairwiseCipher.GCMP_256:
952                     mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
953                             .PairwiseCipherMask.GCMP_256;
954                     break;
955                 case WifiConfiguration.PairwiseCipher.SMS4:
956                     mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
957                             .PairwiseCipherMask.SMS4;
958                     break;
959                 default:
960                     throw new IllegalArgumentException(
961                             "Invalid pairwiseCipherMask bit in wificonfig: " + bit);
962             }
963         }
964         return mask;
965     }
966 
supplicantToWifiConfigurationEapMethod(int value)967     private static int supplicantToWifiConfigurationEapMethod(int value) {
968         switch (value) {
969             case ISupplicantStaNetwork.EapMethod.PEAP:
970                 return WifiEnterpriseConfig.Eap.PEAP;
971             case ISupplicantStaNetwork.EapMethod.TLS:
972                 return WifiEnterpriseConfig.Eap.TLS;
973             case ISupplicantStaNetwork.EapMethod.TTLS:
974                 return WifiEnterpriseConfig.Eap.TTLS;
975             case ISupplicantStaNetwork.EapMethod.PWD:
976                 return WifiEnterpriseConfig.Eap.PWD;
977             case ISupplicantStaNetwork.EapMethod.SIM:
978                 return WifiEnterpriseConfig.Eap.SIM;
979             case ISupplicantStaNetwork.EapMethod.AKA:
980                 return WifiEnterpriseConfig.Eap.AKA;
981             case ISupplicantStaNetwork.EapMethod.AKA_PRIME:
982                 return WifiEnterpriseConfig.Eap.AKA_PRIME;
983             case ISupplicantStaNetwork.EapMethod.WFA_UNAUTH_TLS:
984                 return WifiEnterpriseConfig.Eap.UNAUTH_TLS;
985             // WifiEnterpriseConfig.Eap.NONE:
986             default:
987                 Log.e(TAG, "invalid eap method value from supplicant: " + value);
988                 return -1;
989         }
990     }
991 
supplicantToWifiConfigurationEapPhase2Method(int value)992     private static int supplicantToWifiConfigurationEapPhase2Method(int value) {
993         switch (value) {
994             case ISupplicantStaNetwork.EapPhase2Method.NONE:
995                 return WifiEnterpriseConfig.Phase2.NONE;
996             case ISupplicantStaNetwork.EapPhase2Method.PAP:
997                 return WifiEnterpriseConfig.Phase2.PAP;
998             case ISupplicantStaNetwork.EapPhase2Method.MSPAP:
999                 return WifiEnterpriseConfig.Phase2.MSCHAP;
1000             case ISupplicantStaNetwork.EapPhase2Method.MSPAPV2:
1001                 return WifiEnterpriseConfig.Phase2.MSCHAPV2;
1002             case ISupplicantStaNetwork.EapPhase2Method.GTC:
1003                 return WifiEnterpriseConfig.Phase2.GTC;
1004             case ISupplicantStaNetwork.EapPhase2Method.SIM:
1005                 return WifiEnterpriseConfig.Phase2.SIM;
1006             case ISupplicantStaNetwork.EapPhase2Method.AKA:
1007                 return WifiEnterpriseConfig.Phase2.AKA;
1008             case ISupplicantStaNetwork.EapPhase2Method.AKA_PRIME:
1009                 return WifiEnterpriseConfig.Phase2.AKA_PRIME;
1010             default:
1011                 Log.e(TAG, "invalid eap phase2 method value from supplicant: " + value);
1012                 return -1;
1013         }
1014     }
1015 
supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask, int supplicantValue, BitSet bitset, int bitSetPosition)1016     private static int supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask,
1017             int supplicantValue, BitSet bitset,
1018             int bitSetPosition) {
1019         bitset.set(bitSetPosition, (supplicantMask & supplicantValue) == supplicantValue);
1020         int modifiedSupplicantMask = supplicantMask & ~supplicantValue;
1021         return modifiedSupplicantMask;
1022     }
1023 
supplicantToWifiConfigurationKeyMgmtMask(int mask)1024     private static BitSet supplicantToWifiConfigurationKeyMgmtMask(int mask) {
1025         BitSet bitset = new BitSet();
1026         mask = supplicantMaskValueToWifiConfigurationBitSet(
1027                 mask, ISupplicantStaNetwork.KeyMgmtMask.NONE, bitset,
1028                 WifiConfiguration.KeyMgmt.NONE);
1029         mask = supplicantMaskValueToWifiConfigurationBitSet(
1030                 mask, ISupplicantStaNetwork.KeyMgmtMask.WPA_PSK, bitset,
1031                 WifiConfiguration.KeyMgmt.WPA_PSK);
1032         mask = supplicantMaskValueToWifiConfigurationBitSet(
1033                 mask, ISupplicantStaNetwork.KeyMgmtMask.WPA_EAP, bitset,
1034                 WifiConfiguration.KeyMgmt.WPA_EAP);
1035         mask = supplicantMaskValueToWifiConfigurationBitSet(
1036                 mask, ISupplicantStaNetwork.KeyMgmtMask.IEEE8021X, bitset,
1037                 WifiConfiguration.KeyMgmt.IEEE8021X);
1038         mask = supplicantMaskValueToWifiConfigurationBitSet(
1039                 mask, ISupplicantStaNetwork.KeyMgmtMask.OSEN, bitset,
1040                 WifiConfiguration.KeyMgmt.OSEN);
1041         mask = supplicantMaskValueToWifiConfigurationBitSet(
1042                 mask, ISupplicantStaNetwork.KeyMgmtMask.FT_PSK, bitset,
1043                 WifiConfiguration.KeyMgmt.FT_PSK);
1044         mask = supplicantMaskValueToWifiConfigurationBitSet(
1045                 mask, ISupplicantStaNetwork.KeyMgmtMask.FT_EAP, bitset,
1046                 WifiConfiguration.KeyMgmt.FT_EAP);
1047         mask = supplicantMaskValueToWifiConfigurationBitSet(
1048                 mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask.SAE,
1049                 bitset, WifiConfiguration.KeyMgmt.SAE);
1050         mask = supplicantMaskValueToWifiConfigurationBitSet(
1051                 mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask.OWE,
1052                 bitset, WifiConfiguration.KeyMgmt.OWE);
1053         mask = supplicantMaskValueToWifiConfigurationBitSet(
1054                 mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
1055                         .SUITE_B_192, bitset, WifiConfiguration.KeyMgmt.SUITE_B_192);
1056         mask = supplicantMaskValueToWifiConfigurationBitSet(
1057                 mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
1058                         .WPA_PSK_SHA256, bitset, WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
1059         mask = supplicantMaskValueToWifiConfigurationBitSet(
1060                 mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask
1061                         .WPA_EAP_SHA256, bitset, WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
1062         mask = supplicantMaskValueToWifiConfigurationBitSet(
1063                 mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
1064                         .WAPI_PSK, bitset, WifiConfiguration.KeyMgmt.WAPI_PSK);
1065         mask = supplicantMaskValueToWifiConfigurationBitSet(
1066                 mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
1067                         .WAPI_CERT, bitset, WifiConfiguration.KeyMgmt.WAPI_CERT);
1068         mask = supplicantMaskValueToWifiConfigurationBitSet(
1069                 mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
1070                       .FILS_SHA256, bitset, WifiConfiguration.KeyMgmt.FILS_SHA256);
1071         mask = supplicantMaskValueToWifiConfigurationBitSet(
1072                 mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask
1073                       .FILS_SHA384, bitset, WifiConfiguration.KeyMgmt.FILS_SHA384);
1074         if (mask != 0) {
1075             throw new IllegalArgumentException(
1076                     "invalid key mgmt mask from supplicant: " + mask);
1077         }
1078         return bitset;
1079     }
1080 
supplicantToWifiConfigurationProtoMask(int mask)1081     private static BitSet supplicantToWifiConfigurationProtoMask(int mask) {
1082         BitSet bitset = new BitSet();
1083         mask = supplicantMaskValueToWifiConfigurationBitSet(
1084                 mask, ISupplicantStaNetwork.ProtoMask.WPA, bitset,
1085                 WifiConfiguration.Protocol.WPA);
1086         mask = supplicantMaskValueToWifiConfigurationBitSet(
1087                 mask, ISupplicantStaNetwork.ProtoMask.RSN, bitset,
1088                 WifiConfiguration.Protocol.RSN);
1089         mask = supplicantMaskValueToWifiConfigurationBitSet(
1090                 mask, ISupplicantStaNetwork.ProtoMask.OSEN, bitset,
1091                 WifiConfiguration.Protocol.OSEN);
1092         mask = supplicantMaskValueToWifiConfigurationBitSet(
1093                 mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.ProtoMask.WAPI,
1094                 bitset, WifiConfiguration.Protocol.WAPI);
1095         if (mask != 0) {
1096             throw new IllegalArgumentException(
1097                     "invalid proto mask from supplicant: " + mask);
1098         }
1099         return bitset;
1100     }
1101 
supplicantToWifiConfigurationAuthAlgMask(int mask)1102     private static BitSet supplicantToWifiConfigurationAuthAlgMask(int mask) {
1103         BitSet bitset = new BitSet();
1104         mask = supplicantMaskValueToWifiConfigurationBitSet(
1105                 mask, ISupplicantStaNetwork.AuthAlgMask.OPEN, bitset,
1106                 WifiConfiguration.AuthAlgorithm.OPEN);
1107         mask = supplicantMaskValueToWifiConfigurationBitSet(
1108                 mask, ISupplicantStaNetwork.AuthAlgMask.SHARED, bitset,
1109                 WifiConfiguration.AuthAlgorithm.SHARED);
1110         mask = supplicantMaskValueToWifiConfigurationBitSet(
1111                 mask, ISupplicantStaNetwork.AuthAlgMask.LEAP, bitset,
1112                 WifiConfiguration.AuthAlgorithm.LEAP);
1113         mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
1114                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.AuthAlgMask
1115                         .SAE, bitset, WifiConfiguration.AuthAlgorithm.SAE);
1116         if (mask != 0) {
1117             throw new IllegalArgumentException(
1118                     "invalid auth alg mask from supplicant: " + mask);
1119         }
1120         return bitset;
1121     }
1122 
supplicantToWifiConfigurationGroupCipherMask(int mask)1123     private static BitSet supplicantToWifiConfigurationGroupCipherMask(int mask) {
1124         BitSet bitset = new BitSet();
1125         mask = supplicantMaskValueToWifiConfigurationBitSet(
1126                 mask, ISupplicantStaNetwork.GroupCipherMask.WEP40, bitset,
1127                 WifiConfiguration.GroupCipher.WEP40);
1128         mask = supplicantMaskValueToWifiConfigurationBitSet(
1129                 mask, ISupplicantStaNetwork.GroupCipherMask.WEP104, bitset,
1130                 WifiConfiguration.GroupCipher.WEP104);
1131         mask = supplicantMaskValueToWifiConfigurationBitSet(
1132                 mask, ISupplicantStaNetwork.GroupCipherMask.TKIP, bitset,
1133                 WifiConfiguration.GroupCipher.TKIP);
1134         mask = supplicantMaskValueToWifiConfigurationBitSet(
1135                 mask, ISupplicantStaNetwork.GroupCipherMask.CCMP, bitset,
1136                 WifiConfiguration.GroupCipher.CCMP);
1137         mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
1138                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1139                         .GroupCipherMask.GCMP_256, bitset, WifiConfiguration.GroupCipher.GCMP_256);
1140         mask = supplicantMaskValueToWifiConfigurationBitSet(
1141                 mask, ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED, bitset,
1142                 WifiConfiguration.GroupCipher.GTK_NOT_USED);
1143         mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
1144                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.GroupCipherMask
1145                         .SMS4, bitset, WifiConfiguration.GroupCipher.SMS4);
1146         if (mask != 0) {
1147             throw new IllegalArgumentException(
1148                     "invalid group cipher mask from supplicant: " + mask);
1149         }
1150         return bitset;
1151     }
1152 
supplicantToWifiConfigurationGroupMgmtCipherMask(int mask)1153     private static BitSet supplicantToWifiConfigurationGroupMgmtCipherMask(int mask) {
1154         BitSet bitset = new BitSet();
1155         mask = supplicantMaskValueToWifiConfigurationBitSet(
1156                 mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1157                         .GroupMgmtCipherMask.BIP_GMAC_128, bitset,
1158                 WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128);
1159         mask = supplicantMaskValueToWifiConfigurationBitSet(
1160                 mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1161                         .GroupMgmtCipherMask.BIP_GMAC_256, bitset,
1162                 WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256);
1163         mask = supplicantMaskValueToWifiConfigurationBitSet(
1164                 mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1165                         .GroupMgmtCipherMask.BIP_CMAC_256, bitset,
1166                 WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256);
1167         if (mask != 0) {
1168             throw new IllegalArgumentException(
1169                     "invalid group mgmt cipher mask from supplicant: " + mask);
1170         }
1171         return bitset;
1172     }
1173 
supplicantToWifiConfigurationPairwiseCipherMask(int mask)1174     private static BitSet supplicantToWifiConfigurationPairwiseCipherMask(int mask) {
1175         BitSet bitset = new BitSet();
1176         mask = supplicantMaskValueToWifiConfigurationBitSet(
1177                 mask, ISupplicantStaNetwork.PairwiseCipherMask.NONE, bitset,
1178                 WifiConfiguration.PairwiseCipher.NONE);
1179         mask = supplicantMaskValueToWifiConfigurationBitSet(
1180                 mask, ISupplicantStaNetwork.PairwiseCipherMask.TKIP, bitset,
1181                 WifiConfiguration.PairwiseCipher.TKIP);
1182         mask = supplicantMaskValueToWifiConfigurationBitSet(
1183                 mask, ISupplicantStaNetwork.PairwiseCipherMask.CCMP, bitset,
1184                 WifiConfiguration.PairwiseCipher.CCMP);
1185         mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
1186                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.PairwiseCipherMask
1187                         .GCMP_256, bitset,
1188                 WifiConfiguration.PairwiseCipher.GCMP_256);
1189         mask = supplicantMaskValueToWifiConfigurationBitSet(mask,
1190                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.PairwiseCipherMask
1191                         .SMS4, bitset,
1192                 WifiConfiguration.PairwiseCipher.SMS4);
1193         if (mask != 0) {
1194             throw new IllegalArgumentException(
1195                     "invalid pairwise cipher mask from supplicant: " + mask);
1196         }
1197         return bitset;
1198     }
1199 
wifiConfigurationToSupplicantEapMethod(int value)1200     private static int wifiConfigurationToSupplicantEapMethod(int value) {
1201         switch (value) {
1202             case WifiEnterpriseConfig.Eap.PEAP:
1203                 return ISupplicantStaNetwork.EapMethod.PEAP;
1204             case WifiEnterpriseConfig.Eap.TLS:
1205                 return ISupplicantStaNetwork.EapMethod.TLS;
1206             case WifiEnterpriseConfig.Eap.TTLS:
1207                 return ISupplicantStaNetwork.EapMethod.TTLS;
1208             case WifiEnterpriseConfig.Eap.PWD:
1209                 return ISupplicantStaNetwork.EapMethod.PWD;
1210             case WifiEnterpriseConfig.Eap.SIM:
1211                 return ISupplicantStaNetwork.EapMethod.SIM;
1212             case WifiEnterpriseConfig.Eap.AKA:
1213                 return ISupplicantStaNetwork.EapMethod.AKA;
1214             case WifiEnterpriseConfig.Eap.AKA_PRIME:
1215                 return ISupplicantStaNetwork.EapMethod.AKA_PRIME;
1216             case WifiEnterpriseConfig.Eap.UNAUTH_TLS:
1217                 return ISupplicantStaNetwork.EapMethod.WFA_UNAUTH_TLS;
1218             // WifiEnterpriseConfig.Eap.NONE:
1219             default:
1220                 Log.e(TAG, "invalid eap method value from WifiConfiguration: " + value);
1221                 return -1;
1222         }
1223     }
1224 
wifiConfigurationToSupplicantEapPhase2Method(int value)1225     private static int wifiConfigurationToSupplicantEapPhase2Method(int value) {
1226         switch (value) {
1227             case WifiEnterpriseConfig.Phase2.NONE:
1228                 return ISupplicantStaNetwork.EapPhase2Method.NONE;
1229             case WifiEnterpriseConfig.Phase2.PAP:
1230                 return ISupplicantStaNetwork.EapPhase2Method.PAP;
1231             case WifiEnterpriseConfig.Phase2.MSCHAP:
1232                 return ISupplicantStaNetwork.EapPhase2Method.MSPAP;
1233             case WifiEnterpriseConfig.Phase2.MSCHAPV2:
1234                 return ISupplicantStaNetwork.EapPhase2Method.MSPAPV2;
1235             case WifiEnterpriseConfig.Phase2.GTC:
1236                 return ISupplicantStaNetwork.EapPhase2Method.GTC;
1237             case WifiEnterpriseConfig.Phase2.SIM:
1238                 return ISupplicantStaNetwork.EapPhase2Method.SIM;
1239             case WifiEnterpriseConfig.Phase2.AKA:
1240                 return ISupplicantStaNetwork.EapPhase2Method.AKA;
1241             case WifiEnterpriseConfig.Phase2.AKA_PRIME:
1242                 return ISupplicantStaNetwork.EapPhase2Method.AKA_PRIME;
1243             default:
1244                 Log.e(TAG, "invalid eap phase2 method value from WifiConfiguration: " + value);
1245                 return -1;
1246         }
1247     }
1248 
1249     /** See ISupplicantNetwork.hal for documentation */
getId()1250     private boolean getId() {
1251         synchronized (mLock) {
1252             final String methodStr = "getId";
1253             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1254             try {
1255                 MutableBoolean statusOk = new MutableBoolean(false);
1256                 mISupplicantStaNetwork.getId((SupplicantStatus status, int idValue) -> {
1257                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
1258                     if (statusOk.value) {
1259                         this.mNetworkId = idValue;
1260                     } else {
1261                         checkStatusAndLogFailure(status, methodStr);
1262                     }
1263                 });
1264                 return statusOk.value;
1265             } catch (RemoteException e) {
1266                 handleRemoteException(e, methodStr);
1267                 return false;
1268             }
1269         }
1270     }
1271 
1272     /** See ISupplicantStaNetwork.hal for documentation */
registerCallback(ISupplicantStaNetworkCallback callback)1273     private boolean registerCallback(ISupplicantStaNetworkCallback callback) {
1274         synchronized (mLock) {
1275             final String methodStr = "registerCallback";
1276             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1277             try {
1278                 SupplicantStatus status = mISupplicantStaNetwork.registerCallback(callback);
1279                 return checkStatusAndLogFailure(status, methodStr);
1280             } catch (RemoteException e) {
1281                 handleRemoteException(e, methodStr);
1282                 return false;
1283             }
1284         }
1285     }
1286 
1287     /** See ISupplicantStaNetwork.hal for documentation */
setSsid(java.util.ArrayList<Byte> ssid)1288     private boolean setSsid(java.util.ArrayList<Byte> ssid) {
1289         synchronized (mLock) {
1290             final String methodStr = "setSsid";
1291             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1292             try {
1293                 SupplicantStatus status = mISupplicantStaNetwork.setSsid(ssid);
1294                 return checkStatusAndLogFailure(status, methodStr);
1295             } catch (RemoteException e) {
1296                 handleRemoteException(e, methodStr);
1297                 return false;
1298             }
1299         }
1300     }
1301 
1302     /**
1303      * Set the BSSID for this network.
1304      *
1305      * @param bssidStr MAC address in "XX:XX:XX:XX:XX:XX" form or "any" to reset the mac address.
1306      * @return true if it succeeds, false otherwise.
1307      */
setBssid(String bssidStr)1308     public boolean setBssid(String bssidStr) {
1309         synchronized (mLock) {
1310             try {
1311                 return setBssid(NativeUtil.macAddressToByteArray(bssidStr));
1312             } catch (IllegalArgumentException e) {
1313                 Log.e(TAG, "Illegal argument " + bssidStr, e);
1314                 return false;
1315             }
1316         }
1317     }
1318 
1319     /** See ISupplicantStaNetwork.hal for documentation */
setBssid(byte[ ] bssid)1320     private boolean setBssid(byte[/* 6 */] bssid) {
1321         synchronized (mLock) {
1322             final String methodStr = "setBssid";
1323             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1324             try {
1325                 SupplicantStatus status = mISupplicantStaNetwork.setBssid(bssid);
1326                 return checkStatusAndLogFailure(status, methodStr);
1327             } catch (RemoteException e) {
1328                 handleRemoteException(e, methodStr);
1329                 return false;
1330             }
1331         }
1332     }
1333 
1334     /** See ISupplicantStaNetwork.hal for documentation */
setScanSsid(boolean enable)1335     private boolean setScanSsid(boolean enable) {
1336         synchronized (mLock) {
1337             final String methodStr = "setScanSsid";
1338             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1339             try {
1340                 SupplicantStatus status = mISupplicantStaNetwork.setScanSsid(enable);
1341                 return checkStatusAndLogFailure(status, methodStr);
1342             } catch (RemoteException e) {
1343                 handleRemoteException(e, methodStr);
1344                 return false;
1345             }
1346         }
1347     }
1348 
1349     /** See ISupplicantStaNetwork.hal for documentation */
setKeyMgmt(int keyMgmtMask)1350     private boolean setKeyMgmt(int keyMgmtMask) {
1351         synchronized (mLock) {
1352             final String methodStr = "setKeyMgmt";
1353             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1354             try {
1355                 SupplicantStatus status;
1356                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1357                         iSupplicantStaNetworkV12;
1358                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
1359 
1360                 if (getV1_3StaNetwork() != null) {
1361                     /* Support for new key management types:
1362                      * WAPI_PSK, WAPI_CERT
1363                      * Requires HAL v1.3 or higher */
1364                     status = getV1_3StaNetwork().setKeyMgmt_1_3(keyMgmtMask);
1365                 } else if (iSupplicantStaNetworkV12 != null) {
1366                     /* Support for new key management types;
1367                      * SAE, OWE, WPA_PSK_SHA256, WPA_EAP_SHA256
1368                      * Requires HAL v1.2 or higher */
1369                     status = iSupplicantStaNetworkV12.setKeyMgmt_1_2(keyMgmtMask);
1370                 } else {
1371                     status = mISupplicantStaNetwork.setKeyMgmt(keyMgmtMask);
1372                 }
1373                 return checkStatusAndLogFailure(status, methodStr);
1374             } catch (RemoteException e) {
1375                 handleRemoteException(e, methodStr);
1376                 return false;
1377             }
1378         }
1379     }
1380 
1381     /** See ISupplicantStaNetwork.hal for documentation */
setProto(int protoMask)1382     private boolean setProto(int protoMask) {
1383         synchronized (mLock) {
1384             final String methodStr = "setProto";
1385             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1386             try {
1387                 SupplicantStatus status;
1388                 if (null != getV1_3StaNetwork()) {
1389                     /* Support for new proto types: WAPI
1390                      * Requires HAL v1.3 or higher
1391                      */
1392                     status = getV1_3StaNetwork().setProto_1_3(protoMask);
1393                 } else {
1394                     status = mISupplicantStaNetwork.setProto(protoMask);
1395                 }
1396                 return checkStatusAndLogFailure(status, methodStr);
1397             } catch (RemoteException e) {
1398                 handleRemoteException(e, methodStr);
1399                 return false;
1400             }
1401         }
1402     }
1403 
1404     /** See ISupplicantStaNetwork.hal for documentation */
setAuthAlg(int authAlgMask)1405     private boolean setAuthAlg(int authAlgMask) {
1406         synchronized (mLock) {
1407             final String methodStr = "setAuthAlg";
1408             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1409             try {
1410                 SupplicantStatus status;
1411                 if (null != getV1_3StaNetwork()) {
1412                     /* Support for SAE Authentication algorithm requires HAL v1.3 or higher */
1413                     status = getV1_3StaNetwork().setAuthAlg_1_3(authAlgMask);
1414                 } else {
1415                     status = mISupplicantStaNetwork.setAuthAlg(authAlgMask);
1416                 }
1417                 return checkStatusAndLogFailure(status, methodStr);
1418             } catch (RemoteException e) {
1419                 handleRemoteException(e, methodStr);
1420                 return false;
1421             }
1422         }
1423     }
1424 
1425     /** See ISupplicantStaNetwork.hal for documentation */
setGroupCipher(int groupCipherMask)1426     private boolean setGroupCipher(int groupCipherMask) {
1427         synchronized (mLock) {
1428             final String methodStr = "setGroupCipher";
1429             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1430             try {
1431                 SupplicantStatus status;
1432                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1433                         iSupplicantStaNetworkV12;
1434                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
1435                 if (null != getV1_3StaNetwork()) {
1436                     /* Support for new key group cipher types for SMS4
1437                      * Requires HAL v1.3 or higher */
1438                     status = getV1_3StaNetwork().setGroupCipher_1_3(groupCipherMask);
1439                 } else if (iSupplicantStaNetworkV12 != null) {
1440                     /* Support for new key group cipher types for SuiteB
1441                      * Requires HAL v1.2 or higher */
1442                     status = iSupplicantStaNetworkV12.setGroupCipher_1_2(groupCipherMask);
1443                 } else {
1444                     // Clear GCMP_256 group cipher which is not supported before v1.2
1445                     groupCipherMask &= ~android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1446                             .GroupCipherMask.GCMP_256;
1447                     status = mISupplicantStaNetwork.setGroupCipher(
1448                             groupCipherMask);
1449                 }
1450                 return checkStatusAndLogFailure(status, methodStr);
1451             } catch (RemoteException e) {
1452                 handleRemoteException(e, methodStr);
1453                 return false;
1454             }
1455         }
1456     }
1457 
1458     /** See ISupplicantStaNetwork.hal for documentation */
enableTlsSuiteBEapPhase1Param(boolean enable)1459     private boolean enableTlsSuiteBEapPhase1Param(boolean enable) {
1460         synchronized (mLock) {
1461             final String methodStr = "setEapPhase1Params";
1462             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1463             try {
1464                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1465                         iSupplicantStaNetworkV12;
1466 
1467                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
1468                 if (iSupplicantStaNetworkV12 != null) {
1469                     /* Support for for SuiteB
1470                      * Requires HAL v1.2 or higher */
1471                     SupplicantStatus status = iSupplicantStaNetworkV12
1472                             .enableTlsSuiteBEapPhase1Param(enable);
1473                     return checkStatusAndLogFailure(status, methodStr);
1474                 } else {
1475                     Log.e(TAG, "Supplicant HAL version does not support " + methodStr);
1476                     return false;
1477                 }
1478             } catch (RemoteException e) {
1479                 handleRemoteException(e, methodStr);
1480                 return false;
1481             }
1482         }
1483     }
1484 
1485     /** See ISupplicantStaNetwork.hal for documentation */
enableSuiteBEapOpenSslCiphers()1486     private boolean enableSuiteBEapOpenSslCiphers() {
1487         synchronized (mLock) {
1488             final String methodStr = "setEapOpenSslCiphers";
1489             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1490             try {
1491                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1492                         iSupplicantStaNetworkV12;
1493 
1494                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
1495                 if (iSupplicantStaNetworkV12 != null) {
1496                     /* Support for for SuiteB
1497                      * Requires HAL v1.2 or higher */
1498                     SupplicantStatus status = iSupplicantStaNetworkV12
1499                             .enableSuiteBEapOpenSslCiphers();
1500                     return checkStatusAndLogFailure(status, methodStr);
1501                 } else {
1502                     Log.e(TAG, "Supplicant HAL version does not support " + methodStr);
1503                     return false;
1504                 }
1505             } catch (RemoteException e) {
1506                 handleRemoteException(e, methodStr);
1507                 return false;
1508             }
1509         }
1510     }
1511 
1512     /** See ISupplicantStaNetwork.hal for documentation */
setPairwiseCipher(int pairwiseCipherMask)1513     private boolean setPairwiseCipher(int pairwiseCipherMask) {
1514         synchronized (mLock) {
1515             final String methodStr = "setPairwiseCipher";
1516             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1517             try {
1518                 SupplicantStatus status;
1519                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1520                         iSupplicantStaNetworkV12;
1521                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
1522                 if (null != getV1_3StaNetwork()) {
1523                     /* Support for new key pairwise cipher types for SMS4
1524                      * Requires HAL v1.3 or higher */
1525                     status = getV1_3StaNetwork().setPairwiseCipher_1_3(pairwiseCipherMask);
1526                 } else if (iSupplicantStaNetworkV12 != null) {
1527                     /* Support for new key pairwise cipher types for SuiteB
1528                      * Requires HAL v1.2 or higher */
1529                     status = iSupplicantStaNetworkV12.setPairwiseCipher_1_2(pairwiseCipherMask);
1530                 } else {
1531                     // Clear GCMP_256 pairwise cipher which is not supported before v1.2
1532                     pairwiseCipherMask &= ~android.hardware.wifi.supplicant.V1_2
1533                             .ISupplicantStaNetwork.PairwiseCipherMask.GCMP_256;
1534                     status =
1535                             mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask);
1536                 }
1537                 return checkStatusAndLogFailure(status, methodStr);
1538             } catch (RemoteException e) {
1539                 handleRemoteException(e, methodStr);
1540                 return false;
1541             }
1542         }
1543     }
1544 
1545     /** See ISupplicantStaNetwork.hal for documentation */
setGroupMgmtCipher(int groupMgmtCipherMask)1546     private boolean setGroupMgmtCipher(int groupMgmtCipherMask) {
1547         synchronized (mLock) {
1548             final String methodStr = "setGroupMgmtCipher";
1549             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1550             try {
1551                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1552                         iSupplicantStaNetworkV12;
1553 
1554                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
1555                 if (iSupplicantStaNetworkV12 != null) {
1556                     /* Support for new key pairwise cipher types for SuiteB
1557                      * Requires HAL v1.2 or higher */
1558                     SupplicantStatus status = iSupplicantStaNetworkV12
1559                             .setGroupMgmtCipher(groupMgmtCipherMask);
1560                     return checkStatusAndLogFailure(status, methodStr);
1561                 } else {
1562                     return false;
1563                 }
1564             } catch (RemoteException e) {
1565                 handleRemoteException(e, methodStr);
1566                 return false;
1567             }
1568         }
1569     }
1570 
1571     /** See ISupplicantStaNetwork.hal for documentation */
setPskPassphrase(String psk)1572     private boolean setPskPassphrase(String psk) {
1573         synchronized (mLock) {
1574             final String methodStr = "setPskPassphrase";
1575             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1576             try {
1577                 SupplicantStatus status = mISupplicantStaNetwork.setPskPassphrase(psk);
1578                 return checkStatusAndLogFailure(status, methodStr);
1579             } catch (RemoteException e) {
1580                 handleRemoteException(e, methodStr);
1581                 return false;
1582             }
1583         }
1584     }
1585 
1586     /** See ISupplicantStaNetwork.hal for documentation */
setPsk(byte[] psk)1587     private boolean setPsk(byte[] psk) {
1588         synchronized (mLock) {
1589             final String methodStr = "setPsk";
1590             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1591             try {
1592                 SupplicantStatus status = mISupplicantStaNetwork.setPsk(psk);
1593                 return checkStatusAndLogFailure(status, methodStr);
1594             } catch (RemoteException e) {
1595                 handleRemoteException(e, methodStr);
1596                 return false;
1597             } catch (ArrayIndexOutOfBoundsException e) {
1598                 Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + e);
1599                 return false;
1600             }
1601         }
1602     }
1603 
1604     /** See ISupplicantStaNetwork.hal for documentation */
setWepKey(int keyIdx, java.util.ArrayList<Byte> wepKey)1605     private boolean setWepKey(int keyIdx, java.util.ArrayList<Byte> wepKey) {
1606         synchronized (mLock) {
1607             final String methodStr = "setWepKey";
1608             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1609             try {
1610                 SupplicantStatus status = mISupplicantStaNetwork.setWepKey(keyIdx, wepKey);
1611                 return checkStatusAndLogFailure(status, methodStr);
1612             } catch (RemoteException e) {
1613                 handleRemoteException(e, methodStr);
1614                 return false;
1615             }
1616         }
1617     }
1618 
1619     /** See ISupplicantStaNetwork.hal for documentation */
setWepTxKeyIdx(int keyIdx)1620     private boolean setWepTxKeyIdx(int keyIdx) {
1621         synchronized (mLock) {
1622             final String methodStr = "setWepTxKeyIdx";
1623             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1624             try {
1625                 SupplicantStatus status = mISupplicantStaNetwork.setWepTxKeyIdx(keyIdx);
1626                 return checkStatusAndLogFailure(status, methodStr);
1627             } catch (RemoteException e) {
1628                 handleRemoteException(e, methodStr);
1629                 return false;
1630             }
1631         }
1632     }
1633 
1634     /** See ISupplicantStaNetwork.hal for documentation */
setRequirePmf(boolean enable)1635     private boolean setRequirePmf(boolean enable) {
1636         synchronized (mLock) {
1637             final String methodStr = "setRequirePmf";
1638             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1639             try {
1640                 SupplicantStatus status = mISupplicantStaNetwork.setRequirePmf(enable);
1641                 return checkStatusAndLogFailure(status, methodStr);
1642             } catch (RemoteException e) {
1643                 handleRemoteException(e, methodStr);
1644                 return false;
1645             }
1646         }
1647     }
1648 
1649     /** See ISupplicantStaNetwork.hal for documentation */
setUpdateIdentifier(int identifier)1650     private boolean setUpdateIdentifier(int identifier) {
1651         synchronized (mLock) {
1652             final String methodStr = "setUpdateIdentifier";
1653             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1654             try {
1655                 SupplicantStatus status = mISupplicantStaNetwork.setUpdateIdentifier(identifier);
1656                 return checkStatusAndLogFailure(status, methodStr);
1657             } catch (RemoteException e) {
1658                 handleRemoteException(e, methodStr);
1659                 return false;
1660             }
1661         }
1662     }
1663 
1664     /** See ISupplicantStaNetwork.hal for documentation */
setWapiCertSuite(String certSuite)1665     private boolean setWapiCertSuite(String certSuite) {
1666         synchronized (mLock) {
1667             final String methodStr = "setWapiCertSuite";
1668             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1669             try {
1670                 if (null != getV1_3StaNetwork()) {
1671                     /* Requires HAL v1.3 or higher */
1672                     SupplicantStatus status = getV1_3StaNetwork().setWapiCertSuite(certSuite);
1673                     return checkStatusAndLogFailure(status, methodStr);
1674                 } else {
1675                     Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
1676                     return false;
1677                 }
1678             } catch (RemoteException e) {
1679                 handleRemoteException(e, methodStr);
1680                 return false;
1681             }
1682         }
1683     }
1684 
1685     /** See ISupplicantStaNetwork.hal for documentation */
setEapMethod(int method)1686     private boolean setEapMethod(int method) {
1687         synchronized (mLock) {
1688             final String methodStr = "setEapMethod";
1689             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1690             try {
1691                 SupplicantStatus status = mISupplicantStaNetwork.setEapMethod(method);
1692                 return checkStatusAndLogFailure(status, methodStr);
1693             } catch (RemoteException e) {
1694                 handleRemoteException(e, methodStr);
1695                 return false;
1696             }
1697         }
1698     }
1699 
1700     /** See ISupplicantStaNetwork.hal for documentation */
setEapPhase2Method(int method)1701     private boolean setEapPhase2Method(int method) {
1702         synchronized (mLock) {
1703             final String methodStr = "setEapPhase2Method";
1704             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1705             try {
1706                 SupplicantStatus status = mISupplicantStaNetwork.setEapPhase2Method(method);
1707                 return checkStatusAndLogFailure(status, methodStr);
1708             } catch (RemoteException e) {
1709                 handleRemoteException(e, methodStr);
1710                 return false;
1711             }
1712         }
1713     }
1714 
1715     /** See ISupplicantStaNetwork.hal for documentation */
setEapIdentity(java.util.ArrayList<Byte> identity)1716     private boolean setEapIdentity(java.util.ArrayList<Byte> identity) {
1717         synchronized (mLock) {
1718             final String methodStr = "setEapIdentity";
1719             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1720             try {
1721                 SupplicantStatus status = mISupplicantStaNetwork.setEapIdentity(identity);
1722                 return checkStatusAndLogFailure(status, methodStr);
1723             } catch (RemoteException e) {
1724                 handleRemoteException(e, methodStr);
1725                 return false;
1726             }
1727         }
1728     }
1729 
1730     /** See ISupplicantStaNetwork.hal for documentation */
setEapAnonymousIdentity(java.util.ArrayList<Byte> identity)1731     private boolean setEapAnonymousIdentity(java.util.ArrayList<Byte> identity) {
1732         synchronized (mLock) {
1733             final String methodStr = "setEapAnonymousIdentity";
1734             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1735             try {
1736                 SupplicantStatus status = mISupplicantStaNetwork.setEapAnonymousIdentity(identity);
1737                 return checkStatusAndLogFailure(status, methodStr);
1738             } catch (RemoteException e) {
1739                 handleRemoteException(e, methodStr);
1740                 return false;
1741             }
1742         }
1743     }
1744 
1745     /** See ISupplicantStaNetwork.hal for documentation */
setEapPassword(java.util.ArrayList<Byte> password)1746     private boolean setEapPassword(java.util.ArrayList<Byte> password) {
1747         synchronized (mLock) {
1748             final String methodStr = "setEapPassword";
1749             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1750             try {
1751                 SupplicantStatus status = mISupplicantStaNetwork.setEapPassword(password);
1752                 return checkStatusAndLogFailure(status, methodStr);
1753             } catch (RemoteException e) {
1754                 handleRemoteException(e, methodStr);
1755                 return false;
1756             }
1757         }
1758     }
1759 
1760     /** See ISupplicantStaNetwork.hal for documentation */
setEapCACert(String path)1761     private boolean setEapCACert(String path) {
1762         synchronized (mLock) {
1763             final String methodStr = "setEapCACert";
1764             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1765             try {
1766                 SupplicantStatus status = mISupplicantStaNetwork.setEapCACert(path);
1767                 return checkStatusAndLogFailure(status, methodStr);
1768             } catch (RemoteException e) {
1769                 handleRemoteException(e, methodStr);
1770                 return false;
1771             }
1772         }
1773     }
1774 
1775     /** See ISupplicantStaNetwork.hal for documentation */
setEapCAPath(String path)1776     private boolean setEapCAPath(String path) {
1777         synchronized (mLock) {
1778             final String methodStr = "setEapCAPath";
1779             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1780             try {
1781                 SupplicantStatus status = mISupplicantStaNetwork.setEapCAPath(path);
1782                 return checkStatusAndLogFailure(status, methodStr);
1783             } catch (RemoteException e) {
1784                 handleRemoteException(e, methodStr);
1785                 return false;
1786             }
1787         }
1788     }
1789 
1790     /** See ISupplicantStaNetwork.hal for documentation */
setEapClientCert(String path)1791     private boolean setEapClientCert(String path) {
1792         synchronized (mLock) {
1793             final String methodStr = "setEapClientCert";
1794             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1795             try {
1796                 SupplicantStatus status = mISupplicantStaNetwork.setEapClientCert(path);
1797                 return checkStatusAndLogFailure(status, methodStr);
1798             } catch (RemoteException e) {
1799                 handleRemoteException(e, methodStr);
1800                 return false;
1801             }
1802         }
1803     }
1804 
1805     /** See ISupplicantStaNetwork.hal for documentation */
setEapPrivateKeyId(String id)1806     private boolean setEapPrivateKeyId(String id) {
1807         synchronized (mLock) {
1808             final String methodStr = "setEapPrivateKeyId";
1809             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1810             try {
1811                 SupplicantStatus status = mISupplicantStaNetwork.setEapPrivateKeyId(id);
1812                 return checkStatusAndLogFailure(status, methodStr);
1813             } catch (RemoteException e) {
1814                 handleRemoteException(e, methodStr);
1815                 return false;
1816             }
1817         }
1818     }
1819 
1820     /** See ISupplicantStaNetwork.hal for documentation */
setEapSubjectMatch(String match)1821     private boolean setEapSubjectMatch(String match) {
1822         synchronized (mLock) {
1823             final String methodStr = "setEapSubjectMatch";
1824             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1825             try {
1826                 SupplicantStatus status = mISupplicantStaNetwork.setEapSubjectMatch(match);
1827                 return checkStatusAndLogFailure(status, methodStr);
1828             } catch (RemoteException e) {
1829                 handleRemoteException(e, methodStr);
1830                 return false;
1831             }
1832         }
1833     }
1834 
1835     /** See ISupplicantStaNetwork.hal for documentation */
setEapAltSubjectMatch(String match)1836     private boolean setEapAltSubjectMatch(String match) {
1837         synchronized (mLock) {
1838             final String methodStr = "setEapAltSubjectMatch";
1839             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1840             try {
1841                 SupplicantStatus status = mISupplicantStaNetwork.setEapAltSubjectMatch(match);
1842                 return checkStatusAndLogFailure(status, methodStr);
1843             } catch (RemoteException e) {
1844                 handleRemoteException(e, methodStr);
1845                 return false;
1846             }
1847         }
1848     }
1849 
1850     /** See ISupplicantStaNetwork.hal for documentation */
setEapEngine(boolean enable)1851     private boolean setEapEngine(boolean enable) {
1852         synchronized (mLock) {
1853             final String methodStr = "setEapEngine";
1854             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1855             try {
1856                 SupplicantStatus status = mISupplicantStaNetwork.setEapEngine(enable);
1857                 return checkStatusAndLogFailure(status, methodStr);
1858             } catch (RemoteException e) {
1859                 handleRemoteException(e, methodStr);
1860                 return false;
1861             }
1862         }
1863     }
1864 
1865     /** See ISupplicantStaNetwork.hal for documentation */
setEapEngineID(String id)1866     private boolean setEapEngineID(String id) {
1867         synchronized (mLock) {
1868             final String methodStr = "setEapEngineID";
1869             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1870             try {
1871                 SupplicantStatus status = mISupplicantStaNetwork.setEapEngineID(id);
1872                 return checkStatusAndLogFailure(status, methodStr);
1873             } catch (RemoteException e) {
1874                 handleRemoteException(e, methodStr);
1875                 return false;
1876             }
1877         }
1878     }
1879 
1880     /** See ISupplicantStaNetwork.hal for documentation */
setEapDomainSuffixMatch(String match)1881     private boolean setEapDomainSuffixMatch(String match) {
1882         synchronized (mLock) {
1883             final String methodStr = "setEapDomainSuffixMatch";
1884             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1885             try {
1886                 SupplicantStatus status = mISupplicantStaNetwork.setEapDomainSuffixMatch(match);
1887                 return checkStatusAndLogFailure(status, methodStr);
1888             } catch (RemoteException e) {
1889                 handleRemoteException(e, methodStr);
1890                 return false;
1891             }
1892         }
1893     }
1894 
1895     /** See ISupplicantStaNetwork.hal for documentation */
setEapProactiveKeyCaching(boolean enable)1896     private boolean setEapProactiveKeyCaching(boolean enable) {
1897         synchronized (mLock) {
1898             final String methodStr = "setEapProactiveKeyCaching";
1899             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1900             try {
1901                 SupplicantStatus status = mISupplicantStaNetwork.setProactiveKeyCaching(enable);
1902                 return checkStatusAndLogFailure(status, methodStr);
1903             } catch (RemoteException e) {
1904                 handleRemoteException(e, methodStr);
1905                 return false;
1906             }
1907         }
1908     }
1909 
1910     /** See ISupplicantStaNetwork.hal for documentation */
setIdStr(String idString)1911     private boolean setIdStr(String idString) {
1912         synchronized (mLock) {
1913             final String methodStr = "setIdStr";
1914             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1915             try {
1916                 SupplicantStatus status = mISupplicantStaNetwork.setIdStr(idString);
1917                 return checkStatusAndLogFailure(status, methodStr);
1918             } catch (RemoteException e) {
1919                 handleRemoteException(e, methodStr);
1920                 return false;
1921             }
1922         }
1923     }
1924 
1925     /** See ISupplicantStaNetwork.hal for documentation */
setSaePassword(String saePassword)1926     private boolean setSaePassword(String saePassword) {
1927         synchronized (mLock) {
1928             final String methodStr = "setSaePassword";
1929             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1930             try {
1931                 android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
1932                         iSupplicantStaNetworkV12;
1933 
1934                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
1935                 if (iSupplicantStaNetworkV12 != null) {
1936                     /* Support for SAE Requires HAL v1.2 or higher */
1937                     SupplicantStatus status = iSupplicantStaNetworkV12.setSaePassword(saePassword);
1938                     return checkStatusAndLogFailure(status, methodStr);
1939                 } else {
1940                     return false;
1941                 }
1942             } catch (RemoteException e) {
1943                 handleRemoteException(e, methodStr);
1944                 return false;
1945             }
1946         }
1947     }
1948 
1949     /** See ISupplicantStaNetwork.hal for documentation */
setEapErp(boolean enable)1950     private boolean setEapErp(boolean enable) {
1951         synchronized (mLock) {
1952             final String methodStr = "setEapErp";
1953             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1954             try {
1955                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
1956                         iSupplicantStaNetworkV13;
1957 
1958                 iSupplicantStaNetworkV13 = getV1_3StaNetwork();
1959                 if (iSupplicantStaNetworkV13 != null) {
1960                     /* Support for set ERP Requires HAL v1.3 or higher */
1961                     SupplicantStatus status =  iSupplicantStaNetworkV13.setEapErp(enable);
1962                     return checkStatusAndLogFailure(status, methodStr);
1963                 } else {
1964                     return false;
1965                 }
1966             } catch (RemoteException e) {
1967                 handleRemoteException(e, methodStr);
1968                 return false;
1969             }
1970         }
1971     }
1972 
1973     /** See ISupplicantStaNetwork.hal for documentation */
getSsid()1974     private boolean getSsid() {
1975         synchronized (mLock) {
1976             final String methodStr = "getSsid";
1977             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
1978             try {
1979                 MutableBoolean statusOk = new MutableBoolean(false);
1980                 mISupplicantStaNetwork.getSsid((SupplicantStatus status,
1981                         java.util.ArrayList<Byte> ssidValue) -> {
1982                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
1983                     if (statusOk.value) {
1984                         this.mSsid = ssidValue;
1985                     } else {
1986                         checkStatusAndLogFailure(status, methodStr);
1987                     }
1988                 });
1989                 return statusOk.value;
1990             } catch (RemoteException e) {
1991                 handleRemoteException(e, methodStr);
1992                 return false;
1993             }
1994         }
1995     }
1996 
1997     /** See ISupplicantStaNetwork.hal for documentation */
getBssid()1998     private boolean getBssid() {
1999         synchronized (mLock) {
2000             final String methodStr = "getBssid";
2001             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2002             try {
2003                 MutableBoolean statusOk = new MutableBoolean(false);
2004                 mISupplicantStaNetwork.getBssid((SupplicantStatus status,
2005                         byte[/* 6 */] bssidValue) -> {
2006                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2007                     if (statusOk.value) {
2008                         this.mBssid = bssidValue;
2009                     } else {
2010                         checkStatusAndLogFailure(status, methodStr);
2011                     }
2012                 });
2013                 return statusOk.value;
2014             } catch (RemoteException e) {
2015                 handleRemoteException(e, methodStr);
2016                 return false;
2017             }
2018         }
2019     }
2020 
2021     /** See ISupplicantStaNetwork.hal for documentation */
getScanSsid()2022     private boolean getScanSsid() {
2023         synchronized (mLock) {
2024             final String methodStr = "getScanSsid";
2025             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2026             try {
2027                 MutableBoolean statusOk = new MutableBoolean(false);
2028                 mISupplicantStaNetwork.getScanSsid((SupplicantStatus status,
2029                         boolean enabledValue) -> {
2030                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2031                     if (statusOk.value) {
2032                         this.mScanSsid = enabledValue;
2033                     } else {
2034                         checkStatusAndLogFailure(status, methodStr);
2035                     }
2036                 });
2037                 return statusOk.value;
2038             } catch (RemoteException e) {
2039                 handleRemoteException(e, methodStr);
2040                 return false;
2041             }
2042         }
2043     }
2044 
2045     /** See ISupplicantStaNetwork.hal for documentation */
getKeyMgmt()2046     private boolean getKeyMgmt() {
2047         synchronized (mLock) {
2048             final String methodStr = "getKeyMgmt";
2049             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2050             if (getV1_3StaNetwork() != null) {
2051                 return getKeyMgmt_1_3();
2052             } else {
2053                 try {
2054                     MutableBoolean statusOk = new MutableBoolean(false);
2055                     mISupplicantStaNetwork.getKeyMgmt((SupplicantStatus status,
2056                             int keyMgmtMaskValue) -> {
2057                         statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2058                         if (statusOk.value) {
2059                             this.mKeyMgmtMask = keyMgmtMaskValue;
2060                         } else {
2061                             checkStatusAndLogFailure(status, methodStr);
2062                         }
2063                     });
2064                     return statusOk.value;
2065                 } catch (RemoteException e) {
2066                     handleRemoteException(e, methodStr);
2067                     return false;
2068                 }
2069             }
2070         }
2071     }
2072 
getKeyMgmt_1_3()2073     private boolean getKeyMgmt_1_3() {
2074         synchronized (mLock) {
2075             final String methodStr = "getKeyMgmt_1_3";
2076             try {
2077                 MutableBoolean statusOk = new MutableBoolean(false);
2078                 getV1_3StaNetwork().getKeyMgmt_1_3((SupplicantStatus status,
2079                         int keyMgmtMaskValue) -> {
2080                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2081                     if (statusOk.value) {
2082                         this.mKeyMgmtMask = keyMgmtMaskValue;
2083                     } else {
2084                         checkStatusAndLogFailure(status, methodStr);
2085                     }
2086                 });
2087                 return statusOk.value;
2088             } catch (RemoteException e) {
2089                 handleRemoteException(e, methodStr);
2090                 return false;
2091             }
2092         }
2093     }
2094 
2095     /** See ISupplicantStaNetwork.hal for documentation */
getProto()2096     private boolean getProto() {
2097         synchronized (mLock) {
2098             final String methodStr = "getProto";
2099             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2100             if (getV1_3StaNetwork() != null) {
2101                 return getProto_1_3();
2102             } else {
2103                 try {
2104                     MutableBoolean statusOk = new MutableBoolean(false);
2105                     mISupplicantStaNetwork.getProto(
2106                             (SupplicantStatus status, int protoMaskValue) -> {
2107                             statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2108                             if (statusOk.value) {
2109                                 this.mProtoMask = protoMaskValue;
2110                             } else {
2111                                 checkStatusAndLogFailure(status, methodStr);
2112                             }
2113                         });
2114                     return statusOk.value;
2115                 } catch (RemoteException e) {
2116                     handleRemoteException(e, methodStr);
2117                     return false;
2118                 }
2119             }
2120         }
2121     }
2122 
getProto_1_3()2123     private boolean getProto_1_3() {
2124         synchronized (mLock) {
2125             final String methodStr = "getProto_1_3";
2126             try {
2127                 MutableBoolean statusOk = new MutableBoolean(false);
2128                 getV1_3StaNetwork().getProto((SupplicantStatus status, int protoMaskValue) -> {
2129                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2130                     if (statusOk.value) {
2131                         this.mProtoMask = protoMaskValue;
2132                     } else {
2133                         checkStatusAndLogFailure(status, methodStr);
2134                     }
2135                 });
2136                 return statusOk.value;
2137             } catch (RemoteException e) {
2138                 handleRemoteException(e, methodStr);
2139                 return false;
2140             }
2141         }
2142     }
2143 
2144     /** See ISupplicantStaNetwork.hal for documentation */
getAuthAlg()2145     private boolean getAuthAlg() {
2146         synchronized (mLock) {
2147             final String methodStr = "getAuthAlg";
2148             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2149             if (getV1_3StaNetwork() != null) {
2150                 return getAuthAlg_1_3();
2151             }
2152             try {
2153                 MutableBoolean statusOk = new MutableBoolean(false);
2154                 mISupplicantStaNetwork.getAuthAlg((SupplicantStatus status,
2155                         int authAlgMaskValue) -> {
2156                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2157                     if (statusOk.value) {
2158                         this.mAuthAlgMask = authAlgMaskValue;
2159                     } else {
2160                         checkStatusAndLogFailure(status, methodStr);
2161                     }
2162                 });
2163                 return statusOk.value;
2164             } catch (RemoteException e) {
2165                 handleRemoteException(e, methodStr);
2166                 return false;
2167             }
2168         }
2169     }
2170 
getAuthAlg_1_3()2171     private boolean getAuthAlg_1_3() {
2172         final String methodStr = "getAuthAlg_1_3";
2173         try {
2174             MutableBoolean statusOk = new MutableBoolean(false);
2175             getV1_3StaNetwork().getAuthAlg_1_3((SupplicantStatus status,
2176                     int authAlgMaskValue) -> {
2177                 statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2178                 if (statusOk.value) {
2179                     this.mAuthAlgMask = authAlgMaskValue;
2180                 } else {
2181                     checkStatusAndLogFailure(status, methodStr);
2182                 }
2183             });
2184             return statusOk.value;
2185         } catch (RemoteException e) {
2186             handleRemoteException(e, methodStr);
2187             return false;
2188         }
2189     }
2190 
2191     /** See ISupplicantStaNetwork.hal for documentation */
getGroupCipher()2192     private boolean getGroupCipher() {
2193         synchronized (mLock) {
2194             final String methodStr = "getGroupCipher";
2195             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2196             if (getV1_3StaNetwork() != null) {
2197                 return getGroupCipher_1_3();
2198             } else {
2199                 try {
2200                     MutableBoolean statusOk = new MutableBoolean(false);
2201                     mISupplicantStaNetwork.getGroupCipher((SupplicantStatus status,
2202                             int groupCipherMaskValue) -> {
2203                         statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2204                         if (statusOk.value) {
2205                             this.mGroupCipherMask = groupCipherMaskValue;
2206                         } else {
2207                             checkStatusAndLogFailure(status, methodStr);
2208                         }
2209                     });
2210                     return statusOk.value;
2211                 } catch (RemoteException e) {
2212                     handleRemoteException(e, methodStr);
2213                     return false;
2214                 }
2215             }
2216         }
2217     }
2218 
getGroupCipher_1_3()2219     private boolean getGroupCipher_1_3() {
2220         synchronized (mLock) {
2221             final String methodStr = "getGroupCipher_1_3";
2222             try {
2223                 MutableBoolean statusOk = new MutableBoolean(false);
2224                 getV1_3StaNetwork().getGroupCipher((SupplicantStatus status,
2225                         int groupCipherMaskValue) -> {
2226                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2227                     if (statusOk.value) {
2228                         this.mGroupCipherMask = groupCipherMaskValue;
2229                     } else {
2230                         checkStatusAndLogFailure(status, methodStr);
2231                     }
2232                 });
2233                 return statusOk.value;
2234             } catch (RemoteException e) {
2235                 handleRemoteException(e, methodStr);
2236                 return false;
2237             }
2238         }
2239     }
2240 
2241     /** See ISupplicantStaNetwork.hal for documentation */
getPairwiseCipher()2242     private boolean getPairwiseCipher() {
2243         synchronized (mLock) {
2244             final String methodStr = "getPairwiseCipher";
2245             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2246             if (getV1_3StaNetwork() != null) {
2247                 return getPairwiseCipher_1_3();
2248             } else {
2249                 try {
2250                     MutableBoolean statusOk = new MutableBoolean(false);
2251                     mISupplicantStaNetwork.getPairwiseCipher((SupplicantStatus status,
2252                             int pairwiseCipherMaskValue) -> {
2253                         statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2254                         if (statusOk.value) {
2255                             this.mPairwiseCipherMask = pairwiseCipherMaskValue;
2256                         } else {
2257                             checkStatusAndLogFailure(status, methodStr);
2258                         }
2259                     });
2260                     return statusOk.value;
2261                 } catch (RemoteException e) {
2262                     handleRemoteException(e, methodStr);
2263                     return false;
2264                 }
2265             }
2266         }
2267     }
2268 
getPairwiseCipher_1_3()2269     private boolean getPairwiseCipher_1_3() {
2270         synchronized (mLock) {
2271             final String methodStr = "getPairwiseCipher_1_3";
2272             try {
2273                 MutableBoolean statusOk = new MutableBoolean(false);
2274                 getV1_3StaNetwork().getPairwiseCipher((SupplicantStatus status,
2275                         int pairwiseCipherMaskValue) -> {
2276                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2277                     if (statusOk.value) {
2278                         this.mPairwiseCipherMask = pairwiseCipherMaskValue;
2279                     } else {
2280                         checkStatusAndLogFailure(status, methodStr);
2281                     }
2282                 });
2283                 return statusOk.value;
2284             } catch (RemoteException e) {
2285                 handleRemoteException(e, methodStr);
2286                 return false;
2287             }
2288         }
2289     }
2290 
2291     /** See ISupplicantStaNetwork.hal for documentation */
getGroupMgmtCipher()2292     private boolean getGroupMgmtCipher() {
2293         synchronized (mLock) {
2294             final String methodStr = "getGroupMgmtCipher";
2295             android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
2296                     iSupplicantStaNetworkV12;
2297 
2298             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2299             try {
2300                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
2301                 if (iSupplicantStaNetworkV12 != null) {
2302                     MutableBoolean statusOk = new MutableBoolean(false);
2303                     iSupplicantStaNetworkV12.getGroupMgmtCipher((SupplicantStatus status,
2304                             int groupMgmtCipherMaskValue) -> {
2305                         statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2306                         if (statusOk.value) {
2307                             this.mGroupMgmtCipherMask = groupMgmtCipherMaskValue;
2308                         }
2309                         checkStatusAndLogFailure(status, methodStr);
2310                     });
2311                     return statusOk.value;
2312                 } else {
2313                     return false;
2314                 }
2315             } catch (RemoteException e) {
2316                 handleRemoteException(e, methodStr);
2317                 return false;
2318             }
2319         }
2320     }
2321 
2322     /** See ISupplicantStaNetwork.hal for documentation */
getPskPassphrase()2323     private boolean getPskPassphrase() {
2324         synchronized (mLock) {
2325             final String methodStr = "getPskPassphrase";
2326             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2327             try {
2328                 MutableBoolean statusOk = new MutableBoolean(false);
2329                 mISupplicantStaNetwork.getPskPassphrase((SupplicantStatus status,
2330                         String pskValue) -> {
2331                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2332                     if (statusOk.value) {
2333                         this.mPskPassphrase = pskValue;
2334                     } else {
2335                         checkStatusAndLogFailure(status, methodStr);
2336                     }
2337                 });
2338                 return statusOk.value;
2339             } catch (RemoteException e) {
2340                 handleRemoteException(e, methodStr);
2341                 return false;
2342             }
2343         }
2344     }
2345 
2346     /** See ISupplicantStaNetwork.hal for documentation */
getSaePassword()2347     private boolean getSaePassword() {
2348         synchronized (mLock) {
2349             final String methodStr = "getSaePassword";
2350             android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
2351                     iSupplicantStaNetworkV12;
2352 
2353             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2354             try {
2355                 iSupplicantStaNetworkV12 = getV1_2StaNetwork();
2356                 if (iSupplicantStaNetworkV12 != null) {
2357                     MutableBoolean statusOk = new MutableBoolean(false);
2358                     iSupplicantStaNetworkV12.getSaePassword((SupplicantStatus status,
2359                             String saePassword) -> {
2360                         statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2361                         if (statusOk.value) {
2362                             this.mSaePassword = saePassword;
2363                         }
2364                         checkStatusAndLogFailure(status, methodStr);
2365                     });
2366                     return statusOk.value;
2367                 } else {
2368                     return false;
2369                 }
2370             } catch (RemoteException e) {
2371                 handleRemoteException(e, methodStr);
2372                 return false;
2373             }
2374         }
2375     }
2376 
2377     /** See ISupplicantStaNetwork.hal for documentation */
getPsk()2378     private boolean getPsk() {
2379         synchronized (mLock) {
2380             final String methodStr = "getPsk";
2381             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2382             try {
2383                 MutableBoolean statusOk = new MutableBoolean(false);
2384                 mISupplicantStaNetwork.getPsk((SupplicantStatus status, byte[] pskValue) -> {
2385                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2386                     if (statusOk.value) {
2387                         this.mPsk = pskValue;
2388                     } else {
2389                         checkStatusAndLogFailure(status, methodStr);
2390                     }
2391                 });
2392                 return statusOk.value;
2393             } catch (RemoteException e) {
2394                 handleRemoteException(e, methodStr);
2395                 return false;
2396             }
2397         }
2398     }
2399 
2400     /** See ISupplicantStaNetwork.hal for documentation */
getWepKey(int keyIdx)2401     private boolean getWepKey(int keyIdx) {
2402         synchronized (mLock) {
2403             final String methodStr = "keyIdx";
2404             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2405             try {
2406                 MutableBoolean statusOk = new MutableBoolean(false);
2407                 mISupplicantStaNetwork.getWepKey(keyIdx, (SupplicantStatus status,
2408                         java.util.ArrayList<Byte> wepKeyValue) -> {
2409                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2410                     if (statusOk.value) {
2411                         this.mWepKey = wepKeyValue;
2412                     } else {
2413                         Log.e(TAG, methodStr + ",  failed: " + status.debugMessage);
2414                     }
2415                 });
2416                 return statusOk.value;
2417             } catch (RemoteException e) {
2418                 handleRemoteException(e, methodStr);
2419                 return false;
2420             }
2421         }
2422     }
2423 
2424     /** See ISupplicantStaNetwork.hal for documentation */
getWepTxKeyIdx()2425     private boolean getWepTxKeyIdx() {
2426         synchronized (mLock) {
2427             final String methodStr = "getWepTxKeyIdx";
2428             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2429             try {
2430                 MutableBoolean statusOk = new MutableBoolean(false);
2431                 mISupplicantStaNetwork.getWepTxKeyIdx((SupplicantStatus status,
2432                         int keyIdxValue) -> {
2433                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2434                     if (statusOk.value) {
2435                         this.mWepTxKeyIdx = keyIdxValue;
2436                     } else {
2437                         checkStatusAndLogFailure(status, methodStr);
2438                     }
2439                 });
2440                 return statusOk.value;
2441             } catch (RemoteException e) {
2442                 handleRemoteException(e, methodStr);
2443                 return false;
2444             }
2445         }
2446     }
2447 
2448     /** See ISupplicantStaNetwork.hal for documentation */
getRequirePmf()2449     private boolean getRequirePmf() {
2450         synchronized (mLock) {
2451             final String methodStr = "getRequirePmf";
2452             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2453             try {
2454                 MutableBoolean statusOk = new MutableBoolean(false);
2455                 mISupplicantStaNetwork.getRequirePmf((SupplicantStatus status,
2456                         boolean enabledValue) -> {
2457                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2458                     if (statusOk.value) {
2459                         this.mRequirePmf = enabledValue;
2460                     } else {
2461                         checkStatusAndLogFailure(status, methodStr);
2462                     }
2463                 });
2464                 return statusOk.value;
2465             } catch (RemoteException e) {
2466                 handleRemoteException(e, methodStr);
2467                 return false;
2468             }
2469         }
2470     }
2471 
2472     /** See ISupplicantStaNetwork.hal for documentation */
getWapiCertSuite()2473     private boolean getWapiCertSuite() {
2474         synchronized (mLock) {
2475             final String methodStr = "getWapiCertSuite";
2476             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2477             try {
2478                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
2479                         iSupplicantStaNetworkV13;
2480                 iSupplicantStaNetworkV13 = getV1_3StaNetwork();
2481                 if (iSupplicantStaNetworkV13 != null) {
2482                     MutableBoolean statusOk = new MutableBoolean(false);
2483                     iSupplicantStaNetworkV13.getWapiCertSuite((SupplicantStatus status,
2484                             String suiteValue) -> {
2485                         statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2486                         if (statusOk.value) {
2487                             mWapiCertSuite = suiteValue;
2488                         } else {
2489                             checkStatusAndLogFailure(status, methodStr);
2490                         }
2491                     });
2492                     return statusOk.value;
2493                 } else {
2494                     Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
2495                     return false;
2496                 }
2497             } catch (RemoteException e) {
2498                 handleRemoteException(e, methodStr);
2499                 return false;
2500             }
2501         }
2502     }
2503 
2504     /** See ISupplicantStaNetwork.hal for documentation */
getEapMethod()2505     private boolean getEapMethod() {
2506         synchronized (mLock) {
2507             final String methodStr = "getEapMethod";
2508             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2509             try {
2510                 MutableBoolean statusOk = new MutableBoolean(false);
2511                 mISupplicantStaNetwork.getEapMethod((SupplicantStatus status,
2512                         int methodValue) -> {
2513                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2514                     if (statusOk.value) {
2515                         this.mEapMethod = methodValue;
2516                     } else {
2517                         checkStatusAndLogFailure(status, methodStr);
2518                     }
2519                 });
2520                 return statusOk.value;
2521             } catch (RemoteException e) {
2522                 handleRemoteException(e, methodStr);
2523                 return false;
2524             }
2525         }
2526     }
2527 
2528     /** See ISupplicantStaNetwork.hal for documentation */
getEapPhase2Method()2529     private boolean getEapPhase2Method() {
2530         synchronized (mLock) {
2531             final String methodStr = "getEapPhase2Method";
2532             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2533             try {
2534                 MutableBoolean statusOk = new MutableBoolean(false);
2535                 mISupplicantStaNetwork.getEapPhase2Method((SupplicantStatus status,
2536                         int methodValue) -> {
2537                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2538                     if (statusOk.value) {
2539                         this.mEapPhase2Method = methodValue;
2540                     } else {
2541                         checkStatusAndLogFailure(status, methodStr);
2542                     }
2543                 });
2544                 return statusOk.value;
2545             } catch (RemoteException e) {
2546                 handleRemoteException(e, methodStr);
2547                 return false;
2548             }
2549         }
2550     }
2551 
2552     /** See ISupplicantStaNetwork.hal for documentation */
getEapIdentity()2553     private boolean getEapIdentity() {
2554         synchronized (mLock) {
2555             final String methodStr = "getEapIdentity";
2556             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2557             try {
2558                 MutableBoolean statusOk = new MutableBoolean(false);
2559                 mISupplicantStaNetwork.getEapIdentity((SupplicantStatus status,
2560                         ArrayList<Byte> identityValue) -> {
2561                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2562                     if (statusOk.value) {
2563                         this.mEapIdentity = identityValue;
2564                     } else {
2565                         checkStatusAndLogFailure(status, methodStr);
2566                     }
2567                 });
2568                 return statusOk.value;
2569             } catch (RemoteException e) {
2570                 handleRemoteException(e, methodStr);
2571                 return false;
2572             }
2573         }
2574     }
2575 
2576     /** See ISupplicantStaNetwork.hal for documentation */
getEapAnonymousIdentity()2577     private boolean getEapAnonymousIdentity() {
2578         synchronized (mLock) {
2579             final String methodStr = "getEapAnonymousIdentity";
2580             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2581             try {
2582                 MutableBoolean statusOk = new MutableBoolean(false);
2583                 mISupplicantStaNetwork.getEapAnonymousIdentity((SupplicantStatus status,
2584                         ArrayList<Byte> identityValue) -> {
2585                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2586                     if (statusOk.value) {
2587                         this.mEapAnonymousIdentity = identityValue;
2588                     } else {
2589                         checkStatusAndLogFailure(status, methodStr);
2590                     }
2591                 });
2592                 return statusOk.value;
2593             } catch (RemoteException e) {
2594                 handleRemoteException(e, methodStr);
2595                 return false;
2596             }
2597         }
2598     }
2599 
2600     /**
2601      * A wrapping method for getEapAnonymousIdentity().
2602      * This get anonymous identity from supplicant and returns it as a string.
2603      *
2604      * @return anonymous identity string if succeeds, null otherwise.
2605      */
fetchEapAnonymousIdentity()2606     public String fetchEapAnonymousIdentity() {
2607         synchronized (mLock) {
2608             if (!getEapAnonymousIdentity()) {
2609                 return null;
2610             }
2611             return NativeUtil.stringFromByteArrayList(mEapAnonymousIdentity);
2612         }
2613     }
2614 
2615     /** See ISupplicantStaNetwork.hal for documentation */
getEapPassword()2616     private boolean getEapPassword() {
2617         synchronized (mLock) {
2618             final String methodStr = "getEapPassword";
2619             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2620             try {
2621                 MutableBoolean statusOk = new MutableBoolean(false);
2622                 mISupplicantStaNetwork.getEapPassword((SupplicantStatus status,
2623                         ArrayList<Byte> passwordValue) -> {
2624                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2625                     if (statusOk.value) {
2626                         this.mEapPassword = passwordValue;
2627                     } else {
2628                         checkStatusAndLogFailure(status, methodStr);
2629                     }
2630                 });
2631                 return statusOk.value;
2632             } catch (RemoteException e) {
2633                 handleRemoteException(e, methodStr);
2634                 return false;
2635             }
2636         }
2637     }
2638 
2639     /** See ISupplicantStaNetwork.hal for documentation */
getEapCACert()2640     private boolean getEapCACert() {
2641         synchronized (mLock) {
2642             final String methodStr = "getEapCACert";
2643             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2644             try {
2645                 MutableBoolean statusOk = new MutableBoolean(false);
2646                 mISupplicantStaNetwork.getEapCACert((SupplicantStatus status, String pathValue) -> {
2647                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2648                     if (statusOk.value) {
2649                         this.mEapCACert = pathValue;
2650                     } else {
2651                         checkStatusAndLogFailure(status, methodStr);
2652                     }
2653                 });
2654                 return statusOk.value;
2655             } catch (RemoteException e) {
2656                 handleRemoteException(e, methodStr);
2657                 return false;
2658             }
2659         }
2660     }
2661 
2662     /** See ISupplicantStaNetwork.hal for documentation */
getEapCAPath()2663     private boolean getEapCAPath() {
2664         synchronized (mLock) {
2665             final String methodStr = "getEapCAPath";
2666             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2667             try {
2668                 MutableBoolean statusOk = new MutableBoolean(false);
2669                 mISupplicantStaNetwork.getEapCAPath((SupplicantStatus status, String pathValue) -> {
2670                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2671                     if (statusOk.value) {
2672                         this.mEapCAPath = pathValue;
2673                     } else {
2674                         checkStatusAndLogFailure(status, methodStr);
2675                     }
2676                 });
2677                 return statusOk.value;
2678             } catch (RemoteException e) {
2679                 handleRemoteException(e, methodStr);
2680                 return false;
2681             }
2682         }
2683     }
2684 
2685     /** See ISupplicantStaNetwork.hal for documentation */
getEapClientCert()2686     private boolean getEapClientCert() {
2687         synchronized (mLock) {
2688             final String methodStr = "getEapClientCert";
2689             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2690             try {
2691                 MutableBoolean statusOk = new MutableBoolean(false);
2692                 mISupplicantStaNetwork.getEapClientCert((SupplicantStatus status,
2693                         String pathValue) -> {
2694                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2695                     if (statusOk.value) {
2696                         this.mEapClientCert = pathValue;
2697                     } else {
2698                         checkStatusAndLogFailure(status, methodStr);
2699                     }
2700                 });
2701                 return statusOk.value;
2702             } catch (RemoteException e) {
2703                 handleRemoteException(e, methodStr);
2704                 return false;
2705             }
2706         }
2707     }
2708 
2709     /** See ISupplicantStaNetwork.hal for documentation */
getEapPrivateKeyId()2710     private boolean getEapPrivateKeyId() {
2711         synchronized (mLock) {
2712             final String methodStr = "getEapPrivateKeyId";
2713             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2714             try {
2715                 MutableBoolean statusOk = new MutableBoolean(false);
2716                 mISupplicantStaNetwork.getEapPrivateKeyId((SupplicantStatus status,
2717                         String idValue) -> {
2718                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2719                     if (statusOk.value) {
2720                         this.mEapPrivateKeyId = idValue;
2721                     } else {
2722                         checkStatusAndLogFailure(status, methodStr);
2723                     }
2724                 });
2725                 return statusOk.value;
2726             } catch (RemoteException e) {
2727                 handleRemoteException(e, methodStr);
2728                 return false;
2729             }
2730         }
2731     }
2732 
2733     /** See ISupplicantStaNetwork.hal for documentation */
getEapSubjectMatch()2734     private boolean getEapSubjectMatch() {
2735         synchronized (mLock) {
2736             final String methodStr = "getEapSubjectMatch";
2737             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2738             try {
2739                 MutableBoolean statusOk = new MutableBoolean(false);
2740                 mISupplicantStaNetwork.getEapSubjectMatch((SupplicantStatus status,
2741                         String matchValue) -> {
2742                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2743                     if (statusOk.value) {
2744                         this.mEapSubjectMatch = matchValue;
2745                     } else {
2746                         checkStatusAndLogFailure(status, methodStr);
2747                     }
2748                 });
2749                 return statusOk.value;
2750             } catch (RemoteException e) {
2751                 handleRemoteException(e, methodStr);
2752                 return false;
2753             }
2754         }
2755     }
2756 
2757     /** See ISupplicantStaNetwork.hal for documentation */
getEapAltSubjectMatch()2758     private boolean getEapAltSubjectMatch() {
2759         synchronized (mLock) {
2760             final String methodStr = "getEapAltSubjectMatch";
2761             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2762             try {
2763                 MutableBoolean statusOk = new MutableBoolean(false);
2764                 mISupplicantStaNetwork.getEapAltSubjectMatch((SupplicantStatus status,
2765                         String matchValue) -> {
2766                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2767                     if (statusOk.value) {
2768                         this.mEapAltSubjectMatch = matchValue;
2769                     } else {
2770                         checkStatusAndLogFailure(status, methodStr);
2771                     }
2772                 });
2773                 return statusOk.value;
2774             } catch (RemoteException e) {
2775                 handleRemoteException(e, methodStr);
2776                 return false;
2777             }
2778         }
2779     }
2780 
2781     /** See ISupplicantStaNetwork.hal for documentation */
getEapEngine()2782     private boolean getEapEngine() {
2783         synchronized (mLock) {
2784             final String methodStr = "getEapEngine";
2785             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2786             try {
2787                 MutableBoolean statusOk = new MutableBoolean(false);
2788                 mISupplicantStaNetwork.getEapEngine((SupplicantStatus status,
2789                         boolean enabledValue) -> {
2790                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2791                     if (statusOk.value) {
2792                         this.mEapEngine = enabledValue;
2793                     } else {
2794                         checkStatusAndLogFailure(status, methodStr);
2795                     }
2796                 });
2797                 return statusOk.value;
2798             } catch (RemoteException e) {
2799                 handleRemoteException(e, methodStr);
2800                 return false;
2801             }
2802         }
2803     }
2804 
2805     /** See ISupplicantStaNetwork.hal for documentation */
getEapEngineID()2806     private boolean getEapEngineID() {
2807         synchronized (mLock) {
2808             final String methodStr = "getEapEngineID";
2809             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2810             try {
2811                 MutableBoolean statusOk = new MutableBoolean(false);
2812                 mISupplicantStaNetwork.getEapEngineID((SupplicantStatus status, String idValue) -> {
2813                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2814                     if (statusOk.value) {
2815                         this.mEapEngineID = idValue;
2816                     } else {
2817                         checkStatusAndLogFailure(status, methodStr);
2818                     }
2819                 });
2820                 return statusOk.value;
2821             } catch (RemoteException e) {
2822                 handleRemoteException(e, methodStr);
2823                 return false;
2824             }
2825         }
2826     }
2827 
2828     /** See ISupplicantStaNetwork.hal for documentation */
getEapDomainSuffixMatch()2829     private boolean getEapDomainSuffixMatch() {
2830         synchronized (mLock) {
2831             final String methodStr = "getEapDomainSuffixMatch";
2832             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2833             try {
2834                 MutableBoolean statusOk = new MutableBoolean(false);
2835                 mISupplicantStaNetwork.getEapDomainSuffixMatch((SupplicantStatus status,
2836                         String matchValue) -> {
2837                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2838                     if (statusOk.value) {
2839                         this.mEapDomainSuffixMatch = matchValue;
2840                     } else {
2841                         checkStatusAndLogFailure(status, methodStr);
2842                     }
2843                 });
2844                 return statusOk.value;
2845             } catch (RemoteException e) {
2846                 handleRemoteException(e, methodStr);
2847                 return false;
2848             }
2849         }
2850     }
2851 
2852     /** See ISupplicantStaNetwork.hal for documentation */
getIdStr()2853     private boolean getIdStr() {
2854         synchronized (mLock) {
2855             final String methodStr = "getIdStr";
2856             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2857             try {
2858                 MutableBoolean statusOk = new MutableBoolean(false);
2859                 mISupplicantStaNetwork.getIdStr((SupplicantStatus status, String idString) -> {
2860                     statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
2861                     if (statusOk.value) {
2862                         this.mIdStr = idString;
2863                     } else {
2864                         checkStatusAndLogFailure(status, methodStr);
2865                     }
2866                 });
2867                 return statusOk.value;
2868             } catch (RemoteException e) {
2869                 handleRemoteException(e, methodStr);
2870                 return false;
2871             }
2872         }
2873     }
2874 
2875     /** See ISupplicantStaNetwork.hal for documentation */
enable(boolean noConnect)2876     private boolean enable(boolean noConnect) {
2877         synchronized (mLock) {
2878             final String methodStr = "enable";
2879             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2880             try {
2881                 SupplicantStatus status = mISupplicantStaNetwork.enable(noConnect);
2882                 return checkStatusAndLogFailure(status, methodStr);
2883             } catch (RemoteException e) {
2884                 handleRemoteException(e, methodStr);
2885                 return false;
2886             }
2887         }
2888     }
2889 
2890     /** See ISupplicantStaNetwork.hal for documentation */
disable()2891     private boolean disable() {
2892         synchronized (mLock) {
2893             final String methodStr = "disable";
2894             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2895             try {
2896                 SupplicantStatus status = mISupplicantStaNetwork.disable();
2897                 return checkStatusAndLogFailure(status, methodStr);
2898             } catch (RemoteException e) {
2899                 handleRemoteException(e, methodStr);
2900                 return false;
2901             }
2902         }
2903     }
2904 
2905     /**
2906      * Trigger a connection to this network.
2907      *
2908      * @return true if it succeeds, false otherwise.
2909      */
select()2910     public boolean select() {
2911         synchronized (mLock) {
2912             final String methodStr = "select";
2913             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2914             try {
2915                 SupplicantStatus status = mISupplicantStaNetwork.select();
2916                 return checkStatusAndLogFailure(status, methodStr);
2917             } catch (RemoteException e) {
2918                 handleRemoteException(e, methodStr);
2919                 return false;
2920             }
2921         }
2922     }
2923 
2924     /**
2925      * Send GSM auth response.
2926      *
2927      * @param paramsStr Response params as a string.
2928      * @return true if succeeds, false otherwise.
2929      */
sendNetworkEapSimGsmAuthResponse(String paramsStr)2930     public boolean sendNetworkEapSimGsmAuthResponse(String paramsStr) {
2931         synchronized (mLock) {
2932             try {
2933                 Matcher match = GSM_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
2934                 ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params =
2935                         new ArrayList<>();
2936                 while (match.find()) {
2937                     if (match.groupCount() != 2) {
2938                         Log.e(TAG, "Malformed gsm auth response params: " + paramsStr);
2939                         return false;
2940                     }
2941                     ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams param =
2942                             new ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams();
2943                     byte[] kc = NativeUtil.hexStringToByteArray(match.group(1));
2944                     if (kc == null || kc.length != param.kc.length) {
2945                         Log.e(TAG, "Invalid kc value: " + match.group(1));
2946                         return false;
2947                     }
2948                     byte[] sres = NativeUtil.hexStringToByteArray(match.group(2));
2949                     if (sres == null || sres.length != param.sres.length) {
2950                         Log.e(TAG, "Invalid sres value: " + match.group(2));
2951                         return false;
2952                     }
2953                     System.arraycopy(kc, 0, param.kc, 0, param.kc.length);
2954                     System.arraycopy(sres, 0, param.sres, 0, param.sres.length);
2955                     params.add(param);
2956                 }
2957                 // The number of kc/sres pairs can either be 2 or 3 depending on the request.
2958                 if (params.size() > 3 || params.size() < 2) {
2959                     Log.e(TAG, "Malformed gsm auth response params: " + paramsStr);
2960                     return false;
2961                 }
2962                 return sendNetworkEapSimGsmAuthResponse(params);
2963             } catch (IllegalArgumentException e) {
2964                 Log.e(TAG, "Illegal argument " + paramsStr, e);
2965                 return false;
2966             }
2967         }
2968     }
2969 
2970     /** See ISupplicantStaNetwork.hal for documentation */
sendNetworkEapSimGsmAuthResponse( ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params)2971     private boolean sendNetworkEapSimGsmAuthResponse(
2972             ArrayList<ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams> params) {
2973         synchronized (mLock) {
2974             final String methodStr = "sendNetworkEapSimGsmAuthResponse";
2975             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2976             try {
2977                 SupplicantStatus status =
2978                         mISupplicantStaNetwork.sendNetworkEapSimGsmAuthResponse(params);
2979                 return checkStatusAndLogFailure(status, methodStr);
2980             } catch (RemoteException e) {
2981                 handleRemoteException(e, methodStr);
2982                 return false;
2983             }
2984         }
2985     }
2986 
2987     /** See ISupplicantStaNetwork.hal for documentation */
sendNetworkEapSimGsmAuthFailure()2988     public boolean sendNetworkEapSimGsmAuthFailure() {
2989         synchronized (mLock) {
2990             final String methodStr = "sendNetworkEapSimGsmAuthFailure";
2991             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
2992             try {
2993                 SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimGsmAuthFailure();
2994                 return checkStatusAndLogFailure(status, methodStr);
2995             } catch (RemoteException e) {
2996                 handleRemoteException(e, methodStr);
2997                 return false;
2998             }
2999         }
3000     }
3001 
3002     /**
3003      * Send UMTS auth response.
3004      *
3005      * @param paramsStr Response params as a string.
3006      * @return true if succeeds, false otherwise.
3007      */
sendNetworkEapSimUmtsAuthResponse(String paramsStr)3008     public boolean sendNetworkEapSimUmtsAuthResponse(String paramsStr) {
3009         synchronized (mLock) {
3010             try {
3011                 Matcher match = UMTS_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
3012                 if (!match.find() || match.groupCount() != 3) {
3013                     Log.e(TAG, "Malformed umts auth response params: " + paramsStr);
3014                     return false;
3015                 }
3016                 ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params =
3017                         new ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams();
3018                 byte[] ik = NativeUtil.hexStringToByteArray(match.group(1));
3019                 if (ik == null || ik.length != params.ik.length) {
3020                     Log.e(TAG, "Invalid ik value: " + match.group(1));
3021                     return false;
3022                 }
3023                 byte[] ck = NativeUtil.hexStringToByteArray(match.group(2));
3024                 if (ck == null || ck.length != params.ck.length) {
3025                     Log.e(TAG, "Invalid ck value: " + match.group(2));
3026                     return false;
3027                 }
3028                 byte[] res = NativeUtil.hexStringToByteArray(match.group(3));
3029                 if (res == null || res.length == 0) {
3030                     Log.e(TAG, "Invalid res value: " + match.group(3));
3031                     return false;
3032                 }
3033                 System.arraycopy(ik, 0, params.ik, 0, params.ik.length);
3034                 System.arraycopy(ck, 0, params.ck, 0, params.ck.length);
3035                 for (byte b : res) {
3036                     params.res.add(b);
3037                 }
3038                 return sendNetworkEapSimUmtsAuthResponse(params);
3039             } catch (IllegalArgumentException e) {
3040                 Log.e(TAG, "Illegal argument " + paramsStr, e);
3041                 return false;
3042             }
3043         }
3044     }
3045 
3046     /** See ISupplicantStaNetwork.hal for documentation */
sendNetworkEapSimUmtsAuthResponse( ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params)3047     private boolean sendNetworkEapSimUmtsAuthResponse(
3048             ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params) {
3049         synchronized (mLock) {
3050             final String methodStr = "sendNetworkEapSimUmtsAuthResponse";
3051             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
3052             try {
3053                 SupplicantStatus status =
3054                         mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthResponse(params);
3055                 return checkStatusAndLogFailure(status, methodStr);
3056             } catch (RemoteException e) {
3057                 handleRemoteException(e, methodStr);
3058                 return false;
3059             }
3060         }
3061     }
3062 
3063     /**
3064      * Send UMTS auts response.
3065      *
3066      * @param paramsStr Response params as a string.
3067      * @return true if succeeds, false otherwise.
3068      */
sendNetworkEapSimUmtsAutsResponse(String paramsStr)3069     public boolean sendNetworkEapSimUmtsAutsResponse(String paramsStr) {
3070         synchronized (mLock) {
3071             try {
3072                 Matcher match = UMTS_AUTS_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
3073                 if (!match.find() || match.groupCount() != 1) {
3074                     Log.e(TAG, "Malformed umts auts response params: " + paramsStr);
3075                     return false;
3076                 }
3077                 byte[] auts = NativeUtil.hexStringToByteArray(match.group(1));
3078                 if (auts == null || auts.length != 14) {
3079                     Log.e(TAG, "Invalid auts value: " + match.group(1));
3080                     return false;
3081                 }
3082                 return sendNetworkEapSimUmtsAutsResponse(auts);
3083             } catch (IllegalArgumentException e) {
3084                 Log.e(TAG, "Illegal argument " + paramsStr, e);
3085                 return false;
3086             }
3087         }
3088     }
3089 
3090     /** See ISupplicantStaNetwork.hal for documentation */
sendNetworkEapSimUmtsAutsResponse(byte[ ] auts)3091     private boolean sendNetworkEapSimUmtsAutsResponse(byte[/* 14 */] auts) {
3092         synchronized (mLock) {
3093             final String methodStr = "sendNetworkEapSimUmtsAutsResponse";
3094             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
3095             try {
3096                 SupplicantStatus status =
3097                         mISupplicantStaNetwork.sendNetworkEapSimUmtsAutsResponse(auts);
3098                 return checkStatusAndLogFailure(status, methodStr);
3099             } catch (RemoteException e) {
3100                 handleRemoteException(e, methodStr);
3101                 return false;
3102             }
3103         }
3104     }
3105 
3106     /** See ISupplicantStaNetwork.hal for documentation */
sendNetworkEapSimUmtsAuthFailure()3107     public boolean sendNetworkEapSimUmtsAuthFailure() {
3108         synchronized (mLock) {
3109             final String methodStr = "sendNetworkEapSimUmtsAuthFailure";
3110             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
3111             try {
3112                 SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthFailure();
3113                 return checkStatusAndLogFailure(status, methodStr);
3114             } catch (RemoteException e) {
3115                 handleRemoteException(e, methodStr);
3116                 return false;
3117             }
3118         }
3119     }
3120 
3121     /**
3122      * Method to mock out the V1_1 ISupplicantStaNetwork retrieval in unit tests.
3123      *
3124      * @return 1.1 ISupplicantStaNetwork object if the device is running the 1.1 supplicant hal
3125      * service, null otherwise.
3126      */
3127     protected android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork
getSupplicantStaNetworkForV1_1Mockable()3128     getSupplicantStaNetworkForV1_1Mockable() {
3129         if (mISupplicantStaNetwork == null) return null;
3130         return android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork.castFrom(
3131                 mISupplicantStaNetwork);
3132     }
3133 
3134     /**
3135      * Method to mock out the V1_2 ISupplicantStaNetwork retrieval in unit tests.
3136      *
3137      * @return 1.2 ISupplicantStaNetwork object if the device is running the 1.2 supplicant hal
3138      * service, null otherwise.
3139      */
3140     protected android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
getSupplicantStaNetworkForV1_2Mockable()3141             getSupplicantStaNetworkForV1_2Mockable() {
3142         if (mISupplicantStaNetwork == null) return null;
3143         return android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.castFrom(
3144                 mISupplicantStaNetwork);
3145     }
3146 
3147     /**
3148      * Method to mock out the V1_3 ISupplicantStaNetwork retrieval in unit tests.
3149      *
3150      * @return 1.3 ISupplicantStaNetwork object if the device is running the 1.3 supplicant hal
3151      * service, null otherwise.
3152      */
3153     protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
getSupplicantStaNetworkForV1_3Mockable()3154             getSupplicantStaNetworkForV1_3Mockable() {
3155         if (mISupplicantStaNetwork == null) return null;
3156         return android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.castFrom(
3157                 mISupplicantStaNetwork);
3158     }
3159 
3160     /**
3161      * Send eap identity response.
3162      *
3163      * @param identityStr          identity used for EAP-Identity
3164      * @param encryptedIdentityStr encrypted identity used for EAP-AKA/EAP-SIM
3165      * @return true if succeeds, false otherwise.
3166      */
sendNetworkEapIdentityResponse(String identityStr, String encryptedIdentityStr)3167     public boolean sendNetworkEapIdentityResponse(String identityStr,
3168             String encryptedIdentityStr) {
3169         synchronized (mLock) {
3170             try {
3171                 ArrayList<Byte> unencryptedIdentity =
3172                         NativeUtil.stringToByteArrayList(identityStr);
3173                 ArrayList<Byte> encryptedIdentity = null;
3174                 if (!TextUtils.isEmpty(encryptedIdentityStr)) {
3175                     encryptedIdentity = NativeUtil.stringToByteArrayList(encryptedIdentityStr);
3176                 }
3177                 return sendNetworkEapIdentityResponse(unencryptedIdentity, encryptedIdentity);
3178             } catch (IllegalArgumentException e) {
3179                 Log.e(TAG, "Illegal argument " + identityStr + "," + encryptedIdentityStr, e);
3180                 return false;
3181             }
3182         }
3183     }
3184 
3185     /** See ISupplicantStaNetwork.hal for documentation */
sendNetworkEapIdentityResponse(ArrayList<Byte> unencryptedIdentity, ArrayList<Byte> encryptedIdentity)3186     private boolean sendNetworkEapIdentityResponse(ArrayList<Byte> unencryptedIdentity,
3187             ArrayList<Byte> encryptedIdentity) {
3188         synchronized (mLock) {
3189             final String methodStr = "sendNetworkEapIdentityResponse";
3190             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
3191             try {
3192                 SupplicantStatus status;
3193                 android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork
3194                         iSupplicantStaNetworkV11 =
3195                         getSupplicantStaNetworkForV1_1Mockable();
3196 
3197                 if (iSupplicantStaNetworkV11 != null && encryptedIdentity != null) {
3198                     status = iSupplicantStaNetworkV11.sendNetworkEapIdentityResponse_1_1(
3199                             unencryptedIdentity, encryptedIdentity);
3200                 } else {
3201                     status = mISupplicantStaNetwork.sendNetworkEapIdentityResponse(
3202                             unencryptedIdentity);
3203                 }
3204 
3205                 return checkStatusAndLogFailure(status, methodStr);
3206             } catch (RemoteException e) {
3207                 handleRemoteException(e, methodStr);
3208                 return false;
3209             }
3210         }
3211     }
3212 
3213     /** See ISupplicantStaNetwork.hal for documentation */
setOcsp(@csp int ocsp)3214     private boolean setOcsp(@Ocsp int ocsp) {
3215         synchronized (mLock) {
3216             final String methodStr = "setOcsp";
3217             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
3218 
3219             int halOcspValue = android.hardware.wifi.supplicant.V1_3.OcspType.NONE;
3220             switch (ocsp) {
3221                 case WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS:
3222                     halOcspValue = android.hardware.wifi.supplicant.V1_3
3223                             .OcspType.REQUEST_CERT_STATUS;
3224                     break;
3225                 case WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS:
3226                     halOcspValue = android.hardware.wifi.supplicant.V1_3
3227                             .OcspType.REQUIRE_CERT_STATUS;
3228                     break;
3229                 case WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS:
3230                     halOcspValue = android.hardware.wifi.supplicant.V1_3
3231                             .OcspType.REQUIRE_ALL_CERTS_STATUS;
3232                     break;
3233             }
3234             try {
3235                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
3236                         iSupplicantStaNetworkV13;
3237 
3238                 iSupplicantStaNetworkV13 = getV1_3StaNetwork();
3239                 if (iSupplicantStaNetworkV13 != null) {
3240                     /* Support for OCSP Requires HAL v1.3 or higher */
3241                     SupplicantStatus status = iSupplicantStaNetworkV13
3242                             .setOcsp(halOcspValue);
3243                     return checkStatusAndLogFailure(status, methodStr);
3244                 } else {
3245                     Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
3246                     return false;
3247                 }
3248             } catch (RemoteException e) {
3249                 handleRemoteException(e, methodStr);
3250                 return false;
3251             }
3252         }
3253     }
3254 
3255     /** See ISupplicantStaNetwork.hal for documentation */
getOcsp()3256     private boolean getOcsp() {
3257         synchronized (mLock) {
3258             final String methodStr = "getOcsp";
3259             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
3260 
3261             try {
3262                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
3263                         iSupplicantStaNetworkV13;
3264                 iSupplicantStaNetworkV13 = getV1_3StaNetwork();
3265                 if (iSupplicantStaNetworkV13 != null) {
3266                     MutableBoolean statusOk = new MutableBoolean(false);
3267                     iSupplicantStaNetworkV13.getOcsp((SupplicantStatus status,
3268                             int halOcspValue) -> {
3269                         statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
3270                         if (statusOk.value) {
3271                             mOcsp = WifiEnterpriseConfig.OCSP_NONE;
3272                             switch (halOcspValue) {
3273                                 case android.hardware.wifi.supplicant.V1_3
3274                                         .OcspType.REQUEST_CERT_STATUS:
3275                                     mOcsp = WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS;
3276                                     break;
3277                                 case android.hardware.wifi.supplicant.V1_3
3278                                         .OcspType.REQUIRE_CERT_STATUS:
3279                                     mOcsp = WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS;
3280                                     break;
3281                                 case android.hardware.wifi.supplicant.V1_3
3282                                         .OcspType.REQUIRE_ALL_CERTS_STATUS:
3283                                     mOcsp = WifiEnterpriseConfig
3284                                             .OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS;
3285                                     break;
3286                                 default:
3287                                     Log.e(TAG, "Invalid HAL OCSP value " + halOcspValue);
3288                                     break;
3289                             }
3290                         } else {
3291                             checkStatusAndLogFailure(status, methodStr);
3292                         }
3293                     });
3294                     return statusOk.value;
3295                 } else {
3296                     Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
3297                     return false;
3298                 }
3299             } catch (RemoteException e) {
3300                 handleRemoteException(e, methodStr);
3301                 return false;
3302             }
3303         }
3304     }
3305 
3306     /** See ISupplicantStaNetwork.hal for documentation */
setPmkCache(ArrayList<Byte> serializedEntry)3307     public boolean setPmkCache(ArrayList<Byte> serializedEntry) {
3308         synchronized (mLock) {
3309             final String methodStr = "setPmkCache";
3310             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
3311 
3312             try {
3313                 android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork
3314                         iSupplicantStaNetworkV13;
3315 
3316                 iSupplicantStaNetworkV13 = getV1_3StaNetwork();
3317                 if (iSupplicantStaNetworkV13 != null) {
3318                     SupplicantStatus status = iSupplicantStaNetworkV13
3319                             .setPmkCache(serializedEntry);
3320                     return checkStatusAndLogFailure(status, methodStr);
3321                 } else {
3322                     Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3");
3323                     return false;
3324                 }
3325             } catch (RemoteException e) {
3326                 handleRemoteException(e, methodStr);
3327                 return false;
3328             }
3329         }
3330     }
3331 
3332     /**
3333      * Retrieve the NFC token for this network.
3334      *
3335      * @return Hex string corresponding to the NFC token or null for failure.
3336      */
getWpsNfcConfigurationToken()3337     public String getWpsNfcConfigurationToken() {
3338         synchronized (mLock) {
3339             ArrayList<Byte> token = getWpsNfcConfigurationTokenInternal();
3340             if (token == null) {
3341                 return null;
3342             }
3343             return NativeUtil.hexStringFromByteArray(NativeUtil.byteArrayFromArrayList(token));
3344         }
3345     }
3346 
3347     /** See ISupplicantStaNetwork.hal for documentation */
getWpsNfcConfigurationTokenInternal()3348     private ArrayList<Byte> getWpsNfcConfigurationTokenInternal() {
3349         synchronized (mLock) {
3350             final String methodStr = "getWpsNfcConfigurationToken";
3351             if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return null;
3352             final Mutable<ArrayList<Byte>> gotToken = new Mutable<>();
3353             try {
3354                 mISupplicantStaNetwork.getWpsNfcConfigurationToken(
3355                         (SupplicantStatus status, ArrayList<Byte> token) -> {
3356                             if (checkStatusAndLogFailure(status, methodStr)) {
3357                                 gotToken.value = token;
3358                             }
3359                         });
3360             } catch (RemoteException e) {
3361                 handleRemoteException(e, methodStr);
3362             }
3363             return gotToken.value;
3364         }
3365     }
3366 
3367     /**
3368      * Returns true if provided status code is SUCCESS, logs debug message and returns false
3369      * otherwise
3370      */
checkStatusAndLogFailure(SupplicantStatus status, final String methodStr)3371     private boolean checkStatusAndLogFailure(SupplicantStatus status, final String methodStr) {
3372         synchronized (mLock) {
3373             if (status.code != SupplicantStatusCode.SUCCESS) {
3374                 Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + status);
3375                 return false;
3376             } else {
3377                 if (mVerboseLoggingEnabled) {
3378                     Log.d(TAG, "ISupplicantStaNetwork." + methodStr + " succeeded");
3379                 }
3380                 return true;
3381             }
3382         }
3383     }
3384 
3385     /**
3386      * Helper function to log callbacks.
3387      */
logCallback(final String methodStr)3388     private void logCallback(final String methodStr) {
3389         synchronized (mLock) {
3390             if (mVerboseLoggingEnabled) {
3391                 Log.d(TAG, "ISupplicantStaNetworkCallback." + methodStr + " received");
3392             }
3393         }
3394     }
3395 
3396     /**
3397      * Returns false if ISupplicantStaNetwork is null, and logs failure of methodStr
3398      */
checkISupplicantStaNetworkAndLogFailure(final String methodStr)3399     private boolean checkISupplicantStaNetworkAndLogFailure(final String methodStr) {
3400         synchronized (mLock) {
3401             if (mISupplicantStaNetwork == null) {
3402                 Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaNetwork is null");
3403                 return false;
3404             }
3405             return true;
3406         }
3407     }
3408 
handleRemoteException(RemoteException e, String methodStr)3409     private void handleRemoteException(RemoteException e, String methodStr) {
3410         synchronized (mLock) {
3411             mISupplicantStaNetwork = null;
3412             Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed with exception", e);
3413         }
3414     }
3415 
3416     /**
3417      * Adds FT flags for networks if the device supports it.
3418      */
addFastTransitionFlags(BitSet keyManagementFlags)3419     private BitSet addFastTransitionFlags(BitSet keyManagementFlags) {
3420         synchronized (mLock) {
3421             if (!mContext.getResources().getBoolean(
3422                     R.bool.config_wifi_fast_bss_transition_enabled)) {
3423                 return keyManagementFlags;
3424             }
3425             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3426             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
3427                 modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_PSK);
3428             }
3429             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
3430                 modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_EAP);
3431             }
3432             return modifiedFlags;
3433         }
3434     }
3435 
3436     /**
3437      * Removes FT flags for networks if the device supports it.
3438      */
removeFastTransitionFlags(BitSet keyManagementFlags)3439     private BitSet removeFastTransitionFlags(BitSet keyManagementFlags) {
3440         synchronized (mLock) {
3441             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3442             modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_PSK);
3443             modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_EAP);
3444             return modifiedFlags;
3445         }
3446     }
3447 
3448      /**
3449      * Adds SHA256 key management flags for networks.
3450      */
addSha256KeyMgmtFlags(BitSet keyManagementFlags)3451     private BitSet addSha256KeyMgmtFlags(BitSet keyManagementFlags) {
3452         synchronized (mLock) {
3453             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3454             android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork
3455                     iSupplicantStaNetworkV12;
3456             iSupplicantStaNetworkV12 = getV1_2StaNetwork();
3457             if (iSupplicantStaNetworkV12 == null) {
3458                 // SHA256 key management requires HALv1.2 or higher
3459                 return modifiedFlags;
3460             }
3461 
3462             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
3463                 modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
3464             }
3465             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
3466                 modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
3467             }
3468             return modifiedFlags;
3469         }
3470     }
3471 
3472     /**
3473      * Removes SHA256 key management flags for networks.
3474      */
removeSha256KeyMgmtFlags(BitSet keyManagementFlags)3475     private BitSet removeSha256KeyMgmtFlags(BitSet keyManagementFlags) {
3476         synchronized (mLock) {
3477             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3478             modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
3479             modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
3480             return modifiedFlags;
3481         }
3482     }
3483 
3484     /**
3485      * Creates the JSON encoded network extra using the map of string key, value pairs.
3486      */
createNetworkExtra(Map<String, String> values)3487     public static String createNetworkExtra(Map<String, String> values) {
3488         final String encoded;
3489         try {
3490             encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8");
3491         } catch (NullPointerException e) {
3492             Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
3493             return null;
3494         } catch (UnsupportedEncodingException e) {
3495             Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
3496             return null;
3497         }
3498         return encoded;
3499     }
3500 
3501     /**
3502      * Parse the network extra JSON encoded string to a map of string key, value pairs.
3503      */
parseNetworkExtra(String encoded)3504     public static Map<String, String> parseNetworkExtra(String encoded) {
3505         if (TextUtils.isEmpty(encoded)) {
3506             return null;
3507         }
3508         try {
3509             // This method reads a JSON dictionary that was written by setNetworkExtra(). However,
3510             // on devices that upgraded from Marshmallow, it may encounter a legacy value instead -
3511             // an FQDN stored as a plain string. If such a value is encountered, the JSONObject
3512             // constructor will thrown a JSONException and the method will return null.
3513             final JSONObject json = new JSONObject(URLDecoder.decode(encoded, "UTF-8"));
3514             final Map<String, String> values = new HashMap<>();
3515             final Iterator<?> it = json.keys();
3516             while (it.hasNext()) {
3517                 final String key = (String) it.next();
3518                 final Object value = json.get(key);
3519                 if (value instanceof String) {
3520                     values.put(key, (String) value);
3521                 }
3522             }
3523             return values;
3524         } catch (UnsupportedEncodingException e) {
3525             Log.e(TAG, "Unable to deserialize networkExtra: " + e.toString());
3526             return null;
3527         } catch (JSONException e) {
3528             // This is not necessarily an error. This exception will also occur if we encounter a
3529             // legacy FQDN stored as a plain string. We want to return null in this case as no JSON
3530             // dictionary of extras was found.
3531             return null;
3532         }
3533     }
3534 
3535     private class SupplicantStaNetworkHalCallback extends ISupplicantStaNetworkCallback.Stub {
3536         /**
3537          * Current configured network's framework network id.
3538          */
3539         private final int mFramewokNetworkId;
3540         /**
3541          * Current configured network's ssid.
3542          */
3543         private final String mSsid;
3544 
SupplicantStaNetworkHalCallback(int framewokNetworkId, String ssid)3545         SupplicantStaNetworkHalCallback(int framewokNetworkId, String ssid) {
3546             mFramewokNetworkId = framewokNetworkId;
3547             mSsid = ssid;
3548         }
3549 
3550         @Override
onNetworkEapSimGsmAuthRequest( ISupplicantStaNetworkCallback.NetworkRequestEapSimGsmAuthParams params)3551         public void onNetworkEapSimGsmAuthRequest(
3552                 ISupplicantStaNetworkCallback.NetworkRequestEapSimGsmAuthParams params) {
3553             synchronized (mLock) {
3554                 logCallback("onNetworkEapSimGsmAuthRequest");
3555                 String[] data = new String[params.rands.size()];
3556                 int i = 0;
3557                 for (byte[] rand : params.rands) {
3558                     data[i++] = NativeUtil.hexStringFromByteArray(rand);
3559                 }
3560                 mWifiMonitor.broadcastNetworkGsmAuthRequestEvent(
3561                         mIfaceName, mFramewokNetworkId, mSsid, data);
3562             }
3563         }
3564 
3565         @Override
onNetworkEapSimUmtsAuthRequest( ISupplicantStaNetworkCallback.NetworkRequestEapSimUmtsAuthParams params)3566         public void onNetworkEapSimUmtsAuthRequest(
3567                 ISupplicantStaNetworkCallback.NetworkRequestEapSimUmtsAuthParams params) {
3568             synchronized (mLock) {
3569                 logCallback("onNetworkEapSimUmtsAuthRequest");
3570                 String randHex = NativeUtil.hexStringFromByteArray(params.rand);
3571                 String autnHex = NativeUtil.hexStringFromByteArray(params.autn);
3572                 String[] data = {randHex, autnHex};
3573                 mWifiMonitor.broadcastNetworkUmtsAuthRequestEvent(
3574                         mIfaceName, mFramewokNetworkId, mSsid, data);
3575             }
3576         }
3577 
3578         @Override
onNetworkEapIdentityRequest()3579         public void onNetworkEapIdentityRequest() {
3580             synchronized (mLock) {
3581                 logCallback("onNetworkEapIdentityRequest");
3582                 mWifiMonitor.broadcastNetworkIdentityRequestEvent(
3583                         mIfaceName, mFramewokNetworkId, mSsid);
3584             }
3585         }
3586     }
3587 }
3588