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
18package com.android.internal.telephony;
19
20import android.net.LinkAddress;
21import android.net.LinkProperties;
22import android.net.NetworkUtils;
23import android.net.RouteInfo;
24import android.os.SystemProperties;
25import android.util.Log;
26
27import com.android.internal.telephony.DataConnection.FailCause;
28
29import java.net.Inet4Address;
30import java.net.InetAddress;
31import java.net.UnknownHostException;
32
33/**
34 * This is RIL_Data_Call_Response_v5 from ril.h
35 * TODO: Rename to DataCallResponse.
36 */
37public class DataCallState {
38    private final boolean DBG = true;
39    private final String LOG_TAG = "GSM";
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
52    /**
53     * Class returned by onSetupConnectionCompleted.
54     */
55    public enum SetupResult {
56        SUCCESS,
57        ERR_BadCommand,
58        ERR_UnacceptableParameter,
59        ERR_GetLastErrorFromRil,
60        ERR_Stale,
61        ERR_RilError;
62
63        public FailCause mFailCause;
64
65        SetupResult() {
66            mFailCause = FailCause.fromInt(0);
67        }
68
69        @Override
70        public String toString() {
71            return name() + "  SetupResult.mFailCause=" + mFailCause;
72        }
73    }
74
75    @Override
76    public String toString() {
77        StringBuffer sb = new StringBuffer();
78        sb.append("DataCallState: {")
79           .append("version=").append(version)
80           .append(" status=").append(status)
81           .append(" retry=").append(suggestedRetryTime)
82           .append(" cid=").append(cid)
83           .append(" active=").append(active)
84           .append(" type=").append(type)
85           .append("' ifname='").append(ifname);
86        sb.append("' addresses=[");
87        for (String addr : addresses) {
88            sb.append(addr);
89            sb.append(",");
90        }
91        if (addresses.length > 0) sb.deleteCharAt(sb.length()-1);
92        sb.append("] dnses=[");
93        for (String addr : dnses) {
94            sb.append(addr);
95            sb.append(",");
96        }
97        if (dnses.length > 0) sb.deleteCharAt(sb.length()-1);
98        sb.append("] gateways=[");
99        for (String addr : gateways) {
100            sb.append(addr);
101            sb.append(",");
102        }
103        if (gateways.length > 0) sb.deleteCharAt(sb.length()-1);
104        sb.append("]}");
105        return sb.toString();
106    }
107
108    public SetupResult setLinkProperties(LinkProperties linkProperties,
109            boolean okToUseSystemPropertyDns) {
110        SetupResult result;
111
112        // Start with clean network properties and if we have
113        // a failure we'll clear again at the bottom of this code.
114        if (linkProperties == null)
115            linkProperties = new LinkProperties();
116        else
117            linkProperties.clear();
118
119        if (status == FailCause.NONE.getErrorCode()) {
120            String propertyPrefix = "net." + ifname + ".";
121
122            try {
123                // set interface name
124                linkProperties.setInterfaceName(ifname);
125
126                // set link addresses
127                if (addresses != null && addresses.length > 0) {
128                    for (String addr : addresses) {
129                        addr = addr.trim();
130                        if (addr.isEmpty()) continue;
131                        LinkAddress la;
132                        int addrPrefixLen;
133
134                        String [] ap = addr.split("/");
135                        if (ap.length == 2) {
136                            addr = ap[0];
137                            addrPrefixLen = Integer.parseInt(ap[1]);
138                        } else {
139                            addrPrefixLen = 0;
140                        }
141                        InetAddress ia;
142                        try {
143                            ia = NetworkUtils.numericToInetAddress(addr);
144                        } catch (IllegalArgumentException e) {
145                            throw new UnknownHostException("Non-numeric ip addr=" + addr);
146                        }
147                        if (! ia.isAnyLocalAddress()) {
148                            if (addrPrefixLen == 0) {
149                                // Assume point to point
150                                addrPrefixLen = (ia instanceof Inet4Address) ? 32 : 128;
151                            }
152                            if (DBG) Log.d(LOG_TAG, "addr/pl=" + addr + "/" + addrPrefixLen);
153                            la = new LinkAddress(ia, addrPrefixLen);
154                            linkProperties.addLinkAddress(la);
155                        }
156                    }
157                } else {
158                    throw new UnknownHostException("no address for ifname=" + ifname);
159                }
160
161                // set dns servers
162                if (dnses != null && dnses.length > 0) {
163                    for (String addr : dnses) {
164                        addr = addr.trim();
165                        if (addr.isEmpty()) continue;
166                        InetAddress ia;
167                        try {
168                            ia = NetworkUtils.numericToInetAddress(addr);
169                        } catch (IllegalArgumentException e) {
170                            throw new UnknownHostException("Non-numeric dns addr=" + addr);
171                        }
172                        if (! ia.isAnyLocalAddress()) {
173                            linkProperties.addDns(ia);
174                        }
175                    }
176                } else if (okToUseSystemPropertyDns){
177                    String dnsServers[] = new String[2];
178                    dnsServers[0] = SystemProperties.get(propertyPrefix + "dns1");
179                    dnsServers[1] = SystemProperties.get(propertyPrefix + "dns2");
180                    for (String dnsAddr : dnsServers) {
181                        dnsAddr = dnsAddr.trim();
182                        if (dnsAddr.isEmpty()) continue;
183                        InetAddress ia;
184                        try {
185                            ia = NetworkUtils.numericToInetAddress(dnsAddr);
186                        } catch (IllegalArgumentException e) {
187                            throw new UnknownHostException("Non-numeric dns addr=" + dnsAddr);
188                        }
189                        if (! ia.isAnyLocalAddress()) {
190                            linkProperties.addDns(ia);
191                        }
192                    }
193                } else {
194                    throw new UnknownHostException("Empty dns response and no system default dns");
195                }
196
197                // set gateways
198                if ((gateways == null) || (gateways.length == 0)) {
199                    String sysGateways = SystemProperties.get(propertyPrefix + "gw");
200                    if (sysGateways != null) {
201                        gateways = sysGateways.split(" ");
202                    } else {
203                        gateways = new String[0];
204                    }
205                }
206                for (String addr : gateways) {
207                    addr = addr.trim();
208                    if (addr.isEmpty()) continue;
209                    InetAddress ia;
210                    try {
211                        ia = NetworkUtils.numericToInetAddress(addr);
212                    } catch (IllegalArgumentException e) {
213                        throw new UnknownHostException("Non-numeric gateway addr=" + addr);
214                    }
215                    if (! ia.isAnyLocalAddress()) {
216                        linkProperties.addRoute(new RouteInfo(ia));
217                    }
218                }
219
220                result = SetupResult.SUCCESS;
221            } catch (UnknownHostException e) {
222                Log.d(LOG_TAG, "setLinkProperties: UnknownHostException " + e);
223                e.printStackTrace();
224                result = SetupResult.ERR_UnacceptableParameter;
225            }
226        } else {
227            if (version < 4) {
228                result = SetupResult.ERR_GetLastErrorFromRil;
229            } else {
230                result = SetupResult.ERR_RilError;
231            }
232        }
233
234        // An error occurred so clear properties
235        if (result != SetupResult.SUCCESS) {
236            if(DBG) {
237                Log.d(LOG_TAG, "setLinkProperties: error clearing LinkProperties " +
238                        "status=" + status + " result=" + result);
239            }
240            linkProperties.clear();
241        }
242
243        return result;
244    }
245}
246