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; 20f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kimimport android.net.MacAddress; 2170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IApInterface; 22045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Piusimport android.net.wifi.IApInterfaceEventCallback; 2370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IClientInterface; 2404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wangimport android.net.wifi.IPnoScanEvent; 2570a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wangimport android.net.wifi.IScanEvent; 268631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.IWifiScannerImpl; 2770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IWificond; 288631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.ScanResult; 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; 463feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Piusimport com.android.server.wifi.wificond.RadioChainInfo; 47e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport com.android.server.wifi.wificond.SingleScanSettings; 488631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 498631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport java.util.ArrayList; 5091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Piusimport java.util.HashMap; 5191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Piusimport java.util.Map; 52e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport java.util.Set; 538631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 5470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang/** 5570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * This class provides methods for WifiNative to send control commands to wificond. 5670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * NOTE: This class should only be used from WifiNative. 5770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 5855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Piuspublic class WificondControl implements IBinder.DeathRecipient { 592e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang private boolean mVerboseLoggingEnabled = false; 6070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 6170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private static final String TAG = "WificondControl"; 6271c4c2a898a827a867564159ce78e41aedd2295bSohani Rao 6371c4c2a898a827a867564159ce78e41aedd2295bSohani Rao /* Get scan results for a single scan */ 6471c4c2a898a827a867564159ce78e41aedd2295bSohani Rao public static final int SCAN_TYPE_SINGLE_SCAN = 0; 6571c4c2a898a827a867564159ce78e41aedd2295bSohani Rao 6671c4c2a898a827a867564159ce78e41aedd2295bSohani Rao /* Get scan results for Pno Scan */ 6771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao public static final int SCAN_TYPE_PNO_SCAN = 1; 6871c4c2a898a827a867564159ce78e41aedd2295bSohani Rao 6970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private WifiInjector mWifiInjector; 7070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private WifiMonitor mWifiMonitor; 714eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu private final CarrierNetworkConfig mCarrierNetworkConfig; 7270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 7370a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang // Cached wificond binder handlers. 7470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IWificond mWificond; 7591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private HashMap<String, IClientInterface> mClientInterfaces = new HashMap<>(); 7691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private HashMap<String, IApInterface> mApInterfaces = new HashMap<>(); 7791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private HashMap<String, IWifiScannerImpl> mWificondScanners = new HashMap<>(); 7891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private HashMap<String, IScanEvent> mScanEventHandlers = new HashMap<>(); 7991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private HashMap<String, IPnoScanEvent> mPnoScanEventHandlers = new HashMap<>(); 8091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private HashMap<String, IApInterfaceEventCallback> mApInterfaceListeners = new HashMap<>(); 8155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius private WifiNative.WificondDeathEventHandler mDeathEventHandler; 8270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 8391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private class ScanEventHandler extends IScanEvent.Stub { 8491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private String mIfaceName; 8570a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 8691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius ScanEventHandler(@NonNull String ifaceName) { 8791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mIfaceName = ifaceName; 8891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius } 8970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 9070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang @Override 9170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang public void OnScanResultReady() { 9270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang Log.d(TAG, "Scan result ready event"); 9391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mWifiMonitor.broadcastScanResultEvent(mIfaceName); 9470a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 9570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 9670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang @Override 9770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang public void OnScanFailed() { 9870a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang Log.d(TAG, "Scan failed event"); 9991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mWifiMonitor.broadcastScanFailedEvent(mIfaceName); 10070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 10170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 10270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 1034eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu WificondControl(WifiInjector wifiInjector, WifiMonitor wifiMonitor, 1044eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu CarrierNetworkConfig carrierNetworkConfig) { 10570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWifiInjector = wifiInjector; 10670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWifiMonitor = wifiMonitor; 1074eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu mCarrierNetworkConfig = carrierNetworkConfig; 10870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 10970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 11004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang private class PnoScanEventHandler extends IPnoScanEvent.Stub { 11191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private String mIfaceName; 11291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius 11391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius PnoScanEventHandler(@NonNull String ifaceName) { 11491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mIfaceName = ifaceName; 11591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius } 11691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius 11704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang @Override 11804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang public void OnPnoNetworkFound() { 11904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.d(TAG, "Pno scan result event"); 12091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mWifiMonitor.broadcastPnoScanResultEvent(mIfaceName); 121a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoFoundNetworkEventCount(); 12204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 12304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 12404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang @Override 12504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang public void OnPnoScanFailed() { 12604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.d(TAG, "Pno Scan failed event"); 127a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanFailedCount(); 12804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 12985c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao 13085c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao @Override 13185c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao public void OnPnoScanOverOffloadStarted() { 13285c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao Log.d(TAG, "Pno scan over offload started"); 133a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanStartedOverOffloadCount(); 13485c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao } 13585c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao 13685c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao @Override 13785c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao public void OnPnoScanOverOffloadFailed(int reason) { 13885c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao Log.d(TAG, "Pno scan over offload failed"); 139a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanFailedOverOffloadCount(); 14085c806c0d32bb30f421ebc372a59b2f3ea2dce41Sohani Rao } 14104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 14204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 143045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius /** 144045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * Listener for AP Interface events. 145045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius */ 146045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius private class ApInterfaceEventCallback extends IApInterfaceEventCallback.Stub { 147045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius private SoftApListener mSoftApListener; 148045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 149045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius ApInterfaceEventCallback(SoftApListener listener) { 150045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius mSoftApListener = listener; 151045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 152045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 153045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius @Override 154045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius public void onNumAssociatedStationsChanged(int numStations) { 155045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius mSoftApListener.onNumAssociatedStationsChanged(numStations); 156045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 1574de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh 1584de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh @Override 1594de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh public void onSoftApChannelSwitched(int frequency, int bandwidth) { 1604de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh mSoftApListener.onSoftApChannelSwitched(frequency, bandwidth); 1614de36821d74eb8980c49a0f79c20343591b12e27Mehdi Alizadeh } 162045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 163045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 16455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 16555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Called by the binder subsystem upon remote object death. 16655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Invoke all the register death handlers and clear state. 16755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 16855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius @Override 16955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius public void binderDied() { 17055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "Wificond died!"); 17155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius clearState(); 172f4e144565d1dba55e25ab7b454a7eb7d4a6f8290Roshan Pius // Invalidate the global wificond handle on death. Will be refreshed 17355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // on the next setup call. 17455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mWificond = null; 175f4e144565d1dba55e25ab7b454a7eb7d4a6f8290Roshan Pius if (mDeathEventHandler != null) { 176f4e144565d1dba55e25ab7b454a7eb7d4a6f8290Roshan Pius mDeathEventHandler.onDeath(); 177f4e144565d1dba55e25ab7b454a7eb7d4a6f8290Roshan Pius } 17855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 17955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius 1802e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang /** Enable or disable verbose logging of WificondControl. 1812e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang * @param enable True to enable verbose logging. False to disable verbose logging. 1822e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang */ 1832e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang public void enableVerboseLogging(boolean enable) { 1842e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang mVerboseLoggingEnabled = enable; 1852e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang } 1862e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang 18770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 188ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius * Initializes wificond & registers a death notification for wificond. 189ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius * This method clears any existing state in wificond daemon. 190ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius * 19155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * @return Returns true on success. 19255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 193ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius public boolean initialize(@NonNull WifiNative.WificondDeathEventHandler handler) { 19455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (mDeathEventHandler != null) { 19555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "Death handler already present"); 19655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 19755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mDeathEventHandler = handler; 198ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius tearDownInterfaces(); 19955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return true; 20055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 20155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius 20255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 20355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Helper method to retrieve the global wificond handle and register for 20455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * death notifications. 20555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 20655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius private boolean retrieveWificondAndRegisterForDeath() { 20755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (mWificond != null) { 208ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius if (mVerboseLoggingEnabled) { 209ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius Log.d(TAG, "Wificond handle already retrieved"); 210ba0868687b7a803bc5f817932fa02c0c3e934254Roshan Pius } 21155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // We already have a wificond handle. 21255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return true; 21355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 21455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mWificond = mWifiInjector.makeWificond(); 21555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (mWificond == null) { 21655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "Failed to get reference to wificond"); 21755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return false; 21855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 21955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius try { 22055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius mWificond.asBinder().linkToDeath(this, 0); 22155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } catch (RemoteException e) { 22255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius Log.e(TAG, "Failed to register death notification for wificond"); 22355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // The remote has already died. 22455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return false; 22555dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 22655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius return true; 22755dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 22855dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius 22955dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 2307065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * Setup interface for client mode via wificond. 23170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return An IClientInterface as wificond client interface binder handler. 23270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Returns null on failure. 23370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 2347065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius public IClientInterface setupInterfaceForClientMode(@NonNull String ifaceName) { 2357065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.d(TAG, "Setting up interface for client mode"); 23655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 23770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 23870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 23970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 24070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang IClientInterface clientInterface = null; 24170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 242c7685b40d77b12820c5b04013592834025086cefRoshan Pius clientInterface = mWificond.createClientInterface(ifaceName); 24370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e1) { 24470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get IClientInterface due to remote exception"); 24570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 24670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 24770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 24870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (clientInterface == null) { 24970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Could not get IClientInterface instance from wificond"); 25070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 25170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 25270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Binder.allowBlocking(clientInterface.asBinder()); 25370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 25470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Refresh Handlers 25591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mClientInterfaces.put(ifaceName, clientInterface); 2568631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang try { 25791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IWifiScannerImpl wificondScanner = clientInterface.getWifiScannerImpl(); 25891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (wificondScanner == null) { 259bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang Log.e(TAG, "Failed to get WificondScannerImpl"); 260bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang return null; 261bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang } 26291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mWificondScanners.put(ifaceName, wificondScanner); 26391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius Binder.allowBlocking(wificondScanner.asBinder()); 26491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius ScanEventHandler scanEventHandler = new ScanEventHandler(ifaceName); 26591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mScanEventHandlers.put(ifaceName, scanEventHandler); 26691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius wificondScanner.subscribeScanEvents(scanEventHandler); 26791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius PnoScanEventHandler pnoScanEventHandler = new PnoScanEventHandler(ifaceName); 26891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mPnoScanEventHandlers.put(ifaceName, pnoScanEventHandler); 26991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius wificondScanner.subscribePnoScanEvents(pnoScanEventHandler); 2708631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } catch (RemoteException e) { 2718631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); 2728631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 27370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 27470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return clientInterface; 27570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 27670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 27770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 2787065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * Teardown a specific STA interface configured in wificond. 2797065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * 2807065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * @return Returns true on success. 2817065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius */ 2827065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius public boolean tearDownClientInterface(@NonNull String ifaceName) { 2834d2109e282e5ff427c64788dae814baccb542faeRoshan Pius if (getClientInterface(ifaceName) == null) { 2844d2109e282e5ff427c64788dae814baccb542faeRoshan Pius Log.e(TAG, "No valid wificond client interface handler"); 2854d2109e282e5ff427c64788dae814baccb542faeRoshan Pius return false; 2864d2109e282e5ff427c64788dae814baccb542faeRoshan Pius } 2877065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius try { 28891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IWifiScannerImpl scannerImpl = mWificondScanners.get(ifaceName); 28991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (scannerImpl != null) { 29091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius scannerImpl.unsubscribeScanEvents(); 29191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius scannerImpl.unsubscribePnoScanEvents(); 2927065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 2937065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } catch (RemoteException e) { 2947065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to unsubscribe wificond scanner due to remote exception"); 2957065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 2967065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 2977065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius 2984d2109e282e5ff427c64788dae814baccb542faeRoshan Pius boolean success; 2997065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius try { 3007065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius success = mWificond.tearDownClientInterface(ifaceName); 3017065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } catch (RemoteException e1) { 3027065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to teardown client interface due to remote exception"); 3037065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 3047065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3057065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius if (!success) { 3067065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to teardown client interface"); 3077065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 3087065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3097065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius 31091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mClientInterfaces.remove(ifaceName); 31191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mWificondScanners.remove(ifaceName); 31291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mScanEventHandlers.remove(ifaceName); 31391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mPnoScanEventHandlers.remove(ifaceName); 3147065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return true; 3157065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3167065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius 3177065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius /** 3187065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * Setup interface for softAp mode via wificond. 31970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return An IApInterface as wificond Ap interface binder handler. 32070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Returns null on failure. 32170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 3227065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius public IApInterface setupInterfaceForSoftApMode(@NonNull String ifaceName) { 3237065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.d(TAG, "Setting up interface for soft ap mode"); 32455dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 32570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 32670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 32770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 32870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang IApInterface apInterface = null; 32970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 330c7685b40d77b12820c5b04013592834025086cefRoshan Pius apInterface = mWificond.createApInterface(ifaceName); 33170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e1) { 33270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get IApInterface due to remote exception"); 33370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 33470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 33570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 33670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (apInterface == null) { 33770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Could not get IApInterface instance from wificond"); 33870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 33970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 34070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Binder.allowBlocking(apInterface.asBinder()); 34170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 34270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Refresh Handlers 34391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mApInterfaces.put(ifaceName, apInterface); 34470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return apInterface; 34570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 34670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 34770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 3487065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * Teardown a specific AP interface configured in wificond. 3497065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * 3507065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius * @return Returns true on success. 3517065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius */ 3527065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius public boolean tearDownSoftApInterface(@NonNull String ifaceName) { 3534d2109e282e5ff427c64788dae814baccb542faeRoshan Pius if (getApInterface(ifaceName) == null) { 3544d2109e282e5ff427c64788dae814baccb542faeRoshan Pius Log.e(TAG, "No valid wificond ap interface handler"); 3554d2109e282e5ff427c64788dae814baccb542faeRoshan Pius return false; 3564d2109e282e5ff427c64788dae814baccb542faeRoshan Pius } 3577065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius boolean success; 3587065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius try { 3597065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius success = mWificond.tearDownApInterface(ifaceName); 3607065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } catch (RemoteException e1) { 3617065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to teardown AP interface due to remote exception"); 3627065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 3637065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3647065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius if (!success) { 3657065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius Log.e(TAG, "Failed to teardown AP interface"); 3667065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return false; 3677065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 36891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mApInterfaces.remove(ifaceName); 36991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mApInterfaceListeners.remove(ifaceName); 3707065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius return true; 3717065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius } 3727065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius 3737065d8fb5b3b814d9f15d053b3a30f4543164baeRoshan Pius /** 37470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Teardown all interfaces configured in wificond. 37570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 37670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 37770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean tearDownInterfaces() { 378512ba9008e5b9ab4019647eb036c303a6bb9e0ceNingyuan Wang Log.d(TAG, "tearing down interfaces in wificond"); 37970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Explicitly refresh the wificodn handler because |tearDownInterfaces()| 38070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // could be used to cleanup before we setup any interfaces. 38155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 38270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 38370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 38470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 38570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 38691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius for (Map.Entry<String, IWifiScannerImpl> entry : mWificondScanners.entrySet()) { 38791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius entry.getValue().unsubscribeScanEvents(); 38891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius entry.getValue().unsubscribePnoScanEvents(); 38970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 39070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond.tearDownInterfaces(); 39155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius clearState(); 39270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return true; 39370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 39470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to tear down interfaces due to remote exception"); 39570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 39670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 39770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 39870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 39970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 40091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius /** Helper function to look up the interface handle using name */ 40191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private IClientInterface getClientInterface(@NonNull String ifaceName) { 40291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius return mClientInterfaces.get(ifaceName); 40391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius } 40491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius 40570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 40670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Disable wpa_supplicant via wificond. 40770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 40870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 40970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean disableSupplicant() { 41055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 41170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 41270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 41370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 4147a9936461744922f7785a192493ccce7c4fb52f9Roshan Pius return mWificond.disableSupplicant(); 41570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 41670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to disable supplicant due to remote exception"); 41770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 41870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 41970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 42070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 42170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 42270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Enable wpa_supplicant via wificond. 42370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 42470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 42570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean enableSupplicant() { 42655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius if (!retrieveWificondAndRegisterForDeath()) { 42770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 42870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 42970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 4307a9936461744922f7785a192493ccce7c4fb52f9Roshan Pius return mWificond.enableSupplicant(); 43170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 43270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to enable supplicant due to remote exception"); 43370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 43470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 43570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 436d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 437d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang /** 43891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * Request signal polling to wificond. 43991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 44091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * Returns an SignalPollResult object. 44191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * Returns null on failure. 44291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius */ 44391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius public WifiNative.SignalPollResult signalPoll(@NonNull String ifaceName) { 44491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IClientInterface iface = getClientInterface(ifaceName); 44591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (iface == null) { 446d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 447d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 448d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 449d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 450d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang int[] resultArray; 451d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang try { 45291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius resultArray = iface.signalPoll(); 453d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (resultArray == null || resultArray.length != 3) { 454d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "Invalid signal poll result from wificond"); 455d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 456d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 457d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } catch (RemoteException e) { 4582e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.e(TAG, "Failed to do signal polling due to remote exception"); 459d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 460d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 461d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang WifiNative.SignalPollResult pollResult = new WifiNative.SignalPollResult(); 462d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.currentRssi = resultArray[0]; 463d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.txBitrate = resultArray[1]; 464d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.associationFrequency = resultArray[2]; 465d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return pollResult; 466d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 467d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 468d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang /** 46991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * Fetch TX packet counters on current connection from wificond. 47091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 47191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * Returns an TxPacketCounters object. 47291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * Returns null on failure. 47391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius */ 47491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius public WifiNative.TxPacketCounters getTxPacketCounters(@NonNull String ifaceName) { 47591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IClientInterface iface = getClientInterface(ifaceName); 47691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (iface == null) { 477d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 478d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 479d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 480d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 481d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang int[] resultArray; 482d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang try { 48391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius resultArray = iface.getPacketCounters(); 484d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (resultArray == null || resultArray.length != 2) { 485d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "Invalid signal poll result from wificond"); 486d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 487d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 488d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } catch (RemoteException e) { 4892e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.e(TAG, "Failed to do signal polling due to remote exception"); 490d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 491d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 492d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang WifiNative.TxPacketCounters counters = new WifiNative.TxPacketCounters(); 493d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang counters.txSucceeded = resultArray[0]; 494d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang counters.txFailed = resultArray[1]; 495d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return counters; 496d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 4978631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 49891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius /** Helper function to look up the scanner impl handle using name */ 49991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private IWifiScannerImpl getScannerImpl(@NonNull String ifaceName) { 50091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius return mWificondScanners.get(ifaceName); 50191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius } 50291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius 5038631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang /** 5048631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * Fetch the latest scan result from kernel via wificond. 50591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 5068631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * @return Returns an ArrayList of ScanDetail. 5078631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * Returns an empty ArrayList on failure. 5088631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang */ 50991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius public ArrayList<ScanDetail> getScanResults(@NonNull String ifaceName, int scanType) { 5108631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ArrayList<ScanDetail> results = new ArrayList<>(); 51191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); 51291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (scannerImpl == null) { 5138631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 5148631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang return results; 5158631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 5168631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang try { 51771c4c2a898a827a867564159ce78e41aedd2295bSohani Rao NativeScanResult[] nativeResults; 51871c4c2a898a827a867564159ce78e41aedd2295bSohani Rao if (scanType == SCAN_TYPE_SINGLE_SCAN) { 51991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius nativeResults = scannerImpl.getScanResults(); 52071c4c2a898a827a867564159ce78e41aedd2295bSohani Rao } else { 52191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius nativeResults = scannerImpl.getPnoScanResults(); 52271c4c2a898a827a867564159ce78e41aedd2295bSohani Rao } 5238631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang for (NativeScanResult result : nativeResults) { 524755bbe962c20d37491dd9264ad3497bf27e33602Ningyuan Wang WifiSsid wifiSsid = WifiSsid.createFromByteArray(result.ssid); 5258ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang String bssid; 5268ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang try { 5278ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang bssid = NativeUtil.macAddressFromByteArray(result.bssid); 5288ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } catch (IllegalArgumentException e) { 5298ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang Log.e(TAG, "Illegal argument " + result.bssid, e); 5308ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang continue; 5318ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } 5328ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang if (bssid == null) { 5338ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang Log.e(TAG, "Illegal null bssid"); 5348ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang continue; 5358ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } 5368631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ScanResult.InformationElement[] ies = 5378631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang InformationElementUtil.parseInformationElements(result.infoElement); 5388631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang InformationElementUtil.Capabilities capabilities = 5398631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang new InformationElementUtil.Capabilities(); 5408631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang capabilities.from(ies, result.capability); 5418631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang String flags = capabilities.generateCapabilitiesString(); 5420a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang NetworkDetail networkDetail; 5430a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang try { 5440a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang networkDetail = new NetworkDetail(bssid, ies, null, result.frequency); 5450a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang } catch (IllegalArgumentException e) { 5460a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang Log.e(TAG, "Illegal argument for scan result with bssid: " + bssid, e); 5470a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang continue; 5480a6b9c1199f91790606acc70c771548f079fa8f0Ningyuan Wang } 5498631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 5508631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ScanDetail scanDetail = new ScanDetail(networkDetail, wifiSsid, bssid, flags, 5518631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang result.signalMbm / 100, result.frequency, result.tsf, ies, null); 5523feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius ScanResult scanResult = scanDetail.getScanResult(); 5534eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu // Update carrier network info if this AP's SSID is associated with a carrier Wi-Fi 5544eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu // network and it uses EAP. 5554eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu if (ScanResultUtil.isScanResultForEapNetwork(scanDetail.getScanResult()) 5564eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu && mCarrierNetworkConfig.isCarrierNetwork(wifiSsid.toString())) { 5573feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius scanResult.isCarrierAp = true; 5583feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius scanResult.carrierApEapType = 5594eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu mCarrierNetworkConfig.getNetworkEapType(wifiSsid.toString()); 5603feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius scanResult.carrierName = 5614eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu mCarrierNetworkConfig.getCarrierName(wifiSsid.toString()); 5624eef41ced6143fe7228cf1f06f8a1f45aa8a2b1fPeter Qiu } 5633feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius // Fill up the radio chain info. 5643feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius if (result.radioChainInfos != null) { 5653feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius scanResult.radioChainInfos = 5663feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius new ScanResult.RadioChainInfo[result.radioChainInfos.size()]; 5673feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius int idx = 0; 5683feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius for (RadioChainInfo nativeRadioChainInfo : result.radioChainInfos) { 5693feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius scanResult.radioChainInfos[idx] = new ScanResult.RadioChainInfo(); 5703feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius scanResult.radioChainInfos[idx].id = nativeRadioChainInfo.chainId; 5713feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius scanResult.radioChainInfos[idx].level = nativeRadioChainInfo.level; 5723feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius idx++; 5733feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius } 5743feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius } 5758631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang results.add(scanDetail); 5768631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 5778631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } catch (RemoteException e1) { 5788631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Failed to create ScanDetail ArrayList"); 5798631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 5802e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang if (mVerboseLoggingEnabled) { 5812e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.d(TAG, "get " + results.size() + " scan results from wificond"); 5822e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang } 5832e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang 5848631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang return results; 5858631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 586e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 587e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang /** 5883feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius * Return scan type for the parcelable {@link SingleScanSettings} 5893feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius */ 5903feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius private static int getScanType(int scanType) { 5913feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius switch (scanType) { 5923feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius case WifiNative.SCAN_TYPE_LOW_LATENCY: 5933feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius return IWifiScannerImpl.SCAN_TYPE_LOW_SPAN; 5943feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius case WifiNative.SCAN_TYPE_LOW_POWER: 5953feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius return IWifiScannerImpl.SCAN_TYPE_LOW_POWER; 5963feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius case WifiNative.SCAN_TYPE_HIGH_ACCURACY: 5973feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius return IWifiScannerImpl.SCAN_TYPE_HIGH_ACCURACY; 5983feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius default: 5993feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius throw new IllegalArgumentException("Invalid scan type " + scanType); 6003feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius } 6013feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius } 6023feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius 6033feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius /** 604e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * Start a scan using wificond for the given parameters. 60591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 6063feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius * @param scanType Type of scan to perform. 607e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @param freqs list of frequencies to scan for, if null scan all supported channels. 608e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. 609e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @return Returns true on success. 610e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang */ 61191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius public boolean scan(@NonNull String ifaceName, 6123feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius int scanType, 61391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius Set<Integer> freqs, 61491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius Set<String> hiddenNetworkSSIDs) { 61591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); 61691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (scannerImpl == null) { 617e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 618e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang return false; 619e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 620e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang SingleScanSettings settings = new SingleScanSettings(); 6213feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius try { 6223feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius settings.scanType = getScanType(scanType); 6233feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius } catch (IllegalArgumentException e) { 6243feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius Log.e(TAG, "Invalid scan type ", e); 6253feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius return false; 6263feac6fe9249c1b7bf284c7a9bfa65a86b973154Roshan Pius } 627e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.channelSettings = new ArrayList<>(); 628e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.hiddenNetworks = new ArrayList<>(); 629e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 630e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang if (freqs != null) { 631e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang for (Integer freq : freqs) { 632e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang ChannelSettings channel = new ChannelSettings(); 633e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang channel.frequency = freq; 634e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.channelSettings.add(channel); 635e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 636e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 637e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang if (hiddenNetworkSSIDs != null) { 638e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang for (String ssid : hiddenNetworkSSIDs) { 639e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang HiddenNetwork network = new HiddenNetwork(); 6408ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang try { 6418ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang network.ssid = NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(ssid)); 6428ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } catch (IllegalArgumentException e) { 6438ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang Log.e(TAG, "Illegal argument " + ssid, e); 6448ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang continue; 6458ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } 646e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.hiddenNetworks.add(network); 647e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 648e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 649e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 650e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang try { 65191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius return scannerImpl.scan(settings); 652e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } catch (RemoteException e1) { 653e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang Log.e(TAG, "Failed to request scan due to remote exception"); 654e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 655e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang return false; 656e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 657e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 65804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang /** 65904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * Start PNO scan. 66091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 66104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * @param pnoSettings Pno scan configuration. 66204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * @return true on success. 66304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang */ 66491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius public boolean startPnoScan(@NonNull String ifaceName, WifiNative.PnoSettings pnoSettings) { 66591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); 66691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (scannerImpl == null) { 66704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 66804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return false; 66904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 67004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang PnoSettings settings = new PnoSettings(); 67104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.pnoNetworks = new ArrayList<>(); 67204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.intervalMs = pnoSettings.periodInMs; 67304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.min2gRssi = pnoSettings.min24GHzRssi; 67404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.min5gRssi = pnoSettings.min5GHzRssi; 67504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang if (pnoSettings.networkList != null) { 67604c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang for (WifiNative.PnoNetwork network : pnoSettings.networkList) { 67704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang PnoNetwork condNetwork = new PnoNetwork(); 67804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang condNetwork.isHidden = (network.flags 67904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang & WifiScanner.PnoSettings.PnoNetwork.FLAG_DIRECTED_SCAN) != 0; 6808ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang try { 6818ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang condNetwork.ssid = 6828ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(network.ssid)); 6838ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } catch (IllegalArgumentException e) { 6848ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang Log.e(TAG, "Illegal argument " + network.ssid, e); 6858ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang continue; 6868ce63761f263cc5190e87d6f5f8d0501e531168fNingyuan Wang } 68704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang settings.pnoNetworks.add(condNetwork); 68804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 68904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 69004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 69104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang try { 69291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius boolean success = scannerImpl.startPnoScan(settings); 693a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanStartAttempCount(); 694a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh if (!success) { 695a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh mWifiInjector.getWifiMetrics().incrementPnoScanFailedCount(); 696a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh } 697a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh return success; 69804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } catch (RemoteException e1) { 699a2dae3436431f3fe2ac79ad087fe62f6fcda8ad7Mehdi Alizadeh Log.e(TAG, "Failed to start pno scan due to remote exception"); 70004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 70104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return false; 70204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 70304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 70404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang /** 70504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * Stop PNO scan. 70691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 70704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang * @return true on success. 70804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang */ 70991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius public boolean stopPnoScan(@NonNull String ifaceName) { 71091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); 71191375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (scannerImpl == null) { 71204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 71304c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return false; 71404c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 71504c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang try { 71691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius return scannerImpl.stopPnoScan(); 71704c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } catch (RemoteException e1) { 71804c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang Log.e(TAG, "Failed to stop pno scan due to remote exception"); 71904c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 72004c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang return false; 72104c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang } 72204c453c2e07efc30b99528926f205740226f1c7bNingyuan Wang 723c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang /** 724c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang * Abort ongoing single scan. 72591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 726c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang */ 72791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius public void abortScan(@NonNull String ifaceName) { 72891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName); 72991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (scannerImpl == null) { 730c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 731c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang return; 732c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang } 733c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang try { 73491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius scannerImpl.abortScan(); 735c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang } catch (RemoteException e1) { 736c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang Log.e(TAG, "Failed to request abortScan due to remote exception"); 737c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang } 738c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang } 739c4ad341e844e88a34be7ed4c3c9509fb72608b37Ningyuan Wang 7406baff2cb8dec599af186be521882413787595930Ningyuan Wang /** 7416baff2cb8dec599af186be521882413787595930Ningyuan Wang * Query the list of valid frequencies for the provided band. 7426baff2cb8dec599af186be521882413787595930Ningyuan Wang * The result depends on the on the country code that has been set. 7436baff2cb8dec599af186be521882413787595930Ningyuan Wang * 7446baff2cb8dec599af186be521882413787595930Ningyuan Wang * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. 7456baff2cb8dec599af186be521882413787595930Ningyuan Wang * The following bands are supported: 7466baff2cb8dec599af186be521882413787595930Ningyuan Wang * WifiScanner.WIFI_BAND_24_GHZ 7476baff2cb8dec599af186be521882413787595930Ningyuan Wang * WifiScanner.WIFI_BAND_5_GHZ 7486baff2cb8dec599af186be521882413787595930Ningyuan Wang * WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY 7496baff2cb8dec599af186be521882413787595930Ningyuan Wang * @return frequencies vector of valid frequencies (MHz), or null for error. 7506baff2cb8dec599af186be521882413787595930Ningyuan Wang * @throws IllegalArgumentException if band is not recognized. 7516baff2cb8dec599af186be521882413787595930Ningyuan Wang */ 7526baff2cb8dec599af186be521882413787595930Ningyuan Wang public int [] getChannelsForBand(int band) { 7536baff2cb8dec599af186be521882413787595930Ningyuan Wang if (mWificond == null) { 7546baff2cb8dec599af186be521882413787595930Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 7556baff2cb8dec599af186be521882413787595930Ningyuan Wang return null; 7566baff2cb8dec599af186be521882413787595930Ningyuan Wang } 7576baff2cb8dec599af186be521882413787595930Ningyuan Wang try { 7586baff2cb8dec599af186be521882413787595930Ningyuan Wang switch (band) { 7596baff2cb8dec599af186be521882413787595930Ningyuan Wang case WifiScanner.WIFI_BAND_24_GHZ: 7606baff2cb8dec599af186be521882413787595930Ningyuan Wang return mWificond.getAvailable2gChannels(); 7616baff2cb8dec599af186be521882413787595930Ningyuan Wang case WifiScanner.WIFI_BAND_5_GHZ: 7626baff2cb8dec599af186be521882413787595930Ningyuan Wang return mWificond.getAvailable5gNonDFSChannels(); 7636baff2cb8dec599af186be521882413787595930Ningyuan Wang case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: 7646baff2cb8dec599af186be521882413787595930Ningyuan Wang return mWificond.getAvailableDFSChannels(); 7656baff2cb8dec599af186be521882413787595930Ningyuan Wang default: 7666baff2cb8dec599af186be521882413787595930Ningyuan Wang throw new IllegalArgumentException("unsupported band " + band); 7676baff2cb8dec599af186be521882413787595930Ningyuan Wang } 7686baff2cb8dec599af186be521882413787595930Ningyuan Wang } catch (RemoteException e1) { 7696baff2cb8dec599af186be521882413787595930Ningyuan Wang Log.e(TAG, "Failed to request getChannelsForBand due to remote exception"); 7706baff2cb8dec599af186be521882413787595930Ningyuan Wang } 7716baff2cb8dec599af186be521882413787595930Ningyuan Wang return null; 7726baff2cb8dec599af186be521882413787595930Ningyuan Wang } 773045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 77491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius /** Helper function to look up the interface handle using name */ 77591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius private IApInterface getApInterface(@NonNull String ifaceName) { 77691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius return mApInterfaces.get(ifaceName); 77791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius } 77891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius 779045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius /** 780295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius * Start hostapd 781295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius * TODO(b/71513606): Move this to a global operation. 782045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * 78391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 784045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * @param listener Callback for AP events. 785045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * @return true on success, false otherwise. 786045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius */ 787295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius public boolean startHostapd(@NonNull String ifaceName, 78891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius SoftApListener listener) { 78991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IApInterface iface = getApInterface(ifaceName); 79091375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (iface == null) { 791045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "No valid ap interface handler"); 792045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 793045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 794045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius try { 79591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IApInterfaceEventCallback callback = new ApInterfaceEventCallback(listener); 79691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mApInterfaceListeners.put(ifaceName, callback); 797295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius boolean success = iface.startHostapd(callback); 798045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius if (!success) { 799045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Failed to start hostapd."); 800045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 801045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 802045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } catch (RemoteException e) { 803045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Exception in starting soft AP: " + e); 804045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 805045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 806045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return true; 807045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 808045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 809045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius /** 810295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius * Stop hostapd 811295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius * TODO(b/71513606): Move this to a global operation. 812045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * 81391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius * @param ifaceName Name of the interface. 814045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius * @return true on success, false otherwise. 815045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius */ 816295a0f1632f2c46ffb050ad538eddeb9a2aa7a76Roshan Pius public boolean stopHostapd(@NonNull String ifaceName) { 81791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius IApInterface iface = getApInterface(ifaceName); 81891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius if (iface == null) { 819045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "No valid ap interface handler"); 820045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 821045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 822045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius try { 82391375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius boolean success = iface.stopHostapd(); 824045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius if (!success) { 825045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Failed to stop hostapd."); 826045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 827045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 828045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } catch (RemoteException e) { 829045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius Log.e(TAG, "Exception in stopping soft AP: " + e); 830045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return false; 831045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 83291375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mApInterfaceListeners.remove(ifaceName); 833045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius return true; 834045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius } 835045079df57626fd6a8b94ac19fcdb0540b508c19Roshan Pius 83655dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius /** 837f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim * Set Mac address on the given interface 838f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim * @param interfaceName Name of the interface. 839f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim * @param mac Mac address to change into 840f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim * @return true on success, false otherwise. 841f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim */ 842f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim public boolean setMacAddress(@NonNull String interfaceName, @NonNull MacAddress mac) { 843f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim IClientInterface mClientInterface = getClientInterface(interfaceName); 844f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim if (mClientInterface == null) { 845f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim Log.e(TAG, "No valid wificond client interface handler"); 846f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim return false; 847f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim } 848f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim byte[] macByteArray = mac.toByteArray(); 849f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim 850f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim try { 851f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim mClientInterface.setMacAddress(macByteArray); 852f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim } catch (RemoteException e) { 853f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim Log.e(TAG, "Failed to setMacAddress due to remote exception"); 854f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim return false; 855f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim } 856f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim return true; 857f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim } 858f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim 859f8418067cfc279fc451f3347dab20908a1837bfcJong Wook Kim /** 86055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius * Clear all internal handles. 86155dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius */ 86255dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius private void clearState() { 86355dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius // Refresh handlers 86491375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mClientInterfaces.clear(); 86591375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mWificondScanners.clear(); 86691375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mPnoScanEventHandlers.clear(); 86791375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mScanEventHandlers.clear(); 86891375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mApInterfaces.clear(); 86991375b39b0fdd6b9c692a5d48120673ee472e3ffRoshan Pius mApInterfaceListeners.clear(); 87055dd51a9f9df48a7b92a57f9c969d256c98d33a7Roshan Pius } 87170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang} 872