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