Linkproperties update via unsol data call state change.
Handles the scenario of radio technology handover with IP continuity. Once RIL/Modem finished a handover operation, an unsol data call state change will be send up to FW notifying all link propertes changes. FW will then re-configure the device with new link properties including iptable used by Tethering. Change-Id: I05e29f66ac3db8ba4274d3662642607742ba1d12
This commit is contained in:
committed by
Wink Saville
parent
258208a78c
commit
01758e81b3
@ -276,6 +276,21 @@ public class MobileDataStateTracker implements NetworkStateTracker {
|
|||||||
setDetailedState(DetailedState.CONNECTED, reason, apnName);
|
setDetailedState(DetailedState.CONNECTED, reason, apnName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// There was no state change. Check if LinkProperties has been updated.
|
||||||
|
if (TextUtils.equals(reason, Phone.REASON_LINK_PROPERTIES_CHANGED)) {
|
||||||
|
mLinkProperties = intent.getParcelableExtra(Phone.DATA_LINK_PROPERTIES_KEY);
|
||||||
|
if (mLinkProperties == null) {
|
||||||
|
log("No link property in LINK_PROPERTIES change event.");
|
||||||
|
mLinkProperties = new LinkProperties();
|
||||||
|
}
|
||||||
|
// Just update reason field in this NetworkInfo
|
||||||
|
mNetworkInfo.setDetailedState(mNetworkInfo.getDetailedState(), reason,
|
||||||
|
mNetworkInfo.getExtraInfo());
|
||||||
|
Message msg = mTarget.obtainMessage(EVENT_CONFIGURATION_CHANGED,
|
||||||
|
mNetworkInfo);
|
||||||
|
msg.sendToTarget();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (intent.getAction().
|
} else if (intent.getAction().
|
||||||
equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
|
equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
|
||||||
|
@ -1391,6 +1391,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
} else {
|
} else {
|
||||||
addPrivateDnsRoutes(mNetTrackers[netType]);
|
addPrivateDnsRoutes(mNetTrackers[netType]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Notify TetheringService if interface name has been changed. */
|
||||||
|
if (TextUtils.equals(mNetTrackers[netType].getNetworkInfo().getReason(),
|
||||||
|
Phone.REASON_LINK_PROPERTIES_CHANGED)) {
|
||||||
|
handleTetherIfaceChange(netType);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (mNetConfigs[netType].isDefault()) {
|
if (mNetConfigs[netType].isDefault()) {
|
||||||
removeDefaultRoute(mNetTrackers[netType]);
|
removeDefaultRoute(mNetTrackers[netType]);
|
||||||
@ -2203,6 +2209,14 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleTetherIfaceChange(int type) {
|
||||||
|
String iface = mNetTrackers[type].getLinkProperties().getInterfaceName();
|
||||||
|
|
||||||
|
if (isTetheringSupported()) {
|
||||||
|
mTethering.handleTetherIfaceChange(iface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void log(String s) {
|
private void log(String s) {
|
||||||
Slog.d(TAG, s);
|
Slog.d(TAG, s);
|
||||||
}
|
}
|
||||||
|
@ -668,6 +668,16 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void handleTetherIfaceChange(String iface) {
|
||||||
|
// check if iface is white listed
|
||||||
|
for (String regex : mUpstreamIfaceRegexs) {
|
||||||
|
if (iface.matches(regex)) {
|
||||||
|
if (DEBUG) Log.d(TAG, "Tethering got Interface Change");
|
||||||
|
mTetherMasterSM.sendMessage(TetherMasterSM.CMD_IFACE_CHANGED, iface);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TetherInterfaceSM extends StateMachine {
|
class TetherInterfaceSM extends StateMachine {
|
||||||
// notification from the master SM that it's not in tether mode
|
// notification from the master SM that it's not in tether mode
|
||||||
@ -1076,6 +1086,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
|||||||
static final int CMD_CELL_CONNECTION_RENEW = 4;
|
static final int CMD_CELL_CONNECTION_RENEW = 4;
|
||||||
// we don't have a valid upstream conn, check again after a delay
|
// we don't have a valid upstream conn, check again after a delay
|
||||||
static final int CMD_RETRY_UPSTREAM = 5;
|
static final int CMD_RETRY_UPSTREAM = 5;
|
||||||
|
// received an indication that upstream interface has changed
|
||||||
|
static final int CMD_IFACE_CHANGED = 6;
|
||||||
|
|
||||||
// This indicates what a timeout event relates to. A state that
|
// This indicates what a timeout event relates to. A state that
|
||||||
// sends itself a delayed timeout event and handles incoming timeout events
|
// sends itself a delayed timeout event and handles incoming timeout events
|
||||||
@ -1429,13 +1441,18 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
|||||||
turnOnMobileConnection();
|
turnOnMobileConnection();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CMD_RETRY_UPSTREAM:
|
case CMD_RETRY_UPSTREAM:
|
||||||
chooseUpstreamType(mTryCell);
|
chooseUpstreamType(mTryCell);
|
||||||
mTryCell = !mTryCell;
|
mTryCell = !mTryCell;
|
||||||
break;
|
break;
|
||||||
default:
|
case CMD_IFACE_CHANGED:
|
||||||
retValue = false;
|
String iface = (String)message.obj;
|
||||||
break;
|
if (DEBUG) Log.d(TAG, "Activie upstream interface changed: " + iface);
|
||||||
|
notifyTetheredOfNewUpstreamIface(iface);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
retValue = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
@ -509,24 +509,58 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
result.mFailCause = FailCause.fromInt(response.status);
|
result.mFailCause = FailCause.fromInt(response.status);
|
||||||
} else {
|
} else {
|
||||||
log("onSetupConnectionCompleted received DataCallState: " + response);
|
log("onSetupConnectionCompleted received DataCallState: " + response);
|
||||||
|
|
||||||
// Check if system property dns usable
|
|
||||||
boolean okToUseSystemPropertyDns = false;
|
|
||||||
cid = response.cid;
|
cid = response.cid;
|
||||||
String propertyPrefix = "net." + response.ifname + ".";
|
|
||||||
String dnsServers[] = new String[2];
|
|
||||||
dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
|
|
||||||
dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
|
|
||||||
okToUseSystemPropertyDns = isDnsOk(dnsServers);
|
|
||||||
|
|
||||||
// set link properties based on data call response
|
// set link properties based on data call response
|
||||||
result = response.setLinkProperties(mLinkProperties,
|
result = response.setLinkProperties(mLinkProperties,
|
||||||
okToUseSystemPropertyDns);
|
isOkToUseSystemPropertyDns(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isOkToUseSystemPropertyDns(DataCallState response) {
|
||||||
|
// Check if system property dns usable
|
||||||
|
boolean okToUseSystemPropertyDns = false;
|
||||||
|
String propertyPrefix = "net." + response.ifname + ".";
|
||||||
|
String dnsServers[] = new String[2];
|
||||||
|
dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
|
||||||
|
dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
|
||||||
|
okToUseSystemPropertyDns = isDnsOk(dnsServers);
|
||||||
|
return okToUseSystemPropertyDns;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean updateLinkProperty(DataCallState newState) {
|
||||||
|
boolean changed = false;
|
||||||
|
|
||||||
|
if (newState == null) return changed;
|
||||||
|
|
||||||
|
DataCallState.SetupResult result;
|
||||||
|
LinkProperties linkProperties = new LinkProperties();
|
||||||
|
|
||||||
|
// set link properties based on data call response
|
||||||
|
result = newState.setLinkProperties(linkProperties,
|
||||||
|
isOkToUseSystemPropertyDns(newState));
|
||||||
|
|
||||||
|
if (result != DataCallState.SetupResult.SUCCESS) {
|
||||||
|
log("updateLinkProperty failed : " + result);
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mLinkProperties != null) {
|
||||||
|
// Before comparison, copy HTTP proxy from the original
|
||||||
|
// as it is not part DataCallState.
|
||||||
|
linkProperties.setHttpProxy(mLinkProperties.getHttpProxy());
|
||||||
|
if (!mLinkProperties.equals(linkProperties)) {
|
||||||
|
mLinkProperties = linkProperties;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mLinkProperties = linkProperties;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parent state for all other states.
|
* The parent state for all other states.
|
||||||
*/
|
*/
|
||||||
@ -597,17 +631,24 @@ public abstract class DataConnection extends StateMachine {
|
|||||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_LINK_PROPERTIES_HTTP_PROXY);
|
mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_LINK_PROPERTIES_HTTP_PROXY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
|
||||||
|
DataCallState newState = (DataCallState) msg.obj;
|
||||||
|
int updated = updateLinkProperty(newState) ? 1 : 0;
|
||||||
|
if (DBG) {
|
||||||
|
log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE updated=" + updated +
|
||||||
|
" newState=" + newState);
|
||||||
|
}
|
||||||
|
mAc.replyToMessage(msg,
|
||||||
|
DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
|
||||||
|
updated);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
|
case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {
|
||||||
LinkCapabilities lc = new LinkCapabilities(mCapabilities);
|
LinkCapabilities lc = new LinkCapabilities(mCapabilities);
|
||||||
log("REQ_GET_LINK_CAPABILITIES linkCapabilities" + lc);
|
log("REQ_GET_LINK_CAPABILITIES linkCapabilities" + lc);
|
||||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_CAPABILITIES, lc);
|
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_CAPABILITIES, lc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
|
|
||||||
Bundle data = msg.getData();
|
|
||||||
mLinkProperties = (LinkProperties) data.get("linkProperties");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DataConnectionAc.REQ_RESET:
|
case DataConnectionAc.REQ_RESET:
|
||||||
if (DBG) log("DcDefaultState: msg.what=REQ_RESET");
|
if (DBG) log("DcDefaultState: msg.what=REQ_RESET");
|
||||||
clearSettings();
|
clearSettings();
|
||||||
|
@ -225,6 +225,38 @@ public class DataConnectionAc extends AsyncChannel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request update LinkProperties from DataCallState
|
||||||
|
* Response {@link #rspUpdateLinkPropertiesDataCallState}
|
||||||
|
*/
|
||||||
|
public void reqUpdateLinkPropertiesDataCallState(DataCallState newState) {
|
||||||
|
sendMessage(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
|
||||||
|
if (DBG) log("reqUpdateLinkPropertiesDataCallState");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean rspUpdateLinkPropertiesDataCallState(Message response) {
|
||||||
|
boolean retVal = response.arg1 == 1;
|
||||||
|
if (DBG) log("rspUpdateLinkPropertiesState=" + retVal);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update link properties in the data connection
|
||||||
|
*
|
||||||
|
* @return true if link property has been updated. false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean updateLinkPropertiesDataCallStateSync(DataCallState newState) {
|
||||||
|
Message response =
|
||||||
|
sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
|
||||||
|
if ((response != null) &&
|
||||||
|
(response.what == RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE)) {
|
||||||
|
return rspUpdateLinkPropertiesDataCallState(response);
|
||||||
|
} else {
|
||||||
|
log("getLinkProperties error response=" + response);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request the connections LinkCapabilities.
|
* Request the connections LinkCapabilities.
|
||||||
* Response {@link #rspLinkCapabilities}
|
* Response {@link #rspLinkCapabilities}
|
||||||
|
@ -178,6 +178,7 @@ public interface Phone {
|
|||||||
static final String REASON_NW_TYPE_CHANGED = "nwTypeChanged";
|
static final String REASON_NW_TYPE_CHANGED = "nwTypeChanged";
|
||||||
static final String REASON_DATA_DEPENDENCY_MET = "dependencyMet";
|
static final String REASON_DATA_DEPENDENCY_MET = "dependencyMet";
|
||||||
static final String REASON_DATA_DEPENDENCY_UNMET = "dependencyUnmet";
|
static final String REASON_DATA_DEPENDENCY_UNMET = "dependencyUnmet";
|
||||||
|
static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
|
||||||
|
|
||||||
// Used for band mode selection methods
|
// Used for band mode selection methods
|
||||||
static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
|
static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
|
||||||
|
@ -987,6 +987,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DataCallState findDataCallStateByCID (ArrayList<DataCallState> states, int cid) {
|
||||||
|
for (int i = 0, s = states.size() ; i < s ; i++) {
|
||||||
|
if (states.get(i).cid == cid) {
|
||||||
|
return states.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles changes to the APN database.
|
* Handles changes to the APN database.
|
||||||
*/
|
*/
|
||||||
@ -1090,6 +1099,19 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
|||||||
TelephonyManager.getDefault().getNetworkType());
|
TelephonyManager.getDefault().getNetworkType());
|
||||||
|
|
||||||
cleanUpConnection(true, apnContext);
|
cleanUpConnection(true, apnContext);
|
||||||
|
} else {
|
||||||
|
// Here, data call list has active cid for given ApnContext.
|
||||||
|
// Check if link property has been updated.
|
||||||
|
DataCallState state = findDataCallStateByCID(dataCallStates,
|
||||||
|
apnContext.getDataConnectionAc().getCidSync());
|
||||||
|
|
||||||
|
if ((dcac != null) && (state != null)){
|
||||||
|
if (dcac.updateLinkPropertiesDataCallStateSync(state)) {
|
||||||
|
// notify data change for this apn
|
||||||
|
mPhone.notifyDataConnection(Phone.REASON_LINK_PROPERTIES_CHANGED,
|
||||||
|
apnContext.getApnType());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user