1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.iwlan.epdg;
18 
19 import static org.junit.Assert.*;
20 import static org.mockito.Mockito.*;
21 
22 import android.content.Context;
23 import android.net.Network;
24 import android.os.PersistableBundle;
25 import android.telephony.CarrierConfigManager;
26 import android.telephony.CellIdentityGsm;
27 import android.telephony.CellIdentityLte;
28 import android.telephony.CellIdentityNr;
29 import android.telephony.CellIdentityWcdma;
30 import android.telephony.CellInfo;
31 import android.telephony.CellInfoGsm;
32 import android.telephony.CellInfoLte;
33 import android.telephony.CellInfoNr;
34 import android.telephony.CellInfoWcdma;
35 import android.telephony.SubscriptionInfo;
36 import android.telephony.SubscriptionManager;
37 import android.telephony.TelephonyManager;
38 import android.util.Log;
39 
40 import com.google.android.iwlan.IwlanError;
41 
42 import org.junit.Before;
43 import org.junit.Rule;
44 import org.junit.Test;
45 import org.junit.runner.RunWith;
46 import org.junit.runners.JUnit4;
47 import org.mockito.Mock;
48 import org.mockito.junit.MockitoJUnit;
49 import org.mockito.junit.MockitoRule;
50 
51 import java.net.InetAddress;
52 import java.util.*;
53 import java.util.concurrent.CountDownLatch;
54 import java.util.concurrent.TimeUnit;
55 
56 @RunWith(JUnit4.class)
57 public class EpdgSelectorTest {
58     private static final String TAG = "EpdgSelectorTest";
59     private EpdgSelector mEpdgSelector;
60     public static final int DEFAULT_SLOT_INDEX = 0;
61 
62     private static final String TEST_IP_ADDRESS = "127.0.0.1";
63     private static final String TEST_IP_ADDRESS_1 = "127.0.0.2";
64     private static final String TEST_IP_ADDRESS_2 = "127.0.0.3";
65     private static final String TEST_IPV6_ADDRESS = "0000:0000:0000:0000:0000:0000:0000:0001";
66 
67     private static int testPcoIdIPv6 = 0xFF01;
68     private static int testPcoIdIPv4 = 0xFF02;
69 
70     private String testPcoString = "testPcoData";
71     private byte[] pcoData = testPcoString.getBytes();
72     private List<String> ehplmnList = new ArrayList<String>();
73 
74     @Rule public final MockitoRule mockito = MockitoJUnit.rule();
75 
76     @Mock private Context mMockContext;
77     @Mock private Network mMockNetwork;
78     @Mock private SubscriptionManager mMockSubscriptionManager;
79     @Mock private SubscriptionInfo mMockSubscriptionInfo;
80     @Mock private CarrierConfigManager mMockCarrierConfigManager;
81     @Mock private TelephonyManager mMockTelephonyManager;
82 
83     @Mock private CellInfoGsm mMockCellInfoGsm;
84     @Mock private CellIdentityGsm mMockCellIdentityGsm;
85     @Mock private CellInfoWcdma mMockCellInfoWcdma;
86     @Mock private CellIdentityWcdma mMockCellIdentityWcdma;
87     @Mock private CellInfoLte mMockCellInfoLte;
88     @Mock private CellIdentityLte mMockCellIdentityLte;
89     @Mock private CellInfoNr mMockCellInfoNr;
90     @Mock private CellIdentityNr mMockCellIdentityNr;
91 
92     private PersistableBundle mTestBundle;
93 
94     @Before
setUp()95     public void setUp() throws Exception {
96         mEpdgSelector = new EpdgSelector(mMockContext, DEFAULT_SLOT_INDEX);
97 
98         when(mMockContext.getSystemService(eq(SubscriptionManager.class)))
99                 .thenReturn(mMockSubscriptionManager);
100 
101         when(mMockSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(anyInt()))
102                 .thenReturn(mMockSubscriptionInfo);
103 
104         when(mMockSubscriptionInfo.getMccString()).thenReturn("311");
105 
106         when(mMockSubscriptionInfo.getMncString()).thenReturn("120");
107 
108         when(mMockContext.getSystemService(eq(TelephonyManager.class)))
109                 .thenReturn(mMockTelephonyManager);
110 
111         when(mMockTelephonyManager.createForSubscriptionId(anyInt()))
112                 .thenReturn(mMockTelephonyManager);
113 
114         ehplmnList.add("300120");
115         when(mMockTelephonyManager.getEquivalentHomePlmns()).thenReturn(ehplmnList);
116 
117         // Mock carrier configs with test bundle
118         mTestBundle = new PersistableBundle();
119         when(mMockContext.getSystemService(eq(CarrierConfigManager.class)))
120                 .thenReturn(mMockCarrierConfigManager);
121         when(mMockCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mTestBundle);
122     }
123 
124     @Test
testStaticMethodPass()125     public void testStaticMethodPass() throws Exception {
126         // Set Network.getAllByName mock
127         final String testStaticAddress = "epdg.epc.mnc088.mcc888.pub.3gppnetwork.org";
128         when(mMockNetwork.getAllByName(eq(testStaticAddress)))
129                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS)});
130 
131         // Set carrier config mock
132         mTestBundle.putIntArray(
133                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
134                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
135         mTestBundle.putString(
136                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
137 
138         ArrayList<InetAddress> testInetAddresses =
139                 getValidatedServerListWithDefaultParams(false /*isEmergency*/);
140 
141         InetAddress expectedAddress = InetAddress.getByName(TEST_IP_ADDRESS);
142 
143         assertEquals(testInetAddresses.size(), 1);
144         assertEquals(testInetAddresses.get(0), expectedAddress);
145     }
146 
147     @Test
testPlmnResolutionMethod()148     public void testPlmnResolutionMethod() throws Exception {
149         testPlmnResolutionMethod(false);
150     }
151 
152     @Test
testPlmnResolutionMethodForEmergency()153     public void testPlmnResolutionMethodForEmergency() throws Exception {
154         testPlmnResolutionMethod(true);
155     }
156 
157     @Test
testPlmnResolutionMethodWithNoPlmnInCarrierConfig()158     public void testPlmnResolutionMethodWithNoPlmnInCarrierConfig() throws Exception {
159         // setUp() fills default values for mcc-mnc
160         String expectedFqdn1 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
161         when(mMockNetwork.getAllByName(eq(expectedFqdn1)))
162                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS_1)});
163 
164         ArrayList<InetAddress> testInetAddresses =
165                 getValidatedServerListWithDefaultParams(false /*isEmergency*/);
166 
167         assertEquals(testInetAddresses.size(), 1);
168         assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IP_ADDRESS_1)));
169     }
170 
testPlmnResolutionMethod(boolean isEmergency)171     private void testPlmnResolutionMethod(boolean isEmergency) throws Exception {
172         String expectedFqdn1 =
173                 (isEmergency)
174                         ? "sos.epdg.epc.mnc480.mcc310.pub.3gppnetwork.org"
175                         : "epdg.epc.mnc480.mcc310.pub.3gppnetwork.org";
176         String expectedFqdn2 =
177                 (isEmergency)
178                         ? "sos.epdg.epc.mnc120.mcc300.pub.3gppnetwork.org"
179                         : "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
180         String expectedFqdn3 =
181                 (isEmergency)
182                         ? "sos.epdg.epc.mnc120.mcc311.pub.3gppnetwork.org"
183                         : "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
184 
185         mTestBundle.putIntArray(
186                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
187                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PLMN});
188         mTestBundle.putStringArray(
189                 CarrierConfigManager.Iwlan.KEY_MCC_MNCS_STRING_ARRAY,
190                 new String[] {"310-480", "300-120", "311-120"});
191 
192         when(mMockNetwork.getAllByName(eq(expectedFqdn1)))
193                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS_1)});
194         when(mMockNetwork.getAllByName(eq(expectedFqdn2)))
195                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS_2)});
196         when(mMockNetwork.getAllByName(eq(expectedFqdn3)))
197                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS)});
198 
199         ArrayList<InetAddress> testInetAddresses =
200                 getValidatedServerListWithDefaultParams(isEmergency);
201 
202         verify(mMockNetwork).getAllByName(expectedFqdn1);
203         verify(mMockNetwork).getAllByName(expectedFqdn2);
204         verify(mMockNetwork).getAllByName(expectedFqdn3);
205 
206         assertEquals(testInetAddresses.size(), 3);
207         assertEquals(testInetAddresses.get(0), InetAddress.getByName(TEST_IP_ADDRESS));
208         assertEquals(testInetAddresses.get(1), InetAddress.getByName(TEST_IP_ADDRESS_2));
209         assertEquals(testInetAddresses.get(2), InetAddress.getByName(TEST_IP_ADDRESS_1));
210     }
211 
212     @Test
testCarrierConfigStaticAddressList()213     public void testCarrierConfigStaticAddressList() throws Exception {
214         // Set Network.getAllByName mock
215         final String addr1 = "epdg.epc.mnc480.mcc310.pub.3gppnetwork.org";
216         final String addr2 = "epdg.epc.mnc120.mcc300.pub.3gppnetwork.org";
217         final String addr3 = "epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
218         final String testStaticAddress = addr1 + "," + addr2 + "," + addr3;
219         when(mMockNetwork.getAllByName(eq(addr1)))
220                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS_1)});
221         when(mMockNetwork.getAllByName(eq(addr2)))
222                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS_2)});
223         when(mMockNetwork.getAllByName(eq(addr3)))
224                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS)});
225 
226         // Set carrier config mock
227         mTestBundle.putIntArray(
228                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
229                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_STATIC});
230         mTestBundle.putString(
231                 CarrierConfigManager.Iwlan.KEY_EPDG_STATIC_ADDRESS_STRING, testStaticAddress);
232 
233         ArrayList<InetAddress> testInetAddresses =
234                 getValidatedServerListWithDefaultParams(false /*isEmergency*/);
235 
236         assertEquals(testInetAddresses.size(), 3);
237         assertEquals(testInetAddresses.get(0), InetAddress.getByName(TEST_IP_ADDRESS_1));
238         assertEquals(testInetAddresses.get(1), InetAddress.getByName(TEST_IP_ADDRESS_2));
239         assertEquals(testInetAddresses.get(2), InetAddress.getByName(TEST_IP_ADDRESS));
240     }
241 
getValidatedServerListWithDefaultParams(boolean isEmergency)242     private ArrayList<InetAddress> getValidatedServerListWithDefaultParams(boolean isEmergency)
243             throws Exception {
244         ArrayList<InetAddress> testInetAddresses = new ArrayList<InetAddress>();
245         final CountDownLatch latch = new CountDownLatch(1);
246         IwlanError ret =
247                 mEpdgSelector.getValidatedServerList(
248                         1234,
249                         EpdgSelector.PROTO_FILTER_IPV4V6,
250                         false /*isRoaming*/,
251                         isEmergency,
252                         mMockNetwork,
253                         new EpdgSelector.EpdgSelectorCallback() {
254                             @Override
255                             public void onServerListChanged(
256                                     int transactionId, ArrayList<InetAddress> validIPList) {
257                                 assertEquals(transactionId, 1234);
258 
259                                 for (InetAddress mInetAddress : validIPList) {
260                                     testInetAddresses.add(mInetAddress);
261                                 }
262                                 Log.d(TAG, "onServerListChanged received");
263                                 latch.countDown();
264                             }
265 
266                             @Override
267                             public void onError(int transactionId, IwlanError epdgSelectorError) {
268                                 Log.d(TAG, "onError received");
269                                 latch.countDown();
270                             }
271                         });
272 
273         assertEquals(ret.getErrorType(), IwlanError.NO_ERROR);
274         latch.await(1, TimeUnit.SECONDS);
275         return testInetAddresses;
276     }
277 
278     @Test
testSetPcoData()279     public void testSetPcoData() throws Exception {
280         addTestPcoIdsToTestConfigBundle();
281 
282         boolean retIPv6 = mEpdgSelector.setPcoData(testPcoIdIPv6, pcoData);
283         boolean retIPv4 = mEpdgSelector.setPcoData(testPcoIdIPv4, pcoData);
284         boolean retIncorrect = mEpdgSelector.setPcoData(0xFF00, pcoData);
285 
286         assertTrue(retIPv6);
287         assertTrue(retIPv4);
288         assertFalse(retIncorrect);
289     }
290 
291     @Test
testPcoResolutionMethod()292     public void testPcoResolutionMethod() throws Exception {
293         mTestBundle.putIntArray(
294                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
295                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_PCO});
296         addTestPcoIdsToTestConfigBundle();
297 
298         mEpdgSelector.clearPcoData();
299         boolean retIPv6 =
300                 mEpdgSelector.setPcoData(
301                         testPcoIdIPv6, InetAddress.getByName(TEST_IPV6_ADDRESS).getAddress());
302         boolean retIPv4 =
303                 mEpdgSelector.setPcoData(
304                         testPcoIdIPv4, InetAddress.getByName(TEST_IP_ADDRESS).getAddress());
305 
306         ArrayList<InetAddress> testInetAddresses =
307                 getValidatedServerListWithDefaultParams(false /* isEmergency */);
308 
309         assertEquals(testInetAddresses.size(), 2);
310         assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IP_ADDRESS)));
311         assertTrue(testInetAddresses.contains(InetAddress.getByName(TEST_IPV6_ADDRESS)));
312     }
313 
addTestPcoIdsToTestConfigBundle()314     private void addTestPcoIdsToTestConfigBundle() {
315         mTestBundle.putInt(CarrierConfigManager.Iwlan.KEY_EPDG_PCO_ID_IPV6_INT, testPcoIdIPv6);
316         mTestBundle.putInt(CarrierConfigManager.Iwlan.KEY_EPDG_PCO_ID_IPV4_INT, testPcoIdIPv4);
317     }
318 
319     @Test
testCellularResolutionMethod()320     public void testCellularResolutionMethod() throws Exception {
321         testCellularResolutionMethod(false);
322     }
323 
324     @Test
testCellularResolutionMethodForEmergency()325     public void testCellularResolutionMethodForEmergency() throws Exception {
326         testCellularResolutionMethod(true);
327     }
328 
testCellularResolutionMethod(boolean isEmergency)329     private void testCellularResolutionMethod(boolean isEmergency) throws Exception {
330         int testMcc = 311;
331         int testMnc = 120;
332         String testMccString = "311";
333         String testMncString = "120";
334         int testLac = 65484;
335         int testTac = 65484;
336         int testNrTac = 16764074;
337         String fqdn1_emergency = "lacffcc.sos.epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
338         String fqdn1 = "lacffcc.epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
339         String fqdn2_emergency =
340                 "tac-lbcc.tac-hbff.tac.sos.epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
341         String fqdn2 = "tac-lbcc.tac-hbff.tac.epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
342         String fqdn3_emergency =
343                 "tac-lbaa.tac-mbcc.tac-hbff.5gstac.sos.epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
344         String fqdn3 =
345                 "tac-lbaa.tac-mbcc.tac-hbff.5gstac.epdg.epc.mnc120.mcc311.pub.3gppnetwork.org";
346         List<CellInfo> fakeCellInfoArray = new ArrayList<CellInfo>();
347 
348         mTestBundle.putIntArray(
349                 CarrierConfigManager.Iwlan.KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
350                 new int[] {CarrierConfigManager.Iwlan.EPDG_ADDRESS_CELLULAR_LOC});
351 
352         // Set cell info mock
353         fakeCellInfoArray.add(mMockCellInfoGsm);
354         when(mMockCellInfoGsm.isRegistered()).thenReturn(true);
355         when(mMockCellInfoGsm.getCellIdentity()).thenReturn(mMockCellIdentityGsm);
356         when(mMockCellIdentityGsm.getMcc()).thenReturn(testMcc);
357         when(mMockCellIdentityGsm.getMnc()).thenReturn(testMnc);
358         when(mMockCellIdentityGsm.getLac()).thenReturn(testLac);
359 
360         fakeCellInfoArray.add(mMockCellInfoWcdma);
361         when(mMockCellInfoWcdma.isRegistered()).thenReturn(true);
362         when(mMockCellInfoWcdma.getCellIdentity()).thenReturn(mMockCellIdentityWcdma);
363         when(mMockCellIdentityWcdma.getMcc()).thenReturn(testMcc);
364         when(mMockCellIdentityWcdma.getMnc()).thenReturn(testMnc);
365         when(mMockCellIdentityWcdma.getLac()).thenReturn(testLac);
366 
367         fakeCellInfoArray.add(mMockCellInfoLte);
368         when(mMockCellInfoLte.isRegistered()).thenReturn(true);
369         when(mMockCellInfoLte.getCellIdentity()).thenReturn(mMockCellIdentityLte);
370         when(mMockCellIdentityLte.getMcc()).thenReturn(testMcc);
371         when(mMockCellIdentityLte.getMnc()).thenReturn(testMnc);
372         when(mMockCellIdentityLte.getTac()).thenReturn(testTac);
373 
374         fakeCellInfoArray.add(mMockCellInfoNr);
375         when(mMockCellInfoNr.isRegistered()).thenReturn(true);
376         when(mMockCellInfoNr.getCellIdentity()).thenReturn(mMockCellIdentityNr);
377         when(mMockCellIdentityNr.getMccString()).thenReturn(testMccString);
378         when(mMockCellIdentityNr.getMncString()).thenReturn(testMncString);
379         when(mMockCellIdentityNr.getTac()).thenReturn(testNrTac);
380 
381         when(mMockTelephonyManager.getAllCellInfo()).thenReturn(fakeCellInfoArray);
382 
383         String expectedFqdn1 = (isEmergency) ? fqdn1_emergency : fqdn1;
384         String expectedFqdn2 = (isEmergency) ? fqdn2_emergency : fqdn2;
385         String expectedFqdn3 = (isEmergency) ? fqdn3_emergency : fqdn3;
386 
387         when(mMockNetwork.getAllByName(eq(expectedFqdn1)))
388                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS)});
389         when(mMockNetwork.getAllByName(eq(expectedFqdn2)))
390                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS_1)});
391         when(mMockNetwork.getAllByName(eq(expectedFqdn3)))
392                 .thenReturn(new InetAddress[] {InetAddress.getByName(TEST_IP_ADDRESS_2)});
393 
394         ArrayList<InetAddress> testInetAddresses =
395                 getValidatedServerListWithDefaultParams(isEmergency);
396 
397         verify(mMockNetwork, times(2)).getAllByName(expectedFqdn1);
398         verify(mMockNetwork).getAllByName(expectedFqdn2);
399         verify(mMockNetwork).getAllByName(expectedFqdn3);
400 
401         assertEquals(testInetAddresses.size(), 3);
402         assertEquals(testInetAddresses.get(0), InetAddress.getByName(TEST_IP_ADDRESS));
403         assertEquals(testInetAddresses.get(1), InetAddress.getByName(TEST_IP_ADDRESS_1));
404         assertEquals(testInetAddresses.get(2), InetAddress.getByName(TEST_IP_ADDRESS_2));
405     }
406 }
407