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