blob: 7809fed62d2579456bf34eba7c4566e59e9cf894 [file] [log] [blame]
/*
* 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.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
/**
* {@hide}
*/
public abstract class DataConnection extends Handler {
// the inherited class
public enum State {
ACTIVE, /* has active data connection */
ACTIVATING, /* during connecting process */
INACTIVE; /* has empty data connection */
public String toString() {
switch (this) {
case ACTIVE:
return "active";
case ACTIVATING:
return "setting up";
default:
return "inactive";
}
}
public boolean isActive() {
return this == ACTIVE;
}
public boolean isInactive() {
return this == INACTIVE;
}
}
public enum FailCause {
NONE,
OPERATOR_BARRED,
INSUFFICIENT_RESOURCES,
MISSING_UKNOWN_APN,
UNKNOWN_PDP_ADDRESS,
USER_AUTHENTICATION,
ACTIVATION_REJECT_GGSN,
ACTIVATION_REJECT_UNSPECIFIED,
SERVICE_OPTION_NOT_SUPPORTED,
SERVICE_OPTION_NOT_SUBSCRIBED,
SERVICE_OPTION_OUT_OF_ORDER,
NSAPI_IN_USE,
PROTOCOL_ERRORS,
REGISTRATION_FAIL,
GPRS_REGISTRATION_FAIL,
UNKNOWN,
RADIO_NOT_AVAILABLE,
RADIO_ERROR_RETRY;
public boolean isPermanentFail() {
return (this == OPERATOR_BARRED) || (this == MISSING_UKNOWN_APN) ||
(this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) ||
(this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
(this == SERVICE_OPTION_NOT_SUPPORTED) ||
(this == SERVICE_OPTION_NOT_SUBSCRIBED) || (this == NSAPI_IN_USE) ||
(this == PROTOCOL_ERRORS);
}
public boolean isEventLoggable() {
return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) ||
(this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) ||
(this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
(this == SERVICE_OPTION_NOT_SUBSCRIBED) ||
(this == SERVICE_OPTION_NOT_SUPPORTED) ||
(this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) ||
(this == PROTOCOL_ERRORS);
}
@Override
public String toString() {
switch (this) {
case NONE:
return "No Error";
case OPERATOR_BARRED:
return "Operator Barred";
case INSUFFICIENT_RESOURCES:
return "Insufficient Resources";
case MISSING_UKNOWN_APN:
return "Missing / Unknown APN";
case UNKNOWN_PDP_ADDRESS:
return "Unknown PDP Address";
case USER_AUTHENTICATION:
return "Error User Autentication";
case ACTIVATION_REJECT_GGSN:
return "Activation Reject GGSN";
case ACTIVATION_REJECT_UNSPECIFIED:
return "Activation Reject unspecified";
case SERVICE_OPTION_NOT_SUPPORTED:
return "Data Not Supported";
case SERVICE_OPTION_NOT_SUBSCRIBED:
return "Data Not subscribed";
case SERVICE_OPTION_OUT_OF_ORDER:
return "Data Services Out of Order";
case NSAPI_IN_USE:
return "NSAPI in use";
case PROTOCOL_ERRORS:
return "Protocol Errors";
case REGISTRATION_FAIL:
return "Network Registration Failure";
case GPRS_REGISTRATION_FAIL:
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;
//***** Tag IDs for EventLog
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
//***** Member Variables
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;
/* 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 FailCause getFailCauseFromRequest(int rilCause);
public abstract String toString();
protected abstract void log(String s);
//***** Constructor
protected DataConnection(PhoneBase phone) {
super();
this.phone = phone;
onConnectCompleted = null;
onDisconnect = null;
this.cid = -1;
receivedDisconnectReq = false;
this.dnsServers = new String[2];
clearSettings();
}
protected 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 + "/");
}
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;
dnsServers[0] = null;
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;
if (ar.exception == null) {
int rilFailCause = ((int[]) (ar.result))[0];
cause = getFailCauseFromRequest(rilFailCause);
}
notifyFail(cause, onConnectCompleted);
}
}
protected void onForceRetry() {
if (receivedDisconnectReq) {
notifyDisconnect(onDisconnect);
} else {
notifyFail(FailCause.RADIO_ERROR_RETRY, onConnectCompleted);
}
}
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
log("DataConnection.handleMessage()");
switch (msg.what) {
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;
}
}
public State getState() {
log("DataConnection.getState()");
return state;
}
public long getConnectionTime() {
log("DataConnection.getConnectionTime()");
return createTime;
}
public long getLastFailTime() {
log("DataConnection.getLastFailTime()");
return lastFailTime;
}
public FailCause getLastFailCause() {
log("DataConnection.getLastFailCause()");
return lastFailCause;
}
}