• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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.android.internal.telephony;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.hardware.radio.V1_0.RegState;
22 import android.hardware.radio.V1_4.DataRegStateResult.VopsInfo.hidl_discriminator;
23 import android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo;
24 import android.os.AsyncResult;
25 import android.os.Handler;
26 import android.os.Looper;
27 import android.os.Message;
28 import android.telephony.AccessNetworkConstants;
29 import android.telephony.AccessNetworkConstants.AccessNetworkType;
30 import android.telephony.AnomalyReporter;
31 import android.telephony.CellIdentity;
32 import android.telephony.CellIdentityCdma;
33 import android.telephony.CellIdentityGsm;
34 import android.telephony.CellIdentityLte;
35 import android.telephony.CellIdentityNr;
36 import android.telephony.CellIdentityTdscdma;
37 import android.telephony.CellIdentityWcdma;
38 import android.telephony.LteVopsSupportInfo;
39 import android.telephony.NetworkRegistrationInfo;
40 import android.telephony.NetworkService;
41 import android.telephony.NetworkServiceCallback;
42 import android.telephony.NrVopsSupportInfo;
43 import android.telephony.ServiceState;
44 import android.telephony.SubscriptionManager;
45 import android.telephony.TelephonyManager;
46 import android.telephony.VopsSupportInfo;
47 import android.text.TextUtils;
48 import android.util.ArrayMap;
49 
50 import com.android.internal.annotations.VisibleForTesting;
51 import com.android.telephony.Rlog;
52 
53 import java.util.ArrayList;
54 import java.util.Arrays;
55 import java.util.HashMap;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.UUID;
59 
60 /**
61  * Implementation of network services for Cellular. It's a service that handles network requests
62  * for Cellular. It passes the requests to inner CellularNetworkServiceProvider which has a
63  * handler thread for each slot.
64  */
65 public class CellularNetworkService extends NetworkService {
66     private static final boolean DBG = false;
67 
68     private static final String TAG = CellularNetworkService.class.getSimpleName();
69 
70     private static final int GET_CS_REGISTRATION_STATE_DONE = 1;
71     private static final int GET_PS_REGISTRATION_STATE_DONE = 2;
72     private static final int NETWORK_REGISTRATION_STATE_CHANGED = 3;
73 
74     // From 24.008 6.1.3.0 and 10.5.6.2 the maximum number of PDP Contexts is 16.
75     private static final int MAX_DATA_CALLS = 16;
76 
77     private static final Map<Class<? extends CellIdentity>, List<Integer>> sNetworkTypes;
78 
79     static {
80         sNetworkTypes = new ArrayMap<>();
sNetworkTypes.put(CellIdentityGsm.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_GSM, TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_EDGE}))81         sNetworkTypes.put(CellIdentityGsm.class,
82                 Arrays.asList(new Integer[]{
83                     TelephonyManager.NETWORK_TYPE_GSM,
84                     TelephonyManager.NETWORK_TYPE_GPRS,
85                     TelephonyManager.NETWORK_TYPE_EDGE}));
sNetworkTypes.put(CellIdentityWcdma.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_HSPA, TelephonyManager.NETWORK_TYPE_HSPAP}))86         sNetworkTypes.put(CellIdentityWcdma.class,
87                 Arrays.asList(new Integer[]{
88                     TelephonyManager.NETWORK_TYPE_UMTS,
89                     TelephonyManager.NETWORK_TYPE_HSDPA,
90                     TelephonyManager.NETWORK_TYPE_HSUPA,
91                     TelephonyManager.NETWORK_TYPE_HSPA,
92                     TelephonyManager.NETWORK_TYPE_HSPAP}));
sNetworkTypes.put(CellIdentityCdma.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyManager.NETWORK_TYPE_EHRPD}))93         sNetworkTypes.put(CellIdentityCdma.class,
94                 Arrays.asList(new Integer[]{
95                     TelephonyManager.NETWORK_TYPE_CDMA,
96                     TelephonyManager.NETWORK_TYPE_1xRTT,
97                     TelephonyManager.NETWORK_TYPE_EVDO_0,
98                     TelephonyManager.NETWORK_TYPE_EVDO_A,
99                     TelephonyManager.NETWORK_TYPE_EVDO_B,
100                     TelephonyManager.NETWORK_TYPE_EHRPD}));
sNetworkTypes.put(CellIdentityLte.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_LTE}))101         sNetworkTypes.put(CellIdentityLte.class,
102                 Arrays.asList(new Integer[]{
103                     TelephonyManager.NETWORK_TYPE_LTE}));
sNetworkTypes.put(CellIdentityNr.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_NR}))104         sNetworkTypes.put(CellIdentityNr.class,
105                 Arrays.asList(new Integer[]{
106                     TelephonyManager.NETWORK_TYPE_NR}));
sNetworkTypes.put(CellIdentityTdscdma.class, Arrays.asList(new Integer[]{ TelephonyManager.NETWORK_TYPE_TD_SCDMA}))107         sNetworkTypes.put(CellIdentityTdscdma.class,
108                 Arrays.asList(new Integer[]{
109                     TelephonyManager.NETWORK_TYPE_TD_SCDMA}));
110     }
111 
112     private class CellularNetworkServiceProvider extends NetworkServiceProvider {
113 
114         private final Map<Message, NetworkServiceCallback> mCallbackMap = new HashMap<>();
115 
116         private final Handler mHandler;
117 
118         private final Phone mPhone;
119 
CellularNetworkServiceProvider(int slotId)120         CellularNetworkServiceProvider(int slotId) {
121             super(slotId);
122 
123             mPhone = PhoneFactory.getPhone(getSlotIndex());
124 
125             mHandler = new Handler(Looper.myLooper()) {
126                 @Override
127                 public void handleMessage(Message message) {
128                     NetworkServiceCallback callback = mCallbackMap.remove(message);
129 
130                     AsyncResult ar;
131                     switch (message.what) {
132                         case GET_CS_REGISTRATION_STATE_DONE:
133                         case GET_PS_REGISTRATION_STATE_DONE:
134                             if (callback == null) return;
135                             ar = (AsyncResult) message.obj;
136                             int domain = (message.what == GET_CS_REGISTRATION_STATE_DONE)
137                                     ? NetworkRegistrationInfo.DOMAIN_CS
138                                     : NetworkRegistrationInfo.DOMAIN_PS;
139                             // TODO: move to RILUtils
140                             NetworkRegistrationInfo netState =
141                                     getRegistrationStateFromResult(ar.result, domain);
142 
143                             int resultCode;
144                             if (ar.exception != null || netState == null) {
145                                 resultCode = NetworkServiceCallback.RESULT_ERROR_FAILED;
146                             } else {
147                                 resultCode = NetworkServiceCallback.RESULT_SUCCESS;
148                             }
149 
150                             try {
151                                 if (DBG) {
152                                     log("Calling onRequestNetworkRegistrationInfoComplete."
153                                             + "resultCode = " + resultCode
154                                             + ", netState = " + netState);
155                                 }
156                                 callback.onRequestNetworkRegistrationInfoComplete(
157                                          resultCode, netState);
158                             } catch (Exception e) {
159                                 loge("Exception: " + e);
160                             }
161                             break;
162                         case NETWORK_REGISTRATION_STATE_CHANGED:
163                             notifyNetworkRegistrationInfoChanged();
164                             break;
165                         default:
166                             return;
167                     }
168                 }
169             };
170 
171             mPhone.mCi.registerForNetworkStateChanged(
172                     mHandler, NETWORK_REGISTRATION_STATE_CHANGED, null);
173         }
174 
getRegStateFromHalRegState(int halRegState)175         private int getRegStateFromHalRegState(int halRegState) {
176             switch (halRegState) {
177                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
178                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM:
179                     return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
180                 case RegState.REG_HOME:
181                     return NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
182                 case RegState.NOT_REG_MT_SEARCHING_OP:
183                 case RegState.NOT_REG_MT_SEARCHING_OP_EM:
184                     return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_SEARCHING;
185                 case RegState.REG_DENIED:
186                 case RegState.REG_DENIED_EM:
187                     return NetworkRegistrationInfo.REGISTRATION_STATE_DENIED;
188                 case RegState.UNKNOWN:
189                 case RegState.UNKNOWN_EM:
190                     return NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
191                 case RegState.REG_ROAMING:
192                     return NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING;
193                 default:
194                     return NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
195             }
196         }
197 
isEmergencyOnly(int halRegState)198         private boolean isEmergencyOnly(int halRegState) {
199             switch (halRegState) {
200                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP_EM:
201                 case RegState.NOT_REG_MT_SEARCHING_OP_EM:
202                 case RegState.REG_DENIED_EM:
203                 case RegState.UNKNOWN_EM:
204                     return true;
205                 case RegState.NOT_REG_MT_NOT_SEARCHING_OP:
206                 case RegState.REG_HOME:
207                 case RegState.NOT_REG_MT_SEARCHING_OP:
208                 case RegState.REG_DENIED:
209                 case RegState.UNKNOWN:
210                 case RegState.REG_ROAMING:
211                 default:
212                     return false;
213             }
214         }
215 
getAvailableServices(int regState, int domain, boolean emergencyOnly)216         private List<Integer> getAvailableServices(int regState, int domain,
217                                                    boolean emergencyOnly) {
218             List<Integer> availableServices = new ArrayList<>();
219 
220             // In emergency only states, only SERVICE_TYPE_EMERGENCY is available.
221             // Otherwise, certain services are available only if it's registered on home or roaming
222             // network.
223             if (emergencyOnly) {
224                 availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_EMERGENCY);
225             } else if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING
226                     || regState == NetworkRegistrationInfo.REGISTRATION_STATE_HOME) {
227                 if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
228                     availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_DATA);
229                 } else if (domain == NetworkRegistrationInfo.DOMAIN_CS) {
230                     availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VOICE);
231                     availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_SMS);
232                     availableServices.add(NetworkRegistrationInfo.SERVICE_TYPE_VIDEO);
233                 }
234             }
235 
236             return availableServices;
237         }
238 
getRegistrationStateFromResult(Object result, int domain)239         private NetworkRegistrationInfo getRegistrationStateFromResult(Object result, int domain) {
240             if (result == null) {
241                 return null;
242             }
243 
244             // TODO: unify when voiceRegStateResult and DataRegStateResult are unified.
245             if (domain == NetworkRegistrationInfo.DOMAIN_CS) {
246                 return createRegistrationStateFromVoiceRegState(result);
247             } else if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
248                 return createRegistrationStateFromDataRegState(result);
249             } else {
250                 return null;
251             }
252         }
253 
getPlmnFromCellIdentity(@ullable final CellIdentity ci)254         private @NonNull String getPlmnFromCellIdentity(@Nullable final CellIdentity ci) {
255             if (ci == null || ci instanceof CellIdentityCdma) return "";
256 
257             final String mcc = ci.getMccString();
258             final String mnc = ci.getMncString();
259 
260             if (TextUtils.isEmpty(mcc) || TextUtils.isEmpty(mnc)) return "";
261 
262             return mcc + mnc;
263         }
264 
createRegistrationStateFromVoiceRegState(Object result)265         private NetworkRegistrationInfo createRegistrationStateFromVoiceRegState(Object result) {
266             final int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
267             final int domain = NetworkRegistrationInfo.DOMAIN_CS;
268 
269             if (result instanceof android.hardware.radio.network.RegStateResult) {
270                 return getNetworkRegistrationInfoAidl(domain, transportType,
271                         (android.hardware.radio.network.RegStateResult) result);
272             } else if (result instanceof android.hardware.radio.V1_6.RegStateResult) {
273                 return getNetworkRegistrationInfo1_6(domain, transportType,
274                         (android.hardware.radio.V1_6.RegStateResult) result);
275             } else if (result instanceof android.hardware.radio.V1_5.RegStateResult) {
276                 return getNetworkRegistrationInfo(domain, transportType,
277                         (android.hardware.radio.V1_5.RegStateResult) result);
278             } else if (result instanceof android.hardware.radio.V1_0.VoiceRegStateResult) {
279                 android.hardware.radio.V1_0.VoiceRegStateResult voiceRegState =
280                         (android.hardware.radio.V1_0.VoiceRegStateResult) result;
281                 int regState = getRegStateFromHalRegState(voiceRegState.regState);
282                 int networkType = ServiceState.rilRadioTechnologyToNetworkType(voiceRegState.rat);
283                 int reasonForDenial = voiceRegState.reasonForDenial;
284                 boolean emergencyOnly = isEmergencyOnly(voiceRegState.regState);
285                 boolean cssSupported = voiceRegState.cssSupported;
286                 int roamingIndicator = voiceRegState.roamingIndicator;
287                 int systemIsInPrl = voiceRegState.systemIsInPrl;
288                 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator;
289                 List<Integer> availableServices = getAvailableServices(
290                         regState, domain, emergencyOnly);
291                 CellIdentity cellIdentity =
292                         RILUtils.convertHalCellIdentity(voiceRegState.cellIdentity);
293                 final String rplmn = getPlmnFromCellIdentity(cellIdentity);
294 
295                 return new NetworkRegistrationInfo(domain, transportType, regState,
296                         networkType, reasonForDenial, emergencyOnly, availableServices,
297                         cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
298                         defaultRoamingIndicator);
299             } else if (result instanceof android.hardware.radio.V1_2.VoiceRegStateResult) {
300                 android.hardware.radio.V1_2.VoiceRegStateResult voiceRegState =
301                         (android.hardware.radio.V1_2.VoiceRegStateResult) result;
302                 int regState = getRegStateFromHalRegState(voiceRegState.regState);
303                 int networkType = ServiceState.rilRadioTechnologyToNetworkType(voiceRegState.rat);
304                 int reasonForDenial = voiceRegState.reasonForDenial;
305                 boolean emergencyOnly = isEmergencyOnly(voiceRegState.regState);
306                 boolean cssSupported = voiceRegState.cssSupported;
307                 int roamingIndicator = voiceRegState.roamingIndicator;
308                 int systemIsInPrl = voiceRegState.systemIsInPrl;
309                 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator;
310                 List<Integer> availableServices = getAvailableServices(
311                         regState, domain, emergencyOnly);
312                 CellIdentity cellIdentity =
313                         RILUtils.convertHalCellIdentity(voiceRegState.cellIdentity);
314                 final String rplmn = getPlmnFromCellIdentity(cellIdentity);
315 
316                 return new NetworkRegistrationInfo(domain, transportType, regState,
317                         networkType, reasonForDenial, emergencyOnly, availableServices,
318                         cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
319                         defaultRoamingIndicator);
320             }
321 
322             return null;
323         }
324 
createRegistrationStateFromDataRegState(Object result)325         private NetworkRegistrationInfo createRegistrationStateFromDataRegState(Object result) {
326             final int domain = NetworkRegistrationInfo.DOMAIN_PS;
327             final int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
328 
329             int regState = NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
330             int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
331             int reasonForDenial = 0;
332             boolean emergencyOnly = false;
333             int maxDataCalls = 0;
334             CellIdentity cellIdentity;
335             boolean isEndcAvailable = false;
336             boolean isNrAvailable = false;
337             boolean isDcNrRestricted = false;
338 
339             LteVopsSupportInfo lteVopsSupportInfo =
340                     new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
341                             LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
342 
343             if (result instanceof android.hardware.radio.network.RegStateResult) {
344                 return getNetworkRegistrationInfoAidl(domain, transportType,
345                         (android.hardware.radio.network.RegStateResult) result);
346             } else if (result instanceof android.hardware.radio.V1_6.RegStateResult) {
347                 return getNetworkRegistrationInfo1_6(domain, transportType,
348                         (android.hardware.radio.V1_6.RegStateResult) result);
349             } else if (result instanceof android.hardware.radio.V1_5.RegStateResult) {
350                 return getNetworkRegistrationInfo(domain, transportType,
351                         (android.hardware.radio.V1_5.RegStateResult) result);
352             } else if (result instanceof android.hardware.radio.V1_0.DataRegStateResult) {
353                 android.hardware.radio.V1_0.DataRegStateResult dataRegState =
354                         (android.hardware.radio.V1_0.DataRegStateResult) result;
355                 regState = getRegStateFromHalRegState(dataRegState.regState);
356                 networkType = ServiceState.rilRadioTechnologyToNetworkType(dataRegState.rat);
357                 reasonForDenial = dataRegState.reasonDataDenied;
358                 emergencyOnly = isEmergencyOnly(dataRegState.regState);
359                 maxDataCalls = dataRegState.maxDataCalls;
360                 cellIdentity = RILUtils.convertHalCellIdentity(dataRegState.cellIdentity);
361             } else if (result instanceof android.hardware.radio.V1_2.DataRegStateResult) {
362                 android.hardware.radio.V1_2.DataRegStateResult dataRegState =
363                         (android.hardware.radio.V1_2.DataRegStateResult) result;
364                 regState = getRegStateFromHalRegState(dataRegState.regState);
365                 networkType = ServiceState.rilRadioTechnologyToNetworkType(dataRegState.rat);
366                 reasonForDenial = dataRegState.reasonDataDenied;
367                 emergencyOnly = isEmergencyOnly(dataRegState.regState);
368                 maxDataCalls = dataRegState.maxDataCalls;
369                 cellIdentity = RILUtils.convertHalCellIdentity(dataRegState.cellIdentity);
370             } else if (result instanceof android.hardware.radio.V1_4.DataRegStateResult) {
371                 android.hardware.radio.V1_4.DataRegStateResult dataRegState =
372                         (android.hardware.radio.V1_4.DataRegStateResult) result;
373                 regState = getRegStateFromHalRegState(dataRegState.base.regState);
374                 networkType = ServiceState.rilRadioTechnologyToNetworkType(dataRegState.base.rat);
375 
376                 reasonForDenial = dataRegState.base.reasonDataDenied;
377                 emergencyOnly = isEmergencyOnly(dataRegState.base.regState);
378                 maxDataCalls = dataRegState.base.maxDataCalls;
379                 cellIdentity = RILUtils.convertHalCellIdentity(dataRegState.base.cellIdentity);
380                 android.hardware.radio.V1_4.NrIndicators nrIndicators = dataRegState.nrIndicators;
381 
382                 // Check for lteVopsInfo only if its initialized and RAT is EUTRAN
383                 if (dataRegState.vopsInfo.getDiscriminator() == hidl_discriminator.lteVopsInfo
384                         && ServiceState.rilRadioTechnologyToAccessNetworkType(dataRegState.base.rat)
385                             == AccessNetworkType.EUTRAN) {
386                     android.hardware.radio.V1_4.LteVopsInfo vopsSupport =
387                             dataRegState.vopsInfo.lteVopsInfo();
388                     lteVopsSupportInfo = convertHalLteVopsSupportInfo(vopsSupport.isVopsSupported,
389                         vopsSupport.isEmcBearerSupported);
390                 } else {
391                     lteVopsSupportInfo =
392                         new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
393                         LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
394                 }
395 
396                 isEndcAvailable = nrIndicators.isEndcAvailable;
397                 isNrAvailable = nrIndicators.isNrAvailable;
398                 isDcNrRestricted = nrIndicators.isDcNrRestricted;
399             } else {
400                 loge("Unknown type of DataRegStateResult " + result);
401                 return null;
402             }
403 
404             String rplmn = getPlmnFromCellIdentity(cellIdentity);
405             List<Integer> availableServices = getAvailableServices(
406                     regState, domain, emergencyOnly);
407 
408             return new NetworkRegistrationInfo(domain, transportType, regState, networkType,
409                     reasonForDenial, emergencyOnly, availableServices, cellIdentity, rplmn,
410                     maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable,
411                     lteVopsSupportInfo);
412         }
413 
getNetworkRegistrationInfo( int domain, int transportType, android.hardware.radio.V1_5.RegStateResult regResult)414         private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfo(
415                 int domain, int transportType,
416                 android.hardware.radio.V1_5.RegStateResult regResult) {
417 
418             // Perform common conversions that aren't domain specific
419             final int regState = getRegStateFromHalRegState(regResult.regState);
420             final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
421             final List<Integer> availableServices = getAvailableServices(
422                     regState, domain, isEmergencyOnly);
423             final CellIdentity cellIdentity =
424                     RILUtils.convertHalCellIdentity(regResult.cellIdentity);
425             final String rplmn = regResult.registeredPlmn;
426             final int reasonForDenial = regResult.reasonForDenial;
427 
428             int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
429             networkType =
430                     getNetworkTypeForCellIdentity(networkType, cellIdentity, mPhone.getCarrierId());
431 
432             // Conditional parameters for specific RANs
433             boolean cssSupported = false;
434             int roamingIndicator = 0;
435             int systemIsInPrl = 0;
436             int defaultRoamingIndicator = 0;
437             boolean isEndcAvailable = false;
438             boolean isNrAvailable = false;
439             boolean isDcNrRestricted = false;
440             LteVopsSupportInfo vopsInfo = new LteVopsSupportInfo(
441                     LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
442                     LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
443 
444             switch (regResult.accessTechnologySpecificInfo.getDiscriminator()) {
445                 case android.hardware.radio.V1_5.RegStateResult
446                         .AccessTechnologySpecificInfo.hidl_discriminator.cdmaInfo:
447                     android.hardware.radio.V1_5.RegStateResult
448                             .AccessTechnologySpecificInfo.Cdma2000RegistrationInfo cdmaInfo =
449                                     regResult.accessTechnologySpecificInfo.cdmaInfo();
450                     cssSupported = cdmaInfo.cssSupported;
451                     roamingIndicator = cdmaInfo.roamingIndicator;
452                     systemIsInPrl = cdmaInfo.systemIsInPrl;
453                     defaultRoamingIndicator = cdmaInfo.defaultRoamingIndicator;
454                     break;
455                 case android.hardware.radio.V1_5.RegStateResult
456                         .AccessTechnologySpecificInfo.hidl_discriminator.eutranInfo:
457                     android.hardware.radio.V1_5.RegStateResult
458                             .AccessTechnologySpecificInfo.EutranRegistrationInfo eutranInfo =
459                                     regResult.accessTechnologySpecificInfo.eutranInfo();
460 
461                     isDcNrRestricted = eutranInfo.nrIndicators.isDcNrRestricted;
462                     isNrAvailable = eutranInfo.nrIndicators.isNrAvailable;
463                     isEndcAvailable = eutranInfo.nrIndicators.isEndcAvailable;
464                     vopsInfo = convertHalLteVopsSupportInfo(
465                             eutranInfo.lteVopsInfo.isVopsSupported,
466                             eutranInfo.lteVopsInfo.isEmcBearerSupported);
467                     break;
468                 default:
469                     log("No access tech specific info passes for RegStateResult");
470                     break;
471             }
472 
473             // build the result based on the domain for the request
474             switch(domain) {
475                 case NetworkRegistrationInfo.DOMAIN_CS:
476                     return new NetworkRegistrationInfo(domain, transportType, regState,
477                             networkType, reasonForDenial, isEmergencyOnly, availableServices,
478                             cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
479                             defaultRoamingIndicator);
480                 default:
481                     loge("Unknown domain passed to CellularNetworkService= " + domain);
482                     // fall through
483                 case NetworkRegistrationInfo.DOMAIN_PS:
484                     return new NetworkRegistrationInfo(domain, transportType, regState, networkType,
485                             reasonForDenial, isEmergencyOnly, availableServices, cellIdentity,
486                             rplmn, MAX_DATA_CALLS, isDcNrRestricted, isNrAvailable, isEndcAvailable,
487                             vopsInfo);
488             }
489         }
490 
getNetworkRegistrationInfoAidl(int domain, int transportType, android.hardware.radio.network.RegStateResult regResult)491         private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfoAidl(int domain,
492                 int transportType, android.hardware.radio.network.RegStateResult regResult) {
493             // Perform common conversions that aren't domain specific
494             final int regState = getRegStateFromHalRegState(regResult.regState);
495             final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
496             final List<Integer> availableServices = getAvailableServices(
497                     regState, domain, isEmergencyOnly);
498             final CellIdentity cellIdentity =
499                     RILUtils.convertHalCellIdentity(regResult.cellIdentity);
500             final String rplmn = regResult.registeredPlmn;
501             final int reasonForDenial = regResult.reasonForDenial;
502 
503             if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_DENIED
504                     && reasonForDenial
505                     == android.hardware.radio.network.RegistrationFailCause.NONE) {
506                 AnomalyReporter.reportAnomaly(
507                         UUID.fromString("62ed270f-e139-418a-a427-8bcc1bca8f20"),
508                             "RIL Missing Reg Fail Reason", mPhone.getCarrierId());
509             }
510 
511             int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
512             if (networkType == TelephonyManager.NETWORK_TYPE_LTE_CA) {
513                 networkType = TelephonyManager.NETWORK_TYPE_LTE;
514             }
515 
516             // Conditional parameters for specific RANs
517             boolean cssSupported = false;
518             int roamingIndicator = 0;
519             int systemIsInPrl = 0;
520             int defaultRoamingIndicator = 0;
521             boolean isEndcAvailable = false;
522             boolean isNrAvailable = false;
523             boolean isDcNrRestricted = false;
524             VopsSupportInfo vopsInfo = null;
525 
526             android.hardware.radio.network.AccessTechnologySpecificInfo info =
527                     regResult.accessTechnologySpecificInfo;
528 
529             switch (info.getTag()) {
530                 case android.hardware.radio.network.AccessTechnologySpecificInfo.cdmaInfo:
531                     cssSupported = info.getCdmaInfo().cssSupported;
532                     roamingIndicator = info.getCdmaInfo().roamingIndicator;
533                     systemIsInPrl = info.getCdmaInfo().systemIsInPrl;
534                     defaultRoamingIndicator = info.getCdmaInfo().defaultRoamingIndicator;
535                     break;
536                 case android.hardware.radio.network.AccessTechnologySpecificInfo.eutranInfo:
537                     isDcNrRestricted = info.getEutranInfo().nrIndicators.isDcNrRestricted;
538                     isNrAvailable = info.getEutranInfo().nrIndicators.isNrAvailable;
539                     isEndcAvailable = info.getEutranInfo().nrIndicators.isEndcAvailable;
540                     vopsInfo = convertHalLteVopsSupportInfo(
541                             info.getEutranInfo().lteVopsInfo.isVopsSupported,
542                             info.getEutranInfo().lteVopsInfo.isEmcBearerSupported);
543                     break;
544                 case android.hardware.radio.network.AccessTechnologySpecificInfo.ngranNrVopsInfo:
545                     vopsInfo = new NrVopsSupportInfo(info.getNgranNrVopsInfo().vopsSupported,
546                             info.getNgranNrVopsInfo().emcSupported,
547                             info.getNgranNrVopsInfo().emfSupported);
548                     break;
549                 case android.hardware.radio.network.AccessTechnologySpecificInfo.geranDtmSupported:
550                     cssSupported = info.getGeranDtmSupported();
551                     break;
552                 default:
553                     log("No access tech specific info passes for RegStateResult");
554                     break;
555             }
556 
557             // build the result based on the domain for the request
558             switch (domain) {
559                 case NetworkRegistrationInfo.DOMAIN_CS:
560                     return new NetworkRegistrationInfo(domain, transportType, regState,
561                             networkType, reasonForDenial, isEmergencyOnly, availableServices,
562                             cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
563                             defaultRoamingIndicator);
564                 default:
565                     loge("Unknown domain passed to CellularNetworkService= " + domain);
566                     // fall through
567                 case NetworkRegistrationInfo.DOMAIN_PS:
568                     return new NetworkRegistrationInfo(domain, transportType, regState, networkType,
569                             reasonForDenial, isEmergencyOnly, availableServices, cellIdentity,
570                             rplmn, MAX_DATA_CALLS, isDcNrRestricted, isNrAvailable, isEndcAvailable,
571                             vopsInfo);
572             }
573         }
574 
getNetworkRegistrationInfo1_6( int domain, int transportType, android.hardware.radio.V1_6.RegStateResult regResult)575         private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfo1_6(
576                 int domain, int transportType,
577                 android.hardware.radio.V1_6.RegStateResult regResult) {
578 
579             // Perform common conversions that aren't domain specific
580             final int regState = getRegStateFromHalRegState(regResult.regState);
581             final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
582             final List<Integer> availableServices = getAvailableServices(
583                     regState, domain, isEmergencyOnly);
584             final CellIdentity cellIdentity =
585                     RILUtils.convertHalCellIdentity(regResult.cellIdentity);
586             final String rplmn = regResult.registeredPlmn;
587             final int reasonForDenial = regResult.reasonForDenial;
588 
589             int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
590             networkType =
591                     getNetworkTypeForCellIdentity(networkType, cellIdentity, mPhone.getCarrierId());
592 
593             if (regState == NetworkRegistrationInfo.REGISTRATION_STATE_DENIED
594                     && reasonForDenial
595                     == android.hardware.radio.network.RegistrationFailCause.NONE) {
596                 AnomalyReporter.reportAnomaly(
597                         UUID.fromString("62ed270f-e139-418a-a427-8bcc1bca8f20"),
598                             "RIL Missing Reg Fail Reason", mPhone.getCarrierId());
599             }
600 
601             // Conditional parameters for specific RANs
602             boolean cssSupported = false;
603             int roamingIndicator = 0;
604             int systemIsInPrl = 0;
605             int defaultRoamingIndicator = 0;
606             boolean isEndcAvailable = false;
607             boolean isNrAvailable = false;
608             boolean isDcNrRestricted = false;
609             VopsSupportInfo vopsInfo = null;
610 
611             android.hardware.radio.V1_6.RegStateResult.AccessTechnologySpecificInfo info =
612                     regResult.accessTechnologySpecificInfo;
613 
614             switch (info.getDiscriminator()) {
615                 case AccessTechnologySpecificInfo.hidl_discriminator.cdmaInfo:
616                     cssSupported = info.cdmaInfo().cssSupported;
617                     roamingIndicator = info.cdmaInfo().roamingIndicator;
618                     systemIsInPrl = info.cdmaInfo().systemIsInPrl;
619                     defaultRoamingIndicator = info.cdmaInfo().defaultRoamingIndicator;
620                     break;
621                 case AccessTechnologySpecificInfo.hidl_discriminator.eutranInfo:
622                     isDcNrRestricted = info.eutranInfo().nrIndicators.isDcNrRestricted;
623                     isNrAvailable = info.eutranInfo().nrIndicators.isNrAvailable;
624                     isEndcAvailable = info.eutranInfo().nrIndicators.isEndcAvailable;
625                     vopsInfo = convertHalLteVopsSupportInfo(
626                             info.eutranInfo().lteVopsInfo.isVopsSupported,
627                             info.eutranInfo().lteVopsInfo.isEmcBearerSupported);
628                     break;
629                 case AccessTechnologySpecificInfo.hidl_discriminator.ngranNrVopsInfo:
630                     vopsInfo = new NrVopsSupportInfo(info.ngranNrVopsInfo().vopsSupported,
631                             info.ngranNrVopsInfo().emcSupported,
632                             info.ngranNrVopsInfo().emfSupported);
633                     break;
634                 case AccessTechnologySpecificInfo.hidl_discriminator.geranDtmSupported:
635                     cssSupported = info.geranDtmSupported();
636                     break;
637                 default:
638                     log("No access tech specific info passes for RegStateResult");
639                     break;
640             }
641 
642             // build the result based on the domain for the request
643             switch(domain) {
644                 case NetworkRegistrationInfo.DOMAIN_CS:
645                     return new NetworkRegistrationInfo(domain, transportType, regState,
646                             networkType, reasonForDenial, isEmergencyOnly, availableServices,
647                             cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
648                             defaultRoamingIndicator);
649                 default:
650                     loge("Unknown domain passed to CellularNetworkService= " + domain);
651                     // fall through
652                 case NetworkRegistrationInfo.DOMAIN_PS:
653                     return new NetworkRegistrationInfo(domain, transportType, regState, networkType,
654                             reasonForDenial, isEmergencyOnly, availableServices, cellIdentity,
655                             rplmn, MAX_DATA_CALLS, isDcNrRestricted, isNrAvailable, isEndcAvailable,
656                             vopsInfo);
657             }
658         }
659 
convertHalLteVopsSupportInfo( boolean vopsSupport, boolean emcBearerSupport)660         private LteVopsSupportInfo convertHalLteVopsSupportInfo(
661                 boolean vopsSupport, boolean emcBearerSupport) {
662             int vops = LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED;
663             int emergency = LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED;
664 
665             if (vopsSupport) {
666                 vops = LteVopsSupportInfo.LTE_STATUS_SUPPORTED;
667             }
668             if (emcBearerSupport) {
669                 emergency = LteVopsSupportInfo.LTE_STATUS_SUPPORTED;
670             }
671             return new LteVopsSupportInfo(vops, emergency);
672         }
673 
674         @Override
requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback)675         public void requestNetworkRegistrationInfo(int domain, NetworkServiceCallback callback) {
676             if (DBG) log("requestNetworkRegistrationInfo for domain " + domain);
677             Message message = null;
678 
679             if (domain == NetworkRegistrationInfo.DOMAIN_CS) {
680                 message = Message.obtain(mHandler, GET_CS_REGISTRATION_STATE_DONE);
681                 mCallbackMap.put(message, callback);
682                 mPhone.mCi.getVoiceRegistrationState(message);
683             } else if (domain == NetworkRegistrationInfo.DOMAIN_PS) {
684                 message = Message.obtain(mHandler, GET_PS_REGISTRATION_STATE_DONE);
685                 mCallbackMap.put(message, callback);
686                 mPhone.mCi.getDataRegistrationState(message);
687             } else {
688                 loge("requestNetworkRegistrationInfo invalid domain " + domain);
689                 callback.onRequestNetworkRegistrationInfoComplete(
690                         NetworkServiceCallback.RESULT_ERROR_INVALID_ARG, null);
691             }
692         }
693 
694         @Override
close()695         public void close() {
696             mCallbackMap.clear();
697             mPhone.mCi.unregisterForNetworkStateChanged(mHandler);
698         }
699     }
700 
701     /** Cross-check the network type against the CellIdentity type */
702     @VisibleForTesting
getNetworkTypeForCellIdentity( int networkType, CellIdentity ci, int carrierId)703     public static int getNetworkTypeForCellIdentity(
704             int networkType, CellIdentity ci, int carrierId) {
705         if (ci == null) {
706             if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
707                 // Network type is non-null but CellIdentity is null
708                 AnomalyReporter.reportAnomaly(
709                         UUID.fromString("e67ea4ef-7251-4a69-a063-22c47fc58743"),
710                             "RIL Unexpected NetworkType", carrierId);
711                 if (android.os.Build.isDebuggable()) {
712                     logw("Updating incorrect network type from "
713                             + TelephonyManager.getNetworkTypeName(networkType) + " to UNKNOWN");
714                     return TelephonyManager.NETWORK_TYPE_UNKNOWN;
715                 } else {
716                     // If the build isn't debuggable and CellIdentity is null, there's no way to
717                     // guess the approximately correct type so if it's valid it gets a pass.
718                     for (List<Integer> values : sNetworkTypes.values()) {
719                         if (values.contains(networkType)) return networkType;
720                     }
721                 }
722             }
723 
724             // No valid network type, so return UNKNOWN for safety.
725             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
726         }
727 
728 
729         // If the type is reported as IWLAN but the CellIdentity is a cellular type,
730         // report that; Devices post HAL 1.4 should be operating in AP-assisted mode
731         if (networkType == TelephonyManager.NETWORK_TYPE_IWLAN) {
732             AnomalyReporter.reportAnomaly(
733                     UUID.fromString("07dfa183-b2e7-42b7-98a1-dd5ae2abdd4f"),
734                             "RIL Reported IWLAN", carrierId);
735             if (!android.os.Build.isDebuggable()) return networkType;
736 
737             if (sNetworkTypes.containsKey(ci.getClass())) {
738                 final int updatedType = sNetworkTypes.get(ci.getClass()).get(0);
739                 logw("Updating incorrect network type from IWLAN to " + updatedType);
740                 return updatedType;
741             } else {
742                 logw("Updating incorrect network type from IWLAN to UNKNOWN");
743                 return TelephonyManager.NETWORK_TYPE_UNKNOWN;
744             }
745         }
746 
747         if (!sNetworkTypes.containsKey(ci.getClass())) {
748             AnomalyReporter.reportAnomaly(
749                     UUID.fromString("469858cf-46e5-416e-bc11-5e7970917857"),
750                         "RIL Unknown CellIdentity", carrierId);
751             return networkType;
752         }
753 
754         // If the network type isn't valid for the CellIdentity type,
755         final List<Integer> typesForCi = sNetworkTypes.get(ci.getClass());
756         if (!typesForCi.contains(networkType)) {
757             AnomalyReporter.reportAnomaly(
758                     UUID.fromString("2fb634fa-cab3-44d2-bbe8-c7689b0f3e31"),
759                         "RIL Mismatched NetworkType", carrierId);
760             // Since this is a plain-and-simple mismatch between two conflicting pieces of
761             // data, and theres no way to know which one to trust, pick the one that's harder
762             // to coerce / fake / set incorrectly and make them roughly match.
763             // Note, this also does the fixup for LTE_CA -> LTE that was formerly done as a
764             // special case.
765             logw("Updating incorrect network type from "
766                     + TelephonyManager.getNetworkTypeName(networkType)
767                     + " to " + TelephonyManager.getNetworkTypeName(typesForCi.get(0)));
768             return typesForCi.get(0);
769         }
770 
771         return networkType;
772     }
773 
774     @Override
onCreateNetworkServiceProvider(int slotIndex)775     public NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex) {
776         if (DBG) log("Cellular network service created for slot " + slotIndex);
777         if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
778             loge("Tried to Cellular network service with invalid slotId " + slotIndex);
779             return null;
780         }
781         return new CellularNetworkServiceProvider(slotIndex);
782     }
783 
log(String s)784     private static void log(String s) {
785         Rlog.d(TAG, s);
786     }
787 
logw(String s)788     private static void logw(String s) {
789         Rlog.w(TAG, s);
790     }
791 
loge(String s)792     private static void loge(String s) {
793         Rlog.e(TAG, s);
794     }
795 }
796