Merge change Ia834022d
* changes: Convert DataConnection to an HSM and rename PdpConnection to GsmDataConnection.
This commit is contained in:
@@ -16,43 +16,137 @@
|
||||
|
||||
package com.android.internal.telephony;
|
||||
|
||||
import com.android.internal.telephony.gsm.ApnSetting;
|
||||
|
||||
import com.android.internal.util.HierarchicalState;
|
||||
import com.android.internal.util.HierarchicalStateMachine;
|
||||
|
||||
import android.os.AsyncResult;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.EventLog;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*
|
||||
* DataConnection HierarchicalStateMachine.
|
||||
*
|
||||
* This is an abstract base class for representing a single data connection.
|
||||
* Instances of this class such as <code>CdmaDataConnection</code> and
|
||||
* <code>GsmDataConnection</code>, * represent a connection via the cellular network.
|
||||
* There may be multiple data connections and all of them are managed by the
|
||||
* <code>DataConnectionTracker</code>.
|
||||
*
|
||||
* Instances are asynchronous state machines and have two primary entry points
|
||||
* <code>connect()</code> and <code>disconnect</code>. The message a parameter will be returned
|
||||
* hen the operation completes. The <code>msg.obj</code> will contain an AsyncResult
|
||||
* object and <code>AsyncResult.userObj</code> is the original <code>msg.obj</code>. if successful
|
||||
* with the <code>AsyncResult.result == null</code> and <code>AsyncResult.exception == null</code>.
|
||||
* If an error <code>AsyncResult.result = FailCause</code> and
|
||||
* <code>AsyncResult.exception = new Exception()</code>.
|
||||
*
|
||||
* The other public methods are provided for debugging.
|
||||
*
|
||||
* Below is the state machine description for this class.
|
||||
*
|
||||
* DataConnection {
|
||||
* + mDefaultState {
|
||||
* EVENT_RESET { clearSettings, >mInactiveState }.
|
||||
* EVENT_CONNECT { notifyConnectCompleted(FailCause.UNKNOWN) }.
|
||||
* EVENT_DISCONNECT { notifyDisconnectCompleted }.
|
||||
*
|
||||
* // Ignored messages
|
||||
* EVENT_SETUP_DATA_CONNECTION_DONE,
|
||||
* EVENT_GET_LAST_FAIL_DONE,
|
||||
* EVENT_DEACTIVATE_DONE.
|
||||
* }
|
||||
* ++ # mInactiveState {
|
||||
* EVENT_RESET.
|
||||
* EVENT_CONNECT {startConnecting, >mActivatingState }.
|
||||
* }
|
||||
* ++ mActivatingState {
|
||||
* EVENT_DISCONNECT { %EVENT_DISCONNECT }.
|
||||
* EVENT_SETUP_DATA_CONNECTION_DONE {
|
||||
* if (SUCCESS) { notifyConnectCompleted(FailCause.NONE), >mActiveState }.
|
||||
* if (ERR_BadCommand) {
|
||||
* notifyConnectCompleted(FailCause.UNKNOWN), >mInactiveState }.
|
||||
* if (ERR_BadDns) { tearDownData($DEACTIVATE_DONE), >mDisconnectingBadDnsState }.
|
||||
* if (ERR_Other) { getLastDataCallFailCause($EVENT_GET_LAST_FAIL_DONE) }.
|
||||
* if (ERR_Stale) {}.
|
||||
* }
|
||||
* EVENT_GET_LAST_FAIL_DONE { notifyConnectCompleted(result), >mInactive }.
|
||||
* }
|
||||
* ++ mActiveState {
|
||||
* EVENT_DISCONNECT { tearDownData($EVENT_DEACTIVATE_DONE), >mDisconnecting }.
|
||||
* }
|
||||
* ++ mDisconnectingState {
|
||||
* EVENT_DEACTIVATE_DONE { notifyDisconnectCompleted, >mInactiveState }.
|
||||
* }
|
||||
* ++ mDisconnectingBadDnsState {
|
||||
* EVENT_DEACTIVATE_DONE { notifyConnectComplete(FailCause.UNKNOWN), >mInactiveState }.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public abstract class DataConnection extends Handler {
|
||||
public abstract class DataConnection extends HierarchicalStateMachine {
|
||||
protected static final boolean DBG = true;
|
||||
|
||||
// the inherited class
|
||||
protected static Object mCountLock = new Object();
|
||||
protected static int mCount;
|
||||
|
||||
public enum State {
|
||||
ACTIVE, /* has active data connection */
|
||||
ACTIVATING, /* during connecting process */
|
||||
INACTIVE; /* has empty data connection */
|
||||
/**
|
||||
* Class returned by onSetupConnectionCompleted.
|
||||
*/
|
||||
protected enum SetupResult {
|
||||
ERR_BadCommand,
|
||||
ERR_BadDns,
|
||||
ERR_Other,
|
||||
ERR_Stale,
|
||||
SUCCESS;
|
||||
|
||||
public FailCause mFailCause;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case ACTIVE:
|
||||
return "active";
|
||||
case ACTIVATING:
|
||||
return "setting up";
|
||||
default:
|
||||
return "inactive";
|
||||
case ERR_BadCommand: return "Bad Command";
|
||||
case ERR_BadDns: return "Bad DNS";
|
||||
case ERR_Other: return "Other error";
|
||||
case ERR_Stale: return "Stale command";
|
||||
case SUCCESS: return "SUCCESS";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this == ACTIVE;
|
||||
}
|
||||
|
||||
public boolean isInactive() {
|
||||
return this == INACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally for saving connecting parameters.
|
||||
*/
|
||||
protected static class ConnectionParams {
|
||||
public ConnectionParams(ApnSetting apn, Message onCompletedMsg) {
|
||||
this.apn = apn;
|
||||
this.onCompletedMsg = onCompletedMsg;
|
||||
}
|
||||
|
||||
public int tag;
|
||||
public ApnSetting apn;
|
||||
public Message onCompletedMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally for saving disconnecting parameters.
|
||||
*/
|
||||
protected static class DisconnectParams {
|
||||
public DisconnectParams(Message onCompletedMsg) {
|
||||
this.onCompletedMsg = onCompletedMsg;
|
||||
}
|
||||
|
||||
public int tag;
|
||||
public Message onCompletedMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returned as the reason for a connection failure.
|
||||
*/
|
||||
public enum FailCause {
|
||||
NONE,
|
||||
OPERATOR_BARRED,
|
||||
@@ -71,8 +165,7 @@ public abstract class DataConnection extends Handler {
|
||||
GPRS_REGISTRATION_FAIL,
|
||||
UNKNOWN,
|
||||
|
||||
RADIO_NOT_AVAILABLE,
|
||||
RADIO_ERROR_RETRY;
|
||||
RADIO_NOT_AVAILABLE;
|
||||
|
||||
public boolean isPermanentFail() {
|
||||
return (this == OPERATOR_BARRED) || (this == MISSING_UKNOWN_APN) ||
|
||||
@@ -128,117 +221,139 @@ public abstract class DataConnection extends Handler {
|
||||
return "Data Network Registration Failure";
|
||||
case RADIO_NOT_AVAILABLE:
|
||||
return "Radio Not Available";
|
||||
case RADIO_ERROR_RETRY:
|
||||
return "Transient Radio Rrror";
|
||||
default:
|
||||
return "Unknown Data Error";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ***** Event codes
|
||||
protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = 1;
|
||||
protected static final int EVENT_GET_LAST_FAIL_DONE = 2;
|
||||
protected static final int EVENT_LINK_STATE_CHANGED = 3;
|
||||
protected static final int EVENT_DEACTIVATE_DONE = 4;
|
||||
protected static final int EVENT_FORCE_RETRY = 5;
|
||||
// ***** Event codes for driving the state machine
|
||||
protected static final int EVENT_RESET = 1;
|
||||
protected static final int EVENT_CONNECT = 2;
|
||||
protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = 3;
|
||||
protected static final int EVENT_GET_LAST_FAIL_DONE = 4;
|
||||
protected static final int EVENT_DEACTIVATE_DONE = 5;
|
||||
protected static final int EVENT_DISCONNECT = 6;
|
||||
|
||||
//***** Tag IDs for EventLog
|
||||
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
|
||||
|
||||
|
||||
//***** Member Variables
|
||||
protected int mTag;
|
||||
protected PhoneBase phone;
|
||||
protected Message onConnectCompleted;
|
||||
protected Message onDisconnect;
|
||||
protected int cid;
|
||||
protected String interfaceName;
|
||||
protected String ipAddress;
|
||||
protected String gatewayAddress;
|
||||
protected String[] dnsServers;
|
||||
protected State state;
|
||||
protected long createTime;
|
||||
protected long lastFailTime;
|
||||
protected FailCause lastFailCause;
|
||||
protected static final String NULL_IP = "0.0.0.0";
|
||||
Object userData;
|
||||
|
||||
// receivedDisconnectReq is set when disconnect during activation
|
||||
protected boolean receivedDisconnectReq;
|
||||
//***** Abstract methods
|
||||
public abstract String toString();
|
||||
|
||||
/* Instance Methods */
|
||||
protected abstract void onSetupConnectionCompleted(AsyncResult ar);
|
||||
|
||||
protected abstract void onDeactivated(AsyncResult ar);
|
||||
|
||||
protected abstract void disconnect(Message msg);
|
||||
|
||||
protected abstract void notifyFail(FailCause cause, Message onCompleted);
|
||||
|
||||
protected abstract void notifyDisconnect(Message msg);
|
||||
|
||||
protected abstract void onLinkStateChanged(DataLink.LinkState linkState);
|
||||
protected abstract void onConnect(ConnectionParams cp);
|
||||
|
||||
protected abstract FailCause getFailCauseFromRequest(int rilCause);
|
||||
|
||||
public abstract String toString();
|
||||
protected abstract boolean isDnsOk(String[] domainNameServers);
|
||||
|
||||
protected abstract void log(String s);
|
||||
|
||||
|
||||
//***** Constructor
|
||||
protected DataConnection(PhoneBase phone) {
|
||||
super();
|
||||
protected DataConnection(PhoneBase phone, String name) {
|
||||
super(name);
|
||||
if (DBG) log("DataConnection constructor E");
|
||||
this.phone = phone;
|
||||
onConnectCompleted = null;
|
||||
onDisconnect = null;
|
||||
this.cid = -1;
|
||||
receivedDisconnectReq = false;
|
||||
this.dnsServers = new String[2];
|
||||
|
||||
clearSettings();
|
||||
|
||||
setDbg(true);
|
||||
addState(mDefaultState);
|
||||
addState(mInactiveState, mDefaultState);
|
||||
addState(mActivatingState, mDefaultState);
|
||||
addState(mActiveState, mDefaultState);
|
||||
addState(mDisconnectingState, mDefaultState);
|
||||
addState(mDisconnectingBadDnsState, mDefaultState);
|
||||
setInitialState(mInactiveState);
|
||||
if (DBG) log("DataConnection constructor X");
|
||||
}
|
||||
|
||||
/**
|
||||
* TearDown the data connection.
|
||||
*
|
||||
* @param o will be returned in AsyncResult.userObj
|
||||
* and is either a DisconnectParams or ConnectionParams.
|
||||
*/
|
||||
private void tearDownData(Object o) {
|
||||
if (phone.mCM.getRadioState().isOn()) {
|
||||
if (DBG) log("tearDownData radio is on, call deactivateDataCall");
|
||||
phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, o));
|
||||
} else {
|
||||
if (DBG) log("tearDownData radio is off sendMessage EVENT_DEACTIVATE_DONE immediately");
|
||||
sendMessage(obtainMessage(EVENT_DEACTIVATE_DONE, o));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the connectionCompletedMsg.
|
||||
*
|
||||
* @param cp is the ConnectionParams
|
||||
* @param cause
|
||||
*/
|
||||
private void notifyConnectCompleted(ConnectionParams cp, FailCause cause) {
|
||||
Message connectionCompletedMsg = cp.onCompletedMsg;
|
||||
if (connectionCompletedMsg == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
long timeStamp = System.currentTimeMillis();
|
||||
connectionCompletedMsg.arg1 = cid;
|
||||
|
||||
if (cause == FailCause.NONE) {
|
||||
createTime = timeStamp;
|
||||
AsyncResult.forMessage(connectionCompletedMsg);
|
||||
} else {
|
||||
lastFailCause = cause;
|
||||
lastFailTime = timeStamp;
|
||||
AsyncResult.forMessage(connectionCompletedMsg, cause, new Exception());
|
||||
}
|
||||
if (DBG) log("notifyConnection at " + timeStamp + " cause=" + cause);
|
||||
|
||||
connectionCompletedMsg.sendToTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send ar.userObj if its a message, which is should be back to originator.
|
||||
*
|
||||
* @param dp is the DisconnectParams.
|
||||
*/
|
||||
private void notifyDisconnectCompleted(DisconnectParams dp) {
|
||||
if (DBG) log("NotifyDisconnectCompleted");
|
||||
|
||||
Message msg = dp.onCompletedMsg;
|
||||
AsyncResult.forMessage(msg);
|
||||
msg.sendToTarget();
|
||||
|
||||
clearSettings();
|
||||
}
|
||||
|
||||
protected void setHttpProxy(String httpProxy, String httpPort) {
|
||||
if (httpProxy == null || httpProxy.length() == 0) {
|
||||
phone.setSystemProperty("net.gprs.http-proxy", null);
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Clear all settings called when entering mInactiveState.
|
||||
*/
|
||||
protected void clearSettings() {
|
||||
if (DBG) log("clearSettings");
|
||||
|
||||
if (httpPort == null || httpPort.length() == 0) {
|
||||
httpPort = "8080"; // Default to port 8080
|
||||
}
|
||||
|
||||
phone.setSystemProperty("net.gprs.http-proxy",
|
||||
"http://" + httpProxy + ":" + httpPort + "/");
|
||||
}
|
||||
|
||||
public String getInterface() {
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public String getGatewayAddress() {
|
||||
return gatewayAddress;
|
||||
}
|
||||
|
||||
public String[] getDnsServers() {
|
||||
return dnsServers;
|
||||
}
|
||||
|
||||
public void clearSettings() {
|
||||
log("DataConnection.clearSettings()");
|
||||
|
||||
this.state = State.INACTIVE;
|
||||
this.createTime = -1;
|
||||
this.lastFailTime = -1;
|
||||
this.lastFailCause = FailCause.NONE;
|
||||
|
||||
receivedDisconnectReq = false;
|
||||
onConnectCompleted = null;
|
||||
interfaceName = null;
|
||||
ipAddress = null;
|
||||
gatewayAddress = null;
|
||||
@@ -246,80 +361,433 @@ public abstract class DataConnection extends Handler {
|
||||
dnsServers[1] = null;
|
||||
}
|
||||
|
||||
protected void onGetLastFailCompleted(AsyncResult ar) {
|
||||
if (receivedDisconnectReq) {
|
||||
// Don't bother reporting the error if there's already a
|
||||
// pending disconnect request, since DataConnectionTracker
|
||||
// has already updated its state.
|
||||
notifyDisconnect(onDisconnect);
|
||||
} else {
|
||||
FailCause cause = FailCause.UNKNOWN;
|
||||
/**
|
||||
* Process setup completion.
|
||||
*
|
||||
* @param ar is the result
|
||||
* @return SetupResult.
|
||||
*/
|
||||
private SetupResult onSetupConnectionCompleted(AsyncResult ar) {
|
||||
SetupResult result;
|
||||
String[] response = ((String[]) ar.result);
|
||||
ConnectionParams cp = (ConnectionParams) ar.userObj;
|
||||
|
||||
if (ar.exception == null) {
|
||||
int rilFailCause = ((int[]) (ar.result))[0];
|
||||
cause = getFailCauseFromRequest(rilFailCause);
|
||||
if (ar.exception != null) {
|
||||
if (DBG) log("DataConnection Init failed " + ar.exception);
|
||||
|
||||
if (ar.exception instanceof CommandException
|
||||
&& ((CommandException) (ar.exception)).getCommandError()
|
||||
== CommandException.Error.RADIO_NOT_AVAILABLE) {
|
||||
result = SetupResult.ERR_BadCommand;
|
||||
result.mFailCause = FailCause.RADIO_NOT_AVAILABLE;
|
||||
} else {
|
||||
result = SetupResult.ERR_Other;
|
||||
}
|
||||
notifyFail(cause, onConnectCompleted);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onForceRetry() {
|
||||
if (receivedDisconnectReq) {
|
||||
notifyDisconnect(onDisconnect);
|
||||
} else if (cp.tag != mTag) {
|
||||
if (DBG) {
|
||||
log("BUG: onSetupConnectionCompleted is stale cp.tag=" + cp.tag + ", mtag=" + mTag);
|
||||
}
|
||||
result = SetupResult.ERR_Stale;
|
||||
} else {
|
||||
notifyFail(FailCause.RADIO_ERROR_RETRY, onConnectCompleted);
|
||||
cid = Integer.parseInt(response[0]);
|
||||
if (response.length > 2) {
|
||||
interfaceName = response[1];
|
||||
ipAddress = response[2];
|
||||
String prefix = "net." + interfaceName + ".";
|
||||
gatewayAddress = SystemProperties.get(prefix + "gw");
|
||||
dnsServers[0] = SystemProperties.get(prefix + "dns1");
|
||||
dnsServers[1] = SystemProperties.get(prefix + "dns2");
|
||||
if (DBG) {
|
||||
log("interface=" + interfaceName + " ipAddress=" + ipAddress
|
||||
+ " gateway=" + gatewayAddress + " DNS1=" + dnsServers[0]
|
||||
+ " DNS2=" + dnsServers[1]);
|
||||
}
|
||||
|
||||
if (isDnsOk(dnsServers)) {
|
||||
result = SetupResult.SUCCESS;
|
||||
} else {
|
||||
result = SetupResult.ERR_BadDns;
|
||||
}
|
||||
} else {
|
||||
result = SetupResult.ERR_Other;
|
||||
}
|
||||
}
|
||||
|
||||
if (DBG) log("DataConnection setup result=" + result + " on cid = " + cid);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* The parent state for all other states.
|
||||
*/
|
||||
private class DcDefaultState extends HierarchicalState {
|
||||
@Override
|
||||
protected boolean processMessage(Message msg) {
|
||||
AsyncResult ar;
|
||||
|
||||
switch (msg.what) {
|
||||
case EVENT_RESET:
|
||||
if (DBG) log("DcDefaultState: msg.what=EVENT_RESET");
|
||||
clearSettings();
|
||||
transitionTo(mInactiveState);
|
||||
break;
|
||||
|
||||
case EVENT_CONNECT:
|
||||
if (DBG) log("DcDefaultState: msg.what=EVENT_CONNECT, fail not expected");
|
||||
ConnectionParams cp = (ConnectionParams) msg.obj;
|
||||
notifyConnectCompleted(cp, FailCause.UNKNOWN);
|
||||
break;
|
||||
|
||||
case EVENT_DISCONNECT:
|
||||
if (DBG) log("DcDefaultState: msg.what=EVENT_DISCONNECT");
|
||||
notifyDisconnectCompleted((DisconnectParams) msg.obj);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) {
|
||||
log("DcDefaultState: shouldn't happen but ignore msg.what=" + msg.what);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
private DcDefaultState mDefaultState = new DcDefaultState();
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
AsyncResult ar;
|
||||
/**
|
||||
* The state machine is inactive and expects a EVENT_CONNECT.
|
||||
*/
|
||||
private class DcInactiveState extends HierarchicalState {
|
||||
@Override protected void enter() {
|
||||
mTag += 1;
|
||||
}
|
||||
@Override protected boolean processMessage(Message msg) {
|
||||
boolean retVal;
|
||||
|
||||
log("DataConnection.handleMessage()");
|
||||
switch (msg.what) {
|
||||
case EVENT_RESET:
|
||||
if (DBG) {
|
||||
log("DcInactiveState: msg.what=EVENT_RESET, ignore we're already reset");
|
||||
}
|
||||
retVal = true;
|
||||
break;
|
||||
|
||||
switch (msg.what) {
|
||||
case EVENT_CONNECT:
|
||||
if (DBG) log("DcInactiveState msg.what=EVENT_CONNECT");
|
||||
ConnectionParams cp = (ConnectionParams) msg.obj;
|
||||
cp.tag = mTag;
|
||||
onConnect(cp);
|
||||
transitionTo(mActivatingState);
|
||||
retVal = true;
|
||||
break;
|
||||
|
||||
case EVENT_SETUP_DATA_CONNECTION_DONE:
|
||||
onSetupConnectionCompleted((AsyncResult) msg.obj);
|
||||
break;
|
||||
|
||||
case EVENT_FORCE_RETRY:
|
||||
onForceRetry();
|
||||
break;
|
||||
|
||||
case EVENT_GET_LAST_FAIL_DONE:
|
||||
onGetLastFailCompleted((AsyncResult) msg.obj);
|
||||
break;
|
||||
|
||||
case EVENT_LINK_STATE_CHANGED:
|
||||
ar = (AsyncResult) msg.obj;
|
||||
DataLink.LinkState ls = (DataLink.LinkState) ar.result;
|
||||
onLinkStateChanged(ls);
|
||||
break;
|
||||
|
||||
case EVENT_DEACTIVATE_DONE:
|
||||
onDeactivated((AsyncResult) msg.obj);
|
||||
break;
|
||||
default:
|
||||
if (DBG) log("DcInactiveState nothandled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
private DcInactiveState mInactiveState = new DcInactiveState();
|
||||
|
||||
public State getState() {
|
||||
log("DataConnection.getState()");
|
||||
return state;
|
||||
/**
|
||||
* The state machine is activating a connection.
|
||||
*/
|
||||
private class DcActivatingState extends HierarchicalState {
|
||||
@Override protected boolean processMessage(Message msg) {
|
||||
boolean retVal;
|
||||
AsyncResult ar;
|
||||
ConnectionParams cp;
|
||||
|
||||
switch (msg.what) {
|
||||
case EVENT_DISCONNECT:
|
||||
if (DBG) log("DcActivatingState deferring msg.what=EVENT_DISCONNECT");
|
||||
deferMessage(msg);
|
||||
retVal = true;
|
||||
break;
|
||||
|
||||
case EVENT_SETUP_DATA_CONNECTION_DONE:
|
||||
if (DBG) log("DcActivatingState msg.what=EVENT_SETUP_DATA_CONNECTION_DONE");
|
||||
|
||||
ar = (AsyncResult) msg.obj;
|
||||
cp = (ConnectionParams) ar.userObj;
|
||||
|
||||
SetupResult result = onSetupConnectionCompleted(ar);
|
||||
switch (result) {
|
||||
case SUCCESS:
|
||||
// All is well
|
||||
notifyConnectCompleted(cp, FailCause.NONE);
|
||||
transitionTo(mActiveState);
|
||||
break;
|
||||
case ERR_BadCommand:
|
||||
// Vendor ril rejected the command and didn't connect.
|
||||
notifyConnectCompleted(cp, result.mFailCause);
|
||||
transitionTo(mInactiveState);
|
||||
break;
|
||||
case ERR_BadDns:
|
||||
// Connection succeeded but DNS info is bad so disconnect
|
||||
EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_BAD_DNS_ADDRESS,
|
||||
dnsServers[0]);
|
||||
tearDownData(cp);
|
||||
transitionTo(mDisconnectingBadDnsState);
|
||||
break;
|
||||
case ERR_Other:
|
||||
// Request the failure cause and process in this state
|
||||
phone.mCM.getLastDataCallFailCause(
|
||||
obtainMessage(EVENT_GET_LAST_FAIL_DONE, cp));
|
||||
break;
|
||||
case ERR_Stale:
|
||||
// Request is stale, ignore.
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unkown SetupResult, should not happen");
|
||||
}
|
||||
retVal = true;
|
||||
break;
|
||||
|
||||
case EVENT_GET_LAST_FAIL_DONE:
|
||||
ar = (AsyncResult) msg.obj;
|
||||
cp = (ConnectionParams) ar.userObj;
|
||||
FailCause cause = FailCause.UNKNOWN;
|
||||
|
||||
if (cp.tag == mTag) {
|
||||
if (DBG) log("DcActivatingState msg.what=EVENT_GET_LAST_FAIL_DONE");
|
||||
if (ar.exception == null) {
|
||||
int rilFailCause = ((int[]) (ar.result))[0];
|
||||
cause = getFailCauseFromRequest(rilFailCause);
|
||||
}
|
||||
notifyConnectCompleted(cp, cause);
|
||||
transitionTo(mInactiveState);
|
||||
} else {
|
||||
if (DBG) {
|
||||
log("DcActivatingState EVENT_GET_LAST_FAIL_DONE is stale cp.tag="
|
||||
+ cp.tag + ", mTag=" + mTag);
|
||||
}
|
||||
}
|
||||
|
||||
retVal = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) log("DcActivatingState not handled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
private DcActivatingState mActivatingState = new DcActivatingState();
|
||||
|
||||
/**
|
||||
* The state machine is connected, expecting an EVENT_DISCONNECT.
|
||||
*/
|
||||
private class DcActiveState extends HierarchicalState {
|
||||
@Override protected boolean processMessage(Message msg) {
|
||||
boolean retVal;
|
||||
|
||||
switch (msg.what) {
|
||||
case EVENT_DISCONNECT:
|
||||
if (DBG) log("DcActiveState msg.what=EVENT_DISCONNECT");
|
||||
DisconnectParams dp = (DisconnectParams) msg.obj;
|
||||
dp.tag = mTag;
|
||||
tearDownData(dp);
|
||||
transitionTo(mDisconnectingState);
|
||||
retVal = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) log("DcActiveState nothandled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
private DcActiveState mActiveState = new DcActiveState();
|
||||
|
||||
/**
|
||||
* The state machine is disconnecting.
|
||||
*/
|
||||
private class DcDisconnectingState extends HierarchicalState {
|
||||
@Override protected boolean processMessage(Message msg) {
|
||||
boolean retVal;
|
||||
|
||||
switch (msg.what) {
|
||||
case EVENT_DEACTIVATE_DONE:
|
||||
if (DBG) log("DcDisconnectingState msg.what=EVENT_DEACTIVATE_DONE");
|
||||
AsyncResult ar = (AsyncResult) msg.obj;
|
||||
DisconnectParams dp = (DisconnectParams) ar.userObj;
|
||||
if (dp.tag == mTag) {
|
||||
notifyDisconnectCompleted((DisconnectParams) ar.userObj);
|
||||
transitionTo(mInactiveState);
|
||||
} else {
|
||||
if (DBG) log("DcDisconnectState EVENT_DEACTIVATE_DONE stale dp.tag="
|
||||
+ dp.tag + " mTag=" + mTag);
|
||||
}
|
||||
retVal = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) log("DcDisconnectingState not handled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
private DcDisconnectingState mDisconnectingState = new DcDisconnectingState();
|
||||
|
||||
/**
|
||||
* The state machine is disconnecting after a bad dns setup
|
||||
* was found in mInactivatingState.
|
||||
*/
|
||||
private class DcDisconnectingBadDnsState extends HierarchicalState {
|
||||
@Override protected boolean processMessage(Message msg) {
|
||||
boolean retVal;
|
||||
|
||||
switch (msg.what) {
|
||||
case EVENT_DEACTIVATE_DONE:
|
||||
AsyncResult ar = (AsyncResult) msg.obj;
|
||||
ConnectionParams cp = (ConnectionParams) ar.userObj;
|
||||
if (cp.tag == mTag) {
|
||||
if (DBG) log("DcDisconnectingBadDnsState msg.what=EVENT_DEACTIVATE_DONE");
|
||||
notifyConnectCompleted(cp, FailCause.UNKNOWN);
|
||||
transitionTo(mInactiveState);
|
||||
} else {
|
||||
if (DBG) log("DcDisconnectingBadDnsState EVENT_DEACTIVE_DONE stale dp.tag="
|
||||
+ cp.tag + ", mTag=" + mTag);
|
||||
}
|
||||
retVal = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DBG) log("DcDisconnectingBadDnsState not handled msg.what=" + msg.what);
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
private DcDisconnectingBadDnsState mDisconnectingBadDnsState = new DcDisconnectingBadDnsState();
|
||||
|
||||
// ******* public interface
|
||||
|
||||
/**
|
||||
* Disconnect from the network.
|
||||
*/
|
||||
public void reset() {
|
||||
sendMessage(obtainMessage(EVENT_RESET));
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the apn and return an AsyncResult in onCompletedMsg.
|
||||
* Used for cellular networks that use Acess Point Names (APN) such
|
||||
* as GSM networks.
|
||||
*
|
||||
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
|
||||
* With AsyncResult.userObj set to the original msg.obj,
|
||||
* AsyncResult.result = FailCause and AsyncResult.exception = Exception().
|
||||
* @param apn is the Acces Point Name to connect to
|
||||
*/
|
||||
public void connect(Message onCompletedMsg, ApnSetting apn) {
|
||||
sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, onCompletedMsg)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to the apn and return an AsyncResult in onCompletedMsg.
|
||||
*
|
||||
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
|
||||
* With AsyncResult.userObj set to the original msg.obj,
|
||||
* AsyncResult.result = FailCause and AsyncResult.exception = Exception().
|
||||
*/
|
||||
public void connect(Message onCompletedMsg) {
|
||||
sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(null, onCompletedMsg)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from the network.
|
||||
*
|
||||
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
|
||||
* With AsyncResult.userObj set to the original msg.obj.
|
||||
*/
|
||||
public void disconnect(Message onCompletedMsg) {
|
||||
sendMessage(obtainMessage(EVENT_DISCONNECT, new DisconnectParams(onCompletedMsg)));
|
||||
}
|
||||
|
||||
// ****** The following are used for debugging.
|
||||
|
||||
/**
|
||||
* @return true if the state machine is in the inactive state.
|
||||
*/
|
||||
public boolean isInactive() {
|
||||
boolean retVal = getCurrentState() == mInactiveState;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the state machine is in the inactive state.
|
||||
*/
|
||||
public boolean isActive() {
|
||||
boolean retVal = getCurrentState() == mActiveState;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the interface name as a string.
|
||||
*/
|
||||
public String getInterface() {
|
||||
return interfaceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ip address as a string.
|
||||
*/
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the gateway address as a string.
|
||||
*/
|
||||
public String getGatewayAddress() {
|
||||
return gatewayAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an array of associated DNS addresses.
|
||||
*/
|
||||
public String[] getDnsServers() {
|
||||
return dnsServers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current state as a string.
|
||||
*/
|
||||
public String getStateAsString() {
|
||||
String retVal = getCurrentState().getName();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time of when this connection was created.
|
||||
*/
|
||||
public long getConnectionTime() {
|
||||
log("DataConnection.getConnectionTime()");
|
||||
return createTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time of the last failure.
|
||||
*/
|
||||
public long getLastFailTime() {
|
||||
log("DataConnection.getLastFailTime()");
|
||||
return lastFailTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last cause of failure.
|
||||
*/
|
||||
public FailCause getLastFailCause() {
|
||||
log("DataConnection.getLastFailCause()");
|
||||
return lastFailCause;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.telephony;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Registrant;
|
||||
|
||||
/**
|
||||
* Base class representing the data link layer (eg, PPP).
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract class DataLink extends Handler implements DataLinkInterface {
|
||||
|
||||
/** Registrant for link status change notifications. */
|
||||
protected Registrant mLinkChangeRegistrant;
|
||||
protected DataConnectionTracker dataConnection;
|
||||
|
||||
protected DataLink(DataConnectionTracker dc) {
|
||||
dataConnection = dc;
|
||||
}
|
||||
|
||||
public void setOnLinkChange(Handler h, int what, Object obj) {
|
||||
mLinkChangeRegistrant = new Registrant(h, what, obj);
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.telephony;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.os.Handler;
|
||||
|
||||
/**
|
||||
* Data link interface.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public interface DataLinkInterface {
|
||||
/**
|
||||
* Link state enumeration.
|
||||
*
|
||||
*/
|
||||
enum LinkState {
|
||||
LINK_UNKNOWN,
|
||||
LINK_UP,
|
||||
LINK_DOWN,
|
||||
LINK_EXITED
|
||||
}
|
||||
|
||||
/** Normal exit */
|
||||
final static int EXIT_OK = 0;
|
||||
/** Open failed */
|
||||
final static int EXIT_OPEN_FAILED = 7;
|
||||
|
||||
/**
|
||||
* Sets the handler for link state change events.
|
||||
*
|
||||
* @param h Handler
|
||||
* @param what User-defined message code
|
||||
* @param obj User object
|
||||
*/
|
||||
void setOnLinkChange(Handler h, int what, Object obj);
|
||||
|
||||
/**
|
||||
* Sets up the data link.
|
||||
*/
|
||||
void connect();
|
||||
|
||||
/**
|
||||
* Tears down the data link.
|
||||
*/
|
||||
void disconnect();
|
||||
|
||||
/**
|
||||
* Returns the exit code for a data link failure.
|
||||
*
|
||||
* @return exit code
|
||||
*/
|
||||
int getLastLinkExitCode();
|
||||
|
||||
/**
|
||||
* Sets password information that may be required by the data link
|
||||
* (eg, PAP secrets).
|
||||
*
|
||||
* @param cursor cursor to carriers table
|
||||
*/
|
||||
void setPasswordInfo(Cursor cursor);
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import android.telephony.SignalStrength;
|
||||
|
||||
import com.android.internal.telephony.DataConnection;
|
||||
import com.android.internal.telephony.gsm.NetworkInfo;
|
||||
import com.android.internal.telephony.gsm.PdpConnection;
|
||||
import com.android.internal.telephony.gsm.GsmDataConnection;
|
||||
import com.android.internal.telephony.test.SimulatedRadioControl;
|
||||
|
||||
import java.util.List;
|
||||
@@ -1176,21 +1176,7 @@ public interface Phone {
|
||||
void invokeOemRilRequestStrings(String[] strings, Message response);
|
||||
|
||||
/**
|
||||
* Get the current active PDP context list
|
||||
*
|
||||
* @deprecated
|
||||
* @param response <strong>On success</strong>, "response" bytes is
|
||||
* made available as:
|
||||
* (String[])(((AsyncResult)response.obj).result).
|
||||
* <strong>On failure</strong>,
|
||||
* (((AsyncResult)response.obj).result) == null and
|
||||
* (((AsyncResult)response.obj).exception) being an instance of
|
||||
* com.android.internal.telephony.gsm.CommandException
|
||||
*/
|
||||
void getPdpContextList(Message response);
|
||||
|
||||
/**
|
||||
* Get the current active Data Call list, substitutes getPdpContextList
|
||||
* Get the current active Data Call list
|
||||
*
|
||||
* @param response <strong>On success</strong>, "response" bytes is
|
||||
* made available as:
|
||||
@@ -1202,20 +1188,12 @@ public interface Phone {
|
||||
*/
|
||||
void getDataCallList(Message response);
|
||||
|
||||
/**
|
||||
* Get current mutiple PDP link status
|
||||
*
|
||||
* @deprecated
|
||||
* @return list of pdp link connections
|
||||
*/
|
||||
List<PdpConnection> getCurrentPdpList ();
|
||||
|
||||
/**
|
||||
* Get current mutiple data connection status
|
||||
*
|
||||
* @return list of data connections
|
||||
*/
|
||||
List<DataConnection> getCurrentDataConnectionList ();
|
||||
List<DataConnection> getCurrentDataConnectionList();
|
||||
|
||||
/**
|
||||
* Update the ServiceState CellLocation for current network registration.
|
||||
|
||||
@@ -35,7 +35,7 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.telephony.gsm.PdpConnection;
|
||||
import com.android.internal.telephony.gsm.GsmDataConnection;
|
||||
import com.android.internal.telephony.test.SimulatedRadioControl;
|
||||
|
||||
import java.util.List;
|
||||
@@ -692,16 +692,6 @@ public abstract class PhoneBase extends Handler implements Phone {
|
||||
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
|
||||
}
|
||||
|
||||
/**
|
||||
* This should only be called in GSM mode.
|
||||
* Only here for some backward compatibility
|
||||
* issues concerning the GSMPhone class.
|
||||
* @deprecated Always returns null.
|
||||
*/
|
||||
public List<PdpConnection> getCurrentPdpList() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void enableEnhancedVoicePrivacy(boolean enable, Message onComplete) {
|
||||
// This function should be overridden by the class CDMAPhone. Not implemented in GSMPhone.
|
||||
Log.e(LOG_TAG, "Error! This function should never be executed, inactive CDMAPhone.");
|
||||
|
||||
@@ -34,7 +34,7 @@ import android.util.Log;
|
||||
import com.android.internal.telephony.cdma.CDMAPhone;
|
||||
import com.android.internal.telephony.gsm.GSMPhone;
|
||||
import com.android.internal.telephony.gsm.NetworkInfo;
|
||||
import com.android.internal.telephony.gsm.PdpConnection;
|
||||
import com.android.internal.telephony.gsm.GsmDataConnection;
|
||||
import com.android.internal.telephony.test.SimulatedRadioControl;
|
||||
|
||||
import java.util.List;
|
||||
@@ -564,24 +564,10 @@ public class PhoneProxy extends Handler implements Phone {
|
||||
mActivePhone.invokeOemRilRequestStrings(strings, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public void getPdpContextList(Message response) {
|
||||
mActivePhone.getPdpContextList(response);
|
||||
}
|
||||
|
||||
public void getDataCallList(Message response) {
|
||||
mActivePhone.getDataCallList(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public List<PdpConnection> getCurrentPdpList() {
|
||||
return mActivePhone.getCurrentPdpList();
|
||||
}
|
||||
|
||||
public List<DataConnection> getCurrentDataConnectionList() {
|
||||
return mActivePhone.getCurrentDataConnectionList();
|
||||
}
|
||||
|
||||
@@ -657,13 +657,6 @@ public class CDMAPhone extends PhoneBase {
|
||||
mSST.disableLocationUpdates();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public void getPdpContextList(Message response) {
|
||||
getDataCallList(response);
|
||||
}
|
||||
|
||||
public void getDataCallList(Message response) {
|
||||
mCM.getDataCallList(response);
|
||||
}
|
||||
|
||||
@@ -16,221 +16,77 @@
|
||||
|
||||
package com.android.internal.telephony.cdma;
|
||||
|
||||
import android.os.*;
|
||||
import android.util.EventLog;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.telephony.CommandException;
|
||||
import com.android.internal.telephony.CommandsInterface;
|
||||
import com.android.internal.telephony.DataConnection;
|
||||
import com.android.internal.telephony.DataLink;
|
||||
import com.android.internal.telephony.RILConstants;
|
||||
import com.android.internal.telephony.TelephonyEventLog;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*
|
||||
*/
|
||||
public class CdmaDataConnection extends DataConnection {
|
||||
|
||||
private static final String LOG_TAG = "CDMA";
|
||||
private static final boolean DBG = true;
|
||||
|
||||
/** Fail cause of last Data Call activate from RIL_LastDataCallActivateFailCause */
|
||||
private final static int PS_NET_DOWN_REASON_OPERATOR_DETERMINED_BARRING = 8;
|
||||
private final static int PS_NET_DOWN_REASON_UNKNOWN_APN = 27;
|
||||
private final static int PS_NET_DOWN_REASON_AUTH_FAILED = 29;
|
||||
private final static int PS_NET_DOWN_REASON_OPTION_NOT_SUPPORTED = 32;
|
||||
private final static int PS_NET_DOWN_REASON_OPTION_UNSUBSCRIBED = 33;
|
||||
|
||||
/** It is likely that the number of error codes listed below will be removed
|
||||
* in the foreseeable future. They have been added, but not agreed upon.
|
||||
*
|
||||
*/
|
||||
private final static int PS_NET_DOWN_REASON_NOT_SPECIFIED = 0;
|
||||
private final static int PS_NET_DOWN_REASON_CLOSE_IN_PROGRESS = 1;
|
||||
private final static int PS_NET_DOWN_REASON_NW_INITIATED_TERMINATION = 2;
|
||||
private final static int PS_NET_DOWN_REASON_APP_PREEMPTED = 3;
|
||||
private final static int PS_NET_DOWN_REASON_LLC_SNDCP_FAILURE = 25;
|
||||
private final static int PS_NET_DOWN_REASON_INSUFFICIENT_RESOURCES = 26;
|
||||
private final static int PS_NET_DOWN_REASON_UNKNOWN_PDP = 28;
|
||||
private final static int PS_NET_DOWN_REASON_GGSN_REJECT = 30;
|
||||
private final static int PS_NET_DOWN_REASON_ACTIVATION_REJECT = 31;
|
||||
private final static int PS_NET_DOWN_REASON_OPTION_TEMP_OOO = 34;
|
||||
private final static int PS_NET_DOWN_REASON_NSAPI_ALREADY_USED = 35;
|
||||
private final static int PS_NET_DOWN_REASON_REGULAR_DEACTIVATION = 36;
|
||||
private final static int PS_NET_DOWN_REASON_QOS_NOT_ACCEPTED = 37;
|
||||
private final static int PS_NET_DOWN_REASON_NETWORK_FAILURE = 38;
|
||||
private final static int PS_NET_DOWN_REASON_UMTS_REATTACH_REQ = 39;
|
||||
private final static int PS_NET_DOWN_REASON_TFT_SEMANTIC_ERROR = 41;
|
||||
private final static int PS_NET_DOWN_REASON_TFT_SYNTAX_ERROR = 42;
|
||||
private final static int PS_NET_DOWN_REASON_UNKNOWN_PDP_CONTEXT = 43;
|
||||
private final static int PS_NET_DOWN_REASON_FILTER_SEMANTIC_ERROR = 44;
|
||||
private final static int PS_NET_DOWN_REASON_FILTER_SYNTAX_ERROR = 45;
|
||||
private final static int PS_NET_DOWN_REASON_PDP_WITHOUT_ACTIVE_TFT = 46;
|
||||
private final static int PS_NET_DOWN_REASON_INVALID_TRANSACTION_ID = 81;
|
||||
private final static int PS_NET_DOWN_REASON_MESSAGE_INCORRECT_SEMANTIC = 95;
|
||||
private final static int PS_NET_DOWN_REASON_INVALID_MANDATORY_INFO = 96;
|
||||
private final static int PS_NET_DOWN_REASON_MESSAGE_TYPE_UNSUPPORTED = 97;
|
||||
private final static int PS_NET_DOWN_REASON_MSG_TYPE_NONCOMPATIBLE_STATE = 98;
|
||||
private final static int PS_NET_DOWN_REASON_UNKNOWN_INFO_ELEMENT = 99;
|
||||
private final static int PS_NET_DOWN_REASON_CONDITIONAL_IE_ERROR = 100;
|
||||
private final static int PS_NET_DOWN_REASON_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 101;
|
||||
private final static int PS_NET_DOWN_REASON_PROTOCOL_ERROR = 111;
|
||||
private final static int PS_NET_DOWN_REASON_APN_TYPE_CONFLICT = 112;
|
||||
private final static int PS_NET_DOWN_REASON_UNKNOWN_CAUSE_CODE = 113;
|
||||
private final static int PS_NET_DOWN_REASON_INTERNAL_MIN = 200;
|
||||
private final static int PS_NET_DOWN_REASON_INTERNAL_ERROR = 201;
|
||||
private final static int PS_NET_DOWN_REASON_INTERNAL_CALL_ENDED = 202;
|
||||
private final static int PS_NET_DOWN_REASON_INTERNAL_UNKNOWN_CAUSE_CODE = 203;
|
||||
private final static int PS_NET_DOWN_REASON_INTERNAL_MAX = 204;
|
||||
private final static int PS_NET_DOWN_REASON_CDMA_LOCK = 500;
|
||||
private final static int PS_NET_DOWN_REASON_INTERCEPT = 501;
|
||||
private final static int PS_NET_DOWN_REASON_REORDER = 502;
|
||||
private final static int PS_NET_DOWN_REASON_REL_SO_REJ = 503;
|
||||
private final static int PS_NET_DOWN_REASON_INCOM_CALL = 504;
|
||||
private final static int PS_NET_DOWN_REASON_ALERT_STOP = 505;
|
||||
private final static int PS_NET_DOWN_REASON_ACTIVATION = 506;
|
||||
private final static int PS_NET_DOWN_REASON_MAX_ACCESS_PROBE = 507;
|
||||
private final static int PS_NET_DOWN_REASON_CCS_NOT_SUPPORTED_BY_BS = 508;
|
||||
private final static int PS_NET_DOWN_REASON_NO_RESPONSE_FROM_BS = 509;
|
||||
private final static int PS_NET_DOWN_REASON_REJECTED_BY_BS = 510;
|
||||
private final static int PS_NET_DOWN_REASON_INCOMPATIBLE = 511;
|
||||
private final static int PS_NET_DOWN_REASON_ALREADY_IN_TC = 512;
|
||||
private final static int PS_NET_DOWN_REASON_USER_CALL_ORIG_DURING_GPS = 513;
|
||||
private final static int PS_NET_DOWN_REASON_USER_CALL_ORIG_DURING_SMS = 514;
|
||||
private final static int PS_NET_DOWN_REASON_NO_CDMA_SRV = 515;
|
||||
private final static int PS_NET_DOWN_REASON_CONF_FAILED = 1000;
|
||||
private final static int PS_NET_DOWN_REASON_INCOM_REJ = 1001;
|
||||
private final static int PS_NET_DOWN_REASON_NO_GW_SRV = 1002;
|
||||
private final static int PS_NET_DOWN_REASON_CD_GEN_OR_BUSY = 1500;
|
||||
private final static int PS_NET_DOWN_REASON_CD_BILL_OR_AUTH = 1501;
|
||||
private final static int PS_NET_DOWN_REASON_CHG_HDR = 1502;
|
||||
private final static int PS_NET_DOWN_REASON_EXIT_HDR = 1503;
|
||||
private final static int PS_NET_DOWN_REASON_HDR_NO_SESSION = 1504;
|
||||
private final static int PS_NET_DOWN_REASON_HDR_ORIG_DURING_GPS_FIX = 1505;
|
||||
private final static int PS_NET_DOWN_REASON_HDR_CS_TIMEOUT = 1506;
|
||||
private final static int PS_NET_DOWN_REASON_HDR_RELEASED_BY_CM = 1507;
|
||||
private final static int PS_NET_DOWN_REASON_CLIENT_END = 2000;
|
||||
private final static int PS_NET_DOWN_REASON_NO_SRV = 2001;
|
||||
private final static int PS_NET_DOWN_REASON_FADE = 2002;
|
||||
private final static int PS_NET_DOWN_REASON_REL_NORMAL = 2003;
|
||||
private final static int PS_NET_DOWN_REASON_ACC_IN_PROG = 2004;
|
||||
private final static int PS_NET_DOWN_REASON_ACC_FAIL = 2005;
|
||||
private final static int PS_NET_DOWN_REASON_REDIR_OR_HANDOFF = 2006;
|
||||
|
||||
// ***** Instance Variables
|
||||
|
||||
// ***** Constructor
|
||||
CdmaDataConnection(CDMAPhone phone) {
|
||||
super(phone);
|
||||
|
||||
if (DBG) log("CdmaDataConnection <constructor>");
|
||||
private CdmaDataConnection(CDMAPhone phone, String name) {
|
||||
super(phone, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a data connection
|
||||
* Create the connection object
|
||||
*
|
||||
* @param onCompleted
|
||||
* notify success or not after down
|
||||
* @param phone
|
||||
* @return CdmaDataConnection that was created.
|
||||
*/
|
||||
void connect(Message onCompleted) {
|
||||
static CdmaDataConnection makeDataConnection(CDMAPhone phone) {
|
||||
synchronized (mCountLock) {
|
||||
mCount += 1;
|
||||
}
|
||||
CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDataConnection-" + mCount);
|
||||
cdmaDc.start();
|
||||
if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
|
||||
return cdmaDc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin setting up a data connection, calls setupDataCall
|
||||
* and the ConnectionParams will be returned with the
|
||||
* EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj.
|
||||
*
|
||||
* @param cp is the connection parameters
|
||||
*/
|
||||
@Override
|
||||
protected void onConnect(ConnectionParams cp) {
|
||||
if (DBG) log("CdmaDataConnection Connecting...");
|
||||
|
||||
state = State.ACTIVATING;
|
||||
onConnectCompleted = onCompleted;
|
||||
createTime = -1;
|
||||
lastFailTime = -1;
|
||||
lastFailCause = FailCause.NONE;
|
||||
receivedDisconnectReq = false;
|
||||
|
||||
// msg.obj will be returned in AsyncResult.userObj;
|
||||
Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
|
||||
msg.obj = cp;
|
||||
phone.mCM.setupDataCall(Integer.toString(RILConstants.SETUP_DATA_TECH_CDMA),
|
||||
Integer.toString(RILConstants.DATA_PROFILE_DEFAULT), null, null,
|
||||
null, Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP),
|
||||
obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
|
||||
null, Integer.toString(RILConstants.SETUP_DATA_AUTH_PAP_CHAP), msg);
|
||||
}
|
||||
|
||||
private void tearDownData(Message msg) {
|
||||
if (phone.mCM.getRadioState().isOn()) {
|
||||
phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
|
||||
}
|
||||
}
|
||||
|
||||
protected void disconnect(Message msg) {
|
||||
onDisconnect = msg;
|
||||
if (state == State.ACTIVE) {
|
||||
tearDownData(msg);
|
||||
} else if (state == State.ACTIVATING) {
|
||||
receivedDisconnectReq = true;
|
||||
} else {
|
||||
// state == INACTIVE. Nothing to do, so notify immediately.
|
||||
notifyDisconnect(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "State=" + state + " create=" + createTime + " lastFail="
|
||||
+ lastFailTime + " lastFailCause=" + lastFailCause;
|
||||
}
|
||||
|
||||
|
||||
protected void notifyFail(FailCause cause, Message onCompleted) {
|
||||
if (onCompleted == null) {
|
||||
return;
|
||||
}
|
||||
state = State.INACTIVE;
|
||||
lastFailCause = cause;
|
||||
lastFailTime = System.currentTimeMillis();
|
||||
onConnectCompleted = null;
|
||||
|
||||
if(DBG) {
|
||||
log("Notify data connection fail at " + lastFailTime +
|
||||
" due to " + lastFailCause);
|
||||
}
|
||||
|
||||
AsyncResult.forMessage(onCompleted, cause, new Exception());
|
||||
onCompleted.sendToTarget();
|
||||
}
|
||||
|
||||
protected void notifySuccess(Message onCompleted) {
|
||||
if (onCompleted == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = State.ACTIVE;
|
||||
createTime = System.currentTimeMillis();
|
||||
onConnectCompleted = null;
|
||||
onCompleted.arg1 = cid;
|
||||
|
||||
if (DBG) log("Notify data connection success at " + createTime);
|
||||
|
||||
AsyncResult.forMessage(onCompleted);
|
||||
onCompleted.sendToTarget();
|
||||
}
|
||||
|
||||
protected void notifyDisconnect(Message msg) {
|
||||
if (DBG) log("Notify data connection disconnect");
|
||||
|
||||
if (msg != null) {
|
||||
AsyncResult.forMessage(msg);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
clearSettings();
|
||||
}
|
||||
|
||||
protected void onLinkStateChanged(DataLink.LinkState linkState) {
|
||||
switch (linkState) {
|
||||
case LINK_UP:
|
||||
notifySuccess(onConnectCompleted);
|
||||
break;
|
||||
|
||||
case LINK_DOWN:
|
||||
case LINK_EXITED:
|
||||
phone.mCM.getLastDataCallFailCause(obtainMessage(EVENT_GET_LAST_FAIL_DONE));
|
||||
break;
|
||||
}
|
||||
return "State=" + getCurrentState().getName() + " create=" + createTime + " lastFail="
|
||||
+ lastFailTime + " lastFasilCause=" + lastFailCause;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FailCause getFailCauseFromRequest(int rilCause) {
|
||||
FailCause cause;
|
||||
|
||||
@@ -253,73 +109,19 @@ public class CdmaDataConnection extends DataConnection {
|
||||
return cause;
|
||||
}
|
||||
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, "[CdmaDataConnection] " + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeactivated(AsyncResult ar) {
|
||||
notifyDisconnect((Message) ar.userObj);
|
||||
if (DBG) log("CDMA Connection Deactivated");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSetupConnectionCompleted(AsyncResult ar) {
|
||||
if (ar.exception != null) {
|
||||
Log.e(LOG_TAG, "CdmaDataConnection Init failed " + ar.exception);
|
||||
|
||||
if (receivedDisconnectReq) {
|
||||
// Don't bother reporting the error if there's already a
|
||||
// pending disconnect request, since DataConnectionTracker
|
||||
// has already updated its state.
|
||||
notifyDisconnect(onDisconnect);
|
||||
} else {
|
||||
if (ar.exception instanceof CommandException
|
||||
&& ((CommandException) (ar.exception)).getCommandError()
|
||||
== CommandException.Error.RADIO_NOT_AVAILABLE) {
|
||||
notifyFail(FailCause.RADIO_NOT_AVAILABLE, onConnectCompleted);
|
||||
} else {
|
||||
phone.mCM.getLastDataCallFailCause(obtainMessage(EVENT_GET_LAST_FAIL_DONE));
|
||||
}
|
||||
}
|
||||
protected boolean isDnsOk(String[] domainNameServers) {
|
||||
if ((NULL_IP.equals(domainNameServers[0])
|
||||
&& NULL_IP.equals(domainNameServers[1])
|
||||
&& !((CDMAPhone) phone).isDnsCheckDisabled())) {
|
||||
return false;
|
||||
} else {
|
||||
if (receivedDisconnectReq) {
|
||||
// Don't bother reporting success if there's already a
|
||||
// pending disconnect request, since DataConnectionTracker
|
||||
// has already updated its state.
|
||||
tearDownData(onDisconnect);
|
||||
} else {
|
||||
String[] response = ((String[]) ar.result);
|
||||
cid = Integer.parseInt(response[0]);
|
||||
|
||||
if (response.length > 2) {
|
||||
interfaceName = response[1];
|
||||
ipAddress = response[2];
|
||||
String prefix = "net." + interfaceName + ".";
|
||||
gatewayAddress = SystemProperties.get(prefix + "gw");
|
||||
dnsServers[0] = SystemProperties.get(prefix + "dns1");
|
||||
dnsServers[1] = SystemProperties.get(prefix + "dns2");
|
||||
if (DBG) {
|
||||
log("interface=" + interfaceName + " ipAddress=" + ipAddress
|
||||
+ " gateway=" + gatewayAddress + " DNS1=" + dnsServers[0]
|
||||
+ " DNS2=" + dnsServers[1]);
|
||||
}
|
||||
|
||||
if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1])
|
||||
&& !((CDMAPhone) phone).isDnsCheckDisabled()) {
|
||||
// Work around a race condition where QMI does not fill in DNS:
|
||||
// Deactivate PDP and let DataConnectionTracker retry.
|
||||
EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_BAD_DNS_ADDRESS,
|
||||
dnsServers[0]);
|
||||
phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_FORCE_RETRY));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
onLinkStateChanged(DataLink.LinkState.LINK_UP);
|
||||
|
||||
if (DBG) log("CdmaDataConnection setup on cid = " + cid);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, "[" + getName() + "] " + s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, reason);
|
||||
conn.disconnect(msg);
|
||||
} else {
|
||||
conn.clearSettings();
|
||||
conn.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -403,7 +403,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
private CdmaDataConnection findFreeDataConnection() {
|
||||
for (DataConnection connBase : dataConnectionList) {
|
||||
CdmaDataConnection conn = (CdmaDataConnection) connBase;
|
||||
if (conn.getState() == DataConnection.State.INACTIVE) {
|
||||
if (conn.isInactive()) {
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
@@ -801,7 +801,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
|
||||
CdmaDataConnection dataConn;
|
||||
|
||||
for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
|
||||
dataConn = new CdmaDataConnection(mCdmaPhone);
|
||||
dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone);
|
||||
dataConnectionList.add(dataConn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1050,33 +1050,10 @@ public class GSMPhone extends PhoneBase {
|
||||
return mCT.getMute();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do not use.
|
||||
*/
|
||||
@Deprecated
|
||||
public void getPdpContextList(Message response) {
|
||||
getDataCallList(response);
|
||||
}
|
||||
|
||||
public void getDataCallList(Message response) {
|
||||
mCM.getDataCallList(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do not use.
|
||||
*/
|
||||
@Deprecated
|
||||
public List<PdpConnection> getCurrentPdpList() {
|
||||
ArrayList<DataConnection> connections = new ArrayList<DataConnection>();
|
||||
ArrayList<PdpConnection> pdp_list = new ArrayList<PdpConnection>();
|
||||
|
||||
for(int n = 0; n < connections.size(); n++) {
|
||||
pdp_list.add((PdpConnection) connections.get(n));
|
||||
}
|
||||
|
||||
return pdp_list;
|
||||
}
|
||||
|
||||
public List<DataConnection> getCurrentDataConnectionList () {
|
||||
return mDataConnection.getAllDataConnections();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.telephony.gsm;
|
||||
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.common.Patterns;
|
||||
import com.android.internal.telephony.DataConnection;
|
||||
import com.android.internal.telephony.Phone;
|
||||
import com.android.internal.telephony.RILConstants;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
public class GsmDataConnection extends DataConnection {
|
||||
|
||||
private static final String LOG_TAG = "GSM";
|
||||
|
||||
/** Fail cause of last PDP activate, from RIL_LastPDPActivateFailCause */
|
||||
private static final int PDP_FAIL_OPERATOR_BARRED = 0x08;
|
||||
private static final int PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
|
||||
private static final int PDP_FAIL_MISSING_UKNOWN_APN = 0x1B;
|
||||
private static final int PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
|
||||
private static final int PDP_FAIL_USER_AUTHENTICATION = 0x1D;
|
||||
private static final int PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
|
||||
private static final int PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
|
||||
private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
|
||||
private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
|
||||
private static final int PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
|
||||
private static final int PDP_FAIL_NSAPI_IN_USE = 0x23;
|
||||
private static final int PDP_FAIL_PROTOCOL_ERRORS = 0x6F;
|
||||
private static final int PDP_FAIL_ERROR_UNSPECIFIED = 0xffff;
|
||||
|
||||
private static final int PDP_FAIL_REGISTRATION_FAIL = -1;
|
||||
private static final int PDP_FAIL_GPRS_REGISTRATION_FAIL = -2;
|
||||
|
||||
//***** Instance Variables
|
||||
private ApnSetting apn;
|
||||
|
||||
//***** Constructor
|
||||
private GsmDataConnection(GSMPhone phone, String name) {
|
||||
super(phone, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the connection object
|
||||
*
|
||||
* @param phone
|
||||
* @return GsmDataConnection that was created.
|
||||
*/
|
||||
static GsmDataConnection makeDataConnection(GSMPhone phone) {
|
||||
synchronized (mCountLock) {
|
||||
mCount += 1;
|
||||
}
|
||||
GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount);
|
||||
gsmDc.start();
|
||||
if (DBG) gsmDc.log("Made " + gsmDc.getName());
|
||||
return gsmDc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin setting up a data connection, calls setupDataCall
|
||||
* and the ConnectionParams will be returned with the
|
||||
* EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj.
|
||||
*
|
||||
* @param cp is the connection parameters
|
||||
*/
|
||||
@Override
|
||||
protected
|
||||
void onConnect(ConnectionParams cp) {
|
||||
apn = cp.apn;
|
||||
|
||||
if (DBG) log("Connecting to carrier: '" + apn.carrier
|
||||
+ "' APN: '" + apn.apn
|
||||
+ "' proxy: '" + apn.proxy + "' port: '" + apn.port);
|
||||
|
||||
setHttpProxy (apn.proxy, apn.port);
|
||||
|
||||
createTime = -1;
|
||||
lastFailTime = -1;
|
||||
lastFailCause = FailCause.NONE;
|
||||
|
||||
// msg.obj will be returned in AsyncResult.userObj;
|
||||
Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
|
||||
msg.obj = cp;
|
||||
|
||||
int authType = apn.authType;
|
||||
if (authType == -1) {
|
||||
authType = (apn.user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP :
|
||||
RILConstants.SETUP_DATA_AUTH_NONE;
|
||||
}
|
||||
phone.mCM.setupDataCall(Integer.toString(RILConstants.SETUP_DATA_TECH_GSM),
|
||||
Integer.toString(RILConstants.DATA_PROFILE_DEFAULT), apn.apn, apn.user,
|
||||
apn.password, Integer.toString(authType), msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clearSettings() {
|
||||
super.clearSettings();
|
||||
apn = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "State=" + getCurrentState().getName() + " Apn=" + apn +
|
||||
" create=" + createTime + " lastFail=" + lastFailTime +
|
||||
" lastFailCause=" + lastFailCause;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FailCause getFailCauseFromRequest(int rilCause) {
|
||||
FailCause cause;
|
||||
|
||||
switch (rilCause) {
|
||||
case PDP_FAIL_OPERATOR_BARRED:
|
||||
cause = FailCause.OPERATOR_BARRED;
|
||||
break;
|
||||
case PDP_FAIL_INSUFFICIENT_RESOURCES:
|
||||
cause = FailCause.INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
case PDP_FAIL_MISSING_UKNOWN_APN:
|
||||
cause = FailCause.MISSING_UKNOWN_APN;
|
||||
break;
|
||||
case PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE:
|
||||
cause = FailCause.UNKNOWN_PDP_ADDRESS;
|
||||
break;
|
||||
case PDP_FAIL_USER_AUTHENTICATION:
|
||||
cause = FailCause.USER_AUTHENTICATION;
|
||||
break;
|
||||
case PDP_FAIL_ACTIVATION_REJECT_GGSN:
|
||||
cause = FailCause.ACTIVATION_REJECT_GGSN;
|
||||
break;
|
||||
case PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED:
|
||||
cause = FailCause.ACTIVATION_REJECT_UNSPECIFIED;
|
||||
break;
|
||||
case PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER:
|
||||
cause = FailCause.SERVICE_OPTION_OUT_OF_ORDER;
|
||||
break;
|
||||
case PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED:
|
||||
cause = FailCause.SERVICE_OPTION_NOT_SUPPORTED;
|
||||
break;
|
||||
case PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED:
|
||||
cause = FailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
|
||||
break;
|
||||
case PDP_FAIL_NSAPI_IN_USE:
|
||||
cause = FailCause.NSAPI_IN_USE;
|
||||
break;
|
||||
case PDP_FAIL_PROTOCOL_ERRORS:
|
||||
cause = FailCause.PROTOCOL_ERRORS;
|
||||
break;
|
||||
case PDP_FAIL_ERROR_UNSPECIFIED:
|
||||
cause = FailCause.UNKNOWN;
|
||||
break;
|
||||
case PDP_FAIL_REGISTRATION_FAIL:
|
||||
cause = FailCause.REGISTRATION_FAIL;
|
||||
break;
|
||||
case PDP_FAIL_GPRS_REGISTRATION_FAIL:
|
||||
cause = FailCause.GPRS_REGISTRATION_FAIL;
|
||||
break;
|
||||
default:
|
||||
cause = FailCause.UNKNOWN;
|
||||
}
|
||||
return cause;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isDnsOk(String[] domainNameServers) {
|
||||
if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1])
|
||||
&& !((GSMPhone) phone).isDnsCheckDisabled()) {
|
||||
// Work around a race condition where QMI does not fill in DNS:
|
||||
// Deactivate PDP and let DataConnectionTracker retry.
|
||||
// Do not apply the race condition workaround for MMS APN
|
||||
// if Proxy is an IP-address.
|
||||
// Otherwise, the default APN will not be restored anymore.
|
||||
if (!apn.types[0].equals(Phone.APN_TYPE_MMS)
|
||||
|| !isIpAddress(apn.mmsProxy)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, "[" + getName() + "] " + s);
|
||||
}
|
||||
|
||||
public ApnSetting getApn() {
|
||||
return this.apn;
|
||||
}
|
||||
|
||||
private void setHttpProxy(String httpProxy, String httpPort) {
|
||||
if (httpProxy == null || httpProxy.length() == 0) {
|
||||
phone.setSystemProperty("net.gprs.http-proxy", null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (httpPort == null || httpPort.length() == 0) {
|
||||
httpPort = "8080"; // Default to port 8080
|
||||
}
|
||||
|
||||
phone.setSystemProperty("net.gprs.http-proxy",
|
||||
"http://" + httpProxy + ":" + httpPort + "/");
|
||||
}
|
||||
|
||||
private boolean isIpAddress(String address) {
|
||||
if (address == null) return false;
|
||||
|
||||
return Patterns.IP_ADDRESS.matcher(apn.mmsProxy).matches();
|
||||
}
|
||||
}
|
||||
@@ -126,8 +126,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
*/
|
||||
private ArrayList<DataConnection> pdpList;
|
||||
|
||||
/** Currently active PdpConnection */
|
||||
private PdpConnection mActivePdp;
|
||||
/** Currently active DataConnection */
|
||||
private GsmDataConnection mActivePdp;
|
||||
|
||||
/** Is packet service restricted by network */
|
||||
private boolean mIsPsRestricted = false;
|
||||
@@ -137,7 +137,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
// TODO: Increase this to match the max number of simultaneous
|
||||
// PDP contexts we plan to support.
|
||||
/**
|
||||
* Pool size of PdpConnection objects.
|
||||
* Pool size of DataConnection objects.
|
||||
*/
|
||||
private static final int PDP_CONNECTION_POOL_SIZE = 1;
|
||||
|
||||
@@ -382,7 +382,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
|
||||
/**
|
||||
* Formerly this method was ArrayList<PdpConnection> getAllPdps()
|
||||
* Formerly this method was ArrayList<GsmDataConnection> getAllPdps()
|
||||
*/
|
||||
public ArrayList<DataConnection> getAllDataConnections() {
|
||||
ArrayList<DataConnection> pdps = (ArrayList<DataConnection>)pdpList.clone();
|
||||
@@ -452,7 +452,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
waitingApns = buildWaitingApns();
|
||||
if (waitingApns.isEmpty()) {
|
||||
if (DBG) log("No APN found");
|
||||
notifyNoData(PdpConnection.FailCause.MISSING_UKNOWN_APN);
|
||||
notifyNoData(GsmDataConnection.FailCause.MISSING_UKNOWN_APN);
|
||||
return false;
|
||||
} else {
|
||||
log ("Create from allApns : " + apnListToString(allApns));
|
||||
@@ -487,7 +487,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
* there is no mechanism for abandoning an INITING/CONNECTING session,
|
||||
* but would likely involve cancelling pending async requests or
|
||||
* setting a flag or new state to ignore them when they came in
|
||||
* @param tearDown true if the underlying PdpConnection should be
|
||||
* @param tearDown true if the underlying GsmDataConnection should be
|
||||
* disconnected.
|
||||
* @param reason reason for the clean up.
|
||||
*/
|
||||
@@ -505,12 +505,11 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
setState(State.DISCONNECTING);
|
||||
|
||||
for (DataConnection conn : pdpList) {
|
||||
PdpConnection pdp = (PdpConnection) conn;
|
||||
if (tearDown) {
|
||||
Message msg = obtainMessage(EVENT_DISCONNECT_DONE, reason);
|
||||
pdp.disconnect(msg);
|
||||
conn.disconnect(msg);
|
||||
} else {
|
||||
pdp.clearSettings();
|
||||
conn.reset();
|
||||
}
|
||||
}
|
||||
stopNetStatPoll();
|
||||
@@ -564,10 +563,10 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
return result;
|
||||
}
|
||||
|
||||
private PdpConnection findFreePdp() {
|
||||
private GsmDataConnection findFreePdp() {
|
||||
for (DataConnection conn : pdpList) {
|
||||
PdpConnection pdp = (PdpConnection) conn;
|
||||
if (pdp.getState() == DataConnection.State.INACTIVE) {
|
||||
GsmDataConnection pdp = (GsmDataConnection) conn;
|
||||
if (pdp.isInactive()) {
|
||||
return pdp;
|
||||
}
|
||||
}
|
||||
@@ -576,13 +575,13 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
|
||||
private boolean setupData(String reason) {
|
||||
ApnSetting apn;
|
||||
PdpConnection pdp;
|
||||
GsmDataConnection pdp;
|
||||
|
||||
apn = getNextApn();
|
||||
if (apn == null) return false;
|
||||
pdp = findFreePdp();
|
||||
if (pdp == null) {
|
||||
if (DBG) log("setupData: No free PdpConnection found!");
|
||||
if (DBG) log("setupData: No free GsmDataConnection found!");
|
||||
return false;
|
||||
}
|
||||
mActiveApn = apn;
|
||||
@@ -591,7 +590,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
Message msg = obtainMessage();
|
||||
msg.what = EVENT_DATA_SETUP_COMPLETE;
|
||||
msg.obj = reason;
|
||||
pdp.connect(apn, msg);
|
||||
pdp.connect(msg, apn);
|
||||
|
||||
setState(State.INITING);
|
||||
phone.notifyDataConnection(reason);
|
||||
@@ -974,13 +973,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
* seems like it deserves an error notification.
|
||||
* Transient errors are ignored
|
||||
*/
|
||||
private boolean shouldPostNotification(PdpConnection.FailCause cause) {
|
||||
boolean shouldPost = true;
|
||||
// TODO CHECK
|
||||
// if (dataLink != null) {
|
||||
// shouldPost = dataLink.getLastLinkExitCode() != DataLink.EXIT_OPEN_FAILED;
|
||||
//}
|
||||
return (shouldPost && cause != PdpConnection.FailCause.UNKNOWN);
|
||||
private boolean shouldPostNotification(GsmDataConnection.FailCause cause) {
|
||||
return (cause != GsmDataConnection.FailCause.UNKNOWN);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1046,7 +1040,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyNoData(PdpConnection.FailCause lastFailCauseCode) {
|
||||
private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode) {
|
||||
setState(State.FAILED);
|
||||
}
|
||||
|
||||
@@ -1069,7 +1063,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
mRetryMgr.resetRetryCount();
|
||||
|
||||
// TODO: To support simultaneous PDP contexts, this should really only call
|
||||
// cleanUpConnection if it needs to free up a PdpConnection.
|
||||
// cleanUpConnection if it needs to free up a GsmDataConnection.
|
||||
cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
|
||||
}
|
||||
|
||||
@@ -1149,8 +1143,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
// that the existing connection may service that type, in which
|
||||
// case we should try the next type, etc.
|
||||
} else {
|
||||
PdpConnection.FailCause cause;
|
||||
cause = (PdpConnection.FailCause) (ar.result);
|
||||
GsmDataConnection.FailCause cause;
|
||||
cause = (GsmDataConnection.FailCause) (ar.result);
|
||||
if(DBG) log("PDP setup failed " + cause);
|
||||
// Log this failure to the Event Logs.
|
||||
if (cause.isEventLoggable()) {
|
||||
@@ -1259,9 +1253,9 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
if (cursor.getCount() > 0) {
|
||||
allApns = createApnList(cursor);
|
||||
// TODO: Figure out where this fits in. This basically just
|
||||
// writes the pap-secrets file. No longer tied to PdpConnection
|
||||
// writes the pap-secrets file. No longer tied to GsmDataConnection
|
||||
// object. Not used on current platform (no ppp).
|
||||
//PdpConnection pdp = pdpList.get(pdp_name);
|
||||
//GsmDataConnection pdp = pdpList.get(pdp_name);
|
||||
//if (pdp != null && pdp.dataLink != null) {
|
||||
// pdp.dataLink.setPasswordInfo(cursor);
|
||||
//}
|
||||
@@ -1273,7 +1267,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
if (allApns.isEmpty()) {
|
||||
if (DBG) log("No APN found for carrier: " + operator);
|
||||
preferredApn = null;
|
||||
notifyNoData(PdpConnection.FailCause.MISSING_UKNOWN_APN);
|
||||
notifyNoData(GsmDataConnection.FailCause.MISSING_UKNOWN_APN);
|
||||
} else {
|
||||
preferredApn = getPreferredApn();
|
||||
Log.d(LOG_TAG, "Get PreferredAPN");
|
||||
@@ -1289,14 +1283,14 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
DataConnection pdp;
|
||||
|
||||
for (int i = 0; i < PDP_CONNECTION_POOL_SIZE; i++) {
|
||||
pdp = new PdpConnection(mGsmPhone);
|
||||
pdp = GsmDataConnection.makeDataConnection(mGsmPhone);
|
||||
pdpList.add(pdp);
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyAllPdpList() {
|
||||
if(pdpList != null) {
|
||||
PdpConnection pdp;
|
||||
GsmDataConnection pdp;
|
||||
pdpList.removeAll(pdpList);
|
||||
}
|
||||
}
|
||||
@@ -1361,7 +1355,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private void startDelayedRetry(PdpConnection.FailCause cause, String reason) {
|
||||
private void startDelayedRetry(GsmDataConnection.FailCause cause, String reason) {
|
||||
notifyNoData(cause);
|
||||
reconnectAfterFail(cause, reason);
|
||||
}
|
||||
|
||||
@@ -1,327 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.telephony.gsm;
|
||||
|
||||
import android.os.*;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.common.Patterns;
|
||||
import com.android.internal.telephony.CommandException;
|
||||
import com.android.internal.telephony.CommandsInterface;
|
||||
import com.android.internal.telephony.DataConnection;
|
||||
import com.android.internal.telephony.DataLink;
|
||||
import com.android.internal.telephony.Phone;
|
||||
import com.android.internal.telephony.RILConstants;
|
||||
import com.android.internal.telephony.TelephonyEventLog;
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
public class PdpConnection extends DataConnection {
|
||||
|
||||
private static final String LOG_TAG = "GSM";
|
||||
private static final boolean DBG = true;
|
||||
|
||||
/** Fail cause of last PDP activate, from RIL_LastPDPActivateFailCause */
|
||||
private static final int PDP_FAIL_OPERATOR_BARRED = 0x08;
|
||||
private static final int PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A;
|
||||
private static final int PDP_FAIL_MISSING_UKNOWN_APN = 0x1B;
|
||||
private static final int PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;
|
||||
private static final int PDP_FAIL_USER_AUTHENTICATION = 0x1D;
|
||||
private static final int PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E;
|
||||
private static final int PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
|
||||
private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20;
|
||||
private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;
|
||||
private static final int PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22;
|
||||
private static final int PDP_FAIL_NSAPI_IN_USE = 0x23;
|
||||
private static final int PDP_FAIL_PROTOCOL_ERRORS = 0x6F;
|
||||
private static final int PDP_FAIL_ERROR_UNSPECIFIED = 0xffff;
|
||||
|
||||
private static final int PDP_FAIL_REGISTRATION_FAIL = -1;
|
||||
private static final int PDP_FAIL_GPRS_REGISTRATION_FAIL = -2;
|
||||
|
||||
//***** Instance Variables
|
||||
private String pdp_name;
|
||||
private ApnSetting apn;
|
||||
|
||||
//***** Constructor
|
||||
PdpConnection(GSMPhone phone) {
|
||||
super(phone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup PDP connection for provided apn
|
||||
* @param apn for this connection
|
||||
* @param onCompleted notify success or not after down
|
||||
*/
|
||||
void connect(ApnSetting apn, Message onCompleted) {
|
||||
if (DBG) log("Connecting to carrier: '" + apn.carrier
|
||||
+ "' APN: '" + apn.apn
|
||||
+ "' proxy: '" + apn.proxy + "' port: '" + apn.port);
|
||||
|
||||
setHttpProxy (apn.proxy, apn.port);
|
||||
|
||||
state = State.ACTIVATING;
|
||||
this.apn = apn;
|
||||
onConnectCompleted = onCompleted;
|
||||
createTime = -1;
|
||||
lastFailTime = -1;
|
||||
lastFailCause = FailCause.NONE;
|
||||
receivedDisconnectReq = false;
|
||||
|
||||
int authType = apn.authType;
|
||||
if (authType == -1) {
|
||||
authType = (apn.user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP :
|
||||
RILConstants.SETUP_DATA_AUTH_NONE;
|
||||
}
|
||||
phone.mCM.setupDataCall(Integer.toString(RILConstants.SETUP_DATA_TECH_GSM),
|
||||
Integer.toString(RILConstants.DATA_PROFILE_DEFAULT), apn.apn, apn.user,
|
||||
apn.password, Integer.toString(authType),
|
||||
obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE));
|
||||
}
|
||||
|
||||
private void tearDownData(Message msg) {
|
||||
if (phone.mCM.getRadioState().isOn()) {
|
||||
phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
|
||||
}
|
||||
}
|
||||
|
||||
protected void disconnect(Message msg) {
|
||||
onDisconnect = msg;
|
||||
if (state == State.ACTIVE) {
|
||||
tearDownData(msg);
|
||||
} else if (state == State.ACTIVATING) {
|
||||
receivedDisconnectReq = true;
|
||||
} else {
|
||||
// state == INACTIVE. Nothing to do, so notify immediately.
|
||||
notifyDisconnect(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearSettings() {
|
||||
super.clearSettings();
|
||||
apn = null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "State=" + state + " Apn=" + apn +
|
||||
" create=" + createTime + " lastFail=" + lastFailTime +
|
||||
" lastFailCause=" + lastFailCause;
|
||||
}
|
||||
|
||||
|
||||
protected void notifyFail(FailCause cause, Message onCompleted) {
|
||||
if (onCompleted == null) return;
|
||||
|
||||
state = State.INACTIVE;
|
||||
lastFailCause = cause;
|
||||
lastFailTime = System.currentTimeMillis();
|
||||
onConnectCompleted = null;
|
||||
|
||||
if (DBG) {
|
||||
log("Notify PDP fail at " + lastFailTime +
|
||||
" due to " + lastFailCause);
|
||||
}
|
||||
|
||||
AsyncResult.forMessage(onCompleted, cause, new Exception());
|
||||
onCompleted.sendToTarget();
|
||||
}
|
||||
|
||||
protected void notifySuccess(Message onCompleted) {
|
||||
if (onCompleted == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = State.ACTIVE;
|
||||
createTime = System.currentTimeMillis();
|
||||
onConnectCompleted = null;
|
||||
onCompleted.arg1 = cid;
|
||||
|
||||
if (DBG) log("Notify PDP success at " + createTime);
|
||||
|
||||
AsyncResult.forMessage(onCompleted);
|
||||
onCompleted.sendToTarget();
|
||||
}
|
||||
|
||||
protected void notifyDisconnect(Message msg) {
|
||||
if (DBG) log("Notify PDP disconnect");
|
||||
|
||||
if (msg != null) {
|
||||
AsyncResult.forMessage(msg);
|
||||
msg.sendToTarget();
|
||||
}
|
||||
clearSettings();
|
||||
}
|
||||
|
||||
protected void onLinkStateChanged(DataLink.LinkState linkState) {
|
||||
switch (linkState) {
|
||||
case LINK_UP:
|
||||
notifySuccess(onConnectCompleted);
|
||||
break;
|
||||
|
||||
case LINK_DOWN:
|
||||
case LINK_EXITED:
|
||||
phone.mCM.getLastPdpFailCause(
|
||||
obtainMessage (EVENT_GET_LAST_FAIL_DONE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected FailCause getFailCauseFromRequest(int rilCause) {
|
||||
FailCause cause;
|
||||
|
||||
switch (rilCause) {
|
||||
case PDP_FAIL_OPERATOR_BARRED:
|
||||
cause = FailCause.OPERATOR_BARRED;
|
||||
break;
|
||||
case PDP_FAIL_INSUFFICIENT_RESOURCES:
|
||||
cause = FailCause.INSUFFICIENT_RESOURCES;
|
||||
break;
|
||||
case PDP_FAIL_MISSING_UKNOWN_APN:
|
||||
cause = FailCause.MISSING_UKNOWN_APN;
|
||||
break;
|
||||
case PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE:
|
||||
cause = FailCause.UNKNOWN_PDP_ADDRESS;
|
||||
break;
|
||||
case PDP_FAIL_USER_AUTHENTICATION:
|
||||
cause = FailCause.USER_AUTHENTICATION;
|
||||
break;
|
||||
case PDP_FAIL_ACTIVATION_REJECT_GGSN:
|
||||
cause = FailCause.ACTIVATION_REJECT_GGSN;
|
||||
break;
|
||||
case PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED:
|
||||
cause = FailCause.ACTIVATION_REJECT_UNSPECIFIED;
|
||||
break;
|
||||
case PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER:
|
||||
cause = FailCause.SERVICE_OPTION_OUT_OF_ORDER;
|
||||
break;
|
||||
case PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED:
|
||||
cause = FailCause.SERVICE_OPTION_NOT_SUPPORTED;
|
||||
break;
|
||||
case PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED:
|
||||
cause = FailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
|
||||
break;
|
||||
case PDP_FAIL_NSAPI_IN_USE:
|
||||
cause = FailCause.NSAPI_IN_USE;
|
||||
break;
|
||||
case PDP_FAIL_PROTOCOL_ERRORS:
|
||||
cause = FailCause.PROTOCOL_ERRORS;
|
||||
break;
|
||||
case PDP_FAIL_ERROR_UNSPECIFIED:
|
||||
cause = FailCause.UNKNOWN;
|
||||
break;
|
||||
case PDP_FAIL_REGISTRATION_FAIL:
|
||||
cause = FailCause.REGISTRATION_FAIL;
|
||||
break;
|
||||
case PDP_FAIL_GPRS_REGISTRATION_FAIL:
|
||||
cause = FailCause.GPRS_REGISTRATION_FAIL;
|
||||
break;
|
||||
default:
|
||||
cause = FailCause.UNKNOWN;
|
||||
}
|
||||
return cause;
|
||||
}
|
||||
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, "[PdpConnection] " + s);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeactivated(AsyncResult ar) {
|
||||
notifyDisconnect((Message) ar.userObj);
|
||||
if (DBG) log("PDP Connection Deactivated");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSetupConnectionCompleted(AsyncResult ar) {
|
||||
if (ar.exception != null) {
|
||||
Log.e(LOG_TAG, "PDP Context Init failed " + ar.exception);
|
||||
|
||||
if (receivedDisconnectReq) {
|
||||
// Don't bother reporting the error if there's already a
|
||||
// pending disconnect request, since DataConnectionTracker
|
||||
// has already updated its state.
|
||||
notifyDisconnect(onDisconnect);
|
||||
} else {
|
||||
if ( ar.exception instanceof CommandException &&
|
||||
((CommandException) (ar.exception)).getCommandError()
|
||||
== CommandException.Error.RADIO_NOT_AVAILABLE) {
|
||||
notifyFail(FailCause.RADIO_NOT_AVAILABLE,
|
||||
onConnectCompleted);
|
||||
} else {
|
||||
phone.mCM.getLastPdpFailCause(
|
||||
obtainMessage(EVENT_GET_LAST_FAIL_DONE));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (receivedDisconnectReq) {
|
||||
// Don't bother reporting success if there's already a
|
||||
// pending disconnect request, since DataConnectionTracker
|
||||
// has already updated its state.
|
||||
tearDownData(onDisconnect);
|
||||
} else {
|
||||
String[] response = ((String[]) ar.result);
|
||||
cid = Integer.parseInt(response[0]);
|
||||
|
||||
if (response.length > 2) {
|
||||
interfaceName = response[1];
|
||||
ipAddress = response[2];
|
||||
String prefix = "net." + interfaceName + ".";
|
||||
gatewayAddress = SystemProperties.get(prefix + "gw");
|
||||
dnsServers[0] = SystemProperties.get(prefix + "dns1");
|
||||
dnsServers[1] = SystemProperties.get(prefix + "dns2");
|
||||
if (DBG) {
|
||||
log("interface=" + interfaceName + " ipAddress=" + ipAddress
|
||||
+ " gateway=" + gatewayAddress + " DNS1=" + dnsServers[0]
|
||||
+ " DNS2=" + dnsServers[1]);
|
||||
}
|
||||
|
||||
if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1])
|
||||
&& !((GSMPhone) phone).isDnsCheckDisabled()) {
|
||||
// Work around a race condition where QMI does not fill in DNS:
|
||||
// Deactivate PDP and let DataConnectionTracker retry.
|
||||
// Do not apply the race condition workaround for MMS APN
|
||||
// if Proxy is an IP-address.
|
||||
// Otherwise, the default APN will not be restored anymore.
|
||||
if (!apn.types[0].equals(Phone.APN_TYPE_MMS)
|
||||
|| !isIpAddress(apn.mmsProxy)) {
|
||||
EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_BAD_DNS_ADDRESS,
|
||||
dnsServers[0]);
|
||||
phone.mCM.deactivateDataCall(cid, obtainMessage(EVENT_FORCE_RETRY));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onLinkStateChanged(DataLink.LinkState.LINK_UP);
|
||||
|
||||
if (DBG) log("PDP setup on cid = " + cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isIpAddress(String address) {
|
||||
if (address == null) return false;
|
||||
|
||||
return Patterns.IP_ADDRESS.matcher(apn.mmsProxy).matches();
|
||||
}
|
||||
|
||||
public ApnSetting getApn() {
|
||||
return this.apn;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user