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