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