Loading services/java/com/android/server/PPPOEService.java 0 → 100644 +342 −0 Original line number Diff line number Diff line /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Not a Contribution. * * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.INetworkManagementService; import android.os.Messenger; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.net.RouteInfo; import android.net.wifi.PPPOEConfig; import android.net.wifi.PPPOEInfo; import android.net.wifi.PPPOEInfo.Status; import android.util.Log; /** * Track the state of Wifi connectivity. All event handling is done here, * and all changes in connectivity state are initiated here. * * Wi-Fi now supports three modes of operation: Client, Soft Ap and Direct * In the current implementation, we do not support any concurrency and thus only * one of Client, Soft Ap or Direct operation is supported at any time. * * The WifiStateMachine supports Soft Ap and Client operations while WifiP2pService * handles Direct. WifiP2pService and WifiStateMachine co-ordinate to ensure only * one exists at a certain time. * * @hide */ public class PPPOEService { class NetdResponseCode { /* Keep in sync with system/netd/ResponseCode.h */ public static final int InterfaceListResult = 110; public static final int TetherInterfaceListResult = 111; public static final int TetherDnsFwdTgtListResult = 112; public static final int TtyListResult = 113; public static final int CommandOkay = 200; public static final int TetherStatusResult = 210; public static final int IpFwdStatusResult = 211; public static final int InterfaceGetCfgResult = 213; public static final int SoftapStatusResult = 214; public static final int InterfaceRxCounterResult = 216; public static final int InterfaceTxCounterResult = 217; public static final int InterfaceRxThrottleResult = 218; public static final int InterfaceTxThrottleResult = 219; public static final int QuotaCounterResult = 220; public static final int TetheringStatsResult = 221; public static final int DnsProxyQueryResult = 222; public static final int V6RtrAdvResult = 224; public static final int OperationFailed = 400; public static final int InterfaceChange = 600; public static final int BandwidthControl = 601; } public static final String TAG = "PPPOEService"; public static final int CMD_START_PPPOE = 0; public static final int CMD_STOP_PPPOE = 1; /* * below ACTION and EXTRA definition are the requirement of China Telecom * can not be changed */ public static final String ACTION_PPPOE_COMPLETE = "android.net.wifi.PPPOE_COMPLETED_ACTION"; public static final String ACTION_PPPOE_STATE_CHANGED = "android.net.wifi.PPPOE_STATE_CHANGED"; public static final String EXTRA_PPPOE_RESULT_STATUS = "pppoe_result_status"; public static final String EXTRA_PPPOE_RESULT_ERROR_CODE = "pppoe_result_error_code"; public static final String EXTRA_PPPOE_STATE = "pppoe_state"; public static final String NETD_TAG = "PPPOEService_Netd"; public static final int PPPOEEXIT = 666; public static final String PPPOE_MODULE = "pppoe"; public static final String PROP_NET_DNS1 ="net.dns1"; public static final String PROP_NET_DNS2 ="net.dns2"; /** * Binder context for this service */ private Context mContext; /** * connector object for communicating with netd */ private NativeDaemonConnector mConnector; private Status mPppoeStatus = Status.OFFLINE; private boolean mDoCommand = false; private long mConnectedtime; private Thread mThread; //public static PPPOEService instance /** * Constructs a new PPPOEService instance * * @param context Binder context for this service */ public PPPOEService(Context context) { mContext = context; mConnector = new NativeDaemonConnector( new NetdCallbackReceiver(), "netd", 10, NETD_TAG, 160); mThread = new Thread(mConnector, NETD_TAG); mThread.start(); } /** * Netd Callback handling */ private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { @Override public void onDaemonConnected() { } @Override public boolean onEvent(int code, String raw, String[] cooked) { Log.i(TAG, "NetdCallbackReceiver onEvent " + code + raw); switch (code) { case NetdResponseCode.InterfaceChange: /* * a network interface change occured * Format: "NNN Iface added <name>" * "NNN Iface removed <name>" * "NNN Iface changed <name> <up/down>" * "NNN Iface linkstatus <name> <up/down>" */ if (cooked.length < 4 || !cooked[1].equals("Iface")) { throw new IllegalStateException( String.format("Invalid event from daemon (%s)", raw)); } if (cooked[2].equals("added")) { return true; } else if (cooked[2].equals("removed")) { return true; } else if (cooked[2].equals("changed") && cooked.length == 5) { return true; } else if (cooked[2].equals("linkstate") && cooked.length == 5) { if(cooked[3].startsWith("ppp")) { if(cooked[4].equals("up")) { if(mPppoeStatus != Status.ONLINE) { setRouteAndDNS(cooked[3]); mPppoeStatus = Status.ONLINE; mConnectedtime = System.currentTimeMillis(); notifyStatusChanged("PPPOE_STATE_CONNECTED"); if(mDoCommand) { sendCommandComplete("SUCCESS", "0"); mDoCommand = false; } } } else { if(mPppoeStatus == Status.ONLINE) { mPppoeStatus = Status.OFFLINE; mConnectedtime = 0; notifyStatusChanged("PPPOE_STATE_DISCONNECTED"); } } } return true; } throw new IllegalStateException( String.format("Invalid event from daemon (%s)", raw)); case PPPOEEXIT: /* * pppoe process exit occured * Format: "NNN pppoe exited error code <errncode>" */ if (cooked.length > 5 && PPPOE_MODULE.equals(cooked[1])) { if(mDoCommand) { String errCode = cooked[5]; Log.i(TAG, "pppoeExit mDoCommand errcode is " + errCode); sendCommandComplete("FAILURE", errCode); mDoCommand = false; } mPppoeStatus = Status.OFFLINE; mConnectedtime = 0; notifyStatusChanged("PPPOE_STATE_DISCONNECTED"); } return true; default: break; } return false; } } /** * Get a reference to handler. This is used by a client to establish * an AsyncChannel communication with PPPOEService */ public Messenger getMessenger() { return new Messenger(mMainHandler); } private final Handler mMainHandler = new Handler(){ public void handleMessage(Message msg) { Log.i(TAG, "handleMessage msg is " + msg); switch(msg.what) { case CMD_START_PPPOE: PPPOEConfig config = (PPPOEConfig) msg.obj; startPPPOE(config); break; case CMD_STOP_PPPOE: stopPPPOE(); break; default: break; } } }; private void startPPPOE(PPPOEConfig config) { NativeDaemonEvent event = null; try { mPppoeStatus = Status.CONNECTING; notifyStatusChanged("PPPOE_STATE_CONNECTING"); event = mConnector.execute(PPPOE_MODULE, "start", config.username, config.password, config.interf, Integer.toString(config.lcp_echo_interval), Integer.toString(config.lcp_echo_failure), Integer.toString(config.mtu), Integer.toString(config.mru), Integer.toString(config.timeout), Integer.toString(config.MSS)); mDoCommand = true; } catch (NativeDaemonConnectorException e) { Log.wtf(TAG, "problem start pppoe", e); } if(event != null) { Log.i(TAG, "startPPPOE " + event.getRawEvent()); String cooked[] = event.unescapeArgs(event.getRawEvent()); Log.i(TAG, "cooked.length is " + cooked.length + "cooked[4] is " + cooked[4]); if(event.getCode() == NetdResponseCode.CommandOkay) { if(cooked.length == 6 && cooked[4].equals("failed")) { String errno = cooked[5]; //sendbroadcast(); if(errno.equals("16")) { mPppoeStatus = Status.ONLINE; sendCommandComplete("ALREADY_ONLINE", errno); } } } } } private void stopPPPOE() { //sendBroadcast(); notifyStatusChanged("PPPOE_STATE_DISCONNECTING"); try { mConnector.execute(PPPOE_MODULE, "stop"); } catch (NativeDaemonConnectorException e) { Log.wtf(TAG, "problem stop pppoe", e); } } public PPPOEInfo getPPPOEInfo() { return new PPPOEInfo(mPppoeStatus, mConnectedtime); } private void notifyStatusChanged(String state) { Intent intent = new Intent(ACTION_PPPOE_STATE_CHANGED); intent.putExtra(EXTRA_PPPOE_STATE, state); mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } private void sendCommandComplete(String status, String errno) { Intent intent = new Intent(ACTION_PPPOE_COMPLETE); intent.putExtra(EXTRA_PPPOE_RESULT_STATUS, status); intent.putExtra(EXTRA_PPPOE_RESULT_ERROR_CODE, errno); mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } private void setRouteAndDNS(String iface) { //set ppp0 route as default. String gateway = null; INetworkManagementService mNwService; IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); mNwService = INetworkManagementService.Stub.asInterface(b); try { RouteInfo[] ris = mNwService.getRoutes(iface); for(RouteInfo ri : ris) { if(ri != null) { gateway = ri.getDestination().getAddress().getHostAddress(); break; } } } catch (RemoteException e) { Log.e(TAG, "error: " + e); } Log.i(TAG, "setRouteAndDNS iface is " + iface + " gateway is " + gateway); try{ mConnector.execute(PPPOE_MODULE, "route", "setdefault", iface, gateway); } catch(NativeDaemonConnectorException e) { Log.wtf(TAG, "problem set ppp route", e); } //set ppp0 dns. String pppDNS1Property = "net." + iface + ".dns1"; String pppDNS2Property = "net." + iface + ".dns2"; String pppDns1 = SystemProperties.get(pppDNS1Property); String pppDns2 = SystemProperties.get(pppDNS2Property); Log.i(TAG, "setRouteAndDNS prop " + pppDNS1Property + ": " + pppDns1 + "prop " + pppDNS2Property + ": " + pppDns2); try { mNwService.setDnsServersForInterface(iface, new String[] {pppDns1, pppDns2}, null); mNwService.setDefaultInterfaceForDns(iface); } catch (RemoteException e) { Log.e(TAG, "error: " + e); } SystemProperties.set(PROP_NET_DNS1, pppDns1); SystemProperties.set(PROP_NET_DNS2, pppDns2); } } services/java/com/android/server/wifi/WifiService.java +58 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.net.LinkAddress; import android.net.NetworkUtils; import android.net.RouteInfo; import android.net.wifi.IWifiManager; import android.net.wifi.PPPOEConfig; import android.net.wifi.PPPOEInfo; import android.net.wifi.ScanResult; import android.net.wifi.BatchedScanResult; import android.net.wifi.BatchedScanSettings; Loading Loading @@ -76,6 +78,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.AsyncChannel; import com.android.server.am.BatteryStatsService; import com.android.server.PPPOEService; import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED; import static com.android.server.wifi.WifiController.CMD_BATTERY_CHANGED; import static com.android.server.wifi.WifiController.CMD_EMERGENCY_MODE_CHANGED; Loading Loading @@ -271,6 +274,39 @@ public final class WifiService extends IWifiManager.Stub { } WifiStateMachineHandler mWifiStateMachineHandler; /** * Handles interaction with PPPOEService */ private class PPPOEHandler extends Handler { PPPOEHandler(android.os.Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { Slog.e(TAG, "PPPOEService connection success"); } else { Slog.e(TAG, "PPPOEService connection failure, error=" + msg.arg1); } break; } case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { Slog.e(TAG, "PPPOEHandler channel lost, msg.arg1 =" + msg.arg1); break; } default: { Slog.d(TAG, "PPPOEHandler.handleMessage ignoring msg=" + msg); break; } } } } PPPOEHandler mPPPOEHandler; private WifiWatchdogStateMachine mWifiWatchdogStateMachine; public WifiService(Context context) { Loading @@ -297,6 +333,7 @@ public final class WifiService extends IWifiManager.Stub { mBatchedScanSupported = mContext.getResources().getBoolean( R.bool.config_wifi_batched_scan_supported); mPPPOEHandler = new PPPOEHandler(wifiThread.getLooper()); registerForScanModeChange(); mContext.registerReceiver( new BroadcastReceiver() { Loading @@ -317,6 +354,9 @@ public final class WifiService extends IWifiManager.Stub { private WifiController mWifiController; private AsyncChannel mPPPOEServiceChannel; private PPPOEService mPPPOEService; /** * Check if Wi-Fi needs to be enabled and start * if needed Loading @@ -335,6 +375,9 @@ public final class WifiService extends IWifiManager.Stub { mWifiWatchdogStateMachine = WifiWatchdogStateMachine. makeWifiWatchdogStateMachine(mContext); mPPPOEService = new PPPOEService(mContext); mPPPOEServiceChannel = new AsyncChannel(); mPPPOEServiceChannel.connect(mContext, mPPPOEHandler, mPPPOEService.getMessenger()); } Loading Loading @@ -1133,6 +1176,21 @@ public final class WifiService extends IWifiManager.Stub { return mWifiStateMachine.getConfigFile(); } public void startPPPOE(PPPOEConfig config) { mPPPOEServiceChannel.sendMessage( mPPPOEHandler.obtainMessage(PPPOEService.CMD_START_PPPOE, config)); } public void stopPPPOE() { mPPPOEServiceChannel.sendMessage(PPPOEService.CMD_STOP_PPPOE); } /** */ public PPPOEInfo getPPPOEInfo() { return mPPPOEService.getPPPOEInfo(); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading wifi/java/android/net/wifi/IWifiManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package android.net.wifi; import android.net.wifi.BatchedScanResult; import android.net.wifi.BatchedScanSettings; import android.net.wifi.PPPOEConfig; import android.net.wifi.PPPOEInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.ScanResult; Loading Loading @@ -126,5 +128,11 @@ interface IWifiManager boolean isBatchedScanSupported(); void pollBatchedScan(); void startPPPOE(in PPPOEConfig config); void stopPPPOE(); PPPOEInfo getPPPOEInfo(); } wifi/java/android/net/wifi/PPPOEConfig.aidl 0 → 100644 +22 −0 Original line number Diff line number Diff line /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Not a Contribution. * * Copyright (c) 2008, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.wifi; parcelable PPPOEConfig; wifi/java/android/net/wifi/PPPOEConfig.java 0 → 100644 +120 −0 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ package android.net.wifi; import android.os.Parcel; import android.os.Parcelable; import java.io.FileOutputStream; import java.io.IOException; /** @hide */ public class PPPOEConfig implements Parcelable { public final static String PPPOE_DEFAULT_INTERFACE = "wlan0"; public final static int PPPOE_DEFAULT_LCP_ECHO_INTERVAL = 20; public final static int PPPOE_DEFAULT_LCP_ECHO_FAILURE = 3; public final static int PPPOE_DEFAULT_MTU = 1492; public final static int PPPOE_DEFAULT_MRU = 1492; public final static int PPPOE_DEFAULT_TIMEOUT = 80; public final static int PPPOE_DEFAULT_MSS = 1412; public String username; public String password; public String interf; public int lcp_echo_interval; public int lcp_echo_failure; public int mtu; public int mru; public int timeout; public int MSS; public PPPOEConfig() { this(null, null); } public PPPOEConfig(String user, String pass) { this(user, pass, PPPOE_DEFAULT_INTERFACE, PPPOE_DEFAULT_LCP_ECHO_INTERVAL, PPPOE_DEFAULT_LCP_ECHO_FAILURE, PPPOE_DEFAULT_MTU, PPPOE_DEFAULT_MRU, PPPOE_DEFAULT_TIMEOUT, PPPOE_DEFAULT_MSS); } public PPPOEConfig(String user, String pass, String iface, int lcp_echo_interval, int lcp_echo_failure, int mtu, int mru, int timeout, int mss) { this.username = user; this.password = pass; this.interf = iface; this.lcp_echo_interval = lcp_echo_interval; this.lcp_echo_failure = lcp_echo_failure; this.mtu = mtu; this.mru = mru; this.timeout = timeout; this.MSS = mss; } /** Implement the Parcelable interface */ public int describeContents() { return 0; } /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(username); dest.writeString(password); dest.writeString(interf); dest.writeInt(lcp_echo_interval); dest.writeInt(lcp_echo_failure); dest.writeInt(mtu); dest.writeInt(mru); dest.writeInt(timeout); dest.writeInt(MSS); } /** Implement the Parcelable interface */ public static final Creator<PPPOEConfig> CREATOR = new Creator<PPPOEConfig>() { public PPPOEConfig createFromParcel(Parcel in) { PPPOEConfig config = new PPPOEConfig(); config.username = in.readString(); config.password = in.readString(); config.interf = in.readString(); config.lcp_echo_interval = in.readInt(); config.lcp_echo_failure = in.readInt(); config.mtu = in.readInt(); config.mru = in.readInt(); config.timeout = in.readInt(); config.MSS = in.readInt(); return config; } public PPPOEConfig[] newArray(int size) { return new PPPOEConfig[size]; } }; } Loading
services/java/com/android/server/PPPOEService.java 0 → 100644 +342 −0 Original line number Diff line number Diff line /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Not a Contribution. * * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import android.content.Context; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.INetworkManagementService; import android.os.Messenger; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.net.RouteInfo; import android.net.wifi.PPPOEConfig; import android.net.wifi.PPPOEInfo; import android.net.wifi.PPPOEInfo.Status; import android.util.Log; /** * Track the state of Wifi connectivity. All event handling is done here, * and all changes in connectivity state are initiated here. * * Wi-Fi now supports three modes of operation: Client, Soft Ap and Direct * In the current implementation, we do not support any concurrency and thus only * one of Client, Soft Ap or Direct operation is supported at any time. * * The WifiStateMachine supports Soft Ap and Client operations while WifiP2pService * handles Direct. WifiP2pService and WifiStateMachine co-ordinate to ensure only * one exists at a certain time. * * @hide */ public class PPPOEService { class NetdResponseCode { /* Keep in sync with system/netd/ResponseCode.h */ public static final int InterfaceListResult = 110; public static final int TetherInterfaceListResult = 111; public static final int TetherDnsFwdTgtListResult = 112; public static final int TtyListResult = 113; public static final int CommandOkay = 200; public static final int TetherStatusResult = 210; public static final int IpFwdStatusResult = 211; public static final int InterfaceGetCfgResult = 213; public static final int SoftapStatusResult = 214; public static final int InterfaceRxCounterResult = 216; public static final int InterfaceTxCounterResult = 217; public static final int InterfaceRxThrottleResult = 218; public static final int InterfaceTxThrottleResult = 219; public static final int QuotaCounterResult = 220; public static final int TetheringStatsResult = 221; public static final int DnsProxyQueryResult = 222; public static final int V6RtrAdvResult = 224; public static final int OperationFailed = 400; public static final int InterfaceChange = 600; public static final int BandwidthControl = 601; } public static final String TAG = "PPPOEService"; public static final int CMD_START_PPPOE = 0; public static final int CMD_STOP_PPPOE = 1; /* * below ACTION and EXTRA definition are the requirement of China Telecom * can not be changed */ public static final String ACTION_PPPOE_COMPLETE = "android.net.wifi.PPPOE_COMPLETED_ACTION"; public static final String ACTION_PPPOE_STATE_CHANGED = "android.net.wifi.PPPOE_STATE_CHANGED"; public static final String EXTRA_PPPOE_RESULT_STATUS = "pppoe_result_status"; public static final String EXTRA_PPPOE_RESULT_ERROR_CODE = "pppoe_result_error_code"; public static final String EXTRA_PPPOE_STATE = "pppoe_state"; public static final String NETD_TAG = "PPPOEService_Netd"; public static final int PPPOEEXIT = 666; public static final String PPPOE_MODULE = "pppoe"; public static final String PROP_NET_DNS1 ="net.dns1"; public static final String PROP_NET_DNS2 ="net.dns2"; /** * Binder context for this service */ private Context mContext; /** * connector object for communicating with netd */ private NativeDaemonConnector mConnector; private Status mPppoeStatus = Status.OFFLINE; private boolean mDoCommand = false; private long mConnectedtime; private Thread mThread; //public static PPPOEService instance /** * Constructs a new PPPOEService instance * * @param context Binder context for this service */ public PPPOEService(Context context) { mContext = context; mConnector = new NativeDaemonConnector( new NetdCallbackReceiver(), "netd", 10, NETD_TAG, 160); mThread = new Thread(mConnector, NETD_TAG); mThread.start(); } /** * Netd Callback handling */ private class NetdCallbackReceiver implements INativeDaemonConnectorCallbacks { @Override public void onDaemonConnected() { } @Override public boolean onEvent(int code, String raw, String[] cooked) { Log.i(TAG, "NetdCallbackReceiver onEvent " + code + raw); switch (code) { case NetdResponseCode.InterfaceChange: /* * a network interface change occured * Format: "NNN Iface added <name>" * "NNN Iface removed <name>" * "NNN Iface changed <name> <up/down>" * "NNN Iface linkstatus <name> <up/down>" */ if (cooked.length < 4 || !cooked[1].equals("Iface")) { throw new IllegalStateException( String.format("Invalid event from daemon (%s)", raw)); } if (cooked[2].equals("added")) { return true; } else if (cooked[2].equals("removed")) { return true; } else if (cooked[2].equals("changed") && cooked.length == 5) { return true; } else if (cooked[2].equals("linkstate") && cooked.length == 5) { if(cooked[3].startsWith("ppp")) { if(cooked[4].equals("up")) { if(mPppoeStatus != Status.ONLINE) { setRouteAndDNS(cooked[3]); mPppoeStatus = Status.ONLINE; mConnectedtime = System.currentTimeMillis(); notifyStatusChanged("PPPOE_STATE_CONNECTED"); if(mDoCommand) { sendCommandComplete("SUCCESS", "0"); mDoCommand = false; } } } else { if(mPppoeStatus == Status.ONLINE) { mPppoeStatus = Status.OFFLINE; mConnectedtime = 0; notifyStatusChanged("PPPOE_STATE_DISCONNECTED"); } } } return true; } throw new IllegalStateException( String.format("Invalid event from daemon (%s)", raw)); case PPPOEEXIT: /* * pppoe process exit occured * Format: "NNN pppoe exited error code <errncode>" */ if (cooked.length > 5 && PPPOE_MODULE.equals(cooked[1])) { if(mDoCommand) { String errCode = cooked[5]; Log.i(TAG, "pppoeExit mDoCommand errcode is " + errCode); sendCommandComplete("FAILURE", errCode); mDoCommand = false; } mPppoeStatus = Status.OFFLINE; mConnectedtime = 0; notifyStatusChanged("PPPOE_STATE_DISCONNECTED"); } return true; default: break; } return false; } } /** * Get a reference to handler. This is used by a client to establish * an AsyncChannel communication with PPPOEService */ public Messenger getMessenger() { return new Messenger(mMainHandler); } private final Handler mMainHandler = new Handler(){ public void handleMessage(Message msg) { Log.i(TAG, "handleMessage msg is " + msg); switch(msg.what) { case CMD_START_PPPOE: PPPOEConfig config = (PPPOEConfig) msg.obj; startPPPOE(config); break; case CMD_STOP_PPPOE: stopPPPOE(); break; default: break; } } }; private void startPPPOE(PPPOEConfig config) { NativeDaemonEvent event = null; try { mPppoeStatus = Status.CONNECTING; notifyStatusChanged("PPPOE_STATE_CONNECTING"); event = mConnector.execute(PPPOE_MODULE, "start", config.username, config.password, config.interf, Integer.toString(config.lcp_echo_interval), Integer.toString(config.lcp_echo_failure), Integer.toString(config.mtu), Integer.toString(config.mru), Integer.toString(config.timeout), Integer.toString(config.MSS)); mDoCommand = true; } catch (NativeDaemonConnectorException e) { Log.wtf(TAG, "problem start pppoe", e); } if(event != null) { Log.i(TAG, "startPPPOE " + event.getRawEvent()); String cooked[] = event.unescapeArgs(event.getRawEvent()); Log.i(TAG, "cooked.length is " + cooked.length + "cooked[4] is " + cooked[4]); if(event.getCode() == NetdResponseCode.CommandOkay) { if(cooked.length == 6 && cooked[4].equals("failed")) { String errno = cooked[5]; //sendbroadcast(); if(errno.equals("16")) { mPppoeStatus = Status.ONLINE; sendCommandComplete("ALREADY_ONLINE", errno); } } } } } private void stopPPPOE() { //sendBroadcast(); notifyStatusChanged("PPPOE_STATE_DISCONNECTING"); try { mConnector.execute(PPPOE_MODULE, "stop"); } catch (NativeDaemonConnectorException e) { Log.wtf(TAG, "problem stop pppoe", e); } } public PPPOEInfo getPPPOEInfo() { return new PPPOEInfo(mPppoeStatus, mConnectedtime); } private void notifyStatusChanged(String state) { Intent intent = new Intent(ACTION_PPPOE_STATE_CHANGED); intent.putExtra(EXTRA_PPPOE_STATE, state); mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } private void sendCommandComplete(String status, String errno) { Intent intent = new Intent(ACTION_PPPOE_COMPLETE); intent.putExtra(EXTRA_PPPOE_RESULT_STATUS, status); intent.putExtra(EXTRA_PPPOE_RESULT_ERROR_CODE, errno); mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } private void setRouteAndDNS(String iface) { //set ppp0 route as default. String gateway = null; INetworkManagementService mNwService; IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); mNwService = INetworkManagementService.Stub.asInterface(b); try { RouteInfo[] ris = mNwService.getRoutes(iface); for(RouteInfo ri : ris) { if(ri != null) { gateway = ri.getDestination().getAddress().getHostAddress(); break; } } } catch (RemoteException e) { Log.e(TAG, "error: " + e); } Log.i(TAG, "setRouteAndDNS iface is " + iface + " gateway is " + gateway); try{ mConnector.execute(PPPOE_MODULE, "route", "setdefault", iface, gateway); } catch(NativeDaemonConnectorException e) { Log.wtf(TAG, "problem set ppp route", e); } //set ppp0 dns. String pppDNS1Property = "net." + iface + ".dns1"; String pppDNS2Property = "net." + iface + ".dns2"; String pppDns1 = SystemProperties.get(pppDNS1Property); String pppDns2 = SystemProperties.get(pppDNS2Property); Log.i(TAG, "setRouteAndDNS prop " + pppDNS1Property + ": " + pppDns1 + "prop " + pppDNS2Property + ": " + pppDns2); try { mNwService.setDnsServersForInterface(iface, new String[] {pppDns1, pppDns2}, null); mNwService.setDefaultInterfaceForDns(iface); } catch (RemoteException e) { Log.e(TAG, "error: " + e); } SystemProperties.set(PROP_NET_DNS1, pppDns1); SystemProperties.set(PROP_NET_DNS2, pppDns2); } }
services/java/com/android/server/wifi/WifiService.java +58 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ import android.net.LinkAddress; import android.net.NetworkUtils; import android.net.RouteInfo; import android.net.wifi.IWifiManager; import android.net.wifi.PPPOEConfig; import android.net.wifi.PPPOEInfo; import android.net.wifi.ScanResult; import android.net.wifi.BatchedScanResult; import android.net.wifi.BatchedScanSettings; Loading Loading @@ -76,6 +78,7 @@ import com.android.internal.app.IBatteryStats; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.AsyncChannel; import com.android.server.am.BatteryStatsService; import com.android.server.PPPOEService; import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED; import static com.android.server.wifi.WifiController.CMD_BATTERY_CHANGED; import static com.android.server.wifi.WifiController.CMD_EMERGENCY_MODE_CHANGED; Loading Loading @@ -271,6 +274,39 @@ public final class WifiService extends IWifiManager.Stub { } WifiStateMachineHandler mWifiStateMachineHandler; /** * Handles interaction with PPPOEService */ private class PPPOEHandler extends Handler { PPPOEHandler(android.os.Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: { if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { Slog.e(TAG, "PPPOEService connection success"); } else { Slog.e(TAG, "PPPOEService connection failure, error=" + msg.arg1); } break; } case AsyncChannel.CMD_CHANNEL_DISCONNECTED: { Slog.e(TAG, "PPPOEHandler channel lost, msg.arg1 =" + msg.arg1); break; } default: { Slog.d(TAG, "PPPOEHandler.handleMessage ignoring msg=" + msg); break; } } } } PPPOEHandler mPPPOEHandler; private WifiWatchdogStateMachine mWifiWatchdogStateMachine; public WifiService(Context context) { Loading @@ -297,6 +333,7 @@ public final class WifiService extends IWifiManager.Stub { mBatchedScanSupported = mContext.getResources().getBoolean( R.bool.config_wifi_batched_scan_supported); mPPPOEHandler = new PPPOEHandler(wifiThread.getLooper()); registerForScanModeChange(); mContext.registerReceiver( new BroadcastReceiver() { Loading @@ -317,6 +354,9 @@ public final class WifiService extends IWifiManager.Stub { private WifiController mWifiController; private AsyncChannel mPPPOEServiceChannel; private PPPOEService mPPPOEService; /** * Check if Wi-Fi needs to be enabled and start * if needed Loading @@ -335,6 +375,9 @@ public final class WifiService extends IWifiManager.Stub { mWifiWatchdogStateMachine = WifiWatchdogStateMachine. makeWifiWatchdogStateMachine(mContext); mPPPOEService = new PPPOEService(mContext); mPPPOEServiceChannel = new AsyncChannel(); mPPPOEServiceChannel.connect(mContext, mPPPOEHandler, mPPPOEService.getMessenger()); } Loading Loading @@ -1133,6 +1176,21 @@ public final class WifiService extends IWifiManager.Stub { return mWifiStateMachine.getConfigFile(); } public void startPPPOE(PPPOEConfig config) { mPPPOEServiceChannel.sendMessage( mPPPOEHandler.obtainMessage(PPPOEService.CMD_START_PPPOE, config)); } public void stopPPPOE() { mPPPOEServiceChannel.sendMessage(PPPOEService.CMD_STOP_PPPOE); } /** */ public PPPOEInfo getPPPOEInfo() { return mPPPOEService.getPPPOEInfo(); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Loading
wifi/java/android/net/wifi/IWifiManager.aidl +8 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package android.net.wifi; import android.net.wifi.BatchedScanResult; import android.net.wifi.BatchedScanSettings; import android.net.wifi.PPPOEConfig; import android.net.wifi.PPPOEInfo; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiInfo; import android.net.wifi.ScanResult; Loading Loading @@ -126,5 +128,11 @@ interface IWifiManager boolean isBatchedScanSupported(); void pollBatchedScan(); void startPPPOE(in PPPOEConfig config); void stopPPPOE(); PPPOEInfo getPPPOEInfo(); }
wifi/java/android/net/wifi/PPPOEConfig.aidl 0 → 100644 +22 −0 Original line number Diff line number Diff line /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. * Not a Contribution. * * Copyright (c) 2008, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.net.wifi; parcelable PPPOEConfig;
wifi/java/android/net/wifi/PPPOEConfig.java 0 → 100644 +120 −0 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of The Linux Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ package android.net.wifi; import android.os.Parcel; import android.os.Parcelable; import java.io.FileOutputStream; import java.io.IOException; /** @hide */ public class PPPOEConfig implements Parcelable { public final static String PPPOE_DEFAULT_INTERFACE = "wlan0"; public final static int PPPOE_DEFAULT_LCP_ECHO_INTERVAL = 20; public final static int PPPOE_DEFAULT_LCP_ECHO_FAILURE = 3; public final static int PPPOE_DEFAULT_MTU = 1492; public final static int PPPOE_DEFAULT_MRU = 1492; public final static int PPPOE_DEFAULT_TIMEOUT = 80; public final static int PPPOE_DEFAULT_MSS = 1412; public String username; public String password; public String interf; public int lcp_echo_interval; public int lcp_echo_failure; public int mtu; public int mru; public int timeout; public int MSS; public PPPOEConfig() { this(null, null); } public PPPOEConfig(String user, String pass) { this(user, pass, PPPOE_DEFAULT_INTERFACE, PPPOE_DEFAULT_LCP_ECHO_INTERVAL, PPPOE_DEFAULT_LCP_ECHO_FAILURE, PPPOE_DEFAULT_MTU, PPPOE_DEFAULT_MRU, PPPOE_DEFAULT_TIMEOUT, PPPOE_DEFAULT_MSS); } public PPPOEConfig(String user, String pass, String iface, int lcp_echo_interval, int lcp_echo_failure, int mtu, int mru, int timeout, int mss) { this.username = user; this.password = pass; this.interf = iface; this.lcp_echo_interval = lcp_echo_interval; this.lcp_echo_failure = lcp_echo_failure; this.mtu = mtu; this.mru = mru; this.timeout = timeout; this.MSS = mss; } /** Implement the Parcelable interface */ public int describeContents() { return 0; } /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(username); dest.writeString(password); dest.writeString(interf); dest.writeInt(lcp_echo_interval); dest.writeInt(lcp_echo_failure); dest.writeInt(mtu); dest.writeInt(mru); dest.writeInt(timeout); dest.writeInt(MSS); } /** Implement the Parcelable interface */ public static final Creator<PPPOEConfig> CREATOR = new Creator<PPPOEConfig>() { public PPPOEConfig createFromParcel(Parcel in) { PPPOEConfig config = new PPPOEConfig(); config.username = in.readString(); config.password = in.readString(); config.interf = in.readString(); config.lcp_echo_interval = in.readInt(); config.lcp_echo_failure = in.readInt(); config.mtu = in.readInt(); config.mru = in.readInt(); config.timeout = in.readInt(); config.MSS = in.readInt(); return config; } public PPPOEConfig[] newArray(int size) { return new PPPOEConfig[size]; } }; }