/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.wifi; import android.content.Context; import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetwork; import android.hardware.wifi.supplicant.V1_0.ISupplicantStaNetworkCallback; import android.hardware.wifi.supplicant.V1_0.SupplicantStatus; import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode; import android.net.wifi.SecurityParams; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiEnterpriseConfig.Ocsp; import android.net.wifi.WifiManager; import android.os.RemoteException; import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.server.wifi.util.ArrayUtils; import com.android.server.wifi.util.GeneralUtil.Mutable; import com.android.server.wifi.util.NativeUtil; import com.android.wifi.resources.R; import org.json.JSONException; import org.json.JSONObject; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.BitSet; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.concurrent.ThreadSafe; /** * Wrapper class for ISupplicantStaNetwork HAL calls. Gets and sets supplicant sta network variables * and interacts with networks. * Public fields should be treated as invalid until their 'get' method is called, which will set the * value if it returns true * To maintain thread-safety, the locking protocol is that every non-static method (regardless of * access level) acquires mLock. */ @ThreadSafe public class SupplicantStaNetworkHal { private static final String TAG = "SupplicantStaNetworkHal"; @VisibleForTesting public static final String ID_STRING_KEY_FQDN = "fqdn"; @VisibleForTesting public static final String ID_STRING_KEY_CREATOR_UID = "creatorUid"; @VisibleForTesting public static final String ID_STRING_KEY_CONFIG_KEY = "configKey"; /** * Regex pattern for extracting the GSM sim authentication response params from a string. * Matches a strings like the following: "[::]"; */ private static final Pattern GSM_AUTH_RESPONSE_PARAMS_PATTERN = Pattern.compile(":([0-9a-fA-F]+):([0-9a-fA-F]+)"); /** * Regex pattern for extracting the UMTS sim authentication response params from a string. * Matches a strings like the following: ":::"; */ private static final Pattern UMTS_AUTH_RESPONSE_PARAMS_PATTERN = Pattern.compile("^:([0-9a-fA-F]+):([0-9a-fA-F]+):([0-9a-fA-F]+)$"); /** * Regex pattern for extracting the UMTS sim auts response params from a string. * Matches a strings like the following: ":"; */ private static final Pattern UMTS_AUTS_RESPONSE_PARAMS_PATTERN = Pattern.compile("^:([0-9a-fA-F]+)$"); private final Object mLock = new Object(); private final Context mContext; private final String mIfaceName; private final WifiMonitor mWifiMonitor; private final WifiGlobals mWifiGlobals; private ISupplicantStaNetwork mISupplicantStaNetwork; private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback; private boolean mVerboseLoggingEnabled = false; // Network variables read from wpa_supplicant. private int mNetworkId; private ArrayList mSsid; private byte[/* 6 */] mBssid; private boolean mScanSsid; private int mKeyMgmtMask; private int mProtoMask; private int mAuthAlgMask; private int mGroupCipherMask; private int mPairwiseCipherMask; private int mGroupMgmtCipherMask; private String mPskPassphrase; private String mSaePassword; private String mSaePasswordId; private byte[] mPsk; private ArrayList mWepKey; private int mWepTxKeyIdx; private boolean mRequirePmf; private String mIdStr; private int mEapMethod; private int mEapPhase2Method; private ArrayList mEapIdentity; private ArrayList mEapAnonymousIdentity; private ArrayList mEapPassword; private String mEapCACert; private String mEapCAPath; private String mEapClientCert; private String mEapPrivateKeyId; private String mEapSubjectMatch; private String mEapAltSubjectMatch; private boolean mEapEngine; private String mEapEngineID; private String mEapDomainSuffixMatch; private @Ocsp int mOcsp; private String mWapiCertSuite; private long mAdvanceKeyMgmtFeatures; SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork, String ifaceName, Context context, WifiMonitor monitor, WifiGlobals wifiGlobals, long advanceKeyMgmtFeature) { mISupplicantStaNetwork = iSupplicantStaNetwork; mContext = context; mIfaceName = ifaceName; mWifiMonitor = monitor; mWifiGlobals = wifiGlobals; mAdvanceKeyMgmtFeatures = advanceKeyMgmtFeature; } /** * Enable/Disable verbose logging. * * @param enable true to enable, false to disable. */ void enableVerboseLogging(boolean enable) { synchronized (mLock) { mVerboseLoggingEnabled = enable; } } /** * Read network variables from wpa_supplicant into the provided WifiConfiguration object. * * @param config WifiConfiguration object to be populated. * @param networkExtras Map of network extras parsed from wpa_supplicant. * @return true if succeeds, false otherwise. * @throws IllegalArgumentException on malformed configuration params. */ @VisibleForTesting public boolean loadWifiConfiguration(WifiConfiguration config, Map networkExtras) { synchronized (mLock) { if (config == null) return false; /** SSID */ config.SSID = null; if (getSsid() && !ArrayUtils.isEmpty(mSsid)) { config.SSID = NativeUtil.encodeSsid(mSsid); } else { Log.e(TAG, "failed to read ssid"); return false; } /** Network Id */ config.networkId = -1; if (getId()) { config.networkId = mNetworkId; } else { Log.e(TAG, "getId failed"); return false; } /** BSSID */ config.getNetworkSelectionStatus().setNetworkSelectionBSSID(null); if (getBssid() && !ArrayUtils.isEmpty(mBssid)) { config.getNetworkSelectionStatus().setNetworkSelectionBSSID( NativeUtil.macAddressFromByteArray(mBssid)); } /** Scan SSID (Is Hidden Network?) */ config.hiddenSSID = false; if (getScanSsid()) { config.hiddenSSID = mScanSsid; } /** Require PMF*/ config.requirePmf = false; if (getRequirePmf()) { config.requirePmf = mRequirePmf; } /** WEP keys **/ config.wepTxKeyIndex = -1; if (getWepTxKeyIdx()) { config.wepTxKeyIndex = mWepTxKeyIdx; } for (int i = 0; i < 4; i++) { config.wepKeys[i] = null; if (getWepKey(i) && !ArrayUtils.isEmpty(mWepKey)) { config.wepKeys[i] = NativeUtil.bytesToHexOrQuotedString(mWepKey); } } /** allowedKeyManagement */ if (getKeyMgmt()) { BitSet keyMgmtMask = supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask); keyMgmtMask = removeFastTransitionFlags(keyMgmtMask); keyMgmtMask = removeSha256KeyMgmtFlags(keyMgmtMask); keyMgmtMask = removePskSaeUpgradableTypeFlags(keyMgmtMask); config.setSecurityParams(keyMgmtMask); config.enableFils( keyMgmtMask.get(WifiConfiguration.KeyMgmt.FILS_SHA256), keyMgmtMask.get(WifiConfiguration.KeyMgmt.FILS_SHA384)); } // supplicant only have one valid security type, it won't be a disbled params. SecurityParams securityParams = config.getDefaultSecurityParams(); /** PSK pass phrase */ config.preSharedKey = null; if (getPskPassphrase() && !TextUtils.isEmpty(mPskPassphrase)) { if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK)) { config.preSharedKey = mPskPassphrase; } else { config.preSharedKey = NativeUtil.addEnclosingQuotes(mPskPassphrase); } } else if (getPsk() && !ArrayUtils.isEmpty(mPsk)) { config.preSharedKey = NativeUtil.hexStringFromByteArray(mPsk); } /* Do not read SAE password */ /** metadata: idstr */ if (getIdStr() && !TextUtils.isEmpty(mIdStr)) { Map metadata = parseNetworkExtra(mIdStr); networkExtras.putAll(metadata); } else { Log.w(TAG, "getIdStr failed or empty"); } /** WAPI Cert Suite */ if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_CERT)) { if (config.enterpriseConfig == null) { return false; } config.enterpriseConfig.setEapMethod( WifiEnterpriseConfig.Eap.WAPI_CERT); /** WAPI Certificate Suite. */ if (getWapiCertSuite() && !TextUtils.isEmpty(mWapiCertSuite)) { config.enterpriseConfig.setWapiCertSuite(mWapiCertSuite); } return true; } return loadWifiEnterpriseConfig(config.SSID, config.enterpriseConfig); } } /** * Save an entire WifiConfiguration to wpa_supplicant via HIDL. * * @param config WifiConfiguration object to be saved. * @return true if succeeds, false otherwise. * @throws IllegalArgumentException on malformed configuration params. */ public boolean saveWifiConfiguration(WifiConfiguration config) { synchronized (mLock) { if (config == null) return false; /** SSID */ if (config.SSID != null) { if (!setSsid(NativeUtil.decodeSsid(config.SSID))) { Log.e(TAG, "failed to set SSID: " + config.SSID); return false; } } /** BSSID */ String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID(); if (bssidStr != null) { byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr); if (!setBssid(bssid)) { Log.e(TAG, "failed to set BSSID: " + bssidStr); return false; } } /** HiddenSSID */ if (!setScanSsid(config.hiddenSSID)) { Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID); return false; } SecurityParams securityParams = config.getNetworkSelectionStatus() .getCandidateSecurityParams(); if (null == securityParams) { Log.wtf(TAG, "No available security params."); return false; } Log.d(TAG, "The target security params: " + securityParams); /** RequirePMF */ if (!setRequirePmf(securityParams.isRequirePmf())) { Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePmf); return false; } /** Key Management Scheme */ BitSet allowedKeyManagement = securityParams.getAllowedKeyManagement(); if (allowedKeyManagement.cardinality() != 0) { // Add FT flags if supported. BitSet keyMgmtMask = addFastTransitionFlags(allowedKeyManagement); // Add SHA256 key management flags. keyMgmtMask = addSha256KeyMgmtFlags(keyMgmtMask); // Add upgradable type key management flags for PSK/SAE. keyMgmtMask = addPskSaeUpgradableTypeFlagsIfSupported( config, keyMgmtMask); if (!setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(keyMgmtMask))) { Log.e(TAG, "failed to set Key Management"); return false; } // Check and set SuiteB configurations. if (keyMgmtMask.get(WifiConfiguration.KeyMgmt.SUITE_B_192) && !saveSuiteBConfig(config)) { Log.e(TAG, "Failed to set Suite-B-192 configuration"); return false; } } /** Security Protocol */ BitSet allowedProtocols = securityParams.getAllowedProtocols(); if (allowedProtocols.cardinality() != 0 && !setProto(wifiConfigurationToSupplicantProtoMask(allowedProtocols))) { Log.e(TAG, "failed to set Security Protocol"); return false; } /** Auth Algorithm */ BitSet allowedAuthAlgorithms = securityParams.getAllowedAuthAlgorithms(); if (allowedAuthAlgorithms.cardinality() != 0 && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask( allowedAuthAlgorithms))) { Log.e(TAG, "failed to set AuthAlgorithm"); return false; } /** Group Cipher */ BitSet allowedGroupCiphers = securityParams.getAllowedGroupCiphers(); if (allowedGroupCiphers.cardinality() != 0 && (!setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask( allowedGroupCiphers)))) { Log.e(TAG, "failed to set Group Cipher"); return false; } /** Pairwise Cipher*/ BitSet allowedPairwiseCiphers = securityParams.getAllowedPairwiseCiphers(); if (allowedPairwiseCiphers.cardinality() != 0 && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask( allowedPairwiseCiphers))) { Log.e(TAG, "failed to set PairwiseCipher"); return false; } /** Pre Shared Key */ // For PSK, this can either be quoted ASCII passphrase or hex string for raw psk. // For SAE, password must be a quoted ASCII string if (config.preSharedKey != null) { if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK)) { if (!setPskPassphrase(config.preSharedKey)) { Log.e(TAG, "failed to set wapi psk passphrase"); return false; } } else if (config.preSharedKey.startsWith("\"")) { if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)) { /* WPA3 case, field is SAE Password */ if (!setSaePassword( NativeUtil.removeEnclosingQuotes(config.preSharedKey))) { Log.e(TAG, "failed to set sae password"); return false; } } else { if (!setPskPassphrase( NativeUtil.removeEnclosingQuotes(config.preSharedKey))) { Log.e(TAG, "failed to set psk passphrase"); return false; } } } else { if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)) { return false; } if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) { Log.e(TAG, "failed to set psk"); return false; } } } /** Wep Keys */ boolean hasSetKey = false; if (config.wepKeys != null) { for (int i = 0; i < config.wepKeys.length; i++) { if (config.wepKeys[i] != null) { if (!setWepKey( i, NativeUtil.hexOrQuotedStringToBytes(config.wepKeys[i]))) { Log.e(TAG, "failed to set wep_key " + i); return false; } hasSetKey = true; } } } /** Wep Tx Key Idx */ if (hasSetKey) { if (!setWepTxKeyIdx(config.wepTxKeyIndex)) { Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex); return false; } } /** metadata: FQDN + ConfigKey + CreatorUid */ final Map metadata = new HashMap(); if (config.isPasspoint()) { metadata.put(ID_STRING_KEY_FQDN, config.FQDN); } metadata.put(ID_STRING_KEY_CONFIG_KEY, config.getProfileKey()); metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid)); if (!setIdStr(createNetworkExtra(metadata))) { Log.e(TAG, "failed to set id string"); return false; } /** UpdateIdentifier */ if (config.updateIdentifier != null && !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) { Log.e(TAG, "failed to set update identifier"); return false; } /** SAE configuration */ if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE) && getV1_4StaNetwork() != null) { /** * Hash-to-Element preference. * For devices that don't support H2E, H2E mode will be permanently disabled. * Devices that support H2E will enable both legacy and H2E mode by default, * and will connect to SAE networks with H2E if possible, unless H2E only * mode is enabled, and then the device will not connect to SAE networks in * legacy mode. */ if (!mWifiGlobals.isWpa3SaeH2eSupported() && securityParams.isSaeH2eOnlyMode()) { Log.e(TAG, "This device does not support SAE H2E."); return false; } byte mode = mWifiGlobals.isWpa3SaeH2eSupported() ? android.hardware.wifi.supplicant.V1_4 .ISupplicantStaNetwork.SaeH2eMode.H2E_OPTIONAL : android.hardware.wifi.supplicant.V1_4 .ISupplicantStaNetwork.SaeH2eMode.DISABLED; if (securityParams.isSaeH2eOnlyMode()) { mode = android.hardware.wifi.supplicant.V1_4 .ISupplicantStaNetwork.SaeH2eMode.H2E_MANDATORY; } if (!setSaeH2eMode(mode)) { Log.e(TAG, "failed to set H2E preference."); return false; } } // Finish here if no EAP config to set if (config.enterpriseConfig != null && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) { if (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.WAPI_CERT) { /** WAPI certificate suite name*/ String param = config.enterpriseConfig .getFieldValue(WifiEnterpriseConfig.WAPI_CERT_SUITE_KEY); if (!TextUtils.isEmpty(param) && !setWapiCertSuite(param)) { Log.e(TAG, config.SSID + ": failed to set WAPI certificate suite: " + param); return false; } return true; } else if (!saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig)) { return false; } } // Now that the network is configured fully, start listening for callback events. return tryRegisterCallback(config.networkId, config.SSID); } } private boolean tryRegisterCallback_1_4(int networkId, String ssid) { if (getV1_4StaNetwork() == null) return false; SupplicantStaNetworkHalCallbackV1_4 callback = new SupplicantStaNetworkHalCallbackV1_4(networkId, ssid); if (!registerCallback_1_4(callback)) { Log.e(TAG, "Failed to register V1.4 callback"); return false; } mISupplicantStaNetworkCallback = callback; return true; } private boolean tryRegisterCallback(int networkId, String ssid) { /* try newer version fist. */ if (getV1_4StaNetwork() != null) { return tryRegisterCallback_1_4(networkId, ssid); } mISupplicantStaNetworkCallback = new SupplicantStaNetworkHalCallback(networkId, ssid); if (!registerCallback(mISupplicantStaNetworkCallback)) { Log.e(TAG, "Failed to register callback"); return false; } return true; } /** * Read network variables from wpa_supplicant into the provided WifiEnterpriseConfig object. * * @param ssid SSID of the network. (Used for logging purposes only) * @param eapConfig WifiEnterpriseConfig object to be populated. * @return true if succeeds, false otherwise. */ private boolean loadWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) { synchronized (mLock) { if (eapConfig == null) return false; /** EAP method */ if (getEapMethod()) { eapConfig.setEapMethod(supplicantToWifiConfigurationEapMethod(mEapMethod)); } else { // Invalid eap method could be because it's not an enterprise config. Log.e(TAG, "failed to get eap method. Assumimg not an enterprise network"); return true; } /** EAP Phase 2 method */ if (getEapPhase2Method()) { eapConfig.setPhase2Method( supplicantToWifiConfigurationEapPhase2Method(mEapPhase2Method)); } else { // We cannot have an invalid eap phase 2 method. Return failure. Log.e(TAG, "failed to get eap phase2 method"); return false; } /** EAP Identity */ if (getEapIdentity() && !ArrayUtils.isEmpty(mEapIdentity)) { eapConfig.setFieldValue( WifiEnterpriseConfig.IDENTITY_KEY, NativeUtil.stringFromByteArrayList(mEapIdentity)); } /** EAP Anonymous Identity */ if (getEapAnonymousIdentity() && !ArrayUtils.isEmpty(mEapAnonymousIdentity)) { eapConfig.setFieldValue( WifiEnterpriseConfig.ANON_IDENTITY_KEY, NativeUtil.stringFromByteArrayList(mEapAnonymousIdentity)); } /** EAP Password */ if (getEapPassword() && !ArrayUtils.isEmpty(mEapPassword)) { eapConfig.setFieldValue( WifiEnterpriseConfig.PASSWORD_KEY, NativeUtil.stringFromByteArrayList(mEapPassword)); } /** EAP Client Cert */ if (getEapClientCert() && !TextUtils.isEmpty(mEapClientCert)) { eapConfig.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, mEapClientCert); } /** EAP CA Cert */ if (getEapCACert() && !TextUtils.isEmpty(mEapCACert)) { eapConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, mEapCACert); } /** EAP OCSP type */ if (getOcsp()) { eapConfig.setOcsp(mOcsp); } /** EAP Subject Match */ if (getEapSubjectMatch() && !TextUtils.isEmpty(mEapSubjectMatch)) { eapConfig.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, mEapSubjectMatch); } /** EAP Engine ID */ if (getEapEngineID() && !TextUtils.isEmpty(mEapEngineID)) { eapConfig.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, mEapEngineID); } /** EAP Engine. Set this only if the engine id is non null. */ if (getEapEngine() && !TextUtils.isEmpty(mEapEngineID)) { eapConfig.setFieldValue( WifiEnterpriseConfig.ENGINE_KEY, mEapEngine ? WifiEnterpriseConfig.ENGINE_ENABLE : WifiEnterpriseConfig.ENGINE_DISABLE); } /** EAP Private Key */ if (getEapPrivateKeyId() && !TextUtils.isEmpty(mEapPrivateKeyId)) { eapConfig.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, mEapPrivateKeyId); } /** EAP Alt Subject Match */ if (getEapAltSubjectMatch() && !TextUtils.isEmpty(mEapAltSubjectMatch)) { eapConfig.setFieldValue( WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, mEapAltSubjectMatch); } /** EAP Domain Suffix Match */ if (getEapDomainSuffixMatch() && !TextUtils.isEmpty(mEapDomainSuffixMatch)) { eapConfig.setFieldValue( WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, mEapDomainSuffixMatch); } /** EAP CA Path*/ if (getEapCAPath() && !TextUtils.isEmpty(mEapCAPath)) { eapConfig.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, mEapCAPath); } return true; } } /** * Save network variables from the provided SuiteB configuration to wpa_supplicant. * * @param config WifiConfiguration object to be saved * @return true if succeeds, false otherwise. */ private boolean saveSuiteBConfig(WifiConfiguration config) { SecurityParams securityParams = config.getNetworkSelectionStatus() .getCandidateSecurityParams(); if (null == securityParams) { Log.wtf(TAG, "No available security params."); return false; } /** Group Cipher **/ BitSet allowedGroupCiphers = securityParams.getAllowedGroupCiphers(); if (allowedGroupCiphers.cardinality() != 0 && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask( allowedGroupCiphers))) { Log.e(TAG, "failed to set Group Cipher"); return false; } /** Pairwise Cipher*/ BitSet allowedPairwiseCiphers = securityParams.getAllowedPairwiseCiphers(); if (allowedPairwiseCiphers.cardinality() != 0 && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask( allowedPairwiseCiphers))) { Log.e(TAG, "failed to set PairwiseCipher"); return false; } /** GroupMgmt Cipher */ BitSet allowedGroupManagementCiphers = securityParams.getAllowedGroupManagementCiphers(); if (allowedGroupManagementCiphers.cardinality() != 0 && !setGroupMgmtCipher(wifiConfigurationToSupplicantGroupMgmtCipherMask( allowedGroupManagementCiphers))) { Log.e(TAG, "failed to set GroupMgmtCipher"); return false; } BitSet allowedSuiteBCiphers = securityParams.getAllowedSuiteBCiphers(); if (allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)) { if (!enableTlsSuiteBEapPhase1Param(true)) { Log.e(TAG, "failed to set TLSSuiteB"); return false; } } else if (allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)) { if (!enableSuiteBEapOpenSslCiphers()) { Log.e(TAG, "failed to set OpensslCipher"); return false; } } return true; } /** * Save network variables from the provided WifiEnterpriseConfig object to wpa_supplicant. * * @param ssid SSID of the network. (Used for logging purposes only) * @param eapConfig WifiEnterpriseConfig object to be saved. * @return true if succeeds, false otherwise. */ private boolean saveWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) { synchronized (mLock) { if (eapConfig == null) return false; /** EAP method */ if (!setEapMethod(wifiConfigurationToSupplicantEapMethod(eapConfig.getEapMethod()))) { Log.e(TAG, ssid + ": failed to set eap method: " + eapConfig.getEapMethod()); return false; } /** EAP Phase 2 method */ if (!setEapPhase2Method(wifiConfigurationToSupplicantEapPhase2Method( eapConfig.getPhase2Method()))) { Log.e(TAG, ssid + ": failed to set eap phase 2 method: " + eapConfig.getPhase2Method()); return false; } String eapParam = null; /** EAP Identity */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapIdentity(NativeUtil.stringToByteArrayList(eapParam))) { Log.e(TAG, ssid + ": failed to set eap identity: " + eapParam); return false; } /** EAP Anonymous Identity */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY); if (!TextUtils.isEmpty(eapParam)) { if (null != getV1_4StaNetwork()) { String decoratedUsernamePrefix = eapConfig.getFieldValue( WifiEnterpriseConfig.DECORATED_IDENTITY_PREFIX_KEY); if (!TextUtils.isEmpty(decoratedUsernamePrefix)) { eapParam = decoratedUsernamePrefix + eapParam; } } if (!setEapAnonymousIdentity(NativeUtil.stringToByteArrayList(eapParam))) { Log.e(TAG, ssid + ": failed to set eap anonymous identity: " + eapParam); return false; } } /** EAP Password */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapPassword(NativeUtil.stringToByteArrayList(eapParam))) { Log.e(TAG, ssid + ": failed to set eap password"); return false; } /** EAP Client Cert */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapClientCert(eapParam)) { Log.e(TAG, ssid + ": failed to set eap client cert: " + eapParam); return false; } /** EAP CA Cert */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapCACert(eapParam)) { Log.e(TAG, ssid + ": failed to set eap ca cert: " + eapParam); return false; } /** EAP Subject Match */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapSubjectMatch(eapParam)) { Log.e(TAG, ssid + ": failed to set eap subject match: " + eapParam); return false; } /** EAP Engine ID */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapEngineID(eapParam)) { Log.e(TAG, ssid + ": failed to set eap engine id: " + eapParam); return false; } /** EAP Engine */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapEngine( eapParam.equals(WifiEnterpriseConfig.ENGINE_ENABLE) ? true : false)) { Log.e(TAG, ssid + ": failed to set eap engine: " + eapParam); return false; } /** EAP Private Key */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapPrivateKeyId(eapParam)) { Log.e(TAG, ssid + ": failed to set eap private key: " + eapParam); return false; } /** EAP Alt Subject Match */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapAltSubjectMatch(eapParam)) { Log.e(TAG, ssid + ": failed to set eap alt subject match: " + eapParam); return false; } /** EAP Domain Suffix Match */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapDomainSuffixMatch(eapParam)) { Log.e(TAG, ssid + ": failed to set eap domain suffix match: " + eapParam); return false; } /** EAP CA Path*/ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY); if (!TextUtils.isEmpty(eapParam) && !setEapCAPath(eapParam)) { Log.e(TAG, ssid + ": failed to set eap ca path: " + eapParam); return false; } /** EAP Proactive Key Caching */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.OPP_KEY_CACHING); if (!TextUtils.isEmpty(eapParam) && !setEapProactiveKeyCaching(eapParam.equals("1") ? true : false)) { Log.e(TAG, ssid + ": failed to set proactive key caching: " + eapParam); return false; } /** * OCSP (Online Certificate Status Protocol) * For older HAL compatibility, omit this step to avoid breaking * connection flow. */ if (getV1_3StaNetwork() != null && !setOcsp(eapConfig.getOcsp())) { Log.e(TAG, "failed to set ocsp"); return false; } /** EAP ERP */ eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.EAP_ERP); if (!TextUtils.isEmpty(eapParam) && eapParam.equals("1")) { if (!setEapErp(true)) { Log.e(TAG, ssid + ": failed to set eap erp"); return false; } } return true; } } private android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork getV1_2StaNetwork() { synchronized (mLock) { return getSupplicantStaNetworkForV1_2Mockable(); } } private android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork getV1_3StaNetwork() { synchronized (mLock) { return getSupplicantStaNetworkForV1_3Mockable(); } } private android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork getV1_4StaNetwork() { synchronized (mLock) { return getSupplicantStaNetworkForV1_4Mockable(); } } /** * Maps WifiConfiguration Key Management BitSet to Supplicant HIDL bitmask int * TODO(b/32571829): Update mapping when fast transition keys are added * * @return bitmask int describing the allowed Key Management schemes, readable by the Supplicant * HIDL hal */ private static int wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt) { int mask = 0; for (int bit = keyMgmt.nextSetBit(0); bit != -1; bit = keyMgmt.nextSetBit(bit + 1)) { switch (bit) { case WifiConfiguration.KeyMgmt.NONE: mask |= ISupplicantStaNetwork.KeyMgmtMask.NONE; break; case WifiConfiguration.KeyMgmt.WPA_PSK: mask |= ISupplicantStaNetwork.KeyMgmtMask.WPA_PSK; break; case WifiConfiguration.KeyMgmt.WPA_EAP: mask |= ISupplicantStaNetwork.KeyMgmtMask.WPA_EAP; break; case WifiConfiguration.KeyMgmt.IEEE8021X: mask |= ISupplicantStaNetwork.KeyMgmtMask.IEEE8021X; break; case WifiConfiguration.KeyMgmt.OSEN: mask |= ISupplicantStaNetwork.KeyMgmtMask.OSEN; break; case WifiConfiguration.KeyMgmt.FT_PSK: mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_PSK; break; case WifiConfiguration.KeyMgmt.FT_EAP: mask |= ISupplicantStaNetwork.KeyMgmtMask.FT_EAP; break; case WifiConfiguration.KeyMgmt.OWE: mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask .OWE; break; case WifiConfiguration.KeyMgmt.SAE: mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask .SAE; break; case WifiConfiguration.KeyMgmt.SUITE_B_192: mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask .SUITE_B_192; break; case WifiConfiguration.KeyMgmt.WPA_PSK_SHA256: mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask .WPA_PSK_SHA256; break; case WifiConfiguration.KeyMgmt.WPA_EAP_SHA256: mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask .WPA_EAP_SHA256; break; case WifiConfiguration.KeyMgmt.WAPI_PSK: mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask .WAPI_PSK; break; case WifiConfiguration.KeyMgmt.WAPI_CERT: mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask .WAPI_CERT; break; case WifiConfiguration.KeyMgmt.FILS_SHA256: mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask .FILS_SHA256; break; case WifiConfiguration.KeyMgmt.FILS_SHA384: mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask .FILS_SHA384; break; case WifiConfiguration.KeyMgmt.WPA2_PSK: // This should never happen default: throw new IllegalArgumentException( "Invalid protoMask bit in keyMgmt: " + bit); } } return mask; } private static int wifiConfigurationToSupplicantProtoMask(BitSet protoMask) { int mask = 0; for (int bit = protoMask.nextSetBit(0); bit != -1; bit = protoMask.nextSetBit(bit + 1)) { switch (bit) { case WifiConfiguration.Protocol.WPA: mask |= ISupplicantStaNetwork.ProtoMask.WPA; break; case WifiConfiguration.Protocol.RSN: mask |= ISupplicantStaNetwork.ProtoMask.RSN; break; case WifiConfiguration.Protocol.OSEN: mask |= ISupplicantStaNetwork.ProtoMask.OSEN; break; case WifiConfiguration.Protocol.WAPI: mask |= android.hardware.wifi.supplicant.V1_3 .ISupplicantStaNetwork.ProtoMask.WAPI; break; default: throw new IllegalArgumentException( "Invalid protoMask bit in wificonfig: " + bit); } } return mask; } private static int wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask) { int mask = 0; for (int bit = authAlgMask.nextSetBit(0); bit != -1; bit = authAlgMask.nextSetBit(bit + 1)) { switch (bit) { case WifiConfiguration.AuthAlgorithm.OPEN: mask |= ISupplicantStaNetwork.AuthAlgMask.OPEN; break; case WifiConfiguration.AuthAlgorithm.SHARED: mask |= ISupplicantStaNetwork.AuthAlgMask.SHARED; break; case WifiConfiguration.AuthAlgorithm.LEAP: mask |= ISupplicantStaNetwork.AuthAlgMask.LEAP; break; case WifiConfiguration.AuthAlgorithm.SAE: mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.AuthAlgMask .SAE; break; default: throw new IllegalArgumentException( "Invalid authAlgMask bit in wificonfig: " + bit); } } return mask; } private int wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask) { int mask = 0; for (int bit = groupCipherMask.nextSetBit(0); bit != -1; bit = groupCipherMask.nextSetBit(bit + 1)) { switch (bit) { case WifiConfiguration.GroupCipher.WEP40: mask |= ISupplicantStaNetwork.GroupCipherMask.WEP40; break; case WifiConfiguration.GroupCipher.WEP104: mask |= ISupplicantStaNetwork.GroupCipherMask.WEP104; break; case WifiConfiguration.GroupCipher.TKIP: mask |= ISupplicantStaNetwork.GroupCipherMask.TKIP; break; case WifiConfiguration.GroupCipher.CCMP: mask |= ISupplicantStaNetwork.GroupCipherMask.CCMP; break; case WifiConfiguration.GroupCipher.GTK_NOT_USED: mask |= ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED; break; case WifiConfiguration.GroupCipher.GCMP_256: if (null == getV1_2StaNetwork()) { Log.d(TAG, "Ignore GCMP_256 cipher for the HAL older than 1.2."); break; } if (0 == (mAdvanceKeyMgmtFeatures & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) { Log.d(TAG, "Ignore unsupporting GCMP_256 cipher."); break; } mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .GroupCipherMask.GCMP_256; break; case WifiConfiguration.GroupCipher.SMS4: if (null != getV1_3StaNetwork()) { mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork .GroupCipherMask.SMS4; } else { Log.d(TAG, "Ignore SMS4 cipher for the HAL older than 1.3."); } break; case WifiConfiguration.GroupCipher.GCMP_128: if (null != getV1_4StaNetwork()) { mask |= android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork .GroupCipherMask.GCMP_128; } else { Log.d(TAG, "Ignore GCMP_128 cipher for the HAL older than 1.4."); } break; default: throw new IllegalArgumentException( "Invalid GroupCipherMask bit in wificonfig: " + bit); } } return mask; } private static int wifiConfigurationToSupplicantGroupMgmtCipherMask(BitSet groupMgmtCipherMask) { int mask = 0; for (int bit = groupMgmtCipherMask.nextSetBit(0); bit != -1; bit = groupMgmtCipherMask.nextSetBit(bit + 1)) { switch (bit) { case WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256: mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .GroupMgmtCipherMask.BIP_CMAC_256; break; case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128: mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .GroupMgmtCipherMask.BIP_GMAC_128; break; case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256: mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .GroupMgmtCipherMask.BIP_GMAC_256; break; default: throw new IllegalArgumentException( "Invalid GroupMgmtCipherMask bit in wificonfig: " + bit); } } return mask; } private int wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask) { int mask = 0; for (int bit = pairwiseCipherMask.nextSetBit(0); bit != -1; bit = pairwiseCipherMask.nextSetBit(bit + 1)) { switch (bit) { case WifiConfiguration.PairwiseCipher.NONE: mask |= ISupplicantStaNetwork.PairwiseCipherMask.NONE; break; case WifiConfiguration.PairwiseCipher.TKIP: mask |= ISupplicantStaNetwork.PairwiseCipherMask.TKIP; break; case WifiConfiguration.PairwiseCipher.CCMP: mask |= ISupplicantStaNetwork.PairwiseCipherMask.CCMP; break; case WifiConfiguration.PairwiseCipher.GCMP_256: if (null == getV1_2StaNetwork()) { Log.d(TAG, "Ignore GCMP_256 cipher for the HAL older than 1.2."); break; } if (0 == (mAdvanceKeyMgmtFeatures & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) { Log.d(TAG, "Ignore unsupporting GCMP_256 cipher."); break; } mask |= android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .PairwiseCipherMask.GCMP_256; break; case WifiConfiguration.PairwiseCipher.SMS4: if (null != getV1_3StaNetwork()) { mask |= android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork .PairwiseCipherMask.SMS4; } else { Log.d(TAG, "Ignore SMS4 cipher for the HAL older than 1.3."); } break; case WifiConfiguration.PairwiseCipher.GCMP_128: if (null != getV1_4StaNetwork()) { mask |= android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork .PairwiseCipherMask.GCMP_128; } else { Log.d(TAG, "Ignore GCMP_128 cipher for the HAL older than 1.4."); } break; default: throw new IllegalArgumentException( "Invalid pairwiseCipherMask bit in wificonfig: " + bit); } } return mask; } private static int supplicantToWifiConfigurationEapMethod(int value) { switch (value) { case ISupplicantStaNetwork.EapMethod.PEAP: return WifiEnterpriseConfig.Eap.PEAP; case ISupplicantStaNetwork.EapMethod.TLS: return WifiEnterpriseConfig.Eap.TLS; case ISupplicantStaNetwork.EapMethod.TTLS: return WifiEnterpriseConfig.Eap.TTLS; case ISupplicantStaNetwork.EapMethod.PWD: return WifiEnterpriseConfig.Eap.PWD; case ISupplicantStaNetwork.EapMethod.SIM: return WifiEnterpriseConfig.Eap.SIM; case ISupplicantStaNetwork.EapMethod.AKA: return WifiEnterpriseConfig.Eap.AKA; case ISupplicantStaNetwork.EapMethod.AKA_PRIME: return WifiEnterpriseConfig.Eap.AKA_PRIME; case ISupplicantStaNetwork.EapMethod.WFA_UNAUTH_TLS: return WifiEnterpriseConfig.Eap.UNAUTH_TLS; // WifiEnterpriseConfig.Eap.NONE: default: Log.e(TAG, "invalid eap method value from supplicant: " + value); return -1; } } private static int supplicantToWifiConfigurationEapPhase2Method(int value) { switch (value) { case ISupplicantStaNetwork.EapPhase2Method.NONE: return WifiEnterpriseConfig.Phase2.NONE; case ISupplicantStaNetwork.EapPhase2Method.PAP: return WifiEnterpriseConfig.Phase2.PAP; case ISupplicantStaNetwork.EapPhase2Method.MSPAP: return WifiEnterpriseConfig.Phase2.MSCHAP; case ISupplicantStaNetwork.EapPhase2Method.MSPAPV2: return WifiEnterpriseConfig.Phase2.MSCHAPV2; case ISupplicantStaNetwork.EapPhase2Method.GTC: return WifiEnterpriseConfig.Phase2.GTC; case ISupplicantStaNetwork.EapPhase2Method.SIM: return WifiEnterpriseConfig.Phase2.SIM; case ISupplicantStaNetwork.EapPhase2Method.AKA: return WifiEnterpriseConfig.Phase2.AKA; case ISupplicantStaNetwork.EapPhase2Method.AKA_PRIME: return WifiEnterpriseConfig.Phase2.AKA_PRIME; default: Log.e(TAG, "invalid eap phase2 method value from supplicant: " + value); return -1; } } private static int supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask, int supplicantValue, BitSet bitset, int bitSetPosition) { bitset.set(bitSetPosition, (supplicantMask & supplicantValue) == supplicantValue); int modifiedSupplicantMask = supplicantMask & ~supplicantValue; return modifiedSupplicantMask; } private static BitSet supplicantToWifiConfigurationKeyMgmtMask(int mask) { BitSet bitset = new BitSet(); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.KeyMgmtMask.NONE, bitset, WifiConfiguration.KeyMgmt.NONE); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.KeyMgmtMask.WPA_PSK, bitset, WifiConfiguration.KeyMgmt.WPA_PSK); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.KeyMgmtMask.WPA_EAP, bitset, WifiConfiguration.KeyMgmt.WPA_EAP); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.KeyMgmtMask.IEEE8021X, bitset, WifiConfiguration.KeyMgmt.IEEE8021X); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.KeyMgmtMask.OSEN, bitset, WifiConfiguration.KeyMgmt.OSEN); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.KeyMgmtMask.FT_PSK, bitset, WifiConfiguration.KeyMgmt.FT_PSK); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.KeyMgmtMask.FT_EAP, bitset, WifiConfiguration.KeyMgmt.FT_EAP); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask.SAE, bitset, WifiConfiguration.KeyMgmt.SAE); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask.OWE, bitset, WifiConfiguration.KeyMgmt.OWE); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask .SUITE_B_192, bitset, WifiConfiguration.KeyMgmt.SUITE_B_192); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask .WPA_PSK_SHA256, bitset, WifiConfiguration.KeyMgmt.WPA_PSK_SHA256); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.KeyMgmtMask .WPA_EAP_SHA256, bitset, WifiConfiguration.KeyMgmt.WPA_EAP_SHA256); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask .WAPI_PSK, bitset, WifiConfiguration.KeyMgmt.WAPI_PSK); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask .WAPI_CERT, bitset, WifiConfiguration.KeyMgmt.WAPI_CERT); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask .FILS_SHA256, bitset, WifiConfiguration.KeyMgmt.FILS_SHA256); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.KeyMgmtMask .FILS_SHA384, bitset, WifiConfiguration.KeyMgmt.FILS_SHA384); if (mask != 0) { throw new IllegalArgumentException( "invalid key mgmt mask from supplicant: " + mask); } return bitset; } private static BitSet supplicantToWifiConfigurationProtoMask(int mask) { BitSet bitset = new BitSet(); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.ProtoMask.WPA, bitset, WifiConfiguration.Protocol.WPA); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.ProtoMask.RSN, bitset, WifiConfiguration.Protocol.RSN); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.ProtoMask.OSEN, bitset, WifiConfiguration.Protocol.OSEN); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.ProtoMask.WAPI, bitset, WifiConfiguration.Protocol.WAPI); if (mask != 0) { throw new IllegalArgumentException( "invalid proto mask from supplicant: " + mask); } return bitset; } private static BitSet supplicantToWifiConfigurationAuthAlgMask(int mask) { BitSet bitset = new BitSet(); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.AuthAlgMask.OPEN, bitset, WifiConfiguration.AuthAlgorithm.OPEN); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.AuthAlgMask.SHARED, bitset, WifiConfiguration.AuthAlgorithm.SHARED); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.AuthAlgMask.LEAP, bitset, WifiConfiguration.AuthAlgorithm.LEAP); mask = supplicantMaskValueToWifiConfigurationBitSet(mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.AuthAlgMask .SAE, bitset, WifiConfiguration.AuthAlgorithm.SAE); if (mask != 0) { throw new IllegalArgumentException( "invalid auth alg mask from supplicant: " + mask); } return bitset; } private static BitSet supplicantToWifiConfigurationGroupCipherMask(int mask) { BitSet bitset = new BitSet(); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.GroupCipherMask.WEP40, bitset, WifiConfiguration.GroupCipher.WEP40); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.GroupCipherMask.WEP104, bitset, WifiConfiguration.GroupCipher.WEP104); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.GroupCipherMask.TKIP, bitset, WifiConfiguration.GroupCipher.TKIP); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.GroupCipherMask.CCMP, bitset, WifiConfiguration.GroupCipher.CCMP); mask = supplicantMaskValueToWifiConfigurationBitSet(mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .GroupCipherMask.GCMP_256, bitset, WifiConfiguration.GroupCipher.GCMP_256); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED, bitset, WifiConfiguration.GroupCipher.GTK_NOT_USED); mask = supplicantMaskValueToWifiConfigurationBitSet(mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.GroupCipherMask .SMS4, bitset, WifiConfiguration.GroupCipher.SMS4); mask = supplicantMaskValueToWifiConfigurationBitSet(mask, android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork.GroupCipherMask .GCMP_128, bitset, WifiConfiguration.GroupCipher.GCMP_128); if (mask != 0) { throw new IllegalArgumentException( "invalid group cipher mask from supplicant: " + mask); } return bitset; } private static BitSet supplicantToWifiConfigurationGroupMgmtCipherMask(int mask) { BitSet bitset = new BitSet(); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .GroupMgmtCipherMask.BIP_GMAC_128, bitset, WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .GroupMgmtCipherMask.BIP_GMAC_256, bitset, WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork .GroupMgmtCipherMask.BIP_CMAC_256, bitset, WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256); if (mask != 0) { throw new IllegalArgumentException( "invalid group mgmt cipher mask from supplicant: " + mask); } return bitset; } private static BitSet supplicantToWifiConfigurationPairwiseCipherMask(int mask) { BitSet bitset = new BitSet(); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.PairwiseCipherMask.NONE, bitset, WifiConfiguration.PairwiseCipher.NONE); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.PairwiseCipherMask.TKIP, bitset, WifiConfiguration.PairwiseCipher.TKIP); mask = supplicantMaskValueToWifiConfigurationBitSet( mask, ISupplicantStaNetwork.PairwiseCipherMask.CCMP, bitset, WifiConfiguration.PairwiseCipher.CCMP); mask = supplicantMaskValueToWifiConfigurationBitSet(mask, android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.PairwiseCipherMask .GCMP_256, bitset, WifiConfiguration.PairwiseCipher.GCMP_256); mask = supplicantMaskValueToWifiConfigurationBitSet(mask, android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.PairwiseCipherMask .SMS4, bitset, WifiConfiguration.PairwiseCipher.SMS4); mask = supplicantMaskValueToWifiConfigurationBitSet(mask, android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork.PairwiseCipherMask .GCMP_128, bitset, WifiConfiguration.PairwiseCipher.GCMP_128); if (mask != 0) { throw new IllegalArgumentException( "invalid pairwise cipher mask from supplicant: " + mask); } return bitset; } private static int wifiConfigurationToSupplicantEapMethod(int value) { switch (value) { case WifiEnterpriseConfig.Eap.PEAP: return ISupplicantStaNetwork.EapMethod.PEAP; case WifiEnterpriseConfig.Eap.TLS: return ISupplicantStaNetwork.EapMethod.TLS; case WifiEnterpriseConfig.Eap.TTLS: return ISupplicantStaNetwork.EapMethod.TTLS; case WifiEnterpriseConfig.Eap.PWD: return ISupplicantStaNetwork.EapMethod.PWD; case WifiEnterpriseConfig.Eap.SIM: return ISupplicantStaNetwork.EapMethod.SIM; case WifiEnterpriseConfig.Eap.AKA: return ISupplicantStaNetwork.EapMethod.AKA; case WifiEnterpriseConfig.Eap.AKA_PRIME: return ISupplicantStaNetwork.EapMethod.AKA_PRIME; case WifiEnterpriseConfig.Eap.UNAUTH_TLS: return ISupplicantStaNetwork.EapMethod.WFA_UNAUTH_TLS; // WifiEnterpriseConfig.Eap.NONE: default: Log.e(TAG, "invalid eap method value from WifiConfiguration: " + value); return -1; } } private static int wifiConfigurationToSupplicantEapPhase2Method(int value) { switch (value) { case WifiEnterpriseConfig.Phase2.NONE: return ISupplicantStaNetwork.EapPhase2Method.NONE; case WifiEnterpriseConfig.Phase2.PAP: return ISupplicantStaNetwork.EapPhase2Method.PAP; case WifiEnterpriseConfig.Phase2.MSCHAP: return ISupplicantStaNetwork.EapPhase2Method.MSPAP; case WifiEnterpriseConfig.Phase2.MSCHAPV2: return ISupplicantStaNetwork.EapPhase2Method.MSPAPV2; case WifiEnterpriseConfig.Phase2.GTC: return ISupplicantStaNetwork.EapPhase2Method.GTC; case WifiEnterpriseConfig.Phase2.SIM: return ISupplicantStaNetwork.EapPhase2Method.SIM; case WifiEnterpriseConfig.Phase2.AKA: return ISupplicantStaNetwork.EapPhase2Method.AKA; case WifiEnterpriseConfig.Phase2.AKA_PRIME: return ISupplicantStaNetwork.EapPhase2Method.AKA_PRIME; default: Log.e(TAG, "invalid eap phase2 method value from WifiConfiguration: " + value); return -1; } } /** See ISupplicantNetwork.hal for documentation */ private boolean getId() { synchronized (mLock) { final String methodStr = "getId"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getId((SupplicantStatus status, int idValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mNetworkId = idValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** get current network id */ public int getNetworkId() { if (!getId()) { return -1; } return mNetworkId; } /** See ISupplicantStaNetwork.hal for documentation */ private boolean registerCallback(ISupplicantStaNetworkCallback callback) { synchronized (mLock) { final String methodStr = "registerCallback"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.registerCallback(callback); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean registerCallback_1_4( android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetworkCallback callback) { synchronized (mLock) { final String methodStr = "registerCallback_1_4"; android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork iSupplicantStaNetworkV14 = getV1_4StaNetwork(); if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; if (iSupplicantStaNetworkV14 == null) return false; try { android.hardware.wifi.supplicant.V1_4.SupplicantStatus status = iSupplicantStaNetworkV14.registerCallback_1_4(callback); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setSsid(java.util.ArrayList ssid) { synchronized (mLock) { final String methodStr = "setSsid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setSsid(ssid); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** * Set the BSSID for this network. * * @param bssidStr MAC address in "XX:XX:XX:XX:XX:XX" form or "any" to reset the mac address. * @return true if it succeeds, false otherwise. */ public boolean setBssid(String bssidStr) { synchronized (mLock) { try { return setBssid(NativeUtil.macAddressToByteArray(bssidStr)); } catch (IllegalArgumentException e) { Log.e(TAG, "Illegal argument " + bssidStr, e); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setBssid(byte[/* 6 */] bssid) { synchronized (mLock) { final String methodStr = "setBssid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setBssid(bssid); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setScanSsid(boolean enable) { synchronized (mLock) { final String methodStr = "setScanSsid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setScanSsid(enable); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setKeyMgmt(int keyMgmtMask) { synchronized (mLock) { final String methodStr = "setKeyMgmt"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status; android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12 = getV1_2StaNetwork(); android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null != iSupplicantStaNetworkV13) { /* Support for new key management types: * WAPI_PSK, WAPI_CERT * Requires HAL v1.3 or higher */ status = iSupplicantStaNetworkV13.setKeyMgmt_1_3(keyMgmtMask); } else if (iSupplicantStaNetworkV12 != null) { /* Support for new key management types; * SAE, OWE, WPA_PSK_SHA256, WPA_EAP_SHA256 * Requires HAL v1.2 or higher */ status = iSupplicantStaNetworkV12.setKeyMgmt_1_2(keyMgmtMask); } else { status = mISupplicantStaNetwork.setKeyMgmt(keyMgmtMask); } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setProto(int protoMask) { synchronized (mLock) { final String methodStr = "setProto"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); SupplicantStatus status; if (null != iSupplicantStaNetworkV13) { /* Support for new proto types: WAPI * Requires HAL v1.3 or higher */ status = iSupplicantStaNetworkV13.setProto_1_3(protoMask); } else { status = mISupplicantStaNetwork.setProto(protoMask); } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setAuthAlg(int authAlgMask) { synchronized (mLock) { final String methodStr = "setAuthAlg"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); SupplicantStatus status; if (null != iSupplicantStaNetworkV13) { /* Support for SAE Authentication algorithm requires HAL v1.3 or higher */ status = iSupplicantStaNetworkV13.setAuthAlg_1_3(authAlgMask); } else { status = mISupplicantStaNetwork.setAuthAlg(authAlgMask); } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setGroupCipher_1_4(int groupCipherMask) { synchronized (mLock) { final String methodStr = "setGroupCipher_1_4"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork iSupplicantStaNetworkV14 = getV1_4StaNetwork(); if (null == iSupplicantStaNetworkV14) return false; try { return checkStatusAndLogFailure( iSupplicantStaNetworkV14.setGroupCipher_1_4(groupCipherMask), methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setGroupCipher(int groupCipherMask) { synchronized (mLock) { final String methodStr = "setGroupCipher"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status; android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12 = getV1_2StaNetwork(); android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null != getV1_4StaNetwork()) { /* Support for new key group cipher types for GCMP_128 * Requires HAL v1.4 or higher */ return setGroupCipher_1_4(groupCipherMask); } else if (null != iSupplicantStaNetworkV13) { /* Support for new key group cipher types for SMS4 * Requires HAL v1.3 or higher */ status = iSupplicantStaNetworkV13.setGroupCipher_1_3(groupCipherMask); } else if (iSupplicantStaNetworkV12 != null) { /* Support for new key group cipher types for SuiteB * Requires HAL v1.2 or higher */ status = iSupplicantStaNetworkV12.setGroupCipher_1_2(groupCipherMask); } else { status = mISupplicantStaNetwork.setGroupCipher( groupCipherMask); } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean enableTlsSuiteBEapPhase1Param(boolean enable) { synchronized (mLock) { final String methodStr = "setEapPhase1Params"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12; iSupplicantStaNetworkV12 = getV1_2StaNetwork(); if (iSupplicantStaNetworkV12 != null) { /* Support for for SuiteB * Requires HAL v1.2 or higher */ SupplicantStatus status = iSupplicantStaNetworkV12 .enableTlsSuiteBEapPhase1Param(enable); return checkStatusAndLogFailure(status, methodStr); } else { Log.e(TAG, "Supplicant HAL version does not support " + methodStr); return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean enableSuiteBEapOpenSslCiphers() { synchronized (mLock) { final String methodStr = "setEapOpenSslCiphers"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12; iSupplicantStaNetworkV12 = getV1_2StaNetwork(); if (iSupplicantStaNetworkV12 != null) { /* Support for for SuiteB * Requires HAL v1.2 or higher */ SupplicantStatus status = iSupplicantStaNetworkV12 .enableSuiteBEapOpenSslCiphers(); return checkStatusAndLogFailure(status, methodStr); } else { Log.e(TAG, "Supplicant HAL version does not support " + methodStr); return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setPairwiseCipher_1_4(int pairwiseCipherMask) { synchronized (mLock) { final String methodStr = "setPairwiseCipher_1_4"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork iSupplicantStaNetworkV14 = getV1_4StaNetwork(); if (null == iSupplicantStaNetworkV14) return false; try { return checkStatusAndLogFailure( iSupplicantStaNetworkV14.setPairwiseCipher_1_4(pairwiseCipherMask), methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setPairwiseCipher(int pairwiseCipherMask) { synchronized (mLock) { final String methodStr = "setPairwiseCipher"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status; android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12 = getV1_2StaNetwork(); android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null != getV1_4StaNetwork()) { /* Support for new key pairwise cipher types for GCMP_128 * Requires HAL v1.4 or higher */ return setPairwiseCipher_1_4(pairwiseCipherMask); } else if (null != iSupplicantStaNetworkV13) { /* Support for new key pairwise cipher types for SMS4 * Requires HAL v1.3 or higher */ status = iSupplicantStaNetworkV13.setPairwiseCipher_1_3(pairwiseCipherMask); } else if (iSupplicantStaNetworkV12 != null) { /* Support for new key pairwise cipher types for SuiteB * Requires HAL v1.2 or higher */ status = iSupplicantStaNetworkV12.setPairwiseCipher_1_2(pairwiseCipherMask); } else { status = mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask); } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setGroupMgmtCipher(int groupMgmtCipherMask) { synchronized (mLock) { final String methodStr = "setGroupMgmtCipher"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12; iSupplicantStaNetworkV12 = getV1_2StaNetwork(); if (iSupplicantStaNetworkV12 != null) { /* Support for new key pairwise cipher types for SuiteB * Requires HAL v1.2 or higher */ SupplicantStatus status = iSupplicantStaNetworkV12 .setGroupMgmtCipher(groupMgmtCipherMask); return checkStatusAndLogFailure(status, methodStr); } else { return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setPskPassphrase(String psk) { synchronized (mLock) { final String methodStr = "setPskPassphrase"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setPskPassphrase(psk); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setPsk(byte[] psk) { synchronized (mLock) { final String methodStr = "setPsk"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setPsk(psk); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } catch (ArrayIndexOutOfBoundsException e) { Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + e); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setWepKey(int keyIdx, java.util.ArrayList wepKey) { synchronized (mLock) { final String methodStr = "setWepKey"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setWepKey(keyIdx, wepKey); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setWepTxKeyIdx(int keyIdx) { synchronized (mLock) { final String methodStr = "setWepTxKeyIdx"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setWepTxKeyIdx(keyIdx); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setRequirePmf(boolean enable) { synchronized (mLock) { final String methodStr = "setRequirePmf"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setRequirePmf(enable); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setUpdateIdentifier(int identifier) { synchronized (mLock) { final String methodStr = "setUpdateIdentifier"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setUpdateIdentifier(identifier); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setWapiCertSuite(String certSuite) { synchronized (mLock) { final String methodStr = "setWapiCertSuite"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null != iSupplicantStaNetworkV13) { /* Requires HAL v1.3 or higher */ SupplicantStatus status = iSupplicantStaNetworkV13.setWapiCertSuite(certSuite); return checkStatusAndLogFailure(status, methodStr); } else { Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3"); return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapMethod(int method) { synchronized (mLock) { final String methodStr = "setEapMethod"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapMethod(method); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapPhase2Method(int method) { synchronized (mLock) { final String methodStr = "setEapPhase2Method"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapPhase2Method(method); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapIdentity(java.util.ArrayList identity) { synchronized (mLock) { final String methodStr = "setEapIdentity"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapIdentity(identity); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapAnonymousIdentity(java.util.ArrayList identity) { synchronized (mLock) { final String methodStr = "setEapAnonymousIdentity"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapAnonymousIdentity(identity); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapPassword(java.util.ArrayList password) { synchronized (mLock) { final String methodStr = "setEapPassword"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapPassword(password); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapCACert(String path) { synchronized (mLock) { final String methodStr = "setEapCACert"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapCACert(path); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapCAPath(String path) { synchronized (mLock) { final String methodStr = "setEapCAPath"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapCAPath(path); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapClientCert(String path) { synchronized (mLock) { final String methodStr = "setEapClientCert"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapClientCert(path); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapPrivateKeyId(String id) { synchronized (mLock) { final String methodStr = "setEapPrivateKeyId"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapPrivateKeyId(id); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapSubjectMatch(String match) { synchronized (mLock) { final String methodStr = "setEapSubjectMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapSubjectMatch(match); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapAltSubjectMatch(String match) { synchronized (mLock) { final String methodStr = "setEapAltSubjectMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapAltSubjectMatch(match); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapEngine(boolean enable) { synchronized (mLock) { final String methodStr = "setEapEngine"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapEngine(enable); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapEngineID(String id) { synchronized (mLock) { final String methodStr = "setEapEngineID"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapEngineID(id); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapDomainSuffixMatch(String match) { synchronized (mLock) { final String methodStr = "setEapDomainSuffixMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setEapDomainSuffixMatch(match); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapProactiveKeyCaching(boolean enable) { synchronized (mLock) { final String methodStr = "setEapProactiveKeyCaching"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setProactiveKeyCaching(enable); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setIdStr(String idString) { synchronized (mLock) { final String methodStr = "setIdStr"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.setIdStr(idString); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setSaePassword(String saePassword) { synchronized (mLock) { final String methodStr = "setSaePassword"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12; iSupplicantStaNetworkV12 = getV1_2StaNetwork(); if (iSupplicantStaNetworkV12 != null) { /* Support for SAE Requires HAL v1.2 or higher */ SupplicantStatus status = iSupplicantStaNetworkV12.setSaePassword(saePassword); return checkStatusAndLogFailure(status, methodStr); } else { return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setEapErp(boolean enable) { synchronized (mLock) { final String methodStr = "setEapErp"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13; iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (iSupplicantStaNetworkV13 != null) { /* Support for set ERP Requires HAL v1.3 or higher */ SupplicantStatus status = iSupplicantStaNetworkV13.setEapErp(enable); return checkStatusAndLogFailure(status, methodStr); } else { return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getSsid() { synchronized (mLock) { final String methodStr = "getSsid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getSsid((SupplicantStatus status, java.util.ArrayList ssidValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mSsid = ssidValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getBssid() { synchronized (mLock) { final String methodStr = "getBssid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getBssid((SupplicantStatus status, byte[/* 6 */] bssidValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mBssid = bssidValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getScanSsid() { synchronized (mLock) { final String methodStr = "getScanSsid"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getScanSsid((SupplicantStatus status, boolean enabledValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mScanSsid = enabledValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getKeyMgmt() { synchronized (mLock) { final String methodStr = "getKeyMgmt"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; if (getV1_3StaNetwork() != null) { return getKeyMgmt_1_3(); } else { try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getKeyMgmt((SupplicantStatus status, int keyMgmtMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mKeyMgmtMask = keyMgmtMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } } private boolean getKeyMgmt_1_3() { synchronized (mLock) { final String methodStr = "getKeyMgmt_1_3"; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null == iSupplicantStaNetworkV13) return false; Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV13.getKeyMgmt_1_3((SupplicantStatus status, int keyMgmtMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mKeyMgmtMask = keyMgmtMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getProto() { synchronized (mLock) { final String methodStr = "getProto"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; if (getV1_3StaNetwork() != null) { return getProto_1_3(); } else { try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getProto( (SupplicantStatus status, int protoMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mProtoMask = protoMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } } private boolean getProto_1_3() { synchronized (mLock) { final String methodStr = "getProto_1_3"; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null == iSupplicantStaNetworkV13) return false; Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV13.getProto_1_3( (SupplicantStatus status, int protoMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mProtoMask = protoMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getAuthAlg() { synchronized (mLock) { final String methodStr = "getAuthAlg"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; if (getV1_3StaNetwork() != null) { return getAuthAlg_1_3(); } try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getAuthAlg((SupplicantStatus status, int authAlgMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mAuthAlgMask = authAlgMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } private boolean getAuthAlg_1_3() { final String methodStr = "getAuthAlg_1_3"; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null == iSupplicantStaNetworkV13) return false; Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV13.getAuthAlg_1_3((SupplicantStatus status, int authAlgMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mAuthAlgMask = authAlgMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getGroupCipher() { synchronized (mLock) { final String methodStr = "getGroupCipher"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; if (getV1_4StaNetwork() != null) { return getGroupCipher_1_4(); } else if (getV1_3StaNetwork() != null) { return getGroupCipher_1_3(); } else { try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getGroupCipher((SupplicantStatus status, int groupCipherMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mGroupCipherMask = groupCipherMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } } private boolean getGroupCipher_1_3() { synchronized (mLock) { final String methodStr = "getGroupCipher_1_3"; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null == iSupplicantStaNetworkV13) return false; Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV13.getGroupCipher_1_3((SupplicantStatus status, int groupCipherMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mGroupCipherMask = groupCipherMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } private boolean getGroupCipher_1_4() { synchronized (mLock) { final String methodStr = "getGroupCipher_1_4"; try { android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork iSupplicantStaNetworkV14 = getV1_4StaNetwork(); if (null == iSupplicantStaNetworkV14) return false; Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV14.getGroupCipher_1_4(( android.hardware.wifi.supplicant.V1_4.SupplicantStatus status, int groupCipherMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mGroupCipherMask = groupCipherMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getPairwiseCipher() { synchronized (mLock) { final String methodStr = "getPairwiseCipher"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; if (getV1_4StaNetwork() != null) { return getPairwiseCipher_1_4(); } else if (getV1_3StaNetwork() != null) { return getPairwiseCipher_1_3(); } else { try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getPairwiseCipher((SupplicantStatus status, int pairwiseCipherMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mPairwiseCipherMask = pairwiseCipherMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } } private boolean getPairwiseCipher_1_3() { synchronized (mLock) { final String methodStr = "getPairwiseCipher_1_3"; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (null == iSupplicantStaNetworkV13) return false; Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV13.getPairwiseCipher_1_3((SupplicantStatus status, int pairwiseCipherMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mPairwiseCipherMask = pairwiseCipherMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } private boolean getPairwiseCipher_1_4() { synchronized (mLock) { final String methodStr = "getPairwiseCipher_1_4"; try { android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork iSupplicantStaNetworkV14 = getV1_4StaNetwork(); if (null == iSupplicantStaNetworkV14) return false; Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV14.getPairwiseCipher_1_4(( android.hardware.wifi.supplicant.V1_4.SupplicantStatus status, int pairwiseCipherMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mPairwiseCipherMask = pairwiseCipherMaskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getGroupMgmtCipher() { synchronized (mLock) { final String methodStr = "getGroupMgmtCipher"; android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { iSupplicantStaNetworkV12 = getV1_2StaNetwork(); if (iSupplicantStaNetworkV12 != null) { Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV12.getGroupMgmtCipher((SupplicantStatus status, int groupMgmtCipherMaskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mGroupMgmtCipherMask = groupMgmtCipherMaskValue; } checkStatusAndLogFailure(status, methodStr); }); return statusOk.value; } else { return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getPskPassphrase() { synchronized (mLock) { final String methodStr = "getPskPassphrase"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getPskPassphrase((SupplicantStatus status, String pskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mPskPassphrase = pskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getSaePassword() { synchronized (mLock) { final String methodStr = "getSaePassword"; android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { iSupplicantStaNetworkV12 = getV1_2StaNetwork(); if (iSupplicantStaNetworkV12 != null) { Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV12.getSaePassword((SupplicantStatus status, String saePassword) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mSaePassword = saePassword; } checkStatusAndLogFailure(status, methodStr); }); return statusOk.value; } else { return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getPsk() { synchronized (mLock) { final String methodStr = "getPsk"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getPsk((SupplicantStatus status, byte[] pskValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mPsk = pskValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getWepKey(int keyIdx) { synchronized (mLock) { final String methodStr = "keyIdx"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getWepKey(keyIdx, (SupplicantStatus status, java.util.ArrayList wepKeyValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mWepKey = wepKeyValue; } else { Log.e(TAG, methodStr + ", failed: " + status.debugMessage); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getWepTxKeyIdx() { synchronized (mLock) { final String methodStr = "getWepTxKeyIdx"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getWepTxKeyIdx((SupplicantStatus status, int keyIdxValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mWepTxKeyIdx = keyIdxValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getRequirePmf() { synchronized (mLock) { final String methodStr = "getRequirePmf"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getRequirePmf((SupplicantStatus status, boolean enabledValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mRequirePmf = enabledValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getWapiCertSuite() { synchronized (mLock) { final String methodStr = "getWapiCertSuite"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13; iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (iSupplicantStaNetworkV13 != null) { Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV13.getWapiCertSuite((SupplicantStatus status, String suiteValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { mWapiCertSuite = suiteValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } else { Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3"); return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapMethod() { synchronized (mLock) { final String methodStr = "getEapMethod"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapMethod((SupplicantStatus status, int methodValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapMethod = methodValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapPhase2Method() { synchronized (mLock) { final String methodStr = "getEapPhase2Method"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapPhase2Method((SupplicantStatus status, int methodValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapPhase2Method = methodValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapIdentity() { synchronized (mLock) { final String methodStr = "getEapIdentity"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapIdentity((SupplicantStatus status, ArrayList identityValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapIdentity = identityValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapAnonymousIdentity() { synchronized (mLock) { final String methodStr = "getEapAnonymousIdentity"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapAnonymousIdentity((SupplicantStatus status, ArrayList identityValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapAnonymousIdentity = identityValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** * A wrapping method for getEapAnonymousIdentity(). * This get anonymous identity from supplicant and returns it as a string. * * @return anonymous identity string if succeeds, null otherwise. */ public String fetchEapAnonymousIdentity() { synchronized (mLock) { if (!getEapAnonymousIdentity()) { return null; } return NativeUtil.stringFromByteArrayList(mEapAnonymousIdentity); } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapPassword() { synchronized (mLock) { final String methodStr = "getEapPassword"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapPassword((SupplicantStatus status, ArrayList passwordValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapPassword = passwordValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapCACert() { synchronized (mLock) { final String methodStr = "getEapCACert"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapCACert((SupplicantStatus status, String pathValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapCACert = pathValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapCAPath() { synchronized (mLock) { final String methodStr = "getEapCAPath"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapCAPath((SupplicantStatus status, String pathValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapCAPath = pathValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapClientCert() { synchronized (mLock) { final String methodStr = "getEapClientCert"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapClientCert((SupplicantStatus status, String pathValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapClientCert = pathValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapPrivateKeyId() { synchronized (mLock) { final String methodStr = "getEapPrivateKeyId"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapPrivateKeyId((SupplicantStatus status, String idValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapPrivateKeyId = idValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapSubjectMatch() { synchronized (mLock) { final String methodStr = "getEapSubjectMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapSubjectMatch((SupplicantStatus status, String matchValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapSubjectMatch = matchValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapAltSubjectMatch() { synchronized (mLock) { final String methodStr = "getEapAltSubjectMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapAltSubjectMatch((SupplicantStatus status, String matchValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapAltSubjectMatch = matchValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapEngine() { synchronized (mLock) { final String methodStr = "getEapEngine"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapEngine((SupplicantStatus status, boolean enabledValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapEngine = enabledValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapEngineID() { synchronized (mLock) { final String methodStr = "getEapEngineID"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapEngineID((SupplicantStatus status, String idValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapEngineID = idValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getEapDomainSuffixMatch() { synchronized (mLock) { final String methodStr = "getEapDomainSuffixMatch"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getEapDomainSuffixMatch((SupplicantStatus status, String matchValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mEapDomainSuffixMatch = matchValue; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getIdStr() { synchronized (mLock) { final String methodStr = "getIdStr"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { Mutable statusOk = new Mutable<>(false); mISupplicantStaNetwork.getIdStr((SupplicantStatus status, String idString) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { this.mIdStr = idString; } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ public boolean enable(boolean noConnect) { synchronized (mLock) { final String methodStr = "enable"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.enable(noConnect); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ public boolean disable() { synchronized (mLock) { final String methodStr = "disable"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.disable(); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** * Trigger a connection to this network. * * @return true if it succeeds, false otherwise. */ public boolean select() { synchronized (mLock) { final String methodStr = "select"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.select(); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** * Send GSM auth response. * * @param paramsStr Response params as a string. * @return true if succeeds, false otherwise. */ public boolean sendNetworkEapSimGsmAuthResponse(String paramsStr) { synchronized (mLock) { try { Matcher match = GSM_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr); ArrayList params = new ArrayList<>(); while (match.find()) { if (match.groupCount() != 2) { Log.e(TAG, "Malformed gsm auth response params: " + paramsStr); return false; } ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams param = new ISupplicantStaNetwork.NetworkResponseEapSimGsmAuthParams(); byte[] kc = NativeUtil.hexStringToByteArray(match.group(1)); if (kc == null || kc.length != param.kc.length) { Log.e(TAG, "Invalid kc value: " + match.group(1)); return false; } byte[] sres = NativeUtil.hexStringToByteArray(match.group(2)); if (sres == null || sres.length != param.sres.length) { Log.e(TAG, "Invalid sres value: " + match.group(2)); return false; } System.arraycopy(kc, 0, param.kc, 0, param.kc.length); System.arraycopy(sres, 0, param.sres, 0, param.sres.length); params.add(param); } // The number of kc/sres pairs can either be 2 or 3 depending on the request. if (params.size() > 3 || params.size() < 2) { Log.e(TAG, "Malformed gsm auth response params: " + paramsStr); return false; } return sendNetworkEapSimGsmAuthResponse(params); } catch (IllegalArgumentException e) { Log.e(TAG, "Illegal argument " + paramsStr, e); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean sendNetworkEapSimGsmAuthResponse( ArrayList params) { synchronized (mLock) { final String methodStr = "sendNetworkEapSimGsmAuthResponse"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimGsmAuthResponse(params); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ public boolean sendNetworkEapSimGsmAuthFailure() { synchronized (mLock) { final String methodStr = "sendNetworkEapSimGsmAuthFailure"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimGsmAuthFailure(); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** * Send UMTS auth response. * * @param paramsStr Response params as a string. * @return true if succeeds, false otherwise. */ public boolean sendNetworkEapSimUmtsAuthResponse(String paramsStr) { synchronized (mLock) { try { Matcher match = UMTS_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr); if (!match.find() || match.groupCount() != 3) { Log.e(TAG, "Malformed umts auth response params: " + paramsStr); return false; } ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params = new ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams(); byte[] ik = NativeUtil.hexStringToByteArray(match.group(1)); if (ik == null || ik.length != params.ik.length) { Log.e(TAG, "Invalid ik value: " + match.group(1)); return false; } byte[] ck = NativeUtil.hexStringToByteArray(match.group(2)); if (ck == null || ck.length != params.ck.length) { Log.e(TAG, "Invalid ck value: " + match.group(2)); return false; } byte[] res = NativeUtil.hexStringToByteArray(match.group(3)); if (res == null || res.length == 0) { Log.e(TAG, "Invalid res value: " + match.group(3)); return false; } System.arraycopy(ik, 0, params.ik, 0, params.ik.length); System.arraycopy(ck, 0, params.ck, 0, params.ck.length); for (byte b : res) { params.res.add(b); } return sendNetworkEapSimUmtsAuthResponse(params); } catch (IllegalArgumentException e) { Log.e(TAG, "Illegal argument " + paramsStr, e); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean sendNetworkEapSimUmtsAuthResponse( ISupplicantStaNetwork.NetworkResponseEapSimUmtsAuthParams params) { synchronized (mLock) { final String methodStr = "sendNetworkEapSimUmtsAuthResponse"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthResponse(params); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** * Send UMTS auts response. * * @param paramsStr Response params as a string. * @return true if succeeds, false otherwise. */ public boolean sendNetworkEapSimUmtsAutsResponse(String paramsStr) { synchronized (mLock) { try { Matcher match = UMTS_AUTS_RESPONSE_PARAMS_PATTERN.matcher(paramsStr); if (!match.find() || match.groupCount() != 1) { Log.e(TAG, "Malformed umts auts response params: " + paramsStr); return false; } byte[] auts = NativeUtil.hexStringToByteArray(match.group(1)); if (auts == null || auts.length != 14) { Log.e(TAG, "Invalid auts value: " + match.group(1)); return false; } return sendNetworkEapSimUmtsAutsResponse(auts); } catch (IllegalArgumentException e) { Log.e(TAG, "Illegal argument " + paramsStr, e); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean sendNetworkEapSimUmtsAutsResponse(byte[/* 14 */] auts) { synchronized (mLock) { final String methodStr = "sendNetworkEapSimUmtsAutsResponse"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimUmtsAutsResponse(auts); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ public boolean sendNetworkEapSimUmtsAuthFailure() { synchronized (mLock) { final String methodStr = "sendNetworkEapSimUmtsAuthFailure"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status = mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthFailure(); return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** * Method to mock out the V1_1 ISupplicantStaNetwork retrieval in unit tests. * * @return 1.1 ISupplicantStaNetwork object if the device is running the 1.1 supplicant hal * service, null otherwise. */ protected android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork getSupplicantStaNetworkForV1_1Mockable() { if (mISupplicantStaNetwork == null) return null; return android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork.castFrom( mISupplicantStaNetwork); } /** * Method to mock out the V1_2 ISupplicantStaNetwork retrieval in unit tests. * * @return 1.2 ISupplicantStaNetwork object if the device is running the 1.2 supplicant hal * service, null otherwise. */ protected android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork getSupplicantStaNetworkForV1_2Mockable() { if (mISupplicantStaNetwork == null) return null; return android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork.castFrom( mISupplicantStaNetwork); } /** * Method to mock out the V1_3 ISupplicantStaNetwork retrieval in unit tests. * * @return 1.3 ISupplicantStaNetwork object if the device is running the 1.3 supplicant hal * service, null otherwise. */ protected android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork getSupplicantStaNetworkForV1_3Mockable() { if (mISupplicantStaNetwork == null) return null; return android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork.castFrom( mISupplicantStaNetwork); } /** * Method to mock out the V1_4 ISupplicantStaNetwork retrieval in unit tests. * * @return 1.4 ISupplicantStaNetwork object if the device is running the 1.4 supplicant hal * service, null otherwise. */ protected android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork getSupplicantStaNetworkForV1_4Mockable() { if (mISupplicantStaNetwork == null) return null; return android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork.castFrom( mISupplicantStaNetwork); } /** * Send eap identity response. * * @param identityStr identity used for EAP-Identity * @param encryptedIdentityStr encrypted identity used for EAP-AKA/EAP-SIM * @return true if succeeds, false otherwise. */ public boolean sendNetworkEapIdentityResponse(String identityStr, String encryptedIdentityStr) { synchronized (mLock) { try { ArrayList unencryptedIdentity = NativeUtil.stringToByteArrayList(identityStr); ArrayList encryptedIdentity = null; if (!TextUtils.isEmpty(encryptedIdentityStr)) { encryptedIdentity = NativeUtil.stringToByteArrayList(encryptedIdentityStr); } return sendNetworkEapIdentityResponse(unencryptedIdentity, encryptedIdentity); } catch (IllegalArgumentException e) { Log.e(TAG, "Illegal argument " + identityStr + "," + encryptedIdentityStr, e); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean sendNetworkEapIdentityResponse(ArrayList unencryptedIdentity, ArrayList encryptedIdentity) { synchronized (mLock) { final String methodStr = "sendNetworkEapIdentityResponse"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { SupplicantStatus status; android.hardware.wifi.supplicant.V1_1.ISupplicantStaNetwork iSupplicantStaNetworkV11 = getSupplicantStaNetworkForV1_1Mockable(); if (iSupplicantStaNetworkV11 != null && encryptedIdentity != null) { status = iSupplicantStaNetworkV11.sendNetworkEapIdentityResponse_1_1( unencryptedIdentity, encryptedIdentity); } else { status = mISupplicantStaNetwork.sendNetworkEapIdentityResponse( unencryptedIdentity); } return checkStatusAndLogFailure(status, methodStr); } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setOcsp(@Ocsp int ocsp) { synchronized (mLock) { final String methodStr = "setOcsp"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; int halOcspValue = android.hardware.wifi.supplicant.V1_3.OcspType.NONE; switch (ocsp) { case WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS: halOcspValue = android.hardware.wifi.supplicant.V1_3 .OcspType.REQUEST_CERT_STATUS; break; case WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS: halOcspValue = android.hardware.wifi.supplicant.V1_3 .OcspType.REQUIRE_CERT_STATUS; break; case WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS: halOcspValue = android.hardware.wifi.supplicant.V1_3 .OcspType.REQUIRE_ALL_CERTS_STATUS; break; } try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13; iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (iSupplicantStaNetworkV13 != null) { /* Support for OCSP Requires HAL v1.3 or higher */ SupplicantStatus status = iSupplicantStaNetworkV13 .setOcsp(halOcspValue); return checkStatusAndLogFailure(status, methodStr); } else { Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3"); return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean getOcsp() { synchronized (mLock) { final String methodStr = "getOcsp"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13; iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (iSupplicantStaNetworkV13 != null) { Mutable statusOk = new Mutable<>(false); iSupplicantStaNetworkV13.getOcsp((SupplicantStatus status, int halOcspValue) -> { statusOk.value = status.code == SupplicantStatusCode.SUCCESS; if (statusOk.value) { mOcsp = WifiEnterpriseConfig.OCSP_NONE; switch (halOcspValue) { case android.hardware.wifi.supplicant.V1_3 .OcspType.REQUEST_CERT_STATUS: mOcsp = WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS; break; case android.hardware.wifi.supplicant.V1_3 .OcspType.REQUIRE_CERT_STATUS: mOcsp = WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS; break; case android.hardware.wifi.supplicant.V1_3 .OcspType.REQUIRE_ALL_CERTS_STATUS: mOcsp = WifiEnterpriseConfig .OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS; break; default: Log.e(TAG, "Invalid HAL OCSP value " + halOcspValue); break; } } else { checkStatusAndLogFailure(status, methodStr); } }); return statusOk.value; } else { Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3"); return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ public boolean setPmkCache(ArrayList serializedEntry) { synchronized (mLock) { final String methodStr = "setPmkCache"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_3.ISupplicantStaNetwork iSupplicantStaNetworkV13; iSupplicantStaNetworkV13 = getV1_3StaNetwork(); if (iSupplicantStaNetworkV13 != null) { SupplicantStatus status = iSupplicantStaNetworkV13 .setPmkCache(serializedEntry); return checkStatusAndLogFailure(status, methodStr); } else { Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.3"); return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** See ISupplicantStaNetwork.hal for documentation */ private boolean setSaeH2eMode(byte mode) { synchronized (mLock) { final String methodStr = "setSaeH2eMode"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false; try { android.hardware.wifi.supplicant.V1_4.ISupplicantStaNetwork iSupplicantStaNetworkV14 = getV1_4StaNetwork(); if (iSupplicantStaNetworkV14 != null) { android.hardware.wifi.supplicant.V1_4.SupplicantStatus status = iSupplicantStaNetworkV14.setSaeH2eMode(mode); return checkStatusAndLogFailure(status, methodStr); } else { Log.e(TAG, "Cannot get ISupplicantStaNetwork V1.4"); return false; } } catch (RemoteException e) { handleRemoteException(e, methodStr); return false; } } } /** * Retrieve the NFC token for this network. * * @return Hex string corresponding to the NFC token or null for failure. */ public String getWpsNfcConfigurationToken() { synchronized (mLock) { ArrayList token = getWpsNfcConfigurationTokenInternal(); if (token == null) { return null; } return NativeUtil.hexStringFromByteArray(NativeUtil.byteArrayFromArrayList(token)); } } /** See ISupplicantStaNetwork.hal for documentation */ private ArrayList getWpsNfcConfigurationTokenInternal() { synchronized (mLock) { final String methodStr = "getWpsNfcConfigurationToken"; if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return null; final Mutable> gotToken = new Mutable<>(); try { mISupplicantStaNetwork.getWpsNfcConfigurationToken( (SupplicantStatus status, ArrayList token) -> { if (checkStatusAndLogFailure(status, methodStr)) { gotToken.value = token; } }); } catch (RemoteException e) { handleRemoteException(e, methodStr); } return gotToken.value; } } private String getTag() { return TAG + "[" + mIfaceName + "]"; } /** * Returns true if provided status code is SUCCESS, logs debug message and returns false * otherwise */ private boolean checkStatusAndLogFailure(SupplicantStatus status, final String methodStr) { synchronized (mLock) { if (status.code != SupplicantStatusCode.SUCCESS) { Log.e(getTag(), "ISupplicantStaNetwork." + methodStr + " failed: " + status); return false; } else { if (mVerboseLoggingEnabled) { Log.d(getTag(), "ISupplicantStaNetwork." + methodStr + " succeeded"); } return true; } } } /** * Returns true if provided status code is SUCCESS, logs debug message and returns false * otherwise */ private boolean checkStatusAndLogFailure( android.hardware.wifi.supplicant.V1_4.SupplicantStatus status, final String methodStr) { synchronized (mLock) { if (status.code != android.hardware.wifi.supplicant.V1_4.SupplicantStatusCode.SUCCESS) { Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + status); return false; } else { if (mVerboseLoggingEnabled) { Log.d(TAG, "ISupplicantStaNetwork." + methodStr + " succeeded"); } return true; } } } /** * Helper function to log callbacks. */ protected void logCallback(final String methodStr) { synchronized (mLock) { if (mVerboseLoggingEnabled) { Log.d(TAG, "ISupplicantStaNetworkCallback." + methodStr + " received"); } } } /** * Returns false if ISupplicantStaNetwork is null, and logs failure of methodStr */ private boolean checkISupplicantStaNetworkAndLogFailure(final String methodStr) { synchronized (mLock) { if (mISupplicantStaNetwork == null) { Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaNetwork is null"); return false; } return true; } } private void handleRemoteException(RemoteException e, String methodStr) { synchronized (mLock) { mISupplicantStaNetwork = null; Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed with exception", e); } } /** * Adds FT flags for networks if the device supports it. */ private BitSet addFastTransitionFlags(BitSet keyManagementFlags) { synchronized (mLock) { if (!mContext.getResources().getBoolean( R.bool.config_wifi_fast_bss_transition_enabled)) { return keyManagementFlags; } BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_PSK); } if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) { modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_EAP); } return modifiedFlags; } } /** * Removes FT flags for networks if the device supports it. */ private BitSet removeFastTransitionFlags(BitSet keyManagementFlags) { synchronized (mLock) { BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_PSK); modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_EAP); return modifiedFlags; } } /** * Adds SHA256 key management flags for networks. */ private BitSet addSha256KeyMgmtFlags(BitSet keyManagementFlags) { synchronized (mLock) { BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); android.hardware.wifi.supplicant.V1_2.ISupplicantStaNetwork iSupplicantStaNetworkV12; iSupplicantStaNetworkV12 = getV1_2StaNetwork(); if (iSupplicantStaNetworkV12 == null) { // SHA256 key management requires HALv1.2 or higher return modifiedFlags; } if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256); } if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) { modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256); } return modifiedFlags; } } /** * Removes SHA256 key management flags for networks. */ private BitSet removeSha256KeyMgmtFlags(BitSet keyManagementFlags) { synchronized (mLock) { BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256); modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256); return modifiedFlags; } } /** * Adds both PSK and SAE AKM if auto-upgrade offload is supported. */ private BitSet addPskSaeUpgradableTypeFlagsIfSupported( WifiConfiguration config, BitSet keyManagementFlags) { synchronized (mLock) { if (!config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK) || !config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK).isEnabled() || !mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()) { return keyManagementFlags; } BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_PSK); modifiedFlags.set(WifiConfiguration.KeyMgmt.SAE); return modifiedFlags; } } /** * Removes SAE AKM when PSK and SAE AKM are both set, it only happens when * auto-upgrade offload is supported. */ private BitSet removePskSaeUpgradableTypeFlags(BitSet keyManagementFlags) { if (!keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK) || !keyManagementFlags.get(WifiConfiguration.KeyMgmt.SAE)) { return keyManagementFlags; } BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); modifiedFlags.clear(WifiConfiguration.KeyMgmt.SAE); return modifiedFlags; } /** * Creates the JSON encoded network extra using the map of string key, value pairs. */ public static String createNetworkExtra(Map values) { final String encoded; try { encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8"); } catch (NullPointerException e) { Log.e(TAG, "Unable to serialize networkExtra: " + e.toString()); return null; } catch (UnsupportedEncodingException e) { Log.e(TAG, "Unable to serialize networkExtra: " + e.toString()); return null; } return encoded; } /** * Parse the network extra JSON encoded string to a map of string key, value pairs. */ public static Map parseNetworkExtra(String encoded) { if (TextUtils.isEmpty(encoded)) { return null; } try { // This method reads a JSON dictionary that was written by setNetworkExtra(). However, // on devices that upgraded from Marshmallow, it may encounter a legacy value instead - // an FQDN stored as a plain string. If such a value is encountered, the JSONObject // constructor will thrown a JSONException and the method will return null. final JSONObject json = new JSONObject(URLDecoder.decode(encoded, "UTF-8")); final Map values = new HashMap<>(); final Iterator it = json.keys(); while (it.hasNext()) { final String key = (String) it.next(); final Object value = json.get(key); if (value instanceof String) { values.put(key, (String) value); } } return values; } catch (UnsupportedEncodingException e) { Log.e(TAG, "Unable to deserialize networkExtra: " + e.toString()); return null; } catch (JSONException e) { // This is not necessarily an error. This exception will also occur if we encounter a // legacy FQDN stored as a plain string. We want to return null in this case as no JSON // dictionary of extras was found. return null; } } protected class SupplicantStaNetworkHalCallbackV1_4 extends SupplicantStaNetworkCallbackV1_4Impl { SupplicantStaNetworkHalCallbackV1_4(int frameworkNetworkId, String ssid) { super(SupplicantStaNetworkHal.this, frameworkNetworkId, ssid, mIfaceName, mLock, mWifiMonitor); } } protected class SupplicantStaNetworkHalCallback extends SupplicantStaNetworkCallbackImpl { SupplicantStaNetworkHalCallback(int frameworkNetworkId, String ssid) { super(SupplicantStaNetworkHal.this, frameworkNetworkId, ssid, mIfaceName, mLock, mWifiMonitor); } } }