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.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED; 20 import static android.net.NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED; 21 22 import android.annotation.IntDef; 23 import android.annotation.Nullable; 24 import android.app.PendingIntent; 25 import android.content.Context; 26 import android.net.ConnectivityManager; 27 import android.net.InetAddresses; 28 import android.net.KeepalivePacketData; 29 import android.net.LinkAddress; 30 import android.net.LinkProperties; 31 import android.net.NetworkAgentConfig; 32 import android.net.NetworkCapabilities; 33 import android.net.NetworkFactory; 34 import android.net.NetworkInfo; 35 import android.net.NetworkProvider; 36 import android.net.NetworkRequest; 37 import android.net.ProxyInfo; 38 import android.net.RouteInfo; 39 import android.net.SocketKeepalive; 40 import android.net.TelephonyNetworkSpecifier; 41 import android.os.AsyncResult; 42 import android.os.Message; 43 import android.os.PersistableBundle; 44 import android.os.SystemClock; 45 import android.os.SystemProperties; 46 import android.provider.Telephony; 47 import android.telephony.AccessNetworkConstants; 48 import android.telephony.AccessNetworkConstants.TransportType; 49 import android.telephony.Annotation.ApnType; 50 import android.telephony.Annotation.DataFailureCause; 51 import android.telephony.CarrierConfigManager; 52 import android.telephony.DataFailCause; 53 import android.telephony.NetworkRegistrationInfo; 54 import android.telephony.ServiceState; 55 import android.telephony.SubscriptionManager; 56 import android.telephony.TelephonyManager; 57 import android.telephony.data.ApnSetting; 58 import android.telephony.data.DataCallResponse; 59 import android.telephony.data.DataProfile; 60 import android.telephony.data.DataService; 61 import android.telephony.data.DataServiceCallback; 62 import android.text.TextUtils; 63 import android.util.LocalLog; 64 import android.util.Pair; 65 import android.util.TimeUtils; 66 67 import com.android.internal.annotations.VisibleForTesting; 68 import com.android.internal.telephony.CallTracker; 69 import com.android.internal.telephony.CarrierSignalAgent; 70 import com.android.internal.telephony.DctConstants; 71 import com.android.internal.telephony.LinkCapacityEstimate; 72 import com.android.internal.telephony.Phone; 73 import com.android.internal.telephony.PhoneConstants; 74 import com.android.internal.telephony.PhoneFactory; 75 import com.android.internal.telephony.RIL; 76 import com.android.internal.telephony.RILConstants; 77 import com.android.internal.telephony.RetryManager; 78 import com.android.internal.telephony.ServiceStateTracker; 79 import com.android.internal.telephony.TelephonyStatsLog; 80 import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType; 81 import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType; 82 import com.android.internal.telephony.metrics.TelephonyMetrics; 83 import com.android.internal.telephony.nano.TelephonyProto.RilDataCall; 84 import com.android.internal.util.AsyncChannel; 85 import com.android.internal.util.IndentingPrintWriter; 86 import com.android.internal.util.Protocol; 87 import com.android.internal.util.State; 88 import com.android.internal.util.StateMachine; 89 import com.android.telephony.Rlog; 90 91 import java.io.FileDescriptor; 92 import java.io.PrintWriter; 93 import java.io.StringWriter; 94 import java.lang.annotation.Retention; 95 import java.lang.annotation.RetentionPolicy; 96 import java.net.InetAddress; 97 import java.net.UnknownHostException; 98 import java.util.ArrayList; 99 import java.util.Arrays; 100 import java.util.Collection; 101 import java.util.List; 102 import java.util.Locale; 103 import java.util.Map; 104 import java.util.concurrent.ConcurrentHashMap; 105 import java.util.concurrent.atomic.AtomicInteger; 106 107 /** 108 * {@hide} 109 * 110 * DataConnection StateMachine. 111 * 112 * This a class for representing a single data connection, with instances of this 113 * class representing a connection via the cellular network. There may be multiple 114 * data connections and all of them are managed by the <code>DataConnectionTracker</code>. 115 * 116 * NOTE: All DataConnection objects must be running on the same looper, which is the default 117 * as the coordinator has members which are used without synchronization. 118 */ 119 public class DataConnection extends StateMachine { 120 private static final boolean DBG = true; 121 private static final boolean VDBG = true; 122 123 private static final String NETWORK_TYPE = "MOBILE"; 124 125 private static final String RAT_NAME_5G = "nr"; 126 private static final String RAT_NAME_EVDO = "evdo"; 127 128 /** 129 * The data connection is not being or been handovered. Note this is the state for the source 130 * data connection, not destination data connection 131 */ 132 private static final int HANDOVER_STATE_IDLE = 1; 133 134 /** 135 * The data connection is being handovered. Note this is the state for the source 136 * data connection, not destination data connection. 137 */ 138 private static final int HANDOVER_STATE_BEING_TRANSFERRED = 2; 139 140 /** 141 * The data connection is already handovered. Note this is the state for the source 142 * data connection, not destination data connection. 143 */ 144 private static final int HANDOVER_STATE_COMPLETED = 3; 145 146 /** @hide */ 147 @Retention(RetentionPolicy.SOURCE) 148 @IntDef(prefix = {"HANDOVER_STATE_"}, value = { 149 HANDOVER_STATE_IDLE, 150 HANDOVER_STATE_BEING_TRANSFERRED, 151 HANDOVER_STATE_COMPLETED}) 152 public @interface HandoverState {} 153 154 // The data connection providing default Internet connection will have a higher score of 50. 155 // Other connections will have a slightly lower score of 45. The intention is other connections 156 // will not cause ConnectivityService to tear down default internet connection. For example, 157 // to validate Internet connection on non-default data SIM, we'll set up a temporary Internet 158 // connection on that data SIM. In this case, score of 45 is assigned so ConnectivityService 159 // will not replace the default Internet connection with it. 160 private static final int DEFAULT_INTERNET_CONNECTION_SCORE = 50; 161 private static final int OTHER_CONNECTION_SCORE = 45; 162 163 // The score we report to connectivity service 164 private int mScore; 165 166 // The subscription id associated with this data connection. 167 private int mSubId; 168 169 // The data connection controller 170 private DcController mDcController; 171 172 // The Tester for failing all bringup's 173 private DcTesterFailBringUpAll mDcTesterFailBringUpAll; 174 175 private static AtomicInteger mInstanceNumber = new AtomicInteger(0); 176 private AsyncChannel mAc; 177 178 // The DCT that's talking to us, we only support one! 179 private DcTracker mDct = null; 180 181 private String[] mPcscfAddr; 182 183 private final String mTagSuffix; 184 185 private final LocalLog mHandoverLocalLog = new LocalLog(100); 186 187 private int[] mAdministratorUids = new int[0]; 188 189 /** 190 * Used internally for saving connecting parameters. 191 */ 192 public static class ConnectionParams { 193 int mTag; 194 ApnContext mApnContext; 195 int mProfileId; 196 int mRilRat; 197 Message mOnCompletedMsg; 198 final int mConnectionGeneration; 199 @RequestNetworkType 200 final int mRequestType; 201 final int mSubId; 202 final boolean mIsPreferredApn; 203 ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isPreferredApn)204 ConnectionParams(ApnContext apnContext, int profileId, int rilRadioTechnology, 205 Message onCompletedMsg, int connectionGeneration, 206 @RequestNetworkType int requestType, int subId, 207 boolean isPreferredApn) { 208 mApnContext = apnContext; 209 mProfileId = profileId; 210 mRilRat = rilRadioTechnology; 211 mOnCompletedMsg = onCompletedMsg; 212 mConnectionGeneration = connectionGeneration; 213 mRequestType = requestType; 214 mSubId = subId; 215 mIsPreferredApn = isPreferredApn; 216 } 217 218 @Override toString()219 public String toString() { 220 return "{mTag=" + mTag + " mApnContext=" + mApnContext 221 + " mProfileId=" + mProfileId 222 + " mRat=" + mRilRat 223 + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) 224 + " mRequestType=" + DcTracker.requestTypeToString(mRequestType) 225 + " mSubId=" + mSubId 226 + " mIsPreferredApn=" + mIsPreferredApn 227 + "}"; 228 } 229 } 230 231 /** 232 * Used internally for saving disconnecting parameters. 233 */ 234 public static class DisconnectParams { 235 int mTag; 236 public ApnContext mApnContext; 237 String mReason; 238 @ReleaseNetworkType 239 final int mReleaseType; 240 Message mOnCompletedMsg; 241 DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)242 DisconnectParams(ApnContext apnContext, String reason, @ReleaseNetworkType int releaseType, 243 Message onCompletedMsg) { 244 mApnContext = apnContext; 245 mReason = reason; 246 mReleaseType = releaseType; 247 mOnCompletedMsg = onCompletedMsg; 248 } 249 250 @Override toString()251 public String toString() { 252 return "{mTag=" + mTag + " mApnContext=" + mApnContext 253 + " mReason=" + mReason 254 + " mReleaseType=" + DcTracker.releaseTypeToString(mReleaseType) 255 + " mOnCompletedMsg=" + msgToString(mOnCompletedMsg) + "}"; 256 } 257 } 258 259 private ApnSetting mApnSetting; 260 private ConnectionParams mConnectionParams; 261 private DisconnectParams mDisconnectParams; 262 @DataFailureCause 263 private int mDcFailCause; 264 265 private Phone mPhone; 266 private DataServiceManager mDataServiceManager; 267 private final int mTransportType; 268 private LinkProperties mLinkProperties = new LinkProperties(); 269 private long mCreateTime; 270 private long mLastFailTime; 271 @DataFailureCause 272 private int mLastFailCause; 273 private static final String NULL_IP = "0.0.0.0"; 274 private Object mUserData; 275 private int mSubscriptionOverride; 276 private boolean mUnmeteredOverride; 277 private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN; 278 private int mDataRegState = Integer.MAX_VALUE; 279 private NetworkInfo mNetworkInfo; 280 private int mDownlinkBandwidth = 14; 281 private int mUplinkBandwidth = 14; 282 283 /** The corresponding network agent for this data connection. */ 284 private DcNetworkAgent mNetworkAgent; 285 286 /** 287 * The network agent from handover source data connection. This is the potential network agent 288 * that will be transferred here after handover completed. 289 */ 290 private DcNetworkAgent mHandoverSourceNetworkAgent; 291 292 private int mDisabledApnTypeBitMask = 0; 293 294 int mTag; 295 296 /** Data connection id assigned by the modem. This is unique across transports */ 297 public int mCid; 298 299 @HandoverState 300 private int mHandoverState; 301 private final Map<ApnContext, ConnectionParams> mApnContexts = new ConcurrentHashMap<>(); 302 PendingIntent mReconnectIntent = null; 303 304 305 // ***** Event codes for driving the state machine, package visible for Dcc 306 static final int BASE = Protocol.BASE_DATA_CONNECTION; 307 static final int EVENT_CONNECT = BASE + 0; 308 static final int EVENT_SETUP_DATA_CONNECTION_DONE = BASE + 1; 309 static final int EVENT_DEACTIVATE_DONE = BASE + 3; 310 static final int EVENT_DISCONNECT = BASE + 4; 311 static final int EVENT_RIL_CONNECTED = BASE + 5; 312 static final int EVENT_DISCONNECT_ALL = BASE + 6; 313 static final int EVENT_DATA_STATE_CHANGED = BASE + 7; 314 static final int EVENT_TEAR_DOWN_NOW = BASE + 8; 315 static final int EVENT_LOST_CONNECTION = BASE + 9; 316 static final int EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED = BASE + 11; 317 static final int EVENT_DATA_CONNECTION_ROAM_ON = BASE + 12; 318 static final int EVENT_DATA_CONNECTION_ROAM_OFF = BASE + 13; 319 static final int EVENT_BW_REFRESH_RESPONSE = BASE + 14; 320 static final int EVENT_DATA_CONNECTION_VOICE_CALL_STARTED = BASE + 15; 321 static final int EVENT_DATA_CONNECTION_VOICE_CALL_ENDED = BASE + 16; 322 static final int EVENT_DATA_CONNECTION_OVERRIDE_CHANGED = BASE + 17; 323 static final int EVENT_KEEPALIVE_STATUS = BASE + 18; 324 static final int EVENT_KEEPALIVE_STARTED = BASE + 19; 325 static final int EVENT_KEEPALIVE_STOPPED = BASE + 20; 326 static final int EVENT_KEEPALIVE_START_REQUEST = BASE + 21; 327 static final int EVENT_KEEPALIVE_STOP_REQUEST = BASE + 22; 328 static final int EVENT_LINK_CAPACITY_CHANGED = BASE + 23; 329 static final int EVENT_RESET = BASE + 24; 330 static final int EVENT_REEVALUATE_RESTRICTED_STATE = BASE + 25; 331 static final int EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES = BASE + 26; 332 static final int EVENT_NR_STATE_CHANGED = BASE + 27; 333 static final int EVENT_DATA_CONNECTION_METEREDNESS_CHANGED = BASE + 28; 334 static final int EVENT_NR_FREQUENCY_CHANGED = BASE + 29; 335 static final int EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED = BASE + 30; 336 static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = BASE + 31; 337 private static final int CMD_TO_STRING_COUNT = EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED - BASE + 1; 338 339 private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT]; 340 static { 341 sCmdToString[EVENT_CONNECT - BASE] = "EVENT_CONNECT"; 342 sCmdToString[EVENT_SETUP_DATA_CONNECTION_DONE - BASE] = 343 "EVENT_SETUP_DATA_CONNECTION_DONE"; 344 sCmdToString[EVENT_DEACTIVATE_DONE - BASE] = "EVENT_DEACTIVATE_DONE"; 345 sCmdToString[EVENT_DISCONNECT - BASE] = "EVENT_DISCONNECT"; 346 sCmdToString[EVENT_RIL_CONNECTED - BASE] = "EVENT_RIL_CONNECTED"; 347 sCmdToString[EVENT_DISCONNECT_ALL - BASE] = "EVENT_DISCONNECT_ALL"; 348 sCmdToString[EVENT_DATA_STATE_CHANGED - BASE] = "EVENT_DATA_STATE_CHANGED"; 349 sCmdToString[EVENT_TEAR_DOWN_NOW - BASE] = "EVENT_TEAR_DOWN_NOW"; 350 sCmdToString[EVENT_LOST_CONNECTION - BASE] = "EVENT_LOST_CONNECTION"; 351 sCmdToString[EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED - BASE] = 352 "EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"; 353 sCmdToString[EVENT_DATA_CONNECTION_ROAM_ON - BASE] = "EVENT_DATA_CONNECTION_ROAM_ON"; 354 sCmdToString[EVENT_DATA_CONNECTION_ROAM_OFF - BASE] = "EVENT_DATA_CONNECTION_ROAM_OFF"; 355 sCmdToString[EVENT_BW_REFRESH_RESPONSE - BASE] = "EVENT_BW_REFRESH_RESPONSE"; 356 sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_STARTED - BASE] = 357 "EVENT_DATA_CONNECTION_VOICE_CALL_STARTED"; 358 sCmdToString[EVENT_DATA_CONNECTION_VOICE_CALL_ENDED - BASE] = 359 "EVENT_DATA_CONNECTION_VOICE_CALL_ENDED"; 360 sCmdToString[EVENT_DATA_CONNECTION_OVERRIDE_CHANGED - BASE] = 361 "EVENT_DATA_CONNECTION_OVERRIDE_CHANGED"; 362 sCmdToString[EVENT_KEEPALIVE_STATUS - BASE] = "EVENT_KEEPALIVE_STATUS"; 363 sCmdToString[EVENT_KEEPALIVE_STARTED - BASE] = "EVENT_KEEPALIVE_STARTED"; 364 sCmdToString[EVENT_KEEPALIVE_STOPPED - BASE] = "EVENT_KEEPALIVE_STOPPED"; 365 sCmdToString[EVENT_KEEPALIVE_START_REQUEST - BASE] = "EVENT_KEEPALIVE_START_REQUEST"; 366 sCmdToString[EVENT_KEEPALIVE_STOP_REQUEST - BASE] = "EVENT_KEEPALIVE_STOP_REQUEST"; 367 sCmdToString[EVENT_LINK_CAPACITY_CHANGED - BASE] = "EVENT_LINK_CAPACITY_CHANGED"; 368 sCmdToString[EVENT_RESET - BASE] = "EVENT_RESET"; 369 sCmdToString[EVENT_REEVALUATE_RESTRICTED_STATE - BASE] = 370 "EVENT_REEVALUATE_RESTRICTED_STATE"; 371 sCmdToString[EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES - BASE] = 372 "EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES"; 373 sCmdToString[EVENT_NR_STATE_CHANGED - BASE] = "EVENT_NR_STATE_CHANGED"; 374 sCmdToString[EVENT_DATA_CONNECTION_METEREDNESS_CHANGED - BASE] = 375 "EVENT_DATA_CONNECTION_METEREDNESS_CHANGED"; 376 sCmdToString[EVENT_NR_FREQUENCY_CHANGED - BASE] = "EVENT_NR_FREQUENCY_CHANGED"; 377 sCmdToString[EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED - BASE] = 378 "EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED"; 379 sCmdToString[EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED - BASE] = 380 "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED"; 381 } 382 // Convert cmd to string or null if unknown cmdToString(int cmd)383 static String cmdToString(int cmd) { 384 String value = null; 385 cmd -= BASE; 386 if ((cmd >= 0) && (cmd < sCmdToString.length)) { 387 value = sCmdToString[cmd]; 388 } 389 if (value == null) { 390 value = "0x" + Integer.toHexString(cmd + BASE); 391 } 392 return value; 393 } 394 395 /** 396 * Create the connection object 397 * 398 * @param phone the Phone 399 * @param id the connection id 400 * @return DataConnection that was created. 401 */ makeDataConnection(Phone phone, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc)402 public static DataConnection makeDataConnection(Phone phone, int id, DcTracker dct, 403 DataServiceManager dataServiceManager, 404 DcTesterFailBringUpAll failBringUpAll, 405 DcController dcc) { 406 String transportType = (dataServiceManager.getTransportType() 407 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 408 ? "C" // Cellular 409 : "I"; // IWLAN 410 DataConnection dc = new DataConnection(phone, transportType + "-" 411 + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll, 412 dcc); 413 dc.start(); 414 if (DBG) dc.log("Made " + dc.getName()); 415 return dc; 416 } 417 dispose()418 void dispose() { 419 log("dispose: call quiteNow()"); 420 quitNow(); 421 } 422 423 /* Getter functions */ 424 getLinkProperties()425 LinkProperties getLinkProperties() { 426 return new LinkProperties(mLinkProperties); 427 } 428 isInactive()429 boolean isInactive() { 430 return getCurrentState() == mInactiveState; 431 } 432 isDisconnecting()433 boolean isDisconnecting() { 434 return getCurrentState() == mDisconnectingState; 435 } 436 437 @VisibleForTesting isActive()438 public boolean isActive() { 439 return getCurrentState() == mActiveState; 440 } 441 isActivating()442 boolean isActivating() { 443 return getCurrentState() == mActivatingState; 444 } 445 hasBeenTransferred()446 boolean hasBeenTransferred() { 447 return mHandoverState == HANDOVER_STATE_COMPLETED; 448 } 449 getCid()450 int getCid() { 451 return mCid; 452 } 453 getApnSetting()454 ApnSetting getApnSetting() { 455 return mApnSetting; 456 } 457 setLinkPropertiesHttpProxy(ProxyInfo proxy)458 void setLinkPropertiesHttpProxy(ProxyInfo proxy) { 459 mLinkProperties.setHttpProxy(proxy); 460 } 461 462 public static class UpdateLinkPropertyResult { 463 public SetupResult setupResult = SetupResult.SUCCESS; 464 public LinkProperties oldLp; 465 public LinkProperties newLp; UpdateLinkPropertyResult(LinkProperties curLp)466 public UpdateLinkPropertyResult(LinkProperties curLp) { 467 oldLp = curLp; 468 newLp = curLp; 469 } 470 } 471 472 /** 473 * Class returned by onSetupConnectionCompleted. 474 */ 475 public enum SetupResult { 476 SUCCESS, 477 ERROR_RADIO_NOT_AVAILABLE, 478 ERROR_INVALID_ARG, 479 ERROR_STALE, 480 ERROR_DATA_SERVICE_SPECIFIC_ERROR; 481 482 public int mFailCause; 483 SetupResult()484 SetupResult() { 485 mFailCause = DataFailCause.getFailCause(0); 486 } 487 488 @Override toString()489 public String toString() { 490 return name() + " SetupResult.mFailCause=" + mFailCause; 491 } 492 } 493 isIpv4Connected()494 public boolean isIpv4Connected() { 495 boolean ret = false; 496 Collection <InetAddress> addresses = mLinkProperties.getAddresses(); 497 498 for (InetAddress addr: addresses) { 499 if (addr instanceof java.net.Inet4Address) { 500 java.net.Inet4Address i4addr = (java.net.Inet4Address) addr; 501 if (!i4addr.isAnyLocalAddress() && !i4addr.isLinkLocalAddress() && 502 !i4addr.isLoopbackAddress() && !i4addr.isMulticastAddress()) { 503 ret = true; 504 break; 505 } 506 } 507 } 508 return ret; 509 } 510 isIpv6Connected()511 public boolean isIpv6Connected() { 512 boolean ret = false; 513 Collection <InetAddress> addresses = mLinkProperties.getAddresses(); 514 515 for (InetAddress addr: addresses) { 516 if (addr instanceof java.net.Inet6Address) { 517 java.net.Inet6Address i6addr = (java.net.Inet6Address) addr; 518 if (!i6addr.isAnyLocalAddress() && !i6addr.isLinkLocalAddress() && 519 !i6addr.isLoopbackAddress() && !i6addr.isMulticastAddress()) { 520 ret = true; 521 break; 522 } 523 } 524 } 525 return ret; 526 } 527 528 @VisibleForTesting updateLinkProperty(DataCallResponse newState)529 public UpdateLinkPropertyResult updateLinkProperty(DataCallResponse newState) { 530 UpdateLinkPropertyResult result = new UpdateLinkPropertyResult(mLinkProperties); 531 532 if (newState == null) return result; 533 534 result.newLp = new LinkProperties(); 535 536 // set link properties based on data call response 537 result.setupResult = setLinkProperties(newState, result.newLp); 538 if (result.setupResult != SetupResult.SUCCESS) { 539 if (DBG) log("updateLinkProperty failed : " + result.setupResult); 540 return result; 541 } 542 // copy HTTP proxy as it is not part DataCallResponse. 543 result.newLp.setHttpProxy(mLinkProperties.getHttpProxy()); 544 545 checkSetMtu(mApnSetting, result.newLp); 546 547 mLinkProperties = result.newLp; 548 549 updateTcpBufferSizes(mRilRat); 550 551 if (DBG && (! result.oldLp.equals(result.newLp))) { 552 log("updateLinkProperty old LP=" + result.oldLp); 553 log("updateLinkProperty new LP=" + result.newLp); 554 } 555 556 if (result.newLp.equals(result.oldLp) == false && 557 mNetworkAgent != null) { 558 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 559 } 560 561 return result; 562 } 563 564 /** 565 * Read the MTU value from link properties where it can be set from network. In case 566 * not set by the network, set it again using the mtu szie value defined in the APN 567 * database for the connected APN 568 */ checkSetMtu(ApnSetting apn, LinkProperties lp)569 private void checkSetMtu(ApnSetting apn, LinkProperties lp) { 570 if (lp == null) return; 571 572 if (apn == null || lp == null) return; 573 574 if (lp.getMtu() != PhoneConstants.UNSET_MTU) { 575 if (DBG) log("MTU set by call response to: " + lp.getMtu()); 576 return; 577 } 578 579 if (apn != null && apn.getMtu() != PhoneConstants.UNSET_MTU) { 580 lp.setMtu(apn.getMtu()); 581 if (DBG) log("MTU set by APN to: " + apn.getMtu()); 582 return; 583 } 584 585 int mtu = mPhone.getContext().getResources().getInteger( 586 com.android.internal.R.integer.config_mobile_mtu); 587 if (mtu != PhoneConstants.UNSET_MTU) { 588 lp.setMtu(mtu); 589 if (DBG) log("MTU set by config resource to: " + mtu); 590 } 591 } 592 593 //***** Constructor (NOTE: uses dcc.getHandler() as its Handler) DataConnection(Phone phone, String tagSuffix, int id, DcTracker dct, DataServiceManager dataServiceManager, DcTesterFailBringUpAll failBringUpAll, DcController dcc)594 private DataConnection(Phone phone, String tagSuffix, int id, 595 DcTracker dct, DataServiceManager dataServiceManager, 596 DcTesterFailBringUpAll failBringUpAll, DcController dcc) { 597 super("DC-" + tagSuffix, dcc.getHandler()); 598 mTagSuffix = tagSuffix; 599 setLogRecSize(300); 600 setLogOnlyTransitions(true); 601 if (DBG) log("DataConnection created"); 602 603 mPhone = phone; 604 mDct = dct; 605 mDataServiceManager = dataServiceManager; 606 mTransportType = dataServiceManager.getTransportType(); 607 mDcTesterFailBringUpAll = failBringUpAll; 608 mDcController = dcc; 609 mId = id; 610 mCid = -1; 611 ServiceState ss = mPhone.getServiceState(); 612 mDataRegState = mPhone.getServiceState().getDataRegistrationState(); 613 int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 614 615 NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo( 616 NetworkRegistrationInfo.DOMAIN_PS, mTransportType); 617 if (nri != null) { 618 networkType = nri.getAccessNetworkTechnology(); 619 mRilRat = ServiceState.networkTypeToRilRadioTechnology(networkType); 620 updateLinkBandwidthsFromCarrierConfig(mRilRat); 621 } 622 623 mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_MOBILE, 624 networkType, NETWORK_TYPE, TelephonyManager.getNetworkTypeName(networkType)); 625 626 addState(mDefaultState); 627 addState(mInactiveState, mDefaultState); 628 addState(mActivatingState, mDefaultState); 629 addState(mActiveState, mDefaultState); 630 addState(mDisconnectingState, mDefaultState); 631 addState(mDisconnectingErrorCreatingConnection, mDefaultState); 632 setInitialState(mInactiveState); 633 } 634 635 /** 636 * Get the source transport for handover. For example, handover from WWAN to WLAN, WWAN is the 637 * source transport, and vice versa. 638 */ getHandoverSourceTransport()639 private @TransportType int getHandoverSourceTransport() { 640 return mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 641 ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN 642 : AccessNetworkConstants.TRANSPORT_TYPE_WWAN; 643 } 644 645 /** 646 * Begin setting up a data connection, calls setupDataCall 647 * and the ConnectionParams will be returned with the 648 * EVENT_SETUP_DATA_CONNECTION_DONE 649 * 650 * @param cp is the connection parameters 651 * 652 * @return Fail cause if failed to setup data connection. {@link DataFailCause#NONE} if success. 653 */ connect(ConnectionParams cp)654 private @DataFailureCause int connect(ConnectionParams cp) { 655 log("connect: carrier='" + mApnSetting.getEntryName() 656 + "' APN='" + mApnSetting.getApnName() 657 + "' proxy='" + mApnSetting.getProxyAddressAsString() 658 + "' port='" + mApnSetting.getProxyPort() + "'"); 659 if (cp.mApnContext != null) cp.mApnContext.requestLog("DataConnection.connect"); 660 661 // Check if we should fake an error. 662 if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter > 0) { 663 DataCallResponse response = new DataCallResponse.Builder() 664 .setCause(mDcTesterFailBringUpAll.getDcFailBringUp().mFailCause) 665 .setSuggestedRetryTime( 666 mDcTesterFailBringUpAll.getDcFailBringUp().mSuggestedRetryTime) 667 .setMtuV4(PhoneConstants.UNSET_MTU) 668 .setMtuV6(PhoneConstants.UNSET_MTU) 669 .build(); 670 671 Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp); 672 AsyncResult.forMessage(msg, response, null); 673 sendMessage(msg); 674 if (DBG) { 675 log("connect: FailBringUpAll=" + mDcTesterFailBringUpAll.getDcFailBringUp() 676 + " send error response=" + response); 677 } 678 mDcTesterFailBringUpAll.getDcFailBringUp().mCounter -= 1; 679 return DataFailCause.NONE; 680 } 681 682 mCreateTime = -1; 683 mLastFailTime = -1; 684 mLastFailCause = DataFailCause.NONE; 685 686 Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp); 687 msg.obj = cp; 688 689 DataProfile dp = DcTracker.createDataProfile(mApnSetting, cp.mProfileId, 690 cp.mIsPreferredApn); 691 692 // We need to use the actual modem roaming state instead of the framework roaming state 693 // here. This flag is only passed down to ril_service for picking the correct protocol (for 694 // old modem backward compatibility). 695 boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration(); 696 697 // If the apn is NOT metered, we will allow data roaming regardless of the setting. 698 boolean isUnmeteredApnType = !ApnSettingUtils.isMeteredApnType( 699 cp.mApnContext.getApnTypeBitmask(), mPhone); 700 701 // Set this flag to true if the user turns on data roaming. Or if we override the roaming 702 // state in framework, we should set this flag to true as well so the modem will not reject 703 // the data call setup (because the modem actually thinks the device is roaming). 704 boolean allowRoaming = mPhone.getDataRoamingEnabled() 705 || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming() 706 || isUnmeteredApnType)); 707 708 if (DBG) { 709 log("allowRoaming=" + allowRoaming 710 + ", mPhone.getDataRoamingEnabled()=" + mPhone.getDataRoamingEnabled() 711 + ", isModemRoaming=" + isModemRoaming 712 + ", mPhone.getServiceState().getDataRoaming()=" 713 + mPhone.getServiceState().getDataRoaming() 714 + ", isUnmeteredApnType=" + isUnmeteredApnType 715 ); 716 } 717 718 // Check if this data setup is a handover. 719 LinkProperties linkProperties = null; 720 int reason = DataService.REQUEST_REASON_NORMAL; 721 if (cp.mRequestType == DcTracker.REQUEST_TYPE_HANDOVER) { 722 // If this is a data setup for handover, we need to pass the link properties 723 // of the existing data connection to the modem. 724 DcTracker dcTracker = mPhone.getDcTracker(getHandoverSourceTransport()); 725 if (dcTracker == null || cp.mApnContext == null) { 726 loge("connect: Handover failed. dcTracker=" + dcTracker + ", apnContext=" 727 + cp.mApnContext); 728 return DataFailCause.HANDOVER_FAILED; 729 } 730 731 DataConnection dc = dcTracker.getDataConnectionByApnType(cp.mApnContext.getApnType()); 732 if (dc == null) { 733 loge("connect: Can't find data connection for handover."); 734 return DataFailCause.HANDOVER_FAILED; 735 } 736 737 // Preserve the potential network agent from the source data connection. The ownership 738 // is not transferred at this moment. 739 mHandoverSourceNetworkAgent = dc.getNetworkAgent(); 740 if (mHandoverSourceNetworkAgent == null) { 741 loge("Cannot get network agent from the source dc " + dc.getName()); 742 return DataFailCause.HANDOVER_FAILED; 743 } 744 745 linkProperties = dc.getLinkProperties(); 746 if (linkProperties == null || linkProperties.getLinkAddresses().isEmpty()) { 747 loge("connect: Can't find link properties of handover data connection. dc=" 748 + dc); 749 return DataFailCause.HANDOVER_FAILED; 750 } 751 752 mHandoverLocalLog.log("Handover started. Preserved the agent."); 753 log("Get the handover source network agent: " + mHandoverSourceNetworkAgent); 754 755 dc.setHandoverState(HANDOVER_STATE_BEING_TRANSFERRED); 756 reason = DataService.REQUEST_REASON_HANDOVER; 757 } 758 759 mDataServiceManager.setupDataCall( 760 ServiceState.rilRadioTechnologyToAccessNetworkType(cp.mRilRat), 761 dp, 762 isModemRoaming, 763 allowRoaming, 764 reason, 765 linkProperties, 766 msg); 767 TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(), cp.mRilRat, 768 dp.getProfileId(), dp.getApn(), dp.getProtocolType()); 769 return DataFailCause.NONE; 770 } 771 onSubscriptionOverride(int overrideMask, int overrideValue)772 public void onSubscriptionOverride(int overrideMask, int overrideValue) { 773 mSubscriptionOverride = (mSubscriptionOverride & ~overrideMask) 774 | (overrideValue & overrideMask); 775 sendMessage(obtainMessage(EVENT_DATA_CONNECTION_OVERRIDE_CHANGED)); 776 } 777 778 /** 779 * Update NetworkCapabilities.NET_CAPABILITY_NOT_METERED based on meteredness 780 * @param isUnmetered whether this DC should be set to unmetered or not 781 */ onMeterednessChanged(boolean isUnmetered)782 public void onMeterednessChanged(boolean isUnmetered) { 783 sendMessage(obtainMessage(EVENT_DATA_CONNECTION_METEREDNESS_CHANGED, isUnmetered)); 784 } 785 786 /** 787 * TearDown the data connection when the deactivation is complete a Message with 788 * msg.what == EVENT_DEACTIVATE_DONE 789 * 790 * @param o is the object returned in the AsyncResult.obj. 791 */ tearDownData(Object o)792 private void tearDownData(Object o) { 793 int discReason = DataService.REQUEST_REASON_NORMAL; 794 ApnContext apnContext = null; 795 if ((o != null) && (o instanceof DisconnectParams)) { 796 DisconnectParams dp = (DisconnectParams) o; 797 apnContext = dp.mApnContext; 798 if (TextUtils.equals(dp.mReason, Phone.REASON_RADIO_TURNED_OFF) 799 || TextUtils.equals(dp.mReason, Phone.REASON_PDP_RESET)) { 800 discReason = DataService.REQUEST_REASON_SHUTDOWN; 801 } else if (dp.mReleaseType == DcTracker.RELEASE_TYPE_HANDOVER) { 802 discReason = DataService.REQUEST_REASON_HANDOVER; 803 } 804 } 805 806 String str = "tearDownData. mCid=" + mCid + ", reason=" + discReason; 807 if (DBG) log(str); 808 if (apnContext != null) apnContext.requestLog(str); 809 mDataServiceManager.deactivateDataCall(mCid, discReason, 810 obtainMessage(EVENT_DEACTIVATE_DONE, mTag, 0, o)); 811 } 812 notifyAllWithEvent(ApnContext alreadySent, int event, String reason)813 private void notifyAllWithEvent(ApnContext alreadySent, int event, String reason) { 814 mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason, 815 mNetworkInfo.getExtraInfo()); 816 for (ConnectionParams cp : mApnContexts.values()) { 817 ApnContext apnContext = cp.mApnContext; 818 if (apnContext == alreadySent) continue; 819 if (reason != null) apnContext.setReason(reason); 820 Pair<ApnContext, Integer> pair = new Pair<>(apnContext, cp.mConnectionGeneration); 821 Message msg = mDct.obtainMessage(event, mCid, cp.mRequestType, pair); 822 AsyncResult.forMessage(msg); 823 msg.sendToTarget(); 824 } 825 } 826 827 /** 828 * Send the connectionCompletedMsg. 829 * 830 * @param cp is the ConnectionParams 831 * @param cause and if no error the cause is DataFailCause.NONE 832 * @param sendAll is true if all contexts are to be notified 833 */ notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause, boolean sendAll)834 private void notifyConnectCompleted(ConnectionParams cp, @DataFailureCause int cause, 835 boolean sendAll) { 836 ApnContext alreadySent = null; 837 838 if (cp != null && cp.mOnCompletedMsg != null) { 839 // Get the completed message but only use it once 840 Message connectionCompletedMsg = cp.mOnCompletedMsg; 841 cp.mOnCompletedMsg = null; 842 alreadySent = cp.mApnContext; 843 844 long timeStamp = System.currentTimeMillis(); 845 connectionCompletedMsg.arg1 = mCid; 846 connectionCompletedMsg.arg2 = cp.mRequestType; 847 848 if (cause == DataFailCause.NONE) { 849 mCreateTime = timeStamp; 850 AsyncResult.forMessage(connectionCompletedMsg); 851 } else { 852 mLastFailCause = cause; 853 mLastFailTime = timeStamp; 854 855 // Return message with a Throwable exception to signify an error. 856 if (cause == DataFailCause.NONE) cause = DataFailCause.UNKNOWN; 857 AsyncResult.forMessage(connectionCompletedMsg, cause, 858 new Throwable(DataFailCause.toString(cause))); 859 } 860 if (DBG) { 861 log("notifyConnectCompleted at " + timeStamp + " cause=" + cause 862 + " connectionCompletedMsg=" + msgToString(connectionCompletedMsg)); 863 } 864 865 connectionCompletedMsg.sendToTarget(); 866 } 867 if (sendAll) { 868 log("Send to all. " + alreadySent + " " + DataFailCause.toString(cause)); 869 notifyAllWithEvent(alreadySent, DctConstants.EVENT_DATA_SETUP_COMPLETE_ERROR, 870 DataFailCause.toString(cause)); 871 } 872 } 873 874 /** 875 * Send ar.userObj if its a message, which is should be back to originator. 876 * 877 * @param dp is the DisconnectParams. 878 */ notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll)879 private void notifyDisconnectCompleted(DisconnectParams dp, boolean sendAll) { 880 if (VDBG) log("NotifyDisconnectCompleted"); 881 882 ApnContext alreadySent = null; 883 String reason = null; 884 885 if (dp != null && dp.mOnCompletedMsg != null) { 886 // Get the completed message but only use it once 887 Message msg = dp.mOnCompletedMsg; 888 dp.mOnCompletedMsg = null; 889 if (msg.obj instanceof ApnContext) { 890 alreadySent = (ApnContext)msg.obj; 891 } 892 reason = dp.mReason; 893 if (VDBG) { 894 log(String.format("msg=%s msg.obj=%s", msg.toString(), 895 ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>"))); 896 } 897 AsyncResult.forMessage(msg); 898 msg.sendToTarget(); 899 } 900 if (sendAll) { 901 if (reason == null) { 902 reason = DataFailCause.toString(DataFailCause.UNKNOWN); 903 } 904 notifyAllWithEvent(alreadySent, DctConstants.EVENT_DISCONNECT_DONE, reason); 905 } 906 if (DBG) log("NotifyDisconnectCompleted DisconnectParams=" + dp); 907 } 908 909 /* 910 * ************************************************************************** 911 * Begin Members and methods owned by DataConnectionTracker but stored 912 * in a DataConnection because there is one per connection. 913 * ************************************************************************** 914 */ 915 916 /* 917 * The id is owned by DataConnectionTracker. 918 */ 919 private int mId; 920 921 /** 922 * Get the DataConnection ID 923 */ getDataConnectionId()924 public int getDataConnectionId() { 925 return mId; 926 } 927 928 /* 929 * ************************************************************************** 930 * End members owned by DataConnectionTracker 931 * ************************************************************************** 932 */ 933 934 /** 935 * Clear all settings called when entering mInactiveState. 936 */ clearSettings()937 private void clearSettings() { 938 if (DBG) log("clearSettings"); 939 940 mCreateTime = -1; 941 mLastFailTime = -1; 942 mLastFailCause = DataFailCause.NONE; 943 mCid = -1; 944 945 mPcscfAddr = new String[5]; 946 947 mLinkProperties = new LinkProperties(); 948 mApnContexts.clear(); 949 mApnSetting = null; 950 mUnmeteredUseOnly = false; 951 mRestrictedNetworkOverride = false; 952 mDcFailCause = DataFailCause.NONE; 953 mDisabledApnTypeBitMask = 0; 954 mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 955 mSubscriptionOverride = 0; 956 mUnmeteredOverride = false; 957 mDownlinkBandwidth = 14; 958 mUplinkBandwidth = 14; 959 } 960 961 /** 962 * Process setup data completion result from data service 963 * 964 * @param resultCode The result code returned by data service 965 * @param response Data call setup response from data service 966 * @param cp The original connection params used for data call setup 967 * @return Setup result 968 */ onSetupConnectionCompleted(@ataServiceCallback.ResultCode int resultCode, DataCallResponse response, ConnectionParams cp)969 private SetupResult onSetupConnectionCompleted(@DataServiceCallback.ResultCode int resultCode, 970 DataCallResponse response, 971 ConnectionParams cp) { 972 SetupResult result; 973 974 log("onSetupConnectionCompleted: resultCode=" + resultCode + ", response=" + response); 975 if (cp.mTag != mTag) { 976 if (DBG) { 977 log("onSetupConnectionCompleted stale cp.tag=" + cp.mTag + ", mtag=" + mTag); 978 } 979 result = SetupResult.ERROR_STALE; 980 } else if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) { 981 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE; 982 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE; 983 } else if (response.getCause() != 0) { 984 if (response.getCause() == DataFailCause.RADIO_NOT_AVAILABLE) { 985 result = SetupResult.ERROR_RADIO_NOT_AVAILABLE; 986 result.mFailCause = DataFailCause.RADIO_NOT_AVAILABLE; 987 } else { 988 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR; 989 result.mFailCause = DataFailCause.getFailCause(response.getCause()); 990 } 991 } else { 992 if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse"); 993 mCid = response.getId(); 994 995 mPcscfAddr = response.getPcscfAddresses().stream() 996 .map(InetAddress::getHostAddress).toArray(String[]::new); 997 998 result = updateLinkProperty(response).setupResult; 999 } 1000 1001 return result; 1002 } 1003 isDnsOk(String[] domainNameServers)1004 private boolean isDnsOk(String[] domainNameServers) { 1005 if (NULL_IP.equals(domainNameServers[0]) && NULL_IP.equals(domainNameServers[1]) 1006 && !mPhone.isDnsCheckDisabled()) { 1007 // Work around a race condition where QMI does not fill in DNS: 1008 // Deactivate PDP and let DataConnectionTracker retry. 1009 // Do not apply the race condition workaround for MMS APN 1010 // if Proxy is an IP-address. 1011 // Otherwise, the default APN will not be restored anymore. 1012 if (!isIpAddress(mApnSetting.getMmsProxyAddressAsString())) { 1013 log(String.format( 1014 "isDnsOk: return false apn.types=%d APN_TYPE_MMS=%s isIpAddress(%s)=%s", 1015 mApnSetting.getApnTypeBitmask(), PhoneConstants.APN_TYPE_MMS, 1016 mApnSetting.getMmsProxyAddressAsString(), 1017 isIpAddress(mApnSetting.getMmsProxyAddressAsString()))); 1018 return false; 1019 } 1020 } 1021 return true; 1022 } 1023 1024 /** 1025 * TCP buffer size config based on the ril technology. There are 6 parameters 1026 * read_min, read_default, read_max, write_min, write_default, write_max in the TCP buffer 1027 * config string and they are separated by a comma. The unit of these parameters is byte. 1028 */ 1029 private static final String TCP_BUFFER_SIZES_GPRS = "4092,8760,48000,4096,8760,48000"; 1030 private static final String TCP_BUFFER_SIZES_EDGE = "4093,26280,70800,4096,16384,70800"; 1031 private static final String TCP_BUFFER_SIZES_UMTS = "58254,349525,1048576,58254,349525,1048576"; 1032 private static final String TCP_BUFFER_SIZES_1XRTT = "16384,32768,131072,4096,16384,102400"; 1033 private static final String TCP_BUFFER_SIZES_EVDO = "4094,87380,262144,4096,16384,262144"; 1034 private static final String TCP_BUFFER_SIZES_EHRPD = "131072,262144,1048576,4096,16384,524288"; 1035 private static final String TCP_BUFFER_SIZES_HSDPA = "61167,367002,1101005,8738,52429,262114"; 1036 private static final String TCP_BUFFER_SIZES_HSPA = "40778,244668,734003,16777,100663,301990"; 1037 private static final String TCP_BUFFER_SIZES_LTE = 1038 "524288,1048576,2097152,262144,524288,1048576"; 1039 private static final String TCP_BUFFER_SIZES_HSPAP = 1040 "122334,734003,2202010,32040,192239,576717"; 1041 private static final String TCP_BUFFER_SIZES_NR = 1042 "2097152,6291456,16777216,512000,2097152,8388608"; 1043 private static final String TCP_BUFFER_SIZES_LTE_CA = 1044 "4096,6291456,12582912,4096,1048576,2097152"; 1045 updateTcpBufferSizes(int rilRat)1046 private void updateTcpBufferSizes(int rilRat) { 1047 String sizes = null; 1048 ServiceState ss = mPhone.getServiceState(); 1049 if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && ss.isUsingCarrierAggregation()) { 1050 rilRat = ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA; 1051 } 1052 String ratName = ServiceState.rilRadioTechnologyToString(rilRat).toLowerCase(Locale.ROOT); 1053 // ServiceState gives slightly different names for EVDO tech ("evdo-rev.0" for ex) 1054 // - patch it up: 1055 if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0 || 1056 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A || 1057 rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B) { 1058 ratName = RAT_NAME_EVDO; 1059 } 1060 1061 // NR 5G Non-Standalone use LTE cell as the primary cell, the ril technology is LTE in this 1062 // case. We use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1063 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN 1064 && ((rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE 1065 || rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA) && isNRConnected()) 1066 && mPhone.getServiceStateTracker().getNrContextIds().contains(mCid)) { 1067 ratName = RAT_NAME_5G; 1068 } 1069 1070 log("updateTcpBufferSizes: " + ratName); 1071 1072 // in the form: "ratname:rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max" 1073 String[] configOverride = mPhone.getContext().getResources().getStringArray( 1074 com.android.internal.R.array.config_mobile_tcp_buffers); 1075 for (int i = 0; i < configOverride.length; i++) { 1076 String[] split = configOverride[i].split(":"); 1077 if (ratName.equals(split[0]) && split.length == 2) { 1078 sizes = split[1]; 1079 break; 1080 } 1081 } 1082 1083 if (sizes == null) { 1084 // no override - use telephony defaults 1085 // doing it this way allows device or carrier to just override the types they 1086 // care about and inherit the defaults for the others. 1087 switch (rilRat) { 1088 case ServiceState.RIL_RADIO_TECHNOLOGY_GPRS: 1089 sizes = TCP_BUFFER_SIZES_GPRS; 1090 break; 1091 case ServiceState.RIL_RADIO_TECHNOLOGY_EDGE: 1092 sizes = TCP_BUFFER_SIZES_EDGE; 1093 break; 1094 case ServiceState.RIL_RADIO_TECHNOLOGY_UMTS: 1095 sizes = TCP_BUFFER_SIZES_UMTS; 1096 break; 1097 case ServiceState.RIL_RADIO_TECHNOLOGY_1xRTT: 1098 sizes = TCP_BUFFER_SIZES_1XRTT; 1099 break; 1100 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_0: 1101 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_A: 1102 case ServiceState.RIL_RADIO_TECHNOLOGY_EVDO_B: 1103 sizes = TCP_BUFFER_SIZES_EVDO; 1104 break; 1105 case ServiceState.RIL_RADIO_TECHNOLOGY_EHRPD: 1106 sizes = TCP_BUFFER_SIZES_EHRPD; 1107 break; 1108 case ServiceState.RIL_RADIO_TECHNOLOGY_HSDPA: 1109 sizes = TCP_BUFFER_SIZES_HSDPA; 1110 break; 1111 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPA: 1112 case ServiceState.RIL_RADIO_TECHNOLOGY_HSUPA: 1113 sizes = TCP_BUFFER_SIZES_HSPA; 1114 break; 1115 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE: 1116 // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1117 if (RAT_NAME_5G.equals(ratName)) { 1118 sizes = TCP_BUFFER_SIZES_NR; 1119 } else { 1120 sizes = TCP_BUFFER_SIZES_LTE; 1121 } 1122 break; 1123 case ServiceState.RIL_RADIO_TECHNOLOGY_LTE_CA: 1124 // Use NR 5G TCP buffer size when connected to NR 5G Non-Standalone network. 1125 if (RAT_NAME_5G.equals(ratName)) { 1126 sizes = TCP_BUFFER_SIZES_NR; 1127 } else { 1128 sizes = TCP_BUFFER_SIZES_LTE_CA; 1129 } 1130 break; 1131 case ServiceState.RIL_RADIO_TECHNOLOGY_HSPAP: 1132 sizes = TCP_BUFFER_SIZES_HSPAP; 1133 break; 1134 case ServiceState.RIL_RADIO_TECHNOLOGY_NR: 1135 sizes = TCP_BUFFER_SIZES_NR; 1136 break; 1137 default: 1138 // Leave empty - this will let ConnectivityService use the system default. 1139 break; 1140 } 1141 } 1142 mLinkProperties.setTcpBufferSizes(sizes); 1143 } 1144 updateLinkBandwidthsFromCarrierConfig(int rilRat)1145 private void updateLinkBandwidthsFromCarrierConfig(int rilRat) { 1146 String ratName = ServiceState.rilRadioTechnologyToString(rilRat); 1147 if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) { 1148 ratName = mPhone.getServiceState().getNrFrequencyRange() 1149 == ServiceState.FREQUENCY_RANGE_MMWAVE 1150 ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA; 1151 } 1152 1153 if (DBG) log("updateLinkBandwidthsFromCarrierConfig: " + ratName); 1154 1155 Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName); 1156 if (values == null) { 1157 values = new Pair<>(14, 14); 1158 } 1159 mDownlinkBandwidth = values.first; 1160 mUplinkBandwidth = values.second; 1161 } 1162 1163 updateLinkBandwidthsFromModem(LinkCapacityEstimate lce)1164 private void updateLinkBandwidthsFromModem(LinkCapacityEstimate lce) { 1165 if (DBG) log("updateLinkBandwidthsFromModem: lce=" + lce); 1166 boolean downlinkUpdated = false; 1167 boolean uplinkUpdated = false; 1168 // LCE status deprecated in IRadio 1.2, so only check for IRadio < 1.2 1169 if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2) 1170 || mPhone.getLceStatus() == RILConstants.LCE_ACTIVE) { 1171 if (lce.downlinkCapacityKbps != LinkCapacityEstimate.INVALID) { 1172 mDownlinkBandwidth = lce.downlinkCapacityKbps; 1173 downlinkUpdated = true; 1174 } 1175 if (lce.uplinkCapacityKbps != LinkCapacityEstimate.INVALID) { 1176 mUplinkBandwidth = lce.uplinkCapacityKbps; 1177 uplinkUpdated = true; 1178 } 1179 } 1180 if (!downlinkUpdated || !uplinkUpdated) { 1181 String ratName = ServiceState.rilRadioTechnologyToString(mRilRat); 1182 if (mRilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) { 1183 ratName = mPhone.getServiceState().getNrFrequencyRange() 1184 == ServiceState.FREQUENCY_RANGE_MMWAVE 1185 ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA; 1186 } 1187 Pair<Integer, Integer> values = mDct.getLinkBandwidthsFromCarrierConfig(ratName); 1188 if (values != null) { 1189 if (!downlinkUpdated) { 1190 mDownlinkBandwidth = values.first; 1191 } 1192 if (!uplinkUpdated) { 1193 mUplinkBandwidth = values.second; 1194 } 1195 } 1196 } 1197 if (mNetworkAgent != null) { 1198 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), DataConnection.this); 1199 } 1200 } 1201 isBandwidthSourceKey(String source)1202 private boolean isBandwidthSourceKey(String source) { 1203 return source.equals(mPhone.getContext().getResources().getString( 1204 com.android.internal.R.string.config_bandwidthEstimateSource)); 1205 } 1206 1207 /** 1208 * Indicates if this data connection was established for unmetered use only. Note that this 1209 * flag should be populated when data becomes active. And if it is set to true, it can be set to 1210 * false later when we are reevaluating the data connection. But if it is set to false, it 1211 * can never become true later because setting it to true will cause this data connection 1212 * losing some immutable network capabilities, which can cause issues in connectivity service. 1213 */ 1214 private boolean mUnmeteredUseOnly = false; 1215 1216 /** 1217 * Indicates if when this connection was established we had a restricted/privileged 1218 * NetworkRequest and needed it to overcome data-enabled limitations. 1219 * 1220 * This flag overrides the APN-based restriction capability, restricting the network 1221 * based on both having a NetworkRequest with restricted AND needing a restricted 1222 * bit to overcome user-disabled status. This allows us to handle the common case 1223 * of having both restricted requests and unrestricted requests for the same apn: 1224 * if conditions require a restricted network to overcome user-disabled then it must 1225 * be restricted, otherwise it is unrestricted (or restricted based on APN type). 1226 * 1227 * This supports a privileged app bringing up a network without general apps having access 1228 * to it when the network is otherwise unavailable (hipri). The first use case is 1229 * pre-paid SIM reprovisioning over internet, where the carrier insists on no traffic 1230 * other than from the privileged carrier-app. 1231 * 1232 * Note that the data connection cannot go from unrestricted to restricted because the 1233 * connectivity service does not support dynamically closing TCP connections at this point. 1234 */ 1235 private boolean mRestrictedNetworkOverride = false; 1236 1237 /** 1238 * Check if this data connection should be restricted. We should call this when data connection 1239 * becomes active, or when we want to re-evaluate the conditions to decide if we need to 1240 * unstrict the data connection. 1241 * 1242 * @return True if this data connection needs to be restricted. 1243 */ 1244 shouldRestrictNetwork()1245 private boolean shouldRestrictNetwork() { 1246 // first, check if there is any network request that containing restricted capability 1247 // (i.e. Do not have NET_CAPABILITY_NOT_RESTRICTED in the request) 1248 boolean isAnyRestrictedRequest = false; 1249 for (ApnContext apnContext : mApnContexts.keySet()) { 1250 if (apnContext.hasRestrictedRequests(true /* exclude DUN */)) { 1251 isAnyRestrictedRequest = true; 1252 break; 1253 } 1254 } 1255 1256 // If all of the network requests are non-restricted, then we don't need to restrict 1257 // the network. 1258 if (!isAnyRestrictedRequest) { 1259 return false; 1260 } 1261 1262 // If the network is unmetered, then we don't need to restrict the network because users 1263 // won't be charged anyway. 1264 if (!ApnSettingUtils.isMetered(mApnSetting, mPhone)) { 1265 return false; 1266 } 1267 1268 // If the data is disabled, then we need to restrict the network so only privileged apps can 1269 // use the restricted network while data is disabled. 1270 if (!mPhone.getDataEnabledSettings().isDataEnabled()) { 1271 return true; 1272 } 1273 1274 // If the device is roaming, and the user does not turn on data roaming, then we need to 1275 // restrict the network so only privileged apps can use it. 1276 if (!mDct.getDataRoamingEnabled() && mPhone.getServiceState().getDataRoaming()) { 1277 return true; 1278 } 1279 1280 // Otherwise we should not restrict the network so anyone who requests can use it. 1281 return false; 1282 } 1283 1284 /** 1285 * @return True if this data connection should only be used for unmetered purposes. 1286 */ isUnmeteredUseOnly()1287 private boolean isUnmeteredUseOnly() { 1288 // If this data connection is on IWLAN, then it's unmetered and can be used by everyone. 1289 // Should not be for unmetered used only. 1290 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) { 1291 return false; 1292 } 1293 1294 // If data is enabled, this data connection can't be for unmetered used only because 1295 // everyone should be able to use it if: 1296 // 1. Device is not roaming, or 1297 // 2. Device is roaming and data roaming is turned on 1298 if (mPhone.getDataEnabledSettings().isDataEnabled()) { 1299 if (!mPhone.getServiceState().getDataRoaming() || mDct.getDataRoamingEnabled()) { 1300 return false; 1301 } 1302 } 1303 1304 // The data connection can only be unmetered used only if all attached APN contexts 1305 // attached to this data connection are unmetered. 1306 for (ApnContext apnContext : mApnContexts.keySet()) { 1307 if (ApnSettingUtils.isMeteredApnType(apnContext.getApnTypeBitmask(), mPhone)) { 1308 return false; 1309 } 1310 } 1311 return true; 1312 } 1313 1314 /** 1315 * Get the network capabilities for this data connection. 1316 * 1317 * Note that this method reads fields from mNetworkInfo, so its output is only as fresh 1318 * as mNetworkInfo. Call updateNetworkInfoSuspendState before calling this. 1319 * 1320 * @return the {@link NetworkCapabilities} of this data connection. 1321 */ getNetworkCapabilities()1322 public NetworkCapabilities getNetworkCapabilities() { 1323 NetworkCapabilities result = new NetworkCapabilities(); 1324 result.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); 1325 1326 if (mApnSetting != null) { 1327 final String[] types = ApnSetting.getApnTypesStringFromBitmask( 1328 mApnSetting.getApnTypeBitmask() & ~mDisabledApnTypeBitMask).split(","); 1329 for (String type : types) { 1330 if (!mRestrictedNetworkOverride && mUnmeteredUseOnly 1331 && ApnSettingUtils.isMeteredApnType( 1332 ApnSetting.getApnTypesBitmaskFromString(type), mPhone)) { 1333 log("Dropped the metered " + type + " for the unmetered data call."); 1334 continue; 1335 } 1336 switch (type) { 1337 case PhoneConstants.APN_TYPE_ALL: { 1338 result.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1339 result.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1340 result.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL); 1341 result.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA); 1342 result.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); 1343 result.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS); 1344 result.addCapability(NetworkCapabilities.NET_CAPABILITY_IA); 1345 result.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1346 break; 1347 } 1348 case PhoneConstants.APN_TYPE_DEFAULT: { 1349 result.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1350 break; 1351 } 1352 case PhoneConstants.APN_TYPE_MMS: { 1353 result.addCapability(NetworkCapabilities.NET_CAPABILITY_MMS); 1354 break; 1355 } 1356 case PhoneConstants.APN_TYPE_SUPL: { 1357 result.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL); 1358 break; 1359 } 1360 case PhoneConstants.APN_TYPE_DUN: { 1361 result.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1362 break; 1363 } 1364 case PhoneConstants.APN_TYPE_FOTA: { 1365 result.addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA); 1366 break; 1367 } 1368 case PhoneConstants.APN_TYPE_IMS: { 1369 result.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS); 1370 break; 1371 } 1372 case PhoneConstants.APN_TYPE_CBS: { 1373 result.addCapability(NetworkCapabilities.NET_CAPABILITY_CBS); 1374 break; 1375 } 1376 case PhoneConstants.APN_TYPE_IA: { 1377 result.addCapability(NetworkCapabilities.NET_CAPABILITY_IA); 1378 break; 1379 } 1380 case PhoneConstants.APN_TYPE_EMERGENCY: { 1381 result.addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS); 1382 break; 1383 } 1384 case PhoneConstants.APN_TYPE_MCX: { 1385 result.addCapability(NetworkCapabilities.NET_CAPABILITY_MCX); 1386 break; 1387 } 1388 case PhoneConstants.APN_TYPE_XCAP: { 1389 result.addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP); 1390 break; 1391 } 1392 default: 1393 } 1394 } 1395 1396 // DataConnection has the immutable NOT_METERED capability only if all APNs in the 1397 // APN setting are unmetered according to carrier config METERED_APN_TYPES_STRINGS. 1398 // All other cases should use the dynamic TEMPORARILY_NOT_METERED capability instead. 1399 result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, 1400 !ApnSettingUtils.isMetered(mApnSetting, mPhone)); 1401 1402 if (result.deduceRestrictedCapability()) { 1403 result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1404 } 1405 } 1406 1407 if (mRestrictedNetworkOverride) { 1408 result.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED); 1409 // don't use dun on restriction-overriden networks. 1410 result.removeCapability(NetworkCapabilities.NET_CAPABILITY_DUN); 1411 } 1412 1413 result.setLinkDownstreamBandwidthKbps(mDownlinkBandwidth); 1414 result.setLinkUpstreamBandwidthKbps(mUplinkBandwidth); 1415 1416 result.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder() 1417 .setSubscriptionId(mSubId).build()); 1418 1419 result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, 1420 !mPhone.getServiceState().getDataRoaming()); 1421 1422 if ((mSubscriptionOverride & SUBSCRIPTION_OVERRIDE_CONGESTED) == 0) { 1423 result.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED); 1424 } 1425 1426 // Mark TEMPORARILY_NOT_METERED in the following cases: 1427 // 1. The non-restricted data is intended for unmetered use only. 1428 // 2. DcTracker set an unmetered override due to network/location (eg. 5G). 1429 // 3. SubscriptionManager set an unmetered override as requested by policy. 1430 if ((mUnmeteredUseOnly && !mRestrictedNetworkOverride) || mUnmeteredOverride 1431 || (mSubscriptionOverride & SUBSCRIPTION_OVERRIDE_UNMETERED) != 0) { 1432 result.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED); 1433 } else { 1434 result.removeCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED); 1435 } 1436 1437 final boolean suspended = 1438 mNetworkInfo.getDetailedState() == NetworkInfo.DetailedState.SUSPENDED; 1439 result.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED, !suspended); 1440 1441 result.setAdministratorUids(mAdministratorUids); 1442 1443 return result; 1444 } 1445 1446 /** @return {@code true} if validation is required, {@code false} otherwise. */ isValidationRequired()1447 public boolean isValidationRequired() { 1448 final NetworkCapabilities nc = getNetworkCapabilities(); 1449 return nc != null 1450 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 1451 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED) 1452 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED) 1453 && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN); 1454 } 1455 1456 /** 1457 * @return {@code True} if 464xlat should be skipped. 1458 */ 1459 @VisibleForTesting shouldSkip464Xlat()1460 public boolean shouldSkip464Xlat() { 1461 switch (mApnSetting.getSkip464Xlat()) { 1462 case Telephony.Carriers.SKIP_464XLAT_ENABLE: 1463 return true; 1464 case Telephony.Carriers.SKIP_464XLAT_DISABLE: 1465 return false; 1466 case Telephony.Carriers.SKIP_464XLAT_DEFAULT: 1467 default: 1468 break; 1469 } 1470 1471 // As default, return true if ims and no internet 1472 final NetworkCapabilities nc = getNetworkCapabilities(); 1473 return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS) 1474 && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); 1475 } 1476 1477 /** 1478 * @return {@code} true iff. {@code address} is a literal IPv4 or IPv6 address. 1479 */ 1480 @VisibleForTesting isIpAddress(String address)1481 public static boolean isIpAddress(String address) { 1482 if (address == null) return false; 1483 1484 // Accept IPv6 addresses (only) in square brackets for compatibility. 1485 if (address.startsWith("[") && address.endsWith("]") && address.indexOf(':') != -1) { 1486 address = address.substring(1, address.length() - 1); 1487 } 1488 return InetAddresses.isNumericAddress(address); 1489 } 1490 setLinkProperties(DataCallResponse response, LinkProperties linkProperties)1491 private SetupResult setLinkProperties(DataCallResponse response, 1492 LinkProperties linkProperties) { 1493 // Check if system property dns usable 1494 String propertyPrefix = "net." + response.getInterfaceName() + "."; 1495 String dnsServers[] = new String[2]; 1496 dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1"); 1497 dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2"); 1498 boolean okToUseSystemPropertyDns = isDnsOk(dnsServers); 1499 1500 SetupResult result; 1501 1502 // Start with clean network properties and if we have 1503 // a failure we'll clear again at the bottom of this code. 1504 linkProperties.clear(); 1505 1506 if (response.getCause() == DataFailCause.NONE) { 1507 try { 1508 // set interface name 1509 linkProperties.setInterfaceName(response.getInterfaceName()); 1510 1511 // set link addresses 1512 if (response.getAddresses().size() > 0) { 1513 for (LinkAddress la : response.getAddresses()) { 1514 if (!la.getAddress().isAnyLocalAddress()) { 1515 if (DBG) { 1516 log("addr/pl=" + la.getAddress() + "/" 1517 + la.getPrefixLength()); 1518 } 1519 linkProperties.addLinkAddress(la); 1520 } 1521 } 1522 } else { 1523 throw new UnknownHostException("no address for ifname=" 1524 + response.getInterfaceName()); 1525 } 1526 1527 // set dns servers 1528 if (response.getDnsAddresses().size() > 0) { 1529 for (InetAddress dns : response.getDnsAddresses()) { 1530 if (!dns.isAnyLocalAddress()) { 1531 linkProperties.addDnsServer(dns); 1532 } 1533 } 1534 } else if (okToUseSystemPropertyDns) { 1535 for (String dnsAddr : dnsServers) { 1536 dnsAddr = dnsAddr.trim(); 1537 if (dnsAddr.isEmpty()) continue; 1538 InetAddress ia; 1539 try { 1540 ia = InetAddresses.parseNumericAddress(dnsAddr); 1541 } catch (IllegalArgumentException e) { 1542 throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr); 1543 } 1544 if (!ia.isAnyLocalAddress()) { 1545 linkProperties.addDnsServer(ia); 1546 } 1547 } 1548 } else { 1549 throw new UnknownHostException("Empty dns response and no system default dns"); 1550 } 1551 1552 // set pcscf 1553 if (response.getPcscfAddresses().size() > 0) { 1554 for (InetAddress pcscf : response.getPcscfAddresses()) { 1555 linkProperties.addPcscfServer(pcscf); 1556 } 1557 } 1558 1559 for (InetAddress gateway : response.getGatewayAddresses()) { 1560 int mtu = gateway instanceof java.net.Inet6Address ? response.getMtuV6() 1561 : response.getMtuV4(); 1562 // Allow 0.0.0.0 or :: as a gateway; 1563 // this indicates a point-to-point interface. 1564 linkProperties.addRoute(new RouteInfo(null, gateway, null, 1565 RouteInfo.RTN_UNICAST, mtu)); 1566 } 1567 1568 // set interface MTU 1569 // this may clobber the setting read from the APN db, but that's ok 1570 // TODO: remove once LinkProperties#setMtu is deprecated 1571 linkProperties.setMtu(response.getMtu()); 1572 1573 result = SetupResult.SUCCESS; 1574 } catch (UnknownHostException e) { 1575 log("setLinkProperties: UnknownHostException " + e); 1576 result = SetupResult.ERROR_INVALID_ARG; 1577 } 1578 } else { 1579 result = SetupResult.ERROR_DATA_SERVICE_SPECIFIC_ERROR; 1580 } 1581 1582 // An error occurred so clear properties 1583 if (result != SetupResult.SUCCESS) { 1584 if (DBG) { 1585 log("setLinkProperties: error clearing LinkProperties status=" 1586 + response.getCause() + " result=" + result); 1587 } 1588 linkProperties.clear(); 1589 } 1590 1591 return result; 1592 } 1593 1594 /** 1595 * Initialize connection, this will fail if the 1596 * apnSettings are not compatible. 1597 * 1598 * @param cp the Connection parameters 1599 * @return true if initialization was successful. 1600 */ initConnection(ConnectionParams cp)1601 private boolean initConnection(ConnectionParams cp) { 1602 ApnContext apnContext = cp.mApnContext; 1603 if (mApnSetting == null) { 1604 // Only change apn setting if it isn't set, it will 1605 // only NOT be set only if we're in DcInactiveState. 1606 mApnSetting = apnContext.getApnSetting(); 1607 } 1608 if (mApnSetting == null || !mApnSetting.canHandleType(apnContext.getApnTypeBitmask())) { 1609 if (DBG) { 1610 log("initConnection: incompatible apnSetting in ConnectionParams cp=" + cp 1611 + " dc=" + DataConnection.this); 1612 } 1613 return false; 1614 } 1615 mTag += 1; 1616 mConnectionParams = cp; 1617 mConnectionParams.mTag = mTag; 1618 1619 // always update the ConnectionParams with the latest or the 1620 // connectionGeneration gets stale 1621 mApnContexts.put(apnContext, cp); 1622 1623 if (DBG) { 1624 log("initConnection: " 1625 + " RefCount=" + mApnContexts.size() 1626 + " mApnList=" + mApnContexts 1627 + " mConnectionParams=" + mConnectionParams); 1628 } 1629 return true; 1630 } 1631 1632 /** 1633 * The parent state for all other states. 1634 */ 1635 private class DcDefaultState extends State { 1636 @Override enter()1637 public void enter() { 1638 if (DBG) log("DcDefaultState: enter"); 1639 1640 // Register for DRS or RAT change 1641 mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged( 1642 mTransportType, getHandler(), 1643 DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED, null); 1644 1645 mPhone.getServiceStateTracker().registerForDataRoamingOn(getHandler(), 1646 DataConnection.EVENT_DATA_CONNECTION_ROAM_ON, null); 1647 mPhone.getServiceStateTracker().registerForDataRoamingOff(getHandler(), 1648 DataConnection.EVENT_DATA_CONNECTION_ROAM_OFF, null, true); 1649 mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(), 1650 DataConnection.EVENT_NR_STATE_CHANGED, null); 1651 mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(), 1652 DataConnection.EVENT_NR_FREQUENCY_CHANGED, null); 1653 1654 // Add ourselves to the list of data connections 1655 mDcController.addDc(DataConnection.this); 1656 } 1657 @Override exit()1658 public void exit() { 1659 if (DBG) log("DcDefaultState: exit"); 1660 1661 // Unregister for DRS or RAT change. 1662 mPhone.getServiceStateTracker().unregisterForDataRegStateOrRatChanged( 1663 mTransportType, getHandler()); 1664 1665 mPhone.getServiceStateTracker().unregisterForDataRoamingOn(getHandler()); 1666 mPhone.getServiceStateTracker().unregisterForDataRoamingOff(getHandler()); 1667 mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler()); 1668 mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler()); 1669 1670 // Remove ourselves from the DC lists 1671 mDcController.removeDc(DataConnection.this); 1672 1673 if (mAc != null) { 1674 mAc.disconnected(); 1675 mAc = null; 1676 } 1677 mApnContexts.clear(); 1678 mReconnectIntent = null; 1679 mDct = null; 1680 mApnSetting = null; 1681 mPhone = null; 1682 mDataServiceManager = null; 1683 mLinkProperties = null; 1684 mLastFailCause = DataFailCause.NONE; 1685 mUserData = null; 1686 mDcController = null; 1687 mDcTesterFailBringUpAll = null; 1688 } 1689 1690 @Override processMessage(Message msg)1691 public boolean processMessage(Message msg) { 1692 boolean retVal = HANDLED; 1693 1694 if (VDBG) { 1695 log("DcDefault msg=" + getWhatToString(msg.what) 1696 + " RefCount=" + mApnContexts.size()); 1697 } 1698 switch (msg.what) { 1699 case EVENT_RESET: 1700 if (VDBG) log("DcDefaultState: msg.what=REQ_RESET"); 1701 transitionTo(mInactiveState); 1702 break; 1703 case EVENT_CONNECT: 1704 if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected"); 1705 ConnectionParams cp = (ConnectionParams) msg.obj; 1706 notifyConnectCompleted(cp, DataFailCause.UNKNOWN, false); 1707 break; 1708 1709 case EVENT_DISCONNECT: 1710 case EVENT_DISCONNECT_ALL: 1711 case EVENT_REEVALUATE_RESTRICTED_STATE: 1712 if (DBG) { 1713 log("DcDefaultState deferring msg.what=" + getWhatToString(msg.what) 1714 + " RefCount=" + mApnContexts.size()); 1715 } 1716 deferMessage(msg); 1717 break; 1718 case EVENT_TEAR_DOWN_NOW: 1719 if (DBG) log("DcDefaultState EVENT_TEAR_DOWN_NOW"); 1720 mDataServiceManager.deactivateDataCall(mCid, DataService.REQUEST_REASON_NORMAL, 1721 null); 1722 break; 1723 case EVENT_LOST_CONNECTION: 1724 if (DBG) { 1725 String s = "DcDefaultState ignore EVENT_LOST_CONNECTION" 1726 + " tag=" + msg.arg1 + ":mTag=" + mTag; 1727 logAndAddLogRec(s); 1728 } 1729 break; 1730 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: 1731 AsyncResult ar = (AsyncResult)msg.obj; 1732 Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>)ar.result; 1733 mDataRegState = drsRatPair.first; 1734 updateTcpBufferSizes(drsRatPair.second); 1735 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 1736 updateLinkBandwidthsFromCarrierConfig(drsRatPair.second); 1737 } 1738 mRilRat = drsRatPair.second; 1739 if (DBG) { 1740 log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED" 1741 + " drs=" + mDataRegState 1742 + " mRilRat=" + mRilRat); 1743 } 1744 updateNetworkInfo(); 1745 break; 1746 default: 1747 if (DBG) { 1748 log("DcDefaultState: ignore msg.what=" + getWhatToString(msg.what)); 1749 } 1750 break; 1751 } 1752 1753 return retVal; 1754 } 1755 } 1756 updateNetworkInfo()1757 private void updateNetworkInfo() { 1758 final ServiceState state = mPhone.getServiceState(); 1759 1760 NetworkRegistrationInfo nri = state.getNetworkRegistrationInfo( 1761 NetworkRegistrationInfo.DOMAIN_PS, mTransportType); 1762 int subtype = TelephonyManager.NETWORK_TYPE_UNKNOWN; 1763 if (nri != null) { 1764 subtype = nri.getAccessNetworkTechnology(); 1765 } 1766 1767 mNetworkInfo.setSubtype(subtype, TelephonyManager.getNetworkTypeName(subtype)); 1768 } 1769 updateNetworkInfoSuspendState()1770 private void updateNetworkInfoSuspendState() { 1771 // this is only called when we are either connected or suspended. Decide which. 1772 if (mNetworkAgent == null) { 1773 Rlog.e(getName(), "Setting suspend state without a NetworkAgent"); 1774 } 1775 1776 // if we are not in-service change to SUSPENDED 1777 final ServiceStateTracker sst = mPhone.getServiceStateTracker(); 1778 if (sst.getCurrentDataConnectionState() != ServiceState.STATE_IN_SERVICE) { 1779 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, null, 1780 mNetworkInfo.getExtraInfo()); 1781 } else { 1782 // check for voice call and concurrency issues 1783 if (sst.isConcurrentVoiceAndDataAllowed() == false) { 1784 final CallTracker ct = mPhone.getCallTracker(); 1785 if (ct.getState() != PhoneConstants.State.IDLE) { 1786 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.SUSPENDED, null, 1787 mNetworkInfo.getExtraInfo()); 1788 return; 1789 } 1790 } 1791 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, 1792 mNetworkInfo.getExtraInfo()); 1793 } 1794 } 1795 1796 private DcDefaultState mDefaultState = new DcDefaultState(); 1797 1798 /** 1799 * The state machine is inactive and expects a EVENT_CONNECT. 1800 */ 1801 private class DcInactiveState extends State { 1802 // Inform all contexts we've failed connecting setEnterNotificationParams(ConnectionParams cp, @DataFailureCause int cause)1803 public void setEnterNotificationParams(ConnectionParams cp, 1804 @DataFailureCause int cause) { 1805 if (VDBG) log("DcInactiveState: setEnterNotificationParams cp,cause"); 1806 mConnectionParams = cp; 1807 mDisconnectParams = null; 1808 mDcFailCause = cause; 1809 } 1810 1811 // Inform all contexts we've failed disconnected setEnterNotificationParams(DisconnectParams dp)1812 public void setEnterNotificationParams(DisconnectParams dp) { 1813 if (VDBG) log("DcInactiveState: setEnterNotificationParams dp"); 1814 mConnectionParams = null; 1815 mDisconnectParams = dp; 1816 mDcFailCause = DataFailCause.NONE; 1817 } 1818 1819 // Inform all contexts of the failure cause setEnterNotificationParams(@ataFailureCause int cause)1820 public void setEnterNotificationParams(@DataFailureCause int cause) { 1821 mConnectionParams = null; 1822 mDisconnectParams = null; 1823 mDcFailCause = cause; 1824 } 1825 1826 @Override enter()1827 public void enter() { 1828 mTag += 1; 1829 if (DBG) log("DcInactiveState: enter() mTag=" + mTag); 1830 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 1831 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__INACTIVE, 1832 mPhone.getPhoneId(), mId, 1833 mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L, 1834 mApnSetting != null 1835 ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false); 1836 if (mHandoverState == HANDOVER_STATE_BEING_TRANSFERRED) { 1837 setHandoverState(HANDOVER_STATE_COMPLETED); 1838 } 1839 1840 // Check for dangling agent. Ideally the handover source agent should be null if 1841 // handover process is smooth. When it's not null, that means handover failed. The 1842 // agent was not successfully transferred to the new data connection. We should 1843 // gracefully notify connectivity service the network was disconnected. 1844 if (mHandoverSourceNetworkAgent != null) { 1845 DataConnection sourceDc = mHandoverSourceNetworkAgent.getDataConnection(); 1846 if (sourceDc != null) { 1847 // If the source data connection still owns this agent, then just reset the 1848 // handover state back to idle because handover is already failed. 1849 mHandoverLocalLog.log( 1850 "Handover failed. Reset the source dc " + sourceDc.getName() 1851 + " state to idle"); 1852 sourceDc.setHandoverState(HANDOVER_STATE_IDLE); 1853 } else { 1854 // The agent is now a dangling agent. No data connection owns this agent. 1855 // Gracefully notify connectivity service disconnected. 1856 mHandoverLocalLog.log( 1857 "Handover failed and dangling agent found."); 1858 mHandoverSourceNetworkAgent.acquireOwnership( 1859 DataConnection.this, mTransportType); 1860 NetworkInfo networkInfo = mHandoverSourceNetworkAgent.getNetworkInfo(); 1861 if (networkInfo != null) { 1862 log("Cleared dangling network agent. " + mHandoverSourceNetworkAgent); 1863 mHandoverSourceNetworkAgent.unregister(DataConnection.this); 1864 } else { 1865 String str = "Failed to get network info."; 1866 loge(str); 1867 mHandoverLocalLog.log(str); 1868 } 1869 mHandoverSourceNetworkAgent.releaseOwnership(DataConnection.this); 1870 } 1871 mHandoverSourceNetworkAgent = null; 1872 } 1873 1874 if (mConnectionParams != null) { 1875 if (DBG) { 1876 log("DcInactiveState: enter notifyConnectCompleted +ALL failCause=" 1877 + mDcFailCause); 1878 } 1879 notifyConnectCompleted(mConnectionParams, mDcFailCause, true); 1880 } 1881 if (mDisconnectParams != null) { 1882 if (DBG) { 1883 log("DcInactiveState: enter notifyDisconnectCompleted +ALL failCause=" 1884 + mDcFailCause); 1885 } 1886 notifyDisconnectCompleted(mDisconnectParams, true); 1887 } 1888 if (mDisconnectParams == null && mConnectionParams == null 1889 && mDcFailCause != DataFailCause.NONE) { 1890 if (DBG) { 1891 log("DcInactiveState: enter notifyAllDisconnectCompleted failCause=" 1892 + mDcFailCause); 1893 } 1894 notifyAllWithEvent(null, DctConstants.EVENT_DISCONNECT_DONE, 1895 DataFailCause.toString(mDcFailCause)); 1896 } 1897 1898 // Remove ourselves from cid mapping, before clearSettings 1899 mDcController.removeActiveDcByCid(DataConnection.this); 1900 1901 clearSettings(); 1902 } 1903 1904 @Override exit()1905 public void exit() { 1906 } 1907 1908 @Override processMessage(Message msg)1909 public boolean processMessage(Message msg) { 1910 switch (msg.what) { 1911 case EVENT_RESET: 1912 case EVENT_REEVALUATE_RESTRICTED_STATE: 1913 if (DBG) { 1914 log("DcInactiveState: msg.what=" + getWhatToString(msg.what) 1915 + ", ignore we're already done"); 1916 } 1917 return HANDLED; 1918 case EVENT_CONNECT: 1919 if (DBG) log("DcInactiveState: mag.what=EVENT_CONNECT"); 1920 ConnectionParams cp = (ConnectionParams) msg.obj; 1921 1922 if (!initConnection(cp)) { 1923 log("DcInactiveState: msg.what=EVENT_CONNECT initConnection failed"); 1924 notifyConnectCompleted(cp, DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER, 1925 false); 1926 transitionTo(mInactiveState); 1927 return HANDLED; 1928 } 1929 1930 int cause = connect(cp); 1931 if (cause != DataFailCause.NONE) { 1932 log("DcInactiveState: msg.what=EVENT_CONNECT connect failed"); 1933 notifyConnectCompleted(cp, cause, false); 1934 transitionTo(mInactiveState); 1935 return HANDLED; 1936 } 1937 1938 if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { 1939 mSubId = cp.mSubId; 1940 } 1941 1942 transitionTo(mActivatingState); 1943 return HANDLED; 1944 case EVENT_DISCONNECT: 1945 if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT"); 1946 notifyDisconnectCompleted((DisconnectParams)msg.obj, false); 1947 return HANDLED; 1948 case EVENT_DISCONNECT_ALL: 1949 if (DBG) log("DcInactiveState: msg.what=EVENT_DISCONNECT_ALL"); 1950 notifyDisconnectCompleted((DisconnectParams)msg.obj, false); 1951 return HANDLED; 1952 default: 1953 if (VDBG) { 1954 log("DcInactiveState not handled msg.what=" + getWhatToString(msg.what)); 1955 } 1956 return NOT_HANDLED; 1957 } 1958 } 1959 } 1960 private DcInactiveState mInactiveState = new DcInactiveState(); 1961 1962 /** 1963 * The state machine is activating a connection. 1964 */ 1965 private class DcActivatingState extends State { 1966 @Override enter()1967 public void enter() { 1968 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 1969 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVATING, 1970 mPhone.getPhoneId(), mId, 1971 mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L, 1972 mApnSetting != null 1973 ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false); 1974 setHandoverState(HANDOVER_STATE_IDLE); 1975 // restricted evaluation depends on network requests from apnContext. The evaluation 1976 // should happen once entering connecting state rather than active state because it's 1977 // possible that restricted network request can be released during the connecting window 1978 // and if we wait for connection established, then we might mistakenly 1979 // consider it as un-restricted. ConnectivityService then will immediately 1980 // tear down the connection through networkAgent unwanted callback if all requests for 1981 // this connection are going away. 1982 mRestrictedNetworkOverride = shouldRestrictNetwork(); 1983 1984 mPhone.getCarrierPrivilegesTracker() 1985 .registerCarrierPrivilegesListener( 1986 getHandler(), EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null); 1987 } 1988 @Override processMessage(Message msg)1989 public boolean processMessage(Message msg) { 1990 boolean retVal; 1991 AsyncResult ar; 1992 ConnectionParams cp; 1993 1994 if (DBG) log("DcActivatingState: msg=" + msgToString(msg)); 1995 switch (msg.what) { 1996 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: 1997 case EVENT_CONNECT: 1998 // Activating can't process until we're done. 1999 deferMessage(msg); 2000 retVal = HANDLED; 2001 break; 2002 2003 case EVENT_SETUP_DATA_CONNECTION_DONE: 2004 cp = (ConnectionParams) msg.obj; 2005 2006 DataCallResponse dataCallResponse = 2007 msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE); 2008 SetupResult result = onSetupConnectionCompleted(msg.arg1, dataCallResponse, cp); 2009 if (result != SetupResult.ERROR_STALE) { 2010 if (mConnectionParams != cp) { 2011 loge("DcActivatingState: WEIRD mConnectionsParams:"+ mConnectionParams 2012 + " != cp:" + cp); 2013 } 2014 } 2015 if (DBG) { 2016 log("DcActivatingState onSetupConnectionCompleted result=" + result 2017 + " dc=" + DataConnection.this); 2018 } 2019 if (cp.mApnContext != null) { 2020 cp.mApnContext.requestLog("onSetupConnectionCompleted result=" + result); 2021 } 2022 switch (result) { 2023 case SUCCESS: 2024 // All is well 2025 mDcFailCause = DataFailCause.NONE; 2026 transitionTo(mActiveState); 2027 break; 2028 case ERROR_RADIO_NOT_AVAILABLE: 2029 // Vendor ril rejected the command and didn't connect. 2030 // Transition to inactive but send notifications after 2031 // we've entered the mInactive state. 2032 mInactiveState.setEnterNotificationParams(cp, result.mFailCause); 2033 transitionTo(mInactiveState); 2034 break; 2035 case ERROR_INVALID_ARG: 2036 // The addresses given from the RIL are bad 2037 tearDownData(cp); 2038 transitionTo(mDisconnectingErrorCreatingConnection); 2039 break; 2040 case ERROR_DATA_SERVICE_SPECIFIC_ERROR: 2041 2042 // Retrieve the suggested retry delay from the modem and save it. 2043 // If the modem want us to retry the current APN again, it will 2044 // suggest a positive delay value (in milliseconds). Otherwise we'll get 2045 // NO_SUGGESTED_RETRY_DELAY here. 2046 2047 long delay = getSuggestedRetryDelay(dataCallResponse); 2048 cp.mApnContext.setModemSuggestedDelay(delay); 2049 2050 String str = "DcActivatingState: ERROR_DATA_SERVICE_SPECIFIC_ERROR " 2051 + " delay=" + delay 2052 + " result=" + result 2053 + " result.isRadioRestartFailure=" 2054 + DataFailCause.isRadioRestartFailure(mPhone.getContext(), 2055 result.mFailCause, mPhone.getSubId()) 2056 + " isPermanentFailure=" + 2057 mDct.isPermanentFailure(result.mFailCause); 2058 if (DBG) log(str); 2059 if (cp.mApnContext != null) cp.mApnContext.requestLog(str); 2060 2061 // Save the cause. DcTracker.onDataSetupComplete will check this 2062 // failure cause and determine if we need to retry this APN later 2063 // or not. 2064 mInactiveState.setEnterNotificationParams(cp, result.mFailCause); 2065 transitionTo(mInactiveState); 2066 break; 2067 case ERROR_STALE: 2068 loge("DcActivatingState: stale EVENT_SETUP_DATA_CONNECTION_DONE" 2069 + " tag:" + cp.mTag + " != mTag:" + mTag); 2070 break; 2071 default: 2072 throw new RuntimeException("Unknown SetupResult, should not happen"); 2073 } 2074 retVal = HANDLED; 2075 break; 2076 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: 2077 AsyncResult asyncResult = (AsyncResult) msg.obj; 2078 int[] administratorUids = (int[]) asyncResult.result; 2079 mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); 2080 retVal = HANDLED; 2081 break; 2082 default: 2083 if (VDBG) { 2084 log("DcActivatingState not handled msg.what=" + 2085 getWhatToString(msg.what) + " RefCount=" + mApnContexts.size()); 2086 } 2087 retVal = NOT_HANDLED; 2088 break; 2089 } 2090 return retVal; 2091 } 2092 } 2093 private DcActivatingState mActivatingState = new DcActivatingState(); 2094 2095 /** 2096 * The state machine is connected, expecting an EVENT_DISCONNECT. 2097 */ 2098 private class DcActiveState extends State { 2099 enter()2100 @Override public void enter() { 2101 if (DBG) log("DcActiveState: enter dc=" + DataConnection.this); 2102 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2103 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__ACTIVE, 2104 mPhone.getPhoneId(), mId, 2105 mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L, 2106 mApnSetting != null 2107 ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false); 2108 2109 updateNetworkInfo(); 2110 2111 // If we were retrying there maybe more than one, otherwise they'll only be one. 2112 notifyAllWithEvent(null, DctConstants.EVENT_DATA_SETUP_COMPLETE, 2113 Phone.REASON_CONNECTED); 2114 2115 mPhone.getCallTracker().registerForVoiceCallStarted(getHandler(), 2116 DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED, null); 2117 mPhone.getCallTracker().registerForVoiceCallEnded(getHandler(), 2118 DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED, null); 2119 2120 // If the EVENT_CONNECT set the current max retry restore it here 2121 // if it didn't then this is effectively a NOP. 2122 mDcController.addActiveDcByCid(DataConnection.this); 2123 2124 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, 2125 mNetworkInfo.getReason(), null); 2126 mNetworkInfo.setExtraInfo(mApnSetting.getApnName()); 2127 updateTcpBufferSizes(mRilRat); 2128 updateLinkBandwidthsFromCarrierConfig(mRilRat); 2129 2130 final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder(); 2131 configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE); 2132 configBuilder.setLegacyTypeName(NETWORK_TYPE); 2133 configBuilder.setLegacyExtraInfo(mApnSetting.getApnName()); 2134 final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent(); 2135 if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager 2136 .ACTION_CARRIER_SIGNAL_REDIRECTED)) { 2137 // carrierSignal Receivers will place the carrier-specific provisioning notification 2138 configBuilder.disableProvisioningNotification(); 2139 } 2140 2141 final String subscriberId = mPhone.getSubscriberId(); 2142 if (!TextUtils.isEmpty(subscriberId)) { 2143 configBuilder.setSubscriberId(subscriberId); 2144 } 2145 2146 // set skip464xlat if it is not default otherwise 2147 if (shouldSkip464Xlat()) { 2148 configBuilder.disableNat64Detection(); 2149 } 2150 2151 mUnmeteredUseOnly = isUnmeteredUseOnly(); 2152 2153 if (DBG) { 2154 log("mRestrictedNetworkOverride = " + mRestrictedNetworkOverride 2155 + ", mUnmeteredUseOnly = " + mUnmeteredUseOnly); 2156 } 2157 2158 if (mConnectionParams != null 2159 && mConnectionParams.mRequestType == DcTracker.REQUEST_TYPE_HANDOVER) { 2160 // If this is a data setup for handover, we need to reuse the existing network agent 2161 // instead of creating a new one. This should be transparent to connectivity 2162 // service. 2163 DcTracker dcTracker = mPhone.getDcTracker(getHandoverSourceTransport()); 2164 DataConnection dc = dcTracker.getDataConnectionByApnType( 2165 mConnectionParams.mApnContext.getApnType()); 2166 // It's possible that the source data connection has been disconnected by the modem 2167 // already. If not, set its handover state to completed. 2168 if (dc != null) { 2169 // Transfer network agent from the original data connection as soon as the 2170 // new handover data connection is connected. 2171 dc.setHandoverState(HANDOVER_STATE_COMPLETED); 2172 } 2173 2174 if (mHandoverSourceNetworkAgent != null) { 2175 String logStr = "Transfer network agent " + mHandoverSourceNetworkAgent.getTag() 2176 + " successfully."; 2177 log(logStr); 2178 mHandoverLocalLog.log(logStr); 2179 mNetworkAgent = mHandoverSourceNetworkAgent; 2180 mNetworkAgent.acquireOwnership(DataConnection.this, mTransportType); 2181 2182 // TODO: Should evaluate mDisabledApnTypeBitMask again after handover. We don't 2183 // do it now because connectivity service does not support dynamically removing 2184 // immutable capabilities. 2185 2186 // Update the capability after handover 2187 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2188 DataConnection.this); 2189 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 2190 mHandoverSourceNetworkAgent = null; 2191 } else { 2192 String logStr = "Failed to get network agent from original data connection"; 2193 loge(logStr); 2194 mHandoverLocalLog.log(logStr); 2195 return; 2196 } 2197 } else { 2198 mScore = calculateScore(); 2199 final NetworkFactory factory = PhoneFactory.getNetworkFactory( 2200 mPhone.getPhoneId()); 2201 final NetworkProvider provider = (null == factory) ? null : factory.getProvider(); 2202 2203 mDisabledApnTypeBitMask |= getDisallowedApnTypes(); 2204 2205 mNetworkAgent = new DcNetworkAgent(DataConnection.this, 2206 mPhone, mNetworkInfo, mScore, configBuilder.build(), provider, 2207 mTransportType); 2208 // All network agents start out in CONNECTING mode, but DcNetworkAgents are 2209 // created when the network is already connected. Hence, send the connected 2210 // notification immediately. 2211 mNetworkAgent.markConnected(); 2212 } 2213 2214 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 2215 mPhone.mCi.registerForNattKeepaliveStatus( 2216 getHandler(), DataConnection.EVENT_KEEPALIVE_STATUS, null); 2217 mPhone.mCi.registerForLceInfo( 2218 getHandler(), DataConnection.EVENT_LINK_CAPACITY_CHANGED, null); 2219 } 2220 TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(), 2221 mCid, mApnSetting.getApnTypeBitmask(), RilDataCall.State.CONNECTED); 2222 } 2223 2224 @Override exit()2225 public void exit() { 2226 if (DBG) log("DcActiveState: exit dc=" + this); 2227 String reason = mNetworkInfo.getReason(); 2228 if(mDcController.isExecutingCarrierChange()) { 2229 reason = Phone.REASON_CARRIER_CHANGE; 2230 } else if (mDisconnectParams != null && mDisconnectParams.mReason != null) { 2231 reason = mDisconnectParams.mReason; 2232 } else { 2233 reason = DataFailCause.toString(mDcFailCause); 2234 } 2235 mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler()); 2236 mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler()); 2237 2238 // If the data connection is being handover to other transport, we should not notify 2239 // disconnected to connectivity service. 2240 if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED) { 2241 mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, 2242 reason, mNetworkInfo.getExtraInfo()); 2243 } 2244 2245 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 2246 mPhone.mCi.unregisterForNattKeepaliveStatus(getHandler()); 2247 mPhone.mCi.unregisterForLceInfo(getHandler()); 2248 } 2249 2250 // If we are still owning this agent, then we should inform connectivity service the 2251 // data connection is disconnected. If we don't own this agent at this point, that means 2252 // it has been transferred to the new data connection for IWLAN data handover case. 2253 if (mNetworkAgent != null) { 2254 mNetworkAgent.sendNetworkInfo(mNetworkInfo, DataConnection.this); 2255 mNetworkAgent.releaseOwnership(DataConnection.this); 2256 } 2257 mNetworkAgent = null; 2258 2259 TelephonyMetrics.getInstance().writeRilDataCallEvent(mPhone.getPhoneId(), 2260 mCid, mApnSetting.getApnTypeBitmask(), RilDataCall.State.DISCONNECTED); 2261 2262 mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler()); 2263 } 2264 2265 @Override processMessage(Message msg)2266 public boolean processMessage(Message msg) { 2267 boolean retVal; 2268 2269 switch (msg.what) { 2270 case EVENT_CONNECT: { 2271 ConnectionParams cp = (ConnectionParams) msg.obj; 2272 // either add this new apn context to our set or 2273 // update the existing cp with the latest connection generation number 2274 mApnContexts.put(cp.mApnContext, cp); 2275 // TODO (b/118347948): evaluate if it's still needed after assigning 2276 // different scores to different Cellular network. 2277 mDisabledApnTypeBitMask &= ~cp.mApnContext.getApnTypeBitmask(); 2278 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2279 DataConnection.this); 2280 if (DBG) { 2281 log("DcActiveState: EVENT_CONNECT cp=" + cp + " dc=" + DataConnection.this); 2282 } 2283 notifyConnectCompleted(cp, DataFailCause.NONE, false); 2284 retVal = HANDLED; 2285 break; 2286 } 2287 case EVENT_DISCONNECT: { 2288 DisconnectParams dp = (DisconnectParams) msg.obj; 2289 if (DBG) { 2290 log("DcActiveState: EVENT_DISCONNECT dp=" + dp 2291 + " dc=" + DataConnection.this); 2292 } 2293 if (mApnContexts.containsKey(dp.mApnContext)) { 2294 if (DBG) { 2295 log("DcActiveState msg.what=EVENT_DISCONNECT RefCount=" 2296 + mApnContexts.size()); 2297 } 2298 2299 if (mApnContexts.size() == 1) { 2300 mApnContexts.clear(); 2301 mDisconnectParams = dp; 2302 mConnectionParams = null; 2303 dp.mTag = mTag; 2304 tearDownData(dp); 2305 transitionTo(mDisconnectingState); 2306 } else { 2307 mApnContexts.remove(dp.mApnContext); 2308 // TODO (b/118347948): evaluate if it's still needed after assigning 2309 // different scores to different Cellular network. 2310 mDisabledApnTypeBitMask |= dp.mApnContext.getApnTypeBitmask(); 2311 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2312 DataConnection.this); 2313 notifyDisconnectCompleted(dp, false); 2314 } 2315 } else { 2316 log("DcActiveState ERROR no such apnContext=" + dp.mApnContext 2317 + " in this dc=" + DataConnection.this); 2318 notifyDisconnectCompleted(dp, false); 2319 } 2320 retVal = HANDLED; 2321 break; 2322 } 2323 case EVENT_DISCONNECT_ALL: { 2324 if (DBG) { 2325 log("DcActiveState EVENT_DISCONNECT clearing apn contexts," 2326 + " dc=" + DataConnection.this); 2327 } 2328 DisconnectParams dp = (DisconnectParams) msg.obj; 2329 mDisconnectParams = dp; 2330 mConnectionParams = null; 2331 dp.mTag = mTag; 2332 tearDownData(dp); 2333 transitionTo(mDisconnectingState); 2334 retVal = HANDLED; 2335 break; 2336 } 2337 case EVENT_LOST_CONNECTION: { 2338 if (DBG) { 2339 log("DcActiveState EVENT_LOST_CONNECTION dc=" + DataConnection.this); 2340 } 2341 2342 mInactiveState.setEnterNotificationParams(DataFailCause.LOST_CONNECTION); 2343 transitionTo(mInactiveState); 2344 retVal = HANDLED; 2345 break; 2346 } 2347 case EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED: { 2348 AsyncResult ar = (AsyncResult) msg.obj; 2349 Pair<Integer, Integer> drsRatPair = (Pair<Integer, Integer>) ar.result; 2350 mDataRegState = drsRatPair.first; 2351 updateTcpBufferSizes(drsRatPair.second); 2352 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 2353 updateLinkBandwidthsFromCarrierConfig(drsRatPair.second); 2354 } 2355 mRilRat = drsRatPair.second; 2356 if (DBG) { 2357 log("DcActiveState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED" 2358 + " drs=" + mDataRegState 2359 + " mRilRat=" + mRilRat); 2360 } 2361 updateNetworkInfoSuspendState(); 2362 if (mNetworkAgent != null) { 2363 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2364 DataConnection.this); 2365 mNetworkAgent.sendNetworkInfo(mNetworkInfo, DataConnection.this); 2366 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 2367 } 2368 retVal = HANDLED; 2369 break; 2370 } 2371 case EVENT_NR_FREQUENCY_CHANGED: 2372 // fallthrough 2373 case EVENT_CARRIER_CONFIG_LINK_BANDWIDTHS_CHANGED: 2374 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 2375 updateLinkBandwidthsFromCarrierConfig(mRilRat); 2376 } 2377 if (mNetworkAgent != null) { 2378 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2379 DataConnection.this); 2380 } 2381 retVal = HANDLED; 2382 break; 2383 case EVENT_DATA_CONNECTION_METEREDNESS_CHANGED: 2384 boolean isUnmetered = (boolean) msg.obj; 2385 if (isUnmetered == mUnmeteredOverride) { 2386 retVal = HANDLED; 2387 break; 2388 } 2389 mUnmeteredOverride = isUnmetered; 2390 // fallthrough 2391 case EVENT_DATA_CONNECTION_ROAM_ON: 2392 case EVENT_DATA_CONNECTION_ROAM_OFF: 2393 case EVENT_DATA_CONNECTION_OVERRIDE_CHANGED: { 2394 updateNetworkInfo(); 2395 if (mNetworkAgent != null) { 2396 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2397 DataConnection.this); 2398 } 2399 retVal = HANDLED; 2400 break; 2401 } 2402 case EVENT_BW_REFRESH_RESPONSE: { 2403 AsyncResult ar = (AsyncResult)msg.obj; 2404 if (ar.exception != null) { 2405 log("EVENT_BW_REFRESH_RESPONSE: error ignoring, e=" + ar.exception); 2406 } else { 2407 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) { 2408 updateLinkBandwidthsFromModem((LinkCapacityEstimate) ar.result); 2409 } 2410 } 2411 retVal = HANDLED; 2412 break; 2413 } 2414 case EVENT_DATA_CONNECTION_VOICE_CALL_STARTED: 2415 case EVENT_DATA_CONNECTION_VOICE_CALL_ENDED: { 2416 updateNetworkInfo(); 2417 updateNetworkInfoSuspendState(); 2418 if (mNetworkAgent != null) { 2419 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2420 DataConnection.this); 2421 mNetworkAgent.sendNetworkInfo(mNetworkInfo, DataConnection.this); 2422 } 2423 retVal = HANDLED; 2424 break; 2425 } 2426 case EVENT_KEEPALIVE_START_REQUEST: { 2427 KeepalivePacketData pkt = (KeepalivePacketData) msg.obj; 2428 int slotId = msg.arg1; 2429 int intervalMillis = msg.arg2 * 1000; 2430 if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) { 2431 mPhone.mCi.startNattKeepalive( 2432 DataConnection.this.mCid, pkt, intervalMillis, 2433 DataConnection.this.obtainMessage( 2434 EVENT_KEEPALIVE_STARTED, slotId, 0, null)); 2435 } else { 2436 // We currently do not support NATT Keepalive requests using the 2437 // DataService API, so unless the request is WWAN (always bound via 2438 // the CommandsInterface), the request cannot be honored. 2439 // 2440 // TODO: b/72331356 to add support for Keepalive to the DataService 2441 // so that keepalive requests can be handled (if supported) by the 2442 // underlying transport. 2443 if (mNetworkAgent != null) { 2444 mNetworkAgent.sendSocketKeepaliveEvent( 2445 msg.arg1, SocketKeepalive.ERROR_INVALID_NETWORK); 2446 } 2447 } 2448 retVal = HANDLED; 2449 break; 2450 } 2451 case EVENT_KEEPALIVE_STOP_REQUEST: { 2452 int slotId = msg.arg1; 2453 int handle = mNetworkAgent.keepaliveTracker.getHandleForSlot(slotId); 2454 if (handle < 0) { 2455 loge("No slot found for stopSocketKeepalive! " + slotId); 2456 mNetworkAgent.sendSocketKeepaliveEvent( 2457 slotId, SocketKeepalive.NO_KEEPALIVE); 2458 retVal = HANDLED; 2459 break; 2460 } else { 2461 logd("Stopping keepalive with handle: " + handle); 2462 } 2463 2464 mPhone.mCi.stopNattKeepalive( 2465 handle, DataConnection.this.obtainMessage( 2466 EVENT_KEEPALIVE_STOPPED, handle, slotId, null)); 2467 retVal = HANDLED; 2468 break; 2469 } 2470 case EVENT_KEEPALIVE_STARTED: { 2471 AsyncResult ar = (AsyncResult) msg.obj; 2472 final int slot = msg.arg1; 2473 if (ar.exception != null || ar.result == null) { 2474 loge("EVENT_KEEPALIVE_STARTED: error starting keepalive, e=" 2475 + ar.exception); 2476 mNetworkAgent.sendSocketKeepaliveEvent( 2477 slot, SocketKeepalive.ERROR_HARDWARE_ERROR); 2478 } else { 2479 KeepaliveStatus ks = (KeepaliveStatus) ar.result; 2480 if (ks == null) { 2481 loge("Null KeepaliveStatus received!"); 2482 } else { 2483 mNetworkAgent.keepaliveTracker.handleKeepaliveStarted(slot, ks); 2484 } 2485 } 2486 retVal = HANDLED; 2487 break; 2488 } 2489 case EVENT_KEEPALIVE_STATUS: { 2490 AsyncResult ar = (AsyncResult) msg.obj; 2491 if (ar.exception != null) { 2492 loge("EVENT_KEEPALIVE_STATUS: error in keepalive, e=" + ar.exception); 2493 // We have no way to notify connectivity in this case. 2494 } 2495 if (ar.result != null) { 2496 KeepaliveStatus ks = (KeepaliveStatus) ar.result; 2497 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(ks); 2498 } 2499 2500 retVal = HANDLED; 2501 break; 2502 } 2503 case EVENT_KEEPALIVE_STOPPED: { 2504 AsyncResult ar = (AsyncResult) msg.obj; 2505 final int handle = msg.arg1; 2506 final int slotId = msg.arg2; 2507 2508 if (ar.exception != null) { 2509 loge("EVENT_KEEPALIVE_STOPPED: error stopping keepalive for handle=" 2510 + handle + " e=" + ar.exception); 2511 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus( 2512 new KeepaliveStatus(KeepaliveStatus.ERROR_UNKNOWN)); 2513 } else { 2514 log("Keepalive Stop Requested for handle=" + handle); 2515 mNetworkAgent.keepaliveTracker.handleKeepaliveStatus( 2516 new KeepaliveStatus(handle, KeepaliveStatus.STATUS_INACTIVE)); 2517 } 2518 retVal = HANDLED; 2519 break; 2520 } 2521 case EVENT_LINK_CAPACITY_CHANGED: { 2522 AsyncResult ar = (AsyncResult) msg.obj; 2523 if (ar.exception != null) { 2524 loge("EVENT_LINK_CAPACITY_CHANGED e=" + ar.exception); 2525 } else { 2526 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_MODEM_KEY)) { 2527 updateLinkBandwidthsFromModem((LinkCapacityEstimate) ar.result); 2528 } 2529 } 2530 retVal = HANDLED; 2531 break; 2532 } 2533 case EVENT_REEVALUATE_RESTRICTED_STATE: { 2534 // If the network was restricted, and now it does not need to be restricted 2535 // anymore, we should add the NET_CAPABILITY_NOT_RESTRICTED capability. 2536 if (mRestrictedNetworkOverride && !shouldRestrictNetwork()) { 2537 if (DBG) { 2538 log("Data connection becomes not-restricted. dc=" + this); 2539 } 2540 // Note we only do this when network becomes non-restricted. When a 2541 // non-restricted becomes restricted (e.g. users disable data, or turn off 2542 // data roaming), DCT will explicitly tear down the networks (because 2543 // connectivity service does not support force-close TCP connections today). 2544 // Also note that NET_CAPABILITY_NOT_RESTRICTED is an immutable capability 2545 // (see {@link NetworkCapabilities}) once we add it to the network, we can't 2546 // remove it through the entire life cycle of the connection. 2547 mRestrictedNetworkOverride = false; 2548 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2549 DataConnection.this); 2550 } 2551 2552 // If the data does need to be unmetered use only (e.g. users turn on data, or 2553 // device is not roaming anymore assuming data roaming is off), then we can 2554 // dynamically add those metered APN type capabilities back. (But not the 2555 // other way around because most of the APN-type capabilities are immutable 2556 // capabilities.) 2557 if (mUnmeteredUseOnly && !isUnmeteredUseOnly()) { 2558 mUnmeteredUseOnly = false; 2559 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2560 DataConnection.this); 2561 } 2562 2563 retVal = HANDLED; 2564 break; 2565 } 2566 case EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES: { 2567 // Update other properties like link properties if needed in future. 2568 updateScore(); 2569 retVal = HANDLED; 2570 break; 2571 } 2572 case EVENT_NR_STATE_CHANGED: { 2573 updateTcpBufferSizes(mRilRat); 2574 if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_CARRIER_CONFIG_KEY)) { 2575 updateLinkBandwidthsFromCarrierConfig(mRilRat); 2576 } 2577 if (mNetworkAgent != null) { 2578 mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this); 2579 mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(), 2580 DataConnection.this); 2581 } 2582 retVal = HANDLED; 2583 break; 2584 } 2585 case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: 2586 AsyncResult asyncResult = (AsyncResult) msg.obj; 2587 int[] administratorUids = (int[]) asyncResult.result; 2588 mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length); 2589 2590 // Administrator UIDs changed, so update NetworkAgent with new 2591 // NetworkCapabilities 2592 if (mNetworkAgent != null) { 2593 mNetworkAgent.sendNetworkCapabilities( 2594 getNetworkCapabilities(), DataConnection.this); 2595 } 2596 retVal = HANDLED; 2597 break; 2598 default: 2599 if (VDBG) { 2600 log("DcActiveState not handled msg.what=" + getWhatToString(msg.what)); 2601 } 2602 retVal = NOT_HANDLED; 2603 break; 2604 } 2605 return retVal; 2606 } 2607 } 2608 private DcActiveState mActiveState = new DcActiveState(); 2609 2610 /** 2611 * The state machine is disconnecting. 2612 */ 2613 private class DcDisconnectingState extends State { 2614 @Override enter()2615 public void enter() { 2616 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2617 TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTING, 2618 mPhone.getPhoneId(), mId, 2619 mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L, 2620 mApnSetting != null 2621 ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false); 2622 } 2623 @Override processMessage(Message msg)2624 public boolean processMessage(Message msg) { 2625 boolean retVal; 2626 2627 switch (msg.what) { 2628 case EVENT_CONNECT: 2629 if (DBG) log("DcDisconnectingState msg.what=EVENT_CONNECT. Defer. RefCount = " 2630 + mApnContexts.size()); 2631 deferMessage(msg); 2632 retVal = HANDLED; 2633 break; 2634 2635 case EVENT_DEACTIVATE_DONE: 2636 DisconnectParams dp = (DisconnectParams) msg.obj; 2637 2638 String str = "DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE RefCount=" 2639 + mApnContexts.size(); 2640 if (DBG) log(str); 2641 if (dp.mApnContext != null) dp.mApnContext.requestLog(str); 2642 2643 if (dp.mTag == mTag) { 2644 // Transition to inactive but send notifications after 2645 // we've entered the mInactive state. 2646 mInactiveState.setEnterNotificationParams(dp); 2647 transitionTo(mInactiveState); 2648 } else { 2649 if (DBG) log("DcDisconnectState stale EVENT_DEACTIVATE_DONE" 2650 + " dp.tag=" + dp.mTag + " mTag=" + mTag); 2651 } 2652 retVal = HANDLED; 2653 break; 2654 2655 default: 2656 if (VDBG) { 2657 log("DcDisconnectingState not handled msg.what=" 2658 + getWhatToString(msg.what)); 2659 } 2660 retVal = NOT_HANDLED; 2661 break; 2662 } 2663 return retVal; 2664 } 2665 } 2666 private DcDisconnectingState mDisconnectingState = new DcDisconnectingState(); 2667 2668 /** 2669 * The state machine is disconnecting after an creating a connection. 2670 */ 2671 private class DcDisconnectionErrorCreatingConnection extends State { 2672 @Override enter()2673 public void enter() { 2674 TelephonyStatsLog.write(TelephonyStatsLog.MOBILE_CONNECTION_STATE_CHANGED, 2675 TelephonyStatsLog 2676 .MOBILE_CONNECTION_STATE_CHANGED__STATE__DISCONNECTION_ERROR_CREATING_CONNECTION, 2677 mPhone.getPhoneId(), mId, 2678 mApnSetting != null ? (long) mApnSetting.getApnTypeBitmask() : 0L, 2679 mApnSetting != null 2680 ? mApnSetting.canHandleType(ApnSetting.TYPE_DEFAULT) : false); 2681 } 2682 @Override processMessage(Message msg)2683 public boolean processMessage(Message msg) { 2684 boolean retVal; 2685 2686 switch (msg.what) { 2687 case EVENT_DEACTIVATE_DONE: 2688 ConnectionParams cp = (ConnectionParams) msg.obj; 2689 if (cp.mTag == mTag) { 2690 String str = "DcDisconnectionErrorCreatingConnection" + 2691 " msg.what=EVENT_DEACTIVATE_DONE"; 2692 if (DBG) log(str); 2693 if (cp.mApnContext != null) cp.mApnContext.requestLog(str); 2694 2695 // Transition to inactive but send notifications after 2696 // we've entered the mInactive state. 2697 mInactiveState.setEnterNotificationParams(cp, 2698 DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER); 2699 transitionTo(mInactiveState); 2700 } else { 2701 if (DBG) { 2702 log("DcDisconnectionErrorCreatingConnection stale EVENT_DEACTIVATE_DONE" 2703 + " dp.tag=" + cp.mTag + ", mTag=" + mTag); 2704 } 2705 } 2706 retVal = HANDLED; 2707 break; 2708 2709 default: 2710 if (VDBG) { 2711 log("DcDisconnectionErrorCreatingConnection not handled msg.what=" 2712 + getWhatToString(msg.what)); 2713 } 2714 retVal = NOT_HANDLED; 2715 break; 2716 } 2717 return retVal; 2718 } 2719 } 2720 private DcDisconnectionErrorCreatingConnection mDisconnectingErrorCreatingConnection = 2721 new DcDisconnectionErrorCreatingConnection(); 2722 2723 /** 2724 * Bring up a connection to the apn and return an AsyncResult in onCompletedMsg. 2725 * Used for cellular networks that use Access Point Names (APN) such 2726 * as GSM networks. 2727 * 2728 * @param apnContext is the Access Point Name to bring up a connection to 2729 * @param profileId for the connection 2730 * @param rilRadioTechnology Radio technology for the data connection 2731 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 2732 * With AsyncResult.userObj set to the original msg.obj, 2733 * AsyncResult.result = FailCause and AsyncResult.exception = Exception(). 2734 * @param connectionGeneration used to track a single connection request so disconnects can get 2735 * ignored if obsolete. 2736 * @param requestType Data request type 2737 * @param subId the subscription id associated with this data connection. 2738 * @param isApnPreferred whether or not the apn is preferred. 2739 */ bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology, Message onCompletedMsg, int connectionGeneration, @RequestNetworkType int requestType, int subId, boolean isApnPreferred)2740 public void bringUp(ApnContext apnContext, int profileId, int rilRadioTechnology, 2741 Message onCompletedMsg, int connectionGeneration, 2742 @RequestNetworkType int requestType, int subId, boolean isApnPreferred) { 2743 if (DBG) { 2744 log("bringUp: apnContext=" + apnContext + " onCompletedMsg=" + onCompletedMsg); 2745 } 2746 sendMessage(DataConnection.EVENT_CONNECT, 2747 new ConnectionParams(apnContext, profileId, rilRadioTechnology, onCompletedMsg, 2748 connectionGeneration, requestType, subId, isApnPreferred)); 2749 } 2750 2751 /** 2752 * Tear down the connection through the apn on the network. 2753 * 2754 * @param apnContext APN context 2755 * @param reason reason to tear down 2756 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 2757 * With AsyncResult.userObj set to the original msg.obj. 2758 */ tearDown(ApnContext apnContext, String reason, Message onCompletedMsg)2759 public void tearDown(ApnContext apnContext, String reason, Message onCompletedMsg) { 2760 if (DBG) { 2761 log("tearDown: apnContext=" + apnContext + " reason=" + reason + " onCompletedMsg=" 2762 + onCompletedMsg); 2763 } 2764 sendMessage(DataConnection.EVENT_DISCONNECT, 2765 new DisconnectParams(apnContext, reason, DcTracker.RELEASE_TYPE_DETACH, 2766 onCompletedMsg)); 2767 } 2768 2769 // ******* "public" interface 2770 2771 /** 2772 * Used for testing purposes. 2773 */ tearDownNow()2774 void tearDownNow() { 2775 if (DBG) log("tearDownNow()"); 2776 sendMessage(obtainMessage(EVENT_TEAR_DOWN_NOW)); 2777 } 2778 2779 /** 2780 * Tear down the connection through the apn on the network. Ignores reference count and 2781 * and always tears down. 2782 * 2783 * @param releaseType Data release type 2784 * @param onCompletedMsg is sent with its msg.obj as an AsyncResult object. 2785 * With AsyncResult.userObj set to the original msg.obj. 2786 */ tearDownAll(String reason, @ReleaseNetworkType int releaseType, Message onCompletedMsg)2787 public void tearDownAll(String reason, @ReleaseNetworkType int releaseType, 2788 Message onCompletedMsg) { 2789 if (DBG) log("tearDownAll: reason=" + reason + ", releaseType=" + releaseType); 2790 sendMessage(DataConnection.EVENT_DISCONNECT_ALL, 2791 new DisconnectParams(null, reason, releaseType, onCompletedMsg)); 2792 } 2793 2794 /** 2795 * Reset the data connection to inactive state. 2796 */ reset()2797 public void reset() { 2798 sendMessage(EVENT_RESET); 2799 if (DBG) log("reset"); 2800 } 2801 2802 /** 2803 * Re-evaluate the restricted state. If the restricted data connection does not need to be 2804 * restricted anymore, we need to dynamically change the network's capability. 2805 */ reevaluateRestrictedState()2806 void reevaluateRestrictedState() { 2807 sendMessage(EVENT_REEVALUATE_RESTRICTED_STATE); 2808 if (DBG) log("reevaluate restricted state"); 2809 } 2810 2811 /** 2812 * Re-evaluate the data connection properties. For example, it will recalculate data connection 2813 * score and update through network agent it if changed. 2814 */ reevaluateDataConnectionProperties()2815 void reevaluateDataConnectionProperties() { 2816 sendMessage(EVENT_REEVALUATE_DATA_CONNECTION_PROPERTIES); 2817 if (DBG) log("reevaluate data connection properties"); 2818 } 2819 2820 /** 2821 * @return The parameters used for initiating a data connection. 2822 */ getConnectionParams()2823 public ConnectionParams getConnectionParams() { 2824 return mConnectionParams; 2825 } 2826 2827 /** 2828 * @return The list of PCSCF addresses 2829 */ getPcscfAddresses()2830 public String[] getPcscfAddresses() { 2831 return mPcscfAddr; 2832 } 2833 2834 /** 2835 * Using the result of the SETUP_DATA_CALL determine the retry delay. 2836 * 2837 * @param response The response from setup data call 2838 * @return NO_SUGGESTED_RETRY_DELAY if no retry is needed otherwise the delay to the 2839 * next SETUP_DATA_CALL 2840 */ getSuggestedRetryDelay(DataCallResponse response)2841 private long getSuggestedRetryDelay(DataCallResponse response) { 2842 /** According to ril.h 2843 * The value < 0 means no value is suggested 2844 * The value 0 means retry should be done ASAP. 2845 * The value of Integer.MAX_VALUE(0x7fffffff) means no retry. 2846 */ 2847 2848 // The value < 0 means no value is suggested 2849 if (response.getSuggestedRetryTime() < 0) { 2850 if (DBG) log("No suggested retry delay."); 2851 return RetryManager.NO_SUGGESTED_RETRY_DELAY; 2852 } 2853 // The value of Integer.MAX_VALUE(0x7fffffff) means no retry. 2854 else if (response.getSuggestedRetryTime() == Integer.MAX_VALUE) { 2855 if (DBG) log("Modem suggested not retrying."); 2856 return RetryManager.NO_RETRY; 2857 } 2858 2859 // We need to cast it to long because the value returned from RIL is a 32-bit integer, 2860 // but the time values used in AlarmManager are all 64-bit long. 2861 return (long) response.getSuggestedRetryTime(); 2862 } 2863 getApnContexts()2864 public List<ApnContext> getApnContexts() { 2865 return new ArrayList<>(mApnContexts.keySet()); 2866 } 2867 2868 /** Get the network agent of the data connection */ 2869 @Nullable getNetworkAgent()2870 DcNetworkAgent getNetworkAgent() { 2871 return mNetworkAgent; 2872 } 2873 setHandoverState(@andoverState int state)2874 void setHandoverState(@HandoverState int state) { 2875 if (mHandoverState != state) { 2876 mHandoverLocalLog.log("State changed from " + handoverStateToString(mHandoverState) 2877 + " to " + handoverStateToString(state)); 2878 mHandoverState = state; 2879 } 2880 } 2881 2882 /** 2883 * @return the string for msg.what as our info. 2884 */ 2885 @Override getWhatToString(int what)2886 protected String getWhatToString(int what) { 2887 return cmdToString(what); 2888 } 2889 msgToString(Message msg)2890 private static String msgToString(Message msg) { 2891 String retVal; 2892 if (msg == null) { 2893 retVal = "null"; 2894 } else { 2895 StringBuilder b = new StringBuilder(); 2896 2897 b.append("{what="); 2898 b.append(cmdToString(msg.what)); 2899 2900 b.append(" when="); 2901 TimeUtils.formatDuration(msg.getWhen() - SystemClock.uptimeMillis(), b); 2902 2903 if (msg.arg1 != 0) { 2904 b.append(" arg1="); 2905 b.append(msg.arg1); 2906 } 2907 2908 if (msg.arg2 != 0) { 2909 b.append(" arg2="); 2910 b.append(msg.arg2); 2911 } 2912 2913 if (msg.obj != null) { 2914 b.append(" obj="); 2915 b.append(msg.obj); 2916 } 2917 2918 b.append(" target="); 2919 b.append(msg.getTarget()); 2920 2921 b.append(" replyTo="); 2922 b.append(msg.replyTo); 2923 2924 b.append("}"); 2925 2926 retVal = b.toString(); 2927 } 2928 return retVal; 2929 } 2930 slog(String s)2931 static void slog(String s) { 2932 Rlog.d("DC", s); 2933 } 2934 2935 /** 2936 * Log with debug 2937 * 2938 * @param s is string log 2939 */ 2940 @Override log(String s)2941 protected void log(String s) { 2942 Rlog.d(getName(), s); 2943 } 2944 2945 /** 2946 * Log with debug attribute 2947 * 2948 * @param s is string log 2949 */ 2950 @Override logd(String s)2951 protected void logd(String s) { 2952 Rlog.d(getName(), s); 2953 } 2954 2955 /** 2956 * Log with verbose attribute 2957 * 2958 * @param s is string log 2959 */ 2960 @Override logv(String s)2961 protected void logv(String s) { 2962 Rlog.v(getName(), s); 2963 } 2964 2965 /** 2966 * Log with info attribute 2967 * 2968 * @param s is string log 2969 */ 2970 @Override logi(String s)2971 protected void logi(String s) { 2972 Rlog.i(getName(), s); 2973 } 2974 2975 /** 2976 * Log with warning attribute 2977 * 2978 * @param s is string log 2979 */ 2980 @Override logw(String s)2981 protected void logw(String s) { 2982 Rlog.w(getName(), s); 2983 } 2984 2985 /** 2986 * Log with error attribute 2987 * 2988 * @param s is string log 2989 */ 2990 @Override loge(String s)2991 protected void loge(String s) { 2992 Rlog.e(getName(), s); 2993 } 2994 2995 /** 2996 * Log with error attribute 2997 * 2998 * @param s is string log 2999 * @param e is a Throwable which logs additional information. 3000 */ 3001 @Override loge(String s, Throwable e)3002 protected void loge(String s, Throwable e) { 3003 Rlog.e(getName(), s, e); 3004 } 3005 3006 /** Doesn't print mApnList of ApnContext's which would be recursive */ toStringSimple()3007 public String toStringSimple() { 3008 return getName() + ": State=" + getCurrentState().getName() 3009 + " mApnSetting=" + mApnSetting + " RefCount=" + mApnContexts.size() 3010 + " mCid=" + mCid + " mCreateTime=" + mCreateTime 3011 + " mLastastFailTime=" + mLastFailTime 3012 + " mLastFailCause=" + mLastFailCause 3013 + " mTag=" + mTag 3014 + " mLinkProperties=" + mLinkProperties 3015 + " linkCapabilities=" + getNetworkCapabilities() 3016 + " mRestrictedNetworkOverride=" + mRestrictedNetworkOverride; 3017 } 3018 3019 @Override toString()3020 public String toString() { 3021 return "{" + toStringSimple() + " mApnContexts=" + mApnContexts + "}"; 3022 } 3023 3024 /** Check if the device is connected to NR 5G Non-Standalone network. */ isNRConnected()3025 private boolean isNRConnected() { 3026 return mPhone.getServiceState().getNrState() 3027 == NetworkRegistrationInfo.NR_STATE_CONNECTED; 3028 } 3029 3030 /** 3031 * @return The disallowed APN types bitmask 3032 */ getDisallowedApnTypes()3033 private @ApnType int getDisallowedApnTypes() { 3034 CarrierConfigManager configManager = (CarrierConfigManager) 3035 mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE); 3036 int apnTypesBitmask = 0; 3037 if (configManager != null) { 3038 PersistableBundle bundle = configManager.getConfigForSubId(mSubId); 3039 if (bundle != null) { 3040 String key = (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 3041 ? CarrierConfigManager.KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY 3042 : CarrierConfigManager.KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY; 3043 if (bundle.getStringArray(key) != null) { 3044 String disallowedApnTypesString = 3045 TextUtils.join(",", bundle.getStringArray(key)); 3046 if (!TextUtils.isEmpty(disallowedApnTypesString)) { 3047 apnTypesBitmask = ApnSetting.getApnTypesBitmaskFromString( 3048 disallowedApnTypesString); 3049 } 3050 } 3051 } 3052 } 3053 3054 return apnTypesBitmask; 3055 } 3056 dumpToLog()3057 private void dumpToLog() { 3058 dump(null, new PrintWriter(new StringWriter(0)) { 3059 @Override 3060 public void println(String s) { 3061 DataConnection.this.logd(s); 3062 } 3063 3064 @Override 3065 public void flush() { 3066 } 3067 }, null); 3068 } 3069 3070 /** 3071 * Re-calculate score and update through network agent if it changes. 3072 */ updateScore()3073 private void updateScore() { 3074 int oldScore = mScore; 3075 mScore = calculateScore(); 3076 if (oldScore != mScore && mNetworkAgent != null) { 3077 log("Updating score from " + oldScore + " to " + mScore); 3078 mNetworkAgent.sendNetworkScore(mScore, this); 3079 } 3080 } 3081 calculateScore()3082 private int calculateScore() { 3083 int score = OTHER_CONNECTION_SCORE; 3084 3085 // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have 3086 // specify a subId, this dataConnection is considered to be default Internet data 3087 // connection. In this case we assign a slightly higher score of 50. The intention is 3088 // it will not be replaced by other data connections accidentally in DSDS usecase. 3089 for (ApnContext apnContext : mApnContexts.keySet()) { 3090 for (NetworkRequest networkRequest : apnContext.getNetworkRequests()) { 3091 if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) 3092 && networkRequest.getNetworkSpecifier() == null) { 3093 score = DEFAULT_INTERNET_CONNECTION_SCORE; 3094 break; 3095 } 3096 } 3097 } 3098 3099 return score; 3100 } 3101 handoverStateToString(@andoverState int state)3102 private String handoverStateToString(@HandoverState int state) { 3103 switch (state) { 3104 case HANDOVER_STATE_IDLE: return "IDLE"; 3105 case HANDOVER_STATE_BEING_TRANSFERRED: return "BEING_TRANSFERRED"; 3106 case HANDOVER_STATE_COMPLETED: return "COMPLETED"; 3107 default: return "UNKNOWN"; 3108 } 3109 } 3110 3111 /** 3112 * Dump the current state. 3113 * 3114 * @param fd 3115 * @param pw 3116 * @param args 3117 */ 3118 @Override dump(FileDescriptor fd, PrintWriter printWriter, String[] args)3119 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 3120 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 3121 pw.print("DataConnection "); 3122 super.dump(fd, pw, args); 3123 pw.flush(); 3124 pw.increaseIndent(); 3125 pw.println("transport type=" 3126 + AccessNetworkConstants.transportTypeToString(mTransportType)); 3127 pw.println("mApnContexts.size=" + mApnContexts.size()); 3128 pw.println("mApnContexts=" + mApnContexts); 3129 pw.println("mApnSetting=" + mApnSetting); 3130 pw.println("mTag=" + mTag); 3131 pw.println("mCid=" + mCid); 3132 pw.println("mConnectionParams=" + mConnectionParams); 3133 pw.println("mDisconnectParams=" + mDisconnectParams); 3134 pw.println("mDcFailCause=" + mDcFailCause); 3135 pw.println("mPhone=" + mPhone); 3136 pw.println("mSubId=" + mSubId); 3137 pw.println("mLinkProperties=" + mLinkProperties); 3138 pw.flush(); 3139 pw.println("mDataRegState=" + mDataRegState); 3140 pw.println("mHandoverState=" + handoverStateToString(mHandoverState)); 3141 pw.println("mRilRat=" + mRilRat); 3142 pw.println("mNetworkCapabilities=" + getNetworkCapabilities()); 3143 pw.println("mCreateTime=" + TimeUtils.logTimeOfDay(mCreateTime)); 3144 pw.println("mLastFailTime=" + TimeUtils.logTimeOfDay(mLastFailTime)); 3145 pw.println("mLastFailCause=" + mLastFailCause); 3146 pw.println("mUserData=" + mUserData); 3147 pw.println("mSubscriptionOverride=" + Integer.toHexString(mSubscriptionOverride)); 3148 pw.println("mRestrictedNetworkOverride=" + mRestrictedNetworkOverride); 3149 pw.println("mUnmeteredUseOnly=" + mUnmeteredUseOnly); 3150 pw.println("mUnmeteredOverride=" + mUnmeteredOverride); 3151 pw.println("mDownlinkBandwidth" + mDownlinkBandwidth); 3152 pw.println("mUplinkBandwidth=" + mUplinkBandwidth); 3153 pw.println("disallowedApnTypes=" 3154 + ApnSetting.getApnTypesStringFromBitmask(getDisallowedApnTypes())); 3155 pw.println("mInstanceNumber=" + mInstanceNumber); 3156 pw.println("mAc=" + mAc); 3157 pw.println("mScore=" + mScore); 3158 if (mNetworkAgent != null) { 3159 mNetworkAgent.dump(fd, pw, args); 3160 } 3161 pw.println("handover local log:"); 3162 pw.increaseIndent(); 3163 mHandoverLocalLog.dump(fd, pw, args); 3164 pw.decreaseIndent(); 3165 pw.decreaseIndent(); 3166 pw.println(); 3167 pw.flush(); 3168 } 3169 } 3170 3171