NetworkManagementService.java revision a6e559edb73886c626e0e5a95085d0ead767ceb7
146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)/* 246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Copyright (C) 2007 The Android Open Source Project 346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Licensed under the Apache License, Version 2.0 (the "License"); 546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * you may not use this file except in compliance with the License. 646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * You may obtain a copy of the License at 746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * http://www.apache.org/licenses/LICENSE-2.0 946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * 1046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Unless required by applicable law or agreed to in writing, software 1146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * distributed under the License is distributed on an "AS IS" BASIS, 1246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * See the License for the specific language governing permissions and 1446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * limitations under the License. 1546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 1646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 1746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)package com.android.server; 1846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 1946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.app.PendingIntent; 2046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.BroadcastReceiver; 2146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.Context; 2246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.Intent; 2346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.IntentFilter; 2446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.res.Resources; 2546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.pm.PackageManager; 2646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.net.Uri; 2746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.net.InterfaceConfiguration; 2846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.net.INetworkManagementEventObserver; 2946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.net.wifi.WifiConfiguration; 30e78d6e40e4e78671e6621ba8cf49835568704899Jonathan Dixonimport android.net.wifi.WifiConfiguration.KeyMgmt; 31a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport android.os.INetworkManagementService; 3246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.Handler; 3346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.os.SystemProperties; 3446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.text.TextUtils; 353411fdf2737f3f0dd0c1fa20045356cf89f34eddBo Liuimport android.util.Log; 3646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.util.Slog; 3746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.util.ArrayList; 3846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.util.StringTokenizer; 3946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.provider.Settings; 4046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.content.ContentResolver; 4146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import android.database.ContentObserver; 426d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch 437db34d3dcaac936566f912e1b0b21f3f103029ffJonathan Dixonimport java.io.File; 4446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.io.FileReader; 4546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.lang.IllegalStateException; 4646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 4746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.net.InetAddress; 4846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)import java.net.UnknownHostException; 4946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 5046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)/** 5146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * @hide 52aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen */ 5346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)class NetworkManagementService extends INetworkManagementService.Stub { 5446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 5546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private static final String TAG = "NetworkManagmentService"; 5646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 5746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) class NetdResponseCode { 5846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final int InterfaceListResult = 110; 59ea844f60b1b559788566fe6e004b1eeca53a8039Jonathan Dixon public static final int TetherInterfaceListResult = 111; 6046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final int TetherDnsFwdTgtListResult = 112; 6146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final int TtyListResult = 113; 6246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 6346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final int TetherStatusResult = 210; 6446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final int IpFwdStatusResult = 211; 651cc4c3210fd2ea027bd6d883a15c3951476642bbJonathan Dixon public static final int InterfaceGetCfgResult = 213; 661cc4c3210fd2ea027bd6d883a15c3951476642bbJonathan Dixon public static final int SoftapStatusResult = 214; 671cc4c3210fd2ea027bd6d883a15c3951476642bbJonathan Dixon public static final int UsbRNDISStatusResult = 215; 681cc4c3210fd2ea027bd6d883a15c3951476642bbJonathan Dixon public static final int InterfaceRxCounterResult = 216; 6946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final int InterfaceTxCounterResult = 217; 7046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final int InterfaceRxThrottleResult = 218; 7146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public static final int InterfaceTxThrottleResult = 219; 72e78d6e40e4e78671e6621ba8cf49835568704899Jonathan Dixon 73e78d6e40e4e78671e6621ba8cf49835568704899Jonathan Dixon public static final int InterfaceChange = 600; 74e78d6e40e4e78671e6621ba8cf49835568704899Jonathan Dixon } 7546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 7646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) /** 7746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Binder context for this service 7846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 7946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private Context mContext; 8046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 8146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) /** 8246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * connector object for communicating with netd 8346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 8446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private NativeDaemonConnector mConnector; 853949435b480cb71106f65b237025da359cf8a8caBen Murdoch 8646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private ArrayList<INetworkManagementEventObserver> mObservers; 87a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 88a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon /** 8946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Constructs a new NetworkManagementService instance 90aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen * 91aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen * @param context Binder context for this service 92c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu */ 93c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu public NetworkManagementService(Context context) { 94aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen mContext = context; 95aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen 9646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mObservers = new ArrayList<INetworkManagementEventObserver>(); 9746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 98c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu if ("simulator".equals(SystemProperties.get("ro.product.device"))) { 99aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen return; 10046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 10146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 1021ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch mConnector = new NativeDaemonConnector( 1031ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch new NetdCallbackReceiver(), "netd", 10, "NetdConnector"); 1041ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch Thread thread = new Thread(mConnector, NativeDaemonConnector.class.getName()); 1051ee9dd0420198429115c3fe8cf0b0502fab9cf62Ben Murdoch thread.start(); 10646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 10746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 10846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void registerObserver(INetworkManagementEventObserver obs) { 10946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.d(TAG, "Registering observer"); 11046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mObservers.add(obs); 11146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 11246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 11346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void unregisterObserver(INetworkManagementEventObserver obs) { 1145a25477f4323996be9d5cc32935066c73b47061bBen Murdoch Slog.d(TAG, "Unregistering observer"); 1155a25477f4323996be9d5cc32935066c73b47061bBen Murdoch mObservers.remove(mObservers.indexOf(obs)); 1165a25477f4323996be9d5cc32935066c73b47061bBen Murdoch } 1175a25477f4323996be9d5cc32935066c73b47061bBen Murdoch 11846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) /** 11946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Notify our observers of an interface link status change 12046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 12146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private void notifyInterfaceLinkStatusChanged(String iface, boolean link) { 12246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) for (INetworkManagementEventObserver obs : mObservers) { 123aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen try { 124aa8b39f3e3f208586f3750d7278f1239a09ebd32Kristian Monsen obs.interfaceLinkStatusChanged(iface, link); 12546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (Exception ex) { 12646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.w(TAG, "Observer notifier failed", ex); 12746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 12846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 12946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 13046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 13146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) /** 13246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Notify our observers of an interface addition. 13346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 13446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private void notifyInterfaceAdded(String iface) { 13546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) for (INetworkManagementEventObserver obs : mObservers) { 13646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 13746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) obs.interfaceAdded(iface); 13846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (Exception ex) { 13946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.w(TAG, "Observer notifier failed", ex); 14046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 14346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 14446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) /** 14546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Notify our observers of an interface removal. 14646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 14746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private void notifyInterfaceRemoved(String iface) { 14846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) for (INetworkManagementEventObserver obs : mObservers) { 14946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 15046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) obs.interfaceRemoved(iface); 15146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (Exception ex) { 15246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.w(TAG, "Observer notifier failed", ex); 15346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 15446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 15546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 15646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 15746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 15846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // 15946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // Netd Callback handling 16046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // 16146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 16246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { 16346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void onDaemonConnected() { 16446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) new Thread() { 16546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void run() { 16646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 167adc6c4d74c77a617100bdfeb174ab0c314b24ea8Selim Gurun }.start(); 16846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 16946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public boolean onEvent(int code, String raw, String[] cooked) { 17046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (code == NetdResponseCode.InterfaceChange) { 17146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) /* 17246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * a network interface change occured 17346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * Format: "NNN Iface added <name>" 17446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * "NNN Iface removed <name>" 17546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * "NNN Iface changed <name> <up/down>" 17646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) */ 17746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (cooked.length < 4 || !cooked[1].equals("Iface")) { 17846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException( 17946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String.format("Invalid event from daemon (%s)", raw)); 18046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 18146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (cooked[2].equals("added")) { 18246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) notifyInterfaceAdded(cooked[3]); 1833949435b480cb71106f65b237025da359cf8a8caBen Murdoch return true; 184a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } else if (cooked[2].equals("removed")) { 185a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon notifyInterfaceRemoved(cooked[3]); 186a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon return true; 187a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } else if (cooked[2].equals("changed") && cooked.length == 5) { 18846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) notifyInterfaceLinkStatusChanged(cooked[3], cooked[4].equals("up")); 18946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return true; 19046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 19146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException( 19246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String.format("Invalid event from daemon (%s)", raw)); 19346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 19446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return false; 19546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 19646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 197a08e8aada16dc4dbfb8745532169fb4a8347541dBo Liu 198a08e8aada16dc4dbfb8745532169fb4a8347541dBo Liu private static int stringToIpAddr(String addrString) throws UnknownHostException { 199a08e8aada16dc4dbfb8745532169fb4a8347541dBo Liu try { 20046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String[] parts = addrString.split("\\."); 20146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (parts.length != 4) { 20246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new UnknownHostException(addrString); 20346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 2049405536501747e2d7b4fc46a33e5f0a1e7fd47acJonathan Dixon 20546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int a = Integer.parseInt(parts[0]) ; 20646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int b = Integer.parseInt(parts[1]) << 8; 20746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int c = Integer.parseInt(parts[2]) << 16; 20846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int d = Integer.parseInt(parts[3]) << 24; 20946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 2109405536501747e2d7b4fc46a33e5f0a1e7fd47acJonathan Dixon return a | b | c | d; 21146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (NumberFormatException ex) { 21246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new UnknownHostException(addrString); 21346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 21446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 21546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 216a08e8aada16dc4dbfb8745532169fb4a8347541dBo Liu public static String intToIpString(int i) { 217a08e8aada16dc4dbfb8745532169fb4a8347541dBo Liu return ((i >> 24 ) & 0xFF) + "." + ((i >> 16 ) & 0xFF) + "." + ((i >> 8 ) & 0xFF) + "." + 218a08e8aada16dc4dbfb8745532169fb4a8347541dBo Liu (i & 0xFF); 21946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 22046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 22146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // 22246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // INetworkManagementService members 22346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // 22446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 22546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public String[] listInterfaces() throws IllegalStateException { 22646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 22746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 22846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 22946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult); 23046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 23146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 23246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException { 23346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String rsp = mConnector.doCommand("interface getcfg " + iface).get(0); 23446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.d(TAG, String.format("rsp <%s>", rsp)); 23546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 23646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz [flag1 flag2 flag3] 23746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) StringTokenizer st = new StringTokenizer(rsp); 23846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 23946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 24046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int code = Integer.parseInt(st.nextToken(" ")); 24146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (code != NetdResponseCode.InterfaceGetCfgResult) { 24246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException( 24346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String.format("Expected code %d, but got %d", 24446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) NetdResponseCode.InterfaceGetCfgResult, code)); 24546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 24646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (NumberFormatException nfe) { 24746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException( 24846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String.format("Invalid response from daemon (%s)", rsp)); 24946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 25046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 25146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) InterfaceConfiguration cfg = new InterfaceConfiguration(); 25246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) cfg.hwAddr = st.nextToken(" "); 25346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 2541127e126a25f26d7d255c73e19d2e07f1c854781Ben Murdoch cfg.ipAddr = stringToIpAddr(st.nextToken(" ")); 2551127e126a25f26d7d255c73e19d2e07f1c854781Ben Murdoch } catch (UnknownHostException uhe) { 2561127e126a25f26d7d255c73e19d2e07f1c854781Ben Murdoch Slog.e(TAG, "Failed to parse ipaddr", uhe); 25746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) cfg.ipAddr = 0; 2581127e126a25f26d7d255c73e19d2e07f1c854781Ben Murdoch } 25946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 26046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 26146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) cfg.netmask = stringToIpAddr(st.nextToken(" ")); 26246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (UnknownHostException uhe) { 26346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.e(TAG, "Failed to parse netmask", uhe); 26446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) cfg.netmask = 0; 26546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 26646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) cfg.interfaceFlags = st.nextToken("]").trim() +"]"; 26746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.d(TAG, String.format("flags <%s>", cfg.interfaceFlags)); 26846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return cfg; 26946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 27046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 27146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void setInterfaceConfig( 27246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String iface, InterfaceConfiguration cfg) throws IllegalStateException { 2737cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba String cmd = String.format("interface setcfg %s %s %s %s", iface, 27446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) intToIpString(cfg.ipAddr), intToIpString(cfg.netmask), cfg.interfaceFlags); 27546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(cmd); 27646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 27746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 2787cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba public void shutdown() { 27946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (mContext.checkCallingOrSelfPermission( 28046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.SHUTDOWN) 28146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) != PackageManager.PERMISSION_GRANTED) { 28246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new SecurityException("Requires SHUTDOWN permission"); 2837cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba } 28446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 28546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.d(TAG, "Shutting down"); 28646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 28746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 2887cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba public boolean getIpForwardingEnabled() throws IllegalStateException{ 28946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 29046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 29146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 29246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) ArrayList<String> rsp = mConnector.doCommand("ipfwd status"); 2937cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba 29446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) for (String line : rsp) { 29546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String []tok = line.split(" "); 29646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int code = Integer.parseInt(tok[0]); 29746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (code == NetdResponseCode.IpFwdStatusResult) { 2987cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba // 211 Forwarding <enabled/disabled> 29946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (tok.length !=2) { 30046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException( 30146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String.format("Malformatted list entry '%s'", line)); 30246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 3037cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba if (tok[2].equals("enabled")) 30446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return true; 30546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return false; 30646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } else { 30746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException(String.format("Unexpected response code %d", code)); 3087cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba } 30946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 31046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException("Got an empty response"); 31146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 31246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 3136d58f78e7fc0412a58b163559cb8e9c4af5c6fe1Jonathan Dixon public void setIpForwardingEnabled(boolean enable) throws IllegalStateException { 31446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 31546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 31646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(String.format("ipfwd %sable", (enable ? "en" : "dis"))); 31746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 31846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 3197cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba public void startTethering(String[] dhcpRange) 32046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throws IllegalStateException { 32146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 32246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 32346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // cmd is "tether start first_start first_stop second_start second_stop ..." 3247cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba // an odd number of addrs will fail 32546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String cmd = "tether start"; 32646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) for (String d : dhcpRange) { 32746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) cmd += " " + d; 32846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 32946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(cmd); 33046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 33146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 33246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void stopTethering() throws IllegalStateException { 33346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 3349c5a40623b62737244deb2d04a98830d7ffa8404Leandro Gracia Gil android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 33546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand("tether stop"); 33646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 33746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 33846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public boolean isTetheringStarted() throws IllegalStateException { 3393520eb778d668dc76ca4541c69abd568b9d02691Mikhail Naganov mContext.enforceCallingOrSelfPermission( 34046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 34146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 34246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) ArrayList<String> rsp = mConnector.doCommand("tether status"); 34346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 3443520eb778d668dc76ca4541c69abd568b9d02691Mikhail Naganov for (String line : rsp) { 34546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String []tok = line.split(" "); 34646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int code = Integer.parseInt(tok[0]); 34746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (code == NetdResponseCode.TetherStatusResult) { 34846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) // XXX: Tethering services <started/stopped> <TBD>... 3497cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba if (tok[2].equals("started")) 35046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return true; 35146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return false; 35246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } else { 35346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException(String.format("Unexpected response code %d", code)); 354c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu } 355c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu } 356c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu throw new IllegalStateException("Got an empty response"); 357c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu } 35846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 35946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void tetherInterface(String iface) throws IllegalStateException { 36046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 36146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 362c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu mConnector.doCommand("tether interface add " + iface); 36346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 36446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 36546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void untetherInterface(String iface) { 36646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 367c3fbc0fea57ba0dd4cf9eb8cc4d12f1b0edbcc5cBo Liu android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 36846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand("tether interface remove " + iface); 36946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 37046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 37146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public String[] listTetheredInterfaces() throws IllegalStateException { 3727cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba mContext.enforceCallingOrSelfPermission( 37346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 37446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return mConnector.doListCommand( 37546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) "tether interface list", NetdResponseCode.TetherInterfaceListResult); 37646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 37746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 37846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void setDnsForwarders(String[] dns) throws IllegalStateException { 37946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 38046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 38146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 38246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String cmd = "tether dns set"; 38346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) for (String s : dns) { 38446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) cmd += " " + InetAddress.getByName(s).getHostAddress(); 38546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 3867cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba mConnector.doCommand(cmd); 38746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (UnknownHostException e) { 38846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException("Error resolving dns name", e); 38946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 39046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 3919405536501747e2d7b4fc46a33e5f0a1e7fd47acJonathan Dixon 39246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public String[] getDnsForwarders() throws IllegalStateException { 39346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 39446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 39546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return mConnector.doListCommand( 3969405536501747e2d7b4fc46a33e5f0a1e7fd47acJonathan Dixon "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult); 39746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 39846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 39946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void enableNat(String internalInterface, String externalInterface) 40046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throws IllegalStateException { 40146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 40246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 40346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand( 40446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String.format("nat enable %s %s", internalInterface, externalInterface)); 40546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 40646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 4076b5f3d1546ae2a9c712cde60c54ec027582bc4e6Martin Kosiba public void disableNat(String internalInterface, String externalInterface) 40846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throws IllegalStateException { 40946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 41046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 41146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand( 4126b5f3d1546ae2a9c712cde60c54ec027582bc4e6Martin Kosiba String.format("nat disable %s %s", internalInterface, externalInterface)); 41346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 41446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 41546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public String[] listTtys() throws IllegalStateException { 41646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 417531e68a2b50a5e542eeede13907f29e463a99ebfBen Murdoch android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 41846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult); 41946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 42046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 42146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void attachPppd(String tty, String localAddr, String remoteAddr, String dns1Addr, 422531e68a2b50a5e542eeede13907f29e463a99ebfBen Murdoch String dns2Addr) throws IllegalStateException { 42346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 42446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 42546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 42646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(String.format("pppd attach %s %s %s %s %s", tty, 4271cc4c3210fd2ea027bd6d883a15c3951476642bbJonathan Dixon InetAddress.getByName(localAddr).getHostAddress(), 42846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) InetAddress.getByName(remoteAddr).getHostAddress(), 42946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) InetAddress.getByName(dns1Addr).getHostAddress(), 43046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) InetAddress.getByName(dns2Addr).getHostAddress())); 43146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (UnknownHostException e) { 4321cc4c3210fd2ea027bd6d883a15c3951476642bbJonathan Dixon throw new IllegalStateException("Error resolving addr", e); 43346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 43446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 43546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 43646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void detachPppd(String tty) throws IllegalStateException { 4371cc4c3210fd2ea027bd6d883a15c3951476642bbJonathan Dixon mContext.enforceCallingOrSelfPermission( 43846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 43946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(String.format("pppd detach %s", tty)); 44046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 44146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 44246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void startUsbRNDIS() throws IllegalStateException { 44346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 44446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 44546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand("usb startrndis"); 44646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 44746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 44846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void stopUsbRNDIS() throws IllegalStateException { 44946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 45046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 45146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand("usb stoprndis"); 45246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 45346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 45446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public boolean isUsbRNDISStarted() throws IllegalStateException { 45546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 45646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 4577cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba ArrayList<String> rsp = mConnector.doCommand("usb rndisstatus"); 45846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 45946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) for (String line : rsp) { 46046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String []tok = line.split(" "); 46146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int code = Integer.parseInt(tok[0]); 4627cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba if (code == NetdResponseCode.UsbRNDISStatusResult) { 46346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (tok[3].equals("started")) 46446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return true; 46546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return false; 46646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } else { 46708a5e00cdfb74f4ffd843d2d0a9b0b40b86b107aBo Liu throw new IllegalStateException(String.format("Unexpected response code %d", code)); 4687cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba } 46946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 47046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throw new IllegalStateException("Got an empty response"); 47146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 47246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 47346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void startAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface) 47446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) throws IllegalStateException { 47546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 47646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 47746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 47846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 47946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(String.format("softap stop " + wlanIface)); 48046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP")); 48146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(String.format("softap start " + wlanIface)); 48246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (wifiConfig == null) { 483f37548d6d8e2a73c65d675a26706a38f52960800Jonathan Dixon mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface)); 484f37548d6d8e2a73c65d675a26706a38f52960800Jonathan Dixon } else { 48546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) /** 48646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * softap set arg1 arg2 arg3 [arg4 arg5 arg6 arg7 arg8] 48746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * argv1 - wlan interface 48846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * argv2 - softap interface 48946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * argv3 - SSID 49046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * argv4 - Security 49146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * argv5 - Key 49246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * argv6 - Channel 49346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) * argv7 - Preamble 4946d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch * argv8 - Max SCB 4956d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch */ 4966d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch String str = String.format("softap set " + wlanIface + " " + softapIface + 4976d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch " %s %s %s", convertQuotedString(wifiConfig.SSID), 4986d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? 4996d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch "wpa2-psk" : "open", 5006d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch convertQuotedString(wifiConfig.preSharedKey)); 5016d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch mConnector.doCommand(str); 5026d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch } 5036d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch mConnector.doCommand(String.format("softap startap")); 5046d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch } 5056d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch 5066d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch private String convertQuotedString(String s) { 5076d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch /* Replace \ with \\, then " with \" and add quotes at end */ 5086d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch return '"' + s.replaceAll("\\\\","\\\\\\\\").replaceAll("\"","\\\\\"") + '"'; 5096d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch } 5106d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch 5116d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch public void stopAccessPoint() throws IllegalStateException { 5126d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch mContext.enforceCallingOrSelfPermission( 5136d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 5146d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch mContext.enforceCallingOrSelfPermission( 51546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 51646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand("softap stopap"); 5176d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch } 518fde8dae44f74be3de69ce6dd07b0023279b485a0Ben Murdoch 5196d4097cfa188a95c95fd5d0c86238c91f817c3edBen Murdoch public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface) 520fde8dae44f74be3de69ce6dd07b0023279b485a0Ben Murdoch throws IllegalStateException { 521fde8dae44f74be3de69ce6dd07b0023279b485a0Ben Murdoch mContext.enforceCallingOrSelfPermission( 52246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 52346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 52446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService"); 52546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) if (wifiConfig == null) { 52646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface)); 52746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } else { 52846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String str = String.format("softap set " + wlanIface + " " + softapIface + 52946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) " %s %s %s", convertQuotedString(wifiConfig.SSID), 53046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? 53146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) "wpa2-psk" : "open", 53246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) convertQuotedString(wifiConfig.preSharedKey)); 53346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(str); 53446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 53546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 53646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 53746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private long getInterfaceCounter(String iface, boolean rx) { 53846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 5394320e428efc3bf69387f3b9d5a0589b2b8746409Bo Liu android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 54046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 54146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String rsp = mConnector.doCommand( 54246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String.format("interface read%scounter %s", (rx ? "rx" : "tx"), iface)).get(0); 54346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String []tok = rsp.split(" "); 54446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int code; 54546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 54646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) code = Integer.parseInt(tok[0]); 54746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (NumberFormatException nfe) { 54846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.e(TAG, String.format("Error parsing code %s", tok[0])); 54946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return -1; 5509c5a40623b62737244deb2d04a98830d7ffa8404Leandro Gracia Gil } 5519c5a40623b62737244deb2d04a98830d7ffa8404Leandro Gracia Gil if ((rx && code != NetdResponseCode.InterfaceRxCounterResult) || ( 552edb98e3c667e37b00f338b51fb2e5d6bece4c447Ben Murdoch !rx && code != NetdResponseCode.InterfaceTxCounterResult)) { 55346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.e(TAG, String.format("Unexpected response code %d", code)); 55446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return -1; 55546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 55646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return Long.parseLong(tok[1]); 557ea844f60b1b559788566fe6e004b1eeca53a8039Jonathan Dixon } catch (Exception e) { 5587db34d3dcaac936566f912e1b0b21f3f103029ffJonathan Dixon Slog.e(TAG, String.format( 5597db34d3dcaac936566f912e1b0b21f3f103029ffJonathan Dixon "Failed to read interface %s counters", (rx ? "rx" : "tx")), e); 5607db34d3dcaac936566f912e1b0b21f3f103029ffJonathan Dixon } 5617db34d3dcaac936566f912e1b0b21f3f103029ffJonathan Dixon return -1; 5627cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba } 56346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 56446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public long getInterfaceRxCounter(String iface) { 56546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return getInterfaceCounter(iface, true); 56646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 5677cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba 56846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public long getInterfaceTxCounter(String iface) { 56946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return getInterfaceCounter(iface, false); 57046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 57146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 57246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) { 573420c0da3a4e06e1ac5574091e7c9c286ef012369Mikhail Naganov mContext.enforceCallingOrSelfPermission( 57446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService"); 57546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mConnector.doCommand(String.format( 57646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) "interface setthrottle %s %d %d", iface, rxKbps, txKbps)); 57746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 57846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 57946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) private int getInterfaceThrottle(String iface, boolean rx) { 58046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) mContext.enforceCallingOrSelfPermission( 58146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService"); 58246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 58346f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String rsp = mConnector.doCommand( 58446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) String.format("interface getthrottle %s %s", iface,(rx ? "rx" : "tx"))).get(0); 5857cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba String []tok = rsp.split(" "); 58646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) int code; 58746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) try { 58846f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) code = Integer.parseInt(tok[0]); 58946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (NumberFormatException nfe) { 590e78d6e40e4e78671e6621ba8cf49835568704899Jonathan Dixon Slog.e(TAG, String.format("Error parsing code %s", tok[0])); 591e78d6e40e4e78671e6621ba8cf49835568704899Jonathan Dixon return -1; 592e78d6e40e4e78671e6621ba8cf49835568704899Jonathan Dixon } 593420c0da3a4e06e1ac5574091e7c9c286ef012369Mikhail Naganov if ((rx && code != NetdResponseCode.InterfaceRxThrottleResult) || ( 59446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) !rx && code != NetdResponseCode.InterfaceTxThrottleResult)) { 59546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.e(TAG, String.format("Unexpected response code %d", code)); 59646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return -1; 59746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 5987cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba return Integer.parseInt(tok[1]); 59946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } catch (Exception e) { 60046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) Slog.e(TAG, String.format( 60146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) "Failed to read interface %s throttle value", (rx ? "rx" : "tx")), e); 60246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 6037cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba return -1; 60446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 60546f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 60646f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public int getInterfaceRxThrottle(String iface) { 60746f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return getInterfaceThrottle(iface, true); 6087cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba } 60946f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) 61046f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) public int getInterfaceTxThrottle(String iface) { 61146f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) return getInterfaceThrottle(iface, false); 61246f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles) } 6137cb3dd1c0aca371b628b80afa69c58638de30fa1Martin Kosiba} 61446f104289826e85ba76a1a2139d7ecc7daca07b1Torne (Richard Coles)