summaryrefslogtreecommitdiff
path: root/service/java
diff options
context:
space:
mode:
authorGlen Kuhne <kuh@google.com>2017-02-03 13:36:11 -0800
committerRoshan Pius <rpius@google.com>2017-02-09 14:26:39 -0800
commit66e9f4ab597136cbf4accadb8e009fc68ff071a7 (patch)
tree6d08fad8debbc7dcaca5d2b7d551f68225219334 /service/java
parent7c2c34319905b2122f124134a9f6f2064f1a2ea5 (diff)
downloadwifi-66e9f4ab597136cbf4accadb8e009fc68ff071a7.tar.gz
ISupplicantStaNetwork save & load WifiConfigs
Methods to set/get network variables from wpa_supplicant to WifiConfiguration & vice versa. TODO: Enterprise config params will be added in a further CL. Test: Unit tests Bug: 33383725 Change-Id: Ib002266a93b4738d0634cd1bbc925b61a86c1df7
Diffstat (limited to 'service/java')
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaIfaceHal.java95
-rw-r--r--service/java/com/android/server/wifi/SupplicantStaNetworkHal.java746
-rw-r--r--service/java/com/android/server/wifi/WifiNative.java4
3 files changed, 805 insertions, 40 deletions
diff --git a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
index 18f850c60..08afb3a55 100644
--- a/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
@@ -25,6 +25,7 @@ import android.hardware.wifi.supplicant.V1_0.SupplicantStatus;
import android.hardware.wifi.supplicant.V1_0.SupplicantStatusCode;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
+import android.net.wifi.WifiConfiguration;
import android.os.HandlerThread;
import android.os.RemoteException;
import android.util.Log;
@@ -33,6 +34,7 @@ import android.util.MutableBoolean;
import libcore.util.HexEncoding;
import java.util.ArrayList;
+//import android.net.wifi.WifiEnterpriseConfig;
/**
* Hal calls for bring up/shut down of the supplicant daemon and for
* sending requests to the supplicant daemon
@@ -216,6 +218,83 @@ public class SupplicantStaIfaceHal {
}
/**
+ * Imitation of WifiSupplicantControl.addNetwork()
+ *
+ * Add a network configuration to wpa_supplicant, via HAL
+ * @param config Config corresponding to the network.
+ * @return SupplicantStaNetwork of the added network in wpa_supplicant.
+ */
+ public SupplicantStaNetworkHal addNetwork(WifiConfiguration config) {
+ logi("addSupplicantStaNetwork via HIDL");
+ if (config == null) {
+ loge("Cannot add NULL network!");
+ return null;
+ }
+ SupplicantStaNetworkHal network = addNetwork();
+ if (network == null) {
+ loge("Failed to add a network!");
+ return null;
+ }
+ if (network.saveWifiConfiguration(config)) {
+ return network;
+ } else {
+ loge("Failed to save variables for: " + config.configKey());
+ return null;
+ }
+ }
+
+ /**
+ * Imitation of WifiSupplicantControl.connectToNetwork
+ */
+ public boolean connectToNetwork(WifiConfiguration configuration, boolean shouldDisconnect) {
+ logd("connectToNetwork " + configuration.configKey()
+ + " (shouldDisconnect " + shouldDisconnect + ")");
+ if (shouldDisconnect && !disconnect()) {
+ loge("Failed to trigger disconnect");
+ return false;
+ }
+ if (!removeAllNetworks()) {
+ loge("Failed to remove existing networks");
+ return false;
+ }
+ SupplicantStaNetworkHal network = addNetwork(configuration);
+ if (network == null) {
+ loge("Failed to add/save network configuration: " + configuration.configKey());
+ return false;
+ }
+ if (!network.getId()) {
+ loge("Failed to get network id for configuration: " + configuration.configKey());
+ return false;
+ }
+ if (!network.select()) {
+ loge("Failed to select network configuration: " + configuration.configKey());
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Remove all networks from supplicant
+ * TODO(b/34454675) use ISupplicantIface.removeAllNetworks when it exists
+ */
+ public boolean removeAllNetworks() {
+ synchronized (mLock) {
+ ArrayList<Integer> networks = listNetworks();
+ if (networks == null) {
+ Log.e(TAG, "removeAllNetworks failed, got null networks");
+ return false;
+ }
+ for (int id : networks) {
+ if (!removeNetwork(id)) {
+ Log.e(TAG, "removeAllNetworks failed to remove network: " + id);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
* @return returns the name of Iface or null if the call fails
*/
private String getName() {
@@ -301,7 +380,7 @@ public class SupplicantStaIfaceHal {
}
if (statusSuccess.value) {
return new SupplicantStaNetworkHal(ISupplicantStaNetwork.asInterface(
- newNetwork.value.asBinder()));
+ newNetwork.value.asBinder()), mHandlerThread);
} else {
return null;
}
@@ -353,7 +432,7 @@ public class SupplicantStaIfaceHal {
}
if (statusSuccess.value) {
return new SupplicantStaNetworkHal(ISupplicantStaNetwork.asInterface(
- gotNetwork.value.asBinder()));
+ gotNetwork.value.asBinder()), mHandlerThread);
} else {
return null;
}
@@ -770,4 +849,16 @@ public class SupplicantStaIfaceHal {
this.value = value;
}
}
+
+ private void logd(String s) {
+ Log.d(TAG, s);
+ }
+
+ private void logi(String s) {
+ Log.i(TAG, s);
+ }
+
+ private void loge(String s) {
+ Log.e(TAG, s);
+ }
}
diff --git a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
index d2aff6f58..f501f6b84 100644
--- a/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
+++ b/service/java/com/android/server/wifi/SupplicantStaNetworkHal.java
@@ -19,11 +19,24 @@ 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.WifiConfiguration;
+import android.net.wifi.WifiEnterpriseConfig;
+import android.os.HandlerThread;
import android.os.RemoteException;
+import android.text.TextUtils;
import android.util.Log;
import android.util.MutableBoolean;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+
+import libcore.util.HexEncoding;
+
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
/**
* Wrapper class for ISupplicantStaNetwork HAL calls. Gets and sets supplicant sta network variables
* and interacts with networks.
@@ -33,14 +46,23 @@ import java.util.ArrayList;
public class SupplicantStaNetworkHal {
private static final String TAG = "SupplicantStaNetworkHal";
private static final boolean DBG = false;
+ private static final String ANY_BSSID_STR = "any";
+ private static final byte[] ANY_BSSID_BYTES = {0, 0, 0, 0, 0, 0};
+ private static final int BSSID_LENGTH = 6;
+ @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";
private final Object mLock = new Object();
private ISupplicantStaNetwork mISupplicantStaNetwork = null;
- private int mId;
- private String mName;
- private int mType;
- private ArrayList<Byte> mApSsid;
- private byte[/* 6 */] mApBssid;
+ private final HandlerThread mHandlerThread;
+ private int mNetworkId;
+ private String mIfaceName;
+ private ArrayList<Byte> mSsid;
+ private byte[/* 6 */] mBssid;
private boolean mScanSsid;
private int mKeyMgmtMask;
private int mProtoMask;
@@ -67,12 +89,580 @@ public class SupplicantStaNetworkHal {
private String mEapDomainSuffixMatch;
private String mIdStr;
- SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork) {
+ SupplicantStaNetworkHal(ISupplicantStaNetwork iSupplicantStaNetwork,
+ HandlerThread handlerThread) {
mISupplicantStaNetwork = iSupplicantStaNetwork;
+ mHandlerThread = handlerThread;
+ }
+
+ /**
+ * 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.
+ */
+ public boolean loadWifiConfiguration(WifiConfiguration config,
+ Map<String, String> networkExtras) {
+ if (config == null) return false;
+ /** SSID */
+ config.SSID = null;
+ if (getSsid() && !ArrayUtils.isEmpty(mSsid)) {
+ config.SSID = decodeSsid(mSsid);
+ } else {
+ Log.e(TAG, "Failed to read ssid");
+ return false;
+ }
+ /** BSSID */
+ config.getNetworkSelectionStatus().setNetworkSelectionBSSID(null);
+ if (getBssid() && !ArrayUtils.isEmpty(mBssid)) {
+ config.getNetworkSelectionStatus().setNetworkSelectionBSSID(
+ 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] = stringFromByteArrayList(mWepKey);
+ }
+ }
+ /** PSK pass phrase */
+ config.preSharedKey = null;
+ if (getPskPassphrase() && !TextUtils.isEmpty(mPskPassphrase)) {
+ config.preSharedKey = mPskPassphrase;
+ }
+ /** allowedKeyManagement */
+ if (getKeyMgmt()) {
+ config.allowedKeyManagement =
+ supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask);
+ }
+ /** allowedProtocols */
+ if (getProto()) {
+ config.allowedProtocols =
+ supplicantToWifiConfigurationProtoMask(mProtoMask);
+ }
+ /** allowedAuthAlgorithms */
+ if (getAuthAlg()) {
+ config.allowedAuthAlgorithms =
+ supplicantToWifiConfigurationAuthAlgMask(mAuthAlgMask);
+ }
+ /** allowedGroupCiphers */
+ if (getGroupCipher()) {
+ config.allowedGroupCiphers =
+ supplicantToWifiConfigurationGroupCipherMask(mGroupCipherMask);
+ }
+ /** allowedPairwiseCiphers */
+ if (getPairwiseCipher()) {
+ config.allowedPairwiseCiphers =
+ supplicantToWifiConfigurationPairwiseCipherMask(mPairwiseCipherMask);
+ }
+ /** metadata: idstr */
+ if (getIdStr() && !TextUtils.isEmpty(mIdStr)) {
+ Map<String, String> metadata = WifiNative.parseNetworkExtra(mIdStr);
+ networkExtras.putAll(metadata);
+ } else {
+ Log.e(TAG, "getIdStr failed");
+ return false;
+ }
+ 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.
+ */
+ public boolean saveWifiConfiguration(WifiConfiguration config) {
+ if (config == null) return false;
+ /** SSID */
+ if (config.SSID != null) {
+ if (!setSsid(encodeSsid(config.SSID))) {
+ Log.e(TAG, "Failed to set SSID: " + config.SSID);
+ return false;
+ }
+ }
+ /** BSSID */
+ String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
+ if (bssidStr != null) {
+ byte[] bssid = macAddressToByteArray(bssidStr);
+ if (!setBssid(bssid)) {
+ Log.e(TAG, "Failed to set BSSID: " + bssidStr);
+ return false;
+ }
+ }
+ /** Pre Shared Key */
+ if (config.preSharedKey != null && !setPskPassphrase(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++) {
+ // Prevent client screw-up by passing in a WifiConfiguration we gave it
+ // by preventing "*" as a key.
+ if (config.wepKeys[i] != null && !config.wepKeys[i].equals("*")) {
+ if (!setWepKey(i, stringToByteArrayList(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;
+ }
+ }
+ /** HiddenSSID */
+ if (!setScanSsid(config.hiddenSSID)) {
+ Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID);
+ return false;
+ }
+ /** RequirePMF */
+ if (!setRequirePmf(config.requirePMF)) {
+ Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePMF);
+ return false;
+ }
+ /** Key Management Scheme */
+ if (config.allowedKeyManagement.cardinality() != 0
+ && !setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(
+ config.allowedKeyManagement))) {
+ Log.e(TAG, "Failed to set Key Management");
+ return false;
+ }
+ /** Security Protocol */
+ if (config.allowedProtocols.cardinality() != 0
+ && !setProto(wifiConfigurationToSupplicantProtoMask(config.allowedProtocols))) {
+ Log.e(TAG, "Failed to set Security Protocol");
+ return false;
+ }
+ /** Auth Algorithm */
+ if (config.allowedAuthAlgorithms.cardinality() != 0
+ && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask(
+ config.allowedAuthAlgorithms))) {
+ Log.e(TAG, "Failed to set AuthAlgorithm");
+ return false;
+ }
+ /** Group Cipher */
+ if (config.allowedGroupCiphers.cardinality() != 0
+ && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
+ config.allowedGroupCiphers))) {
+ Log.e(TAG, "Failed to set Group Cipher");
+ return false;
+ }
+ /** Pairwise Cipher*/
+ if (config.allowedPairwiseCiphers.cardinality() != 0
+ && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
+ config.allowedPairwiseCiphers))) {
+ Log.e(TAG, "Failed to set PairwiseCipher");
+ return false;
+ }
+ /** metadata: FQDN + ConfigKey + CreatorUid */
+ final Map<String, String> metadata = new HashMap<String, String>();
+ if (config.isPasspoint()) {
+ metadata.put(ID_STRING_KEY_FQDN, config.FQDN);
+ }
+ metadata.put(ID_STRING_KEY_CONFIG_KEY, config.configKey());
+ metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid));
+ if (!setIdStr(WifiNative.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;
+ }
+ // Finish here if no EAP config to set
+ if (config.enterpriseConfig == null
+ || config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.NONE) {
+ return true;
+ } else {
+ return saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig);
+ }
+ }
+
+ /**
+ * 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) {
+ // TBD
+ 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) {
+ // TBD
+ return true;
+ }
+
+ /**
+ * 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.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;
+ 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;
+ default:
+ throw new IllegalArgumentException(
+ "Invalid authAlgMask bit in wificonfig: " + bit);
+ }
+ }
+ return mask;
+ };
+
+ private static 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;
+ default:
+ throw new IllegalArgumentException(
+ "Invalid GroupCipherMask bit in wificonfig: " + bit);
+ }
+ }
+ return mask;
+ };
+
+ private static 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;
+ 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;
+ 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);
+ 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);
+ 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);
+ 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, ISupplicantStaNetwork.GroupCipherMask.GTK_NOT_USED, bitset,
+ WifiConfiguration.GroupCipher.GTK_NOT_USED);
+ if (mask != 0) {
+ throw new IllegalArgumentException(
+ "invalid group 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);
+ 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;
+ default:
+ Log.e(TAG, "invalid eap phase2 method value from WifiConfiguration: " + value);
+ return -1;
+ }
+ };
+
/** See ISupplicantNetwork.hal for documentation */
- private boolean getId() {
+ public boolean getId() {
synchronized (mLock) {
final String methodStr = "getId";
if (DBG) Log.i(TAG, methodStr);
@@ -82,7 +672,7 @@ public class SupplicantStaNetworkHal {
mISupplicantStaNetwork.getId((SupplicantStatus status, int idValue) -> {
statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
if (statusOk.value) {
- this.mId = idValue;
+ this.mNetworkId = idValue;
} else {
logFailureStatus(status, methodStr);
}
@@ -106,30 +696,7 @@ public class SupplicantStaNetworkHal {
String nameValue) -> {
statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
if (statusOk.value) {
- this.mName = nameValue;
- } else {
- logFailureStatus(status, methodStr);
- }
- });
- return statusOk.value;
- } catch (RemoteException e) {
- handleRemoteException(e, methodStr);
- return false;
- }
- }
- }
-
- /** See ISupplicantNetwork.hal for documentation */
- private boolean getType() {
- synchronized (mLock) {
- final String methodStr = "getType";
- if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
- try {
- MutableBoolean statusOk = new MutableBoolean(false);
- mISupplicantStaNetwork.getType((SupplicantStatus status, int typeValue) -> {
- statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
- if (statusOk.value) {
- this.mType = typeValue;
+ this.mIfaceName = nameValue;
} else {
logFailureStatus(status, methodStr);
}
@@ -327,6 +894,20 @@ public class SupplicantStaNetworkHal {
}
}
/** 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 setEapMethod(int method) {
synchronized (mLock) {
final String methodStr = "setEapMethod";
@@ -547,7 +1128,7 @@ public class SupplicantStaNetworkHal {
java.util.ArrayList<Byte> ssidValue) -> {
statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
if (statusOk.value) {
- this.mApSsid = ssidValue;
+ this.mSsid = ssidValue;
} else {
logFailureStatus(status, methodStr);
}
@@ -570,7 +1151,7 @@ public class SupplicantStaNetworkHal {
byte[/* 6 */] bssidValue) -> {
statusOk.value = status.code == SupplicantStatusCode.SUCCESS;
if (statusOk.value) {
- this.mApBssid = bssidValue;
+ this.mBssid = bssidValue;
} else {
logFailureStatus(status, methodStr);
}
@@ -743,7 +1324,7 @@ public class SupplicantStaNetworkHal {
}
}
/** See ISupplicantStaNetwork.hal for documentation */
- private boolean getWepKeyCallback(int keyIdx) {
+ private boolean getWepKey(int keyIdx) {
synchronized (mLock) {
final String methodStr = "keyIdx";
if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
@@ -1181,7 +1762,7 @@ public class SupplicantStaNetworkHal {
}
}
/** See ISupplicantStaNetwork.hal for documentation */
- private boolean select() {
+ public boolean select() {
synchronized (mLock) {
final String methodStr = "select";
if (!checkISupplicantStaNetworkAndLogFailure(methodStr)) return false;
@@ -1319,4 +1900,97 @@ public class SupplicantStaNetworkHal {
private void logFailureStatus(SupplicantStatus status, String methodStr) {
Log.e(TAG, methodStr + " failed: " + status.debugMessage);
}
+
+ /**
+ * @return the UTF_8 char byte values of str, as an ArrayList
+ */
+ private static ArrayList<Byte> stringToByteArrayList(String str) {
+ ArrayList<Byte> byteArrayList = new ArrayList<Byte>();
+ for (byte b : str.getBytes(StandardCharsets.UTF_8)) {
+ byteArrayList.add(new Byte(b));
+ }
+ return byteArrayList;
+ }
+
+ /**
+ * @return the string decoded from UTF_8 byte values in byteArrayList
+ * returns null for null input
+ */
+ private static String stringFromByteArrayList(ArrayList<Byte> byteArrayList) {
+ if (byteArrayList == null) return null;
+ byte[] byteArray = new byte[byteArrayList.size()];
+ int i = 0;
+ for (Byte b : byteArrayList) {
+ byteArray[i] = b;
+ i++;
+ }
+ return new String(byteArray, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * Converts a mac address string to an array of Byes
+ * @param bssidStr string of format: "XX:XX:XX:XX:XX:XX", where X is any hexadecimal digit.
+ * Passing "any" is the same as 00:00:00:00:00:00
+ * @throws IllegalArgumentException for various malformed inputs
+ */
+ private static byte[] macAddressToByteArray(String bssidStr) {
+ if (bssidStr == null) {
+ throw new IllegalArgumentException("null bssid String");
+ }
+ if (ANY_BSSID_STR.equals(bssidStr)) return ANY_BSSID_BYTES;
+ String cleanBssid = bssidStr.replace(":", "");
+ if (cleanBssid.length() != 12) {
+ throw new IllegalArgumentException("invalid bssid String length: " + cleanBssid);
+ }
+ return HexEncoding.decode(cleanBssid.toCharArray(), false);
+ }
+
+ /**
+ * Converts an array of 6 bytes to a HexEncoded String with format: "XX:XX:XX:XX:XX:XX", where X
+ * is any hexadecimal digit.
+ * @param macArray byte array of bssid values, must have length 6
+ * @throws IllegalArgumentException for malformed inputs
+ */
+ private static String macAddressFromByteArray(byte[] macArray) {
+ if (macArray == null) {
+ throw new IllegalArgumentException("null macArray");
+ }
+ if (macArray.length != 6) {
+ throw new IllegalArgumentException("invalid macArray length: " + macArray.length);
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < macArray.length; i++) {
+ sb.append(new String(HexEncoding.encode(macArray, i, 1))).append(":");
+ }
+ String mac = sb.toString();
+ return mac.substring(0, mac.length() - 1); //remove trailing ':'
+ }
+
+ /**
+ * Converts an ssid string to an arraylist of UTF_8 byte values.
+ * Removes encapsulating quotation marks if they exist
+ */
+ private static ArrayList<Byte> encodeSsid(String ssid) {
+ int length = ssid.length();
+ if ((length > 1) && (ssid.charAt(0) == '"') && (ssid.charAt(length - 1) == '"')) {
+ ssid = ssid.substring(1, ssid.length() - 1);
+ }
+ return stringToByteArrayList(ssid);
+ }
+
+ /**
+ * Converts an ArrayList<Byte> of UTF_8 byte values to an SSID String, encapsulated in quotes
+ * Will return null given null ssidBytes
+ */
+ private static String decodeSsid(ArrayList<Byte> ssidBytes) {
+ if (ssidBytes == null) return null;
+ if (ssidBytes.size() == 0) return "\"\"";
+ byte[] ssidArray = new byte[ssidBytes.size()];
+ int i = 0;
+ for (Byte b : ssidBytes) {
+ ssidArray[i] = b;
+ i++;
+ }
+ return "\"" + (new String(ssidArray, StandardCharsets.UTF_8)) + "\"";
+ }
}
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index c0afb9bc4..5eb71b751 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -491,7 +491,7 @@ public class WifiNative {
if (encoded == null) {
return false;
}
- return setNetworkVariable(netId, name, "\"" + encoded + "\"");
+ return setNetworkVariable(netId, name, encoded);
}
@VisibleForTesting
@@ -506,7 +506,7 @@ public class WifiNative {
Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
return null;
}
- return encoded;
+ return "\"" + encoded + "\"";
}
public boolean setNetworkVariable(int netId, String name, String value) {