1 /*
2  * Copyright (C) 2009 Qualcomm Innovation Center, Inc.  All Rights Reserved.
3  * Copyright (C) 2009 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.internal.telephony.dataconnection;
19 
20 import android.net.LinkAddress;
21 import android.net.LinkProperties;
22 import android.net.NetworkUtils;
23 import android.net.RouteInfo;
24 import android.os.SystemProperties;
25 import android.telephony.Rlog;
26 
27 import com.android.internal.telephony.PhoneConstants;
28 import com.android.internal.telephony.dataconnection.DcFailCause;
29 
30 import java.net.Inet4Address;
31 import java.net.InetAddress;
32 import java.net.UnknownHostException;
33 
34 /**
35  * This is RIL_Data_Call_Response_v5 from ril.h
36  */
37 public class DataCallResponse {
38     private final boolean DBG = true;
39     private final String LOG_TAG = "DataCallResponse";
40 
41     public int version = 0;
42     public int status = 0;
43     public int cid = 0;
44     public int active = 0;
45     public String type = "";
46     public String ifname = "";
47     public String [] addresses = new String[0];
48     public String [] dnses = new String[0];
49     public String[] gateways = new String[0];
50     public int suggestedRetryTime = -1;
51     public String [] pcscf = new String[0];
52     public int mtu = PhoneConstants.UNSET_MTU;
53 
54     /**
55      * Class returned by onSetupConnectionCompleted.
56      */
57     public enum SetupResult {
58         SUCCESS,
59         ERR_BadCommand,
60         ERR_UnacceptableParameter,
61         ERR_GetLastErrorFromRil,
62         ERR_Stale,
63         ERR_RilError;
64 
65         public DcFailCause mFailCause;
66 
SetupResult()67         SetupResult() {
68             mFailCause = DcFailCause.fromInt(0);
69         }
70 
71         @Override
toString()72         public String toString() {
73             return name() + "  SetupResult.mFailCause=" + mFailCause;
74         }
75     }
76 
77     @Override
toString()78     public String toString() {
79         StringBuffer sb = new StringBuffer();
80         sb.append("DataCallResponse: {")
81            .append("version=").append(version)
82            .append(" status=").append(status)
83            .append(" retry=").append(suggestedRetryTime)
84            .append(" cid=").append(cid)
85            .append(" active=").append(active)
86            .append(" type=").append(type)
87            .append(" ifname=").append(ifname)
88            .append(" mtu=").append(mtu)
89            .append(" addresses=[");
90         for (String addr : addresses) {
91             sb.append(addr);
92             sb.append(",");
93         }
94         if (addresses.length > 0) sb.deleteCharAt(sb.length()-1);
95         sb.append("] dnses=[");
96         for (String addr : dnses) {
97             sb.append(addr);
98             sb.append(",");
99         }
100         if (dnses.length > 0) sb.deleteCharAt(sb.length()-1);
101         sb.append("] gateways=[");
102         for (String addr : gateways) {
103             sb.append(addr);
104             sb.append(",");
105         }
106         if (gateways.length > 0) sb.deleteCharAt(sb.length()-1);
107         sb.append("] pcscf=[");
108         for (String addr : pcscf) {
109             sb.append(addr);
110             sb.append(",");
111         }
112         if (pcscf.length > 0) sb.deleteCharAt(sb.length()-1);
113         sb.append("]}");
114         return sb.toString();
115     }
116 
setLinkProperties(LinkProperties linkProperties, boolean okToUseSystemPropertyDns)117     public SetupResult setLinkProperties(LinkProperties linkProperties,
118             boolean okToUseSystemPropertyDns) {
119         SetupResult result;
120 
121         // Start with clean network properties and if we have
122         // a failure we'll clear again at the bottom of this code.
123         if (linkProperties == null)
124             linkProperties = new LinkProperties();
125         else
126             linkProperties.clear();
127 
128         if (status == DcFailCause.NONE.getErrorCode()) {
129             String propertyPrefix = "net." + ifname + ".";
130 
131             try {
132                 // set interface name
133                 linkProperties.setInterfaceName(ifname);
134 
135                 // set link addresses
136                 if (addresses != null && addresses.length > 0) {
137                     for (String addr : addresses) {
138                         addr = addr.trim();
139                         if (addr.isEmpty()) continue;
140                         LinkAddress la;
141                         int addrPrefixLen;
142 
143                         String [] ap = addr.split("/");
144                         if (ap.length == 2) {
145                             addr = ap[0];
146                             addrPrefixLen = Integer.parseInt(ap[1]);
147                         } else {
148                             addrPrefixLen = 0;
149                         }
150                         InetAddress ia;
151                         try {
152                             ia = NetworkUtils.numericToInetAddress(addr);
153                         } catch (IllegalArgumentException e) {
154                             throw new UnknownHostException("Non-numeric ip addr=" + addr);
155                         }
156                         if (! ia.isAnyLocalAddress()) {
157                             if (addrPrefixLen == 0) {
158                                 // Assume point to point
159                                 addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128;
160                             }
161                             if (DBG) Rlog.d(LOG_TAG, "addr/pl=" + addr + "/" + addrPrefixLen);
162                             try {
163                                 la = new LinkAddress(ia, addrPrefixLen);
164                             } catch (IllegalArgumentException e) {
165                                 throw new UnknownHostException("Bad parameter for LinkAddress, ia="
166                                         + ia.getHostAddress() + "/" + addrPrefixLen);
167                             }
168 
169                             linkProperties.addLinkAddress(la);
170                         }
171                     }
172                 } else {
173                     throw new UnknownHostException("no address for ifname=" + ifname);
174                 }
175 
176                 // set dns servers
177                 if (dnses != null && dnses.length > 0) {
178                     for (String addr : dnses) {
179                         addr = addr.trim();
180                         if (addr.isEmpty()) continue;
181                         InetAddress ia;
182                         try {
183                             ia = NetworkUtils.numericToInetAddress(addr);
184                         } catch (IllegalArgumentException e) {
185                             throw new UnknownHostException("Non-numeric dns addr=" + addr);
186                         }
187                         if (! ia.isAnyLocalAddress()) {
188                             linkProperties.addDnsServer(ia);
189                         }
190                     }
191                 } else if (okToUseSystemPropertyDns){
192                     String dnsServers[] = new String[2];
193                     dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
194                     dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
195                     for (String dnsAddr : dnsServers) {
196                         dnsAddr = dnsAddr.trim();
197                         if (dnsAddr.isEmpty()) continue;
198                         InetAddress ia;
199                         try {
200                             ia = NetworkUtils.numericToInetAddress(dnsAddr);
201                         } catch (IllegalArgumentException e) {
202                             throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr);
203                         }
204                         if (! ia.isAnyLocalAddress()) {
205                             linkProperties.addDnsServer(ia);
206                         }
207                     }
208                 } else {
209                     throw new UnknownHostException("Empty dns response and no system default dns");
210                 }
211 
212                 // set gateways
213                 if ((gateways == null) || (gateways.length == 0)) {
214                     String sysGateways = SystemProperties.get(propertyPrefix + "gw");
215                     if (sysGateways != null) {
216                         gateways = sysGateways.split(" ");
217                     } else {
218                         gateways = new String[0];
219                     }
220                 }
221                 for (String addr : gateways) {
222                     addr = addr.trim();
223                     if (addr.isEmpty()) continue;
224                     InetAddress ia;
225                     try {
226                         ia = NetworkUtils.numericToInetAddress(addr);
227                     } catch (IllegalArgumentException e) {
228                         throw new UnknownHostException("Non-numeric gateway addr=" + addr);
229                     }
230                     // Allow 0.0.0.0 or :: as a gateway; this indicates a point-to-point interface.
231                     linkProperties.addRoute(new RouteInfo(ia));
232                 }
233 
234                 // set interface MTU
235                 // this may clobber the setting read from the APN db, but that's ok
236                 linkProperties.setMtu(mtu);
237 
238                 result = SetupResult.SUCCESS;
239             } catch (UnknownHostException e) {
240                 Rlog.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e);
241                 e.printStackTrace();
242                 result = SetupResult.ERR_UnacceptableParameter;
243             }
244         } else {
245             if (version < 4) {
246                 result = SetupResult.ERR_GetLastErrorFromRil;
247             } else {
248                 result = SetupResult.ERR_RilError;
249             }
250         }
251 
252         // An error occurred so clear properties
253         if (result != SetupResult.SUCCESS) {
254             if(DBG) {
255                 Rlog.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " +
256                         "status=" + status + " result=" + result);
257             }
258             linkProperties.clear();
259         }
260 
261         return result;
262     }
263 }
264