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 17 package com.android.internal.telephony.dataconnection; 18 19 import android.text.TextUtils; 20 21 import com.android.internal.telephony.PhoneConstants; 22 import com.android.internal.telephony.RILConstants; 23 24 import java.util.ArrayList; 25 import java.util.List; 26 import java.util.Locale; 27 28 /** 29 * This class represents a apn setting for create PDP link 30 */ 31 public class ApnSetting { 32 33 static final String V2_FORMAT_REGEX = "^\\[ApnSettingV2\\]\\s*"; 34 static final String V3_FORMAT_REGEX = "^\\[ApnSettingV3\\]\\s*"; 35 36 public final String carrier; 37 public final String apn; 38 public final String proxy; 39 public final String port; 40 public final String mmsc; 41 public final String mmsProxy; 42 public final String mmsPort; 43 public final String user; 44 public final String password; 45 public final int authType; 46 public final String[] types; 47 public final int id; 48 public final String numeric; 49 public final String protocol; 50 public final String roamingProtocol; 51 public final int mtu; 52 53 /** 54 * Current status of APN 55 * true : enabled APN, false : disabled APN. 56 */ 57 public final boolean carrierEnabled; 58 /** 59 * Radio Access Technology info 60 * To check what values can hold, refer to ServiceState.java. 61 * This should be spread to other technologies, 62 * but currently only used for LTE(14) and EHRPD(13). 63 */ 64 public final int bearer; 65 66 /* ID of the profile in the modem */ 67 public final int profileId; 68 public final boolean modemCognitive; 69 public final int maxConns; 70 public final int waitTime; 71 public final int maxConnsTime; 72 73 /** 74 * MVNO match type. Possible values: 75 * "spn": Service provider name. 76 * "imsi": IMSI. 77 * "gid": Group identifier level 1. 78 */ 79 public final String mvnoType; 80 /** 81 * MVNO data. Examples: 82 * "spn": A MOBILE, BEN NL 83 * "imsi": 302720x94, 2060188 84 * "gid": 4E, 33 85 */ 86 public final String mvnoMatchData; 87 88 public ApnSetting(int id, String numeric, String carrier, String apn, 89 String proxy, String port, 90 String mmsc, String mmsProxy, String mmsPort, 91 String user, String password, int authType, String[] types, 92 String protocol, String roamingProtocol, boolean carrierEnabled, int bearer, 93 int profileId, boolean modemCognitive, int maxConns, int waitTime, int maxConnsTime, 94 int mtu, String mvnoType, String mvnoMatchData) { 95 this.id = id; 96 this.numeric = numeric; 97 this.carrier = carrier; 98 this.apn = apn; 99 this.proxy = proxy; 100 this.port = port; 101 this.mmsc = mmsc; 102 this.mmsProxy = mmsProxy; 103 this.mmsPort = mmsPort; 104 this.user = user; 105 this.password = password; 106 this.authType = authType; 107 this.types = new String[types.length]; 108 for (int i = 0; i < types.length; i++) { 109 this.types[i] = types[i].toLowerCase(Locale.ROOT); 110 } 111 this.protocol = protocol; 112 this.roamingProtocol = roamingProtocol; 113 this.carrierEnabled = carrierEnabled; 114 this.bearer = bearer; 115 this.profileId = profileId; 116 this.modemCognitive = modemCognitive; 117 this.maxConns = maxConns; 118 this.waitTime = waitTime; 119 this.maxConnsTime = maxConnsTime; 120 this.mtu = mtu; 121 this.mvnoType = mvnoType; 122 this.mvnoMatchData = mvnoMatchData; 123 124 } 125 126 /** 127 * Creates an ApnSetting object from a string. 128 * 129 * @param data the string to read. 130 * 131 * The string must be in one of two formats (newlines added for clarity, 132 * spaces are optional): 133 * 134 * v1 format: 135 * <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>, 136 * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>, 137 * <type>[| <type>...], 138 * 139 * v2 format: 140 * [ApnSettingV2] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>, 141 * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>, 142 * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearer>, 143 * 144 * v3 format: 145 * [ApnSettingV3] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>, 146 * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>, 147 * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearer>, 148 * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>, 149 * <mvnoType>, <mvnoMatchData> 150 * 151 * Note that the strings generated by toString() do not contain the username 152 * and password and thus cannot be read by this method. 153 */ 154 public static ApnSetting fromString(String data) { 155 if (data == null) return null; 156 157 int version; 158 // matches() operates on the whole string, so append .* to the regex. 159 if (data.matches(V3_FORMAT_REGEX + ".*")) { 160 version = 3; 161 data = data.replaceFirst(V3_FORMAT_REGEX, ""); 162 } else if (data.matches(V2_FORMAT_REGEX + ".*")) { 163 version = 2; 164 data = data.replaceFirst(V2_FORMAT_REGEX, ""); 165 } else { 166 version = 1; 167 } 168 169 String[] a = data.split("\\s*,\\s*"); 170 if (a.length < 14) { 171 return null; 172 } 173 174 int authType; 175 try { 176 authType = Integer.parseInt(a[12]); 177 } catch (NumberFormatException e) { 178 authType = 0; 179 } 180 181 String[] typeArray; 182 String protocol, roamingProtocol; 183 boolean carrierEnabled; 184 int bearer = 0; 185 int profileId = 0; 186 boolean modemCognitive = false; 187 int maxConns = 0; 188 int waitTime = 0; 189 int maxConnsTime = 0; 190 int mtu = PhoneConstants.UNSET_MTU; 191 String mvnoType = ""; 192 String mvnoMatchData = ""; 193 if (version == 1) { 194 typeArray = new String[a.length - 13]; 195 System.arraycopy(a, 13, typeArray, 0, a.length - 13); 196 protocol = RILConstants.SETUP_DATA_PROTOCOL_IP; 197 roamingProtocol = RILConstants.SETUP_DATA_PROTOCOL_IP; 198 carrierEnabled = true; 199 bearer = 0; 200 } else { 201 if (a.length < 18) { 202 return null; 203 } 204 typeArray = a[13].split("\\s*\\|\\s*"); 205 protocol = a[14]; 206 roamingProtocol = a[15]; 207 carrierEnabled = Boolean.parseBoolean(a[16]); 208 209 try { 210 bearer = Integer.parseInt(a[17]); 211 } catch (NumberFormatException ex) { 212 } 213 214 if (a.length > 22) { 215 modemCognitive = Boolean.parseBoolean(a[19]); 216 try { 217 profileId = Integer.parseInt(a[18]); 218 maxConns = Integer.parseInt(a[20]); 219 waitTime = Integer.parseInt(a[21]); 220 maxConnsTime = Integer.parseInt(a[22]); 221 } catch (NumberFormatException e) { 222 } 223 } 224 if (a.length > 23) { 225 try { 226 mtu = Integer.parseInt(a[23]); 227 } catch (NumberFormatException e) { 228 } 229 } 230 if (a.length > 25) { 231 mvnoType = a[24]; 232 mvnoMatchData = a[25]; 233 } 234 } 235 236 return new ApnSetting(-1,a[10]+a[11],a[0],a[1],a[2],a[3],a[7],a[8], 237 a[9],a[4],a[5],authType,typeArray,protocol,roamingProtocol,carrierEnabled,bearer, 238 profileId, modemCognitive, maxConns, waitTime, maxConnsTime, mtu, 239 mvnoType, mvnoMatchData); 240 } 241 242 /** 243 * Creates an array of ApnSetting objects from a string. 244 * 245 * @param data the string to read. 246 * 247 * Builds on top of the same format used by fromString, but allows for multiple entries 248 * separated by "; ". 249 */ 250 public static List<ApnSetting> arrayFromString(String data) { 251 List<ApnSetting> retVal = new ArrayList<ApnSetting>(); 252 if (TextUtils.isEmpty(data)) { 253 return retVal; 254 } 255 String[] apnStrings = data.split("\\s*;\\s*"); 256 for (String apnString : apnStrings) { 257 ApnSetting apn = fromString(apnString); 258 if (apn != null) { 259 retVal.add(apn); 260 } 261 } 262 return retVal; 263 } 264 265 @Override 266 public String toString() { 267 StringBuilder sb = new StringBuilder(); 268 sb.append("[ApnSettingV3] ") 269 .append(carrier) 270 .append(", ").append(id) 271 .append(", ").append(numeric) 272 .append(", ").append(apn) 273 .append(", ").append(proxy) 274 .append(", ").append(mmsc) 275 .append(", ").append(mmsProxy) 276 .append(", ").append(mmsPort) 277 .append(", ").append(port) 278 .append(", ").append(authType).append(", "); 279 for (int i = 0; i < types.length; i++) { 280 sb.append(types[i]); 281 if (i < types.length - 1) { 282 sb.append(" | "); 283 } 284 } 285 sb.append(", ").append(protocol); 286 sb.append(", ").append(roamingProtocol); 287 sb.append(", ").append(carrierEnabled); 288 sb.append(", ").append(bearer); 289 sb.append(", ").append(profileId); 290 sb.append(", ").append(modemCognitive); 291 sb.append(", ").append(maxConns); 292 sb.append(", ").append(waitTime); 293 sb.append(", ").append(maxConnsTime); 294 sb.append(", ").append(mtu); 295 sb.append(", ").append(mvnoType); 296 sb.append(", ").append(mvnoMatchData); 297 return sb.toString(); 298 } 299 300 /** 301 * Returns true if there are MVNO params specified. 302 */ 303 public boolean hasMvnoParams() { 304 return !TextUtils.isEmpty(mvnoType) && !TextUtils.isEmpty(mvnoMatchData); 305 } 306 307 public boolean canHandleType(String type) { 308 if (!carrierEnabled) return false; 309 for (String t : types) { 310 // DEFAULT handles all, and HIPRI is handled by DEFAULT 311 if (t.equalsIgnoreCase(type) || 312 t.equalsIgnoreCase(PhoneConstants.APN_TYPE_ALL) || 313 (t.equalsIgnoreCase(PhoneConstants.APN_TYPE_DEFAULT) && 314 type.equalsIgnoreCase(PhoneConstants.APN_TYPE_HIPRI))) { 315 return true; 316 } 317 } 318 return false; 319 } 320 321 // TODO - if we have this function we should also have hashCode. 322 // Also should handle changes in type order and perhaps case-insensitivity 323 @Override 324 public boolean equals(Object o) { 325 if (o instanceof ApnSetting == false) return false; 326 return (toString().equals(o.toString())); 327 } 328 } 329