WificondControl.java revision 7065d8fb5b3b814d9f15d053b3a30f4543164bae
170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang/* 270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Copyright (C) 2017 The Android Open Source Project 370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * 470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Licensed under the Apache License, Version 2.0 (the "License"); 570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * you may not use this file except in compliance with the License. 670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * You may obtain a copy of the License at 770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * 870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * http://www.apache.org/licenses/LICENSE-2.0 970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * 1070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Unless required by applicable law or agreed to in writing, software 1170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * distributed under the License is distributed on an "AS IS" BASIS, 1270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * See the License for the specific language governing permissions and 1470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * limitations under the License. 1570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 1670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 1770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangpackage com.android.server.wifi; 1870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 19c7685b40d77b12820c5b04013592834025086cefRoshan Piusimport android.annotation.NonNull; 2070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IApInterface; 21045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Piusimport android.net.wifi.IApInterfaceEventCallback; 2270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IClientInterface; 2304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wangimport android.net.wifi.IPnoScanEvent; 2470a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wangimport android.net.wifi.IScanEvent; 258631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.IWifiScannerImpl; 2670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IWificond; 278631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.ScanResult; 28045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Piusimport android.net.wifi.WifiConfiguration; 2904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wangimport android.net.wifi.WifiScanner; 308631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.WifiSsid; 3170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.os.Binder; 3255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Piusimport android.os.IBinder; 3370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.os.RemoteException; 3470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.util.Log; 3570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 36045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Piusimport com.android.server.wifi.WifiNative.SoftApListener; 378631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.hotspot2.NetworkDetail; 388631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.util.InformationElementUtil; 39f4b53ff21ce0aa25131222d0cd15cc4a5e8c0c4fNingyuan Wangimport com.android.server.wifi.util.NativeUtil; 404eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiuimport com.android.server.wifi.util.ScanResultUtil; 41e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport com.android.server.wifi.wificond.ChannelSettings; 42e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport com.android.server.wifi.wificond.HiddenNetwork; 438631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.wificond.NativeScanResult; 4404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wangimport com.android.server.wifi.wificond.PnoNetwork; 4504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wangimport com.android.server.wifi.wificond.PnoSettings; 46e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport com.android.server.wifi.wificond.SingleScanSettings; 478631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 48045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Piusimport java.nio.charset.StandardCharsets; 498631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport java.util.ArrayList; 50e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport java.util.Set; 518631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 5270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang/** 5370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * This class provides methods for WifiNative to send control commands to wificond. 5470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * NOTE: This class should only be used from WifiNative. 5570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 5655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Piuspublic class WificondControl implements IBinder.DeathRecipient { 572e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang private boolean mVerboseLoggingEnabled = false; 5870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 5970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private static final String TAG = "WificondControl"; 6071c4c2a898a827a867564159ce78e41aedd2295bSohani Rao 6171c4c2a898a827a867564159ce78e41aedd2295bSohani Rao /* Get scan results for a single scan */ 6271c4c2a898a827a867564159ce78e41aedd2295bSohani Rao public static final int SCAN_TYPE_SINGLE_SCAN = 0; 6371c4c2a898a827a867564159ce78e41aedd2295bSohani Rao 6471c4c2a898a827a867564159ce78e41aedd2295bSohani Rao /* Get scan results for Pno Scan */ 6571c4c2a898a827a867564159ce78e41aedd2295bSohani Rao public static final int SCAN_TYPE_PNO_SCAN = 1; 6671c4c2a898a827a867564159ce78e41aedd2295bSohani Rao 6770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private WifiInjector mWifiInjector; 6870a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private WifiMonitor mWifiMonitor; 694eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu private final CarrierNetworkConfig mCarrierNetworkConfig; 7070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 7170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang // Cached wificond binder handlers. 7270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IWificond mWificond; 7370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IClientInterface mClientInterface; 7470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IApInterface mApInterface; 758631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang private IWifiScannerImpl mWificondScanner; 7670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private IScanEvent mScanEventHandler; 7704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang private IPnoScanEvent mPnoScanEventHandler; 78045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius private IApInterfaceEventCallback mApInterfaceListener; 7955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius private WifiNative.WificondDeathEventHandler mDeathEventHandler; 8070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 8170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private String mClientInterfaceName; 8270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 8370a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 8470a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private class ScanEventHandler extends IScanEvent.Stub { 8570a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang @Override 8670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang public void OnScanResultReady() { 8770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang Log.d(TAG, "Scan result ready event"); 8870a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWifiMonitor.broadcastScanResultEvent(mClientInterfaceName); 8970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 9070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 9170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang @Override 9270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang public void OnScanFailed() { 9370a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang Log.d(TAG, "Scan failed event"); 9470a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWifiMonitor.broadcastScanFailedEvent(mClientInterfaceName); 9570a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 9670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 9770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 984eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu WificondControl(WifiInjector wifiInjector, WifiMonitor wifiMonitor, 994eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu CarrierNetworkConfig carrierNetworkConfig) { 10070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWifiInjector = wifiInjector; 10170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWifiMonitor = wifiMonitor; 1024eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu mCarrierNetworkConfig = carrierNetworkConfig; 10370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 10470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 10504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang private class PnoScanEventHandler extends IPnoScanEvent.Stub { 10604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang @Override 10704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang public void OnPnoNetworkFound() { 10804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.d(TAG, "Pno scan result event"); 10951493e199ebf1e1191ccf652f0081d229018a11fNingyuan Wang mWifiMonitor.broadcastPnoScanResultEvent(mClientInterfaceName); 110a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoFoundNetworkEventCount(); 11104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 11204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 11304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang @Override 11404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang public void OnPnoScanFailed() { 11504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.d(TAG, "Pno Scan failed event"); 116a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanFailedCount(); 11704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 11885c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao 11985c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao @Override 12085c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao public void OnPnoScanOverOffloadStarted() { 12185c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao Log.d(TAG, "Pno scan over offload started"); 122a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanStartedOverOffloadCount(); 12385c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao } 12485c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao 12585c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao @Override 12685c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao public void OnPnoScanOverOffloadFailed(int reason) { 12785c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao Log.d(TAG, "Pno scan over offload failed"); 128a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanFailedOverOffloadCount(); 12985c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao } 13004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 13104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 132045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius /** 133045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * Listener for AP Interface events. 134045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius */ 135045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { 136045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius private SoftApListener mSoftApListener; 137045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 138045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius ApInterfaceEventCallback(SoftApListener listener) { 139045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius mSoftApListener = listener; 140045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 141045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 142045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius @Override 143045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius public void onNumAssociatedStationsChanged(int numStations) { 144045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius mSoftApListener.onNumAssociatedStationsChanged(numStations); 145045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 146045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 147045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 14855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 14955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Called by the binder subsystem upon remote object death. 15055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Invoke all the register death handlers and clear state. 15155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 15255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius @Override 15355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius public void binderDied() { 15455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "Wificond died!"); 15555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (mDeathEventHandler != null) { 15655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mDeathEventHandler.onDeath(); 15755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 15855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius clearState(); 15955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // Invalidate the global wificond handle on death. Will be refereshed 16055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // on the next setup call. 16155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mWificond = null; 16255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 16355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius 1642e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang /** Enable or disable verbose logging of WificondControl. 1652e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang * @param enable True to enable verbose logging. False to disable verbose logging. 1662e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang */ 1672e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang public void enableVerboseLogging(boolean enable) { 1682e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang mVerboseLoggingEnabled = enable; 1692e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang } 1702e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang 17170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 17255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Registers a death notification for wificond. 17355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * @return Returns true on success. 17455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 17555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius public boolean registerDeathHandler(@NonNull WifiNative.WificondDeathEventHandler handler) { 17655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (mDeathEventHandler != null) { 17755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "Death handler already present"); 17855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return false; 17955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 18055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mDeathEventHandler = handler; 18155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return true; 18255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 18355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius 18455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 18555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Deregisters a death notification for wificond. 18655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * @return Returns true on success. 18755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 18855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius public boolean deregisterDeathHandler() { 18955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (mDeathEventHandler == null) { 19055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "No Death handler present"); 19155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return false; 19255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 19355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mDeathEventHandler = null; 19455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return true; 19555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 19655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius 19755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 19855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Helper method to retrieve the global wificond handle and register for 19955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * death notifications. 20055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 20155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius private boolean retrieveWificondAndRegisterForDeath() { 20255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (mWificond != null) { 20355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.d(TAG, "Wificond handle already retrieved"); 20455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // We already have a wificond handle. 20555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return true; 20655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 20755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mWificond = mWifiInjector.makeWificond(); 20855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (mWificond == null) { 20955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "Failed to get reference to wificond"); 21055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return false; 21155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 21255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius try { 21355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mWificond.asBinder().linkToDeath(this, 0); 21455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } catch (RemoteException e) { 21555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "Failed to register death notification for wificond"); 21655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // The remote has already died. 21755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return false; 21855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 21955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return true; 22055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 22155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius 22255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 2237065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * Setup interface for client mode via wificond. 22470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return An IClientInterface as wificond client interface binder handler. 22570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Returns null on failure. 22670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 2277065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius public IClientInterface setupInterfaceForClientMode(@NonNull String ifaceName) { 2287065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.d(TAG, "Setting up interface for client mode"); 22955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 23070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 23170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 23270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 23370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang IClientInterface clientInterface = null; 23470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 235c7685b40d77b12820c5b04013592834025086cefRoshan Pius clientInterface = mWificond.createClientInterface(ifaceName); 23670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e1) { 23770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get IClientInterface due to remote exception"); 23870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 23970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 24070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 24170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (clientInterface == null) { 24270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Could not get IClientInterface instance from wificond"); 24370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 24470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 24570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Binder.allowBlocking(clientInterface.asBinder()); 24670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 24770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Refresh Handlers 24870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mClientInterface = clientInterface; 2498631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang try { 25070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mClientInterfaceName = clientInterface.getInterfaceName(); 2518631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang mWificondScanner = mClientInterface.getWifiScannerImpl(); 252bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang if (mWificondScanner == null) { 253bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang Log.e(TAG, "Failed to get WificondScannerImpl"); 254bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang return null; 255bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang } 256bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang Binder.allowBlocking(mWificondScanner.asBinder()); 25770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mScanEventHandler = new ScanEventHandler(); 25870a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWificondScanner.subscribeScanEvents(mScanEventHandler); 25904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang mPnoScanEventHandler = new PnoScanEventHandler(); 26004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang mWificondScanner.subscribePnoScanEvents(mPnoScanEventHandler); 2618631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } catch (RemoteException e) { 2628631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); 2638631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 26470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 26570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return clientInterface; 26670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 26770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 26870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 2697065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * Teardown a specific STA interface configured in wificond. 2707065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * 2717065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * @return Returns true on success. 2727065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius */ 2737065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius public boolean tearDownClientInterface(@NonNull String ifaceName) { 2747065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius boolean success; 2757065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius try { 2767065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius if (mWificondScanner != null) { 2777065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mWificondScanner.unsubscribeScanEvents(); 2787065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mWificondScanner.unsubscribePnoScanEvents(); 2797065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 2807065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } catch (RemoteException e) { 2817065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); 2827065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 2837065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 2847065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius 2857065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius try { 2867065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius success = mWificond.tearDownClientInterface(ifaceName); 2877065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } catch (RemoteException e1) { 2887065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to teardown client interface due to remote exception"); 2897065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 2907065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 2917065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius if (!success) { 2927065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to teardown client interface"); 2937065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 2947065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 2957065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius 2967065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mClientInterface = null; 2977065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mWificondScanner = null; 2987065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mPnoScanEventHandler = null; 2997065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mScanEventHandler = null; 3007065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return true; 3017065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3027065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius 3037065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius /** 3047065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * Setup interface for softAp mode via wificond. 30570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return An IApInterface as wificond Ap interface binder handler. 30670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Returns null on failure. 30770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 3087065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius public IApInterface setupInterfaceForSoftApMode(@NonNull String ifaceName) { 3097065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.d(TAG, "Setting up interface for soft ap mode"); 31055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 31170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 31270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 31370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 31470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang IApInterface apInterface = null; 31570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 316c7685b40d77b12820c5b04013592834025086cefRoshan Pius apInterface = mWificond.createApInterface(ifaceName); 31770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e1) { 31870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get IApInterface due to remote exception"); 31970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 32070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 32170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 32270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (apInterface == null) { 32370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Could not get IApInterface instance from wificond"); 32470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 32570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 32670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Binder.allowBlocking(apInterface.asBinder()); 32770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 32870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Refresh Handlers 32970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mApInterface = apInterface; 33070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 33170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return apInterface; 33270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 33370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 33470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 3357065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * Teardown a specific AP interface configured in wificond. 3367065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * 3377065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * @return Returns true on success. 3387065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius */ 3397065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius public boolean tearDownSoftApInterface(@NonNull String ifaceName) { 3407065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius boolean success; 3417065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius try { 3427065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius success = mWificond.tearDownApInterface(ifaceName); 3437065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } catch (RemoteException e1) { 3447065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to teardown AP interface due to remote exception"); 3457065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 3467065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3477065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius if (!success) { 3487065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to teardown AP interface"); 3497065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 3507065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3517065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mApInterface = null; 3527065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mApInterfaceListener = null; 3537065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return true; 3547065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3557065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius 3567065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius /** 35770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Teardown all interfaces configured in wificond. 35870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 35970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 36070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean tearDownInterfaces() { 361512ba9008e5b9ab4019647eb036c303a6bb9e0ceNingyuan Wang Log.d(TAG, "tearing down interfaces in wificond"); 36270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Explicitly refresh the wificodn handler because |tearDownInterfaces()| 36370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // could be used to cleanup before we setup any interfaces. 36455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 36570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 36670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 36770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 36870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 36970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang if (mWificondScanner != null) { 37070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWificondScanner.unsubscribeScanEvents(); 37104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang mWificondScanner.unsubscribePnoScanEvents(); 37270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 37370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond.tearDownInterfaces(); 37455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius clearState(); 37570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return true; 37670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 37770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to tear down interfaces due to remote exception"); 37870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 37970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 38070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 38170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 38270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 38370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 38470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Disable wpa_supplicant via wificond. 38570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 38670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 38770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean disableSupplicant() { 38855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 38970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 39070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 39170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 3927a9936461744922f7785a192493ccce7c4fb52f9Roshan Pius return mWificond.disableSupplicant(); 39370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 39470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to disable supplicant due to remote exception"); 39570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 39670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 39770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 39870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 39970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 40070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Enable wpa_supplicant via wificond. 40170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 40270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 40370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean enableSupplicant() { 40455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 40570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 40670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 40770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 4087a9936461744922f7785a192493ccce7c4fb52f9Roshan Pius return mWificond.enableSupplicant(); 40970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 41070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to enable supplicant due to remote exception"); 41170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 41270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 41370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 414d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 415d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang /** 416d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Request signal polling to wificond. 417d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns an SignalPollResult object. 418d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns null on failure. 419d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang */ 420d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang public WifiNative.SignalPollResult signalPoll() { 421d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (mClientInterface == null) { 422d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 423d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 424d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 425d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 426d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang int[] resultArray; 427d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang try { 428d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang resultArray = mClientInterface.signalPoll(); 429d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (resultArray == null || resultArray.length != 3) { 430d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "Invalid signal poll result from wificond"); 431d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 432d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 433d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } catch (RemoteException e) { 4342e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.e(TAG, "Failed to do signal polling due to remote exception"); 435d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 436d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 437d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang WifiNative.SignalPollResult pollResult = new WifiNative.SignalPollResult(); 438d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.currentRssi = resultArray[0]; 439d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.txBitrate = resultArray[1]; 440d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.associationFrequency = resultArray[2]; 441d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return pollResult; 442d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 443d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 444d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang /** 445d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Fetch TX packet counters on current connection from wificond. 446d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns an TxPacketCounters object. 447d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns null on failure. 448d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang */ 449d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang public WifiNative.TxPacketCounters getTxPacketCounters() { 450d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (mClientInterface == null) { 451d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 452d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 453d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 454d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 455d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang int[] resultArray; 456d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang try { 457d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang resultArray = mClientInterface.getPacketCounters(); 458d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (resultArray == null || resultArray.length != 2) { 459d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "Invalid signal poll result from wificond"); 460d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 461d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 462d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } catch (RemoteException e) { 4632e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.e(TAG, "Failed to do signal polling due to remote exception"); 464d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 465d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 466d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang WifiNative.TxPacketCounters counters = new WifiNative.TxPacketCounters(); 467d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang counters.txSucceeded = resultArray[0]; 468d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang counters.txFailed = resultArray[1]; 469d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return counters; 470d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 4718631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 4728631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang /** 4738631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * Fetch the latest scan result from kernel via wificond. 4748631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * @return Returns an ArrayList of ScanDetail. 4758631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * Returns an empty ArrayList on failure. 4768631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang */ 47771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao public ArrayList<ScanDetail> getScanResults(int scanType) { 4788631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ArrayList<ScanDetail> results = new ArrayList<>(); 4798631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang if (mWificondScanner == null) { 4808631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 4818631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang return results; 4828631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 4838631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang try { 48471c4c2a898a827a867564159ce78e41aedd2295bSohani Rao NativeScanResult[] nativeResults; 48571c4c2a898a827a867564159ce78e41aedd2295bSohani Rao if (scanType == SCAN_TYPE_SINGLE_SCAN) { 48671c4c2a898a827a867564159ce78e41aedd2295bSohani Rao nativeResults = mWificondScanner.getScanResults(); 48771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao } else { 48871c4c2a898a827a867564159ce78e41aedd2295bSohani Rao nativeResults = mWificondScanner.getPnoScanResults(); 48971c4c2a898a827a867564159ce78e41aedd2295bSohani Rao } 4908631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang for (NativeScanResult result : nativeResults) { 491755bbe962c20d37491dd9264ad3497bf27e33602Ningyuan Wang WifiSsid wifiSsid = WifiSsid.createFromByteArray(result.ssid); 4928ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang String bssid; 4938ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang try { 4948ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang bssid = NativeUtil.macAddressFromByteArray(result.bssid); 4958ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } catch (IllegalArgumentException e) { 4968ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang Log.e(TAG, "Illegal argument " + result.bssid, e); 4978ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang continue; 4988ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } 4998ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang if (bssid == null) { 5008ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang Log.e(TAG, "Illegal null bssid"); 5018ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang continue; 5028ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } 5038631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ScanResult.InformationElement[] ies = 5048631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang InformationElementUtil.parseInformationElements(result.infoElement); 5058631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang InformationElementUtil.Capabilities capabilities = 5068631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang new InformationElementUtil.Capabilities(); 5078631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang capabilities.from(ies, result.capability); 5088631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang String flags = capabilities.generateCapabilitiesString(); 5090a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang NetworkDetail networkDetail; 5100a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang try { 5110a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang networkDetail = new NetworkDetail(bssid, ies, null, result.frequency); 5120a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang } catch (IllegalArgumentException e) { 5130a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang Log.e(TAG, "Illegal argument for scan result with bssid: " + bssid, e); 5140a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang continue; 5150a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang } 5168631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 5178631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ScanDetail scanDetail = new ScanDetail(networkDetail, wifiSsid, bssid, flags, 5188631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang result.signalMbm / 100, result.frequency, result.tsf, ies, null); 5194eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu // Update carrier network info if this AP's SSID is associated with a carrier Wi-Fi 5204eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu // network and it uses EAP. 5214eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu if (ScanResultUtil.isScanResultForEapNetwork(scanDetail.getScanResult()) 5224eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu && mCarrierNetworkConfig.isCarrierNetwork(wifiSsid.toString())) { 5234eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu scanDetail.getScanResult().isCarrierAp = true; 5244eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu scanDetail.getScanResult().carrierApEapType = 5254eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu mCarrierNetworkConfig.getNetworkEapType(wifiSsid.toString()); 5264eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu scanDetail.getScanResult().carrierName = 5274eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu mCarrierNetworkConfig.getCarrierName(wifiSsid.toString()); 5284eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu } 5298631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang results.add(scanDetail); 5308631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 5318631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } catch (RemoteException e1) { 5328631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Failed to create ScanDetail ArrayList"); 5338631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 5342e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang if (mVerboseLoggingEnabled) { 5352e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.d(TAG, "get " + results.size() + " scan results from wificond"); 5362e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang } 5372e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang 5388631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang return results; 5398631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 540e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 541e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang /** 542e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * Start a scan using wificond for the given parameters. 543e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @param freqs list of frequencies to scan for, if null scan all supported channels. 544e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. 545e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @return Returns true on success. 546e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang */ 547e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang public boolean scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) { 548e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang if (mWificondScanner == null) { 549e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 550e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang return false; 551e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 552e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang SingleScanSettings settings = new SingleScanSettings(); 553e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.channelSettings = new ArrayList<>(); 554e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.hiddenNetworks = new ArrayList<>(); 555e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 556e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang if (freqs != null) { 557e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang for (Integer freq : freqs) { 558e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang ChannelSettings channel = new ChannelSettings(); 559e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang channel.frequency = freq; 560e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.channelSettings.add(channel); 561e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 562e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 563e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang if (hiddenNetworkSSIDs != null) { 564e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang for (String ssid : hiddenNetworkSSIDs) { 565e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang HiddenNetwork network = new HiddenNetwork(); 5668ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang try { 5678ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang network.ssid = NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(ssid)); 5688ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } catch (IllegalArgumentException e) { 5698ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang Log.e(TAG, "Illegal argument " + ssid, e); 5708ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang continue; 5718ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } 572e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.hiddenNetworks.add(network); 573e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 574e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 575e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 576e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang try { 577e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang return mWificondScanner.scan(settings); 578e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } catch (RemoteException e1) { 579e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang Log.e(TAG, "Failed to request scan due to remote exception"); 580e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 581e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang return false; 582e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 583e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 58404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang /** 58504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * Start PNO scan. 58604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * @param pnoSettings Pno scan configuration. 58704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * @return true on success. 58804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang */ 58904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang public boolean startPnoScan(WifiNative.PnoSettings pnoSettings) { 59004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang if (mWificondScanner == null) { 59104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 59204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return false; 59304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 59404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang PnoSettings settings = new PnoSettings(); 59504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.pnoNetworks = new ArrayList<>(); 59604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.intervalMs = pnoSettings.periodInMs; 59704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.min2gRssi = pnoSettings.min24GHzRssi; 59804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.min5gRssi = pnoSettings.min5GHzRssi; 59904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang if (pnoSettings.networkList != null) { 60004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang for (WifiNative.PnoNetwork network : pnoSettings.networkList) { 60104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang PnoNetwork condNetwork = new PnoNetwork(); 60204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang condNetwork.isHidden = (network.flags 60304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang & WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN) != 0; 6048ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang try { 6058ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang condNetwork.ssid = 6068ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(network.ssid)); 6078ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } catch (IllegalArgumentException e) { 6088ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang Log.e(TAG, "Illegal argument " + network.ssid, e); 6098ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang continue; 6108ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } 61104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.pnoNetworks.add(condNetwork); 61204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 61304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 61404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 61504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang try { 616a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh boolean success = mWificondScanner.startPnoScan(settings); 617a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanStartAttempCount(); 618a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh if (!success) { 619a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanFailedCount(); 620a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh } 621a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh return success; 62204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } catch (RemoteException e1) { 623a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh Log.e(TAG, "Failed to start pno scan due to remote exception"); 62404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 62504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return false; 62604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 62704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 62804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang /** 62904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * Stop PNO scan. 63004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * @return true on success. 63104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang */ 63204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang public boolean stopPnoScan() { 63304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang if (mWificondScanner == null) { 63404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 63504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return false; 63604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 63704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang try { 63804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return mWificondScanner.stopPnoScan(); 63904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } catch (RemoteException e1) { 64004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.e(TAG, "Failed to stop pno scan due to remote exception"); 64104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 64204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return false; 64304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 64404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 645c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang /** 646c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang * Abort ongoing single scan. 647c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang */ 648c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang public void abortScan() { 649c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang if (mWificondScanner == null) { 650c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 651c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang return; 652c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang } 653c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang try { 654c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang mWificondScanner.abortScan(); 655c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang } catch (RemoteException e1) { 656c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang Log.e(TAG, "Failed to request abortScan due to remote exception"); 657c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang } 658c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang } 659c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang 6606baff2cb8dec599af186be521882413787595930Ningyuan Wang /** 6616baff2cb8dec599af186be521882413787595930Ningyuan Wang * Query the list of valid frequencies for the provided band. 6626baff2cb8dec599af186be521882413787595930Ningyuan Wang * The result depends on the on the country code that has been set. 6636baff2cb8dec599af186be521882413787595930Ningyuan Wang * 6646baff2cb8dec599af186be521882413787595930Ningyuan Wang * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. 6656baff2cb8dec599af186be521882413787595930Ningyuan Wang * The following bands are supported: 6666baff2cb8dec599af186be521882413787595930Ningyuan Wang * WifiScanner.WIFI_BAND_24_GHZ 6676baff2cb8dec599af186be521882413787595930Ningyuan Wang * WifiScanner.WIFI_BAND_5_GHZ 6686baff2cb8dec599af186be521882413787595930Ningyuan Wang * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY 6696baff2cb8dec599af186be521882413787595930Ningyuan Wang * @return frequencies vector of valid frequencies (MHz), or null for error. 6706baff2cb8dec599af186be521882413787595930Ningyuan Wang * @throws IllegalArgumentException if band is not recognized. 6716baff2cb8dec599af186be521882413787595930Ningyuan Wang */ 6726baff2cb8dec599af186be521882413787595930Ningyuan Wang public int [] getChannelsForBand(int band) { 6736baff2cb8dec599af186be521882413787595930Ningyuan Wang if (mWificond == null) { 6746baff2cb8dec599af186be521882413787595930Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 6756baff2cb8dec599af186be521882413787595930Ningyuan Wang return null; 6766baff2cb8dec599af186be521882413787595930Ningyuan Wang } 6776baff2cb8dec599af186be521882413787595930Ningyuan Wang try { 6786baff2cb8dec599af186be521882413787595930Ningyuan Wang switch (band) { 6796baff2cb8dec599af186be521882413787595930Ningyuan Wang case WifiScanner.WIFI_BAND_24_GHZ: 6806baff2cb8dec599af186be521882413787595930Ningyuan Wang return mWificond.getAvailable2gChannels(); 6816baff2cb8dec599af186be521882413787595930Ningyuan Wang case WifiScanner.WIFI_BAND_5_GHZ: 6826baff2cb8dec599af186be521882413787595930Ningyuan Wang return mWificond.getAvailable5gNonDFSChannels(); 6836baff2cb8dec599af186be521882413787595930Ningyuan Wang case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: 6846baff2cb8dec599af186be521882413787595930Ningyuan Wang return mWificond.getAvailableDFSChannels(); 6856baff2cb8dec599af186be521882413787595930Ningyuan Wang default: 6866baff2cb8dec599af186be521882413787595930Ningyuan Wang throw new IllegalArgumentException("unsupported band " + band); 6876baff2cb8dec599af186be521882413787595930Ningyuan Wang } 6886baff2cb8dec599af186be521882413787595930Ningyuan Wang } catch (RemoteException e1) { 6896baff2cb8dec599af186be521882413787595930Ningyuan Wang Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); 6906baff2cb8dec599af186be521882413787595930Ningyuan Wang } 6916baff2cb8dec599af186be521882413787595930Ningyuan Wang return null; 6926baff2cb8dec599af186be521882413787595930Ningyuan Wang } 693045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 694045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius /** 695045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * Start Soft AP operation using the provided configuration. 696045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * 697045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * @param config Configuration to use for the soft ap created. 698045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * @param listener Callback for AP events. 699045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * @return true on success, false otherwise. 700045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius */ 701045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius public boolean startSoftAp(WifiConfiguration config, SoftApListener listener) { 702045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius if (mApInterface == null) { 703045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "No valid ap interface handler"); 704045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 705045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 706045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius int encryptionType = getIApInterfaceEncryptionType(config); 707045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius try { 708045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius // TODO(b/67745880) Note that config.SSID is intended to be either a 709045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius // hex string or "double quoted". 710045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius // However, it seems that whatever is handing us these configurations does not obey 711045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius // this convention. 712045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius boolean success = mApInterface.writeHostapdConfig( 713045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius config.SSID.getBytes(StandardCharsets.UTF_8), config.hiddenSSID, 714045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius config.apChannel, encryptionType, 715045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius (config.preSharedKey != null) 716045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius ? config.preSharedKey.getBytes(StandardCharsets.UTF_8) 717045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius : new byte[0]); 718045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius if (!success) { 719045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Failed to write hostapd configuration"); 720045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 721045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 722045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius mApInterfaceListener = new ApInterfaceEventCallback(listener); 723045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius success = mApInterface.startHostapd(mApInterfaceListener); 724045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius if (!success) { 725045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Failed to start hostapd."); 726045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 727045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 728045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } catch (RemoteException e) { 729045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Exception in starting soft AP: " + e); 730045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 731045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 732045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return true; 733045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 734045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 735045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius /** 736045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * Stop the ongoing Soft AP operation. 737045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * 738045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * @return true on success, false otherwise. 739045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius */ 740045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius public boolean stopSoftAp() { 741045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius if (mApInterface == null) { 742045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "No valid ap interface handler"); 743045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 744045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 745045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius try { 746045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius boolean success = mApInterface.stopHostapd(); 747045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius if (!success) { 748045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Failed to stop hostapd."); 749045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 750045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 751045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } catch (RemoteException e) { 752045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Exception in stopping soft AP: " + e); 753045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 754045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 755045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius mApInterfaceListener = null; 756045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return true; 757045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 758045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 759045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius private static int getIApInterfaceEncryptionType(WifiConfiguration localConfig) { 760045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius int encryptionType; 761045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius switch (localConfig.getAuthType()) { 762045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius case WifiConfiguration.KeyMgmt.NONE: 763045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius encryptionType = IApInterface.ENCRYPTION_TYPE_NONE; 764045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius break; 765045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius case WifiConfiguration.KeyMgmt.WPA_PSK: 766045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius encryptionType = IApInterface.ENCRYPTION_TYPE_WPA; 767045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius break; 768045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius case WifiConfiguration.KeyMgmt.WPA2_PSK: 769045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius encryptionType = IApInterface.ENCRYPTION_TYPE_WPA2; 770045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius break; 771045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius default: 772045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius // We really shouldn't default to None, but this was how NetworkManagementService 773045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius // used to do this. 774045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius encryptionType = IApInterface.ENCRYPTION_TYPE_NONE; 775045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius break; 776045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 777045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return encryptionType; 778045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 77955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius 78055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 78155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Clear all internal handles. 78255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 78355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius private void clearState() { 78455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // Refresh handlers 78555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mClientInterface = null; 78655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mWificondScanner = null; 78755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mPnoScanEventHandler = null; 78855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mScanEventHandler = null; 78955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mApInterface = null; 7907065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius mApInterfaceListener = null; 79155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 79270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang} 793