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