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