NetworkManagementService.java revision a6e559edb73886c626e0e5a95085d0ead767ceb7
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; 299ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriffimport android.net.wifi.WifiConfiguration; 309ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriffimport android.net.wifi.WifiConfiguration.KeyMgmt; 31873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.os.INetworkManagementService; 32873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.os.Handler; 3362dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissenimport android.os.SystemProperties; 34873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.text.TextUtils; 359ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriffimport android.util.Log; 368a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 37873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.util.ArrayList; 38ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehatimport java.util.StringTokenizer; 39873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.provider.Settings; 40873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.content.ContentResolver; 41873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport android.database.ContentObserver; 42873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 43873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.io.File; 44873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.io.FileReader; 45873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.lang.IllegalStateException; 46873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 47873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.net.InetAddress; 48873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatimport java.net.UnknownHostException; 49873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 50873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat/** 51873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * @hide 52873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 53873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehatclass NetworkManagementService extends INetworkManagementService.Stub { 54873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 55873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat private static final String TAG = "NetworkManagmentService"; 56873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 57873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat class NetdResponseCode { 58873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int InterfaceListResult = 110; 59873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int TetherInterfaceListResult = 111; 60873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int TetherDnsFwdTgtListResult = 112; 6172759df749bb8557269db86c2e3b2a8a0343cc26San Mehat public static final int TtyListResult = 113; 62873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 63873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int TetherStatusResult = 210; 64873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public static final int IpFwdStatusResult = 211; 65ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public static final int InterfaceGetCfgResult = 213; 66e325392c257a5460de6327420c81729f4e687881Robert Greenwalt public static final int SoftapStatusResult = 214; 67e325392c257a5460de6327420c81729f4e687881Robert Greenwalt public static final int UsbRNDISStatusResult = 215; 6891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat public static final int InterfaceRxCounterResult = 216; 6991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat public static final int InterfaceTxCounterResult = 217; 7091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat public static final int InterfaceRxThrottleResult = 218; 7191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat public static final int InterfaceTxThrottleResult = 219; 72e325392c257a5460de6327420c81729f4e687881Robert Greenwalt 73e325392c257a5460de6327420c81729f4e687881Robert Greenwalt public static final int InterfaceChange = 600; 74873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 75873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 76873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 77873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Binder context for this service 78873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 79873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat private Context mContext; 80873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 81873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 82873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * connector object for communicating with netd 83873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 84873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat private NativeDaemonConnector mConnector; 85873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 864d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private ArrayList<INetworkManagementEventObserver> mObservers; 874d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 88873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 89873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Constructs a new NetworkManagementService instance 90873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * 91873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * @param context Binder context for this service 92873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 93d1df8ac6d076ef15ba8857211da2e447b6505fb3San Mehat public NetworkManagementService(Context context) { 94873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext = context; 95873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 964d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers = new ArrayList<INetworkManagementEventObserver>(); 974d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 9862dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen if ("simulator".equals(SystemProperties.get("ro.product.device"))) { 9962dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen return; 10062dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen } 10162dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen 102873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector = new NativeDaemonConnector( 103873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat new NetdCallbackReceiver(), "netd", 10, "NetdConnector"); 104873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat Thread thread = new Thread(mConnector, NativeDaemonConnector.class.getName()); 105873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat thread.start(); 106873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 107873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 1084d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat public void registerObserver(INetworkManagementEventObserver obs) { 1098a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, "Registering observer"); 1104d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers.add(obs); 1114d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1124d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1134d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat public void unregisterObserver(INetworkManagementEventObserver obs) { 1148a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, "Unregistering observer"); 1154d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers.remove(mObservers.indexOf(obs)); 1164d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1174d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1184d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1194d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface link status change 1204d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1214d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceLinkStatusChanged(String iface, boolean link) { 1224d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1234d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1244d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceLinkStatusChanged(iface, link); 1254d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1268a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Observer notifier failed", ex); 1274d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1284d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1294d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1304d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1314d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1324d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface addition. 1334d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1344d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceAdded(String iface) { 1354d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1364d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1374d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceAdded(iface); 1384d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1398a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Observer notifier failed", ex); 1404d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1414d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1424d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1434d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1444d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1454d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface removal. 1464d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1474d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceRemoved(String iface) { 1484d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1494d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1504d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceRemoved(iface); 1514d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Observer notifier failed", ex); 1534d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1544d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1554d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1564d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1574d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 158873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 159873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // Netd Callback handling 160873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 161873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 162873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { 163873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void onDaemonConnected() { 164873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat new Thread() { 165873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void run() { 166873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 167873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat }.start(); 168873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 169873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean onEvent(int code, String raw, String[] cooked) { 170e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (code == NetdResponseCode.InterfaceChange) { 171e325392c257a5460de6327420c81729f4e687881Robert Greenwalt /* 172e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * a network interface change occured 173e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * Format: "NNN Iface added <name>" 174e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * "NNN Iface removed <name>" 175e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * "NNN Iface changed <name> <up/down>" 176e325392c257a5460de6327420c81729f4e687881Robert Greenwalt */ 177e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (cooked.length < 4 || !cooked[1].equals("Iface")) { 178e325392c257a5460de6327420c81729f4e687881Robert Greenwalt throw new IllegalStateException( 179e325392c257a5460de6327420c81729f4e687881Robert Greenwalt String.format("Invalid event from daemon (%s)", raw)); 180e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 181e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (cooked[2].equals("added")) { 182e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceAdded(cooked[3]); 183e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 184e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } else if (cooked[2].equals("removed")) { 185e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceRemoved(cooked[3]); 186e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 187e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } else if (cooked[2].equals("changed") && cooked.length == 5) { 188e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceLinkStatusChanged(cooked[3], cooked[4].equals("up")); 189e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 190e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 191e325392c257a5460de6327420c81729f4e687881Robert Greenwalt throw new IllegalStateException( 192e325392c257a5460de6327420c81729f4e687881Robert Greenwalt String.format("Invalid event from daemon (%s)", raw)); 193e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 194e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return false; 195873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 196873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 197873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 198ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat private static int stringToIpAddr(String addrString) throws UnknownHostException { 199ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 200ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String[] parts = addrString.split("\\."); 201ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat if (parts.length != 4) { 202ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new UnknownHostException(addrString); 203ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 204ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 205ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int a = Integer.parseInt(parts[0]) ; 206ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int b = Integer.parseInt(parts[1]) << 8; 207ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int c = Integer.parseInt(parts[2]) << 16; 208ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int d = Integer.parseInt(parts[3]) << 24; 209ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 210ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return a | b | c | d; 211ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (NumberFormatException ex) { 212ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new UnknownHostException(addrString); 213ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 214ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 215ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 216ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public static String intToIpString(int i) { 217ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return ((i >> 24 ) & 0xFF) + "." + ((i >> 16 ) & 0xFF) + "." + ((i >> 8 ) & 0xFF) + "." + 218ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat (i & 0xFF); 219ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 220ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 221873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 222873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // INetworkManagementService members 223873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 224873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 225873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] listInterfaces() throws IllegalStateException { 226873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 227873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 228873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 229ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult); 230ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 231ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 232ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException { 233ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String rsp = mConnector.doCommand("interface getcfg " + iface).get(0); 2348a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, String.format("rsp <%s>", rsp)); 235ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 236ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz [flag1 flag2 flag3] 237ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat StringTokenizer st = new StringTokenizer(rsp); 238ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 239ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 240ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int code = Integer.parseInt(st.nextToken(" ")); 241ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat if (code != NetdResponseCode.InterfaceGetCfgResult) { 242ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new IllegalStateException( 243ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String.format("Expected code %d, but got %d", 244ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat NetdResponseCode.InterfaceGetCfgResult, code)); 245ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 246ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (NumberFormatException nfe) { 247ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new IllegalStateException( 248ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String.format("Invalid response from daemon (%s)", rsp)); 249ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 250ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 251ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat InterfaceConfiguration cfg = new InterfaceConfiguration(); 252ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.hwAddr = st.nextToken(" "); 253ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 254ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.ipAddr = stringToIpAddr(st.nextToken(" ")); 255ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (UnknownHostException uhe) { 2568a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "Failed to parse ipaddr", uhe); 257ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.ipAddr = 0; 258ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 259ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 260ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 261ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.netmask = stringToIpAddr(st.nextToken(" ")); 262ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (UnknownHostException uhe) { 2638a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "Failed to parse netmask", uhe); 264ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.netmask = 0; 265ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 26665ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt cfg.interfaceFlags = st.nextToken("]").trim() +"]"; 2678a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, String.format("flags <%s>", cfg.interfaceFlags)); 268ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return cfg; 269ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 270ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 271ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public void setInterfaceConfig( 272ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String iface, InterfaceConfiguration cfg) throws IllegalStateException { 27365ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt String cmd = String.format("interface setcfg %s %s %s %s", iface, 274ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat intToIpString(cfg.ipAddr), intToIpString(cfg.netmask), cfg.interfaceFlags); 275ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat mConnector.doCommand(cmd); 276873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 277873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 278873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void shutdown() { 279873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (mContext.checkCallingOrSelfPermission( 280873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.SHUTDOWN) 281873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat != PackageManager.PERMISSION_GRANTED) { 282873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new SecurityException("Requires SHUTDOWN permission"); 283873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 284873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 2858a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, "Shutting down"); 286873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 287873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 288873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean getIpForwardingEnabled() throws IllegalStateException{ 289873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 290873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 291873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 292873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat ArrayList<String> rsp = mConnector.doCommand("ipfwd status"); 293873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 294873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String line : rsp) { 295873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String []tok = line.split(" "); 296873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat int code = Integer.parseInt(tok[0]); 297873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (code == NetdResponseCode.IpFwdStatusResult) { 298873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 211 Forwarding <enabled/disabled> 299873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok.length !=2) { 300873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException( 301873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("Malformatted list entry '%s'", line)); 302873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 303873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok[2].equals("enabled")) 304873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return true; 305873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return false; 306873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } else { 307873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException(String.format("Unexpected response code %d", code)); 308873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 309873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 310873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Got an empty response"); 311873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 312873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 313873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void setIpForwardingEnabled(boolean enable) throws IllegalStateException { 314873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 315873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 316873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand(String.format("ipfwd %sable", (enable ? "en" : "dis"))); 317873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 318873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 319bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt public void startTethering(String[] dhcpRange) 320873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 321873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 322873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 323bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt // cmd is "tether start first_start first_stop second_start second_stop ..." 324bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt // an odd number of addrs will fail 325bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt String cmd = "tether start"; 326bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt for (String d : dhcpRange) { 327bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt cmd += " " + d; 328bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt } 329bfb7bfa53847832db2a3eb05e5eff7cb974c3c7aRobert Greenwalt mConnector.doCommand(cmd); 330873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 331873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 332873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void stopTethering() throws IllegalStateException { 333873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 334873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 335873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether stop"); 336873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 337873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 338873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean isTetheringStarted() throws IllegalStateException { 339873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 340873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 341873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 342873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat ArrayList<String> rsp = mConnector.doCommand("tether status"); 343873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 344873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String line : rsp) { 345873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String []tok = line.split(" "); 346873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat int code = Integer.parseInt(tok[0]); 347873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (code == NetdResponseCode.TetherStatusResult) { 348873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // XXX: Tethering services <started/stopped> <TBD>... 349873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok[2].equals("started")) 350873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return true; 351873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return false; 352873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } else { 353873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException(String.format("Unexpected response code %d", code)); 354873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 355873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 356873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Got an empty response"); 357873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 358873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 359873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void tetherInterface(String iface) throws IllegalStateException { 360873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 361873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 362873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether interface add " + iface); 363873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 364873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 365873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void untetherInterface(String iface) { 366873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 367873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 368873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether interface remove " + iface); 369873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 370873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 371873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] listTetheredInterfaces() throws IllegalStateException { 372873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 373873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 37472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand( 37572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat "tether interface list", NetdResponseCode.TetherInterfaceListResult); 376873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 377873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 378873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void setDnsForwarders(String[] dns) throws IllegalStateException { 379873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 380873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 381873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat try { 382d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt String cmd = "tether dns set"; 383873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String s : dns) { 384d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt cmd += " " + InetAddress.getByName(s).getHostAddress(); 385873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 386873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand(cmd); 387873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } catch (UnknownHostException e) { 388873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Error resolving dns name", e); 389873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 390873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 391873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 392873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] getDnsForwarders() throws IllegalStateException { 393873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 394873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 39572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand( 39672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult); 397873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 398873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 399873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void enableNat(String internalInterface, String externalInterface) 400873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 401873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 402873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 403873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand( 404873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("nat enable %s %s", internalInterface, externalInterface)); 405873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 406873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 407873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void disableNat(String internalInterface, String externalInterface) 408873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 409873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 410873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 411873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand( 412873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("nat disable %s %s", internalInterface, externalInterface)); 413873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 41472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 41572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat public String[] listTtys() throws IllegalStateException { 41672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 41772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 41872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult); 41972759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 42072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 421d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt public void attachPppd(String tty, String localAddr, String remoteAddr, String dns1Addr, 422d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt String dns2Addr) throws IllegalStateException { 42372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat try { 42472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 42572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 426d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mConnector.doCommand(String.format("pppd attach %s %s %s %s %s", tty, 427d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(localAddr).getHostAddress(), 428d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(remoteAddr).getHostAddress(), 429d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(dns1Addr).getHostAddress(), 430d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(dns2Addr).getHostAddress())); 43172759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } catch (UnknownHostException e) { 43272759df749bb8557269db86c2e3b2a8a0343cc26San Mehat throw new IllegalStateException("Error resolving addr", e); 43372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 43472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 43572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 43672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat public void detachPppd(String tty) throws IllegalStateException { 43772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 43872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 43972759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mConnector.doCommand(String.format("pppd detach %s", tty)); 44072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 441ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 442ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public void startUsbRNDIS() throws IllegalStateException { 443ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 444ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 445ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mConnector.doCommand("usb startrndis"); 446ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 447ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 448ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public void stopUsbRNDIS() throws IllegalStateException { 449ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 450ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 451ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mConnector.doCommand("usb stoprndis"); 452ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 453ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 454ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public boolean isUsbRNDISStarted() throws IllegalStateException { 455ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 456ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 457ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt ArrayList<String> rsp = mConnector.doCommand("usb rndisstatus"); 458ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 459ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt for (String line : rsp) { 460ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt String []tok = line.split(" "); 461ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt int code = Integer.parseInt(tok[0]); 462ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt if (code == NetdResponseCode.UsbRNDISStatusResult) { 46351cb9d5d55a673f329c17a689f724af772257804Mike Lockwood if (tok[3].equals("started")) 464ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt return true; 465ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt return false; 466ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } else { 467ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt throw new IllegalStateException(String.format("Unexpected response code %d", code)); 468ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 469ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 470ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt throw new IllegalStateException("Got an empty response"); 471ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 4725321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 473c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff public void startAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface) 4745321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff throws IllegalStateException { 4755321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff mContext.enforceCallingOrSelfPermission( 4765321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 4775321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff mContext.enforceCallingOrSelfPermission( 478c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 479c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap stop " + wlanIface)); 480c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP")); 481c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap start " + wlanIface)); 4829ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff if (wifiConfig == null) { 483c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface)); 4849ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff } else { 4859ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff /** 4869ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * softap set arg1 arg2 arg3 [arg4 arg5 arg6 arg7 arg8] 4879ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv1 - wlan interface 4889ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv2 - softap interface 4899ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv3 - SSID 4909ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv4 - Security 4919ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv5 - Key 4929ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv6 - Channel 4939ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv7 - Preamble 4949ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv8 - Max SCB 4959ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff */ 496723f1097294396817bbe1ea0fc45cfea4a6430daIrfan Sheriff String str = String.format("softap set " + wlanIface + " " + softapIface + 497a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff " %s %s %s", convertQuotedString(wifiConfig.SSID), 4989ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? 4999ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff "wpa2-psk" : "open", 500a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff convertQuotedString(wifiConfig.preSharedKey)); 5019ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff mConnector.doCommand(str); 5029ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff } 5039ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff mConnector.doCommand(String.format("softap startap")); 5045321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 5055321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 506a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff private String convertQuotedString(String s) { 507a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff /* Replace \ with \\, then " with \" and add quotes at end */ 508a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff return '"' + s.replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\\\"") + '"'; 509a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff } 510a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff 5115321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff public void stopAccessPoint() throws IllegalStateException { 5125321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff mContext.enforceCallingOrSelfPermission( 5135321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 5145321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff mContext.enforceCallingOrSelfPermission( 515c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 5169ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff mConnector.doCommand("softap stopap"); 5175321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 5185321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 519c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface) 520c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff throws IllegalStateException { 521c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mContext.enforceCallingOrSelfPermission( 522c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 523c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mContext.enforceCallingOrSelfPermission( 524c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 525c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff if (wifiConfig == null) { 526c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface)); 527c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff } else { 528c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff String str = String.format("softap set " + wlanIface + " " + softapIface + 529a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff " %s %s %s", convertQuotedString(wifiConfig.SSID), 530c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? 531c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff "wpa2-psk" : "open", 532a6e559edb73886c626e0e5a95085d0ead767ceb7Irfan Sheriff convertQuotedString(wifiConfig.preSharedKey)); 533c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(str); 534c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff } 535c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff } 53691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat 53791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat private long getInterfaceCounter(String iface, boolean rx) { 53891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat mContext.enforceCallingOrSelfPermission( 53991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 54091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat try { 54191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat String rsp = mConnector.doCommand( 54291cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat String.format("interface read%scounter %s", (rx ? "rx" : "tx"), iface)).get(0); 54391cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat String []tok = rsp.split(" "); 54491cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat int code; 54591cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat try { 54691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat code = Integer.parseInt(tok[0]); 54791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } catch (NumberFormatException nfe) { 54891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat Slog.e(TAG, String.format("Error parsing code %s", tok[0])); 54991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return -1; 55091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 55191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat if ((rx && code != NetdResponseCode.InterfaceRxCounterResult) || ( 55291cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat !rx && code != NetdResponseCode.InterfaceTxCounterResult)) { 55391cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat Slog.e(TAG, String.format("Unexpected response code %d", code)); 55491cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return -1; 55591cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 55691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return Long.parseLong(tok[1]); 55791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } catch (Exception e) { 55891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat Slog.e(TAG, String.format( 55991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat "Failed to read interface %s counters", (rx ? "rx" : "tx")), e); 56091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 56191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return -1; 56291cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 56391cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat 56491cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat public long getInterfaceRxCounter(String iface) { 56591cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return getInterfaceCounter(iface, true); 56691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 56791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat 56891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat public long getInterfaceTxCounter(String iface) { 56991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return getInterfaceCounter(iface, false); 57091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 57191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat 572f0db6e1853e929ae3b65501c31ee57c4dfbc767cSan Mehat public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) { 57391cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat mContext.enforceCallingOrSelfPermission( 57491cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 57591cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat mConnector.doCommand(String.format( 576f0db6e1853e929ae3b65501c31ee57c4dfbc767cSan Mehat "interface setthrottle %s %d %d", iface, rxKbps, txKbps)); 57791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 57891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat 57991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat private int getInterfaceThrottle(String iface, boolean rx) { 58091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat mContext.enforceCallingOrSelfPermission( 58191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 58291cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat try { 58391cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat String rsp = mConnector.doCommand( 58491cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat String.format("interface getthrottle %s %s", iface,(rx ? "rx" : "tx"))).get(0); 58591cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat String []tok = rsp.split(" "); 58691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat int code; 58791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat try { 58891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat code = Integer.parseInt(tok[0]); 58991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } catch (NumberFormatException nfe) { 59091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat Slog.e(TAG, String.format("Error parsing code %s", tok[0])); 59191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return -1; 59291cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 59391cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat if ((rx && code != NetdResponseCode.InterfaceRxThrottleResult) || ( 59491cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat !rx && code != NetdResponseCode.InterfaceTxThrottleResult)) { 59591cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat Slog.e(TAG, String.format("Unexpected response code %d", code)); 59691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return -1; 59791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 59891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return Integer.parseInt(tok[1]); 59991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } catch (Exception e) { 60091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat Slog.e(TAG, String.format( 60191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat "Failed to read interface %s throttle value", (rx ? "rx" : "tx")), e); 60291cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 60391cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return -1; 60491cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 60591cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat 60691cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat public int getInterfaceRxThrottle(String iface) { 60791cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return getInterfaceThrottle(iface, true); 60891cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 60991cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat 61091cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat public int getInterfaceTxThrottle(String iface) { 61191cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat return getInterfaceThrottle(iface, false); 61291cac64cd010e6b4006fdd14b39dbc75778f20cbSan Mehat } 613873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat} 614