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);
|
||||
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().
|
||||
equals(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED)) {
|
||||
|
@ -1391,6 +1391,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
} else {
|
||||
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 {
|
||||
if (mNetConfigs[netType].isDefault()) {
|
||||
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) {
|
||||
Slog.d(TAG, s);
|
||||
}
|
||||
|
@ -668,6 +668,16 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
||||
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 {
|
||||
// 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;
|
||||
// we don't have a valid upstream conn, check again after a delay
|
||||
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
|
||||
// sends itself a delayed timeout event and handles incoming timeout events
|
||||
@ -1429,13 +1441,18 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
|
||||
turnOnMobileConnection();
|
||||
}
|
||||
break;
|
||||
case CMD_RETRY_UPSTREAM:
|
||||
chooseUpstreamType(mTryCell);
|
||||
mTryCell = !mTryCell;
|
||||
break;
|
||||
default:
|
||||
retValue = false;
|
||||
break;
|
||||
case CMD_RETRY_UPSTREAM:
|
||||
chooseUpstreamType(mTryCell);
|
||||
mTryCell = !mTryCell;
|
||||
break;
|
||||
case CMD_IFACE_CHANGED:
|
||||
String iface = (String)message.obj;
|
||||
if (DEBUG) Log.d(TAG, "Activie upstream interface changed: " + iface);
|
||||
notifyTetheredOfNewUpstreamIface(iface);
|
||||
break;
|
||||
default:
|
||||
retValue = false;
|
||||
break;
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
|
@ -509,24 +509,58 @@ public abstract class DataConnection extends StateMachine {
|
||||
result.mFailCause = FailCause.fromInt(response.status);
|
||||
} else {
|
||||
log("onSetupConnectionCompleted received DataCallState: " + response);
|
||||
|
||||
// Check if system property dns usable
|
||||
boolean okToUseSystemPropertyDns = false;
|
||||
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
|
||||
result = response.setLinkProperties(mLinkProperties,
|
||||
okToUseSystemPropertyDns);
|
||||
isOkToUseSystemPropertyDns(response));
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
@ -597,17 +631,24 @@ public abstract class DataConnection extends StateMachine {
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_SET_LINK_PROPERTIES_HTTP_PROXY);
|
||||
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: {
|
||||
LinkCapabilities lc = new LinkCapabilities(mCapabilities);
|
||||
log("REQ_GET_LINK_CAPABILITIES linkCapabilities" + lc);
|
||||
mAc.replyToMessage(msg, DataConnectionAc.RSP_GET_LINK_CAPABILITIES, lc);
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
|
||||
Bundle data = msg.getData();
|
||||
mLinkProperties = (LinkProperties) data.get("linkProperties");
|
||||
break;
|
||||
}
|
||||
case DataConnectionAc.REQ_RESET:
|
||||
if (DBG) log("DcDefaultState: msg.what=REQ_RESET");
|
||||
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.
|
||||
* Response {@link #rspLinkCapabilities}
|
||||
|
@ -178,6 +178,7 @@ public interface Phone {
|
||||
static final String REASON_NW_TYPE_CHANGED = "nwTypeChanged";
|
||||
static final String REASON_DATA_DEPENDENCY_MET = "dependencyMet";
|
||||
static final String REASON_DATA_DEPENDENCY_UNMET = "dependencyUnmet";
|
||||
static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
|
||||
|
||||
// Used for band mode selection methods
|
||||
static final int BM_UNSPECIFIED = 0; // selected by baseband automatically
|
||||
|
@ -987,6 +987,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
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.
|
||||
*/
|
||||
@ -1090,6 +1099,19 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
TelephonyManager.getDefault().getNetworkType());
|
||||
|
||||
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