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