WificondControl.java revision bb1a2db286601be78d36c9fe747e779d40cd7d6c
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 1970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IApInterface; 2070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IClientInterface; 2170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wangimport android.net.wifi.IScanEvent; 228631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.IWifiScannerImpl; 2370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IWificond; 248631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.ScanResult; 258631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.WifiSsid; 2670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.os.Binder; 2770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.os.RemoteException; 2870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.util.Log; 2970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 308631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.hotspot2.NetworkDetail; 318631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.util.InformationElementUtil; 32f4b53ff21ce0aa25131222d0cd15cc4a5e8c0c4fNingyuan Wangimport com.android.server.wifi.util.NativeUtil; 33e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport com.android.server.wifi.wificond.ChannelSettings; 34e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport com.android.server.wifi.wificond.HiddenNetwork; 358631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.wificond.NativeScanResult; 36e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport com.android.server.wifi.wificond.SingleScanSettings; 378631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 388631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport java.util.ArrayList; 39e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wangimport java.util.Set; 408631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 4170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang/** 4270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * This class provides methods for WifiNative to send control commands to wificond. 4370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * NOTE: This class should only be used from WifiNative. 4470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 4570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangpublic class WificondControl { 462e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang private boolean mVerboseLoggingEnabled = false; 4770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 4870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private static final String TAG = "WificondControl"; 4970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private WifiInjector mWifiInjector; 5070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private WifiMonitor mWifiMonitor; 5170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 5270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang // Cached wificond binder handlers. 5370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IWificond mWificond; 5470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IClientInterface mClientInterface; 5570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IApInterface mApInterface; 568631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang private IWifiScannerImpl mWificondScanner; 5770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private IScanEvent mScanEventHandler; 5870a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 5970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private String mClientInterfaceName; 6070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 6170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 6270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang private class ScanEventHandler extends IScanEvent.Stub { 6370a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang @Override 6470a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang public void OnScanResultReady() { 6570a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang Log.d(TAG, "Scan result ready event"); 6670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWifiMonitor.broadcastScanResultEvent(mClientInterfaceName); 6770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 6870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 6970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang @Override 7070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang public void OnScanFailed() { 7170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang Log.d(TAG, "Scan failed event"); 7270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWifiMonitor.broadcastScanFailedEvent(mClientInterfaceName); 7370a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 7470a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 7570a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 7670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang WificondControl(WifiInjector wifiInjector, WifiMonitor wifiMonitor) { 7770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWifiInjector = wifiInjector; 7870a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWifiMonitor = wifiMonitor; 7970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 8070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 812e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang /** Enable or disable verbose logging of WificondControl. 822e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang * @param enable True to enable verbose logging. False to disable verbose logging. 832e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang */ 842e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang public void enableVerboseLogging(boolean enable) { 852e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang mVerboseLoggingEnabled = enable; 862e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang } 872e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang 8870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 8970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Setup driver for client mode via wificond. 9070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return An IClientInterface as wificond client interface binder handler. 9170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Returns null on failure. 9270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 9370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public IClientInterface setupDriverForClientMode() { 94512ba9008e5b9ab4019647eb036c303a6bb9e0ceNingyuan Wang Log.d(TAG, "Setting up driver for client mode"); 9570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond = mWifiInjector.makeWificond(); 9670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mWificond == null) { 9770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get reference to wificond"); 9870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 9970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 10070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 10170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang IClientInterface clientInterface = null; 10270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 10370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang clientInterface = mWificond.createClientInterface(); 10470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e1) { 10570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get IClientInterface due to remote exception"); 10670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 10770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 10870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 10970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (clientInterface == null) { 11070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Could not get IClientInterface instance from wificond"); 11170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 11270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 11370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Binder.allowBlocking(clientInterface.asBinder()); 11470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 11570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Refresh Handlers 11670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mClientInterface = clientInterface; 1178631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang try { 11870a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mClientInterfaceName = clientInterface.getInterfaceName(); 1198631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang mWificondScanner = mClientInterface.getWifiScannerImpl(); 120bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang if (mWificondScanner == null) { 121bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang Log.e(TAG, "Failed to get WificondScannerImpl"); 122bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang return null; 123bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang } 124bb1a2db286601be78d36c9fe747e779d40cd7d6cNingyuan Wang Binder.allowBlocking(mWificondScanner.asBinder()); 12570a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mScanEventHandler = new ScanEventHandler(); 12670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWificondScanner.subscribeScanEvents(mScanEventHandler); 1278631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } catch (RemoteException e) { 1288631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); 1298631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 13070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 13170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return clientInterface; 13270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 13370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 13470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 13570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Setup driver for softAp mode via wificond. 13670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return An IApInterface as wificond Ap interface binder handler. 13770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Returns null on failure. 13870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 13970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public IApInterface setupDriverForSoftApMode() { 140512ba9008e5b9ab4019647eb036c303a6bb9e0ceNingyuan Wang Log.d(TAG, "Setting up driver for soft ap mode"); 14170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond = mWifiInjector.makeWificond(); 14270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mWificond == null) { 14370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get reference to wificond"); 14470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 14570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 14670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 14770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang IApInterface apInterface = null; 14870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 14970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang apInterface = mWificond.createApInterface(); 15070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e1) { 15170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get IApInterface due to remote exception"); 15270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 15370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 15470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 15570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (apInterface == null) { 15670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Could not get IApInterface instance from wificond"); 15770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 15870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 15970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Binder.allowBlocking(apInterface.asBinder()); 16070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 16170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Refresh Handlers 16270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mApInterface = apInterface; 16370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 16470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return apInterface; 16570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 16670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 16770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 16870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Teardown all interfaces configured in wificond. 16970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 17070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 17170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean tearDownInterfaces() { 172512ba9008e5b9ab4019647eb036c303a6bb9e0ceNingyuan Wang Log.d(TAG, "tearing down interfaces in wificond"); 17370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Explicitly refresh the wificodn handler because |tearDownInterfaces()| 17470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // could be used to cleanup before we setup any interfaces. 17570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond = mWifiInjector.makeWificond(); 17670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mWificond == null) { 17770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get reference to wificond"); 17870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 17970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 18070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 18170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 18270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang if (mWificondScanner != null) { 18370a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWificondScanner.unsubscribeScanEvents(); 18470a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang } 18570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond.tearDownInterfaces(); 18670a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 18770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang // Refresh handlers 18870a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mClientInterface = null; 18970a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mWificondScanner = null; 19070a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mScanEventHandler = null; 19170a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang mApInterface = null; 19270a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 19370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return true; 19470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 19570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to tear down interfaces due to remote exception"); 19670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 19770a9b25ee5d051660b8aeb15ffa97d36a181741dNingyuan Wang 19870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 19970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 20070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 20170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 20270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Disable wpa_supplicant via wificond. 20370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 20470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 20570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean disableSupplicant() { 20670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mClientInterface == null) { 20770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 20870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 20970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 21070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 21170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return mClientInterface.disableSupplicant(); 21270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 21370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to disable supplicant due to remote exception"); 21470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 21570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 21670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 21770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 21870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 21970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Enable wpa_supplicant via wificond. 22070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 22170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 22270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean enableSupplicant() { 22370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mClientInterface == null) { 22470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 22570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 22670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 22770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 22870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 22970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return mClientInterface.enableSupplicant(); 23070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 23170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to enable supplicant due to remote exception"); 23270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 23370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 23470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 235d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 236d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang /** 237d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Request signal polling to wificond. 238d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns an SignalPollResult object. 239d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns null on failure. 240d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang */ 241d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang public WifiNative.SignalPollResult signalPoll() { 242d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (mClientInterface == null) { 243d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 244d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 245d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 246d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 247d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang int[] resultArray; 248d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang try { 249d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang resultArray = mClientInterface.signalPoll(); 250d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (resultArray == null || resultArray.length != 3) { 251d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "Invalid signal poll result from wificond"); 252d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 253d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 254d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } catch (RemoteException e) { 2552e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.e(TAG, "Failed to do signal polling due to remote exception"); 256d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 257d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 258d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang WifiNative.SignalPollResult pollResult = new WifiNative.SignalPollResult(); 259d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.currentRssi = resultArray[0]; 260d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.txBitrate = resultArray[1]; 261d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.associationFrequency = resultArray[2]; 262d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return pollResult; 263d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 264d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 265d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang /** 266d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Fetch TX packet counters on current connection from wificond. 267d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns an TxPacketCounters object. 268d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns null on failure. 269d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang */ 270d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang public WifiNative.TxPacketCounters getTxPacketCounters() { 271d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (mClientInterface == null) { 272d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 273d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 274d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 275d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 276d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang int[] resultArray; 277d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang try { 278d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang resultArray = mClientInterface.getPacketCounters(); 279d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (resultArray == null || resultArray.length != 2) { 280d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "Invalid signal poll result from wificond"); 281d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 282d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 283d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } catch (RemoteException e) { 2842e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.e(TAG, "Failed to do signal polling due to remote exception"); 285d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 286d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 287d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang WifiNative.TxPacketCounters counters = new WifiNative.TxPacketCounters(); 288d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang counters.txSucceeded = resultArray[0]; 289d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang counters.txFailed = resultArray[1]; 290d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return counters; 291d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 2928631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 2938631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang /** 2948631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * Fetch the latest scan result from kernel via wificond. 2958631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * @return Returns an ArrayList of ScanDetail. 2968631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * Returns an empty ArrayList on failure. 2978631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang */ 2988631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang public ArrayList<ScanDetail> getScanResults() { 2998631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ArrayList<ScanDetail> results = new ArrayList<>(); 3008631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang if (mWificondScanner == null) { 3018631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 3028631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang return results; 3038631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 3048631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang try { 3058631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang NativeScanResult[] nativeResults = mWificondScanner.getScanResults(); 3068631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang for (NativeScanResult result : nativeResults) { 307755bbe962c20d37491dd9264ad3497bf27e33602Ningyuan Wang WifiSsid wifiSsid = WifiSsid.createFromByteArray(result.ssid); 308f4b53ff21ce0aa25131222d0cd15cc4a5e8c0c4fNingyuan Wang String bssid = NativeUtil.macAddressFromByteArray(result.bssid); 3098631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ScanResult.InformationElement[] ies = 3108631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang InformationElementUtil.parseInformationElements(result.infoElement); 3118631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang InformationElementUtil.Capabilities capabilities = 3128631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang new InformationElementUtil.Capabilities(); 3138631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang capabilities.from(ies, result.capability); 3148631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang String flags = capabilities.generateCapabilitiesString(); 3158631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang NetworkDetail networkDetail = 3168631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang new NetworkDetail(bssid, ies, null, result.frequency); 3178631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 3188631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang if (!wifiSsid.toString().equals(networkDetail.getTrimmedSSID())) { 3198631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Inconsistent SSID on BSSID: " + bssid); 3208631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang continue; 3218631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 3228631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ScanDetail scanDetail = new ScanDetail(networkDetail, wifiSsid, bssid, flags, 3238631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang result.signalMbm / 100, result.frequency, result.tsf, ies, null); 3248631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang results.add(scanDetail); 3258631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 3268631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } catch (RemoteException e1) { 3278631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Failed to create ScanDetail ArrayList"); 3288631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 3292e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang if (mVerboseLoggingEnabled) { 3302e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.d(TAG, "get " + results.size() + " scan results from wificond"); 3312e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang } 3322e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang 3338631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang return results; 3348631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 335e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 336e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang /** 337e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * Start a scan using wificond for the given parameters. 338e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @param freqs list of frequencies to scan for, if null scan all supported channels. 339e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. 340e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang * @return Returns true on success. 341e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang */ 342e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang public boolean scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) { 343e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang if (mWificondScanner == null) { 344e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 345e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang return false; 346e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 347e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang SingleScanSettings settings = new SingleScanSettings(); 348e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.channelSettings = new ArrayList<>(); 349e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.hiddenNetworks = new ArrayList<>(); 350e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 351e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang if (freqs != null) { 352e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang for (Integer freq : freqs) { 353e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang ChannelSettings channel = new ChannelSettings(); 354e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang channel.frequency = freq; 355e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.channelSettings.add(channel); 356e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 357e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 358e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang if (hiddenNetworkSSIDs != null) { 359e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang for (String ssid : hiddenNetworkSSIDs) { 360e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang HiddenNetwork network = new HiddenNetwork(); 361e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang network.ssid = NativeUtil.byteArrayFromArrayList(NativeUtil.decodeSsid(ssid)); 362e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang settings.hiddenNetworks.add(network); 363e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 364e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 365e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 366e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang try { 367e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang return mWificondScanner.scan(settings); 368e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } catch (RemoteException e1) { 369e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang Log.e(TAG, "Failed to request scan due to remote exception"); 370e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 371e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang return false; 372e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang } 373e6d7f23569585f8f0fb02adbef992d3f1430db44Ningyuan Wang 37470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang} 375