NetworkManagementService.java revision ce1200d42c46ae5d3ec637587b07dfdc02ad21c0
1873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat/* 2873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Copyright (C) 2007 The Android Open Source Project 3873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * 4873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Licensed under the Apache License, Version 2.0 (the "License"); 5873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * you may not use this file except in compliance with the License. 6873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * You may obtain a copy of the License at 7873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * 8873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * http://www.apache.org/licenses/LICENSE-2.0 9873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * 10873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Unless required by applicable law or agreed to in writing, software 11873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * distributed under the License is distributed on an "AS IS" BASIS, 12873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * See the License for the specific language governing permissions and 14873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * limitations under the License. 15873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 16873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 17873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatpackage com.android.server; 18873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 19873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.app.PendingIntent; 20873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.BroadcastReceiver; 21873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.Context; 22873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.Intent; 23873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.IntentFilter; 24873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.res.Resources; 25873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.pm.PackageManager; 26873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.net.Uri; 27ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehatimport android.net.InterfaceConfiguration; 284d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehatimport android.net.INetworkManagementEventObserver; 29873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.os.INetworkManagementService; 30873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.os.Handler; 3162dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissenimport android.os.SystemProperties; 32873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.text.TextUtils; 33873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.util.Log; 34873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.util.ArrayList; 35ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehatimport java.util.StringTokenizer; 36873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.provider.Settings; 37873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.ContentResolver; 38873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.database.ContentObserver; 39873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 40873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.io.File; 41873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.io.FileReader; 42873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.lang.IllegalStateException; 43873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 44873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.net.InetAddress; 45873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.net.UnknownHostException; 46873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 47873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat/** 48873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * @hide 49873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 50873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatclass NetworkManagementService extends INetworkManagementService.Stub { 51873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 52873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat private static final String TAG = "NetworkManagmentService"; 53873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 54873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat class NetdResponseCode { 55873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int InterfaceListResult = 110; 56873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int TetherInterfaceListResult = 111; 57873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int TetherDnsFwdTgtListResult = 112; 5872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat public static final int TtyListResult = 113; 59873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 60873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int TetherStatusResult = 210; 61873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int IpFwdStatusResult = 211; 62ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public static final int InterfaceGetCfgResult = 213; 63e325392c257a5460de6327420c81729f4e687881Robert Greenwalt public static final int SoftapStatusResult = 214; 64e325392c257a5460de6327420c81729f4e687881Robert Greenwalt public static final int UsbRNDISStatusResult = 215; 65e325392c257a5460de6327420c81729f4e687881Robert Greenwalt 66e325392c257a5460de6327420c81729f4e687881Robert Greenwalt public static final int InterfaceChange = 600; 67873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 68873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 69873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 70873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Binder context for this service 71873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 72873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat private Context mContext; 73873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 74873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 75873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * connector object for communicating with netd 76873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 77873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat private NativeDaemonConnector mConnector; 78873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 794d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private ArrayList<INetworkManagementEventObserver> mObservers; 804d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 81873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 82873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Constructs a new NetworkManagementService instance 83873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * 84873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * @param context Binder context for this service 85873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 86d1df8ac6d076ef15ba8857211da2e447b6505fb3San Mehat public NetworkManagementService(Context context) { 87873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext = context; 88873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 894d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers = new ArrayList<INetworkManagementEventObserver>(); 904d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 9162dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen if ("simulator".equals(SystemProperties.get("ro.product.device"))) { 9262dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen return; 9362dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen } 9462dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen 95873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector = new NativeDaemonConnector( 96873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat new NetdCallbackReceiver(), "netd", 10, "NetdConnector"); 97873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat Thread thread = new Thread(mConnector, NativeDaemonConnector.class.getName()); 98873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat thread.start(); 99873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 100873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 1014d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat public void registerObserver(INetworkManagementEventObserver obs) { 1024d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat Log.d(TAG, "Registering observer"); 1034d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers.add(obs); 1044d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1054d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1064d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat public void unregisterObserver(INetworkManagementEventObserver obs) { 1074d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat Log.d(TAG, "Unregistering observer"); 1084d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers.remove(mObservers.indexOf(obs)); 1094d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1104d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1114d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1124d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface link status change 1134d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1144d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceLinkStatusChanged(String iface, boolean link) { 1154d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1164d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1174d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceLinkStatusChanged(iface, link); 1184d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1194d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat Log.w(TAG, "Observer notifier failed", ex); 1204d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1214d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1224d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1234d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1244d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1254d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface addition. 1264d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1274d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceAdded(String iface) { 1284d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1294d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1304d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceAdded(iface); 1314d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1324d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat Log.w(TAG, "Observer notifier failed", ex); 1334d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1344d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1354d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1364d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1374d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1384d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface removal. 1394d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1404d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceRemoved(String iface) { 1414d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1424d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1434d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceRemoved(iface); 1444d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1454d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat Log.w(TAG, "Observer notifier failed", ex); 1464d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1474d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1484d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1494d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1504d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 151873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 152873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // Netd Callback handling 153873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 154873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 155873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { 156873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void onDaemonConnected() { 157873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat new Thread() { 158873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void run() { 159873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 160873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat }.start(); 161873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 162873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean onEvent(int code, String raw, String[] cooked) { 163e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (code == NetdResponseCode.InterfaceChange) { 164e325392c257a5460de6327420c81729f4e687881Robert Greenwalt /* 165e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * a network interface change occured 166e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * Format: "NNN Iface added <name>" 167e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * "NNN Iface removed <name>" 168e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * "NNN Iface changed <name> <up/down>" 169e325392c257a5460de6327420c81729f4e687881Robert Greenwalt */ 170e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (cooked.length < 4 || !cooked[1].equals("Iface")) { 171e325392c257a5460de6327420c81729f4e687881Robert Greenwalt throw new IllegalStateException( 172e325392c257a5460de6327420c81729f4e687881Robert Greenwalt String.format("Invalid event from daemon (%s)", raw)); 173e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 174e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (cooked[2].equals("added")) { 175e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceAdded(cooked[3]); 176e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 177e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } else if (cooked[2].equals("removed")) { 178e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceRemoved(cooked[3]); 179e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 180e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } else if (cooked[2].equals("changed") && cooked.length == 5) { 181e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceLinkStatusChanged(cooked[3], cooked[4].equals("up")); 182e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 183e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 184e325392c257a5460de6327420c81729f4e687881Robert Greenwalt throw new IllegalStateException( 185e325392c257a5460de6327420c81729f4e687881Robert Greenwalt String.format("Invalid event from daemon (%s)", raw)); 186e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 187e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return false; 188873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 189873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 190873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 191ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat private static int stringToIpAddr(String addrString) throws UnknownHostException { 192ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 193ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String[] parts = addrString.split("\\."); 194ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat if (parts.length != 4) { 195ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new UnknownHostException(addrString); 196ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 197ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 198ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int a = Integer.parseInt(parts[0]) ; 199ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int b = Integer.parseInt(parts[1]) << 8; 200ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int c = Integer.parseInt(parts[2]) << 16; 201ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int d = Integer.parseInt(parts[3]) << 24; 202ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 203ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return a | b | c | d; 204ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (NumberFormatException ex) { 205ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new UnknownHostException(addrString); 206ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 207ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 208ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 209ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public static String intToIpString(int i) { 210ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return ((i >> 24 ) & 0xFF) + "." + ((i >> 16 ) & 0xFF) + "." + ((i >> 8 ) & 0xFF) + "." + 211ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat (i & 0xFF); 212ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 213ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 214873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 215873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // INetworkManagementService members 216873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 217873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 218873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] listInterfaces() throws IllegalStateException { 219873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 220873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 221873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 222ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult); 223ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 224ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 225ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException { 226ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String rsp = mConnector.doCommand("interface getcfg " + iface).get(0); 227ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat Log.d(TAG, String.format("rsp <%s>", rsp)); 228ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 229ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz [flag1 flag2 flag3] 230ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat StringTokenizer st = new StringTokenizer(rsp); 231ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 232ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 233ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int code = Integer.parseInt(st.nextToken(" ")); 234ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat if (code != NetdResponseCode.InterfaceGetCfgResult) { 235ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new IllegalStateException( 236ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String.format("Expected code %d, but got %d", 237ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat NetdResponseCode.InterfaceGetCfgResult, code)); 238ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 239ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (NumberFormatException nfe) { 240ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new IllegalStateException( 241ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String.format("Invalid response from daemon (%s)", rsp)); 242ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 243ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 244ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat InterfaceConfiguration cfg = new InterfaceConfiguration(); 245ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.hwAddr = st.nextToken(" "); 246ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 247ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.ipAddr = stringToIpAddr(st.nextToken(" ")); 248ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (UnknownHostException uhe) { 249ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat Log.e(TAG, "Failed to parse ipaddr", uhe); 250ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.ipAddr = 0; 251ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 252ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 253ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 254ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.netmask = stringToIpAddr(st.nextToken(" ")); 255ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (UnknownHostException uhe) { 256ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat Log.e(TAG, "Failed to parse netmask", uhe); 257ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.netmask = 0; 258ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 259ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.interfaceFlags = st.nextToken("]"); 260ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat Log.d(TAG, String.format("flags <%s>", cfg.interfaceFlags)); 261ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return cfg; 262ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 263ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 264ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public void setInterfaceConfig( 265ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String iface, InterfaceConfiguration cfg) throws IllegalStateException { 266ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String cmd = String.format("interface setcfg %s %s %s", iface, 267ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat intToIpString(cfg.ipAddr), intToIpString(cfg.netmask), cfg.interfaceFlags); 268ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat mConnector.doCommand(cmd); 269873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 270873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 271873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void shutdown() { 272873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (mContext.checkCallingOrSelfPermission( 273873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.SHUTDOWN) 274873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat != PackageManager.PERMISSION_GRANTED) { 275873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new SecurityException("Requires SHUTDOWN permission"); 276873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 277873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 278873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat Log.d(TAG, "Shutting down"); 279873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 280873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 281873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean getIpForwardingEnabled() throws IllegalStateException{ 282873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 283873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 284873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 285873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat ArrayList<String> rsp = mConnector.doCommand("ipfwd status"); 286873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 287873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String line : rsp) { 288873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String []tok = line.split(" "); 289873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat int code = Integer.parseInt(tok[0]); 290873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (code == NetdResponseCode.IpFwdStatusResult) { 291873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 211 Forwarding <enabled/disabled> 292873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok.length !=2) { 293873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException( 294873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("Malformatted list entry '%s'", line)); 295873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 296873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok[2].equals("enabled")) 297873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return true; 298873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return false; 299873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } else { 300873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException(String.format("Unexpected response code %d", code)); 301873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 302873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 303873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Got an empty response"); 304873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 305873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 306873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void setIpForwardingEnabled(boolean enable) throws IllegalStateException { 307873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 308873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 309873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand(String.format("ipfwd %sable", (enable ? "en" : "dis"))); 310873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 311873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 312873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void startTethering(String dhcpRangeStart, String dhcpRangeEnd) 313873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 314873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 315873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 316873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand(String.format("tether start %s %s", dhcpRangeStart, dhcpRangeEnd)); 317873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 318873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 319873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void stopTethering() throws IllegalStateException { 320873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 321873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 322873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether stop"); 323873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 324873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 325873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean isTetheringStarted() throws IllegalStateException { 326873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 327873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 328873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 329873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat ArrayList<String> rsp = mConnector.doCommand("tether status"); 330873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 331873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String line : rsp) { 332873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String []tok = line.split(" "); 333873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat int code = Integer.parseInt(tok[0]); 334873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (code == NetdResponseCode.TetherStatusResult) { 335873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // XXX: Tethering services <started/stopped> <TBD>... 336873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok[2].equals("started")) 337873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return true; 338873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return false; 339873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } else { 340873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException(String.format("Unexpected response code %d", code)); 341873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 342873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 343873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Got an empty response"); 344873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 345873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 346873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void tetherInterface(String iface) throws IllegalStateException { 347873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 348873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 349873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether interface add " + iface); 350873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 351873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 352873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void untetherInterface(String iface) { 353873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 354873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 355873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether interface remove " + iface); 356873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 357873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 358873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] listTetheredInterfaces() throws IllegalStateException { 359873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 360873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 36172759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand( 36272759df749bb8557269db86c2e3b2a8a0343cc26San Mehat "tether interface list", NetdResponseCode.TetherInterfaceListResult); 363873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 364873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 365873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void setDnsForwarders(String[] dns) throws IllegalStateException { 366873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 367873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 368873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat try { 369d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt String cmd = "tether dns set"; 370873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String s : dns) { 371d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt cmd += " " + InetAddress.getByName(s).getHostAddress(); 372873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 373873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand(cmd); 374873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } catch (UnknownHostException e) { 375873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Error resolving dns name", e); 376873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 377873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 378873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 379873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] getDnsForwarders() throws IllegalStateException { 380873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 381873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 38272759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand( 38372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult); 384873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 385873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 386873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void enableNat(String internalInterface, String externalInterface) 387873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 388873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 389873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 390873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand( 391873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("nat enable %s %s", internalInterface, externalInterface)); 392873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 393873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 394873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void disableNat(String internalInterface, String externalInterface) 395873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 396873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 397873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 398873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand( 399873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("nat disable %s %s", internalInterface, externalInterface)); 400873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 40172759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 40272759df749bb8557269db86c2e3b2a8a0343cc26San Mehat public String[] listTtys() throws IllegalStateException { 40372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 40472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 40572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult); 40672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 40772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 408d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt public void attachPppd(String tty, String localAddr, String remoteAddr, String dns1Addr, 409d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt String dns2Addr) throws IllegalStateException { 41072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat try { 41172759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 41272759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 413d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mConnector.doCommand(String.format("pppd attach %s %s %s %s %s", tty, 414d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(localAddr).getHostAddress(), 415d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(remoteAddr).getHostAddress(), 416d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(dns1Addr).getHostAddress(), 417d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(dns2Addr).getHostAddress())); 41872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } catch (UnknownHostException e) { 41972759df749bb8557269db86c2e3b2a8a0343cc26San Mehat throw new IllegalStateException("Error resolving addr", e); 42072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 42172759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 42272759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 42372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat public void detachPppd(String tty) throws IllegalStateException { 42472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 42572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 42672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mConnector.doCommand(String.format("pppd detach %s", tty)); 42772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 428ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 429ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public void startUsbRNDIS() throws IllegalStateException { 430ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 431ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 432ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mConnector.doCommand("usb startrndis"); 433ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 434ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 435ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public void stopUsbRNDIS() throws IllegalStateException { 436ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 437ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 438ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mConnector.doCommand("usb stoprndis"); 439ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 440ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 441ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public boolean isUsbRNDISStarted() throws IllegalStateException { 442ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 443ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 444ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt ArrayList<String> rsp = mConnector.doCommand("usb rndisstatus"); 445ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 446ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt for (String line : rsp) { 447ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt String []tok = line.split(" "); 448ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt int code = Integer.parseInt(tok[0]); 449ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt if (code == NetdResponseCode.UsbRNDISStatusResult) { 450ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt if (tok[2].equals("started")) 451ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt return true; 452ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt return false; 453ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } else { 454ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt throw new IllegalStateException(String.format("Unexpected response code %d", code)); 455ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 456ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 457ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt throw new IllegalStateException("Got an empty response"); 458ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 459873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat} 460