• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 android.telephony.mockmodem;
18 
19 import android.content.Context;
20 import android.hardware.radio.RadioError;
21 import android.hardware.radio.data.DataCallFailCause;
22 import android.hardware.radio.data.DataProfileInfo;
23 import android.hardware.radio.data.LinkAddress;
24 import android.hardware.radio.data.PdpProtocolType;
25 import android.hardware.radio.data.Qos;
26 import android.hardware.radio.data.QosSession;
27 import android.hardware.radio.data.SetupDataCallResult;
28 import android.hardware.radio.data.SliceInfo;
29 import android.hardware.radio.data.TrafficDescriptor;
30 import android.telephony.cts.util.TelephonyUtils;
31 import android.util.Log;
32 
33 import androidx.test.platform.app.InstrumentationRegistry;
34 
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.Iterator;
38 import java.util.List;
39 
40 public class MockDataService {
41     private static final String TAG = "MockDataService";
42     private Context mContext;
43 
44     // Data Profile
45     List<DataProfileInfo> mDataProfileInfo = new ArrayList<>();
46     DataProfileInfo mInitialAttachProfile;
47     int mInitialAttachProfileId;
48 
49     // setup data call
50     public static final int APN_TYPE_IMS = 0;
51     public static final int APN_TYPE_DEFAULT = 1;
52     public static final int PHONE0 = 0;
53     public static final int PHONE1 = 1;
54 
55     SetupDataCallResult mSetupDataCallResultIms = new SetupDataCallResult();
56     SetupDataCallResult mSetupDataCallResultDefault = new SetupDataCallResult();
57 
58     // data call list
59     static List<SetupDataCallResult> sDataCallLists = new ArrayList<>();
60 
61     // Supported capability in physical layer
62     static List<String> sSupportedCapabilities = new ArrayList<>();
63 
64     /* Mock Data Config XML TAG definition */
65     private static final String MOCK_DATA_CONFIG_TAG = "MockDataConfig";
66     private static final String MOCK_CUTTLEFISH_CONFIG_TAG = "CuttlefishConfig";
67     private static final String MOCK_CUTTLEFISH_TYPE = "Cuttlefish";
68     private static final String MOCK_INTERFACE_NAME_TAG = "InterfaceName";
69     private static final String MOCK_IP_ADDRESS_TAG = "IpAddress";
70     private static final String MOCK_DNS_ADDRESS_TAG = "DnsAddress";
71     private static final String MOCK_GATEWAY_ADDRESS_TAG = "GatewayAddress";
72     private static final String MOCK_MTU_V4_TAG = "MtuV4";
73     private static String sQueryTelephonyDebugServiceCommand =
74             "dumpsys activity service com.android.phone.TelephonyDebugService";
75 
76     // Setup data call result parameteres
77     int mDataCallFailCause;
78     int mSuggestedRetryTime;
79     int mImsCid;
80     int mImsType;
81     String mImsIfname;
82     String mImsAddress;
83     String[] mImsGateways;
84     String[] mImsPcscf;
85     int mImsMtuV4;
86     int mImsMtuV6;
87     int mInternetCid;
88     int mInternetType;
89     String mInternetIfname;
90     String mInternetAddress;
91     String[] mInternetDnses;
92     String[] mInternetGateways;
93     int mInternetMtuV4;
94     int mInternetMtuV6;
95     int mAddressProperties;
96     long mLaDeprecationTime;
97     long mLaExpirationTime;
98     Qos mDefaultQos;
99     QosSession[] mQosSessions;
100     byte mHandoverFailureMode;
101     int mPduSessionId;
102     SliceInfo mSliceInfo;
103     TrafficDescriptor[] mTrafficDescriptors;
104     private final Object mDataCallListLock = new Object();
105     LinkAddress[] mImsLinkAddress;
106     LinkAddress[] mDefaultLinkAddress;
107     int mPhoneId;
108 
MockDataService(Context context, int instanceId)109     public MockDataService(Context context, int instanceId) {
110         mContext = context;
111         mPhoneId = instanceId;
112         initializeParameter();
113 
114         Log.d(TAG, "MockDataService(): enter");
115         try {
116             setDataCallListFromNetworkAgent();
117         } catch (Exception e) {
118             Log.e(TAG, "Exception error: " + e);
119         }
120         Log.d(TAG, "MockDataService(): initialized");
121     }
122 
setDataCallListFromNetworkAgent()123     private void setDataCallListFromNetworkAgent() throws Exception {
124         Log.d(TAG, "setDataCallListFromNetworkAgent(): enter");
125         String result =
126                 TelephonyUtils.executeShellCommand(
127                         InstrumentationRegistry.getInstrumentation(),
128                         sQueryTelephonyDebugServiceCommand);
129         Log.d(TAG, "setDataCallListFromNetworkAgent(): query finished");
130         setBridgeTheDataConnection(result);
131         Log.d(TAG, "setDataCallListFromNetworkAgent(): exit");
132     }
133 
134     /* Default value definition */
initializeParameter()135     private void initializeParameter() {
136         this.mDataCallFailCause = DataCallFailCause.NONE;
137         this.mSuggestedRetryTime = -1;
138 
139         this.mImsType = PdpProtocolType.IP;
140         this.mImsIfname = "mock_network0";
141         this.mImsAddress = "192.168.66.2";
142         this.mImsGateways = new String[] {"0.0.0.0"};
143         this.mImsPcscf = new String[] {"192.168.66.100", "192.168.66.101"};
144         this.mImsMtuV4 = 1280;
145         this.mImsMtuV6 = 0;
146         this.mImsLinkAddress = new LinkAddress[1];
147 
148         this.mInternetType = PdpProtocolType.IP;
149         this.mInternetIfname = "mock_network1";
150         this.mInternetAddress = "192.168.66.1";
151         this.mInternetDnses = new String[] {"8.8.8.8"};
152         this.mInternetGateways = new String[] {"0.0.0.0"};
153         this.mInternetMtuV4 = 1280;
154         this.mInternetMtuV6 = 0;
155         this.mDefaultLinkAddress = new LinkAddress[1];
156 
157         this.mAddressProperties = LinkAddress.ADDRESS_PROPERTY_NONE;
158         this.mLaDeprecationTime = 0x7FFFFFFF;
159         this.mLaExpirationTime = 0x7FFFFFFF;
160 
161         this.mDefaultQos = new Qos();
162         this.mQosSessions = new QosSession[0];
163         this.mHandoverFailureMode =
164                 SetupDataCallResult.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER;
165         this.mPduSessionId = 0;
166         this.mSliceInfo = null;
167         this.mTrafficDescriptors = new TrafficDescriptor[0];
168     }
169 
setDataProfileInfo(DataProfileInfo[] dataProfilesInfo)170     public int setDataProfileInfo(DataProfileInfo[] dataProfilesInfo) {
171         int result = RadioError.NONE;
172         if (dataProfilesInfo != null) {
173             mDataProfileInfo.clear();
174             for (DataProfileInfo dp : dataProfilesInfo) {
175                 mDataProfileInfo.add(dp);
176                 Log.d(TAG, "setDataProfileInfo: profileId=" + dp.profileId + ", " + dp.apn);
177             }
178             return result;
179         }
180         return RadioError.INVALID_ARGUMENTS;
181     }
182 
setInitialAttachProfile(DataProfileInfo dataProfileInfo)183     public int setInitialAttachProfile(DataProfileInfo dataProfileInfo) {
184         int result = RadioError.NONE;
185         if (dataProfileInfo != null) {
186             Log.d(TAG, "setInitialAttachProfile: profileId=" + dataProfileInfo.profileId);
187             mInitialAttachProfile = dataProfileInfo;
188             mInitialAttachProfileId = dataProfileInfo.profileId;
189             return result;
190         }
191         return RadioError.INVALID_ARGUMENTS;
192     }
193 
setupDataCall(int apnType)194     SetupDataCallResult setupDataCall(int apnType) {
195         checkExistDataCall(apnType);
196 
197         SetupDataCallResult dc = new SetupDataCallResult();
198         dc.cause = this.mDataCallFailCause;
199         dc.suggestedRetryTime = this.mSuggestedRetryTime;
200 
201         dc.active = SetupDataCallResult.DATA_CONNECTION_STATUS_ACTIVE;
202         LinkAddress[] arrayLinkAddress = new LinkAddress[1];
203         LinkAddress linkAddress = new LinkAddress();
204 
205         switch (apnType) {
206             case APN_TYPE_IMS:
207                 dc.cid = this.mImsCid;
208                 dc.type = this.mImsType;
209                 dc.ifname = this.mImsIfname;
210                 linkAddress.address = this.mImsAddress;
211                 linkAddress.addressProperties = this.mAddressProperties;
212                 linkAddress.deprecationTime = this.mLaDeprecationTime;
213                 linkAddress.expirationTime = this.mLaExpirationTime;
214                 arrayLinkAddress[0] = linkAddress;
215                 dc.addresses = this.mImsLinkAddress;
216                 dc.gateways = this.mImsGateways;
217                 dc.pcscf = this.mImsPcscf;
218                 dc.mtuV4 = this.mImsMtuV4;
219                 dc.mtuV6 = this.mImsMtuV6;
220                 break;
221             case APN_TYPE_DEFAULT:
222                 dc.cid = this.mInternetCid;
223                 dc.type = this.mInternetType;
224                 dc.ifname = this.mInternetIfname;
225                 linkAddress.address = this.mInternetAddress;
226                 linkAddress.addressProperties = this.mAddressProperties;
227                 linkAddress.deprecationTime = this.mLaDeprecationTime;
228                 linkAddress.expirationTime = this.mLaExpirationTime;
229                 arrayLinkAddress[0] = linkAddress;
230                 dc.addresses = this.mDefaultLinkAddress;
231                 dc.dnses = this.mInternetDnses;
232                 dc.gateways = this.mInternetGateways;
233                 dc.mtuV4 = this.mInternetMtuV4;
234                 dc.mtuV6 = this.mInternetMtuV6;
235                 break;
236             default:
237                 Log.d(TAG, "Unexpected APN type: " + apnType);
238                 return new SetupDataCallResult();
239         }
240         dc.defaultQos = this.mDefaultQos;
241         dc.qosSessions = this.mQosSessions;
242         dc.handoverFailureMode = this.mHandoverFailureMode;
243         dc.pduSessionId = this.mPduSessionId;
244         dc.sliceInfo = this.mSliceInfo;
245         dc.trafficDescriptors = this.mTrafficDescriptors;
246         synchronized (mDataCallListLock) {
247             sDataCallLists.add(dc);
248         }
249         return dc;
250     }
251 
252     /**
253      * Get current data call list
254      *
255      * @return The SetupDataCallResult array list.
256      */
getDataCallList()257     List<SetupDataCallResult> getDataCallList() {
258         List<SetupDataCallResult> dataCallLists;
259         synchronized (mDataCallListLock) {
260             dataCallLists = sDataCallLists;
261         }
262         return dataCallLists;
263     }
264 
deactivateDataCall(int cid, int reason)265     void deactivateDataCall(int cid, int reason) {
266         synchronized (mDataCallListLock) {
267             Iterator<SetupDataCallResult> it = sDataCallLists.iterator();
268             while (it.hasNext()) {
269                 SetupDataCallResult dc = it.next();
270                 if (dc.cid == cid) {
271                     it.remove();
272                 }
273             }
274         }
275     }
276 
checkExistDataCall(int apnType)277     void checkExistDataCall(int apnType) {
278         synchronized (mDataCallListLock) {
279             int cid = (apnType == APN_TYPE_IMS) ? mImsCid : mInternetCid;
280             Iterator<SetupDataCallResult> it = sDataCallLists.iterator();
281             while (it.hasNext()) {
282                 SetupDataCallResult dc = it.next();
283                 if (dc.cid == cid) {
284                     it.remove();
285                 }
286             }
287         }
288     }
289 
convertToMtuV4(String mtuv4)290     private int convertToMtuV4(String mtuv4) {
291         int value = 0;
292         try {
293             value = Integer.parseInt(mtuv4);
294         } catch (NumberFormatException ex) {
295             Log.e(TAG, "Exception error: " + ex);
296         }
297         return value;
298     }
299 
getInterfaceName(String string)300     private String getInterfaceName(String string) {
301         String interfaceName = "";
302         try {
303             interfaceName = string.split("InterfaceName: ")[1].split(" LinkAddresses")[0];
304             Log.d(TAG, "getInterfaceName: " + interfaceName);
305         } catch (Exception e) {
306             Log.e(TAG, "Exception error: " + e);
307         }
308         return interfaceName;
309     }
310 
getIpAddress(String string)311     private LinkAddress[] getIpAddress(String string) {
312         String[] ipaddress = new String[] {};
313         LinkAddress[] arrayLinkAddress = new LinkAddress[0];
314         try {
315             ipaddress =
316                     string.split("LinkAddresses: \\[ ")[1].split(" ] DnsAddresses")[0].split(",");
317             arrayLinkAddress = new LinkAddress[ipaddress.length];
318             for (int idx = 0; idx < ipaddress.length; idx++) {
319                 if (ipaddress[idx].equals("LinkAddresses: [ ]")) {
320                     throw new Exception("Not valid ip address");
321                 }
322                 LinkAddress linkAddress = new LinkAddress();
323                 linkAddress.address = ipaddress[idx];
324                 linkAddress.addressProperties = this.mAddressProperties;
325                 linkAddress.deprecationTime = this.mLaDeprecationTime;
326                 linkAddress.expirationTime = this.mLaExpirationTime;
327                 arrayLinkAddress[idx] = linkAddress;
328                 Log.d(TAG, "getIpAddress:" + linkAddress.address);
329             }
330         } catch (Exception e) {
331             Log.e(TAG, "Exception error: " + e);
332         }
333         return arrayLinkAddress;
334     }
335 
getDnses(String string)336     private String[] getDnses(String string) {
337         String[] dnses = new String[] {};
338         try {
339             dnses =
340                     string.split("DnsAddresses: \\[ ")[1]
341                             .split(" ] Domains:")[0]
342                             .replace("/", "")
343                             .split(",");
344             Log.d(TAG, "getDnses: " + Arrays.toString(dnses));
345         } catch (Exception e) {
346             Log.e(TAG, "Exception error: " + e);
347         }
348         return dnses;
349     }
350 
getGateways(String string)351     private String[] getGateways(String string) {
352         ArrayList<String> gateways = new ArrayList<String>();
353         try {
354             gateways.add(
355                     string.split("Routes: \\[ ")[1]
356                             .split("-> ")[1]
357                             .split(" ")[0]);
358             Log.d(TAG, "getGateways: " + gateways);
359         } catch (Exception e) {
360             Log.e(TAG, "Exception error: " + e);
361         }
362         return gateways.toArray(new String[gateways.size()]);
363     }
364 
getMtu(String string)365     private int getMtu(String string) {
366         String mtu = "";
367         try {
368             mtu = string.split(" MTU: ")[1].split(" TcpBufferSizes:")[0];
369             Log.d(TAG, "getMtu: " + mtu);
370         } catch (Exception e) {
371             Log.e(TAG, "Exception error: " + e);
372         }
373         return Integer.valueOf(mtu);
374     }
375 
getPcscf(String string)376     private String[] getPcscf(String string) {
377         String[] pcscf = new String[] {};
378         try {
379             pcscf =
380                     string.split(" PcscfAddresses: \\[ ")[1]
381                             .split(" ] Domains:")[0]
382                             .replace("/", "")
383                             .split(",");
384             Log.d(TAG, "getPcscf: " + Arrays.toString(pcscf));
385         } catch (Exception e) {
386             Log.e(TAG, "Exception error: " + e);
387         }
388         return pcscf;
389     }
390 
getCapabilities(String string)391     private String getCapabilities(String string) {
392         String capabilities = "";
393         try {
394             capabilities = string.trim().split("Capabilities:")[1].split("LinkUpBandwidth")[0];
395             Log.d(TAG, "getCapabilities: " + capabilities);
396         } catch (Exception e) {
397             Log.e(TAG, "getCapabilities(): Exception error: " + e);
398         }
399         return capabilities;
400     }
401 
getCid(String string)402     private int getCid(String string) {
403         int cid = 0;
404         try {
405             String strCid = string.split("WWAN cid=")[1].split("WLAN cid")[0].trim();
406             cid = Integer.parseInt(strCid);
407             Log.d(TAG, "getCid: " + strCid);
408         } catch (Exception e) {
409             Log.e(TAG, "getCid(): Exception error: " + e);
410         }
411         return cid;
412     }
413 
setBridgeTheDataConnection(String string)414     public synchronized void setBridgeTheDataConnection(String string) {
415         try {
416             String[] lines = new String[] {};
417             String line =
418                     string.split("DataNetworkController-" + mPhoneId)[1]
419                             .split("All telephony network requests:")[0];
420             if (line.contains("curState=ConnectedState")) {
421                 lines = line.split(("curState=ConnectedState"));
422             }
423             for (String str : lines) {
424                 String capabilities = getCapabilities(str);
425                 if (capabilities.contains("INTERNET")) {
426                     Log.d(TAG, "[internet]:" + str);
427                     sSupportedCapabilities.add("internet");
428                     this.mInternetCid = getCid(str);
429                     this.mInternetIfname = getInterfaceName(str);
430                     this.mDefaultLinkAddress = getIpAddress(str);
431                     this.mInternetDnses = getDnses(str);
432                     this.mInternetGateways = getGateways(str);
433                     this.mInternetMtuV4 = getMtu(str);
434                     this.mInternetMtuV6 = getMtu(str);
435                 } else if (capabilities.contains("IMS")) {
436                     Log.d(TAG, "[ims]:" + str);
437                     sSupportedCapabilities.add("ims");
438                     this.mImsCid = getCid(str);
439                     this.mImsIfname = getInterfaceName(str);
440                     this.mImsLinkAddress = getIpAddress(str);
441                     this.mImsGateways = getGateways(str);
442                     this.mImsPcscf = getPcscf(str);
443                     this.mImsMtuV4 = getMtu(str);
444                     this.mImsMtuV6 = getMtu(str);
445                 }
446             }
447         } catch (Exception e) {
448             Log.e(TAG, "Exception error: [No NetworkAgentInfo]" + e);
449         }
450     }
451 
isSupportedCapability(String capability)452     public synchronized boolean isSupportedCapability(String capability) {
453         for (String cap : sSupportedCapabilities) {
454             Log.d(TAG, "Supported Capability:" + cap + ", Requested Capability:" + capability);
455             if (cap.contains(capability)) {
456                 return true;
457             }
458         }
459         return false;
460     }
461 
setDataCallFailCause(int failcause)462     public synchronized void setDataCallFailCause(int failcause) {
463         this.mDataCallFailCause = failcause;
464     }
465 
setSuggestedRetryTime(int retrytime)466     public synchronized void setSuggestedRetryTime(int retrytime) {
467         this.mSuggestedRetryTime = retrytime;
468     }
469 
setImsMtuV4(int mtusize)470     public synchronized void setImsMtuV4(int mtusize) {
471         this.mImsMtuV4 = mtusize;
472     }
473 
setImsMtuV6(int mtusize)474     public synchronized void setImsMtuV6(int mtusize) {
475         this.mImsMtuV6 = mtusize;
476     }
477 
setInternetMtuV4(int mtusize)478     public synchronized void setInternetMtuV4(int mtusize) {
479         this.mInternetMtuV4 = mtusize;
480     }
481 
setInternetMtuV6(int mtusize)482     public synchronized void setInternetMtuV6(int mtusize) {
483         this.mInternetMtuV6 = mtusize;
484     }
485 }
486