WificondControl.java revision 2e5959fc746d48ab49f731cdbbb2b9fea6704e2a
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; 218631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.IWifiScannerImpl; 2270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.net.wifi.IWificond; 238631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.ScanResult; 248631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport android.net.wifi.WifiSsid; 2570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.os.Binder; 2670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.os.RemoteException; 2770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangimport android.util.Log; 2870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 298631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.hotspot2.NetworkDetail; 308631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.util.InformationElementUtil; 31f4b53ff21ce0aa25131222d0cd15cc4a5e8c0c4fNingyuan Wangimport com.android.server.wifi.util.NativeUtil; 328631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport com.android.server.wifi.wificond.NativeScanResult; 338631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 348631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wangimport java.util.ArrayList; 358631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 3670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang/** 3770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * This class provides methods for WifiNative to send control commands to wificond. 3870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * NOTE: This class should only be used from WifiNative. 3970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 4070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wangpublic class WificondControl { 412e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang private boolean mVerboseLoggingEnabled = false; 4270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 4370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private static final String TAG = "WificondControl"; 448631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang private static final int MAC_ADDR_LEN = 6; 4570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IWificond mWificond; 4670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IClientInterface mClientInterface; 4770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private IApInterface mApInterface; 488631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang private IWifiScannerImpl mWificondScanner; 4970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang private WifiInjector mWifiInjector; 5070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 5170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang WificondControl(WifiInjector wifiInjector) { 5270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWifiInjector = wifiInjector; 5370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 5470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 552e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang /** Enable or disable verbose logging of WificondControl. 562e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang * @param enable True to enable verbose logging. False to disable verbose logging. 572e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang */ 582e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang public void enableVerboseLogging(boolean enable) { 592e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang mVerboseLoggingEnabled = enable; 602e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang } 612e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang 6270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 6370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Setup driver for client mode via wificond. 6470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return An IClientInterface as wificond client interface binder handler. 6570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Returns null on failure. 6670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 6770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public IClientInterface setupDriverForClientMode() { 6870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond = mWifiInjector.makeWificond(); 6970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mWificond == null) { 7070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get reference to wificond"); 7170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 7270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 7370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 7470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang IClientInterface clientInterface = null; 7570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 7670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang clientInterface = mWificond.createClientInterface(); 7770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e1) { 7870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get IClientInterface due to remote exception"); 7970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 8070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 8170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 8270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (clientInterface == null) { 8370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Could not get IClientInterface instance from wificond"); 8470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 8570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 8670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Binder.allowBlocking(clientInterface.asBinder()); 8770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 8870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Refresh Handlers 8970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mClientInterface = clientInterface; 908631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang try { 918631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang mWificondScanner = mClientInterface.getWifiScannerImpl(); 928631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } catch (RemoteException e) { 938631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Failed to refresh wificond scanner due to remote exception"); 948631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 9570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 9670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return clientInterface; 9770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 9870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 9970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 10070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Setup driver for softAp mode via wificond. 10170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return An IApInterface as wificond Ap interface binder handler. 10270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Returns null on failure. 10370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 10470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public IApInterface setupDriverForSoftApMode() { 10570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond = mWifiInjector.makeWificond(); 10670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mWificond == null) { 10770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get reference to wificond"); 10870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 10970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 11070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 11170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang IApInterface apInterface = null; 11270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 11370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang apInterface = mWificond.createApInterface(); 11470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e1) { 11570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get IApInterface due to remote exception"); 11670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 11770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 11870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 11970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (apInterface == null) { 12070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Could not get IApInterface instance from wificond"); 12170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return null; 12270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 12370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Binder.allowBlocking(apInterface.asBinder()); 12470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 12570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Refresh Handlers 12670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mApInterface = apInterface; 1278631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang mWificondScanner = null; 12870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 12970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return apInterface; 13070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 13170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 13270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 13370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Teardown all interfaces configured in wificond. 13470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 13570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 13670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean tearDownInterfaces() { 13770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // Explicitly refresh the wificodn handler because |tearDownInterfaces()| 13870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang // could be used to cleanup before we setup any interfaces. 13970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond = mWifiInjector.makeWificond(); 14070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mWificond == null) { 14170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to get reference to wificond"); 14270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 14370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 14470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 14570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 14670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang mWificond.tearDownInterfaces(); 14770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return true; 14870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 14970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to tear down interfaces due to remote exception"); 15070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 15170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 15270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 15370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 15470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 15570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Disable wpa_supplicant via wificond. 15670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 15770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 15870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean disableSupplicant() { 15970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mClientInterface == null) { 16070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 16170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 16270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 16370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 16470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return mClientInterface.disableSupplicant(); 16570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 16670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to disable supplicant due to remote exception"); 16770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 16870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 16970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 17070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 17170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang /** 17270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * Enable wpa_supplicant via wificond. 17370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang * @return Returns true on success. 17470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang */ 17570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang public boolean enableSupplicant() { 17670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang if (mClientInterface == null) { 17770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 17870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 17970603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 18070603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang 18170603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang try { 18270603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return mClientInterface.enableSupplicant(); 18370603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } catch (RemoteException e) { 18470603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang Log.e(TAG, "Failed to enable supplicant due to remote exception"); 18570603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 18670603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang return false; 18770603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang } 188d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 189d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang /** 190d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Request signal polling to wificond. 191d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns an SignalPollResult object. 192d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns null on failure. 193d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang */ 194d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang public WifiNative.SignalPollResult signalPoll() { 195d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (mClientInterface == null) { 196d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 197d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 198d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 199d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 200d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang int[] resultArray; 201d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang try { 202d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang resultArray = mClientInterface.signalPoll(); 203d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (resultArray == null || resultArray.length != 3) { 204d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "Invalid signal poll result from wificond"); 205d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 206d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 207d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } catch (RemoteException e) { 2082e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.e(TAG, "Failed to do signal polling due to remote exception"); 209d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 210d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 211d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang WifiNative.SignalPollResult pollResult = new WifiNative.SignalPollResult(); 212d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.currentRssi = resultArray[0]; 213d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.txBitrate = resultArray[1]; 214d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang pollResult.associationFrequency = resultArray[2]; 215d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return pollResult; 216d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 217d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 218d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang /** 219d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Fetch TX packet counters on current connection from wificond. 220d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns an TxPacketCounters object. 221d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang * Returns null on failure. 222d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang */ 223d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang public WifiNative.TxPacketCounters getTxPacketCounters() { 224d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (mClientInterface == null) { 225d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "No valid wificond client interface handler"); 226d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 227d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 228d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang 229d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang int[] resultArray; 230d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang try { 231d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang resultArray = mClientInterface.getPacketCounters(); 232d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang if (resultArray == null || resultArray.length != 2) { 233d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang Log.e(TAG, "Invalid signal poll result from wificond"); 234d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 235d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 236d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } catch (RemoteException e) { 2372e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.e(TAG, "Failed to do signal polling due to remote exception"); 238d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return null; 239d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 240d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang WifiNative.TxPacketCounters counters = new WifiNative.TxPacketCounters(); 241d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang counters.txSucceeded = resultArray[0]; 242d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang counters.txFailed = resultArray[1]; 243d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang return counters; 244d45b46b01f8562219468291bdc19363f0540ced0Ningyuan Wang } 2458631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 2468631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang /** 2478631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * Fetch the latest scan result from kernel via wificond. 2488631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * @return Returns an ArrayList of ScanDetail. 2498631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang * Returns an empty ArrayList on failure. 2508631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang */ 2518631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang public ArrayList<ScanDetail> getScanResults() { 2528631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ArrayList<ScanDetail> results = new ArrayList<>(); 2538631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang if (mWificondScanner == null) { 2548631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "No valid wificond scanner interface handler"); 2558631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang return results; 2568631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 2578631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang try { 2588631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang NativeScanResult[] nativeResults = mWificondScanner.getScanResults(); 2598631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang for (NativeScanResult result : nativeResults) { 260755bbe962c20d37491dd9264ad3497bf27e33602Ningyuan Wang WifiSsid wifiSsid = WifiSsid.createFromByteArray(result.ssid); 261f4b53ff21ce0aa25131222d0cd15cc4a5e8c0c4fNingyuan Wang String bssid = NativeUtil.macAddressFromByteArray(result.bssid); 2628631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ScanResult.InformationElement[] ies = 2638631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang InformationElementUtil.parseInformationElements(result.infoElement); 2648631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang InformationElementUtil.Capabilities capabilities = 2658631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang new InformationElementUtil.Capabilities(); 2668631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang capabilities.from(ies, result.capability); 2678631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang String flags = capabilities.generateCapabilitiesString(); 2688631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang NetworkDetail networkDetail = 2698631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang new NetworkDetail(bssid, ies, null, result.frequency); 2708631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang 2718631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang if (!wifiSsid.toString().equals(networkDetail.getTrimmedSSID())) { 2728631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Inconsistent SSID on BSSID: " + bssid); 2738631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang continue; 2748631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 2758631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang ScanDetail scanDetail = new ScanDetail(networkDetail, wifiSsid, bssid, flags, 2768631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang result.signalMbm / 100, result.frequency, result.tsf, ies, null); 2778631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang results.add(scanDetail); 2788631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 2798631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } catch (RemoteException e1) { 2808631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang Log.e(TAG, "Failed to create ScanDetail ArrayList"); 2818631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 2822e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang if (mVerboseLoggingEnabled) { 2832e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang Log.d(TAG, "get " + results.size() + " scan results from wificond"); 2842e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang } 2852e5959fc746d48ab49f731cdbbb2b9fea6704e2aNingyuan Wang 2868631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang return results; 2878631700c2c81784d8fb02d38a304cf6609f67c14Ningyuan Wang } 28870603901b67c48202ecbb1818e59d487bbcceedaNingyuan Wang} 289