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