• 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.network.CellConnectionStatus;
21 import android.hardware.radio.network.CellIdentityLte;
22 import android.hardware.radio.network.CellIdentityWcdma;
23 import android.hardware.radio.network.CellInfo;
24 import android.hardware.radio.network.CellInfoLte;
25 import android.hardware.radio.network.CellInfoRatSpecificInfo;
26 import android.hardware.radio.network.CellInfoWcdma;
27 import android.hardware.radio.network.LteSignalStrength;
28 import android.hardware.radio.network.OperatorInfo;
29 import android.hardware.radio.network.WcdmaSignalStrength;
30 import android.util.Log;
31 import android.util.Xml;
32 
33 import org.xmlpull.v1.XmlPullParser;
34 import org.xmlpull.v1.XmlPullParserException;
35 
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.util.ArrayList;
39 
40 public class MockNetworkConfig {
41     private static final String TAG = "MockNetworkConfig";
42 
43     private static final String MOCK_NETWORK_TAG = "MockNetwork";
44     private static final String MOCK_NETWORK_PROFILE_TAG = "MockNetworkProfile";
45     private static final String MOCK_CELL_PROPERTY_TAG = "MockCellProperty";
46     private static final String MOCK_CELL_IDENTITY_TAG = "MockCellIdentity";
47     private static final String MOCK_CELL_SIGNAL_STRENGTH_TAG = "MockCellSignalStrength";
48 
49     private final Context mContext;
50     private MockCellProperty mMockCellProperty;
51     private ArrayList<MockNetworkProfile> mMockNetworkProfiles =
52             new ArrayList<MockNetworkProfile>();
53 
54     private int mCarrierId;
55 
56     private static class MockCellProperty {
57         private String[] mEHPlmnList;
58         private String[] mAllowRoamingList;
59 
MockCellProperty(XmlPullParser parser)60         MockCellProperty(XmlPullParser parser) {
61             try {
62                 loadCellProperty(parser);
63             } catch (Exception e) {
64                 Log.e(TAG, "Failed to loadCellProperty: " + e);
65             }
66         }
67 
loadCellProperty(XmlPullParser parser)68         private void loadCellProperty(XmlPullParser parser)
69                 throws IOException, XmlPullParserException {
70             int outerDepth = parser.getDepth();
71             int type;
72 
73             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
74                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
75                 String parameter = parser.getName();
76                 if (parameter == null || type == XmlPullParser.END_TAG) {
77                     continue;
78                 }
79 
80                 switch (parameter) {
81                     case "EHPLMNLIST":
82                         mEHPlmnList = parser.nextText().replace(" ", "").split(",");
83                         break;
84                     case "AllowRoamingList":
85                         mAllowRoamingList = parser.nextText().replace(" ", "").split(",");
86                         break;
87                     default:
88                         Log.d(TAG, "Cell property: " + parameter + " Not Support");
89                         break;
90                 }
91             }
92         }
93 
getEHPlmnList()94         public String[] getEHPlmnList() {
95             return mEHPlmnList;
96         }
97 
getAllowRoamingList()98         public String[] getAllowRoamingList() {
99             return mAllowRoamingList;
100         }
101     }
102 
103     private static class MockNetworkProfile {
104         private int mId;
105         private String mRat;
106         private CellInfo mCell;
107 
MockNetworkProfile(XmlPullParser parser)108         MockNetworkProfile(XmlPullParser parser) {
109             mId = Integer.parseInt(parser.getAttributeValue(null, "id").trim());
110             Log.d(TAG, "Load: " + mId);
111             mRat = parser.getAttributeValue(null, "rat").trim();
112             String connectionStatus = parser.getAttributeValue(null, "connection");
113 
114             mCell = new CellInfo();
115             mCell.registered = false;
116 
117             if (connectionStatus != null && connectionStatus.trim().equals("primary")) {
118                 mCell.connectionStatus = CellConnectionStatus.PRIMARY_SERVING;
119             } else {
120                 mCell.connectionStatus = CellConnectionStatus.SECONDARY_SERVING;
121             }
122             mCell.ratSpecificInfo = new CellInfoRatSpecificInfo();
123 
124             loadNetworkCellParameters(parser);
125         }
126 
loadLteCellIdentity(XmlPullParser parser, CellInfoLte lte)127         private void loadLteCellIdentity(XmlPullParser parser, CellInfoLte lte)
128                 throws IOException, XmlPullParserException {
129             int outerDepth = parser.getDepth();
130             int type;
131 
132             lte.cellIdentityLte = new CellIdentityLte();
133             lte.cellIdentityLte.operatorNames = new OperatorInfo();
134             lte.cellIdentityLte.additionalPlmns = new String[0];
135             lte.cellIdentityLte.bands = new int[0];
136 
137             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
138                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
139                 String parameter = parser.getName();
140                 if (parameter == null || type == XmlPullParser.END_TAG) {
141                     continue;
142                 }
143 
144                 switch (parameter) {
145                     case "MCC":
146                         lte.cellIdentityLte.mcc = parser.nextText().trim();
147                         break;
148                     case "MNC":
149                         lte.cellIdentityLte.mnc = parser.nextText().trim();
150                         break;
151                     case "CI":
152                         lte.cellIdentityLte.ci = Integer.parseInt(parser.nextText().trim());
153                         break;
154                     case "PCI":
155                         lte.cellIdentityLte.pci = Integer.parseInt(parser.nextText().trim());
156                         break;
157                     case "TAC":
158                         lte.cellIdentityLte.tac = Integer.parseInt(parser.nextText().trim());
159                         break;
160                     case "EARFCN":
161                         lte.cellIdentityLte.earfcn = Integer.parseInt(parser.nextText().trim());
162                         break;
163                     case "BANDWIDTH":
164                         lte.cellIdentityLte.bandwidth = Integer.parseInt(parser.nextText().trim());
165                         break;
166                     case "OperatorInfo":
167                         // lte.cellIdentityLte.operatorNames = new OperatorInfo();
168                         break;
169                     case "AlphaLong":
170                         lte.cellIdentityLte.operatorNames.alphaLong = parser.nextText().trim();
171                         break;
172                     case "AlphaShort":
173                         lte.cellIdentityLte.operatorNames.alphaShort = parser.nextText().trim();
174                         break;
175                     case "OperatorNumeric":
176                         lte.cellIdentityLte.operatorNames.operatorNumeric =
177                                 parser.nextText().trim();
178                         break;
179                     default:
180                         Log.d(TAG, "LTE Cell Identity: " + parameter + " Not Support");
181                         break;
182                 }
183             }
184         }
185 
loadLteSignalStrength(XmlPullParser parser, CellInfoLte lte)186         private void loadLteSignalStrength(XmlPullParser parser, CellInfoLte lte)
187                 throws IOException, XmlPullParserException {
188             int outerDepth = parser.getDepth();
189             int type;
190 
191             lte.signalStrengthLte = new LteSignalStrength();
192             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
193                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
194                 String parameter = parser.getName();
195                 if (parameter == null || type == XmlPullParser.END_TAG) {
196                     continue;
197                 }
198 
199                 switch (parameter) {
200                     case "SignalStrength":
201                         lte.signalStrengthLte.signalStrength =
202                                 Integer.parseInt(parser.nextText().trim());
203                         break;
204                     case "RSRP":
205                         lte.signalStrengthLte.rsrp = Integer.parseInt(parser.nextText().trim());
206                         break;
207                     case "RSRQ":
208                         lte.signalStrengthLte.rsrq = Integer.parseInt(parser.nextText().trim());
209                         break;
210                     case "RSSNR":
211                         lte.signalStrengthLte.rssnr = Integer.parseInt(parser.nextText().trim());
212                         break;
213                     case "CQI":
214                         lte.signalStrengthLte.cqi = Integer.parseInt(parser.nextText().trim());
215                         break;
216                     case "TimingAdvance":
217                         lte.signalStrengthLte.timingAdvance =
218                                 Integer.parseInt(parser.nextText().trim());
219                         break;
220                     case "CqiTableIndex":
221                         lte.signalStrengthLte.cqiTableIndex =
222                                 Integer.parseInt(parser.nextText().trim());
223                         break;
224                     default:
225                         Log.d(TAG, "LTE Cell Signal: " + parameter + " Not Support");
226                         break;
227                 }
228             }
229         }
230 
loadLteCellInfo(XmlPullParser parser, CellInfoLte lte)231         private void loadLteCellInfo(XmlPullParser parser, CellInfoLte lte)
232                 throws IOException, XmlPullParserException {
233             int outerDepth = parser.getDepth();
234             int type;
235             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
236                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
237                 String name = parser.getName();
238                 if (name == null) {
239                     continue;
240                 }
241 
242                 if (MOCK_CELL_IDENTITY_TAG.equals(name)) {
243                     loadLteCellIdentity(parser, lte);
244                     Log.d(TAG, "LTE Cell ID: " + lte.cellIdentityLte.toString());
245                 } else if (MOCK_CELL_SIGNAL_STRENGTH_TAG.equals(name)) {
246                     loadLteSignalStrength(parser, lte);
247                     Log.d(TAG, "LTE Cell Signal: " + lte.signalStrengthLte.toString());
248                 }
249             }
250         }
251 
loadWcdmaCellIdentity(XmlPullParser parser, CellInfoWcdma wcdma)252         private void loadWcdmaCellIdentity(XmlPullParser parser, CellInfoWcdma wcdma)
253                 throws IOException, XmlPullParserException {
254             int outerDepth = parser.getDepth();
255             int type;
256 
257             wcdma.cellIdentityWcdma = new CellIdentityWcdma();
258             wcdma.cellIdentityWcdma.operatorNames = new OperatorInfo();
259             wcdma.cellIdentityWcdma.additionalPlmns = new String[0];
260 
261             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
262                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
263                 String parameter = parser.getName();
264                 if (parameter == null || type == XmlPullParser.END_TAG) {
265                     continue;
266                 }
267 
268                 switch (parameter) {
269                     case "MCC":
270                         wcdma.cellIdentityWcdma.mcc = parser.nextText().trim();
271                         break;
272                     case "MNC":
273                         wcdma.cellIdentityWcdma.mnc = parser.nextText().trim();
274                         break;
275                     case "LAC":
276                         wcdma.cellIdentityWcdma.lac = Integer.parseInt(parser.nextText().trim());
277                         break;
278                     case "CID":
279                         wcdma.cellIdentityWcdma.cid = Integer.parseInt(parser.nextText().trim());
280                         break;
281                     case "PSC":
282                         wcdma.cellIdentityWcdma.psc = Integer.parseInt(parser.nextText().trim());
283                         break;
284                     case "UARFCN":
285                         wcdma.cellIdentityWcdma.uarfcn = Integer.parseInt(parser.nextText().trim());
286                         break;
287                     case "OperatorInfo":
288                         // lte.cellIdentityLte.operatorNames = new OperatorInfo();
289                         break;
290                     case "AlphaLong":
291                         wcdma.cellIdentityWcdma.operatorNames.alphaLong = parser.nextText().trim();
292                         break;
293                     case "AlphaShort":
294                         wcdma.cellIdentityWcdma.operatorNames.alphaShort = parser.nextText().trim();
295                         break;
296                     case "OperatorNumeric":
297                         wcdma.cellIdentityWcdma.operatorNames.operatorNumeric =
298                                 parser.nextText().trim();
299                         break;
300                     default:
301                         Log.d(TAG, "WCDMA Cell Identity: " + parameter + " Not Support");
302                         break;
303                 }
304             }
305         }
306 
loadWcdmaSignalStrength(XmlPullParser parser, CellInfoWcdma wcdma)307         private void loadWcdmaSignalStrength(XmlPullParser parser, CellInfoWcdma wcdma)
308                 throws IOException, XmlPullParserException {
309             int outerDepth = parser.getDepth();
310             int type;
311 
312             wcdma.signalStrengthWcdma = new WcdmaSignalStrength();
313             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
314                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
315                 String parameter = parser.getName();
316                 if (parameter == null || type == XmlPullParser.END_TAG) {
317                     continue;
318                 }
319 
320                 switch (parameter) {
321                     case "SignalStrength":
322                         wcdma.signalStrengthWcdma.signalStrength =
323                                 Integer.parseInt(parser.nextText().trim());
324                         break;
325                     case "BitErrorRate":
326                         wcdma.signalStrengthWcdma.bitErrorRate =
327                                 Integer.parseInt(parser.nextText().trim());
328                         break;
329                     case "RSCP":
330                         wcdma.signalStrengthWcdma.rscp = Integer.parseInt(parser.nextText().trim());
331                         break;
332                     case "ECNO":
333                         wcdma.signalStrengthWcdma.ecno = Integer.parseInt(parser.nextText().trim());
334                         break;
335                     default:
336                         Log.d(TAG, "WCDMA Cell Signal: " + parameter + " Not Support");
337                         break;
338                 }
339             }
340         }
341 
loadWcdmaCellInfo(XmlPullParser parser, CellInfoWcdma wcdma)342         private void loadWcdmaCellInfo(XmlPullParser parser, CellInfoWcdma wcdma)
343                 throws IOException, XmlPullParserException {
344             int outerDepth = parser.getDepth();
345             int type;
346             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
347                     && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
348                 String name = parser.getName();
349                 if (name == null) {
350                     continue;
351                 }
352 
353                 if (MOCK_CELL_IDENTITY_TAG.equals(name)) {
354                     loadWcdmaCellIdentity(parser, wcdma);
355                     Log.d(TAG, "WCDMA Cell ID: " + wcdma.cellIdentityWcdma.toString());
356                 } else if (MOCK_CELL_SIGNAL_STRENGTH_TAG.equals(name)) {
357                     loadWcdmaSignalStrength(parser, wcdma);
358                     Log.d(TAG, "WCDMA Cell Signal: " + wcdma.signalStrengthWcdma.toString());
359                 }
360             }
361         }
362 
loadNetworkCellParameters(XmlPullParser parser)363         private void loadNetworkCellParameters(XmlPullParser parser) {
364             try {
365                 switch (mRat) {
366                     case "LTE":
367                         CellInfoLte lte = new CellInfoLte();
368                         loadLteCellInfo(parser, lte);
369                         mCell.ratSpecificInfo.setLte(lte);
370                         break;
371                     case "WCDMA":
372                         CellInfoWcdma wcdma = new CellInfoWcdma();
373                         loadWcdmaCellInfo(parser, wcdma);
374                         mCell.ratSpecificInfo.setWcdma(wcdma);
375                         break;
376                     default:
377                         Log.e(TAG, "RAT " + mRat + " Cell Parameter Not Support");
378                         break;
379                 }
380             } catch (Exception e) {
381                 Log.e(TAG, "Failed to loadNetworkCellParameters: " + e);
382             }
383         }
384 
getCell()385         public CellInfo getCell() {
386             return mCell;
387         }
388     }
389 
MockNetworkConfig(Context context)390     public MockNetworkConfig(Context context) {
391         mContext = context;
392     }
393 
readConfigFromXml(XmlPullParser parser)394     private void readConfigFromXml(XmlPullParser parser)
395             throws IOException, XmlPullParserException {
396         int type;
397         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
398             String name = parser.getName();
399             switch (type) {
400                 case XmlPullParser.START_TAG:
401                     if (MOCK_NETWORK_TAG.equals(name)) {
402                         mCarrierId =
403                                 Integer.parseInt(
404                                         parser.getAttributeValue(null, "carrierid").trim());
405                     } else if (MOCK_NETWORK_PROFILE_TAG.equals(name)) {
406                         mMockNetworkProfiles.add(new MockNetworkProfile(parser));
407                     } else if (MOCK_CELL_PROPERTY_TAG.equals(name)) {
408                         mMockCellProperty = new MockCellProperty(parser);
409                     } else {
410                         Log.e(TAG, "Type " + name + " Not Support.");
411                     }
412                     break;
413                 case XmlPullParser.END_TAG:
414                     break;
415             }
416         }
417     }
418 
getConfigFromAssets(String fileName)419     public void getConfigFromAssets(String fileName) {
420         try {
421             XmlPullParser parser = Xml.newPullParser();
422             InputStream input = mContext.getAssets().open(fileName);
423             parser.setInput(input, "utf-8");
424             readConfigFromXml(parser);
425             input.close();
426         } catch (Exception e) {
427             Log.e(TAG, "Failed to read config: " + e);
428         }
429     }
430 
getCarrierId()431     public int getCarrierId() {
432         return mCarrierId;
433     }
434 
getEHPlmnList()435     public String[] getEHPlmnList() {
436         return mMockCellProperty.getEHPlmnList();
437     }
438 
getAllowRoamingList()439     public String[] getAllowRoamingList() {
440         return mMockCellProperty.getAllowRoamingList();
441     }
442 
getCellNum()443     public int getCellNum() {
444         return mMockNetworkProfiles.size();
445     }
446 
getCellInfo(int index)447     public CellInfo getCellInfo(int index) {
448         if (index > getCellNum()) {
449             return null;
450         }
451         return mMockNetworkProfiles.get(index).getCell();
452     }
453 }
454