Snap for 8618812 from 23ff4d4549779628a4c1eb8a7f5002a18cadde8d to mainline-tzdata4-release
Change-Id: I3a8bc409b9b5ff6d96ae3e56358a363dbc16c6a7
diff --git a/OWNERS b/OWNERS
index b6feac0..54d6c0b 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,5 @@
edensu@google.com
amreddy@google.com
radhikaagrawal@google.com
+pochunlee@google.com
+apsankar@google.com
diff --git a/assets/defaultiwlanerrorconfig.json b/assets/defaultiwlanerrorconfig.json
index 07b980d..eae1ae2 100644
--- a/assets/defaultiwlanerrorconfig.json
+++ b/assets/defaultiwlanerrorconfig.json
@@ -72,6 +72,12 @@
"ErrorDetails": ["IO_EXCEPTION"],
"RetryArray": ["0", "0", "0", "60+r15", "120", "-1"],
"UnthrottlingEvents": ["APM_ENABLE_EVENT", "APM_DISABLE_EVENT", "WIFI_DISABLE_EVENT", "WIFI_AP_CHANGED_EVENT"]
+ },
+ {
+ "ErrorType": "IKE_PROTOCOL_ERROR_TYPE",
+ "ErrorDetails": ["24"],
+ "RetryArray": ["10", "20", "40", "80", "160"],
+ "UnthrottlingEvents": ["APM_ENABLE_EVENT", "WIFI_DISABLE_EVENT", "WIFI_CALLING_DISABLE_EVENT"]
}
]
}
diff --git a/src/com/google/android/iwlan/ErrorPolicyManager.java b/src/com/google/android/iwlan/ErrorPolicyManager.java
index 15d8116..59fad64 100644
--- a/src/com/google/android/iwlan/ErrorPolicyManager.java
+++ b/src/com/google/android/iwlan/ErrorPolicyManager.java
@@ -302,6 +302,10 @@
ret = DataFailCause.IWLAN_DNS_RESOLUTION_NAME_FAILURE;
} else if (error.getErrorType() == IwlanError.IKE_INTERNAL_IO_EXCEPTION) {
ret = DataFailCause.IWLAN_IKEV2_MSG_TIMEOUT;
+ } else if (error.getErrorType() == IwlanError.SIM_NOT_READY_EXCEPTION) {
+ ret = DataFailCause.IWLAN_PDN_CONNECTION_REJECTION;
+ } else if (error.getErrorType() == IwlanError.NETWORK_FAILURE) {
+ ret = DataFailCause.NETWORK_FAILURE;
} else if (error.getErrorType() == IwlanError.IKE_PROTOCOL_EXCEPTION) {
Exception exception = error.getException();
if (exception != null && exception instanceof IkeProtocolException) {
diff --git a/src/com/google/android/iwlan/IwlanDataService.java b/src/com/google/android/iwlan/IwlanDataService.java
index 923a393..a254535 100644
--- a/src/com/google/android/iwlan/IwlanDataService.java
+++ b/src/com/google/android/iwlan/IwlanDataService.java
@@ -872,8 +872,7 @@
+ ", transport: "
+ sDefaultDataTransport);
- if (networkConnected == false
- || mTunnelStateForApn.get(dataProfile.getApn()) != null) {
+ if (networkConnected == false) {
deliverCallback(
CALLBACK_TYPE_SETUP_DATACALL_COMPLETE,
5 /* DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */,
@@ -882,6 +881,39 @@
return;
}
+ TunnelState tunnelState = mTunnelStateForApn.get(dataProfile.getApn());
+
+ // Return the existing PDN if the pduSessionId is the same and the tunnel state is
+ // TUNNEL_UP.
+ if (tunnelState != null) {
+ if (tunnelState.getPduSessionId() == pduSessionId
+ && tunnelState.getState() == TunnelState.TUNNEL_UP) {
+ Log.w(
+ SUB_TAG,
+ "The tunnel for " + dataProfile.getApn() + " already exists.");
+ deliverCallback(
+ CALLBACK_TYPE_SETUP_DATACALL_COMPLETE,
+ DataServiceCallback.RESULT_SUCCESS,
+ callback,
+ apnTunnelStateToDataCallResponse(dataProfile.getApn()));
+ return;
+ } else {
+ Log.e(
+ SUB_TAG,
+ "Force close the existing PDN. pduSessionId = "
+ + tunnelState.getPduSessionId()
+ + " Tunnel State = "
+ + tunnelState.getState());
+ getTunnelManager().closeTunnel(dataProfile.getApn(), true /* forceClose */);
+ deliverCallback(
+ CALLBACK_TYPE_SETUP_DATACALL_COMPLETE,
+ 5 /* DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE */,
+ callback,
+ null);
+ return;
+ }
+ }
+
TunnelSetupRequest.Builder tunnelReqBuilder =
TunnelSetupRequest.builder()
.setApnName(dataProfile.getApn())
diff --git a/src/com/google/android/iwlan/IwlanError.java b/src/com/google/android/iwlan/IwlanError.java
index 6d5e249..f621a7a 100644
--- a/src/com/google/android/iwlan/IwlanError.java
+++ b/src/com/google/android/iwlan/IwlanError.java
@@ -40,9 +40,11 @@
// Known internal types
public static final int EPDG_SELECTOR_SERVER_SELECTION_FAILED = 4;
public static final int TUNNEL_TRANSFORM_FAILED = 5;
+ public static final int SIM_NOT_READY_EXCEPTION = 6;
+ public static final int NETWORK_FAILURE = 7;
// Catch all exception
- public static final int UNKNOWN_EXCEPTION = 6; // catch all
+ public static final int UNKNOWN_EXCEPTION = 8; // catch all
@IntDef({
NO_ERROR,
@@ -51,6 +53,8 @@
IKE_GENERIC_EXCEPTION,
EPDG_SELECTOR_SERVER_SELECTION_FAILED,
TUNNEL_TRANSFORM_FAILED,
+ SIM_NOT_READY_EXCEPTION,
+ NETWORK_FAILURE,
UNKNOWN_EXCEPTION
})
@interface IwlanErrorType {};
@@ -66,6 +70,8 @@
EPDG_SELECTOR_SERVER_SELECTION_FAILED,
"IWLAN_EPDG_SELECTOR_SERVER_SELECTION_FAILED");
put(TUNNEL_TRANSFORM_FAILED, "IWLAN_TUNNEL_TRANSFORM_FAILED");
+ put(SIM_NOT_READY_EXCEPTION, "IWLAN_SIM_NOT_READY_EXCEPTION");
+ put(NETWORK_FAILURE, "IWLAN_NETWORK_FAILURE");
put(UNKNOWN_EXCEPTION, "IWLAN_UNKNOWN_EXCEPTION");
}
};
@@ -192,6 +198,12 @@
case "TUNNEL_TRANSFORM_FAILED":
ret = IwlanError.TUNNEL_TRANSFORM_FAILED;
break;
+ case "SIM_NOT_READY_EXCEPTION":
+ ret = IwlanError.SIM_NOT_READY_EXCEPTION;
+ break;
+ case "NETWORK_FAILURE":
+ ret = IwlanError.NETWORK_FAILURE;
+ break;
}
return ret;
}
diff --git a/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java b/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
index eecede0..1c824b7 100644
--- a/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
+++ b/src/com/google/android/iwlan/epdg/EpdgTunnelManager.java
@@ -62,6 +62,7 @@
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.NetworkSliceInfo;
@@ -72,6 +73,7 @@
import com.google.android.iwlan.ErrorPolicyManager;
import com.google.android.iwlan.IwlanError;
import com.google.android.iwlan.IwlanHelper;
+import com.google.android.iwlan.exceptions.IwlanSimNotReadyException;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -110,6 +112,7 @@
private static final int EVENT_IPSEC_TRANSFORM_CREATED = 7;
private static final int EVENT_IPSEC_TRANSFORM_DELETED = 8;
private static final int EVENT_UPDATE_NETWORK = 9;
+ private static final int EVENT_IKE_SESSION_OPENED = 10;
private static final int IKE_HARD_LIFETIME_SEC_MINIMUM = 300;
private static final int IKE_HARD_LIFETIME_SEC_MAXIMUM = 86400;
private static final int IKE_SOFT_LIFETIME_SEC_MINIMUM = 120;
@@ -384,6 +387,12 @@
return sb.toString();
}
+ public boolean hasTunnelOpened() {
+ return mInternalAddrList != null
+ && !mInternalAddrList.isEmpty() /* The child session is opened */
+ && mIface != null; /* The tunnel interface is bring up */
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -434,27 +443,10 @@
@Override
public void onOpened(IkeSessionConfiguration sessionConfiguration) {
Log.d(TAG, "Ike session opened for apn: " + mApnName);
- TunnelConfig tunnelConfig = mApnNameToTunnelConfig.get(mApnName);
- tunnelConfig.setPcscfAddrList(sessionConfiguration.getPcscfServers());
-
- boolean enabledFastReauth =
- (boolean)
- getConfig(
- CarrierConfigManager.Iwlan
- .KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL);
- Log.d(
- TAG,
- "CarrierConfigManager.Iwlan.KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL "
- + enabledFastReauth);
- if (enabledFastReauth) {
- EapInfo eapInfo = sessionConfiguration.getEapInfo();
- if (eapInfo != null && eapInfo instanceof EapAkaInfo) {
- mNextReauthId = ((EapAkaInfo) eapInfo).getReauthId();
- Log.d(TAG, "Update ReauthId: " + Arrays.toString(mNextReauthId));
- } else {
- mNextReauthId = null;
- }
- }
+ mHandler.sendMessage(
+ mHandler.obtainMessage(
+ EVENT_IKE_SESSION_OPENED,
+ new IkeSessionOpenedData(mApnName, sessionConfiguration)));
}
@Override
@@ -731,6 +723,7 @@
private void onBringUpTunnel(TunnelSetupRequest setupRequest, TunnelCallback tunnelCallback) {
String apnName = setupRequest.apnName();
+ IkeSessionParams ikeSessionParams = null;
Log.d(
TAG,
@@ -739,11 +732,21 @@
+ "ePDG : "
+ mEpdgAddress.getHostAddress());
+ try {
+ ikeSessionParams = buildIkeSessionParams(setupRequest, apnName);
+ } catch (IwlanSimNotReadyException e) {
+ mRequestQueue.poll();
+ IwlanError iwlanError = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION);
+ reportIwlanError(apnName, iwlanError);
+ tunnelCallback.onClosed(apnName, iwlanError);
+ return;
+ }
+
IkeSession ikeSession =
getIkeSessionCreator()
.createIkeSession(
mContext,
- buildIkeSessionParams(setupRequest, apnName),
+ ikeSessionParams,
buildChildSessionParams(setupRequest),
Executors.newSingleThreadExecutor(),
getTmIkeSessionCallback(apnName),
@@ -888,7 +891,8 @@
// Returns the IMEISV or device IMEI, in that order of priority.
private @Nullable String getMobileDeviceIdentity() {
TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
- telephonyManager = telephonyManager.createForSubscriptionId(mSlotId);
+ telephonyManager =
+ telephonyManager.createForSubscriptionId(IwlanHelper.getSubId(mContext, mSlotId));
if (telephonyManager == null) {
return null;
}
@@ -907,8 +911,8 @@
return imei.substring(0, imei.length() - 1) + imeisv_suffix;
}
- private IkeSessionParams buildIkeSessionParams(
- TunnelSetupRequest setupRequest, String apnName) {
+ private IkeSessionParams buildIkeSessionParams(TunnelSetupRequest setupRequest, String apnName)
+ throws IwlanSimNotReadyException {
int hardTimeSeconds =
(int) getConfig(CarrierConfigManager.Iwlan.KEY_IKE_REKEY_HARD_TIMER_SEC_INT);
int softTimeSeconds =
@@ -952,6 +956,7 @@
.setNetwork(mNetwork)
.addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
.addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
+ .addIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY)
.setLifetimeSeconds(hardTimeSeconds, softTimeSeconds)
.setRetransmissionTimeoutsMillis(getRetransmissionTimeoutsFromConfig())
.setDpdDelaySeconds(getDpdDelayFromConfig());
@@ -1179,13 +1184,13 @@
return saProposalBuilder.build();
}
- private IkeIdentification getLocalIdentification() {
+ private IkeIdentification getLocalIdentification() throws IwlanSimNotReadyException {
String nai;
nai = IwlanHelper.getNai(mContext, mSlotId, mNextReauthId);
if (nai == null) {
- throw new IllegalArgumentException("Nai is null.");
+ throw new IwlanSimNotReadyException("Nai is null.");
}
Log.d(TAG, "getLocalIdentification: Nai: " + nai);
@@ -1210,12 +1215,12 @@
}
}
- private EapSessionConfig getEapConfig() {
+ private EapSessionConfig getEapConfig() throws IwlanSimNotReadyException {
int subId = IwlanHelper.getSubId(mContext, mSlotId);
String nai = IwlanHelper.getNai(mContext, mSlotId, null);
if (nai == null) {
- throw new IllegalArgumentException("Nai is null.");
+ throw new IwlanSimNotReadyException("Nai is null.");
}
EapSessionConfig.EapAkaOption option = null;
@@ -1261,6 +1266,18 @@
case EVENT_TUNNEL_BRINGUP_REQUEST:
TunnelRequestWrapper tunnelRequestWrapper = (TunnelRequestWrapper) msg.obj;
TunnelSetupRequest setupRequest = tunnelRequestWrapper.getSetupRequest();
+
+ if (IwlanHelper.getSubId(mContext, mSlotId)
+ == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ Log.e(TAG, "SIM isn't ready");
+ IwlanError iwlanError = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION);
+ reportIwlanError(setupRequest.apnName(), iwlanError);
+ tunnelRequestWrapper
+ .getTunnelCallback()
+ .onClosed(setupRequest.apnName(), iwlanError);
+ return;
+ }
+
if (!canBringUpTunnel(setupRequest.apnName())) {
Log.d(TAG, "Cannot bring up tunnel as retry time has not passed");
tunnelRequestWrapper
@@ -1376,7 +1393,13 @@
if (sessionClosedData.mIwlanError.getErrorType() != IwlanError.NO_ERROR) {
iwlanError = sessionClosedData.mIwlanError;
} else {
- iwlanError = tunnelConfig.getError();
+ // If IKE session setup failed without error cause, Iwlan reports
+ // NETWORK_FAILURE instead of NO_ERROR
+ if (!tunnelConfig.hasTunnelOpened()) {
+ iwlanError = new IwlanError(IwlanError.NETWORK_FAILURE);
+ } else {
+ iwlanError = tunnelConfig.getError();
+ }
}
IpSecManager.IpSecTunnelInterface iface = tunnelConfig.getIface();
@@ -1417,7 +1440,7 @@
tunnelConfig = mApnNameToTunnelConfig.get(apnName);
// Update the global cache if they aren't equal
- if (!mNetwork.equals(network)) {
+ if (mNetwork == null || !mNetwork.equals(network)) {
Log.d(TAG, "Updating mNetwork to " + network);
mNetwork = network;
}
@@ -1523,6 +1546,34 @@
tunnelConfig.getIkeSession().close();
break;
+ case EVENT_IKE_SESSION_OPENED:
+ IkeSessionOpenedData ikeSessionOpenedData = (IkeSessionOpenedData) msg.obj;
+ IkeSessionConfiguration sessionConfiguration =
+ ikeSessionOpenedData.mIkeSessionConfiguration;
+
+ tunnelConfig = mApnNameToTunnelConfig.get(ikeSessionOpenedData.mApnName);
+ tunnelConfig.setPcscfAddrList(sessionConfiguration.getPcscfServers());
+
+ boolean enabledFastReauth =
+ (boolean)
+ getConfig(
+ CarrierConfigManager.Iwlan
+ .KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL);
+ Log.d(
+ TAG,
+ "CarrierConfigManager.Iwlan.KEY_SUPPORTS_EAP_AKA_FAST_REAUTH_BOOL "
+ + enabledFastReauth);
+
+ if (enabledFastReauth) {
+ EapInfo eapInfo = sessionConfiguration.getEapInfo();
+ if (eapInfo != null && eapInfo instanceof EapAkaInfo) {
+ mNextReauthId = ((EapAkaInfo) eapInfo).getReauthId();
+ Log.d(TAG, "Update ReauthId: " + Arrays.toString(mNextReauthId));
+ } else {
+ mNextReauthId = null;
+ }
+ }
+ break;
default:
throw new IllegalStateException("Unexpected value: " + msg.what);
}
@@ -1722,6 +1773,7 @@
}
}
+ // Data received from IkeSessionStateMachine on successful EVENT_CHILD_SESSION_OPENED.
private static final class TunnelOpenedData {
final String mApnName;
final List<InetAddress> mInternalDnsServers;
@@ -1737,6 +1789,20 @@
}
}
+ // Data received from IkeSessionStateMachine on successful EVENT_IKE_SESSION_OPENED.
+ private static final class IkeSessionOpenedData {
+ final String mApnName;
+ final IkeSessionConfiguration mIkeSessionConfiguration;
+
+ private IkeSessionOpenedData(
+ String apnName, IkeSessionConfiguration ikeSessionConfiguration) {
+ mApnName = apnName;
+ mIkeSessionConfiguration = ikeSessionConfiguration;
+ }
+ }
+
+ // Data received from IkeSessionStateMachine if either IKE session or Child session have been
+ // closed, normally or exceptionally.
private static final class SessionClosedData {
final String mApnName;
final IwlanError mIwlanError;
@@ -1951,6 +2017,11 @@
}
@VisibleForTesting
+ TunnelConfig getTunnelConfigForApn(String apnName) {
+ return mApnNameToTunnelConfig.get(apnName);
+ }
+
+ @VisibleForTesting
long reportIwlanError(String apnName, IwlanError error) {
return ErrorPolicyManager.getInstance(mContext, mSlotId).reportIwlanError(apnName, error);
}
diff --git a/src/com/google/android/iwlan/exceptions/IwlanException.java b/src/com/google/android/iwlan/exceptions/IwlanException.java
new file mode 100644
index 0000000..9afad54
--- /dev/null
+++ b/src/com/google/android/iwlan/exceptions/IwlanException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 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.google.android.iwlan.exceptions;
+
+/** Generic Exception for Iwlan error. */
+public abstract class IwlanException extends Exception {
+ protected IwlanException() {
+ super();
+ }
+
+ protected IwlanException(String message) {
+ super(message);
+ }
+
+ protected IwlanException(Throwable cause) {
+ super(cause);
+ }
+
+ protected IwlanException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/com/google/android/iwlan/exceptions/IwlanSimNotReadyException.java b/src/com/google/android/iwlan/exceptions/IwlanSimNotReadyException.java
new file mode 100644
index 0000000..424bd5a
--- /dev/null
+++ b/src/com/google/android/iwlan/exceptions/IwlanSimNotReadyException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 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.google.android.iwlan.exceptions;
+
+/** Represent the error when getting the invalid Subscription info */
+public final class IwlanSimNotReadyException extends IwlanException {
+ public IwlanSimNotReadyException() {
+ super();
+ }
+
+ public IwlanSimNotReadyException(String message) {
+ super(message);
+ }
+
+ public IwlanSimNotReadyException(Throwable cause) {
+ super(cause);
+ }
+
+ public IwlanSimNotReadyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/test/com/google/android/iwlan/ErrorPolicyManagerTest.java b/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
index 718a875..3bc624b 100644
--- a/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
+++ b/test/com/google/android/iwlan/ErrorPolicyManagerTest.java
@@ -191,7 +191,7 @@
}
@Test
- public void testInvalidCarrierConfig() throws Exception {
+ public void testDefaultPolicyFallback() throws Exception {
String apn = "ims";
String config =
"[{"
@@ -217,17 +217,21 @@
sleep(1000);
- // IKE_PROTOCOL_ERROR_TYPE(24) and retryArray = 5, 10, 15 as it will fallback due to failed
- // parsing
+ // Fallback to default Iwlan error policy for IKE_PROTOCOL_ERROR_TYPE(24) because of failed
+ // parsing (or lack of explicit carrier-defined policy).
IwlanError iwlanError = buildIwlanIkeAuthFailedError();
long time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
- assertEquals(5, time);
- time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
assertEquals(10, time);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
- assertEquals(10, time);
+ assertEquals(20, time);
time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
- assertEquals(10, time);
+ assertEquals(40, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(80, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(160, time);
+ time = mErrorPolicyManager.reportIwlanError(apn, iwlanError);
+ assertEquals(86400, time);
}
@Test
diff --git a/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java b/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
index 97b409c..5960e00 100644
--- a/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
+++ b/test/com/google/android/iwlan/epdg/EpdgTunnelManagerTest.java
@@ -36,6 +36,7 @@
import android.net.ipsec.ike.IkeFqdnIdentification;
import android.net.ipsec.ike.IkeSession;
import android.net.ipsec.ike.IkeSessionCallback;
+import android.net.ipsec.ike.IkeSessionConfiguration;
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.SaProposal;
import android.net.ipsec.ike.TunnelModeChildSessionParams;
@@ -71,6 +72,7 @@
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executor;
@@ -79,8 +81,16 @@
public static final int DEFAULT_SLOT_INDEX = 0;
public static final int DEFAULT_SUBID = 0;
- private final String TEST_IP_ADDRESS = "127.0.0.1";
- private final String TEST_APN_NAME = "www.xyz.com";
+ private static final String TEST_IP_ADDRESS = "127.0.0.1";
+ private static final String TEST_APN_NAME = "www.xyz.com";
+
+ private static final ArrayList<InetAddress> EXPECTED_EPDG_ADDRESSES =
+ new ArrayList<>(
+ Arrays.asList(
+ new InetAddress[] {
+ InetAddresses.parseNumericAddress(TEST_IP_ADDRESS)
+ }));
+
private EpdgTunnelManager mEpdgTunnelManager;
private class IwlanTunnelCallback implements EpdgTunnelManager.TunnelCallback {
@@ -103,6 +113,7 @@
@Mock TelephonyManager mMockTelephonyManager;
@Mock EpdgTunnelManager.IkeSessionCreator mMockIkeSessionCreator;
@Mock IkeException mMockIkeException;
+ @Mock IkeSessionConfiguration mMockIkeSessionConfiguration;
@Before
public void setUp() throws Exception {
@@ -123,6 +134,10 @@
any(EpdgSelector.EpdgSelectorCallback.class)))
.thenReturn(new IwlanError(IwlanError.NO_ERROR));
+ // initialize carrier configuration
+ PersistableBundle bundle = new PersistableBundle();
+ setupMockForGetConfig(bundle);
+
// Fake local address
List<InetAddress> testLocalAddressList = new ArrayList<InetAddress>();
InetAddress testInetaddr = InetAddress.getByName(TEST_IP_ADDRESS);
@@ -227,6 +242,9 @@
TunnelSetupRequest TSR = getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP);
doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(TEST_APN_NAME));
+ PersistableBundle bundle = new PersistableBundle();
+ setupMockForGetConfig(bundle);
+
boolean ret = mEpdgTunnelManager.bringUpTunnel(TSR, mMockIwlanTunnelCallback);
assertTrue(ret);
mTestLooper.dispatchAll();
@@ -241,6 +259,160 @@
any());
}
+ private void setupTunnelBringup() throws Exception {
+ setupMockForGetConfig(null);
+ doReturn(null)
+ .when(mMockIkeSessionCreator)
+ .createIkeSession(
+ eq(mMockContext),
+ any(IkeSessionParams.class),
+ any(ChildSessionParams.class),
+ any(Executor.class),
+ any(IkeSessionCallback.class),
+ any(ChildSessionCallback.class));
+
+ doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(TEST_APN_NAME));
+
+ boolean ret =
+ mEpdgTunnelManager.bringUpTunnel(
+ getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
+ mMockIwlanTunnelCallback);
+ assertTrue(ret);
+ mTestLooper.dispatchAll();
+
+ ArrayList<InetAddress> ipList = new ArrayList<>();
+ ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
+ mEpdgTunnelManager.sendSelectionRequestComplete(
+ ipList, new IwlanError(IwlanError.NO_ERROR), 1);
+ mTestLooper.dispatchAll();
+ }
+
+ @Test
+ public void testBringUpTunnelSetsDeviceIdentityImeiSv() throws Exception {
+ when(mMockContext.getSystemService(eq(TelephonyManager.class)))
+ .thenReturn(mMockTelephonyManager);
+ when(mMockTelephonyManager.createForSubscriptionId(DEFAULT_SUBID))
+ .thenReturn(mMockTelephonyManager);
+
+ String TEST_IMEI = "012345678901234";
+ String TEST_IMEI_SUFFIX = "56";
+ String EXPECTED_IMEISV = TEST_IMEI.substring(0, TEST_IMEI.length() - 1) + TEST_IMEI_SUFFIX;
+ when(mMockTelephonyManager.getImei()).thenReturn(TEST_IMEI);
+ when(mMockTelephonyManager.getDeviceSoftwareVersion()).thenReturn(TEST_IMEI_SUFFIX);
+
+ setupTunnelBringup();
+
+ ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
+ ArgumentCaptor.forClass(IkeSessionParams.class);
+ verify(mMockIkeSessionCreator, atLeastOnce())
+ .createIkeSession(
+ eq(mMockContext),
+ ikeSessionParamsCaptor.capture(),
+ any(ChildSessionParams.class),
+ any(Executor.class),
+ any(IkeSessionCallback.class),
+ any(ChildSessionCallback.class));
+ IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
+ assertEquals(
+ ikeSessionParams.getIke3gppExtension().getIke3gppParams().getMobileDeviceIdentity(),
+ EXPECTED_IMEISV);
+ }
+
+ @Test
+ public void testBringUpTunnelSetsDeviceIdentityImei() throws Exception {
+ when(mMockContext.getSystemService(eq(TelephonyManager.class)))
+ .thenReturn(mMockTelephonyManager);
+ when(mMockTelephonyManager.createForSubscriptionId(DEFAULT_SUBID))
+ .thenReturn(mMockTelephonyManager);
+
+ String TEST_IMEI = "012345678901234";
+ when(mMockTelephonyManager.getImei()).thenReturn(TEST_IMEI);
+ when(mMockTelephonyManager.getDeviceSoftwareVersion()).thenReturn(null);
+
+ setupTunnelBringup();
+
+ ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
+ ArgumentCaptor.forClass(IkeSessionParams.class);
+ verify(mMockIkeSessionCreator, atLeastOnce())
+ .createIkeSession(
+ eq(mMockContext),
+ ikeSessionParamsCaptor.capture(),
+ any(ChildSessionParams.class),
+ any(Executor.class),
+ any(IkeSessionCallback.class),
+ any(ChildSessionCallback.class));
+ IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
+ assertEquals(
+ ikeSessionParams.getIke3gppExtension().getIke3gppParams().getMobileDeviceIdentity(),
+ TEST_IMEI);
+ }
+
+ @Test
+ public void testBringUpTunnelNoDeviceIdentityWhenImeiUnavailable() throws Exception {
+ when(mMockContext.getSystemService(eq(TelephonyManager.class)))
+ .thenReturn(mMockTelephonyManager);
+ when(mMockTelephonyManager.createForSubscriptionId(DEFAULT_SUBID))
+ .thenReturn(mMockTelephonyManager);
+ when(mMockTelephonyManager.getImei()).thenReturn(null);
+
+ setupTunnelBringup();
+
+ ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
+ ArgumentCaptor.forClass(IkeSessionParams.class);
+ verify(mMockIkeSessionCreator, atLeastOnce())
+ .createIkeSession(
+ eq(mMockContext),
+ ikeSessionParamsCaptor.capture(),
+ any(ChildSessionParams.class),
+ any(Executor.class),
+ any(IkeSessionCallback.class),
+ any(ChildSessionCallback.class));
+ IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
+ assertEquals(
+ ikeSessionParams.getIke3gppExtension().getIke3gppParams().getMobileDeviceIdentity(),
+ null);
+ }
+
+ @Test
+ public void testBringUpTunnelWithMobilityOptions() throws Exception {
+ doReturn(null)
+ .when(mMockIkeSessionCreator)
+ .createIkeSession(
+ eq(mMockContext),
+ any(IkeSessionParams.class),
+ any(ChildSessionParams.class),
+ any(Executor.class),
+ any(IkeSessionCallback.class),
+ any(ChildSessionCallback.class));
+
+ doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(TEST_APN_NAME));
+
+ boolean ret =
+ mEpdgTunnelManager.bringUpTunnel(
+ getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
+ mMockIwlanTunnelCallback);
+ assertTrue(ret);
+ mTestLooper.dispatchAll();
+
+ mEpdgTunnelManager.sendSelectionRequestComplete(
+ EXPECTED_EPDG_ADDRESSES, new IwlanError(IwlanError.NO_ERROR), 1);
+ mTestLooper.dispatchAll();
+
+ ArgumentCaptor<IkeSessionParams> ikeSessionParamsCaptor =
+ ArgumentCaptor.forClass(IkeSessionParams.class);
+ verify(mMockIkeSessionCreator, atLeastOnce())
+ .createIkeSession(
+ eq(mMockContext),
+ ikeSessionParamsCaptor.capture(),
+ any(ChildSessionParams.class),
+ any(Executor.class),
+ any(IkeSessionCallback.class),
+ any(ChildSessionCallback.class));
+ IkeSessionParams ikeSessionParams = ikeSessionParamsCaptor.getValue();
+ assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE));
+ assertTrue(ikeSessionParams.hasIkeOption(IkeSessionParams.IKE_OPTION_REKEY_MOBILITY));
+ }
+
@Test
public void testCloseTunnelWithNoTunnelForApn() throws Exception {
String testApnName = "www.xyz.com";
@@ -819,7 +991,7 @@
@Test
public void testHandleOnClosedWithEpdgAddressSelected_True() throws Exception {
String testApnName = "www.xyz.com";
- IwlanError error = new IwlanError(IwlanError.NO_ERROR);
+ IwlanError error = new IwlanError(IwlanError.NETWORK_FAILURE);
doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
mEpdgTunnelManager.putApnNameToTunnelConfig(
@@ -838,7 +1010,7 @@
@Test
public void testHandleOnClosedWithEpdgAddressSelected_False() throws Exception {
String testApnName = "www.xyz.com";
- IwlanError error = new IwlanError(IwlanError.NO_ERROR);
+ IwlanError error = new IwlanError(IwlanError.NETWORK_FAILURE);
doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
@@ -928,6 +1100,32 @@
}
@Test
+ public void testIkeSessionOnOpenedUpdatesPcscfAddrInTunnelConfig() throws Exception {
+ String testApnName = "ims";
+ IwlanError error = new IwlanError(IwlanError.NO_ERROR);
+
+ doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
+ mEpdgTunnelManager.putApnNameToTunnelConfig(
+ testApnName, mMockIkeSession, mMockIwlanTunnelCallback, null, 0);
+
+ List<InetAddress> ipList = new ArrayList<>();
+ ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
+ when(mMockIkeSessionConfiguration.getPcscfServers()).thenReturn(ipList);
+
+ PersistableBundle bundle = new PersistableBundle();
+ setupMockForGetConfig(bundle);
+
+ mEpdgTunnelManager
+ .getTmIkeSessionCallback(testApnName)
+ .onOpened(mMockIkeSessionConfiguration);
+ mTestLooper.dispatchAll();
+
+ EpdgTunnelManager.TunnelConfig testApnTunnelConfig =
+ mEpdgTunnelManager.getTunnelConfigForApn(testApnName);
+ assertEquals(testApnTunnelConfig.getPcscfAddrList(), ipList);
+ }
+
+ @Test
public void testSetIkeTrafficSelectorsIPv4() throws Exception {
testSetIkeTrafficSelectors(ApnSetting.PROTOCOL_IP, false);
}
@@ -1420,4 +1618,65 @@
assertTrue(ipv6ConfigRequestPresent);
assertTrue(ipv4ConfigRequestPresent);
}
+
+ @Test
+ public void testBringupTunnelFailWithInvalidSimState() throws Exception {
+ String testApnName = "www.xyz.com";
+ IwlanError error = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION);
+
+ doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
+ doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
+
+ PersistableBundle bundle = new PersistableBundle();
+ setupMockForGetConfig(bundle);
+
+ when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(DEFAULT_SLOT_INDEX))
+ .thenReturn(null);
+
+ boolean ret =
+ mEpdgTunnelManager.bringUpTunnel(
+ getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
+ mMockIwlanTunnelCallback);
+ assertTrue(ret);
+ mTestLooper.dispatchAll();
+
+ ArrayList<InetAddress> ipList = new ArrayList<>();
+ ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
+ mEpdgTunnelManager.sendSelectionRequestComplete(
+ ipList, new IwlanError(IwlanError.NO_ERROR), 1);
+ mTestLooper.dispatchAll();
+
+ verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
+ }
+
+ @Test
+ public void testBringupTunnelFailWithInvalidNai() throws Exception {
+ String testApnName = "www.xyz.com";
+ IwlanError error = new IwlanError(IwlanError.SIM_NOT_READY_EXCEPTION);
+
+ doReturn(0L).when(mEpdgTunnelManager).reportIwlanError(eq(testApnName), eq(error));
+ doReturn(true).when(mEpdgTunnelManager).canBringUpTunnel(eq(testApnName));
+
+ PersistableBundle bundle = new PersistableBundle();
+ setupMockForGetConfig(bundle);
+
+ when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(DEFAULT_SLOT_INDEX))
+ .thenReturn(mMockSubscriptionInfo)
+ .thenReturn(null);
+
+ boolean ret =
+ mEpdgTunnelManager.bringUpTunnel(
+ getBasicTunnelSetupRequest(TEST_APN_NAME, ApnSetting.PROTOCOL_IP),
+ mMockIwlanTunnelCallback);
+ assertTrue(ret);
+ mTestLooper.dispatchAll();
+
+ ArrayList<InetAddress> ipList = new ArrayList<>();
+ ipList.add(InetAddress.getByName(TEST_IP_ADDRESS));
+ mEpdgTunnelManager.sendSelectionRequestComplete(
+ ipList, new IwlanError(IwlanError.NO_ERROR), 1);
+ mTestLooper.dispatchAll();
+
+ verify(mMockIwlanTunnelCallback, times(1)).onClosed(eq(testApnName), eq(error));
+ }
}