Tear down connection with unwanted linkproperty change

Make sure to disconnect the link when RIL reported link property change
which could cause connectivity issue. (i.e. IP address)

Change-Id: I6601ef53e4561bdc7d2760d00e134b8431512cb2
This commit is contained in:
Wink Saville
2011-05-21 10:05:26 -07:00
parent 16e8d22b20
commit 15cd6ec250
3 changed files with 75 additions and 25 deletions

View File

@@ -22,8 +22,10 @@ import com.android.internal.util.Protocol;
import com.android.internal.util.State; import com.android.internal.util.State;
import com.android.internal.util.StateMachine; import com.android.internal.util.StateMachine;
import android.net.LinkAddress;
import android.net.LinkCapabilities; import android.net.LinkCapabilities;
import android.net.LinkProperties; import android.net.LinkProperties;
import android.net.NetworkUtils;
import android.net.ProxyProperties; import android.net.ProxyProperties;
import android.os.AsyncResult; import android.os.AsyncResult;
import android.os.Bundle; import android.os.Bundle;
@@ -33,6 +35,7 @@ import android.os.Parcelable;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.text.TextUtils; import android.text.TextUtils;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@@ -533,8 +536,10 @@ public abstract class DataConnection extends StateMachine {
return response.setLinkProperties(lp, okToUseSystemPropertyDns); return response.setLinkProperties(lp, okToUseSystemPropertyDns);
} }
private boolean updateLinkProperty(DataCallState newState) { private DataConnectionAc.LinkPropertyChangeAction updateLinkProperty(
boolean changed = false; DataCallState newState) {
DataConnectionAc.LinkPropertyChangeAction changed =
DataConnectionAc.LinkPropertyChangeAction.NONE;
if (newState == null) return changed; if (newState == null) return changed;
@@ -553,9 +558,23 @@ public abstract class DataConnection extends StateMachine {
if (DBG) log("old LP=" + mLinkProperties); if (DBG) log("old LP=" + mLinkProperties);
if (DBG) log("new LP=" + newLp); if (DBG) log("new LP=" + newLp);
// Check consistency of link address. Currently we expect
// only one "global" address is assigned per each IP type.
Collection<LinkAddress> oLinks = mLinkProperties.getLinkAddresses();
Collection<LinkAddress> nLinks = newLp.getLinkAddresses();
for (LinkAddress oldLink : oLinks) {
for (LinkAddress newLink : nLinks) {
if ((NetworkUtils.addressTypeMatches(oldLink.getAddress(),
newLink.getAddress())) &&
(oldLink.equals(newLink) == false)) {
return DataConnectionAc.LinkPropertyChangeAction.RESET;
}
}
}
if (mLinkProperties == null || !mLinkProperties.equals(newLp)) { if (mLinkProperties == null || !mLinkProperties.equals(newLp)) {
mLinkProperties = newLp; mLinkProperties = newLp;
changed = true; changed = DataConnectionAc.LinkPropertyChangeAction.CHANGED;
} }
return changed; return changed;
@@ -633,15 +652,14 @@ public abstract class DataConnection extends StateMachine {
} }
case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: { case DataConnectionAc.REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE: {
DataCallState newState = (DataCallState) msg.obj; DataCallState newState = (DataCallState) msg.obj;
int updated = updateLinkProperty(newState) ? 1 : 0; DataConnectionAc.LinkPropertyChangeAction action = updateLinkProperty(newState);
if (DBG) { if (DBG) {
log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE updated=" log("REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE action="
+ (updated == 1) + action + " newState=" + newState);
+ " newState=" + newState);
} }
mAc.replyToMessage(msg, mAc.replyToMessage(msg,
DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, DataConnectionAc.RSP_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE,
updated); action.ordinal());
break; break;
} }
case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: { case DataConnectionAc.REQ_GET_LINK_CAPABILITIES: {

View File

@@ -59,6 +59,26 @@ public class DataConnectionAc extends AsyncChannel {
public static final int REQ_RESET = BASE + 14; public static final int REQ_RESET = BASE + 14;
public static final int RSP_RESET = BASE + 15; public static final int RSP_RESET = BASE + 15;
/**
* enum used to notify action taken or necessary to be
* taken after the link property is changed.
*/
public enum LinkPropertyChangeAction {
NONE, CHANGED, RESET;
public static LinkPropertyChangeAction fromInt(int value) {
if (value == NONE.ordinal()) {
return NONE;
} else if (value == CHANGED.ordinal()) {
return CHANGED;
} else if (value == RESET.ordinal()) {
return RESET;
} else {
throw new RuntimeException("LinkPropertyChangeAction.fromInt: bad value=" + value);
}
}
}
public DataConnectionAc(DataConnection dc, String logTag) { public DataConnectionAc(DataConnection dc, String logTag) {
dataConnection = dc; dataConnection = dc;
mLogTag = logTag; mLogTag = logTag;
@@ -234,8 +254,8 @@ public class DataConnectionAc extends AsyncChannel {
if (DBG) log("reqUpdateLinkPropertiesDataCallState"); if (DBG) log("reqUpdateLinkPropertiesDataCallState");
} }
public boolean rspUpdateLinkPropertiesDataCallState(Message response) { public LinkPropertyChangeAction rspUpdateLinkPropertiesDataCallState(Message response) {
boolean retVal = response.arg1 == 1; LinkPropertyChangeAction retVal = LinkPropertyChangeAction.fromInt(response.arg1);
if (DBG) log("rspUpdateLinkPropertiesState=" + retVal); if (DBG) log("rspUpdateLinkPropertiesState=" + retVal);
return retVal; return retVal;
} }
@@ -245,7 +265,7 @@ public class DataConnectionAc extends AsyncChannel {
* *
* @return true if link property has been updated. false otherwise. * @return true if link property has been updated. false otherwise.
*/ */
public boolean updateLinkPropertiesDataCallStateSync(DataCallState newState) { public LinkPropertyChangeAction updateLinkPropertiesDataCallStateSync(DataCallState newState) {
Message response = Message response =
sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState); sendMessageSynchronously(REQ_UPDATE_LINK_PROPERTIES_DATA_CALL_STATE, newState);
if ((response != null) && if ((response != null) &&
@@ -253,7 +273,7 @@ public class DataConnectionAc extends AsyncChannel {
return rspUpdateLinkPropertiesDataCallState(response); return rspUpdateLinkPropertiesDataCallState(response);
} else { } else {
log("getLinkProperties error response=" + response); log("getLinkProperties error response=" + response);
return false; return LinkPropertyChangeAction.NONE;
} }
} }

View File

@@ -1059,25 +1059,37 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
if (DBG) log("onDataStateChanged(ar): Found ConnId=" + connectionId if (DBG) log("onDataStateChanged(ar): Found ConnId=" + connectionId
+ " newState=" + newState.toString()); + " newState=" + newState.toString());
if (newState.active != 0) { if (newState.active != 0) {
boolean changed boolean resetConnection;
= dcac.updateLinkPropertiesDataCallStateSync(newState); switch (dcac.updateLinkPropertiesDataCallStateSync(newState)) {
if (changed) { case NONE:
if (DBG) log("onDataStateChanged(ar): Found but no change, skip");
resetConnection = false;
break;
case CHANGED:
if (DBG) log("onDataStateChanged(ar): Found and changed, notify"); if (DBG) log("onDataStateChanged(ar): Found and changed, notify");
mPhone.notifyDataConnection(Phone.REASON_LINK_PROPERTIES_CHANGED, mPhone.notifyDataConnection(Phone.REASON_LINK_PROPERTIES_CHANGED,
apnContext.getApnType()); apnContext.getApnType());
// Temporary hack, if false we'll reset connections and at this // Temporary hack, at this time a transition from CDMA -> Global
// time a transition from CDMA -> Global fails. The DEACTIVATE // fails so we'll hope for the best and not reset the connection.
// fails with a GENERIC_FAILURE and the VZWINTERNET connection is // @see bug/4455071
// never setup. @see bug/
if (SystemProperties.getBoolean("telephony.ignore-state-changes", if (SystemProperties.getBoolean("telephony.ignore-state-changes",
true)) { true)) {
log("onDataStateChanged(ar): STOPSHIP don't reset, continue"); log("onDataStateChanged(ar): STOPSHIP don't reset, continue");
continue; resetConnection = false;
} else {
// Things changed so reset connection, when hack is removed
// this is the normal path.
log("onDataStateChanged(ar): changed so resetting connection");
resetConnection = true;
} }
} else { break;
if (DBG) log("onDataStateChanged(ar): Found but no change, skip"); case RESET:
continue; default:
if (DBG) log("onDataStateChanged(ar): an error, reset connection");
resetConnection = true;
break;
} }
if (resetConnection == false) continue;
} }
} }