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.gsm; 18 19import android.os.Message; 20import android.util.Log; 21import android.util.Patterns; 22 23import com.android.internal.telephony.DataConnection; 24import com.android.internal.telephony.Phone; 25import com.android.internal.telephony.RILConstants; 26 27/** 28 * {@hide} 29 */ 30public class GsmDataConnection extends DataConnection { 31 32 private static final String LOG_TAG = "GSM"; 33 34 /** Fail cause of last PDP activate, from RIL_LastPDPActivateFailCause */ 35 private static final int PDP_FAIL_OPERATOR_BARRED = 0x08; 36 private static final int PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A; 37 private static final int PDP_FAIL_MISSING_UKNOWN_APN = 0x1B; 38 private static final int PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C; 39 private static final int PDP_FAIL_USER_AUTHENTICATION = 0x1D; 40 private static final int PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E; 41 private static final int PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F; 42 private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20; 43 private static final int PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21; 44 private static final int PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22; 45 private static final int PDP_FAIL_NSAPI_IN_USE = 0x23; 46 private static final int PDP_FAIL_PROTOCOL_ERRORS = 0x6F; 47 private static final int PDP_FAIL_ERROR_UNSPECIFIED = 0xffff; 48 49 private static final int PDP_FAIL_REGISTRATION_FAIL = -1; 50 private static final int PDP_FAIL_GPRS_REGISTRATION_FAIL = -2; 51 52 //***** Instance Variables 53 private ApnSetting apn; 54 55 //***** Constructor 56 private GsmDataConnection(GSMPhone phone, String name) { 57 super(phone, name); 58 } 59 60 /** 61 * Create the connection object 62 * 63 * @param phone 64 * @return GsmDataConnection that was created. 65 */ 66 static GsmDataConnection makeDataConnection(GSMPhone phone) { 67 synchronized (mCountLock) { 68 mCount += 1; 69 } 70 GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount); 71 gsmDc.start(); 72 if (DBG) gsmDc.log("Made " + gsmDc.getName()); 73 return gsmDc; 74 } 75 76 /** 77 * Begin setting up a data connection, calls setupDataCall 78 * and the ConnectionParams will be returned with the 79 * EVENT_SETUP_DATA_CONNECTION_DONE AsyncResul.userObj. 80 * 81 * @param cp is the connection parameters 82 */ 83 @Override 84 protected 85 void onConnect(ConnectionParams cp) { 86 apn = cp.apn; 87 88 if (DBG) log("Connecting to carrier: '" + apn.carrier 89 + "' APN: '" + apn.apn 90 + "' proxy: '" + apn.proxy + "' port: '" + apn.port); 91 92 setHttpProxy (apn.proxy, apn.port); 93 94 createTime = -1; 95 lastFailTime = -1; 96 lastFailCause = FailCause.NONE; 97 98 // msg.obj will be returned in AsyncResult.userObj; 99 Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp); 100 msg.obj = cp; 101 102 int authType = apn.authType; 103 if (authType == -1) { 104 authType = (apn.user != null) ? RILConstants.SETUP_DATA_AUTH_PAP_CHAP : 105 RILConstants.SETUP_DATA_AUTH_NONE; 106 } 107 108 String protocol; 109 if (phone.getServiceState().getRoaming()) { 110 protocol = apn.roamingProtocol; 111 } else { 112 protocol = apn.protocol; 113 } 114 115 phone.mCM.setupDataCall( 116 Integer.toString(RILConstants.SETUP_DATA_TECH_GSM), 117 Integer.toString(RILConstants.DATA_PROFILE_DEFAULT), 118 apn.apn, apn.user, apn.password, Integer.toString(authType), 119 protocol, msg); 120 } 121 122 @Override 123 protected void clearSettings() { 124 super.clearSettings(); 125 apn = null; 126 } 127 128 @Override 129 public String toString() { 130 return "State=" + getCurrentState().getName() + " Apn=" + apn + 131 " create=" + createTime + " lastFail=" + lastFailTime + 132 " lastFailCause=" + lastFailCause; 133 } 134 135 @Override 136 protected FailCause getFailCauseFromRequest(int rilCause) { 137 FailCause cause; 138 139 switch (rilCause) { 140 case PDP_FAIL_OPERATOR_BARRED: 141 cause = FailCause.OPERATOR_BARRED; 142 break; 143 case PDP_FAIL_INSUFFICIENT_RESOURCES: 144 cause = FailCause.INSUFFICIENT_RESOURCES; 145 break; 146 case PDP_FAIL_MISSING_UKNOWN_APN: 147 cause = FailCause.MISSING_UNKNOWN_APN; 148 break; 149 case PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE: 150 cause = FailCause.UNKNOWN_PDP_ADDRESS; 151 break; 152 case PDP_FAIL_USER_AUTHENTICATION: 153 cause = FailCause.USER_AUTHENTICATION; 154 break; 155 case PDP_FAIL_ACTIVATION_REJECT_GGSN: 156 cause = FailCause.ACTIVATION_REJECT_GGSN; 157 break; 158 case PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED: 159 cause = FailCause.ACTIVATION_REJECT_UNSPECIFIED; 160 break; 161 case PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER: 162 cause = FailCause.SERVICE_OPTION_OUT_OF_ORDER; 163 break; 164 case PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED: 165 cause = FailCause.SERVICE_OPTION_NOT_SUPPORTED; 166 break; 167 case PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED: 168 cause = FailCause.SERVICE_OPTION_NOT_SUBSCRIBED; 169 break; 170 case PDP_FAIL_NSAPI_IN_USE: 171 cause = FailCause.NSAPI_IN_USE; 172 break; 173 case PDP_FAIL_PROTOCOL_ERRORS: 174 cause = FailCause.PROTOCOL_ERRORS; 175 break; 176 case PDP_FAIL_ERROR_UNSPECIFIED: 177 cause = FailCause.UNKNOWN; 178 break; 179 case PDP_FAIL_REGISTRATION_FAIL: 180 cause = FailCause.REGISTRATION_FAIL; 181 break; 182 case PDP_FAIL_GPRS_REGISTRATION_FAIL: 183 cause = FailCause.GPRS_REGISTRATION_FAIL; 184 break; 185 default: 186 cause = FailCause.UNKNOWN; 187 } 188 return cause; 189 } 190 191 @Override 192 protected boolean isDnsOk(String[] domainNameServers) { 193 if (NULL_IP.equals(dnsServers[0]) && NULL_IP.equals(dnsServers[1]) 194 && !((GSMPhone) phone).isDnsCheckDisabled()) { 195 // Work around a race condition where QMI does not fill in DNS: 196 // Deactivate PDP and let DataConnectionTracker retry. 197 // Do not apply the race condition workaround for MMS APN 198 // if Proxy is an IP-address. 199 // Otherwise, the default APN will not be restored anymore. 200 if (!apn.types[0].equals(Phone.APN_TYPE_MMS) 201 || !isIpAddress(apn.mmsProxy)) { 202 return false; 203 } 204 } 205 return true; 206 } 207 208 @Override 209 protected void log(String s) { 210 Log.d(LOG_TAG, "[" + getName() + "] " + s); 211 } 212 213 public ApnSetting getApn() { 214 return this.apn; 215 } 216 217 private void setHttpProxy(String httpProxy, String httpPort) { 218 if (httpProxy == null || httpProxy.length() == 0) { 219 phone.setSystemProperty("net.gprs.http-proxy", null); 220 return; 221 } 222 223 if (httpPort == null || httpPort.length() == 0) { 224 httpPort = "8080"; // Default to port 8080 225 } 226 227 phone.setSystemProperty("net.gprs.http-proxy", 228 "http://" + httpProxy + ":" + httpPort + "/"); 229 } 230 231 private boolean isIpAddress(String address) { 232 if (address == null) return false; 233 234 return Patterns.IP_ADDRESS.matcher(apn.mmsProxy).matches(); 235 } 236} 237