merge in lmp-release history after reset to 8e6144b4059fc2117be23d7222893bc57a33f64d
diff --git a/service/java/com/android/server/wifi/WifiMonitor.java b/service/java/com/android/server/wifi/WifiMonitor.java
index 0760605..e2046a3 100644
--- a/service/java/com/android/server/wifi/WifiMonitor.java
+++ b/service/java/com/android/server/wifi/WifiMonitor.java
@@ -114,6 +114,8 @@
private static final String IDENTITY_STR = "IDENTITY";
+ private static final String SIM_STR = "SIM";
+
//used to debug and detect if we miss an event
private static int eventLogCounter = 0;
@@ -231,11 +233,27 @@
/**
* Regex pattern for extracting SSIDs from request identity string.
* Matches a strings like the following:<pre>
+ * CTRL-REQ-SIM-<network id>:GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>] needed for SSID <SSID>
+ * This pattern should find
+ * 0 - id
+ * 1 - Rand1
+ * 2 - Rand2
+ * 3 - Rand3
+ * 4 - SSID
+ */
+ private static Pattern mRequestSimAuthPattern =
+ Pattern.compile("SIM-([0-9]*):GSM-AUTH(:[0-9a-f]*)(:[0-9a-f]*)(:[0-9a-f]*)?"
+ + " needed for SSID (.+)");
+
+ /**
+ * Regex pattern for extracting SSIDs from request identity string.
+ * Matches a strings like the following:<pre>
* CTRL-REQ-IDENTITY-1:Identity needed for SSID XXXX</pre>
*/
private static Pattern mRequestIdentityPattern =
Pattern.compile("IDENTITY-[0-9]:Identity needed for SSID (.+)");
+
/** P2P events */
private static final String P2P_EVENT_PREFIX_STR = "P2P";
@@ -385,6 +403,9 @@
/* Request Identity */
public static final int SUP_REQUEST_IDENTITY = BASE + 15;
+ /* Request SIM Auth */
+ public static final int SUP_REQUEST_SIM_AUTH = BASE + 16;
+
/* P2P events */
public static final int P2P_DEVICE_FOUND_EVENT = BASE + 21;
public static final int P2P_DEVICE_LOST_EVENT = BASE + 22;
@@ -1091,9 +1112,25 @@
if (match.find()) {
SSID = match.group(1);
} else {
- Log.e(TAG, "didnt find SSID " + requestName);
+ Log.e(TAG, "didn't find SSID " + requestName);
}
mStateMachine.sendMessage(SUP_REQUEST_IDENTITY, eventLogCounter, 0, SSID);
+ } if (requestName.startsWith(SIM_STR)) {
+ Matcher match = mRequestSimAuthPattern.matcher(requestName);
+ if (match.find()) {
+ WifiStateMachine.SimAuthRequestData data =
+ new WifiStateMachine.SimAuthRequestData();
+ data.networkId = Integer.parseInt(match.group(1));
+ data.ssid = match.group(5);
+ data.rand1 = match.group(2).substring(1);
+ data.rand2 = match.group(3).substring(1);
+ data.rand3 = match.group(4).substring(1);
+
+ mStateMachine.sendMessage(SUP_REQUEST_SIM_AUTH, data);
+ } else {
+ Log.e(TAG, "couldn't parse SIM auth request - " + requestName);
+ }
+
} else {
if (DBG) Log.w(TAG, "couldn't identify request type - " + dataString);
}
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java
index 253a53e..1381d8a 100644
--- a/service/java/com/android/server/wifi/WifiNative.java
+++ b/service/java/com/android/server/wifi/WifiNative.java
@@ -672,6 +672,19 @@
}
}
+ public boolean setExternalSim(boolean external) {
+ synchronized (mLock) {
+ String value = external ? "1" : "0";
+ return doBooleanCommand("set external_sim " + value);
+ }
+ }
+
+ public boolean simAuthResponse(int id, String response) {
+ synchronized (mLock) {
+ return doBooleanCommand("SIM " + id + ":GSM-AUTH:" + response);
+ }
+ }
+
/* Configures an access point connection */
public boolean startWpsRegistrar(String bssid, String pin) {
if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
diff --git a/service/java/com/android/server/wifi/WifiServiceImpl.java b/service/java/com/android/server/wifi/WifiServiceImpl.java
index 9ab8e3f..f5eb08b 100644
--- a/service/java/com/android/server/wifi/WifiServiceImpl.java
+++ b/service/java/com/android/server/wifi/WifiServiceImpl.java
@@ -1228,6 +1228,10 @@
}
public void enableTdls(String remoteAddress, boolean enable) {
+ if (remoteAddress == null) {
+ throw new IllegalArgumentException("remoteAddress cannot be null");
+ }
+
TdlsTaskParams params = new TdlsTaskParams();
params.remoteIpAddress = remoteAddress;
params.enable = enable;
@@ -1236,6 +1240,10 @@
public void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable) {
+ if (remoteMacAddress == null) {
+ throw new IllegalArgumentException("remoteMacAddress cannot be null");
+ }
+
mWifiStateMachine.enableTdls(remoteMacAddress, enable);
}
diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java
index f148c02..d0dafae 100644
--- a/service/java/com/android/server/wifi/WifiStateMachine.java
+++ b/service/java/com/android/server/wifi/WifiStateMachine.java
@@ -76,6 +76,7 @@
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
+import android.telephony.TelephonyManager;
import android.util.LruCache;
import android.text.TextUtils;
import android.util.Log;
@@ -692,6 +693,23 @@
}
}
+ public static class SimAuthRequestData {
+ int networkId;
+ String ssid;
+ String rand1;
+ String rand2;
+ String rand3;
+ }
+
+ public static class SimAuthResponseData {
+ int id;
+ String Kc1;
+ String SRES1;
+ String Kc2;
+ String SRES2;
+ String Kc3;
+ String SRES3;
+ }
/**
* One of {@link WifiManager#WIFI_STATE_DISABLED},
@@ -3892,6 +3910,7 @@
case WifiMonitor.SUP_REQUEST_IDENTITY:
case CMD_TEST_NETWORK_DISCONNECT:
case CMD_OBTAINING_IP_ADDRESS_WATCHDOG_TIMER:
+ case WifiMonitor.SUP_REQUEST_SIM_AUTH:
break;
case DhcpStateMachine.CMD_ON_QUIT:
mDhcpStateMachine = null;
@@ -4154,6 +4173,7 @@
defaultInterval);
mWifiNative.setScanInterval((int)mSupplicantScanIntervalMs / 1000);
+ mWifiNative.setExternalSim(true);
if (mFrameworkAutoJoin.get()) {
mWifiNative.enableAutoConnect(false);
@@ -5314,6 +5334,15 @@
(WifiConfiguration.INVALID_NETWORK_ID);
mWifiNative.disconnect();
break;
+ case WifiMonitor.SUP_REQUEST_SIM_AUTH:
+ logd("Received SUP_REQUEST_SIM_AUTH");
+ SimAuthRequestData requestData = (SimAuthRequestData) message.obj;
+ if (requestData != null) {
+ handleSimAuthRequest(requestData);
+ } else {
+ loge("Invalid sim auth request");
+ }
+ break;
case CMD_GET_PRIVILEGED_CONFIGURED_NETWORKS:
replyToMessage(message, message.what,
mWifiConfigStore.getPrivilegedConfiguredNetworks());
@@ -6924,4 +6953,151 @@
msg.arg2 = srcMsg.arg2;
return msg;
}
+
+ private static int parseHex(char ch) {
+ if ('0' <= ch && ch <= '9') {
+ return ch - '0';
+ } else if ('a' <= ch && ch <= 'f') {
+ return ch - 'a' + 10;
+ } else if ('A' <= ch && ch <= 'F') {
+ return ch - 'A' + 10;
+ } else {
+ throw new NumberFormatException("" + ch + " is not a valid hex digit");
+ }
+ }
+
+ private byte[] parseHex(String hex) {
+ /* This only works for good input; don't throw bad data at it */
+ if (hex == null) {
+ return new byte[0];
+ }
+
+ if (hex.length() % 2 != 0) {
+ throw new NumberFormatException(hex + " is not a valid hex string");
+ }
+
+ byte[] result = new byte[(hex.length())/2];
+ for (int i = 0, j = 0; i < hex.length(); i += 2, j++) {
+
+ int val = parseHex(hex.charAt(i)) * 16 + parseHex(hex.charAt(i+1));
+ byte b = (byte) (val & 0xFF);
+ result[j] = b;
+ }
+
+ return result;
+ }
+
+ private static String makeHex(byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+ for (byte b : bytes) {
+ sb.append(String.format("%02x", b));
+ }
+ return sb.toString();
+ }
+
+ private static byte[] concat(byte[] array1, byte[] array2, byte[] array3) {
+
+ int len = array1.length + array2.length + array3.length;
+
+ if (array1.length != 0) {
+ len++; /* add another byte for size */
+ }
+
+ if (array2.length != 0) {
+ len++; /* add another byte for size */
+ }
+
+ if (array3.length != 0) {
+ len++; /* add another byte for size */
+ }
+
+ byte[] result = new byte[len];
+
+ int index = 0;
+ if (array1.length != 0) {
+ result[index] = (byte) (array1.length & 0xFF);
+ index++;
+ for (byte b : array1) {
+ result[index] = b;
+ index++;
+ }
+ }
+
+ if (array2.length != 0) {
+ result[index] = (byte) (array2.length & 0xFF);
+ index++;
+ for (byte b : array2) {
+ result[index] = b;
+ index++;
+ }
+ }
+
+ if (array3.length != 0) {
+ result[index] = (byte) (array3.length & 0xFF);
+ index++;
+ for (byte b : array3) {
+ result[index] = b;
+ index++;
+ }
+ }
+ return result;
+ }
+
+ void handleSimAuthRequest(SimAuthRequestData requestData) {
+ if (targetWificonfiguration == null
+ || targetWificonfiguration.networkId == requestData.networkId) {
+ logd("id matches targetWifiConfiguration");
+ } else {
+ logd("id does not match targetWifiConfiguration");
+ }
+
+ logd("rand1 = " + requestData.rand1);
+ logd("rand2 = " + requestData.rand2);
+ logd("rand3 = " + requestData.rand3);
+
+ byte[] rand1, rand2, rand3;
+
+ try {
+ rand1 = parseHex(requestData.rand1);
+ rand2 = parseHex(requestData.rand2);
+ rand3 = parseHex(requestData.rand3);
+ } catch (NumberFormatException e) {
+ loge("malformed challenge");
+ return;
+ }
+
+ byte[] c = concat(rand1, rand2, rand3);
+
+ String challenge = android.util.Base64.encodeToString(c, android.util.Base64.NO_WRAP);
+
+ logd("challenge = " + challenge);
+ logd("challenge length = " + challenge.length());
+
+ TelephonyManager tm = (TelephonyManager)
+ mContext.getSystemService(Context.TELEPHONY_SERVICE);
+
+ if (tm != null) {
+ /*
+ * appType = 1 => SIM, 2 => USIM according to
+ * com.android.internal.telephony.PhoneConstants#APPTYPE_xxx
+ */
+
+ int appType = 2;
+ String response = tm.getIccSimChallengeResponse(appType, challenge);
+ logd("Raw Response - " + response);
+
+ if (response != null) {
+ byte[] result = android.util.Base64.decode(response, android.util.Base64.DEFAULT);
+ response = makeHex(result);
+ logd("Sim Response - " + response);
+ mWifiNative.simAuthResponse(requestData.networkId, response);
+ } else {
+ logd("bad response - " + response);
+ }
+
+ } else {
+ loge("could not get telephony manager");
+ }
+
+ }
}