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