NetworkManagementService.java revision c2f54c267b896cd1799d82be81e904a2b56c2f26
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; 68e325392c257a5460de6327420c81729f4e687881Robert Greenwalt 69e325392c257a5460de6327420c81729f4e687881Robert Greenwalt public static final int InterfaceChange = 600; 70873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 71873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 72873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 73873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Binder context for this service 74873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 75873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat private Context mContext; 76873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 77873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 78873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * connector object for communicating with netd 79873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 80873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat private NativeDaemonConnector mConnector; 81873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 824d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private ArrayList<INetworkManagementEventObserver> mObservers; 834d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 84873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat /** 85873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * Constructs a new NetworkManagementService instance 86873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * 87873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat * @param context Binder context for this service 88873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat */ 89d1df8ac6d076ef15ba8857211da2e447b6505fb3San Mehat public NetworkManagementService(Context context) { 90873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext = context; 91873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 924d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers = new ArrayList<INetworkManagementEventObserver>(); 934d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 9462dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen if ("simulator".equals(SystemProperties.get("ro.product.device"))) { 9562dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen return; 9662dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen } 9762dbb22bd4878369975492c8a1c234840e418a4fMarco Nelissen 98873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector = new NativeDaemonConnector( 99873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat new NetdCallbackReceiver(), "netd", 10, "NetdConnector"); 100873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat Thread thread = new Thread(mConnector, NativeDaemonConnector.class.getName()); 101873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat thread.start(); 102873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 103873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 1044d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat public void registerObserver(INetworkManagementEventObserver obs) { 1058a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, "Registering observer"); 1064d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers.add(obs); 1074d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1084d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1094d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat public void unregisterObserver(INetworkManagementEventObserver obs) { 1108a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, "Unregistering observer"); 1114d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat mObservers.remove(mObservers.indexOf(obs)); 1124d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1134d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1144d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1154d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface link status change 1164d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1174d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceLinkStatusChanged(String iface, boolean link) { 1184d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1194d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1204d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceLinkStatusChanged(iface, link); 1214d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1228a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Observer notifier failed", ex); 1234d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1244d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1254d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1264d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1274d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1284d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface addition. 1294d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1304d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceAdded(String iface) { 1314d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1324d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1334d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceAdded(iface); 1344d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1358a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Observer notifier failed", ex); 1364d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1374d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1384d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1394d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1404d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat /** 1414d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat * Notify our observers of an interface removal. 1424d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat */ 1434d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat private void notifyInterfaceRemoved(String iface) { 1444d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat for (INetworkManagementEventObserver obs : mObservers) { 1454d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat try { 1464d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat obs.interfaceRemoved(iface); 1474d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } catch (Exception ex) { 1488a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Observer notifier failed", ex); 1494d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1504d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1514d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat } 1524d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 1534d02d001ef6e06583e858e63e48d1aebf54ba28dSan Mehat 154873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 155873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // Netd Callback handling 156873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 157873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 158873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { 159873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void onDaemonConnected() { 160873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat new Thread() { 161873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void run() { 162873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 163873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat }.start(); 164873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 165873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean onEvent(int code, String raw, String[] cooked) { 166e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (code == NetdResponseCode.InterfaceChange) { 167e325392c257a5460de6327420c81729f4e687881Robert Greenwalt /* 168e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * a network interface change occured 169e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * Format: "NNN Iface added <name>" 170e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * "NNN Iface removed <name>" 171e325392c257a5460de6327420c81729f4e687881Robert Greenwalt * "NNN Iface changed <name> <up/down>" 172e325392c257a5460de6327420c81729f4e687881Robert Greenwalt */ 173e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (cooked.length < 4 || !cooked[1].equals("Iface")) { 174e325392c257a5460de6327420c81729f4e687881Robert Greenwalt throw new IllegalStateException( 175e325392c257a5460de6327420c81729f4e687881Robert Greenwalt String.format("Invalid event from daemon (%s)", raw)); 176e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 177e325392c257a5460de6327420c81729f4e687881Robert Greenwalt if (cooked[2].equals("added")) { 178e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceAdded(cooked[3]); 179e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 180e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } else if (cooked[2].equals("removed")) { 181e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceRemoved(cooked[3]); 182e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 183e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } else if (cooked[2].equals("changed") && cooked.length == 5) { 184e325392c257a5460de6327420c81729f4e687881Robert Greenwalt notifyInterfaceLinkStatusChanged(cooked[3], cooked[4].equals("up")); 185e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return true; 186e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 187e325392c257a5460de6327420c81729f4e687881Robert Greenwalt throw new IllegalStateException( 188e325392c257a5460de6327420c81729f4e687881Robert Greenwalt String.format("Invalid event from daemon (%s)", raw)); 189e325392c257a5460de6327420c81729f4e687881Robert Greenwalt } 190e325392c257a5460de6327420c81729f4e687881Robert Greenwalt return false; 191873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 192873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 193873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 194ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat private static int stringToIpAddr(String addrString) throws UnknownHostException { 195ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 196ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String[] parts = addrString.split("\\."); 197ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat if (parts.length != 4) { 198ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new UnknownHostException(addrString); 199ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 200ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 201ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int a = Integer.parseInt(parts[0]) ; 202ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int b = Integer.parseInt(parts[1]) << 8; 203ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int c = Integer.parseInt(parts[2]) << 16; 204ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int d = Integer.parseInt(parts[3]) << 24; 205ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 206ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return a | b | c | d; 207ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (NumberFormatException ex) { 208ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new UnknownHostException(addrString); 209ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 210ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 211ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 212ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public static String intToIpString(int i) { 213ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return ((i >> 24 ) & 0xFF) + "." + ((i >> 16 ) & 0xFF) + "." + ((i >> 8 ) & 0xFF) + "." + 214ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat (i & 0xFF); 215ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 216ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 217873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 218873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // INetworkManagementService members 219873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 220873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 221873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] listInterfaces() throws IllegalStateException { 222873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 223873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 224873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 225ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult); 226ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 227ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 228ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException { 229ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String rsp = mConnector.doCommand("interface getcfg " + iface).get(0); 2308a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, String.format("rsp <%s>", rsp)); 231ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 232ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz [flag1 flag2 flag3] 233ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat StringTokenizer st = new StringTokenizer(rsp); 234ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 235ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 236ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat int code = Integer.parseInt(st.nextToken(" ")); 237ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat if (code != NetdResponseCode.InterfaceGetCfgResult) { 238ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new IllegalStateException( 239ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String.format("Expected code %d, but got %d", 240ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat NetdResponseCode.InterfaceGetCfgResult, code)); 241ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 242ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (NumberFormatException nfe) { 243ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat throw new IllegalStateException( 244ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String.format("Invalid response from daemon (%s)", rsp)); 245ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 246ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 247ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat InterfaceConfiguration cfg = new InterfaceConfiguration(); 248ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.hwAddr = st.nextToken(" "); 249ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 250ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.ipAddr = stringToIpAddr(st.nextToken(" ")); 251ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (UnknownHostException uhe) { 2528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "Failed to parse ipaddr", uhe); 253ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.ipAddr = 0; 254ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 255ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 256ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat try { 257ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.netmask = stringToIpAddr(st.nextToken(" ")); 258ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } catch (UnknownHostException uhe) { 2598a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "Failed to parse netmask", uhe); 260ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat cfg.netmask = 0; 261ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 26265ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt cfg.interfaceFlags = st.nextToken("]").trim() +"]"; 2638a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, String.format("flags <%s>", cfg.interfaceFlags)); 264ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat return cfg; 265ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat } 266ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat 267ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat public void setInterfaceConfig( 268ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat String iface, InterfaceConfiguration cfg) throws IllegalStateException { 26965ae29bd852ff468ad003af241d5177fe016c74aRobert Greenwalt String cmd = String.format("interface setcfg %s %s %s %s", iface, 270ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat intToIpString(cfg.ipAddr), intToIpString(cfg.netmask), cfg.interfaceFlags); 271ed4fc8acc52d89f1d4dec853a29288c6d06717c3San Mehat mConnector.doCommand(cmd); 272873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 273873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 274873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void shutdown() { 275873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (mContext.checkCallingOrSelfPermission( 276873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.SHUTDOWN) 277873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat != PackageManager.PERMISSION_GRANTED) { 278873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new SecurityException("Requires SHUTDOWN permission"); 279873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 280873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 2818a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, "Shutting down"); 282873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 283873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 284873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean getIpForwardingEnabled() throws IllegalStateException{ 285873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 286873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 287873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 288873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat ArrayList<String> rsp = mConnector.doCommand("ipfwd status"); 289873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 290873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String line : rsp) { 291873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String []tok = line.split(" "); 292873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat int code = Integer.parseInt(tok[0]); 293873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (code == NetdResponseCode.IpFwdStatusResult) { 294873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // 211 Forwarding <enabled/disabled> 295873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok.length !=2) { 296873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException( 297873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("Malformatted list entry '%s'", line)); 298873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 299873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok[2].equals("enabled")) 300873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return true; 301873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return false; 302873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } else { 303873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException(String.format("Unexpected response code %d", code)); 304873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 305873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 306873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Got an empty response"); 307873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 308873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 309873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void setIpForwardingEnabled(boolean enable) throws IllegalStateException { 310873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 311873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 312873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand(String.format("ipfwd %sable", (enable ? "en" : "dis"))); 313873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 314873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 315873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void startTethering(String dhcpRangeStart, String dhcpRangeEnd) 316873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 317873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 318873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 319873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand(String.format("tether start %s %s", dhcpRangeStart, dhcpRangeEnd)); 320873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 321873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 322873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void stopTethering() throws IllegalStateException { 323873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 324873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 325873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether stop"); 326873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 327873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 328873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public boolean isTetheringStarted() throws IllegalStateException { 329873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 330873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 331873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 332873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat ArrayList<String> rsp = mConnector.doCommand("tether status"); 333873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 334873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String line : rsp) { 335873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String []tok = line.split(" "); 336873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat int code = Integer.parseInt(tok[0]); 337873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (code == NetdResponseCode.TetherStatusResult) { 338873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat // XXX: Tethering services <started/stopped> <TBD>... 339873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat if (tok[2].equals("started")) 340873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return true; 341873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat return false; 342873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } else { 343873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException(String.format("Unexpected response code %d", code)); 344873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 345873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 346873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Got an empty response"); 347873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 348873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 349873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void tetherInterface(String iface) throws IllegalStateException { 350873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 351873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 352873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether interface add " + iface); 353873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 354873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 355873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void untetherInterface(String iface) { 356873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 357873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 358873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand("tether interface remove " + iface); 359873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 360873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 361873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] listTetheredInterfaces() throws IllegalStateException { 362873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 363873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 36472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand( 36572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat "tether interface list", NetdResponseCode.TetherInterfaceListResult); 366873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 367873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 368873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void setDnsForwarders(String[] dns) throws IllegalStateException { 369873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 370873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 371873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat try { 372d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt String cmd = "tether dns set"; 373873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat for (String s : dns) { 374d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt cmd += " " + InetAddress.getByName(s).getHostAddress(); 375873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 376873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand(cmd); 377873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } catch (UnknownHostException e) { 378873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throw new IllegalStateException("Error resolving dns name", e); 379873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 380873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 381873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 382873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public String[] getDnsForwarders() throws IllegalStateException { 383873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 384873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 38572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand( 38672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult); 387873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 388873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 389873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void enableNat(String internalInterface, String externalInterface) 390873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 391873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 392873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 393873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand( 394873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("nat enable %s %s", internalInterface, externalInterface)); 395873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 396873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat 397873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat public void disableNat(String internalInterface, String externalInterface) 398873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat throws IllegalStateException { 399873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mContext.enforceCallingOrSelfPermission( 400873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 401873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat mConnector.doCommand( 402873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat String.format("nat disable %s %s", internalInterface, externalInterface)); 403873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat } 40472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 40572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat public String[] listTtys() throws IllegalStateException { 40672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 40772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 40872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult); 40972759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 41072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 411d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt public void attachPppd(String tty, String localAddr, String remoteAddr, String dns1Addr, 412d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt String dns2Addr) throws IllegalStateException { 41372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat try { 41472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 41572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 416d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt mConnector.doCommand(String.format("pppd attach %s %s %s %s %s", tty, 417d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(localAddr).getHostAddress(), 418d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(remoteAddr).getHostAddress(), 419d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(dns1Addr).getHostAddress(), 420d0e18ffb82b59d38aeaf0e552f48e734202719abRobert Greenwalt InetAddress.getByName(dns2Addr).getHostAddress())); 42172759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } catch (UnknownHostException e) { 42272759df749bb8557269db86c2e3b2a8a0343cc26San Mehat throw new IllegalStateException("Error resolving addr", e); 42372759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 42472759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 42572759df749bb8557269db86c2e3b2a8a0343cc26San Mehat 42672759df749bb8557269db86c2e3b2a8a0343cc26San Mehat public void detachPppd(String tty) throws IllegalStateException { 42772759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mContext.enforceCallingOrSelfPermission( 42872759df749bb8557269db86c2e3b2a8a0343cc26San Mehat android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 42972759df749bb8557269db86c2e3b2a8a0343cc26San Mehat mConnector.doCommand(String.format("pppd detach %s", tty)); 43072759df749bb8557269db86c2e3b2a8a0343cc26San Mehat } 431ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 432ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public void startUsbRNDIS() throws IllegalStateException { 433ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 434ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 435ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mConnector.doCommand("usb startrndis"); 436ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 437ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 438ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public void stopUsbRNDIS() throws IllegalStateException { 439ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 440ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 441ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mConnector.doCommand("usb stoprndis"); 442ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 443ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 444ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt public boolean isUsbRNDISStarted() throws IllegalStateException { 445ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt mContext.enforceCallingOrSelfPermission( 446ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 447ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt ArrayList<String> rsp = mConnector.doCommand("usb rndisstatus"); 448ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt 449ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt for (String line : rsp) { 450ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt String []tok = line.split(" "); 451ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt int code = Integer.parseInt(tok[0]); 452ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt if (code == NetdResponseCode.UsbRNDISStatusResult) { 45351cb9d5d55a673f329c17a689f724af772257804Mike Lockwood if (tok[3].equals("started")) 454ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt return true; 455ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt return false; 456ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } else { 457ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt throw new IllegalStateException(String.format("Unexpected response code %d", code)); 458ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 459ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 460ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt throw new IllegalStateException("Got an empty response"); 461ce1200d42c46ae5d3ec637587b07dfdc02ad21c0Robert Greenwalt } 4625321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 463c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff public void startAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface) 4645321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff throws IllegalStateException { 4655321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff mContext.enforceCallingOrSelfPermission( 4665321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 4675321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff mContext.enforceCallingOrSelfPermission( 468c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 469c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap stop " + wlanIface)); 470c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP")); 471c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap start " + wlanIface)); 4729ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff if (wifiConfig == null) { 473c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface)); 4749ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff } else { 4759ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff /** 4769ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * softap set arg1 arg2 arg3 [arg4 arg5 arg6 arg7 arg8] 4779ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv1 - wlan interface 4789ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv2 - softap interface 4799ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv3 - SSID 4809ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv4 - Security 4819ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv5 - Key 4829ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv6 - Channel 4839ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv7 - Preamble 4849ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff * argv8 - Max SCB 4859ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff */ 486c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff String str = String.format("softap set " + wlanIface + " " + softapIface + " %s %s %s", 487c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff wifiConfig.SSID, 4889ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? 4899ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff "wpa2-psk" : "open", 4909ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff wifiConfig.preSharedKey); 4919ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff mConnector.doCommand(str); 4929ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff } 4939ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff mConnector.doCommand(String.format("softap startap")); 4945321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 4955321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 4965321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff public void stopAccessPoint() throws IllegalStateException { 4975321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff mContext.enforceCallingOrSelfPermission( 4985321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 4995321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff mContext.enforceCallingOrSelfPermission( 500c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 5019ab518ad793385f8405edf19363fe825fb64f5f8Irfan Sheriff mConnector.doCommand("softap stopap"); 5025321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff } 5035321aef4a22daef6ed01ed48d936cdd82f2e38b7Irfan Sheriff 504c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface) 505c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff throws IllegalStateException { 506c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mContext.enforceCallingOrSelfPermission( 507c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 508c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mContext.enforceCallingOrSelfPermission( 509c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 510c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff if (wifiConfig == null) { 511c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface)); 512c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff } else { 513c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff String str = String.format("softap set " + wlanIface + " " + softapIface + 514c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff " %s %s %s", wifiConfig.SSID, 515c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? 516c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff "wpa2-psk" : "open", 517c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff wifiConfig.preSharedKey); 518c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff mConnector.doCommand(str); 519c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff } 520c2f54c267b896cd1799d82be81e904a2b56c2f26Irfan Sheriff } 521873f2145941cc28f6931dc18b5e9987bd22e2e19San Mehat} 522