FileDocCategorySizeDatePackage
PdpConnection.javaAPI DocAndroid 1.5 API17232Wed May 06 22:42:02 BST 2009com.android.internal.telephony.gsm

PdpConnection

public class PdpConnection extends Handler
{@hide}

Fields Summary
private static final String
LOG_TAG
private static final boolean
DBG
private static final boolean
FAKE_FAIL
private static final int
PDP_FAIL_RIL_BARRED
Fail cause of last PDP activate, from RIL_LastPDPActivateFailCause
private static final int
PDP_FAIL_RIL_BAD_APN
private static final int
PDP_FAIL_RIL_USER_AUTHENTICATION
private static final int
PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED
private static final int
PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED
private static final int
PDP_FAIL_RIL_ERROR_UNSPECIFIED
private static final int
EVENT_SETUP_PDP_DONE
private static final int
EVENT_GET_LAST_FAIL_DONE
private static final int
EVENT_LINK_STATE_CHANGED
private static final int
EVENT_DEACTIVATE_DONE
private static final int
EVENT_FORCE_RETRY
private GSMPhone
phone
private String
pdp_name
private PdpState
state
private Message
onConnectCompleted
private Message
onDisconnect
private int
cid
private long
createTime
private long
lastFailTime
private PdpFailCause
lastFailCause
private ApnSetting
apn
private String
interfaceName
private String
ipAddress
private String
gatewayAddress
private String[]
dnsServers
private static final String
NULL_IP
DataLink
dataLink
private boolean
receivedDisconnectReq
Constructors Summary
PdpConnection(GSMPhone phone)


    //***** Constructor
     
    
        this.phone = phone;
        this.state = PdpState.INACTIVE;
        onConnectCompleted = null;
        onDisconnect = null;
        this.cid = -1;
        this.createTime = -1;
        this.lastFailTime = -1;
        this.lastFailCause = PdpFailCause.NONE;
        this.apn = null;
        this.dataLink = null;
        receivedDisconnectReq = false;
        this.dnsServers = new String[2];

        if (SystemProperties.get("ro.radio.use-ppp","no").equals("yes")) {
            dataLink = new PppLink(phone.mDataConnection);
            dataLink.setOnLinkChange(this, EVENT_LINK_STATE_CHANGED, null);
        }
    
Methods Summary
voidclearSettings()

        state = PdpState.INACTIVE;
        receivedDisconnectReq = false;
        createTime = -1;
        lastFailTime = -1;
        lastFailCause = PdpFailCause.NONE;
        apn = null;
        onConnectCompleted = null;
        interfaceName = null;
        ipAddress = null;
        gatewayAddress = null;
        dnsServers[0] = null;
        dnsServers[1] = null;
    
voidconnect(ApnSetting apn, Message onCompleted)
Setup PDP connection for provided apn

param
apn for this connection
param
onCompleted notify success or not after down

        if (DBG) log("Connecting to carrier: '" + apn.carrier
                + "' APN: '" + apn.apn
                + "' proxy: '" + apn.proxy + "' port: '" + apn.port);

        setHttpProxy (apn.proxy, apn.port);

        state = PdpState.ACTIVATING;
        this.apn = apn;
        onConnectCompleted = onCompleted;
        createTime = -1;
        lastFailTime = -1;
        lastFailCause = PdpFailCause.NONE;
        receivedDisconnectReq = false;

        if (FAKE_FAIL) {
            // for debug before baseband implement error in setup PDP
            if (apn.apn.equalsIgnoreCase("badapn")){
                notifyFail(PdpFailCause.BAD_APN, onConnectCompleted);
                return;
            }
        }

        phone.mCM.setupDefaultPDP(apn.apn, apn.user, apn.password,
                obtainMessage(EVENT_SETUP_PDP_DONE));
    
voiddisconnect(Message msg)

        onDisconnect = msg;
        if (state == PdpState.ACTIVE) {
            if (dataLink != null) {
                dataLink.disconnect();
            }

            if (phone.mCM.getRadioState().isOn()) {
                phone.mCM.deactivateDefaultPDP(cid, obtainMessage(EVENT_DEACTIVATE_DONE, msg));
            }
        } else if (state == PdpState.ACTIVATING) {
            receivedDisconnectReq = true;
        } else {
            // state == INACTIVE.  Nothing to do, so notify immediately.
            notifyDisconnect(msg);
        }
    
public ApnSettinggetApn()

        return apn;
    
public longgetConnectionTime()

        return createTime;
    
java.lang.String[]getDnsServers()

        return dnsServers;
    
private com.android.internal.telephony.gsm.PdpConnection$PdpFailCausegetFailCauseFromRequest(int rilCause)

        PdpFailCause cause;

        switch (rilCause) {
            case PDP_FAIL_RIL_BARRED:
                cause = PdpFailCause.BARRED;
                break;
            case PDP_FAIL_RIL_BAD_APN:
                cause = PdpFailCause.BAD_APN;
                break;
            case PDP_FAIL_RIL_USER_AUTHENTICATION:
                cause = PdpFailCause.USER_AUTHENTICATION;
                break;
            case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUPPORTED:
                cause = PdpFailCause.SERVICE_OPTION_NOT_SUPPORTED;
                break;
            case PDP_FAIL_RIL_SERVICE_OPTION_NOT_SUBSCRIBED:
                cause = PdpFailCause.SERVICE_OPTION_NOT_SUBSCRIBED;
                break;
            default:
                cause = PdpFailCause.UNKNOWN;
        }
        return cause;
    
java.lang.StringgetGatewayAddress()

        return gatewayAddress;
    
java.lang.StringgetInterface()

        return interfaceName;
    
java.lang.StringgetIpAddress()

        return ipAddress;
    
public com.android.internal.telephony.gsm.PdpConnection$PdpFailCausegetLastFailCause()

        return lastFailCause;
    
public longgetLastFailTime()

        return lastFailTime;
    
public com.android.internal.telephony.gsm.PdpConnection$PdpStategetState()

        return state;
    
public voidhandleMessage(Message msg)

        AsyncResult ar;

        switch (msg.what) {
            case EVENT_SETUP_PDP_DONE:
                ar = (AsyncResult) msg.obj;

                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(PdpFailCause.RADIO_NOT_AVIALABLE,
                                    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.
                        // Set ACTIVE so that disconnect does the right thing.
                        state = PdpState.ACTIVE;
                        disconnect(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])
                                    && !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.deactivateDefaultPDP(cid,
                                            obtainMessage(EVENT_FORCE_RETRY));
                                    break;
                                }
                            }
                        }

                        if (dataLink != null) {
                            dataLink.connect();
                        } else {
                            onLinkStateChanged(DataLink.LinkState.LINK_UP);
                        }

                        if (DBG) log("PDP setup on cid = " + cid);
                    }
                }
                break;
            case EVENT_FORCE_RETRY:
                if (receivedDisconnectReq) {
                    notifyDisconnect(onDisconnect);
                } else {
                    ar = (AsyncResult) msg.obj;
                    notifyFail(PdpFailCause.RADIO_ERROR_RETRY, onConnectCompleted);
                }
                break;
            case EVENT_GET_LAST_FAIL_DONE:
                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 {
                    ar = (AsyncResult) msg.obj;
                    PdpFailCause cause = PdpFailCause.UNKNOWN;

                    if (ar.exception == null) {
                        int rilFailCause = ((int[]) (ar.result))[0];
                        cause = getFailCauseFromRequest(rilFailCause);
                    }
                    notifyFail(cause, onConnectCompleted);
                }

                break;
            case EVENT_LINK_STATE_CHANGED:
                ar = (AsyncResult) msg.obj;
                DataLink.LinkState ls  = (DataLink.LinkState) ar.result;
                onLinkStateChanged(ls);
                break;
            case EVENT_DEACTIVATE_DONE:
                ar = (AsyncResult) msg.obj;
                notifyDisconnect((Message) ar.userObj);
                break;
        }
    
private booleanisIpAddress(java.lang.String address)

        if (address == null) return false;

        return Regex.IP_ADDRESS_PATTERN.matcher(apn.mmsProxy).matches();
    
private voidlog(java.lang.String s)

        Log.d(LOG_TAG, "[PdpConnection] " + s);
    
private voidnotifyDisconnect(Message msg)

        if (DBG) log("Notify PDP disconnect");

        if (msg != null) {
            AsyncResult.forMessage(msg);
            msg.sendToTarget();
        }
        clearSettings();
    
private voidnotifyFail(com.android.internal.telephony.gsm.PdpConnection$PdpFailCause cause, Message onCompleted)

        if (onCompleted == null) return;

        state = PdpState.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();
    
private voidnotifySuccess(Message onCompleted)

        if (onCompleted == null) return;

        state = PdpState.ACTIVE;
        createTime = System.currentTimeMillis();
        onConnectCompleted = null;
        onCompleted.arg1 = cid;

        if (DBG) log("Notify PDP success at " + createTime);

        AsyncResult.forMessage(onCompleted);
        onCompleted.sendToTarget();
    
private voidonLinkStateChanged(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;
        }
    
private voidsetHttpProxy(java.lang.String httpProxy, java.lang.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 + "/");
    
public java.lang.StringtoString()

        return "State=" + state + " Apn=" + apn +
               " create=" + createTime + " lastFail=" + lastFailTime +
               " lastFailCause=" + lastFailCause;