1 /* 2 * Copyright (C) 2006 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.dataconnection; 18 19 import static android.telephony.data.DataCallResponse.PDU_SESSION_ID_NOT_SET; 20 21 import static com.android.internal.telephony.dataconnection.DcTracker.REQUEST_TYPE_HANDOVER; 22 23 import android.annotation.IntDef; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.app.PendingIntent; 27 import android.content.Context; 28 import android.net.ConnectivityManager; 29 import android.net.InetAddresses; 30 import android.net.KeepalivePacketData; 31 import android.net.LinkAddress; 32 import android.net.LinkProperties; 33 import android.net.NetworkAgentConfig; 34 import android.net.NetworkCapabilities; 35 import android.net.NetworkFactory; 36 import android.net.NetworkProvider; 37 import android.net.NetworkRequest; 38 import android.net.ProxyInfo; 39 import android.net.RouteInfo; 40 import android.net.SocketKeepalive; 41 import android.net.TelephonyNetworkSpecifier; 42 import android.net.vcn.VcnManager; 43 import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener; 44 import android.net.vcn.VcnNetworkPolicyResult; 45 import android.os.AsyncResult; 46 import android.os.HandlerExecutor; 47 import android.os.Message; 48 import android.os.PersistableBundle; 49 import android.os.SystemClock; 50 import android.os.SystemProperties; 51 import android.provider.Telephony; 52 import android.telephony.AccessNetworkConstants; 53 import android.telephony.AccessNetworkConstants.TransportType; 54 import android.telephony.Annotation.ApnType; 55 import android.telephony.Annotation.DataFailureCause; 56 import android.telephony.Annotation.DataState; 57 import android.telephony.Annotation.NetworkType; 58 import android.telephony.CarrierConfigManager; 59 import android.telephony.DataFailCause; 60 import android.telephony.LinkCapacityEstimate; 61 import android.telephony.NetworkRegistrationInfo; 62 import android.telephony.PreciseDataConnectionState; 63 import android.telephony.ServiceState; 64 import android.telephony.SubscriptionManager; 65 import android.telephony.TelephonyManager; 66 import android.telephony.data.ApnSetting; 67 import android.telephony.data.DataCallResponse; 68 import android.telephony.data.DataCallResponse.HandoverFailureMode; 69 import android.telephony.data.DataProfile; 70 import android.telephony.data.DataService; 71 import android.telephony.data.DataServiceCallback; 72 import android.telephony.data.NetworkSliceInfo; 73 import android.telephony.data.Qos; 74 import android.telephony.data.QosBearerSession; 75 import android.telephony.data.TrafficDescriptor; 76 import android.text.TextUtils; 77 import android.util.LocalLog; 78 import android.util.Pair; 79 import android.util.TimeUtils; 80 81 import com.android.internal.annotations.VisibleForTesting; 82 import com.android.internal.telephony.CarrierSignalAgent; 83 import com.android.internal.telephony.DctConstants; 84 import com.android.internal.telephony.Phone; 85 import com.android.internal.telephony.PhoneConstants; 86 import com.android.internal.telephony.PhoneFactory; 87 import com.android.internal.telephony.RIL; 88 import com.android.internal.telephony.RILConstants; 89 import com.android.internal.telephony.RetryManager; 90 import com.android.internal.telephony.TelephonyStatsLog; 91 import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType; 92 import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType; 93 import com.android.internal.telephony.metrics.DataCallSessionStats; 94 import com.android.internal.telephony.metrics.TelephonyMetrics; 95 import com.android.internal.telephony.nano.TelephonyProto.RilDataCall; 96 import com.android.internal.telephony.uicc.IccUtils; 97 import com.android.internal.util.AsyncChannel; 98 import com.android.internal.util.IndentingPrintWriter; 99 import com.android.internal.util.Protocol; 100 import com.android.internal.util.State; 101 import com.android.internal.util.StateMachine; 102 import com.android.net.module.util.NetworkCapabilitiesUtils; 103 import com.android.telephony.Rlog; 104 105 import java.io.FileDescriptor; 106 import java.io.PrintWriter; 107 import java.io.StringWriter; 108 import java.lang.annotation.Retention; 109 import java.lang.annotation.RetentionPolicy; 110 import java.net.InetAddress; 111 import java.net.UnknownHostException; 112 import java.nio.ByteBuffer; 113 import java.util.ArrayList; 114 import java.util.Arrays; 115 import java.util.Collection; 116 import java.util.Collections; 117 import java.util.List; 118 import java.util.Locale; 119 import java.util.Map; 120 import java.util.UUID; 121 import java.util.concurrent.ConcurrentHashMap; 122 import java.util.concurrent.atomic.AtomicInteger; 123 import java.util.function.Consumer; 124 125 /** 126 * {@hide} 127 * 128 * DataConnection StateMachine. 129 * 130 * This a class for representing a single data connection, with instances of this 131 * class representing a connection via the cellular network. There may be multiple 132 * data connections and all of them are managed by the <code>DataConnectionTracker</code>. 133 * 134 * NOTE: All DataConnection objects must be running on the same looper, which is the default 135 * as the coordinator has members which are used without synchronization. 136 */ 137 public class DataConnection extends StateMachine { 138 private static final boolean DBG = true; 139 private static final boolean VDBG = true; 140 141 private static final String NETWORK_TYPE = "MOBILE"; 142 143 private static final String RAT_NAME_5G = "nr"; 144 private static final String RAT_NAME_EVDO = "evdo"; 145 146 /** 147 * OSId for "Android", using UUID version 5 with namespace ISO OSI. 148 * Prepended to the OsAppId in TrafficDescriptor to use for URSP matching. 149 */ 150 private static final UUID OS_ID = UUID.fromString("97a498e3-fc92-5c94-8986-0333d06e4e47"); 151 152 private static final int MIN_V6_MTU = 1280; 153 154 /** 155 * The data connection is not being or been handovered. Note this is the state for the source 156 * data connection, not destination data connection 157 */ 158 private static final int HANDOVER_STATE_IDLE = 1; 159 160 /** 161 * The data connection is being handovered. Note this is the state for the source 162 * data connection, not destination data connection. 163 */ 164 private static final int HANDOVER_STATE_BEING_TRANSFERRED = 2; 165 166 /** 167 * The data connection is already handovered. Note this is the state for the source 168 * data connection, not destination data connection. 169 */ 170 private static final int HANDOVER_STATE_COMPLETED = 3; 171 172 173 /** @hide */ 174 @Retention(RetentionPolicy.SOURCE) 175 @IntDef(prefix = {"HANDOVER_STATE_"}, value = { 176 HANDOVER_STATE_IDLE, 177 HANDOVER_STATE_BEING_TRANSFERRED, 178 HANDOVER_STATE_COMPLETED}) 179 public @interface HandoverState {} 180 181 // The data connection providing default Internet connection will have a higher score of 50. 182 // Other connections will have a slightly lower score of 45. The intention is other connections 183 // will not cause ConnectivityService to tear down default internet connection. For example, 184 // to validate Internet connection on non-default data SIM, we'll set up a temporary Internet 185 // connection on that data SIM. In this case, score of 45 is assigned so ConnectivityService 186 // will not replace the default Internet connection with it. 187 private static final int DEFAULT_INTERNET_CONNECTION_SCORE = 50; 188 private static final int OTHER_CONNECTION_SCORE = 45; 189 190 // The score we report to connectivity service 191 private int mScore; 192 193 // The subscription id associated with this data connection. 194 private int mSubId; 195 196 // The data connection controller 197 private DcController mDcController; 198 199 // The Tester for failing all bringup's 200 private DcTesterFailBringUpAll mDcTesterFailBringUpAll; 201 202 // Whether or not the data connection should allocate its own pdu session id 203 private final boolean mDoAllocatePduSessionId; 204 205 private static AtomicInteger mInstanceNumber = new AtomicInteger(0); 206 private AsyncChannel mAc; 207 208 // The DCT that's talking to us, we only support one! 209 private DcTracker mDct = null; 210 211 private String[] mPcscfAddr; 212 213 private final String mTagSuffix; 214 215 private final LocalLog mHandoverLocalLog = new LocalLog(100); 216 217 private int[] mAdministratorUids = new int[0]; 218 219 // stats per data call 220 private DataCallSessionStats mDataCallSessionStats; 221 222 /** 223 * Used internally for saving connecting parameters. 224 */ 225 public static class ConnectionParams { 226 int mTag; 227 ApnContext mApnContext; 228 int mProfileId; 229 int mRilRat; 230 Message mOnCompletedMsg; 231 final int mConnectionGeneration; 232 @RequestNetworkType 233 final int mRequestType; 234 final int mSubId; 235 final boolean mIsPreferredApn; 236 ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isPreferredApn)237 ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology, 238 Message onCompletedMsg, int connectionGeneration, 239 @RequestNetworkType int requestType, int subId, 240 boolean isPreferredApn) { 241 mApnContext = apnContext; 242 mProfileId = profileId; 243 mRilRat = rilRadioTechnology; 244 mOnCompletedMsg = onCompletedMsg; 245 mConnectionGeneration = connectionGeneration; 246 mRequestType = requestType; 247 mSubId = subId; 248 mIsPreferredApn = isPreferredApn; 249 } 250 251 @Override toString()252 public String toString() { 253 return "{mTag=" + mTag + " mApnContext=" + mApnContext 254 + " mProfileId=" + mProfileId 255 + " mRat=" + mRilRat 256 + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) 257 + " mRequestType=" + DcTracker.requestTypeToString(mRequestType) 258 + " mSubId=" + mSubId 259 + " mIsPreferredApn=" + mIsPreferredApn 260 + "}"; 261 } 262 } 263 264 /** 265 * Used internally for saving disconnecting parameters. 266 */ 267 public static class DisconnectParams { 268 int mTag; 269 public ApnContext mApnContext; 270 String mReason; 271 @ReleaseNetworkType 272 final int mReleaseType; 273 Message mOnCompletedMsg; 274 DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)275 DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType, 276 Message onCompletedMsg) { 277 mApnContext = apnContext; 278 mReason = reason; 279 mReleaseType = releaseType; 280 mOnCompletedMsg = onCompletedMsg; 281 } 282 283 @Override toString()284 public String toString() { 285 return "{mTag=" + mTag + " mApnContext=" + mApnContext 286 + " mReason=" + mReason 287 + " mReleaseType=" + DcTracker.releaseTypeToString(mReleaseType) 288 + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) + "}"; 289 } 290 } 291 292 private volatile ApnSetting mApnSetting; 293 private ConnectionParams mConnectionParams; 294 private DisconnectParams mDisconnectParams; 295 @DataFailureCause 296 private int mDcFailCause; 297 298 @HandoverFailureMode 299 private int mHandoverFailureMode; 300 301 private Phone mPhone; 302 private DataServiceManager mDataServiceManager; 303 private VcnManager mVcnManager; 304 private final int mTransportType; 305 private LinkProperties mLinkProperties = new LinkProperties(); 306 private int mPduSessionId; 307 private long mCreateTime; 308 private long mLastFailTime; 309 @DataFailureCause 310 private int mLastFailCause; 311 private static final String NULL_IP = "0.0.0.0"; 312 private Object mUserData; 313 private boolean mCongestedOverride; 314 private boolean mUnmeteredOverride; 315 private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; 316 private int mDataRegState = Integer.MAX_VALUE; 317 // Indicating data connection is suspended due to temporary reasons, for example, out of 318 // service, concurrency voice/data not supported, etc.. Note this flag is only meaningful when 319 // data is in active state. When data is in inactive, connecting, or disconnecting, this flag 320 // is unmeaningful. 321 private boolean mIsSuspended; 322 private int mDownlinkBandwidth = 14; 323 private int mUplinkBandwidth = 14; 324 private Qos mDefaultQos = null; 325 private List<QosBearerSession> mQosBearerSessions = new ArrayList<>(); 326 private NetworkSliceInfo mSliceInfo; 327 private List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>(); 328 329 /** The corresponding network agent for this data connection. */ 330 private DcNetworkAgent mNetworkAgent; 331 332 /** 333 * The network agent from handover source data connection. This is the potential network agent 334 * that will be transferred here after handover completed. 335 */ 336 private DcNetworkAgent mHandoverSourceNetworkAgent; 337 338 private int mDisabledApnTypeBitMask = 0; 339 340 int mTag; 341 342 /** Data connection id assigned by the modem. This is unique across transports */ 343 public int mCid; 344 345 @HandoverState 346 private int mHandoverState = HANDOVER_STATE_IDLE; 347 private final Map<ApnContext, ConnectionParams> mApnContexts = new ConcurrentHashMap<>(); 348 PendingIntent mReconnectIntent = null; 349 350 /** Class used to track VCN-defined Network policies for this DcNetworkAgent. */ 351 private final VcnNetworkPolicyChangeListener mVcnPolicyChangeListener = 352 new DataConnectionVcnNetworkPolicyChangeListener(); 353 354 // ***** Event codes for driving the state machine, package visible for Dcc 355 static final int BASE = Protocol.BASE_DATA_CONNECTION; 356 static final int EVENT_CONNECT = BASE + 0; 357 static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1; 358 static final int EVENT_DEACTIVATE_DONE = BASE + 3; 359 static final int EVENT_DISCONNECT = BASE + 4; 360 static final int EVENT_DISCONNECT_ALL = BASE + 6; 361 static final int EVENT_DATA_STATE_CHANGED = BASE + 7; 362 static final int EVENT_TEAR_DOWN_NOW = BASE + 8; 363 static final int EVENT_LOST_CONNECTION = BASE + 9; 364 static final int EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED = BASE + 11; 365 static final int EVENT_DATA_CONNECTION_ROAM_ON = BASE + 12; 366 static final int EVENT_DATA_CONNECTION_ROAM_OFF = BASE + 13; 367 static final int EVENT_BW_REFRESH_RESPONSE = BASE + 14; 368 static final int EVENT_DATA_CONNECTION_VOICE_CALL_STARTED = BASE + 15; 369 static final int EVENT_DATA_CONNECTION_VOICE_CALL_ENDED = BASE + 16; 370 static final int EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED = BASE + 17; 371 static final int EVENT_KEEPALIVE_STATUS = BASE + 18; 372 static final int EVENT_KEEPALIVE_STARTED = BASE + 19; 373 static final int EVENT_KEEPALIVE_STOPPED = BASE + 20; 374 static final int EVENT_KEEPALIVE_START_REQUEST = BASE + 21; 375 static final int EVENT_KEEPALIVE_STOP_REQUEST = BASE + 22; 376 static final int EVENT_LINK_CAPACITY_CHANGED = BASE + 23; 377 static final int EVENT_RESET = BASE + 24; 378 static final int EVENT_REEVALUATE_RESTRICTED_STATE = BASE + 25; 379 static final int EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES = BASE + 26; 380 static final int EVENT_NR_STATE_CHANGED = BASE + 27; 381 static final int EVENT_DATA_CONNECTION_METEREDNESS_CHANGED = BASE + 28; 382 static final int EVENT_NR_FREQUENCY_CHANGED = BASE + 29; 383 static final int EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED = BASE + 30; 384 static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = BASE + 31; 385 static final int EVENT_CSS_INDICATOR_CHANGED = BASE + 32; 386 static final int EVENT_UPDATE_SUSPENDED_STATE = BASE + 33; 387 static final int EVENT_START_HANDOVER = BASE + 34; 388 static final int EVENT_CANCEL_HANDOVER = BASE + 35; 389 static final int EVENT_START_HANDOVER_ON_TARGET = BASE + 36; 390 static final int EVENT_ALLOCATE_PDU_SESSION_ID = BASE + 37; 391 static final int EVENT_RELEASE_PDU_SESSION_ID = BASE + 38; 392 static final int EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE = BASE + 39; 393 private static final int CMD_TO_STRING_COUNT = EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE - BASE + 1; 394 395 private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT]; 396 static { 397 sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT"; 398 sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] = 399 "EVENT_SETUP_DATA_CONNECTION_DONE"; 400 sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE"; 401 sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT"; 402 sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL"; 403 sCmdToString[EVENT_DATA_STATE_CHANGED - BASE] = "EVENT_DATA_STATE_CHANGED"; 404 sCmdToString[EVENT_TEAR_DOWN_NOW - BASE] = "EVENT_TEAR_DOWN_NOW"; 405 sCmdToString[EVENT_LOST_CONNECTION - BASE] = "EVENT_LOST_CONNECTION"; 406 sCmdToString[EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED - BASE] = 407 "EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"; 408 sCmdToString[EVENT_DATA_CONNECTION_ROAM_ON - BASE] = "EVENT_DATA_CONNECTION_ROAM_ON"; 409 sCmdToString[EVENT_DATA_CONNECTION_ROAM_OFF - BASE] = "EVENT_DATA_CONNECTION_ROAM_OFF"; 410 sCmdToString[EVENT_BW_REFRESH_RESPONSE - BASE] = "EVENT_BW_REFRESH_RESPONSE"; 411 sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_STARTED - BASE] = 412 "EVENT_DATA_CONNECTION_VOICE_CALL_STARTED"; 413 sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_ENDED - BASE] = 414 "EVENT_DATA_CONNECTION_VOICE_CALL_ENDED"; 415 sCmdToString[EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED - BASE] = 416 "EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED"; 417 sCmdToString[EVENT_KEEPALIVE_STATUS - BASE] = "EVENT_KEEPALIVE_STATUS"; 418 sCmdToString[EVENT_KEEPALIVE_STARTED - BASE] = "EVENT_KEEPALIVE_STARTED"; 419 sCmdToString[EVENT_KEEPALIVE_STOPPED - BASE] = "EVENT_KEEPALIVE_STOPPED"; 420 sCmdToString[EVENT_KEEPALIVE_START_REQUEST - BASE] = "EVENT_KEEPALIVE_START_REQUEST"; 421 sCmdToString[EVENT_KEEPALIVE_STOP_REQUEST - BASE] = "EVENT_KEEPALIVE_STOP_REQUEST"; 422 sCmdToString[EVENT_LINK_CAPACITY_CHANGED - BASE] = "EVENT_LINK_CAPACITY_CHANGED"; 423 sCmdToString[EVENT_RESET - BASE] = "EVENT_RESET"; 424 sCmdToString[EVENT_REEVALUATE_RESTRICTED_STATE - BASE] = 425 "EVENT_REEVALUATE_RESTRICTED_STATE"; 426 sCmdToString[EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES - BASE] = 427 "EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES"; 428 sCmdToString[EVENT_NR_STATE_CHANGED - BASE] = "EVENT_NR_STATE_CHANGED"; 429 sCmdToString[EVENT_DATA_CONNECTION_METEREDNESS_CHANGED - BASE] = 430 "EVENT_DATA_CONNECTION_METEREDNESS_CHANGED"; 431 sCmdToString[EVENT_NR_FREQUENCY_CHANGED - BASE] = "EVENT_NR_FREQUENCY_CHANGED"; 432 sCmdToString[EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED - BASE] = 433 "EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED"; 434 sCmdToString[EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED - BASE] = 435 "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED"; 436 sCmdToString[EVENT_CSS_INDICATOR_CHANGED - BASE] = "EVENT_CSS_INDICATOR_CHANGED"; 437 sCmdToString[EVENT_UPDATE_SUSPENDED_STATE - BASE] = "EVENT_UPDATE_SUSPENDED_STATE"; 438 sCmdToString[EVENT_START_HANDOVER - BASE] = "EVENT_START_HANDOVER"; 439 sCmdToString[EVENT_CANCEL_HANDOVER - BASE] = "EVENT_CANCEL_HANDOVER"; 440 sCmdToString[EVENT_START_HANDOVER_ON_TARGET - BASE] = "EVENT_START_HANDOVER_ON_TARGET"; 441 sCmdToString[EVENT_ALLOCATE_PDU_SESSION_ID - BASE] = "EVENT_ALLOCATE_PDU_SESSION_ID"; 442 sCmdToString[EVENT_RELEASE_PDU_SESSION_ID - BASE] = "EVENT_RELEASE_PDU_SESSION_ID"; 443 sCmdToString[EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE - BASE] = 444 "EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE"; 445 } 446 // Convert cmd to string or null if unknown cmdToString(int cmd)447 static String cmdToString(int cmd) { 448 String value = null; 449 cmd -= BASE; 450 if ((cmd >= 0) && (cmd < sCmdToString.length)) { 451 value = sCmdToString[cmd]; 452 } 453 if (value == null) { 454 value = "0x" + Integer.toHexString(cmd + BASE); 455 } 456 return value; 457 } 458 459 /** 460 * Create the connection object 461 * 462 * @param phone the Phone 463 * @param id the connection id 464 * @return DataConnection that was created. 465 */ makeDataConnection(Phone phone, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc, boolean doAllocatePduSessionId)466 public static DataConnection makeDataConnection(Phone phone, int id, DcTracker dct, 467 DataServiceManager dataServiceManager, 468 DcTesterFailBringUpAll failBringUpAll, 469 DcController dcc, 470 boolean doAllocatePduSessionId) { 471 String transportType = (dataServiceManager.getTransportType() 472 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 473 ? "C" // Cellular 474 : "I"; // IWLAN 475 DataConnection dc = new DataConnection(phone, transportType + "-" 476 + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll, 477 dcc, doAllocatePduSessionId); 478 dc.start(); 479 if (DBG) dc.log("Made " + dc.getName()); 480 return dc; 481 } 482 dispose()483 void dispose() { 484 log("dispose: call quiteNow()"); 485 quitNow(); 486 } 487 488 /* Getter functions */ 489 getLinkProperties()490 LinkProperties getLinkProperties() { 491 return new LinkProperties(mLinkProperties); 492 } 493 isDisconnecting()494 boolean isDisconnecting() { 495 return getCurrentState() == mDisconnectingState 496 || getCurrentState() == mDisconnectingErrorCreatingConnection; 497 } 498 499 @VisibleForTesting isActive()500 public boolean isActive() { 501 return getCurrentState() == mActiveState; 502 } 503 504 @VisibleForTesting isInactive()505 public boolean isInactive() { 506 return getCurrentState() == mInactiveState; 507 } 508 isActivating()509 boolean isActivating() { 510 return getCurrentState() == mActivatingState; 511 } 512 hasBeenTransferred()513 boolean hasBeenTransferred() { 514 return mHandoverState == HANDOVER_STATE_COMPLETED; 515 } 516 getCid()517 int getCid() { 518 return mCid; 519 } 520 521 /** 522 * @return DataConnection's ApnSetting. 523 */ getApnSetting()524 public ApnSetting getApnSetting() { 525 return mApnSetting; 526 } 527 528 /** 529 * Update http proxy of link properties based on current apn setting 530 */ updateLinkPropertiesHttpProxy()531 private void updateLinkPropertiesHttpProxy() { 532 if (mApnSetting == null 533 || TextUtils.isEmpty(mApnSetting.getProxyAddressAsString())) { 534 return; 535 } 536 try { 537 int port = mApnSetting.getProxyPort(); 538 if (port == -1) { 539 port = 8080; 540 } 541 ProxyInfo proxy = ProxyInfo.buildDirectProxy( 542 mApnSetting.getProxyAddressAsString(), port); 543 mLinkProperties.setHttpProxy(proxy); 544 } catch (NumberFormatException e) { 545 loge("onDataSetupComplete: NumberFormatException making ProxyProperties (" 546 + mApnSetting.getProxyPort() + "): " + e); 547 } 548 } 549 550 public static class UpdateLinkPropertyResult { 551 public SetupResult setupResult = SetupResult.SUCCESS; 552 public LinkProperties oldLp; 553 public LinkProperties newLp; UpdateLinkPropertyResult(LinkProperties curLp)554 public UpdateLinkPropertyResult(LinkProperties curLp) { 555 oldLp = curLp; 556 newLp = curLp; 557 } 558 } 559 560 /** 561 * Class returned by onSetupConnectionCompleted. 562 */ 563 public enum SetupResult { 564 SUCCESS, 565 ERROR_RADIO_NOT_AVAILABLE, 566 ERROR_INVALID_ARG, 567 ERROR_STALE, 568 ERROR_DATA_SERVICE_SPECIFIC_ERROR, 569 ERROR_DUPLICATE_CID, 570 ERROR_NO_DEFAULT_CONNECTION; 571 572 public int mFailCause; 573 SetupResult()574 SetupResult() { 575 mFailCause = DataFailCause.getFailCause(0); 576 } 577 578 @Override toString()579 public String toString() { 580 return name() + " SetupResult.mFailCause=" + DataFailCause.toString(mFailCause); 581 } 582 } 583 isIpv4Connected()584 public boolean isIpv4Connected() { 585 boolean ret = false; 586 Collection <InetAddress> addresses = mLinkProperties.getAddresses(); 587 588 for (InetAddress addr: addresses) { 589 if (addr instanceof java.net.Inet4Address) { 590 java.net.Inet4Address i4addr = (java.net.Inet4Address) addr; 591 if (!i4addr.isAnyLocalAddress() && !i4addr.isLinkLocalAddress() && 592 !i4addr.isLoopbackAddress() && !i4addr.isMulticastAddress()) { 593 ret = true; 594 break; 595 } 596 } 597 } 598 return ret; 599 } 600 isIpv6Connected()601 public boolean isIpv6Connected() { 602 boolean ret = false; 603 Collection <InetAddress> addresses = mLinkProperties.getAddresses(); 604 605 for (InetAddress addr: addresses) { 606 if (addr instanceof java.net.Inet6Address) { 607 java.net.Inet6Address i6addr = (java.net.Inet6Address) addr; 608 if (!i6addr.isAnyLocalAddress() && !i6addr.isLinkLocalAddress() && 609 !i6addr.isLoopbackAddress() && !i6addr.isMulticastAddress()) { 610 ret = true; 611 break; 612 } 613 } 614 } 615 return ret; 616 } 617 getPduSessionId()618 public int getPduSessionId() { 619 return mPduSessionId; 620 } 621 getSliceInfo()622 public NetworkSliceInfo getSliceInfo() { 623 return mSliceInfo; 624 } 625 getTrafficDescriptors()626 public List<TrafficDescriptor> getTrafficDescriptors() { 627 return mTrafficDescriptors; 628 } 629 630 /** 631 * Update DC fields based on a new DataCallResponse 632 * @param response the response to use to update DC fields 633 */ updateResponseFields(DataCallResponse response)634 public void updateResponseFields(DataCallResponse response) { 635 updateQosParameters(response); 636 updateSliceInfo(response); 637 updateTrafficDescriptors(response); 638 } 639 updateQosParameters(final @Nullable DataCallResponse response)640 public void updateQosParameters(final @Nullable DataCallResponse response) { 641 if (response == null) { 642 mDefaultQos = null; 643 mQosBearerSessions.clear(); 644 return; 645 } 646 647 mDefaultQos = response.getDefaultQos(); 648 mQosBearerSessions = response.getQosBearerSessions(); 649 650 if (mNetworkAgent != null) { 651 syncQosToNetworkAgent(); 652 } 653 } 654 syncQosToNetworkAgent()655 private void syncQosToNetworkAgent() { 656 final DcNetworkAgent networkAgent = mNetworkAgent; 657 final List<QosBearerSession> qosBearerSessions = mQosBearerSessions; 658 if (qosBearerSessions == null) { 659 networkAgent.updateQosBearerSessions(new ArrayList<>()); 660 return; 661 } 662 networkAgent.updateQosBearerSessions(qosBearerSessions); 663 } 664 665 /** 666 * Update the latest slice info on this data connection with 667 * {@link DataCallResponse#getSliceInfo}. 668 */ updateSliceInfo(DataCallResponse response)669 public void updateSliceInfo(DataCallResponse response) { 670 mSliceInfo = response.getSliceInfo(); 671 } 672 673 /** 674 * Update the latest traffic descriptor on this data connection with 675 * {@link DataCallResponse#getTrafficDescriptors}. 676 */ updateTrafficDescriptors(DataCallResponse response)677 public void updateTrafficDescriptors(DataCallResponse response) { 678 mTrafficDescriptors = response.getTrafficDescriptors(); 679 } 680 681 @VisibleForTesting updateLinkProperty(DataCallResponse newState)682 public UpdateLinkPropertyResult updateLinkProperty(DataCallResponse newState) { 683 UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties); 684 685 if (newState == null) return result; 686 687 result.newLp = new LinkProperties(); 688 689 // set link properties based on data call response 690 result.setupResult = setLinkProperties(newState, result.newLp); 691 if (result.setupResult != SetupResult.SUCCESS) { 692 if (DBG) log("updateLinkProperty failed : " + result.setupResult); 693 return result; 694 } 695 // copy HTTP proxy as it is not part DataCallResponse. 696 result.newLp.setHttpProxy(mLinkProperties.getHttpProxy()); 697 698 checkSetMtu(mApnSetting, result.newLp); 699 700 mLinkProperties = result.newLp; 701 702 updateTcpBufferSizes(mRilRat); 703 704 if (DBG && (! result.oldLp.equals(result.newLp))) { 705 log("updateLinkProperty old LP=" + result.oldLp); 706 log("updateLinkProperty new LP=" + result.newLp); 707 } 708 709 if (result.newLp.equals(result.oldLp) == false && 710 mNetworkAgent != null) { 711 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 712 } 713 714 return result; 715 } 716 717 /** 718 * Sets the pdu session id of the data connection 719 * @param pduSessionId pdu session id to set 720 */ 721 @VisibleForTesting setPduSessionId(int pduSessionId)722 public void setPduSessionId(int pduSessionId) { 723 if (mPduSessionId != pduSessionId) { 724 logd("Changing pdu session id from: " + mPduSessionId + " to: " + pduSessionId + ", " 725 + "Handover state: " + handoverStateToString(this.mHandoverState)); 726 mPduSessionId = pduSessionId; 727 } 728 } 729 730 /** 731 * Read the MTU value from link properties where it can be set from network. In case 732 * not set by the network, set it again using the mtu szie value defined in the APN 733 * database for the connected APN 734 */ checkSetMtu(ApnSetting apn, LinkProperties lp)735 private void checkSetMtu(ApnSetting apn, LinkProperties lp) { 736 if (lp == null) return; 737 738 if (apn == null || lp == null) return; 739 740 if (lp.getMtu() != PhoneConstants.UNSET_MTU) { 741 if (DBG) log("MTU set by call response to: " + lp.getMtu()); 742 return; 743 } 744 745 if (apn != null && apn.getMtu() != PhoneConstants.UNSET_MTU) { 746 lp.setMtu(apn.getMtu()); 747 if (DBG) log("MTU set by APN to: " + apn.getMtu()); 748 return; 749 } 750 751 int mtu = mPhone.getContext().getResources().getInteger( 752 com.android.internal.R.integer.config_mobile_mtu); 753 if (mtu != PhoneConstants.UNSET_MTU) { 754 lp.setMtu(mtu); 755 if (DBG) log("MTU set by config resource to: " + mtu); 756 } 757 } 758 759 //***** Constructor (NOTE: uses dcc.getHandler() as its Handler) DataConnection(Phone phone, String tagSuffix, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc, boolean doAllocatePduSessionId)760 private DataConnection(Phone phone, String tagSuffix, int id, 761 DcTracker dct, DataServiceManager dataServiceManager, 762 DcTesterFailBringUpAll failBringUpAll, DcController dcc, 763 boolean doAllocatePduSessionId) { 764 super("DC-" + tagSuffix, dcc); 765 mTagSuffix = tagSuffix; 766 setLogRecSize(300); 767 setLogOnlyTransitions(true); 768 if (DBG) log("DataConnection created"); 769 770 mPhone = phone; 771 mDct = dct; 772 mDataServiceManager = dataServiceManager; 773 mVcnManager = mPhone.getContext().getSystemService(VcnManager.class); 774 mTransportType = dataServiceManager.getTransportType(); 775 mDcTesterFailBringUpAll = failBringUpAll; 776 mDcController = dcc; 777 mId = id; 778 mCid = -1; 779 mDataRegState = mPhone.getServiceState().getDataRegistrationState(); 780 mIsSuspended = false; 781 mDataCallSessionStats = new DataCallSessionStats(mPhone); 782 mDoAllocatePduSessionId = doAllocatePduSessionId; 783 784 int networkType = getNetworkType(); 785 mRilRat = ServiceState.networkTypeToRilRadioTechnology(networkType); 786 updateLinkBandwidthsFromCarrierConfig(mRilRat); 787 788 addState(mDefaultState); 789 addState(mInactiveState, mDefaultState); 790 addState(mActivatingState, mDefaultState); 791 addState(mActiveState, mDefaultState); 792 addState(mDisconnectingState, mDefaultState); 793 addState(mDisconnectingErrorCreatingConnection, mDefaultState); 794 setInitialState(mInactiveState); 795 } 796 getNetworkType()797 private @NetworkType int getNetworkType() { 798 ServiceState ss = mPhone.getServiceState(); 799 int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 800 801 NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo( 802 NetworkRegistrationInfo.DOMAIN_PS, mTransportType); 803 if (nri != null) { 804 networkType = nri.getAccessNetworkTechnology(); 805 } 806 807 return networkType; 808 } 809 810 /** 811 * Get the source transport for handover. For example, handover from WWAN to WLAN, WWAN is the 812 * source transport, and vice versa. 813 */ getHandoverSourceTransport()814 private @TransportType int getHandoverSourceTransport() { 815 return mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 816 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN 817 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN; 818 } 819 820 /** 821 * API to generate the OsAppId for enterprise traffic category. 822 * @return byte[] representing OsId + length of OsAppId + OsAppId 823 */ 824 @VisibleForTesting getEnterpriseOsAppId()825 public static byte[] getEnterpriseOsAppId() { 826 byte[] osAppId = NetworkCapabilities.getCapabilityCarrierName( 827 NetworkCapabilities.NET_CAPABILITY_ENTERPRISE).getBytes(); 828 // 16 bytes for UUID, 1 byte for length of osAppId, and up to 255 bytes for osAppId 829 ByteBuffer bb = ByteBuffer.allocate(16 + 1 + osAppId.length); 830 bb.putLong(OS_ID.getMostSignificantBits()); 831 bb.putLong(OS_ID.getLeastSignificantBits()); 832 bb.put((byte) osAppId.length); 833 bb.put(osAppId); 834 if (VDBG) { 835 Rlog.d("DataConnection", "getEnterpriseOsAppId: " 836 + IccUtils.bytesToHexString(bb.array())); 837 } 838 return bb.array(); 839 } 840 841 /** 842 * Begin setting up a data connection, calls setupDataCall 843 * and the ConnectionParams will be returned with the 844 * EVENT_SETUP_DATA_CONNECTION_DONE 845 * 846 * @param cp is the connection parameters 847 * 848 * @return Fail cause if failed to setup data connection. {@link DataFailCause#NONE} if success. 849 */ connect(ConnectionParams cp)850 private @DataFailureCause int connect(ConnectionParams cp) { 851 log("connect: carrier='" + mApnSetting.getEntryName() 852 + "' APN='" + mApnSetting.getApnName() 853 + "' proxy='" + mApnSetting.getProxyAddressAsString() 854 + "' port='" + mApnSetting.getProxyPort() + "'"); 855 if (cp.mApnContext != null) cp.mApnContext.requestLog("DataConnection.connect"); 856 857 // Check if we should fake an error. 858 if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter > 0) { 859 DataCallResponse response = new DataCallResponse.Builder() 860 .setCause(mDcTesterFailBringUpAll.getDcFailBringUp().mFailCause) 861 .setRetryDurationMillis( 862 mDcTesterFailBringUpAll.getDcFailBringUp().mSuggestedRetryTime) 863 .setMtuV4(PhoneConstants.UNSET_MTU) 864 .setMtuV6(PhoneConstants.UNSET_MTU) 865 .build(); 866 867 Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp); 868 AsyncResult.forMessage(msg, response, null); 869 sendMessage(msg); 870 if (DBG) { 871 log("connect: FailBringUpAll=" + mDcTesterFailBringUpAll.getDcFailBringUp() 872 + " send error response=" + response); 873 } 874 mDcTesterFailBringUpAll.getDcFailBringUp().mCounter -= 1; 875 return DataFailCause.NONE; 876 } 877 878 mCreateTime = -1; 879 mLastFailTime = -1; 880 mLastFailCause = DataFailCause.NONE; 881 882 Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp); 883 msg.obj = cp; 884 885 DataProfile dp = DcTracker.createDataProfile(mApnSetting, cp.mProfileId, 886 cp.mIsPreferredApn); 887 888 // We need to use the actual modem roaming state instead of the framework roaming state 889 // here. This flag is only passed down to ril_service for picking the correct protocol (for 890 // old modem backward compatibility). 891 boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration(); 892 893 // If the apn is NOT metered, we will allow data roaming regardless of the setting. 894 boolean isUnmeteredApnType = !ApnSettingUtils.isMeteredApnType( 895 cp.mApnContext.getApnTypeBitmask(), mPhone); 896 897 // Set this flag to true if the user turns on data roaming. Or if we override the roaming 898 // state in framework, we should set this flag to true as well so the modem will not reject 899 // the data call setup (because the modem actually thinks the device is roaming). 900 boolean allowRoaming = mPhone.getDataRoamingEnabled() 901 || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming() 902 || isUnmeteredApnType)); 903 904 String dnn = null; 905 byte[] osAppId = null; 906 if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) { 907 osAppId = getEnterpriseOsAppId(); 908 } else { 909 dnn = mApnSetting.getApnName(); 910 } 911 final TrafficDescriptor td = osAppId == null && dnn == null ? null 912 : new TrafficDescriptor(dnn, osAppId); 913 final boolean matchAllRuleAllowed = td == null || td.getOsAppId() == null; 914 915 if (DBG) { 916 log("allowRoaming=" + allowRoaming 917 + ", mPhone.getDataRoamingEnabled()=" + mPhone.getDataRoamingEnabled() 918 + ", isModemRoaming=" + isModemRoaming 919 + ", mPhone.getServiceState().getDataRoaming()=" 920 + mPhone.getServiceState().getDataRoaming() 921 + ", isUnmeteredApnType=" + isUnmeteredApnType 922 + ", trafficDescriptor=" + td 923 + ", matchAllRuleAllowed=" + matchAllRuleAllowed 924 ); 925 } 926 927 // Check if this data setup is a handover. 928 LinkProperties linkProperties = null; 929 int reason = DataService.REQUEST_REASON_NORMAL; 930 if (cp.mRequestType == REQUEST_TYPE_HANDOVER) { 931 // If this is a data setup for handover, we need to pass the link properties 932 // of the existing data connection to the modem. 933 DcTracker srcDcTracker = mPhone.getDcTracker(getHandoverSourceTransport()); 934 if (srcDcTracker == null || cp.mApnContext == null) { 935 loge("connect: Handover failed. dcTracker=" + srcDcTracker + ", apnContext=" 936 + cp.mApnContext); 937 return DataFailCause.HANDOVER_FAILED; 938 } 939 940 941 // srcDc is the source data connection while the current instance is the target 942 DataConnection srcDc = 943 srcDcTracker.getDataConnectionByApnType(cp.mApnContext.getApnType()); 944 if (srcDc == null) { 945 loge("connect: Can't find data connection for handover."); 946 return DataFailCause.HANDOVER_FAILED; 947 } 948 949 // Helpful for logging purposes 950 DataServiceManager srcDsm = srcDc.mDataServiceManager; 951 String srcDsmTag = (srcDsm == null ? "(null)" : srcDsm.getTag()); 952 logd("connect: REQUEST_TYPE_HANDOVER - Request handover from " + srcDc.getName() 953 + ", targetDsm=" + mDataServiceManager.getTag() 954 + ", sourceDsm=" + srcDsmTag); 955 956 957 /* startHandover is called on the source data connection, and if successful, 958 we ask the target data connection (which is the current instance) to call 959 #setupDataCall with request type handover. 960 */ 961 Consumer<Integer> onCompleted = (dataServiceCallbackResultCode) -> 962 /* startHandover is called on the srcDc handler, but the callback needs to 963 be called on the current (which is the targetDc) handler which is why we 964 call sendRunnableMessage. */ 965 sendRunnableMessage(EVENT_START_HANDOVER_ON_TARGET, 966 (inCorrectState) -> requestHandover(inCorrectState, srcDc, 967 dataServiceCallbackResultCode, 968 cp, msg, dp, isModemRoaming, allowRoaming)); 969 srcDc.startHandover(onCompleted); 970 return DataFailCause.NONE; 971 } 972 973 // setup data call for REQUEST_TYPE_NORMAL 974 allocatePduSessionId(psi -> { 975 this.setPduSessionId(psi); 976 mDataServiceManager.setupDataCall( 977 ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat), 978 dp, 979 isModemRoaming, 980 allowRoaming, 981 reason, 982 linkProperties, 983 psi, 984 null, //slice info is null since this is not a handover 985 td, 986 matchAllRuleAllowed, 987 msg); 988 TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat, 989 dp.getProfileId(), dp.getApn(), dp.getProtocolType()); 990 }); 991 return DataFailCause.NONE; 992 } 993 allocatePduSessionId(Consumer<Integer> allocateCallback)994 private void allocatePduSessionId(Consumer<Integer> allocateCallback) { 995 if (getDoAllocatePduSessionId()) { 996 Message msg = this.obtainMessage(EVENT_ALLOCATE_PDU_SESSION_ID); 997 msg.obj = allocateCallback; 998 mPhone.mCi.allocatePduSessionId(msg); 999 } else { 1000 allocateCallback.accept(PDU_SESSION_ID_NOT_SET); 1001 } 1002 } 1003 onRquestHandoverFailed(ConnectionParams cp)1004 private void onRquestHandoverFailed(ConnectionParams cp) { 1005 sendMessage(obtainMessage(EVENT_CANCEL_HANDOVER)); 1006 notifyConnectCompleted(cp, DataFailCause.UNKNOWN, 1007 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 1008 } 1009 requestHandover(boolean inCorrectState, DataConnection srcDc, @DataServiceCallback.ResultCode int resultCode, ConnectionParams cp, Message msg, DataProfile dp, boolean isModemRoaming, boolean allowRoaming)1010 private void requestHandover(boolean inCorrectState, DataConnection srcDc, 1011 @DataServiceCallback.ResultCode int resultCode, 1012 ConnectionParams cp, Message msg, DataProfile dp, boolean isModemRoaming, 1013 boolean allowRoaming) { 1014 1015 if (!inCorrectState) { 1016 logd("requestHandover: Not in correct state"); 1017 if (isResultCodeSuccess(resultCode)) { 1018 if (srcDc != null) { 1019 logd("requestHandover: Not in correct state - Success result code"); 1020 // We need to cancel the handover on source if we ended up in the wrong state. 1021 srcDc.cancelHandover(); 1022 } else { 1023 logd("requestHandover: Not in correct state - Success result code - " 1024 + "srcdc = null"); 1025 } 1026 } 1027 onRquestHandoverFailed(cp); 1028 return; 1029 } else if (!isResultCodeSuccess(resultCode)) { 1030 if (DBG) { 1031 logd("requestHandover: Non success result code from DataService, " 1032 + "setupDataCall will not be called, result code = " 1033 + DataServiceCallback.resultCodeToString(resultCode)); 1034 } 1035 onRquestHandoverFailed(cp); 1036 return; 1037 } 1038 1039 if (srcDc == null) { 1040 loge("requestHandover: Cannot find source data connection."); 1041 onRquestHandoverFailed(cp); 1042 return; 1043 } 1044 1045 LinkProperties linkProperties; 1046 int reason; 1047 1048 // Preserve the potential network agent from the source data connection. The ownership 1049 // is not transferred at this moment. 1050 mHandoverSourceNetworkAgent = srcDc.getNetworkAgent(); 1051 if (mHandoverSourceNetworkAgent == null) { 1052 loge("requestHandover: Cannot get network agent from the source dc " + srcDc.getName()); 1053 onRquestHandoverFailed(cp); 1054 return; 1055 } 1056 1057 linkProperties = srcDc.getLinkProperties(); 1058 if (linkProperties == null || linkProperties.getLinkAddresses().isEmpty()) { 1059 loge("requestHandover: Can't find link properties of handover data connection. dc=" 1060 + srcDc); 1061 onRquestHandoverFailed(cp); 1062 return; 1063 } 1064 1065 mHandoverLocalLog.log("Handover started. Preserved the agent."); 1066 log("Get the handover source network agent: " + mHandoverSourceNetworkAgent); 1067 1068 reason = DataService.REQUEST_REASON_HANDOVER; 1069 1070 TrafficDescriptor td = dp.getApn() == null ? null 1071 : new TrafficDescriptor(dp.getApn(), null); 1072 boolean matchAllRuleAllowed = true; 1073 1074 mDataServiceManager.setupDataCall( 1075 ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat), 1076 dp, 1077 isModemRoaming, 1078 allowRoaming, 1079 reason, 1080 linkProperties, 1081 srcDc.getPduSessionId(), 1082 srcDc.getSliceInfo(), 1083 td, 1084 matchAllRuleAllowed, 1085 msg); 1086 TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat, 1087 dp.getProfileId(), dp.getApn(), dp.getProtocolType()); 1088 } 1089 1090 /** 1091 * Called on the source data connection from the target data connection. 1092 */ 1093 @VisibleForTesting startHandover(Consumer<Integer> onTargetDcComplete)1094 public void startHandover(Consumer<Integer> onTargetDcComplete) { 1095 logd("startHandover: " + toStringSimple()); 1096 // Set the handover state to being transferred on "this" data connection which is the src. 1097 setHandoverState(HANDOVER_STATE_BEING_TRANSFERRED); 1098 1099 Consumer<Integer> onSrcDcComplete = 1100 resultCode -> onHandoverStarted(resultCode, onTargetDcComplete); 1101 /* 1102 The flow here is: 1103 srcDc#startHandover -> dataService#startHandover -> (onHandoverStarted) -> 1104 onSrcDcComplete -> onTargetDcComplete 1105 */ 1106 mDataServiceManager.startHandover(mCid, 1107 this.obtainMessage(EVENT_START_HANDOVER, 1108 onSrcDcComplete)); 1109 } 1110 1111 /** 1112 * Called on the source data connection when the async call to start handover is complete 1113 */ onHandoverStarted(@ataServiceCallback.ResultCode int resultCode, Consumer<Integer> onTargetDcComplete)1114 private void onHandoverStarted(@DataServiceCallback.ResultCode int resultCode, 1115 Consumer<Integer> onTargetDcComplete) { 1116 logd("onHandoverStarted: " + toStringSimple()); 1117 if (!isResultCodeSuccess(resultCode)) { 1118 setHandoverState(HANDOVER_STATE_IDLE); 1119 } 1120 onTargetDcComplete.accept(resultCode); 1121 } 1122 cancelHandover()1123 private void cancelHandover() { 1124 if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED) { 1125 logd("cancelHandover: handover state is " + handoverStateToString(mHandoverState) 1126 + ", expecting HANDOVER_STATE_BEING_TRANSFERRED"); 1127 } 1128 mDataServiceManager.cancelHandover(mCid, this.obtainMessage(EVENT_CANCEL_HANDOVER)); 1129 setHandoverState(HANDOVER_STATE_IDLE); 1130 } 1131 1132 /** 1133 * Update NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED based on congested override 1134 * @param isCongested whether this DC should be set to congested or not 1135 */ onCongestednessChanged(boolean isCongested)1136 public void onCongestednessChanged(boolean isCongested) { 1137 sendMessage(obtainMessage(EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED, isCongested)); 1138 } 1139 1140 /** 1141 * Update NetworkCapabilities.NET_CAPABILITY_NOT_METERED based on metered override 1142 * @param isUnmetered whether this DC should be set to unmetered or not 1143 */ onMeterednessChanged(boolean isUnmetered)1144 public void onMeterednessChanged(boolean isUnmetered) { 1145 sendMessage(obtainMessage(EVENT_DATA_CONNECTION_METEREDNESS_CHANGED, isUnmetered)); 1146 } 1147 1148 /** 1149 * TearDown the data connection when the deactivation is complete a Message with 1150 * msg.what == EVENT_DEACTIVATE_DONE 1151 * 1152 * @param o is the object returned in the AsyncResult.obj. 1153 */ tearDownData(Object o)1154 private void tearDownData(Object o) { 1155 int discReason = DataService.REQUEST_REASON_NORMAL; 1156 ApnContext apnContext = null; 1157 if ((o != null) && (o instanceof DisconnectParams)) { 1158 DisconnectParams dp = (DisconnectParams) o; 1159 apnContext = dp.mApnContext; 1160 if (TextUtils.equals(dp.mReason, Phone.REASON_RADIO_TURNED_OFF) 1161 || TextUtils.equals(dp.mReason, Phone.REASON_PDP_RESET)) { 1162 discReason = DataService.REQUEST_REASON_SHUTDOWN; 1163 } else if (dp.mReleaseType == DcTracker.RELEASE_TYPE_HANDOVER) { 1164 discReason = DataService.REQUEST_REASON_HANDOVER; 1165 } 1166 } 1167 1168 String str = "tearDownData. mCid=" + mCid + ", reason=" + discReason; 1169 if (DBG) log(str); 1170 if (apnContext != null) apnContext.requestLog(str); 1171 1172 1173 //Needed to be final to work in a closure 1174 final int fDiscReason = discReason; 1175 releasePduSessionId(() -> { 1176 // This is run after release pdu session id is complete 1177 this.setPduSessionId(PDU_SESSION_ID_NOT_SET); 1178 mDataServiceManager.deactivateDataCall(mCid, fDiscReason, 1179 obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, o)); 1180 mDataCallSessionStats.setDeactivateDataCallReason(fDiscReason); 1181 }); 1182 } 1183 releasePduSessionId(Runnable releaseCallback)1184 private void releasePduSessionId(Runnable releaseCallback) { 1185 // If we are not in the middle of a handover and have a real pdu session id, then we release 1186 if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED 1187 && this.getPduSessionId() != PDU_SESSION_ID_NOT_SET) { 1188 Message msg = this.obtainMessage(EVENT_RELEASE_PDU_SESSION_ID); 1189 msg.obj = releaseCallback; 1190 mPhone.mCi.releasePduSessionId(msg, this.getPduSessionId()); 1191 } else { 1192 // Just go and run the callback since we either have no pdu session id to release 1193 // or we are in the middle of a handover 1194 releaseCallback.run(); 1195 } 1196 } 1197 notifyAllWithEvent(ApnContext alreadySent, int event, String reason)1198 private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) { 1199 for (ConnectionParams cp : mApnContexts.values()) { 1200 ApnContext apnContext = cp.mApnContext; 1201 if (apnContext == alreadySent) continue; 1202 if (reason != null) apnContext.setReason(reason); 1203 Pair<ApnContext, Integer> pair = new Pair<>(apnContext, cp.mConnectionGeneration); 1204 Message msg = mDct.obtainMessage(event, cp.mRequestType, 1205 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, pair); 1206 AsyncResult.forMessage(msg); 1207 msg.sendToTarget(); 1208 } 1209 } 1210 1211 /** 1212 * Send the connectionCompletedMsg. 1213 * 1214 * @param cp is the ConnectionParams 1215 * @param cause and if no error the cause is DataFailCause.NONE 1216 * @param handoverFailureMode The action on handover failure 1217 * @param sendAll is true if all contexts are to be notified 1218 */ notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause, @HandoverFailureMode int handoverFailureMode, boolean sendAll)1219 private void notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause, 1220 @HandoverFailureMode int handoverFailureMode, boolean sendAll) { 1221 ApnContext alreadySent = null; 1222 1223 if (cp != null && cp.mOnCompletedMsg != null) { 1224 // Get the completed message but only use it once 1225 Message connectionCompletedMsg = cp.mOnCompletedMsg; 1226 cp.mOnCompletedMsg = null; 1227 alreadySent = cp.mApnContext; 1228 1229 long timeStamp = System.currentTimeMillis(); 1230 connectionCompletedMsg.arg1 = cp.mRequestType; 1231 connectionCompletedMsg.arg2 = handoverFailureMode; 1232 1233 if (cause == DataFailCause.NONE) { 1234 mCreateTime = timeStamp; 1235 AsyncResult.forMessage(connectionCompletedMsg); 1236 } else { 1237 mLastFailCause = cause; 1238 mLastFailTime = timeStamp; 1239 1240 // Return message with a Throwable exception to signify an error. 1241 if (cause == DataFailCause.NONE) cause = DataFailCause.UNKNOWN; 1242 AsyncResult.forMessage(connectionCompletedMsg, cause, 1243 new Throwable(DataFailCause.toString(cause))); 1244 } 1245 if (DBG) { 1246 log("notifyConnectCompleted at " + timeStamp + " cause=" 1247 + DataFailCause.toString(cause) + " connectionCompletedMsg=" 1248 + msgToString(connectionCompletedMsg)); 1249 } 1250 1251 connectionCompletedMsg.sendToTarget(); 1252 } 1253 if (sendAll) { 1254 log("Send to all. " + alreadySent + " " + DataFailCause.toString(cause)); 1255 notifyAllWithEvent(alreadySent, DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR, 1256 DataFailCause.toString(cause)); 1257 } 1258 } 1259 1260 /** 1261 * Send ar.userObj if its a message, which is should be back to originator. 1262 * 1263 * @param dp is the DisconnectParams. 1264 */ notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll)1265 private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) { 1266 if (VDBG) log("NotifyDisconnectCompleted"); 1267 1268 ApnContext alreadySent = null; 1269 String reason = null; 1270 1271 if (dp != null && dp.mOnCompletedMsg != null) { 1272 // Get the completed message but only use it once 1273 Message msg = dp.mOnCompletedMsg; 1274 dp.mOnCompletedMsg = null; 1275 if (msg.obj instanceof ApnContext) { 1276 alreadySent = (ApnContext)msg.obj; 1277 } 1278 reason = dp.mReason; 1279 if (VDBG) { 1280 log(String.format("msg=%s msg.obj=%s", msg.toString(), 1281 ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>"))); 1282 } 1283 AsyncResult.forMessage(msg); 1284 msg.sendToTarget(); 1285 } 1286 if (sendAll) { 1287 if (reason == null) { 1288 reason = DataFailCause.toString(DataFailCause.UNKNOWN); 1289 } 1290 notifyAllWithEvent(alreadySent, DctConstants.EVENT_DISCONNECT_DONE, reason); 1291 } 1292 if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp); 1293 } 1294 sendRunnableMessage(int eventCode, @NonNull final Consumer<Boolean> r)1295 private void sendRunnableMessage(int eventCode, @NonNull final Consumer<Boolean> r) { 1296 sendMessage(eventCode, r); 1297 } 1298 1299 /* 1300 * ************************************************************************** 1301 * Begin Members and methods owned by DataConnectionTracker but stored 1302 * in a DataConnection because there is one per connection. 1303 * ************************************************************************** 1304 */ 1305 1306 /* 1307 * The id is owned by DataConnectionTracker. 1308 */ 1309 private int mId; 1310 1311 /** 1312 * Get the DataConnection ID 1313 */ getDataConnectionId()1314 public int getDataConnectionId() { 1315 return mId; 1316 } 1317 1318 /* 1319 * ************************************************************************** 1320 * End members owned by DataConnectionTracker 1321 * ************************************************************************** 1322 */ 1323 1324 /** 1325 * Clear all settings called when entering mInactiveState. 1326 */ clearSettings()1327 private void clearSettings() { 1328 if (DBG) log("clearSettings"); 1329 1330 mCreateTime = -1; 1331 mLastFailTime = -1; 1332 mLastFailCause = DataFailCause.NONE; 1333 mCid = -1; 1334 1335 mPcscfAddr = new String[5]; 1336 1337 mLinkProperties = new LinkProperties(); 1338 mApnContexts.clear(); 1339 mApnSetting = null; 1340 mUnmeteredUseOnly = false; 1341 mMmsUseOnly = false; 1342 mEnterpriseUse = false; 1343 mRestrictedNetworkOverride = false; 1344 mDcFailCause = DataFailCause.NONE; 1345 mDisabledApnTypeBitMask = 0; 1346 mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 1347 mCongestedOverride = false; 1348 mUnmeteredOverride = false; 1349 mDownlinkBandwidth = 14; 1350 mUplinkBandwidth = 14; 1351 mIsSuspended = false; 1352 mHandoverState = HANDOVER_STATE_IDLE; 1353 mHandoverFailureMode = DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN; 1354 mSliceInfo = null; 1355 mDefaultQos = null; 1356 mQosBearerSessions.clear(); 1357 mTrafficDescriptors.clear(); 1358 } 1359 1360 /** 1361 * Process setup data completion result from data service 1362 * 1363 * @param resultCode The result code returned by data service 1364 * @param response Data call setup response from data service 1365 * @param cp The original connection params used for data call setup 1366 * @return Setup result 1367 */ onSetupConnectionCompleted(@ataServiceCallback.ResultCode int resultCode, DataCallResponse response, ConnectionParams cp)1368 private SetupResult onSetupConnectionCompleted(@DataServiceCallback.ResultCode int resultCode, 1369 DataCallResponse response, 1370 ConnectionParams cp) { 1371 SetupResult result; 1372 1373 log("onSetupConnectionCompleted: resultCode=" + resultCode + ", response=" + response); 1374 if (cp.mTag != mTag) { 1375 if (DBG) { 1376 log("onSetupConnectionCompleted stale cp.tag=" + cp.mTag + ", mtag=" + mTag); 1377 } 1378 result = SetupResult.ERROR_STALE; 1379 } else if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) { 1380 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE; 1381 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE; 1382 } else if (resultCode == DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE) { 1383 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR; 1384 result.mFailCause = DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE; 1385 } else if (resultCode == DataServiceCallback.RESULT_ERROR_INVALID_ARG) { 1386 result = SetupResult.ERROR_INVALID_ARG; 1387 result.mFailCause = DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER; 1388 } else if (response.getCause() != 0) { 1389 if (response.getCause() == DataFailCause.RADIO_NOT_AVAILABLE) { 1390 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE; 1391 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE; 1392 } else { 1393 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR; 1394 result.mFailCause = DataFailCause.getFailCause(response.getCause()); 1395 } 1396 } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE 1397 && mDcController.getActiveDcByCid(response.getId()) != null) { 1398 if (DBG) log("DataConnection already exists for cid: " + response.getId()); 1399 result = SetupResult.ERROR_DUPLICATE_CID; 1400 result.mFailCause = DataFailCause.DUPLICATE_CID; 1401 } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE 1402 && !mDcController.isDefaultDataActive()) { 1403 if (DBG) log("No default data connection currently active"); 1404 mCid = response.getId(); 1405 result = SetupResult.ERROR_NO_DEFAULT_CONNECTION; 1406 result.mFailCause = DataFailCause.NO_DEFAULT_DATA; 1407 } else { 1408 if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse"); 1409 mCid = response.getId(); 1410 1411 if (response.getPduSessionId() != getPduSessionId()) { 1412 if (getDoAllocatePduSessionId()) { 1413 loge("The pdu session id on DataCallResponse is different than the one " 1414 + "allocated. response psi=" + response.getPduSessionId() 1415 + ", allocated psi=" + getPduSessionId()); 1416 } else { 1417 setPduSessionId(response.getPduSessionId()); 1418 } 1419 } 1420 1421 updatePcscfAddr(response); 1422 updateResponseFields(response); 1423 result = updateLinkProperty(response).setupResult; 1424 } 1425 1426 return result; 1427 } 1428 isResultCodeSuccess(int resultCode)1429 private static boolean isResultCodeSuccess(int resultCode) { 1430 return resultCode == DataServiceCallback.RESULT_SUCCESS 1431 || resultCode == DataServiceCallback.RESULT_ERROR_UNSUPPORTED; 1432 } 1433 isDnsOk(String[] domainNameServers)1434 private boolean isDnsOk(String[] domainNameServers) { 1435 if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1]) 1436 && !mPhone.isDnsCheckDisabled()) { 1437 // Work around a race condition where QMI does not fill in DNS: 1438 // Deactivate PDP and let DataConnectionTracker retry. 1439 // Do not apply the race condition workaround for MMS APN 1440 // if Proxy is an IP-address. 1441 // Otherwise, the default APN will not be restored anymore. 1442 if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) { 1443 log(String.format( 1444 "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s", 1445 mApnSetting.getApnTypeBitmask(), ApnSetting.TYPE_MMS_STRING, 1446 mApnSetting.getMmsProxyAddressAsString(), 1447 isIpAddress(mApnSetting.getMmsProxyAddressAsString()))); 1448 return false; 1449 } 1450 } 1451 return true; 1452 } 1453 1454 /** 1455 * TCP buffer size config based on the ril technology. There are 6 parameters 1456 * read_min, read_default, read_max, write_min, write_default, write_max in the TCP buffer 1457 * config string and they are separated by a comma. The unit of these parameters is byte. 1458 */ 1459 private static final String TCP_BUFFER_SIZES_GPRS = "4092,8760,48000,4096,8760,48000"; 1460 private static final String TCP_BUFFER_SIZES_EDGE = "4093,26280,70800,4096,16384,70800"; 1461 private static final String TCP_BUFFER_SIZES_UMTS = "58254,349525,1048576,58254,349525,1048576"; 1462 private static final String TCP_BUFFER_SIZES_1XRTT = "16384,32768,131072,4096,16384,102400"; 1463 private static final String TCP_BUFFER_SIZES_EVDO = "4094,87380,262144,4096,16384,262144"; 1464 private static final String TCP_BUFFER_SIZES_EHRPD = "131072,262144,1048576,4096,16384,524288"; 1465 private static final String TCP_BUFFER_SIZES_HSDPA = "61167,367002,1101005,8738,52429,262114"; 1466 private static final String TCP_BUFFER_SIZES_HSPA = "40778,244668,734003,16777,100663,301990"; 1467 private static final String TCP_BUFFER_SIZES_LTE = 1468 "524288,1048576,2097152,262144,524288,1048576"; 1469 private static final String TCP_BUFFER_SIZES_HSPAP = 1470 "122334,734003,2202010,32040,192239,576717"; 1471 private static final String TCP_BUFFER_SIZES_NR = 1472 "2097152,6291456,16777216,512000,2097152,8388608"; 1473 private static final String TCP_BUFFER_SIZES_LTE_CA = 1474 "4096,6291456,12582912,4096,1048576,2097152"; 1475 updateTcpBufferSizes(int rilRat)1476 private void updateTcpBufferSizes(int rilRat) { 1477 String sizes = null; 1478 ServiceState ss = mPhone.getServiceState(); 1479 if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && 1480 ss.isUsingCarrierAggregation()) { 1481 rilRat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA; 1482 } 1483 String ratName = ServiceState.rilRadioTechnologyToString(rilRat).toLowerCase(Locale.ROOT); 1484 // ServiceState gives slightly different names for EVDO tech ("evdo-rev.0" for ex) 1485 // - patch it up: 1486 if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 || 1487 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A || 1488 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B) { 1489 ratName = RAT_NAME_EVDO; 1490 } 1491 1492 // NR 5G Non-Standalone use LTE cell as the primary cell, the ril technology is LTE in this 1493 // case. We use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1494 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1495 && ((rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE || 1496 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) && isNRConnected()) 1497 && mPhone.getServiceStateTracker().getNrContextIds().contains(mCid)) { 1498 ratName = RAT_NAME_5G; 1499 } 1500 1501 log("updateTcpBufferSizes: " + ratName); 1502 1503 // in the form: "ratname:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max" 1504 String[] configOverride = mPhone.getContext().getResources().getStringArray( 1505 com.android.internal.R.array.config_mobile_tcp_buffers); 1506 for (int i = 0; i < configOverride.length; i++) { 1507 String[] split = configOverride[i].split(":"); 1508 if (ratName.equals(split[0]) && split.length == 2) { 1509 sizes = split[1]; 1510 break; 1511 } 1512 } 1513 1514 if (sizes == null) { 1515 // no override - use telephony defaults 1516 // doing it this way allows device or carrier to just override the types they 1517 // care about and inherit the defaults for the others. 1518 switch (rilRat) { 1519 case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS: 1520 sizes = TCP_BUFFER_SIZES_GPRS; 1521 break; 1522 case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE: 1523 sizes = TCP_BUFFER_SIZES_EDGE; 1524 break; 1525 case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS: 1526 sizes = TCP_BUFFER_SIZES_UMTS; 1527 break; 1528 case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT: 1529 sizes = TCP_BUFFER_SIZES_1XRTT; 1530 break; 1531 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0: 1532 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A: 1533 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B: 1534 sizes = TCP_BUFFER_SIZES_EVDO; 1535 break; 1536 case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD: 1537 sizes = TCP_BUFFER_SIZES_EHRPD; 1538 break; 1539 case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA: 1540 sizes = TCP_BUFFER_SIZES_HSDPA; 1541 break; 1542 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA: 1543 case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA: 1544 sizes = TCP_BUFFER_SIZES_HSPA; 1545 break; 1546 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE: 1547 // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1548 if (RAT_NAME_5G.equals(ratName)) { 1549 sizes = TCP_BUFFER_SIZES_NR; 1550 } else { 1551 sizes = TCP_BUFFER_SIZES_LTE; 1552 } 1553 break; 1554 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA: 1555 // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1556 if (RAT_NAME_5G.equals(ratName)) { 1557 sizes = TCP_BUFFER_SIZES_NR; 1558 } else { 1559 sizes = TCP_BUFFER_SIZES_LTE_CA; 1560 } 1561 break; 1562 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP: 1563 sizes = TCP_BUFFER_SIZES_HSPAP; 1564 break; 1565 case ServiceState.RIL_RADIO_TECHNOLOGY_NR: 1566 sizes = TCP_BUFFER_SIZES_NR; 1567 break; 1568 default: 1569 // Leave empty - this will let ConnectivityService use the system default. 1570 break; 1571 } 1572 } 1573 mLinkProperties.setTcpBufferSizes(sizes); 1574 } 1575 updateLinkBandwidthsFromCarrierConfig(int rilRat)1576 private void updateLinkBandwidthsFromCarrierConfig(int rilRat) { 1577 String ratName = ServiceState.rilRadioTechnologyToString(rilRat); 1578 if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) { 1579 ratName = mPhone.getServiceState().getNrFrequencyRange() 1580 == ServiceState.FREQUENCY_RANGE_MMWAVE 1581 ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA; 1582 } 1583 1584 if (DBG) log("updateLinkBandwidthsFromCarrierConfig: " + ratName); 1585 1586 Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName); 1587 if (values == null) { 1588 values = new Pair<>(14, 14); 1589 } 1590 mDownlinkBandwidth = values.first; 1591 mUplinkBandwidth = values.second; 1592 } 1593 1594 updateLinkBandwidthsFromModem(List<LinkCapacityEstimate> lceList)1595 private void updateLinkBandwidthsFromModem(List<LinkCapacityEstimate> lceList) { 1596 if (DBG) log("updateLinkBandwidthsFromModem: lceList=" + lceList); 1597 boolean downlinkUpdated = false; 1598 boolean uplinkUpdated = false; 1599 LinkCapacityEstimate lce = lceList.get(0); 1600 // LCE status deprecated in IRadio 1.2, so only check for IRadio < 1.2 1601 if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2) 1602 || mPhone.getLceStatus() == RILConstants.LCE_ACTIVE) { 1603 if (lce.getDownlinkCapacityKbps() != LinkCapacityEstimate.INVALID) { 1604 mDownlinkBandwidth = lce.getDownlinkCapacityKbps(); 1605 downlinkUpdated = true; 1606 } 1607 if (lce.getUplinkCapacityKbps() != LinkCapacityEstimate.INVALID) { 1608 mUplinkBandwidth = lce.getUplinkCapacityKbps(); 1609 uplinkUpdated = true; 1610 } 1611 } 1612 1613 if (!downlinkUpdated || !uplinkUpdated) { 1614 fallBackToCarrierConfigValues(downlinkUpdated, uplinkUpdated); 1615 } 1616 1617 if (mNetworkAgent != null) { 1618 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this); 1619 } 1620 } 1621 updateLinkBandwidthsFromBandwidthEstimator(int uplinkBandwidthKbps, int downlinkBandwidthKbps)1622 private void updateLinkBandwidthsFromBandwidthEstimator(int uplinkBandwidthKbps, 1623 int downlinkBandwidthKbps) { 1624 if (DBG) { 1625 log("updateLinkBandwidthsFromBandwidthEstimator, UL= " 1626 + uplinkBandwidthKbps + " DL= " + downlinkBandwidthKbps); 1627 } 1628 boolean downlinkUpdated = false; 1629 boolean uplinkUpdated = false; 1630 if (downlinkBandwidthKbps > 0) { 1631 mDownlinkBandwidth = downlinkBandwidthKbps; 1632 downlinkUpdated = true; 1633 } 1634 if (uplinkBandwidthKbps > 0) { 1635 mUplinkBandwidth = uplinkBandwidthKbps; 1636 uplinkUpdated = true; 1637 } 1638 1639 if (!downlinkUpdated || !uplinkUpdated) { 1640 fallBackToCarrierConfigValues(downlinkUpdated, uplinkUpdated); 1641 } 1642 if (mNetworkAgent != null) { 1643 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this); 1644 } 1645 } 1646 fallBackToCarrierConfigValues(boolean downlinkUpdated, boolean uplinkUpdated)1647 private void fallBackToCarrierConfigValues(boolean downlinkUpdated, boolean uplinkUpdated) { 1648 String ratName = ServiceState.rilRadioTechnologyToString(mRilRat); 1649 if (mRilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) { 1650 ratName = mPhone.getServiceState().getNrFrequencyRange() 1651 == ServiceState.FREQUENCY_RANGE_MMWAVE 1652 ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA; 1653 } 1654 Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName); 1655 if (values != null) { 1656 if (!downlinkUpdated) { 1657 mDownlinkBandwidth = values.first; 1658 } 1659 if (!uplinkUpdated) { 1660 mUplinkBandwidth = values.second; 1661 } 1662 } 1663 } 1664 isBandwidthSourceKey(String source)1665 private boolean isBandwidthSourceKey(String source) { 1666 return source.equals(mPhone.getContext().getResources().getString( 1667 com.android.internal.R.string.config_bandwidthEstimateSource)); 1668 } 1669 1670 /** 1671 * Indicates if this data connection was established for unmetered use only. Note that this 1672 * flag should be populated when data becomes active. And if it is set to true, it can be set to 1673 * false later when we are reevaluating the data connection. But if it is set to false, it 1674 * can never become true later because setting it to true will cause this data connection 1675 * losing some immutable network capabilities, which can cause issues in connectivity service. 1676 */ 1677 private boolean mUnmeteredUseOnly = false; 1678 1679 /** 1680 * Indicates if this data connection was established for MMS use only. This is true only when 1681 * mobile data is disabled but the user allows sending and receiving MMS messages. If the data 1682 * enabled settings indicate that MMS data is allowed unconditionally, MMS can be sent when data 1683 * is disabled even if it is a metered APN type. 1684 */ 1685 private boolean mMmsUseOnly = false; 1686 1687 /** 1688 * Indicates if when this connection was established we had a restricted/privileged 1689 * NetworkRequest and needed it to overcome data-enabled limitations. 1690 * 1691 * This flag overrides the APN-based restriction capability, restricting the network 1692 * based on both having a NetworkRequest with restricted AND needing a restricted 1693 * bit to overcome user-disabled status. This allows us to handle the common case 1694 * of having both restricted requests and unrestricted requests for the same apn: 1695 * if conditions require a restricted network to overcome user-disabled then it must 1696 * be restricted, otherwise it is unrestricted (or restricted based on APN type). 1697 * 1698 * This supports a privileged app bringing up a network without general apps having access 1699 * to it when the network is otherwise unavailable (hipri). The first use case is 1700 * pre-paid SIM reprovisioning over internet, where the carrier insists on no traffic 1701 * other than from the privileged carrier-app. 1702 * 1703 * Note that the data connection cannot go from unrestricted to restricted because the 1704 * connectivity service does not support dynamically closing TCP connections at this point. 1705 */ 1706 private boolean mRestrictedNetworkOverride = false; 1707 1708 /** 1709 * Indicates if this data connection supports enterprise use. Note that this flag should be 1710 * populated when data becomes active. Once it is set, the value cannot be changed because 1711 * setting it will cause this data connection to lose immutable network capabilities, which can 1712 * cause issues in connectivity service. 1713 */ 1714 private boolean mEnterpriseUse = false; 1715 1716 /** 1717 * Check if this data connection should be restricted. We should call this when data connection 1718 * becomes active, or when we want to re-evaluate the conditions to decide if we need to 1719 * unstrict the data connection. 1720 * 1721 * @return True if this data connection needs to be restricted. 1722 */ shouldRestrictNetwork()1723 private boolean shouldRestrictNetwork() { 1724 // first, check if there is any network request that containing restricted capability 1725 // (i.e. Do not have NET_CAPABILITY_NOT_RESTRICTED in the request) 1726 boolean isAnyRestrictedRequest = false; 1727 for (ApnContext apnContext : mApnContexts.keySet()) { 1728 if (apnContext.hasRestrictedRequests(true /* exclude DUN */)) { 1729 isAnyRestrictedRequest = true; 1730 break; 1731 } 1732 } 1733 1734 // If all of the network requests are non-restricted, then we don't need to restrict 1735 // the network. 1736 if (!isAnyRestrictedRequest) { 1737 return false; 1738 } 1739 1740 // If the network is unmetered, then we don't need to restrict the network because users 1741 // won't be charged anyway. 1742 if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) { 1743 return false; 1744 } 1745 1746 // If the data is disabled, then we need to restrict the network so only privileged apps can 1747 // use the restricted network while data is disabled. 1748 if (!mPhone.getDataEnabledSettings().isDataEnabled()) { 1749 return true; 1750 } 1751 1752 // If the device is roaming, and the user does not turn on data roaming, then we need to 1753 // restrict the network so only privileged apps can use it. 1754 if (!mDct.getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) { 1755 return true; 1756 } 1757 1758 // Otherwise we should not restrict the network so anyone who requests can use it. 1759 return false; 1760 } 1761 1762 /** 1763 * @return True if this data connection should only be used for unmetered purposes. 1764 */ isUnmeteredUseOnly()1765 private boolean isUnmeteredUseOnly() { 1766 // If this data connection is on IWLAN, then it's unmetered and can be used by everyone. 1767 // Should not be for unmetered used only. 1768 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1769 return false; 1770 } 1771 1772 // If data is enabled, this data connection can't be for unmetered used only because 1773 // everyone should be able to use it if: 1774 // 1. Device is not roaming, or 1775 // 2. Device is roaming and data roaming is turned on 1776 if (mPhone.getDataEnabledSettings().isDataEnabled()) { 1777 if (!mPhone.getServiceState().getDataRoaming() || mDct.getDataRoamingEnabled()) { 1778 return false; 1779 } 1780 } 1781 1782 // The data connection can only be unmetered used only if all attached APN contexts 1783 // attached to this data connection are unmetered. 1784 for (ApnContext apnContext : mApnContexts.keySet()) { 1785 if (ApnSettingUtils.isMeteredApnType(apnContext.getApnTypeBitmask(), mPhone)) { 1786 return false; 1787 } 1788 } 1789 return true; 1790 } 1791 1792 /** 1793 * @return True if this data connection should only be used for MMS purposes. 1794 */ isMmsUseOnly()1795 private boolean isMmsUseOnly() { 1796 // MMS use only if data is disabled, MMS is allowed unconditionally, and MMS is the only 1797 // APN type for this data connection. 1798 DataEnabledSettings des = mPhone.getDataEnabledSettings(); 1799 boolean mmsAllowedUnconditionally = !des.isDataEnabled() && des.isMmsAlwaysAllowed(); 1800 boolean mmsApnOnly = isApnContextAttached(ApnSetting.TYPE_MMS, true); 1801 return mmsAllowedUnconditionally && mmsApnOnly; 1802 } 1803 1804 /** 1805 * Check if this data connection supports enterprise use. We call this when the data connection 1806 * becomes active or when we want to reevaluate the conditions to decide if we need to update 1807 * the network agent capabilities. 1808 * 1809 * @return True if this data connection supports enterprise use. 1810 */ isEnterpriseUse()1811 private boolean isEnterpriseUse() { 1812 boolean enterpriseTrafficDescriptor = mTrafficDescriptors 1813 .stream() 1814 .anyMatch(td -> td.getOsAppId() != null && Arrays.equals(td.getOsAppId(), 1815 getEnterpriseOsAppId())); 1816 boolean enterpriseApnContext = mApnContexts.keySet() 1817 .stream() 1818 .anyMatch(ac -> ac.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE); 1819 return enterpriseTrafficDescriptor || enterpriseApnContext; 1820 } 1821 1822 /** 1823 * Get the network capabilities for this data connection. 1824 * 1825 * @return the {@link NetworkCapabilities} of this data connection. 1826 */ getNetworkCapabilities()1827 public NetworkCapabilities getNetworkCapabilities() { 1828 final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder() 1829 .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); 1830 boolean unmeteredApns = false; 1831 1832 if (mApnSetting != null && !mEnterpriseUse && !mMmsUseOnly) { 1833 final int[] types = ApnSetting.getApnTypesFromBitmask( 1834 mApnSetting.getApnTypeBitmask() & ~mDisabledApnTypeBitMask); 1835 for (int type : types) { 1836 if ((!mRestrictedNetworkOverride && mUnmeteredUseOnly) 1837 && ApnSettingUtils.isMeteredApnType(type, mPhone)) { 1838 log("Dropped the metered " + ApnSetting.getApnTypeString(type) 1839 + " type for the unmetered data call."); 1840 continue; 1841 } 1842 switch (type) { 1843 case ApnSetting.TYPE_ALL: { 1844 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1845 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1846 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL); 1847 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA); 1848 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); 1849 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS); 1850 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IA); 1851 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1852 break; 1853 } 1854 case ApnSetting.TYPE_DEFAULT: { 1855 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1856 break; 1857 } 1858 case ApnSetting.TYPE_MMS: { 1859 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1860 break; 1861 } 1862 case ApnSetting.TYPE_SUPL: { 1863 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL); 1864 break; 1865 } 1866 case ApnSetting.TYPE_DUN: { 1867 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1868 break; 1869 } 1870 case ApnSetting.TYPE_FOTA: { 1871 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA); 1872 break; 1873 } 1874 case ApnSetting.TYPE_IMS: { 1875 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); 1876 break; 1877 } 1878 case ApnSetting.TYPE_CBS: { 1879 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS); 1880 break; 1881 } 1882 case ApnSetting.TYPE_IA: { 1883 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_IA); 1884 break; 1885 } 1886 case ApnSetting.TYPE_EMERGENCY: { 1887 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS); 1888 break; 1889 } 1890 case ApnSetting.TYPE_MCX: { 1891 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX); 1892 break; 1893 } 1894 case ApnSetting.TYPE_XCAP: { 1895 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP); 1896 break; 1897 } 1898 default: 1899 } 1900 } 1901 1902 if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) { 1903 unmeteredApns = true; 1904 } 1905 } 1906 1907 // Mark NOT_METERED in the following cases: 1908 // 1. All APNs in the APN settings are unmetered. 1909 // 2. The non-restricted data is intended for unmetered use only. 1910 if (unmeteredApns || (mUnmeteredUseOnly && !mRestrictedNetworkOverride)) { 1911 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1912 } else { 1913 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1914 } 1915 1916 if (mEnterpriseUse) { 1917 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE); 1918 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1919 } 1920 1921 if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())) { 1922 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1923 } 1924 1925 if (mMmsUseOnly) { 1926 if (ApnSettingUtils.isMeteredApnType(ApnSetting.TYPE_MMS, mPhone)) { 1927 log("Adding unmetered capability for the unmetered MMS-only data connection"); 1928 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED); 1929 } 1930 log("Adding MMS capability for the MMS-only data connection"); 1931 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1932 } 1933 1934 if (mRestrictedNetworkOverride) { 1935 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1936 // don't use dun on restriction-overriden networks. 1937 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1938 } 1939 1940 builder.setLinkDownstreamBandwidthKbps(mDownlinkBandwidth); 1941 builder.setLinkUpstreamBandwidthKbps(mUplinkBandwidth); 1942 1943 builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 1944 .setSubscriptionId(mSubId).build()); 1945 builder.setSubscriptionIds(Collections.singleton(mSubId)); 1946 1947 if (!mPhone.getServiceState().getDataRoaming()) { 1948 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING); 1949 } 1950 1951 if (!mCongestedOverride) { 1952 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); 1953 } 1954 1955 if (mUnmeteredOverride) { 1956 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED); 1957 } 1958 1959 if (!mIsSuspended) { 1960 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED); 1961 } 1962 1963 builder.setAdministratorUids(mAdministratorUids); 1964 1965 // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a 1966 // VCN. 1967 builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 1968 if (isVcnManaged(builder.build())) { 1969 builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 1970 } 1971 1972 return builder.build(); 1973 } 1974 1975 /** 1976 * Returns whether the Network represented by this DataConnection is VCN-managed. 1977 * 1978 * <p>Determining if the Network is VCN-managed requires polling VcnManager. 1979 */ isVcnManaged(NetworkCapabilities networkCapabilities)1980 private boolean isVcnManaged(NetworkCapabilities networkCapabilities) { 1981 VcnNetworkPolicyResult policyResult = 1982 mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties()); 1983 1984 // if the Network does have capability NOT_VCN_MANAGED, return false to indicate it's not 1985 // VCN-managed 1986 return !policyResult 1987 .getNetworkCapabilities() 1988 .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); 1989 } 1990 1991 /** @return {@code true} if validation is required, {@code false} otherwise. */ isValidationRequired()1992 public boolean isValidationRequired() { 1993 final NetworkCapabilities nc = getNetworkCapabilities(); 1994 return nc != null 1995 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 1996 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 1997 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) 1998 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN); 1999 } 2000 2001 /** 2002 * @return {@code True} if 464xlat should be skipped. 2003 */ 2004 @VisibleForTesting shouldSkip464Xlat()2005 public boolean shouldSkip464Xlat() { 2006 switch (mApnSetting.getSkip464Xlat()) { 2007 case Telephony.Carriers.SKIP_464XLAT_ENABLE: 2008 return true; 2009 case Telephony.Carriers.SKIP_464XLAT_DISABLE: 2010 return false; 2011 case Telephony.Carriers.SKIP_464XLAT_DEFAULT: 2012 default: 2013 break; 2014 } 2015 2016 // As default, return true if ims and no internet 2017 final NetworkCapabilities nc = getNetworkCapabilities(); 2018 return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS) 2019 && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 2020 } 2021 2022 /** 2023 * @return {@code} true iff. {@code address} is a literal IPv4 or IPv6 address. 2024 */ 2025 @VisibleForTesting isIpAddress(String address)2026 public static boolean isIpAddress(String address) { 2027 if (address == null) return false; 2028 2029 // Accept IPv6 addresses (only) in square brackets for compatibility. 2030 if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) { 2031 address = address.substring(1, address.length() - 1); 2032 } 2033 return InetAddresses.isNumericAddress(address); 2034 } 2035 setLinkProperties(DataCallResponse response, LinkProperties linkProperties)2036 private SetupResult setLinkProperties(DataCallResponse response, 2037 LinkProperties linkProperties) { 2038 // Check if system property dns usable 2039 String propertyPrefix = "net." + response.getInterfaceName() + "."; 2040 String dnsServers[] = new String[2]; 2041 dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1"); 2042 dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2"); 2043 boolean okToUseSystemPropertyDns = isDnsOk(dnsServers); 2044 2045 SetupResult result; 2046 2047 // Start with clean network properties and if we have 2048 // a failure we'll clear again at the bottom of this code. 2049 linkProperties.clear(); 2050 2051 if (response.getCause() == DataFailCause.NONE) { 2052 try { 2053 // set interface name 2054 linkProperties.setInterfaceName(response.getInterfaceName()); 2055 2056 // set link addresses 2057 if (response.getAddresses().size() > 0) { 2058 for (LinkAddress la : response.getAddresses()) { 2059 if (!la.getAddress().isAnyLocalAddress()) { 2060 if (DBG) { 2061 log("addr/pl=" + la.getAddress() + "/" 2062 + la.getPrefixLength()); 2063 } 2064 linkProperties.addLinkAddress(la); 2065 } 2066 } 2067 } else { 2068 throw new UnknownHostException("no address for ifname=" 2069 + response.getInterfaceName()); 2070 } 2071 2072 // set dns servers 2073 if (response.getDnsAddresses().size() > 0) { 2074 for (InetAddress dns : response.getDnsAddresses()) { 2075 if (!dns.isAnyLocalAddress()) { 2076 linkProperties.addDnsServer(dns); 2077 } 2078 } 2079 } else if (okToUseSystemPropertyDns) { 2080 for (String dnsAddr : dnsServers) { 2081 dnsAddr = dnsAddr.trim(); 2082 if (dnsAddr.isEmpty()) continue; 2083 InetAddress ia; 2084 try { 2085 ia = InetAddresses.parseNumericAddress(dnsAddr); 2086 } catch (IllegalArgumentException e) { 2087 throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr); 2088 } 2089 if (!ia.isAnyLocalAddress()) { 2090 linkProperties.addDnsServer(ia); 2091 } 2092 } 2093 } else { 2094 throw new UnknownHostException("Empty dns response and no system default dns"); 2095 } 2096 2097 // set pcscf 2098 if (response.getPcscfAddresses().size() > 0) { 2099 for (InetAddress pcscf : response.getPcscfAddresses()) { 2100 linkProperties.addPcscfServer(pcscf); 2101 } 2102 } 2103 2104 boolean useLowerMtuValue = false; 2105 CarrierConfigManager configManager = (CarrierConfigManager) 2106 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 2107 if (configManager != null) { 2108 PersistableBundle bundle = configManager.getConfigForSubId(mSubId); 2109 if (bundle != null) { 2110 useLowerMtuValue = bundle.getBoolean( 2111 CarrierConfigManager.KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED) 2112 && response.getMtuV4() != PhoneConstants.UNSET_MTU 2113 && response.getMtuV6() != PhoneConstants.UNSET_MTU; 2114 } 2115 } 2116 2117 int interfaceMtu = response.getMtu(); 2118 for (InetAddress gateway : response.getGatewayAddresses()) { 2119 int mtu = gateway instanceof java.net.Inet6Address ? response.getMtuV6() 2120 : response.getMtuV4(); 2121 if (useLowerMtuValue) { 2122 mtu = Math.min(response.getMtuV4(), response.getMtuV6()); 2123 // Never set an MTU below MIN_V6_MTU on a network that has IPv6. 2124 if (mtu < MIN_V6_MTU) { 2125 mtu = MIN_V6_MTU; 2126 } 2127 interfaceMtu = mtu; 2128 } 2129 // Allow 0.0.0.0 or :: as a gateway; 2130 // this indicates a point-to-point interface. 2131 linkProperties.addRoute(new RouteInfo(null, gateway, null, 2132 RouteInfo.RTN_UNICAST, mtu)); 2133 } 2134 2135 // set interface MTU 2136 // this may clobber the setting read from the APN db, but that's ok 2137 // TODO: remove once LinkProperties#setMtu is deprecated 2138 linkProperties.setMtu(interfaceMtu); 2139 2140 result = SetupResult.SUCCESS; 2141 } catch (UnknownHostException e) { 2142 log("setLinkProperties: UnknownHostException " + e); 2143 result = SetupResult.ERROR_INVALID_ARG; 2144 } 2145 } else { 2146 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR; 2147 } 2148 2149 // An error occurred so clear properties 2150 if (result != SetupResult.SUCCESS) { 2151 if (DBG) { 2152 log("setLinkProperties: error clearing LinkProperties status=" 2153 + response.getCause() + " result=" + result); 2154 } 2155 linkProperties.clear(); 2156 } 2157 2158 return result; 2159 } 2160 getDoAllocatePduSessionId()2161 private boolean getDoAllocatePduSessionId() { 2162 return mDoAllocatePduSessionId; 2163 } 2164 2165 /** 2166 * Initialize connection, this will fail if the 2167 * apnSettings are not compatible. 2168 * 2169 * @param cp the Connection parameters 2170 * @return true if initialization was successful. 2171 */ initConnection(ConnectionParams cp)2172 private boolean initConnection(ConnectionParams cp) { 2173 ApnContext apnContext = cp.mApnContext; 2174 if (mApnSetting == null) { 2175 // Only change apn setting if it isn't set, it will 2176 // only NOT be set only if we're in DcInactiveState. 2177 mApnSetting = apnContext.getApnSetting(); 2178 } 2179 if (mApnSetting == null || (!mApnSetting.canHandleType(apnContext.getApnTypeBitmask()) 2180 && apnContext.getApnTypeBitmask() != ApnSetting.TYPE_ENTERPRISE)) { 2181 if (DBG) { 2182 log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp 2183 + " dc=" + DataConnection.this); 2184 } 2185 return false; 2186 } 2187 mTag += 1; 2188 mConnectionParams = cp; 2189 mConnectionParams.mTag = mTag; 2190 2191 // always update the ConnectionParams with the latest or the 2192 // connectionGeneration gets stale 2193 mApnContexts.put(apnContext, cp); 2194 2195 if (DBG) { 2196 log("initConnection: " 2197 + " RefCount=" + mApnContexts.size() 2198 + " mApnList=" + mApnContexts 2199 + " mConnectionParams=" + mConnectionParams); 2200 } 2201 return true; 2202 } 2203 2204 /** 2205 * The parent state for all other states. 2206 */ 2207 private class DcDefaultState extends State { 2208 @Override enter()2209 public void enter() { 2210 if (DBG) log("DcDefaultState: enter"); 2211 2212 // Register for DRS or RAT change 2213 mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged( 2214 mTransportType, getHandler(), 2215 DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null); 2216 2217 mPhone.getServiceStateTracker().registerForDataRoamingOn(getHandler(), 2218 DataConnection.EVENT_DATA_CONNECTION_ROAM_ON, null); 2219 mPhone.getServiceStateTracker().registerForDataRoamingOff(getHandler(), 2220 DataConnection.EVENT_DATA_CONNECTION_ROAM_OFF, null, true); 2221 mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(), 2222 DataConnection.EVENT_NR_STATE_CHANGED, null); 2223 mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(), 2224 DataConnection.EVENT_NR_FREQUENCY_CHANGED, null); 2225 mPhone.getServiceStateTracker().registerForCssIndicatorChanged(getHandler(), 2226 DataConnection.EVENT_CSS_INDICATOR_CHANGED, null); 2227 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) { 2228 mPhone.getLinkBandwidthEstimator().registerForBandwidthChanged(getHandler(), 2229 DataConnection.EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE, null); 2230 } 2231 2232 // Add ourselves to the list of data connections 2233 mDcController.addDc(DataConnection.this); 2234 } 2235 @Override exit()2236 public void exit() { 2237 if (DBG) log("DcDefaultState: exit"); 2238 2239 // Unregister for DRS or RAT change. 2240 mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged( 2241 mTransportType, getHandler()); 2242 2243 mPhone.getServiceStateTracker().unregisterForDataRoamingOn(getHandler()); 2244 mPhone.getServiceStateTracker().unregisterForDataRoamingOff(getHandler()); 2245 mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler()); 2246 mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler()); 2247 mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler()); 2248 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) { 2249 mPhone.getLinkBandwidthEstimator().unregisterForBandwidthChanged(getHandler()); 2250 } 2251 2252 // Remove ourselves from the DC lists 2253 mDcController.removeDc(DataConnection.this); 2254 2255 if (mAc != null) { 2256 mAc.disconnected(); 2257 mAc = null; 2258 } 2259 mApnContexts.clear(); 2260 mReconnectIntent = null; 2261 mDct = null; 2262 mApnSetting = null; 2263 mPhone = null; 2264 mDataServiceManager = null; 2265 mLinkProperties = null; 2266 mLastFailCause = DataFailCause.NONE; 2267 mUserData = null; 2268 mDcController = null; 2269 mDcTesterFailBringUpAll = null; 2270 } 2271 2272 @Override processMessage(Message msg)2273 public boolean processMessage(Message msg) { 2274 boolean retVal = HANDLED; 2275 2276 if (VDBG) { 2277 log("DcDefault msg=" + getWhatToString(msg.what) 2278 + " RefCount=" + mApnContexts.size()); 2279 } 2280 switch (msg.what) { 2281 case EVENT_RESET: 2282 if (VDBG) log("DcDefaultState: msg.what=REQ_RESET"); 2283 transitionTo(mInactiveState); 2284 break; 2285 case EVENT_CONNECT: 2286 if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected"); 2287 ConnectionParams cp = (ConnectionParams) msg.obj; 2288 notifyConnectCompleted(cp, DataFailCause.UNKNOWN, 2289 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 2290 break; 2291 2292 case EVENT_DISCONNECT: 2293 case EVENT_DISCONNECT_ALL: 2294 case EVENT_REEVALUATE_RESTRICTED_STATE: 2295 if (DBG) { 2296 log("DcDefaultState deferring msg.what=" + getWhatToString(msg.what) 2297 + " RefCount=" + mApnContexts.size()); 2298 } 2299 deferMessage(msg); 2300 break; 2301 case EVENT_TEAR_DOWN_NOW: 2302 if (DBG) log("DcDefaultState EVENT_TEAR_DOWN_NOW"); 2303 mDataServiceManager.deactivateDataCall(mCid, DataService.REQUEST_REASON_NORMAL, 2304 null); 2305 mDataCallSessionStats.setDeactivateDataCallReason( 2306 DataService.REQUEST_REASON_NORMAL); 2307 break; 2308 case EVENT_LOST_CONNECTION: 2309 if (DBG) { 2310 String s = "DcDefaultState ignore EVENT_LOST_CONNECTION" 2311 + " tag=" + msg.arg1 + ":mTag=" + mTag; 2312 logAndAddLogRec(s); 2313 } 2314 break; 2315 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: 2316 AsyncResult ar = (AsyncResult)msg.obj; 2317 Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>)ar.result; 2318 mDataRegState = drsRatPair.first; 2319 updateTcpBufferSizes(drsRatPair.second); 2320 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 2321 updateLinkBandwidthsFromCarrierConfig(drsRatPair.second); 2322 } 2323 mRilRat = drsRatPair.second; 2324 if (DBG) { 2325 log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED" 2326 + " regState=" + ServiceState.rilServiceStateToString(mDataRegState) 2327 + " RAT=" + ServiceState.rilRadioTechnologyToString(mRilRat)); 2328 } 2329 mDataCallSessionStats.onDrsOrRatChanged(mRilRat); 2330 break; 2331 2332 case EVENT_START_HANDOVER: //calls startHandover() 2333 if (DBG) { 2334 log("DcDefaultState: EVENT_START_HANDOVER not expected."); 2335 } 2336 Consumer<Integer> r = (Consumer<Integer>) msg.obj; 2337 r.accept(DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE); 2338 break; 2339 case EVENT_START_HANDOVER_ON_TARGET: 2340 if (DBG) { 2341 log("DcDefaultState: EVENT_START_HANDOVER not expected, but will " 2342 + "clean up, result code: " 2343 + DataServiceCallback.resultCodeToString(msg.arg1)); 2344 } 2345 ((Consumer<Boolean>) msg.obj).accept(false /* is in correct state*/); 2346 break; 2347 case EVENT_CANCEL_HANDOVER: 2348 // We don't need to do anything in this case 2349 if (DBG) { 2350 log("DcDefaultState: EVENT_CANCEL_HANDOVER resultCode=" 2351 + DataServiceCallback.resultCodeToString(msg.arg1)); 2352 } 2353 break; 2354 case EVENT_RELEASE_PDU_SESSION_ID: { 2355 // We do the same thing in all state in order to preserve the existing workflow 2356 final AsyncResult asyncResult = (AsyncResult) msg.obj; 2357 if (asyncResult == null) { 2358 loge("EVENT_RELEASE_PDU_SESSION_ID: asyncResult is null!"); 2359 } else { 2360 if (msg.obj != null) { 2361 if (DBG) logd("EVENT_RELEASE_PDU_SESSION_ID: id released"); 2362 Runnable runnable = (Runnable) asyncResult.userObj; 2363 runnable.run(); 2364 } else { 2365 loge("EVENT_RELEASE_PDU_SESSION_ID: no runnable set"); 2366 } 2367 } 2368 retVal = HANDLED; 2369 break; 2370 } 2371 case EVENT_ALLOCATE_PDU_SESSION_ID: { 2372 // We do the same thing in all state in order to preserve the existing workflow 2373 final AsyncResult asyncResult = (AsyncResult) msg.obj; 2374 if (asyncResult == null) { 2375 loge("EVENT_ALLOCATE_PDU_SESSION_ID: asyncResult is null!"); 2376 } else { 2377 Consumer<Integer> onAllocated = (Consumer<Integer>) asyncResult.userObj; 2378 if (asyncResult.exception != null) { 2379 loge("EVENT_ALLOCATE_PDU_SESSION_ID: exception", 2380 asyncResult.exception); 2381 onAllocated.accept(PDU_SESSION_ID_NOT_SET); 2382 } else if (asyncResult.result == null) { 2383 loge("EVENT_ALLOCATE_PDU_SESSION_ID: result null, no id"); 2384 onAllocated.accept(PDU_SESSION_ID_NOT_SET); 2385 } else { 2386 int psi = (int) asyncResult.result; 2387 if (DBG) logd("EVENT_ALLOCATE_PDU_SESSION_ID: psi=" + psi); 2388 onAllocated.accept(psi); 2389 } 2390 } 2391 retVal = HANDLED; 2392 break; 2393 } 2394 default: 2395 if (DBG) { 2396 log("DcDefaultState: ignore msg.what=" + getWhatToString(msg.what)); 2397 } 2398 break; 2399 } 2400 2401 return retVal; 2402 } 2403 } 2404 updateSuspendState()2405 private void updateSuspendState() { 2406 if (mNetworkAgent == null) { 2407 Rlog.d(getName(), "Setting suspend state without a NetworkAgent"); 2408 } 2409 2410 boolean newSuspendedState = false; 2411 // Data can only be (temporarily) suspended while data is in active state 2412 if (getCurrentState() == mActiveState) { 2413 // Never set suspended for emergency apn. Emergency data connection 2414 // can work while device is not in service. 2415 if (mApnSetting != null && mApnSetting.isEmergencyApn()) { 2416 newSuspendedState = false; 2417 // If we are not in service, change to suspended. 2418 } else if (mDataRegState != ServiceState.STATE_IN_SERVICE) { 2419 newSuspendedState = true; 2420 // Check voice/data concurrency. 2421 } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) { 2422 newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE; 2423 } 2424 } 2425 2426 // Only notify when there is a change. 2427 if (mIsSuspended != newSuspendedState) { 2428 mIsSuspended = newSuspendedState; 2429 2430 // If data connection is active, we need to notify the new data connection state 2431 // changed event reflecting the latest suspended state. 2432 if (isActive()) { 2433 notifyDataConnectionState(); 2434 } 2435 } 2436 } 2437 notifyDataConnectionState()2438 private void notifyDataConnectionState() { 2439 // The receivers of this have no way to differentiate between default and enterprise 2440 // connections. Do not notify for enterprise. 2441 if (!isEnterpriseUse()) { 2442 mPhone.notifyDataConnection(getPreciseDataConnectionState()); 2443 } else { 2444 log("notifyDataConnectionState: Skipping for enterprise; state=" + getState()); 2445 } 2446 } 2447 2448 private DcDefaultState mDefaultState = new DcDefaultState(); 2449 getApnTypeBitmask()2450 private int getApnTypeBitmask() { 2451 return isEnterpriseUse() ? ApnSetting.TYPE_ENTERPRISE : 2452 mApnSetting != null ? mApnSetting.getApnTypeBitmask() : 0; 2453 } 2454 canHandleDefault()2455 private boolean canHandleDefault() { 2456 return !isEnterpriseUse() && mApnSetting != null 2457 ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false; 2458 } 2459 2460 /** 2461 * The state machine is inactive and expects a EVENT_CONNECT. 2462 */ 2463 private class DcInactiveState extends State { 2464 // Inform all contexts we've failed connecting setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause, @HandoverFailureMode int handoverFailureMode)2465 public void setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause, 2466 @HandoverFailureMode int handoverFailureMode) { 2467 if (VDBG) log("DcInactiveState: setEnterNotificationParams cp,cause"); 2468 mConnectionParams = cp; 2469 mDisconnectParams = null; 2470 mDcFailCause = cause; 2471 mHandoverFailureMode = handoverFailureMode; 2472 } 2473 2474 // Inform all contexts we've failed disconnected setEnterNotificationParams(DisconnectParams dp)2475 public void setEnterNotificationParams(DisconnectParams dp) { 2476 if (VDBG) log("DcInactiveState: setEnterNotificationParams dp"); 2477 mConnectionParams = null; 2478 mDisconnectParams = dp; 2479 mDcFailCause = DataFailCause.NONE; 2480 } 2481 2482 // Inform all contexts of the failure cause setEnterNotificationParams(@ataFailureCause int cause)2483 public void setEnterNotificationParams(@DataFailureCause int cause) { 2484 mConnectionParams = null; 2485 mDisconnectParams = null; 2486 mDcFailCause = cause; 2487 } 2488 2489 @Override enter()2490 public void enter() { 2491 mTag += 1; 2492 if (DBG) log("DcInactiveState: enter() mTag=" + mTag); 2493 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2494 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__INACTIVE, 2495 mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault()); 2496 mDataCallSessionStats.onDataCallDisconnected(mDcFailCause); 2497 if (mHandoverState == HANDOVER_STATE_BEING_TRANSFERRED) { 2498 // This is from source data connection to set itself's state 2499 setHandoverState(HANDOVER_STATE_COMPLETED); 2500 } 2501 2502 // Check for dangling agent. Ideally the handover source agent should be null if 2503 // handover process is smooth. When it's not null, that means handover failed. The 2504 // agent was not successfully transferred to the new data connection. We should 2505 // gracefully notify connectivity service the network was disconnected. 2506 if (mHandoverSourceNetworkAgent != null) { 2507 DataConnection sourceDc = mHandoverSourceNetworkAgent.getDataConnection(); 2508 if (sourceDc != null) { 2509 // If the source data connection still owns this agent, then just reset the 2510 // handover state back to idle because handover is already failed. 2511 mHandoverLocalLog.log( 2512 "Handover failed. Reset the source dc " + sourceDc.getName() 2513 + " state to idle"); 2514 sourceDc.cancelHandover(); 2515 } else { 2516 // The agent is now a dangling agent. No data connection owns this agent. 2517 // Gracefully notify connectivity service disconnected. 2518 mHandoverLocalLog.log( 2519 "Handover failed and dangling agent found."); 2520 mHandoverSourceNetworkAgent.acquireOwnership( 2521 DataConnection.this, mTransportType); 2522 log("Cleared dangling network agent. " + mHandoverSourceNetworkAgent); 2523 mHandoverSourceNetworkAgent.unregister(DataConnection.this); 2524 mHandoverSourceNetworkAgent.releaseOwnership(DataConnection.this); 2525 } 2526 mHandoverSourceNetworkAgent = null; 2527 } 2528 2529 if (mConnectionParams != null) { 2530 if (DBG) { 2531 log("DcInactiveState: enter notifyConnectCompleted +ALL failCause=" 2532 + DataFailCause.toString(mDcFailCause)); 2533 } 2534 notifyConnectCompleted(mConnectionParams, mDcFailCause, mHandoverFailureMode, 2535 true); 2536 } 2537 if (mDisconnectParams != null) { 2538 if (DBG) { 2539 log("DcInactiveState: enter notifyDisconnectCompleted +ALL failCause=" 2540 + DataFailCause.toString(mDcFailCause)); 2541 } 2542 notifyDisconnectCompleted(mDisconnectParams, true); 2543 } 2544 if (mDisconnectParams == null && mConnectionParams == null 2545 && mDcFailCause != DataFailCause.NONE) { 2546 if (DBG) { 2547 log("DcInactiveState: enter notifyAllDisconnectCompleted failCause=" 2548 + DataFailCause.toString(mDcFailCause)); 2549 } 2550 notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE, 2551 DataFailCause.toString(mDcFailCause)); 2552 } 2553 2554 // Remove ourselves from cid mapping, before clearSettings 2555 mDcController.removeActiveDcByCid(DataConnection.this); 2556 2557 // For the first time entering here (idle state before setup), do not notify 2558 // disconnected state. Only notify data connection disconnected for data that is 2559 // actually moving from disconnecting to disconnected, or setup failed. In both cases, 2560 // APN setting will not be null. 2561 if (mApnSetting != null) { 2562 notifyDataConnectionState(); 2563 } 2564 clearSettings(); 2565 } 2566 2567 @Override exit()2568 public void exit() { 2569 } 2570 2571 @Override processMessage(Message msg)2572 public boolean processMessage(Message msg) { 2573 switch (msg.what) { 2574 case EVENT_RESET: 2575 case EVENT_REEVALUATE_RESTRICTED_STATE: 2576 if (DBG) { 2577 log("DcInactiveState: msg.what=" + getWhatToString(msg.what) 2578 + ", ignore we're already done"); 2579 } 2580 return HANDLED; 2581 case EVENT_CONNECT: 2582 if (DBG) log("DcInactiveState: mag.what=EVENT_CONNECT"); 2583 ConnectionParams cp = (ConnectionParams) msg.obj; 2584 2585 if (!initConnection(cp)) { 2586 log("DcInactiveState: msg.what=EVENT_CONNECT initConnection failed"); 2587 notifyConnectCompleted(cp, DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER, 2588 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 2589 transitionTo(mInactiveState); 2590 return HANDLED; 2591 } 2592 2593 int cause = connect(cp); 2594 if (cause != DataFailCause.NONE) { 2595 log("DcInactiveState: msg.what=EVENT_CONNECT connect failed"); 2596 notifyConnectCompleted(cp, cause, 2597 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 2598 transitionTo(mInactiveState); 2599 return HANDLED; 2600 } 2601 2602 if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 2603 mSubId = cp.mSubId; 2604 } 2605 2606 transitionTo(mActivatingState); 2607 return HANDLED; 2608 case EVENT_DISCONNECT: 2609 if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT"); 2610 notifyDisconnectCompleted((DisconnectParams)msg.obj, false); 2611 return HANDLED; 2612 case EVENT_DISCONNECT_ALL: 2613 if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL"); 2614 notifyDisconnectCompleted((DisconnectParams)msg.obj, false); 2615 return HANDLED; 2616 default: 2617 if (VDBG) { 2618 log("DcInactiveState not handled msg.what=" + getWhatToString(msg.what)); 2619 } 2620 return NOT_HANDLED; 2621 } 2622 } 2623 } 2624 private DcInactiveState mInactiveState = new DcInactiveState(); 2625 2626 /** 2627 * The state machine is activating a connection. 2628 */ 2629 private class DcActivatingState extends State { 2630 @Override enter()2631 public void enter() { 2632 int apnTypeBitmask = getApnTypeBitmask(); 2633 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2634 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVATING, 2635 mPhone.getPhoneId(), mId, apnTypeBitmask, canHandleDefault()); 2636 setHandoverState(HANDOVER_STATE_IDLE); 2637 // restricted evaluation depends on network requests from apnContext. The evaluation 2638 // should happen once entering connecting state rather than active state because it's 2639 // possible that restricted network request can be released during the connecting window 2640 // and if we wait for connection established, then we might mistakenly 2641 // consider it as un-restricted. ConnectivityService then will immediately 2642 // tear down the connection through networkAgent unwanted callback if all requests for 2643 // this connection are going away. 2644 mRestrictedNetworkOverride = shouldRestrictNetwork(); 2645 2646 mPhone.getCarrierPrivilegesTracker() 2647 .registerCarrierPrivilegesListener( 2648 getHandler(), EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null); 2649 notifyDataConnectionState(); 2650 mDataCallSessionStats.onSetupDataCall(apnTypeBitmask); 2651 } 2652 @Override processMessage(Message msg)2653 public boolean processMessage(Message msg) { 2654 boolean retVal; 2655 AsyncResult ar; 2656 ConnectionParams cp; 2657 2658 if (DBG) log("DcActivatingState: msg=" + msgToString(msg)); 2659 switch (msg.what) { 2660 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: 2661 case EVENT_CONNECT: 2662 // Activating can't process until we're done. 2663 deferMessage(msg); 2664 retVal = HANDLED; 2665 break; 2666 2667 case EVENT_SETUP_DATA_CONNECTION_DONE: 2668 cp = (ConnectionParams) msg.obj; 2669 2670 DataCallResponse dataCallResponse = 2671 msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE); 2672 SetupResult result = onSetupConnectionCompleted(msg.arg1, dataCallResponse, cp); 2673 if (result != SetupResult.ERROR_STALE) { 2674 if (mConnectionParams != cp) { 2675 loge("DcActivatingState: WEIRD mConnectionsParams:"+ mConnectionParams 2676 + " != cp:" + cp); 2677 } 2678 } 2679 if (DBG) { 2680 log("DcActivatingState onSetupConnectionCompleted result=" + result 2681 + " dc=" + DataConnection.this); 2682 } 2683 if (cp.mApnContext != null) { 2684 cp.mApnContext.requestLog("onSetupConnectionCompleted result=" + result); 2685 } 2686 switch (result) { 2687 case SUCCESS: 2688 // All is well 2689 mDcFailCause = DataFailCause.NONE; 2690 transitionTo(mActiveState); 2691 break; 2692 case ERROR_RADIO_NOT_AVAILABLE: 2693 // Vendor ril rejected the command and didn't connect. 2694 // Transition to inactive but send notifications after 2695 // we've entered the mInactive state. 2696 mInactiveState.setEnterNotificationParams(cp, result.mFailCause, 2697 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN); 2698 transitionTo(mInactiveState); 2699 break; 2700 case ERROR_DUPLICATE_CID: 2701 // TODO (b/180988471): Properly handle the case when an existing cid is 2702 // returned by tearing down the network agent if enterprise changed. 2703 long retry = RetryManager.NO_SUGGESTED_RETRY_DELAY; 2704 if (cp.mApnContext != null) { 2705 retry = RetryManager.NO_RETRY; 2706 mDct.getDataThrottler().setRetryTime( 2707 cp.mApnContext.getApnTypeBitmask(), 2708 retry, DcTracker.REQUEST_TYPE_NORMAL); 2709 } 2710 String logStr = "DcActivatingState: " 2711 + DataFailCause.toString(result.mFailCause) 2712 + " retry=" + retry; 2713 if (DBG) log(logStr); 2714 if (cp.mApnContext != null) cp.mApnContext.requestLog(logStr); 2715 mInactiveState.setEnterNotificationParams(cp, result.mFailCause, 2716 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN); 2717 transitionTo(mInactiveState); 2718 break; 2719 case ERROR_NO_DEFAULT_CONNECTION: 2720 // TODO (b/180988471): Properly handle the case when a default data 2721 // connection doesn't exist (tear down connection and retry). 2722 // Currently, this just tears down the connection without retry. 2723 if (DBG) log("DcActivatingState: NO_DEFAULT_DATA"); 2724 case ERROR_INVALID_ARG: 2725 // The addresses given from the RIL are bad 2726 tearDownData(cp); 2727 transitionTo(mDisconnectingErrorCreatingConnection); 2728 break; 2729 case ERROR_DATA_SERVICE_SPECIFIC_ERROR: 2730 2731 // Retrieve the suggested retry delay from the modem and save it. 2732 // If the modem want us to retry the current APN again, it will 2733 // suggest a positive delay value (in milliseconds). Otherwise we'll get 2734 // NO_SUGGESTED_RETRY_DELAY here. 2735 2736 long delay = getSuggestedRetryDelay(dataCallResponse); 2737 long retryTime = RetryManager.NO_SUGGESTED_RETRY_DELAY; 2738 if (delay == RetryManager.NO_RETRY) { 2739 retryTime = RetryManager.NO_RETRY; 2740 } else if (delay >= 0) { 2741 retryTime = SystemClock.elapsedRealtime() + delay; 2742 } 2743 int newRequestType = DcTracker.calculateNewRetryRequestType( 2744 mHandoverFailureMode, cp.mRequestType, mDcFailCause); 2745 mDct.getDataThrottler().setRetryTime(getApnTypeBitmask(), 2746 retryTime, newRequestType); 2747 2748 String str = "DcActivatingState: ERROR_DATA_SERVICE_SPECIFIC_ERROR " 2749 + " delay=" + delay 2750 + " result=" + result 2751 + " result.isRadioRestartFailure=" 2752 + DataFailCause.isRadioRestartFailure(mPhone.getContext(), 2753 result.mFailCause, mPhone.getSubId()) 2754 + " isPermanentFailure=" + 2755 mDct.isPermanentFailure(result.mFailCause); 2756 if (DBG) log(str); 2757 if (cp.mApnContext != null) cp.mApnContext.requestLog(str); 2758 2759 // Save the cause. DcTracker.onDataSetupComplete will check this 2760 // failure cause and determine if we need to retry this APN later 2761 // or not. 2762 mInactiveState.setEnterNotificationParams(cp, result.mFailCause, 2763 dataCallResponse != null 2764 ? dataCallResponse.getHandoverFailureMode() 2765 : DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN); 2766 transitionTo(mInactiveState); 2767 break; 2768 case ERROR_STALE: 2769 loge("DcActivatingState: stale EVENT_SETUP_DATA_CONNECTION_DONE" 2770 + " tag:" + cp.mTag + " != mTag:" + mTag); 2771 break; 2772 default: 2773 throw new RuntimeException("Unknown SetupResult, should not happen"); 2774 } 2775 retVal = HANDLED; 2776 mDataCallSessionStats 2777 .onSetupDataCallResponse(dataCallResponse, cp.mRilRat, 2778 getApnTypeBitmask(), mApnSetting.getProtocol(), 2779 result.mFailCause); 2780 break; 2781 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: 2782 AsyncResult asyncResult = (AsyncResult) msg.obj; 2783 int[] administratorUids = (int[]) asyncResult.result; 2784 mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); 2785 retVal = HANDLED; 2786 break; 2787 case EVENT_START_HANDOVER_ON_TARGET: 2788 //called after startHandover on target transport 2789 ((Consumer<Boolean>) msg.obj).accept(true /* is in correct state*/); 2790 retVal = HANDLED; 2791 break; 2792 case EVENT_CANCEL_HANDOVER: 2793 transitionTo(mInactiveState); 2794 retVal = HANDLED; 2795 break; 2796 default: 2797 if (VDBG) { 2798 log("DcActivatingState not handled msg.what=" + 2799 getWhatToString(msg.what) + " RefCount=" + mApnContexts.size()); 2800 } 2801 retVal = NOT_HANDLED; 2802 break; 2803 } 2804 return retVal; 2805 } 2806 } 2807 private DcActivatingState mActivatingState = new DcActivatingState(); 2808 2809 /** 2810 * The state machine is connected, expecting an EVENT_DISCONNECT. 2811 */ 2812 private class DcActiveState extends State { 2813 enter()2814 @Override public void enter() { 2815 if (DBG) log("DcActiveState: enter dc=" + DataConnection.this); 2816 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2817 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVE, 2818 mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault()); 2819 // If we were retrying there maybe more than one, otherwise they'll only be one. 2820 notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE, 2821 Phone.REASON_CONNECTED); 2822 2823 mPhone.getCallTracker().registerForVoiceCallStarted(getHandler(), 2824 DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED, null); 2825 mPhone.getCallTracker().registerForVoiceCallEnded(getHandler(), 2826 DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED, null); 2827 2828 // If the EVENT_CONNECT set the current max retry restore it here 2829 // if it didn't then this is effectively a NOP. 2830 mDcController.addActiveDcByCid(DataConnection.this); 2831 2832 updateTcpBufferSizes(mRilRat); 2833 updateLinkBandwidthsFromCarrierConfig(mRilRat); 2834 2835 final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder(); 2836 configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE); 2837 configBuilder.setLegacyTypeName(NETWORK_TYPE); 2838 int networkType = getNetworkType(); 2839 configBuilder.setLegacySubType(networkType); 2840 configBuilder.setLegacySubTypeName(TelephonyManager.getNetworkTypeName(networkType)); 2841 configBuilder.setLegacyExtraInfo(mApnSetting.getApnName()); 2842 final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent(); 2843 if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager 2844 .ACTION_CARRIER_SIGNAL_REDIRECTED)) { 2845 // carrierSignal Receivers will place the carrier-specific provisioning notification 2846 configBuilder.setProvisioningNotificationEnabled(false); 2847 } 2848 2849 final String subscriberId = mPhone.getSubscriberId(); 2850 if (!TextUtils.isEmpty(subscriberId)) { 2851 configBuilder.setSubscriberId(subscriberId); 2852 } 2853 2854 // set skip464xlat if it is not default otherwise 2855 if (shouldSkip464Xlat()) { 2856 configBuilder.setNat64DetectionEnabled(false); 2857 } 2858 2859 mUnmeteredUseOnly = isUnmeteredUseOnly(); 2860 mMmsUseOnly = isMmsUseOnly(); 2861 mEnterpriseUse = isEnterpriseUse(); 2862 2863 if (DBG) { 2864 log("mRestrictedNetworkOverride = " + mRestrictedNetworkOverride 2865 + ", mUnmeteredUseOnly = " + mUnmeteredUseOnly 2866 + ", mMmsUseOnly = " + mMmsUseOnly 2867 + ", mEnterpriseUse = " + mEnterpriseUse); 2868 } 2869 2870 // Always register a VcnNetworkPolicyChangeListener, regardless of whether this is a 2871 // handover 2872 // or new Network. 2873 mVcnManager.addVcnNetworkPolicyChangeListener( 2874 new HandlerExecutor(getHandler()), mVcnPolicyChangeListener); 2875 2876 if (mConnectionParams != null 2877 && mConnectionParams.mRequestType == REQUEST_TYPE_HANDOVER) { 2878 // If this is a data setup for handover, we need to reuse the existing network agent 2879 // instead of creating a new one. This should be transparent to connectivity 2880 // service. 2881 DcTracker dcTracker = mPhone.getDcTracker(getHandoverSourceTransport()); 2882 DataConnection dc = dcTracker.getDataConnectionByApnType( 2883 mConnectionParams.mApnContext.getApnType()); 2884 // It's possible that the source data connection has been disconnected by the modem 2885 // already. If not, set its handover state to completed. 2886 if (dc != null) { 2887 // Transfer network agent from the original data connection as soon as the 2888 // new handover data connection is connected. 2889 dc.setHandoverState(HANDOVER_STATE_COMPLETED); 2890 } 2891 2892 if (mHandoverSourceNetworkAgent != null) { 2893 String logStr = "Transfer network agent " + mHandoverSourceNetworkAgent.getTag() 2894 + " successfully."; 2895 log(logStr); 2896 mHandoverLocalLog.log(logStr); 2897 mNetworkAgent = mHandoverSourceNetworkAgent; 2898 mNetworkAgent.acquireOwnership(DataConnection.this, mTransportType); 2899 2900 // TODO: Should evaluate mDisabledApnTypeBitMask again after handover. We don't 2901 // do it now because connectivity service does not support dynamically removing 2902 // immutable capabilities. 2903 2904 mNetworkAgent.updateLegacySubtype(DataConnection.this); 2905 // Update the capability after handover 2906 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2907 DataConnection.this); 2908 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 2909 mHandoverSourceNetworkAgent = null; 2910 } else { 2911 String logStr = "Failed to get network agent from original data connection"; 2912 loge(logStr); 2913 mHandoverLocalLog.log(logStr); 2914 return; 2915 } 2916 } else { 2917 mScore = calculateScore(); 2918 final NetworkFactory factory = PhoneFactory.getNetworkFactory( 2919 mPhone.getPhoneId()); 2920 final NetworkProvider provider = (null == factory) ? null : factory.getProvider(); 2921 2922 mDisabledApnTypeBitMask |= getDisallowedApnTypes(); 2923 updateLinkPropertiesHttpProxy(); 2924 mNetworkAgent = new DcNetworkAgent(DataConnection.this, mPhone, mScore, 2925 configBuilder.build(), provider, mTransportType); 2926 2927 VcnNetworkPolicyResult policyResult = 2928 mVcnManager.applyVcnNetworkPolicy( 2929 getNetworkCapabilities(), getLinkProperties()); 2930 if (policyResult.isTeardownRequested()) { 2931 tearDownAll( 2932 Phone.REASON_VCN_REQUESTED_TEARDOWN, 2933 DcTracker.RELEASE_TYPE_DETACH, 2934 null /* onCompletedMsg */); 2935 } else { 2936 // All network agents start out in CONNECTING mode, but DcNetworkAgents are 2937 // created when the network is already connected. Hence, send the connected 2938 // notification immediately. 2939 mNetworkAgent.markConnected(); 2940 } 2941 2942 // The network agent is always created with NOT_SUSPENDED capability, but the 2943 // network might be already out of service (or voice call is ongoing) just right 2944 // before data connection is created. Connectivity service would not allow a network 2945 // created with suspended state, so we create a non-suspended network first, and 2946 // then immediately evaluate the suspended state. 2947 sendMessage(obtainMessage(EVENT_UPDATE_SUSPENDED_STATE)); 2948 } 2949 2950 // The qos parameters are set when the call is connected 2951 syncQosToNetworkAgent(); 2952 2953 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 2954 mPhone.mCi.registerForNattKeepaliveStatus( 2955 getHandler(), DataConnection.EVENT_KEEPALIVE_STATUS, null); 2956 mPhone.mCi.registerForLceInfo( 2957 getHandler(), DataConnection.EVENT_LINK_CAPACITY_CHANGED, null); 2958 } 2959 notifyDataConnectionState(); 2960 TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(), 2961 mCid, getApnTypeBitmask(), RilDataCall.State.CONNECTED); 2962 } 2963 2964 @Override exit()2965 public void exit() { 2966 if (DBG) log("DcActiveState: exit dc=" + this); 2967 mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler()); 2968 mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler()); 2969 2970 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 2971 mPhone.mCi.unregisterForNattKeepaliveStatus(getHandler()); 2972 mPhone.mCi.unregisterForLceInfo(getHandler()); 2973 } 2974 2975 // If we are still owning this agent, then we should inform connectivity service the 2976 // data connection is disconnected. There is one exception that we shouldn't unregister, 2977 // which is when IWLAN handover is ongoing. Instead of unregistering, the agent will 2978 // be transferred to the new data connection on the other transport. 2979 if (mNetworkAgent != null) { 2980 syncQosToNetworkAgent(); 2981 if (mHandoverState == HANDOVER_STATE_IDLE) { 2982 mNetworkAgent.unregister(DataConnection.this); 2983 } 2984 mNetworkAgent.releaseOwnership(DataConnection.this); 2985 } 2986 mNetworkAgent = null; 2987 2988 TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(), 2989 mCid, getApnTypeBitmask(), RilDataCall.State.DISCONNECTED); 2990 2991 mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener); 2992 2993 mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler()); 2994 } 2995 2996 @Override processMessage(Message msg)2997 public boolean processMessage(Message msg) { 2998 boolean retVal; 2999 3000 switch (msg.what) { 3001 case EVENT_CONNECT: { 3002 ConnectionParams cp = (ConnectionParams) msg.obj; 3003 // either add this new apn context to our set or 3004 // update the existing cp with the latest connection generation number 3005 mApnContexts.put(cp.mApnContext, cp); 3006 // TODO (b/118347948): evaluate if it's still needed after assigning 3007 // different scores to different Cellular network. 3008 mDisabledApnTypeBitMask &= ~cp.mApnContext.getApnTypeBitmask(); 3009 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3010 DataConnection.this); 3011 if (DBG) { 3012 log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this); 3013 } 3014 notifyConnectCompleted(cp, DataFailCause.NONE, 3015 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN, false); 3016 retVal = HANDLED; 3017 break; 3018 } 3019 case EVENT_DISCONNECT: { 3020 DisconnectParams dp = (DisconnectParams) msg.obj; 3021 if (DBG) { 3022 log("DcActiveState: EVENT_DISCONNECT dp=" + dp 3023 + " dc=" + DataConnection.this); 3024 } 3025 if (mApnContexts.containsKey(dp.mApnContext)) { 3026 if (DBG) { 3027 log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" 3028 + mApnContexts.size()); 3029 } 3030 3031 if (mApnContexts.size() == 1) { 3032 mApnContexts.clear(); 3033 mDisconnectParams = dp; 3034 mConnectionParams = null; 3035 dp.mTag = mTag; 3036 tearDownData(dp); 3037 transitionTo(mDisconnectingState); 3038 } else { 3039 mApnContexts.remove(dp.mApnContext); 3040 // TODO (b/118347948): evaluate if it's still needed after assigning 3041 // different scores to different Cellular network. 3042 mDisabledApnTypeBitMask |= dp.mApnContext.getApnTypeBitmask(); 3043 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3044 DataConnection.this); 3045 notifyDisconnectCompleted(dp, false); 3046 } 3047 } else { 3048 log("DcActiveState ERROR no such apnContext=" + dp.mApnContext 3049 + " in this dc=" + DataConnection.this); 3050 notifyDisconnectCompleted(dp, false); 3051 } 3052 retVal = HANDLED; 3053 break; 3054 } 3055 case EVENT_DISCONNECT_ALL: { 3056 if (DBG) { 3057 log("DcActiveState EVENT_DISCONNECT clearing apn contexts," 3058 + " dc=" + DataConnection.this); 3059 } 3060 DisconnectParams dp = (DisconnectParams) msg.obj; 3061 mDisconnectParams = dp; 3062 mConnectionParams = null; 3063 dp.mTag = mTag; 3064 tearDownData(dp); 3065 transitionTo(mDisconnectingState); 3066 retVal = HANDLED; 3067 break; 3068 } 3069 case EVENT_LOST_CONNECTION: { 3070 if (DBG) { 3071 log("DcActiveState EVENT_LOST_CONNECTION dc=" + DataConnection.this); 3072 } 3073 3074 mInactiveState.setEnterNotificationParams(DataFailCause.LOST_CONNECTION); 3075 transitionTo(mInactiveState); 3076 retVal = HANDLED; 3077 break; 3078 } 3079 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: { 3080 AsyncResult ar = (AsyncResult) msg.obj; 3081 Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>) ar.result; 3082 mDataRegState = drsRatPair.first; 3083 updateTcpBufferSizes(drsRatPair.second); 3084 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 3085 updateLinkBandwidthsFromCarrierConfig(drsRatPair.second); 3086 } 3087 mRilRat = drsRatPair.second; 3088 if (DBG) { 3089 log("DcActiveState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED" 3090 + " drs=" + mDataRegState 3091 + " mRilRat=" + mRilRat); 3092 } 3093 updateSuspendState(); 3094 if (mNetworkAgent != null) { 3095 mNetworkAgent.updateLegacySubtype(DataConnection.this); 3096 // The new suspended state will be passed through connectivity service 3097 // through NET_CAPABILITY_NOT_SUSPENDED. 3098 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3099 DataConnection.this); 3100 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 3101 } 3102 retVal = HANDLED; 3103 mDataCallSessionStats.onDrsOrRatChanged(mRilRat); 3104 break; 3105 } 3106 case EVENT_NR_FREQUENCY_CHANGED: 3107 // fallthrough 3108 case EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED: 3109 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 3110 updateLinkBandwidthsFromCarrierConfig(mRilRat); 3111 } 3112 if (mNetworkAgent != null) { 3113 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3114 DataConnection.this); 3115 } 3116 retVal = HANDLED; 3117 break; 3118 case EVENT_DATA_CONNECTION_METEREDNESS_CHANGED: 3119 boolean isUnmetered = (boolean) msg.obj; 3120 if (isUnmetered == mUnmeteredOverride) { 3121 retVal = HANDLED; 3122 break; 3123 } 3124 mUnmeteredOverride = isUnmetered; 3125 if (mNetworkAgent != null) { 3126 mNetworkAgent.updateLegacySubtype(DataConnection.this); 3127 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3128 DataConnection.this); 3129 } 3130 retVal = HANDLED; 3131 break; 3132 case EVENT_DATA_CONNECTION_CONGESTEDNESS_CHANGED: 3133 boolean isCongested = (boolean) msg.obj; 3134 if (isCongested == mCongestedOverride) { 3135 retVal = HANDLED; 3136 break; 3137 } 3138 mCongestedOverride = isCongested; 3139 if (mNetworkAgent != null) { 3140 mNetworkAgent.updateLegacySubtype(DataConnection.this); 3141 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3142 DataConnection.this); 3143 } 3144 retVal = HANDLED; 3145 break; 3146 case EVENT_DATA_CONNECTION_ROAM_ON: 3147 case EVENT_DATA_CONNECTION_ROAM_OFF: { 3148 if (mNetworkAgent != null) { 3149 mNetworkAgent.updateLegacySubtype(DataConnection.this); 3150 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3151 DataConnection.this); 3152 } 3153 retVal = HANDLED; 3154 break; 3155 } 3156 case EVENT_DATA_CONNECTION_VOICE_CALL_STARTED: 3157 case EVENT_DATA_CONNECTION_VOICE_CALL_ENDED: 3158 case EVENT_CSS_INDICATOR_CHANGED: 3159 case EVENT_UPDATE_SUSPENDED_STATE: { 3160 updateSuspendState(); 3161 if (mNetworkAgent != null) { 3162 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3163 DataConnection.this); 3164 } 3165 retVal = HANDLED; 3166 break; 3167 } 3168 case EVENT_BW_REFRESH_RESPONSE: { 3169 AsyncResult ar = (AsyncResult)msg.obj; 3170 if (ar.exception != null) { 3171 log("EVENT_BW_REFRESH_RESPONSE: error ignoring, e=" + ar.exception); 3172 } else { 3173 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) { 3174 updateLinkBandwidthsFromModem((List<LinkCapacityEstimate>) ar.result); 3175 } 3176 } 3177 retVal = HANDLED; 3178 break; 3179 } 3180 case EVENT_KEEPALIVE_START_REQUEST: { 3181 KeepalivePacketData pkt = (KeepalivePacketData) msg.obj; 3182 int slotId = msg.arg1; 3183 int intervalMillis = msg.arg2 * 1000; 3184 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 3185 mPhone.mCi.startNattKeepalive( 3186 DataConnection.this.mCid, pkt, intervalMillis, 3187 DataConnection.this.obtainMessage( 3188 EVENT_KEEPALIVE_STARTED, slotId, 0, null)); 3189 } else { 3190 // We currently do not support NATT Keepalive requests using the 3191 // DataService API, so unless the request is WWAN (always bound via 3192 // the CommandsInterface), the request cannot be honored. 3193 // 3194 // TODO: b/72331356 to add support for Keepalive to the DataService 3195 // so that keepalive requests can be handled (if supported) by the 3196 // underlying transport. 3197 if (mNetworkAgent != null) { 3198 mNetworkAgent.sendSocketKeepaliveEvent( 3199 msg.arg1, SocketKeepalive.ERROR_INVALID_NETWORK); 3200 } 3201 } 3202 retVal = HANDLED; 3203 break; 3204 } 3205 case EVENT_KEEPALIVE_STOP_REQUEST: { 3206 int slotId = msg.arg1; 3207 int handle = mNetworkAgent.keepaliveTracker.getHandleForSlot(slotId); 3208 if (handle < 0) { 3209 loge("No slot found for stopSocketKeepalive! " + slotId); 3210 mNetworkAgent.sendSocketKeepaliveEvent( 3211 slotId, SocketKeepalive.ERROR_NO_SUCH_SLOT); 3212 retVal = HANDLED; 3213 break; 3214 } else { 3215 logd("Stopping keepalive with handle: " + handle); 3216 } 3217 3218 mPhone.mCi.stopNattKeepalive( 3219 handle, DataConnection.this.obtainMessage( 3220 EVENT_KEEPALIVE_STOPPED, handle, slotId, null)); 3221 retVal = HANDLED; 3222 break; 3223 } 3224 case EVENT_KEEPALIVE_STARTED: { 3225 AsyncResult ar = (AsyncResult) msg.obj; 3226 final int slot = msg.arg1; 3227 if (ar.exception != null || ar.result == null) { 3228 loge("EVENT_KEEPALIVE_STARTED: error starting keepalive, e=" 3229 + ar.exception); 3230 mNetworkAgent.sendSocketKeepaliveEvent( 3231 slot, SocketKeepalive.ERROR_HARDWARE_ERROR); 3232 } else { 3233 KeepaliveStatus ks = (KeepaliveStatus) ar.result; 3234 if (ks == null) { 3235 loge("Null KeepaliveStatus received!"); 3236 } else { 3237 mNetworkAgent.keepaliveTracker.handleKeepaliveStarted(slot, ks); 3238 } 3239 } 3240 retVal = HANDLED; 3241 break; 3242 } 3243 case EVENT_KEEPALIVE_STATUS: { 3244 AsyncResult ar = (AsyncResult) msg.obj; 3245 if (ar.exception != null) { 3246 loge("EVENT_KEEPALIVE_STATUS: error in keepalive, e=" + ar.exception); 3247 // We have no way to notify connectivity in this case. 3248 } 3249 if (ar.result != null) { 3250 KeepaliveStatus ks = (KeepaliveStatus) ar.result; 3251 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(ks); 3252 } 3253 3254 retVal = HANDLED; 3255 break; 3256 } 3257 case EVENT_KEEPALIVE_STOPPED: { 3258 AsyncResult ar = (AsyncResult) msg.obj; 3259 final int handle = msg.arg1; 3260 final int slotId = msg.arg2; 3261 3262 if (ar.exception != null) { 3263 loge("EVENT_KEEPALIVE_STOPPED: error stopping keepalive for handle=" 3264 + handle + " e=" + ar.exception); 3265 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus( 3266 new KeepaliveStatus(KeepaliveStatus.ERROR_UNKNOWN)); 3267 } else { 3268 log("Keepalive Stop Requested for handle=" + handle); 3269 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus( 3270 new KeepaliveStatus(handle, KeepaliveStatus.STATUS_INACTIVE)); 3271 } 3272 retVal = HANDLED; 3273 break; 3274 } 3275 case EVENT_LINK_CAPACITY_CHANGED: { 3276 AsyncResult ar = (AsyncResult) msg.obj; 3277 if (ar.exception != null) { 3278 loge("EVENT_LINK_CAPACITY_CHANGED e=" + ar.exception); 3279 } else { 3280 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) { 3281 updateLinkBandwidthsFromModem((List<LinkCapacityEstimate>) ar.result); 3282 } 3283 } 3284 retVal = HANDLED; 3285 break; 3286 } 3287 case EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE: { 3288 AsyncResult ar = (AsyncResult) msg.obj; 3289 if (ar.exception != null) { 3290 loge("EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE e=" + ar.exception); 3291 } else { 3292 Pair<Integer, Integer> pair = (Pair<Integer, Integer>) ar.result; 3293 if (isBandwidthSourceKey( 3294 DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) { 3295 updateLinkBandwidthsFromBandwidthEstimator(pair.first, pair.second); 3296 } 3297 } 3298 retVal = HANDLED; 3299 break; 3300 } 3301 case EVENT_REEVALUATE_RESTRICTED_STATE: { 3302 // If the network was restricted, and now it does not need to be restricted 3303 // anymore, we should add the NET_CAPABILITY_NOT_RESTRICTED capability. 3304 if (mRestrictedNetworkOverride && !shouldRestrictNetwork()) { 3305 if (DBG) { 3306 log("Data connection becomes not-restricted. dc=" + this); 3307 } 3308 // Note we only do this when network becomes non-restricted. When a 3309 // non-restricted becomes restricted (e.g. users disable data, or turn off 3310 // data roaming), DCT will explicitly tear down the networks (because 3311 // connectivity service does not support force-close TCP connections today). 3312 // Also note that NET_CAPABILITY_NOT_RESTRICTED is an immutable capability 3313 // (see {@link NetworkCapabilities}) once we add it to the network, we can't 3314 // remove it through the entire life cycle of the connection. 3315 mRestrictedNetworkOverride = false; 3316 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3317 DataConnection.this); 3318 } 3319 3320 // If the data does need to be unmetered use only (e.g. users turn on data, or 3321 // device is not roaming anymore assuming data roaming is off), then we can 3322 // dynamically add those metered APN type capabilities back. (But not the 3323 // other way around because most of the APN-type capabilities are immutable 3324 // capabilities.) 3325 if (mUnmeteredUseOnly && !isUnmeteredUseOnly()) { 3326 mUnmeteredUseOnly = false; 3327 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3328 DataConnection.this); 3329 } 3330 3331 mMmsUseOnly = isMmsUseOnly(); 3332 3333 retVal = HANDLED; 3334 break; 3335 } 3336 case EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES: { 3337 // Update other properties like link properties if needed in future. 3338 updateScore(); 3339 retVal = HANDLED; 3340 break; 3341 } 3342 case EVENT_NR_STATE_CHANGED: { 3343 updateTcpBufferSizes(mRilRat); 3344 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 3345 updateLinkBandwidthsFromCarrierConfig(mRilRat); 3346 } 3347 if (mNetworkAgent != null) { 3348 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 3349 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 3350 DataConnection.this); 3351 } 3352 retVal = HANDLED; 3353 break; 3354 } 3355 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: 3356 AsyncResult asyncResult = (AsyncResult) msg.obj; 3357 int[] administratorUids = (int[]) asyncResult.result; 3358 mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); 3359 3360 // Administrator UIDs changed, so update NetworkAgent with new 3361 // NetworkCapabilities 3362 if (mNetworkAgent != null) { 3363 mNetworkAgent.sendNetworkCapabilities( 3364 getNetworkCapabilities(), DataConnection.this); 3365 } 3366 retVal = HANDLED; 3367 break; 3368 case EVENT_START_HANDOVER: //calls startHandover() 3369 Consumer<Integer> r = (Consumer<Integer>) msg.obj; 3370 r.accept(msg.arg1); 3371 retVal = HANDLED; 3372 break; 3373 3374 default: 3375 if (VDBG) { 3376 log("DcActiveState not handled msg.what=" + getWhatToString(msg.what)); 3377 } 3378 retVal = NOT_HANDLED; 3379 break; 3380 } 3381 return retVal; 3382 } 3383 } 3384 private DcActiveState mActiveState = new DcActiveState(); 3385 3386 /** 3387 * The state machine is disconnecting. 3388 */ 3389 private class DcDisconnectingState extends State { 3390 @Override enter()3391 public void enter() { 3392 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 3393 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTING, 3394 mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault()); 3395 notifyDataConnectionState(); 3396 } 3397 @Override processMessage(Message msg)3398 public boolean processMessage(Message msg) { 3399 boolean retVal; 3400 3401 switch (msg.what) { 3402 case EVENT_CONNECT: 3403 if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = " 3404 + mApnContexts.size()); 3405 deferMessage(msg); 3406 retVal = HANDLED; 3407 break; 3408 3409 case EVENT_DEACTIVATE_DONE: 3410 DisconnectParams dp = (DisconnectParams) msg.obj; 3411 3412 String str = "DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE RefCount=" 3413 + mApnContexts.size(); 3414 3415 if (DBG) log(str); 3416 if (dp.mApnContext != null) dp.mApnContext.requestLog(str); 3417 3418 // Clear out existing qos sessions 3419 updateQosParameters(null); 3420 3421 if (dp.mTag == mTag) { 3422 // Transition to inactive but send notifications after 3423 // we've entered the mInactive state. 3424 mInactiveState.setEnterNotificationParams(dp); 3425 transitionTo(mInactiveState); 3426 } else { 3427 if (DBG) log("DcDisconnectState stale EVENT_DEACTIVATE_DONE" 3428 + " dp.tag=" + dp.mTag + " mTag=" + mTag); 3429 } 3430 retVal = HANDLED; 3431 break; 3432 3433 default: 3434 if (VDBG) { 3435 log("DcDisconnectingState not handled msg.what=" 3436 + getWhatToString(msg.what)); 3437 } 3438 retVal = NOT_HANDLED; 3439 break; 3440 } 3441 return retVal; 3442 } 3443 } 3444 private DcDisconnectingState mDisconnectingState = new DcDisconnectingState(); 3445 3446 /** 3447 * The state machine is disconnecting after an creating a connection. 3448 */ 3449 private class DcDisconnectionErrorCreatingConnection extends State { 3450 @Override enter()3451 public void enter() { 3452 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 3453 TelephonyStatsLog 3454 .MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTION_ERROR_CREATING_CONNECTION, 3455 mPhone.getPhoneId(), mId, getApnTypeBitmask(), canHandleDefault()); 3456 notifyDataConnectionState(); 3457 } 3458 @Override processMessage(Message msg)3459 public boolean processMessage(Message msg) { 3460 boolean retVal; 3461 3462 switch (msg.what) { 3463 case EVENT_DEACTIVATE_DONE: 3464 ConnectionParams cp = (ConnectionParams) msg.obj; 3465 if (cp.mTag == mTag) { 3466 String str = "DcDisconnectionErrorCreatingConnection" + 3467 " msg.what=EVENT_DEACTIVATE_DONE"; 3468 if (DBG) log(str); 3469 if (cp.mApnContext != null) cp.mApnContext.requestLog(str); 3470 3471 // Transition to inactive but send notifications after 3472 // we've entered the mInactive state. 3473 mInactiveState.setEnterNotificationParams(cp, 3474 DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER, 3475 DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN); 3476 transitionTo(mInactiveState); 3477 } else { 3478 if (DBG) { 3479 log("DcDisconnectionErrorCreatingConnection stale EVENT_DEACTIVATE_DONE" 3480 + " dp.tag=" + cp.mTag + ", mTag=" + mTag); 3481 } 3482 } 3483 retVal = HANDLED; 3484 break; 3485 3486 default: 3487 if (VDBG) { 3488 log("DcDisconnectionErrorCreatingConnection not handled msg.what=" 3489 + getWhatToString(msg.what)); 3490 } 3491 retVal = NOT_HANDLED; 3492 break; 3493 } 3494 return retVal; 3495 } 3496 } 3497 private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection = 3498 new DcDisconnectionErrorCreatingConnection(); 3499 3500 /** 3501 * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg. 3502 * Used for cellular networks that use Access Point Names (APN) such 3503 * as GSM networks. 3504 * 3505 * @param apnContext is the Access Point Name to bring up a connection to 3506 * @param profileId for the connection 3507 * @param rilRadioTechnology Radio technology for the data connection 3508 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 3509 * With AsyncResult.userObj set to the original msg.obj, 3510 * AsyncResult.result = FailCause and AsyncResult.exception = Exception(). 3511 * @param connectionGeneration used to track a single connection request so disconnects can get 3512 * ignored if obsolete. 3513 * @param requestType Data request type 3514 * @param subId the subscription id associated with this data connection. 3515 * @param isApnPreferred whether or not the apn is preferred. 3516 */ bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isApnPreferred)3517 public void bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology, 3518 Message onCompletedMsg, int connectionGeneration, 3519 @RequestNetworkType int requestType, int subId, boolean isApnPreferred) { 3520 if (DBG) { 3521 log("bringUp: apnContext=" + apnContext + " onCompletedMsg=" + onCompletedMsg); 3522 } 3523 3524 if (mApnSetting == null) { 3525 mApnSetting = apnContext.getApnSetting(); 3526 } 3527 3528 sendMessage(DataConnection.EVENT_CONNECT, 3529 new ConnectionParams(apnContext, profileId, rilRadioTechnology, onCompletedMsg, 3530 connectionGeneration, requestType, subId, isApnPreferred)); 3531 } 3532 3533 /** 3534 * Tear down the connection through the apn on the network. 3535 * 3536 * @param apnContext APN context 3537 * @param reason reason to tear down 3538 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 3539 * With AsyncResult.userObj set to the original msg.obj. 3540 */ tearDown(ApnContext apnContext, String reason, Message onCompletedMsg)3541 public void tearDown(ApnContext apnContext, String reason, Message onCompletedMsg) { 3542 if (DBG) { 3543 log("tearDown: apnContext=" + apnContext + " reason=" + reason + " onCompletedMsg=" 3544 + onCompletedMsg); 3545 } 3546 sendMessage(DataConnection.EVENT_DISCONNECT, 3547 new DisconnectParams(apnContext, reason, DcTracker.RELEASE_TYPE_DETACH, 3548 onCompletedMsg)); 3549 } 3550 3551 // ******* "public" interface 3552 3553 /** 3554 * Used for testing purposes. 3555 */ tearDownNow()3556 void tearDownNow() { 3557 if (DBG) log("tearDownNow()"); 3558 sendMessage(obtainMessage(EVENT_TEAR_DOWN_NOW)); 3559 } 3560 3561 /** 3562 * Tear down the connection through the apn on the network. Ignores reference count and 3563 * and always tears down. 3564 * 3565 * @param releaseType Data release type 3566 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 3567 * With AsyncResult.userObj set to the original msg.obj. 3568 */ tearDownAll(String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)3569 public void tearDownAll(String reason, @ReleaseNetworkType int releaseType, 3570 Message onCompletedMsg) { 3571 if (DBG) { 3572 log("tearDownAll: reason=" + reason + ", releaseType=" 3573 + DcTracker.releaseTypeToString(releaseType)); 3574 } 3575 sendMessage(DataConnection.EVENT_DISCONNECT_ALL, 3576 new DisconnectParams(null, reason, releaseType, onCompletedMsg)); 3577 } 3578 3579 /** 3580 * Reset the data connection to inactive state. 3581 */ reset()3582 public void reset() { 3583 sendMessage(EVENT_RESET); 3584 if (DBG) log("reset"); 3585 } 3586 3587 /** 3588 * Re-evaluate the restricted state. If the restricted data connection does not need to be 3589 * restricted anymore, we need to dynamically change the network's capability. 3590 */ reevaluateRestrictedState()3591 void reevaluateRestrictedState() { 3592 sendMessage(EVENT_REEVALUATE_RESTRICTED_STATE); 3593 if (DBG) log("reevaluate restricted state"); 3594 } 3595 3596 /** 3597 * Re-evaluate the data connection properties. For example, it will recalculate data connection 3598 * score and update through network agent it if changed. 3599 */ reevaluateDataConnectionProperties()3600 void reevaluateDataConnectionProperties() { 3601 sendMessage(EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES); 3602 if (DBG) log("reevaluate data connection properties"); 3603 } 3604 3605 /** 3606 * @return The parameters used for initiating a data connection. 3607 */ getConnectionParams()3608 public ConnectionParams getConnectionParams() { 3609 return mConnectionParams; 3610 } 3611 3612 /** 3613 * Update PCSCF addresses 3614 * 3615 * @param response 3616 */ updatePcscfAddr(DataCallResponse response)3617 public void updatePcscfAddr(DataCallResponse response) { 3618 mPcscfAddr = response.getPcscfAddresses().stream() 3619 .map(InetAddress::getHostAddress).toArray(String[]::new); 3620 } 3621 3622 /** 3623 * @return The list of PCSCF addresses 3624 */ getPcscfAddresses()3625 public String[] getPcscfAddresses() { 3626 return mPcscfAddr; 3627 } 3628 3629 /** 3630 * Using the result of the SETUP_DATA_CALL determine the retry delay. 3631 * 3632 * @param response The response from setup data call 3633 * @return {@link RetryManager#NO_SUGGESTED_RETRY_DELAY} if not suggested. 3634 * {@link RetryManager#NO_RETRY} if retry should not happen. Otherwise the delay in milliseconds 3635 * to the next SETUP_DATA_CALL. 3636 */ getSuggestedRetryDelay(DataCallResponse response)3637 private long getSuggestedRetryDelay(DataCallResponse response) { 3638 /** According to ril.h 3639 * The value < 0 means no value is suggested 3640 * The value 0 means retry should be done ASAP. 3641 * The value of Long.MAX_VALUE(0x7fffffffffffffff) means no retry. 3642 */ 3643 if (response == null) { 3644 return RetryManager.NO_SUGGESTED_RETRY_DELAY; 3645 } 3646 3647 long suggestedRetryTime = response.getRetryDurationMillis(); 3648 3649 // The value < 0 means no value is suggested 3650 if (suggestedRetryTime < 0) { 3651 if (DBG) log("No suggested retry delay."); 3652 return RetryManager.NO_SUGGESTED_RETRY_DELAY; 3653 } else if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6) 3654 && suggestedRetryTime == Long.MAX_VALUE) { 3655 if (DBG) log("Network suggested not retrying."); 3656 return RetryManager.NO_RETRY; 3657 } else if (mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_6) 3658 && suggestedRetryTime == Integer.MAX_VALUE) { 3659 if (DBG) log("Network suggested not retrying."); 3660 return RetryManager.NO_RETRY; 3661 } 3662 3663 return suggestedRetryTime; 3664 } 3665 getApnContexts()3666 public List<ApnContext> getApnContexts() { 3667 return new ArrayList<>(mApnContexts.keySet()); 3668 } 3669 3670 /** 3671 * Return whether there is an ApnContext for the given type in this DataConnection. 3672 * @param type APN type to check 3673 * @param exclusive true if the given APN type should be the only APN type that exists 3674 * @return True if there is an ApnContext for the given type 3675 */ isApnContextAttached(@pnType int type, boolean exclusive)3676 private boolean isApnContextAttached(@ApnType int type, boolean exclusive) { 3677 boolean attached = mApnContexts.keySet().stream() 3678 .map(ApnContext::getApnTypeBitmask) 3679 .anyMatch(bitmask -> bitmask == type); 3680 if (exclusive) { 3681 attached &= mApnContexts.size() == 1; 3682 } 3683 return attached; 3684 } 3685 3686 /** Get the network agent of the data connection */ 3687 @Nullable getNetworkAgent()3688 DcNetworkAgent getNetworkAgent() { 3689 return mNetworkAgent; 3690 } 3691 setHandoverState(@andoverState int state)3692 void setHandoverState(@HandoverState int state) { 3693 if (mHandoverState != state) { 3694 String logStr = "State changed from " + handoverStateToString(mHandoverState) 3695 + " to " + handoverStateToString(state); 3696 mHandoverLocalLog.log(logStr); 3697 logd(logStr); 3698 mHandoverState = state; 3699 } 3700 } 3701 3702 /** Sets the {@link DataCallSessionStats} mock for this phone ID during unit testing. */ 3703 @VisibleForTesting setDataCallSessionStats(DataCallSessionStats dataCallSessionStats)3704 public void setDataCallSessionStats(DataCallSessionStats dataCallSessionStats) { 3705 mDataCallSessionStats = dataCallSessionStats; 3706 } 3707 3708 /** 3709 * @return the string for msg.what as our info. 3710 */ 3711 @Override getWhatToString(int what)3712 protected String getWhatToString(int what) { 3713 return cmdToString(what); 3714 } 3715 msgToString(Message msg)3716 private static String msgToString(Message msg) { 3717 String retVal; 3718 if (msg == null) { 3719 retVal = "null"; 3720 } else { 3721 StringBuilder b = new StringBuilder(); 3722 3723 b.append("{what="); 3724 b.append(cmdToString(msg.what)); 3725 3726 b.append(" when="); 3727 TimeUtils.formatDuration(msg.getWhen() - SystemClock.uptimeMillis(), b); 3728 3729 if (msg.arg1 != 0) { 3730 b.append(" arg1="); 3731 b.append(msg.arg1); 3732 } 3733 3734 if (msg.arg2 != 0) { 3735 b.append(" arg2="); 3736 b.append(msg.arg2); 3737 } 3738 3739 if (msg.obj != null) { 3740 b.append(" obj="); 3741 b.append(msg.obj); 3742 } 3743 3744 b.append(" target="); 3745 b.append(msg.getTarget()); 3746 3747 b.append(" replyTo="); 3748 b.append(msg.replyTo); 3749 3750 b.append("}"); 3751 3752 retVal = b.toString(); 3753 } 3754 return retVal; 3755 } 3756 slog(String s)3757 static void slog(String s) { 3758 Rlog.d("DC", s); 3759 } 3760 3761 /** 3762 * Log with debug 3763 * 3764 * @param s is string log 3765 */ 3766 @Override log(String s)3767 protected void log(String s) { 3768 Rlog.d(getName(), s); 3769 } 3770 3771 /** 3772 * Log with debug attribute 3773 * 3774 * @param s is string log 3775 */ 3776 @Override logd(String s)3777 protected void logd(String s) { 3778 Rlog.d(getName(), s); 3779 } 3780 3781 /** 3782 * Log with verbose attribute 3783 * 3784 * @param s is string log 3785 */ 3786 @Override logv(String s)3787 protected void logv(String s) { 3788 Rlog.v(getName(), s); 3789 } 3790 3791 /** 3792 * Log with info attribute 3793 * 3794 * @param s is string log 3795 */ 3796 @Override logi(String s)3797 protected void logi(String s) { 3798 Rlog.i(getName(), s); 3799 } 3800 3801 /** 3802 * Log with warning attribute 3803 * 3804 * @param s is string log 3805 */ 3806 @Override logw(String s)3807 protected void logw(String s) { 3808 Rlog.w(getName(), s); 3809 } 3810 3811 /** 3812 * Log with error attribute 3813 * 3814 * @param s is string log 3815 */ 3816 @Override loge(String s)3817 protected void loge(String s) { 3818 Rlog.e(getName(), s); 3819 } 3820 3821 /** 3822 * Log with error attribute 3823 * 3824 * @param s is string log 3825 * @param e is a Throwable which logs additional information. 3826 */ 3827 @Override loge(String s, Throwable e)3828 protected void loge(String s, Throwable e) { 3829 Rlog.e(getName(), s, e); 3830 } 3831 3832 /** Doesn't print mApnList of ApnContext's which would be recursive */ toStringSimple()3833 public String toStringSimple() { 3834 return getName() + ": State=" + getCurrentState().getName() 3835 + " mApnSetting=" + mApnSetting + " RefCount=" + mApnContexts.size() 3836 + " mCid=" + mCid + " mCreateTime=" + mCreateTime 3837 + " mLastastFailTime=" + mLastFailTime 3838 + " mLastFailCause=" + DataFailCause.toString(mLastFailCause) 3839 + " mTag=" + mTag 3840 + " mLinkProperties=" + mLinkProperties 3841 + " linkCapabilities=" + getNetworkCapabilities() 3842 + " mRestrictedNetworkOverride=" + mRestrictedNetworkOverride; 3843 } 3844 3845 @Override toString()3846 public String toString() { 3847 return "{" + toStringSimple() + " mApnContexts=" + mApnContexts + "}"; 3848 } 3849 3850 /** Check if the device is connected to NR 5G Non-Standalone network. */ isNRConnected()3851 private boolean isNRConnected() { 3852 return mPhone.getServiceState().getNrState() 3853 == NetworkRegistrationInfo.NR_STATE_CONNECTED; 3854 } 3855 3856 /** 3857 * @return The disallowed APN types bitmask 3858 */ getDisallowedApnTypes()3859 private @ApnType int getDisallowedApnTypes() { 3860 CarrierConfigManager configManager = (CarrierConfigManager) 3861 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 3862 int apnTypesBitmask = 0; 3863 if (configManager != null) { 3864 PersistableBundle bundle = configManager.getConfigForSubId(mSubId); 3865 if (bundle != null) { 3866 String key = (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 3867 ? CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY 3868 : CarrierConfigManager.KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY; 3869 if (bundle.getStringArray(key) != null) { 3870 String disallowedApnTypesString = 3871 TextUtils.join(",", bundle.getStringArray(key)); 3872 if (!TextUtils.isEmpty(disallowedApnTypesString)) { 3873 apnTypesBitmask = ApnSetting.getApnTypesBitmaskFromString( 3874 disallowedApnTypesString); 3875 } 3876 } 3877 } 3878 } 3879 3880 return apnTypesBitmask; 3881 } 3882 dumpToLog()3883 private void dumpToLog() { 3884 dump(null, new PrintWriter(new StringWriter(0)) { 3885 @Override 3886 public void println(String s) { 3887 DataConnection.this.logd(s); 3888 } 3889 3890 @Override 3891 public void flush() { 3892 } 3893 }, null); 3894 } 3895 3896 /** 3897 * Re-calculate score and update through network agent if it changes. 3898 */ updateScore()3899 private void updateScore() { 3900 int oldScore = mScore; 3901 mScore = calculateScore(); 3902 if (oldScore != mScore && mNetworkAgent != null) { 3903 log("Updating score from " + oldScore + " to " + mScore); 3904 mNetworkAgent.sendNetworkScore(mScore, this); 3905 } 3906 } 3907 calculateScore()3908 private int calculateScore() { 3909 int score = OTHER_CONNECTION_SCORE; 3910 3911 // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have 3912 // specify a subId, this dataConnection is considered to be default Internet data 3913 // connection. In this case we assign a slightly higher score of 50. The intention is 3914 // it will not be replaced by other data connections accidentally in DSDS usecase. 3915 for (ApnContext apnContext : mApnContexts.keySet()) { 3916 for (NetworkRequest networkRequest : apnContext.getNetworkRequests()) { 3917 if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 3918 && networkRequest.getNetworkSpecifier() == null) { 3919 score = DEFAULT_INTERNET_CONNECTION_SCORE; 3920 break; 3921 } 3922 } 3923 } 3924 3925 return score; 3926 } 3927 handoverStateToString(@andoverState int state)3928 private String handoverStateToString(@HandoverState int state) { 3929 switch (state) { 3930 case HANDOVER_STATE_IDLE: return "IDLE"; 3931 case HANDOVER_STATE_BEING_TRANSFERRED: return "BEING_TRANSFERRED"; 3932 case HANDOVER_STATE_COMPLETED: return "COMPLETED"; 3933 default: return "UNKNOWN"; 3934 } 3935 } 3936 getState()3937 private @DataState int getState() { 3938 if (isInactive()) { 3939 return TelephonyManager.DATA_DISCONNECTED; 3940 } else if (isActivating()) { 3941 return TelephonyManager.DATA_CONNECTING; 3942 } else if (isActive()) { 3943 // The data connection can only be suspended when it's in active state. 3944 if (mIsSuspended) { 3945 return TelephonyManager.DATA_SUSPENDED; 3946 } 3947 return TelephonyManager.DATA_CONNECTED; 3948 } else if (isDisconnecting()) { 3949 return TelephonyManager.DATA_DISCONNECTING; 3950 } 3951 3952 return TelephonyManager.DATA_UNKNOWN; 3953 } 3954 3955 /** 3956 * Get precise data connection state 3957 * 3958 * @return The {@link PreciseDataConnectionState} 3959 */ getPreciseDataConnectionState()3960 public PreciseDataConnectionState getPreciseDataConnectionState() { 3961 return new PreciseDataConnectionState.Builder() 3962 .setTransportType(mTransportType) 3963 .setId(mCid) 3964 .setState(getState()) 3965 .setApnSetting(mApnSetting) 3966 .setLinkProperties(mLinkProperties) 3967 .setNetworkType(getNetworkType()) 3968 .setFailCause(mDcFailCause) 3969 .build(); 3970 } 3971 3972 /** 3973 * Dump the current state. 3974 * 3975 * @param fd 3976 * @param printWriter 3977 * @param args 3978 */ 3979 @Override dump(FileDescriptor fd, PrintWriter printWriter, String[] args)3980 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 3981 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 3982 pw.print("DataConnection "); 3983 super.dump(fd, pw, args); 3984 pw.flush(); 3985 pw.increaseIndent(); 3986 pw.println("transport type=" 3987 + AccessNetworkConstants.transportTypeToString(mTransportType)); 3988 pw.println("mApnContexts.size=" + mApnContexts.size()); 3989 pw.println("mApnContexts=" + mApnContexts); 3990 pw.println("mApnSetting=" + mApnSetting); 3991 pw.println("mTag=" + mTag); 3992 pw.println("mCid=" + mCid); 3993 pw.println("mConnectionParams=" + mConnectionParams); 3994 pw.println("mDisconnectParams=" + mDisconnectParams); 3995 pw.println("mDcFailCause=" + DataFailCause.toString(mDcFailCause)); 3996 pw.println("mPhone=" + mPhone); 3997 pw.println("mSubId=" + mSubId); 3998 pw.println("mLinkProperties=" + mLinkProperties); 3999 pw.flush(); 4000 pw.println("mDataRegState=" + mDataRegState); 4001 pw.println("mHandoverState=" + handoverStateToString(mHandoverState)); 4002 pw.println("mRilRat=" + mRilRat); 4003 pw.println("mNetworkCapabilities=" + getNetworkCapabilities()); 4004 pw.println("mCreateTime=" + TimeUtils.logTimeOfDay(mCreateTime)); 4005 pw.println("mLastFailTime=" + TimeUtils.logTimeOfDay(mLastFailTime)); 4006 pw.println("mLastFailCause=" + DataFailCause.toString(mLastFailCause)); 4007 pw.println("mUserData=" + mUserData); 4008 pw.println("mRestrictedNetworkOverride=" + mRestrictedNetworkOverride); 4009 pw.println("mUnmeteredUseOnly=" + mUnmeteredUseOnly); 4010 pw.println("mMmsUseOnly=" + mMmsUseOnly); 4011 pw.println("mEnterpriseUse=" + mEnterpriseUse); 4012 pw.println("mUnmeteredOverride=" + mUnmeteredOverride); 4013 pw.println("mCongestedOverride=" + mCongestedOverride); 4014 pw.println("mDownlinkBandwidth" + mDownlinkBandwidth); 4015 pw.println("mUplinkBandwidth=" + mUplinkBandwidth); 4016 pw.println("mDefaultQos=" + mDefaultQos); 4017 pw.println("mQosBearerSessions=" + mQosBearerSessions); 4018 pw.println("disallowedApnTypes=" 4019 + ApnSetting.getApnTypesStringFromBitmask(getDisallowedApnTypes())); 4020 pw.println("mInstanceNumber=" + mInstanceNumber); 4021 pw.println("mAc=" + mAc); 4022 pw.println("mScore=" + mScore); 4023 if (mNetworkAgent != null) { 4024 mNetworkAgent.dump(fd, pw, args); 4025 } 4026 pw.println("handover local log:"); 4027 pw.increaseIndent(); 4028 mHandoverLocalLog.dump(fd, pw, args); 4029 pw.decreaseIndent(); 4030 pw.decreaseIndent(); 4031 pw.println(); 4032 pw.flush(); 4033 } 4034 4035 /** 4036 * Class used to track VCN-defined Network policies for this DataConnection. 4037 * 4038 * <p>MUST be registered with the associated DataConnection's Handler. 4039 */ 4040 private class DataConnectionVcnNetworkPolicyChangeListener 4041 implements VcnNetworkPolicyChangeListener { 4042 @Override onPolicyChanged()4043 public void onPolicyChanged() { 4044 // Poll the current underlying Network policy from VcnManager and send to NetworkAgent. 4045 final NetworkCapabilities networkCapabilities = getNetworkCapabilities(); 4046 VcnNetworkPolicyResult policyResult = 4047 mVcnManager.applyVcnNetworkPolicy( 4048 networkCapabilities, getLinkProperties()); 4049 if (policyResult.isTeardownRequested()) { 4050 tearDownAll( 4051 Phone.REASON_VCN_REQUESTED_TEARDOWN, 4052 DcTracker.RELEASE_TYPE_DETACH, 4053 null /* onCompletedMsg */); 4054 } 4055 4056 if (mNetworkAgent != null) { 4057 mNetworkAgent.sendNetworkCapabilities(networkCapabilities, DataConnection.this); 4058 } 4059 } 4060 } 4061 } 4062 4063