1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony; 18 19import android.os.AsyncResult; 20import android.os.Handler; 21import android.os.Message; 22import android.util.Log; 23 24/** 25 * {@hide} 26 */ 27public abstract class DataConnection extends Handler { 28 29 // the inherited class 30 31 public enum State { 32 ACTIVE, /* has active data connection */ 33 ACTIVATING, /* during connecting process */ 34 INACTIVE; /* has empty data connection */ 35 36 public String toString() { 37 switch (this) { 38 case ACTIVE: 39 return "active"; 40 case ACTIVATING: 41 return "setting up"; 42 default: 43 return "inactive"; 44 } 45 } 46 47 public boolean isActive() { 48 return this == ACTIVE; 49 } 50 51 public boolean isInactive() { 52 return this == INACTIVE; 53 } 54 } 55 56 public enum FailCause { 57 NONE, 58 OPERATOR_BARRED, 59 INSUFFICIENT_RESOURCES, 60 MISSING_UKNOWN_APN, 61 UNKNOWN_PDP_ADDRESS, 62 USER_AUTHENTICATION, 63 ACTIVATION_REJECT_GGSN, 64 ACTIVATION_REJECT_UNSPECIFIED, 65 SERVICE_OPTION_NOT_SUPPORTED, 66 SERVICE_OPTION_NOT_SUBSCRIBED, 67 SERVICE_OPTION_OUT_OF_ORDER, 68 NSAPI_IN_USE, 69 PROTOCOL_ERRORS, 70 REGISTRATION_FAIL, 71 GPRS_REGISTRATION_FAIL, 72 UNKNOWN, 73 74 RADIO_NOT_AVAILABLE, 75 RADIO_ERROR_RETRY; 76 77 public boolean isPermanentFail() { 78 return (this == OPERATOR_BARRED) || (this == MISSING_UKNOWN_APN) || 79 (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) || 80 (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) || 81 (this == SERVICE_OPTION_NOT_SUPPORTED) || 82 (this == SERVICE_OPTION_NOT_SUBSCRIBED) || (this == NSAPI_IN_USE) || 83 (this == PROTOCOL_ERRORS); 84 } 85 86 public boolean isEventLoggable() { 87 return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) || 88 (this == UNKNOWN_PDP_ADDRESS) || (this == USER_AUTHENTICATION) || 89 (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) || 90 (this == SERVICE_OPTION_NOT_SUBSCRIBED) || 91 (this == SERVICE_OPTION_NOT_SUPPORTED) || 92 (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) || 93 (this == PROTOCOL_ERRORS); 94 } 95 96 @Override 97 public String toString() { 98 switch (this) { 99 case NONE: 100 return "No Error"; 101 case OPERATOR_BARRED: 102 return "Operator Barred"; 103 case INSUFFICIENT_RESOURCES: 104 return "Insufficient Resources"; 105 case MISSING_UKNOWN_APN: 106 return "Missing / Unknown APN"; 107 case UNKNOWN_PDP_ADDRESS: 108 return "Unknown PDP Address"; 109 case USER_AUTHENTICATION: 110 return "Error User Autentication"; 111 case ACTIVATION_REJECT_GGSN: 112 return "Activation Reject GGSN"; 113 case ACTIVATION_REJECT_UNSPECIFIED: 114 return "Activation Reject unspecified"; 115 case SERVICE_OPTION_NOT_SUPPORTED: 116 return "Data Not Supported"; 117 case SERVICE_OPTION_NOT_SUBSCRIBED: 118 return "Data Not subscribed"; 119 case SERVICE_OPTION_OUT_OF_ORDER: 120 return "Data Services Out of Order"; 121 case NSAPI_IN_USE: 122 return "NSAPI in use"; 123 case PROTOCOL_ERRORS: 124 return "Protocol Errors"; 125 case REGISTRATION_FAIL: 126 return "Network Registration Failure"; 127 case GPRS_REGISTRATION_FAIL: 128 return "Data Network Registration Failure"; 129 case RADIO_NOT_AVAILABLE: 130 return "Radio Not Available"; 131 case RADIO_ERROR_RETRY: 132 return "Transient Radio Rrror"; 133 default: 134 return "Unknown Data Error"; 135 } 136 } 137 } 138 139 // ***** Event codes 140 protected static final int EVENT_SETUP_DATA_CONNECTION_DONE = 1; 141 protected static final int EVENT_GET_LAST_FAIL_DONE = 2; 142 protected static final int EVENT_LINK_STATE_CHANGED = 3; 143 protected static final int EVENT_DEACTIVATE_DONE = 4; 144 protected static final int EVENT_FORCE_RETRY = 5; 145 146 //***** Tag IDs for EventLog 147 protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100; 148 149 150 //***** Member Variables 151 protected PhoneBase phone; 152 protected Message onConnectCompleted; 153 protected Message onDisconnect; 154 protected int cid; 155 protected String interfaceName; 156 protected String ipAddress; 157 protected String gatewayAddress; 158 protected String[] dnsServers; 159 protected State state; 160 protected long createTime; 161 protected long lastFailTime; 162 protected FailCause lastFailCause; 163 protected static final String NULL_IP = "0.0.0.0"; 164 Object userData; 165 166 // receivedDisconnectReq is set when disconnect during activation 167 protected boolean receivedDisconnectReq; 168 169 /* Instance Methods */ 170 protected abstract void onSetupConnectionCompleted(AsyncResult ar); 171 172 protected abstract void onDeactivated(AsyncResult ar); 173 174 protected abstract void disconnect(Message msg); 175 176 protected abstract void notifyFail(FailCause cause, Message onCompleted); 177 178 protected abstract void notifyDisconnect(Message msg); 179 180 protected abstract void onLinkStateChanged(DataLink.LinkState linkState); 181 182 protected abstract FailCause getFailCauseFromRequest(int rilCause); 183 184 public abstract String toString(); 185 186 protected abstract void log(String s); 187 188 189 //***** Constructor 190 protected DataConnection(PhoneBase phone) { 191 super(); 192 this.phone = phone; 193 onConnectCompleted = null; 194 onDisconnect = null; 195 this.cid = -1; 196 receivedDisconnectReq = false; 197 this.dnsServers = new String[2]; 198 199 clearSettings(); 200 } 201 202 protected void setHttpProxy(String httpProxy, String httpPort) { 203 if (httpProxy == null || httpProxy.length() == 0) { 204 phone.setSystemProperty("net.gprs.http-proxy", null); 205 return; 206 } 207 208 if (httpPort == null || httpPort.length() == 0) { 209 httpPort = "8080"; // Default to port 8080 210 } 211 212 phone.setSystemProperty("net.gprs.http-proxy", 213 "http://" + httpProxy + ":" + httpPort + "/"); 214 } 215 216 public String getInterface() { 217 return interfaceName; 218 } 219 220 public String getIpAddress() { 221 return ipAddress; 222 } 223 224 public String getGatewayAddress() { 225 return gatewayAddress; 226 } 227 228 public String[] getDnsServers() { 229 return dnsServers; 230 } 231 232 public void clearSettings() { 233 log("DataConnection.clearSettings()"); 234 235 this.state = State.INACTIVE; 236 this.createTime = -1; 237 this.lastFailTime = -1; 238 this.lastFailCause = FailCause.NONE; 239 240 receivedDisconnectReq = false; 241 onConnectCompleted = null; 242 interfaceName = null; 243 ipAddress = null; 244 gatewayAddress = null; 245 dnsServers[0] = null; 246 dnsServers[1] = null; 247 } 248 249 protected void onGetLastFailCompleted(AsyncResult ar) { 250 if (receivedDisconnectReq) { 251 // Don't bother reporting the error if there's already a 252 // pending disconnect request, since DataConnectionTracker 253 // has already updated its state. 254 notifyDisconnect(onDisconnect); 255 } else { 256 FailCause cause = FailCause.UNKNOWN; 257 258 if (ar.exception == null) { 259 int rilFailCause = ((int[]) (ar.result))[0]; 260 cause = getFailCauseFromRequest(rilFailCause); 261 } 262 notifyFail(cause, onConnectCompleted); 263 } 264 } 265 266 protected void onForceRetry() { 267 if (receivedDisconnectReq) { 268 notifyDisconnect(onDisconnect); 269 } else { 270 notifyFail(FailCause.RADIO_ERROR_RETRY, onConnectCompleted); 271 } 272 } 273 274 @Override 275 public void handleMessage(Message msg) { 276 AsyncResult ar; 277 278 log("DataConnection.handleMessage()"); 279 280 switch (msg.what) { 281 282 case EVENT_SETUP_DATA_CONNECTION_DONE: 283 onSetupConnectionCompleted((AsyncResult) msg.obj); 284 break; 285 286 case EVENT_FORCE_RETRY: 287 onForceRetry(); 288 break; 289 290 case EVENT_GET_LAST_FAIL_DONE: 291 onGetLastFailCompleted((AsyncResult) msg.obj); 292 break; 293 294 case EVENT_LINK_STATE_CHANGED: 295 ar = (AsyncResult) msg.obj; 296 DataLink.LinkState ls = (DataLink.LinkState) ar.result; 297 onLinkStateChanged(ls); 298 break; 299 300 case EVENT_DEACTIVATE_DONE: 301 onDeactivated((AsyncResult) msg.obj); 302 break; 303 } 304 } 305 306 public State getState() { 307 log("DataConnection.getState()"); 308 return state; 309 } 310 311 public long getConnectionTime() { 312 log("DataConnection.getConnectionTime()"); 313 return createTime; 314 } 315 316 public long getLastFailTime() { 317 log("DataConnection.getLastFailTime()"); 318 return lastFailTime; 319 } 320 321 public FailCause getLastFailCause() { 322 log("DataConnection.getLastFailCause()"); 323 return lastFailCause; 324 } 325} 326