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 
ApnSetting(int id, String numeric, String carrier, String apn, String proxy, String port, String mmsc, String mmsProxy, String mmsPort, String user, String password, int authType, String[] types, String protocol, String roamingProtocol, boolean carrierEnabled, int bearer, int profileId, boolean modemCognitive, int maxConns, int waitTime, int maxConnsTime, int mtu, String mvnoType, String mvnoMatchData)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      */
fromString(String data)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      */
arrayFromString(String data)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
toString()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      */
hasMvnoParams()303     public boolean hasMvnoParams() {
304         return !TextUtils.isEmpty(mvnoType) && !TextUtils.isEmpty(mvnoMatchData);
305     }
306 
canHandleType(String type)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
equals(Object o)324     public boolean equals(Object o) {
325         if (o instanceof ApnSetting == false) return false;
326         return (toString().equals(o.toString()));
327     }
328 }
329