• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi;
18 
19 import android.annotation.Nullable;
20 import android.net.apf.ApfCapabilities;
21 import android.net.wifi.IApInterface;
22 import android.net.wifi.IClientInterface;
23 import android.net.wifi.RttManager;
24 import android.net.wifi.RttManager.ResponderConfig;
25 import android.net.wifi.ScanResult;
26 import android.net.wifi.WifiConfiguration;
27 import android.net.wifi.WifiLinkLayerStats;
28 import android.net.wifi.WifiScanner;
29 import android.net.wifi.WifiWakeReasonAndCounts;
30 import android.os.SystemClock;
31 import android.util.Log;
32 import android.util.SparseArray;
33 
34 import com.android.internal.annotations.Immutable;
35 import com.android.internal.util.HexDump;
36 import com.android.server.connectivity.KeepalivePacketData;
37 import com.android.server.wifi.util.FrameParser;
38 
39 import java.io.PrintWriter;
40 import java.io.StringWriter;
41 import java.nio.ByteBuffer;
42 import java.nio.CharBuffer;
43 import java.nio.charset.CharacterCodingException;
44 import java.nio.charset.CharsetDecoder;
45 import java.nio.charset.StandardCharsets;
46 import java.text.SimpleDateFormat;
47 import java.util.ArrayList;
48 import java.util.Date;
49 import java.util.Map;
50 import java.util.Objects;
51 import java.util.Set;
52 import java.util.TimeZone;
53 
54 
55 /**
56  * Native calls for bring up/shut down of the supplicant daemon and for
57  * sending requests to the supplicant daemon
58  *
59  * {@hide}
60  */
61 public class WifiNative {
62     private final String mTAG;
63     private final String mInterfaceName;
64     private final SupplicantStaIfaceHal mSupplicantStaIfaceHal;
65     private final WifiVendorHal mWifiVendorHal;
66     private final WificondControl mWificondControl;
67 
WifiNative(String interfaceName, WifiVendorHal vendorHal, SupplicantStaIfaceHal staIfaceHal, WificondControl condControl)68     public WifiNative(String interfaceName, WifiVendorHal vendorHal,
69                       SupplicantStaIfaceHal staIfaceHal, WificondControl condControl) {
70         mTAG = "WifiNative-" + interfaceName;
71         mInterfaceName = interfaceName;
72         mWifiVendorHal = vendorHal;
73         mSupplicantStaIfaceHal = staIfaceHal;
74         mWificondControl = condControl;
75     }
76 
getInterfaceName()77     public String getInterfaceName() {
78         return mInterfaceName;
79     }
80 
81     /**
82      * Enable verbose logging for all sub modules.
83      */
enableVerboseLogging(int verbose)84     public void enableVerboseLogging(int verbose) {
85         mWificondControl.enableVerboseLogging(verbose > 0 ? true : false);
86         mSupplicantStaIfaceHal.enableVerboseLogging(verbose > 0);
87         mWifiVendorHal.enableVerboseLogging(verbose > 0);
88     }
89 
90    /********************************************************
91     * Native Initialization/Deinitialization
92     ********************************************************/
93 
94    /**
95     * Setup wifi native for Client mode operations.
96     *
97     * 1. Starts the Wifi HAL and configures it in client/STA mode.
98     * 2. Setup Wificond to operate in client mode and retrieve the handle to use for client
99     * operations.
100     *
101     * @return An IClientInterface as wificond client interface binder handler.
102     * Returns null on failure.
103     */
setupForClientMode()104     public IClientInterface setupForClientMode() {
105         if (!startHalIfNecessary(true)) {
106             Log.e(mTAG, "Failed to start HAL for client mode");
107             return null;
108         }
109         return mWificondControl.setupDriverForClientMode();
110     }
111 
112     /**
113      * Setup wifi native for AP mode operations.
114      *
115      * 1. Starts the Wifi HAL and configures it in AP mode.
116      * 2. Setup Wificond to operate in AP mode and retrieve the handle to use for ap operations.
117      *
118      * @return An IApInterface as wificond Ap interface binder handler.
119      * Returns null on failure.
120      */
setupForSoftApMode()121     public IApInterface setupForSoftApMode() {
122         if (!startHalIfNecessary(false)) {
123             Log.e(mTAG, "Failed to start HAL for AP mode");
124             return null;
125         }
126         return mWificondControl.setupDriverForSoftApMode();
127     }
128 
129     /**
130      * Teardown all mode configurations in wifi native.
131      *
132      * 1. Tears down all the interfaces from Wificond.
133      * 2. Stops the Wifi HAL.
134      *
135      * @return Returns true on success.
136      */
tearDown()137     public boolean tearDown() {
138         if (!mWificondControl.tearDownInterfaces()) {
139             // TODO(b/34859006): Handle failures.
140             Log.e(mTAG, "Failed to teardown interfaces from Wificond");
141             return false;
142         }
143         stopHalIfNecessary();
144         return true;
145     }
146 
147     /********************************************************
148      * Wificond operations
149      ********************************************************/
150     /**
151      * Result of a signal poll.
152      */
153     public static class SignalPollResult {
154         // RSSI value in dBM.
155         public int currentRssi;
156         //Transmission bit rate in Mbps.
157         public int txBitrate;
158         // Association frequency in MHz.
159         public int associationFrequency;
160     }
161 
162     /**
163      * WiFi interface transimission counters.
164      */
165     public static class TxPacketCounters {
166         // Number of successfully transmitted packets.
167         public int txSucceeded;
168         // Number of tramsmission failures.
169         public int txFailed;
170     }
171 
172     /**
173     * Disable wpa_supplicant via wificond.
174     * @return Returns true on success.
175     */
disableSupplicant()176     public boolean disableSupplicant() {
177         return mWificondControl.disableSupplicant();
178     }
179 
180     /**
181     * Enable wpa_supplicant via wificond.
182     * @return Returns true on success.
183     */
enableSupplicant()184     public boolean enableSupplicant() {
185         return mWificondControl.enableSupplicant();
186     }
187 
188     /**
189     * Request signal polling to wificond.
190     * Returns an SignalPollResult object.
191     * Returns null on failure.
192     */
signalPoll()193     public SignalPollResult signalPoll() {
194         return mWificondControl.signalPoll();
195     }
196 
197     /**
198      * Fetch TX packet counters on current connection from wificond.
199     * Returns an TxPacketCounters object.
200     * Returns null on failure.
201     */
getTxPacketCounters()202     public TxPacketCounters getTxPacketCounters() {
203         return mWificondControl.getTxPacketCounters();
204     }
205 
206     /**
207      * Start a scan using wificond for the given parameters.
208      * @param freqs list of frequencies to scan for, if null scan all supported channels.
209      * @param hiddenNetworkSSIDs List of hidden networks to be scanned for.
210      * @return Returns true on success.
211      */
scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs)212     public boolean scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) {
213         return mWificondControl.scan(freqs, hiddenNetworkSSIDs);
214     }
215 
216     /**
217      * Fetch the latest scan result from kernel via wificond.
218      * @return Returns an ArrayList of ScanDetail.
219      * Returns an empty ArrayList on failure.
220      */
getScanResults()221     public ArrayList<ScanDetail> getScanResults() {
222         return mWificondControl.getScanResults();
223     }
224 
225     /**
226      * Start PNO scan.
227      * @param pnoSettings Pno scan configuration.
228      * @return true on success.
229      */
startPnoScan(PnoSettings pnoSettings)230     public boolean startPnoScan(PnoSettings pnoSettings) {
231         return mWificondControl.startPnoScan(pnoSettings);
232     }
233 
234     /**
235      * Stop PNO scan.
236      * @return true on success.
237      */
stopPnoScan()238     public boolean stopPnoScan() {
239         return mWificondControl.stopPnoScan();
240     }
241 
242     /********************************************************
243      * Supplicant operations
244      ********************************************************/
245 
246     /**
247      * This method is called repeatedly until the connection to wpa_supplicant is established.
248      *
249      * @return true if connection is established, false otherwise.
250      * TODO: Add unit tests for these once we remove the legacy code.
251      */
connectToSupplicant()252     public boolean connectToSupplicant() {
253         // Start initialization if not already started.
254         if (!mSupplicantStaIfaceHal.isInitializationStarted()
255                 && !mSupplicantStaIfaceHal.initialize()) {
256             return false;
257         }
258         // Check if the initialization is complete.
259         return mSupplicantStaIfaceHal.isInitializationComplete();
260     }
261 
262     /**
263      * Close supplicant connection.
264      */
closeSupplicantConnection()265     public void closeSupplicantConnection() {
266         // Nothing to do for HIDL.
267     }
268 
269     /**
270      * Set supplicant log level
271      *
272      * @param turnOnVerbose Whether to turn on verbose logging or not.
273      */
setSupplicantLogLevel(boolean turnOnVerbose)274     public void setSupplicantLogLevel(boolean turnOnVerbose) {
275         mSupplicantStaIfaceHal.setLogLevel(turnOnVerbose);
276     }
277 
278     /**
279      * Trigger a reconnection if the iface is disconnected.
280      *
281      * @return true if request is sent successfully, false otherwise.
282      */
reconnect()283     public boolean reconnect() {
284         return mSupplicantStaIfaceHal.reconnect();
285     }
286 
287     /**
288      * Trigger a reassociation even if the iface is currently connected.
289      *
290      * @return true if request is sent successfully, false otherwise.
291      */
reassociate()292     public boolean reassociate() {
293         return mSupplicantStaIfaceHal.reassociate();
294     }
295 
296     /**
297      * Trigger a disconnection from the currently connected network.
298      *
299      * @return true if request is sent successfully, false otherwise.
300      */
disconnect()301     public boolean disconnect() {
302         return mSupplicantStaIfaceHal.disconnect();
303     }
304 
305     /**
306      * Makes a callback to HIDL to getMacAddress from supplicant
307      *
308      * @return string containing the MAC address, or null on a failed call
309      */
getMacAddress()310     public String getMacAddress() {
311         return mSupplicantStaIfaceHal.getMacAddress();
312     }
313 
314     public static final int RX_FILTER_TYPE_V4_MULTICAST = 0;
315     public static final int RX_FILTER_TYPE_V6_MULTICAST = 1;
316     /**
317      * Start filtering out Multicast V4 packets
318      * @return {@code true} if the operation succeeded, {@code false} otherwise
319      *
320      * Multicast filtering rules work as follows:
321      *
322      * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
323      * a power optimized mode (typically when screen goes off).
324      *
325      * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
326      * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
327      *
328      * DRIVER RXFILTER-ADD Num
329      *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
330      *
331      * and DRIVER RXFILTER-START
332      * In order to stop the usage of these rules, we do
333      *
334      * DRIVER RXFILTER-STOP
335      * DRIVER RXFILTER-REMOVE Num
336      *   where Num is as described for RXFILTER-ADD
337      *
338      * The  SETSUSPENDOPT driver command overrides the filtering rules
339      */
startFilteringMulticastV4Packets()340     public boolean startFilteringMulticastV4Packets() {
341         return mSupplicantStaIfaceHal.stopRxFilter()
342                 && mSupplicantStaIfaceHal.removeRxFilter(
343                 RX_FILTER_TYPE_V4_MULTICAST)
344                 && mSupplicantStaIfaceHal.startRxFilter();
345     }
346 
347     /**
348      * Stop filtering out Multicast V4 packets.
349      * @return {@code true} if the operation succeeded, {@code false} otherwise
350      */
stopFilteringMulticastV4Packets()351     public boolean stopFilteringMulticastV4Packets() {
352         return mSupplicantStaIfaceHal.stopRxFilter()
353                 && mSupplicantStaIfaceHal.addRxFilter(
354                 RX_FILTER_TYPE_V4_MULTICAST)
355                 && mSupplicantStaIfaceHal.startRxFilter();
356     }
357 
358     /**
359      * Start filtering out Multicast V6 packets
360      * @return {@code true} if the operation succeeded, {@code false} otherwise
361      */
startFilteringMulticastV6Packets()362     public boolean startFilteringMulticastV6Packets() {
363         return mSupplicantStaIfaceHal.stopRxFilter()
364                 && mSupplicantStaIfaceHal.removeRxFilter(
365                 RX_FILTER_TYPE_V6_MULTICAST)
366                 && mSupplicantStaIfaceHal.startRxFilter();
367     }
368 
369     /**
370      * Stop filtering out Multicast V6 packets.
371      * @return {@code true} if the operation succeeded, {@code false} otherwise
372      */
stopFilteringMulticastV6Packets()373     public boolean stopFilteringMulticastV6Packets() {
374         return mSupplicantStaIfaceHal.stopRxFilter()
375                 && mSupplicantStaIfaceHal.addRxFilter(
376                 RX_FILTER_TYPE_V6_MULTICAST)
377                 && mSupplicantStaIfaceHal.startRxFilter();
378     }
379 
380     public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED  = 0;
381     public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1;
382     public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE    = 2;
383     /**
384       * Sets the bluetooth coexistence mode.
385       *
386       * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
387       *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
388       *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
389       * @return Whether the mode was successfully set.
390       */
setBluetoothCoexistenceMode(int mode)391     public boolean setBluetoothCoexistenceMode(int mode) {
392         return mSupplicantStaIfaceHal.setBtCoexistenceMode(mode);
393     }
394 
395     /**
396      * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
397      * some of the low-level scan parameters used by the driver are changed to
398      * reduce interference with A2DP streaming.
399      *
400      * @param setCoexScanMode whether to enable or disable this mode
401      * @return {@code true} if the command succeeded, {@code false} otherwise.
402      */
setBluetoothCoexistenceScanMode(boolean setCoexScanMode)403     public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
404         return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(setCoexScanMode);
405     }
406 
407     /**
408      * Enable or disable suspend mode optimizations.
409      *
410      * @param enabled true to enable, false otherwise.
411      * @return true if request is sent successfully, false otherwise.
412      */
setSuspendOptimizations(boolean enabled)413     public boolean setSuspendOptimizations(boolean enabled) {
414         return mSupplicantStaIfaceHal.setSuspendModeEnabled(enabled);
415     }
416 
417     /**
418      * Set country code.
419      *
420      * @param countryCode 2 byte ASCII string. For ex: US, CA.
421      * @return true if request is sent successfully, false otherwise.
422      */
setCountryCode(String countryCode)423     public boolean setCountryCode(String countryCode) {
424         return mSupplicantStaIfaceHal.setCountryCode(countryCode);
425     }
426 
427     /**
428      * Initiate TDLS discover and setup or teardown with the specified peer.
429      *
430      * @param macAddr MAC Address of the peer.
431      * @param enable true to start discovery and setup, false to teardown.
432      */
startTdls(String macAddr, boolean enable)433     public void startTdls(String macAddr, boolean enable) {
434         if (enable) {
435             mSupplicantStaIfaceHal.initiateTdlsDiscover(macAddr);
436             mSupplicantStaIfaceHal.initiateTdlsSetup(macAddr);
437         } else {
438             mSupplicantStaIfaceHal.initiateTdlsTeardown(macAddr);
439         }
440     }
441 
442     /**
443      * Start WPS pin display operation with the specified peer.
444      *
445      * @param bssid BSSID of the peer.
446      * @return true if request is sent successfully, false otherwise.
447      */
startWpsPbc(String bssid)448     public boolean startWpsPbc(String bssid) {
449         return mSupplicantStaIfaceHal.startWpsPbc(bssid);
450     }
451 
452     /**
453      * Start WPS pin keypad operation with the specified pin.
454      *
455      * @param pin Pin to be used.
456      * @return true if request is sent successfully, false otherwise.
457      */
startWpsPinKeypad(String pin)458     public boolean startWpsPinKeypad(String pin) {
459         return mSupplicantStaIfaceHal.startWpsPinKeypad(pin);
460     }
461 
462     /**
463      * Start WPS pin display operation with the specified peer.
464      *
465      * @param bssid BSSID of the peer.
466      * @return new pin generated on success, null otherwise.
467      */
startWpsPinDisplay(String bssid)468     public String startWpsPinDisplay(String bssid) {
469         return mSupplicantStaIfaceHal.startWpsPinDisplay(bssid);
470     }
471 
472     /**
473      * Sets whether to use external sim for SIM/USIM processing.
474      *
475      * @param external true to enable, false otherwise.
476      * @return true if request is sent successfully, false otherwise.
477      */
setExternalSim(boolean external)478     public boolean setExternalSim(boolean external) {
479         return mSupplicantStaIfaceHal.setExternalSim(external);
480     }
481 
482     /**
483      * Sim auth response types.
484      */
485     public static final String SIM_AUTH_RESP_TYPE_GSM_AUTH = "GSM-AUTH";
486     public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTH = "UMTS-AUTH";
487     public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTS = "UMTS-AUTS";
488 
489     /**
490      * Send the sim auth response for the currently configured network.
491      *
492      * @param type |GSM-AUTH|, |UMTS-AUTH| or |UMTS-AUTS|.
493      * @param response Response params.
494      * @return true if succeeds, false otherwise.
495      */
simAuthResponse(int id, String type, String response)496     public boolean simAuthResponse(int id, String type, String response) {
497         if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) {
498             return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(response);
499         } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTH.equals(type)) {
500             return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(response);
501         } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTS.equals(type)) {
502             return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAutsResponse(response);
503         } else {
504             return false;
505         }
506     }
507 
508     /**
509      * Send the eap sim gsm auth failure for the currently configured network.
510      *
511      * @return true if succeeds, false otherwise.
512      */
simAuthFailedResponse(int id)513     public boolean simAuthFailedResponse(int id) {
514         return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure();
515     }
516 
517     /**
518      * Send the eap sim umts auth failure for the currently configured network.
519      *
520      * @return true if succeeds, false otherwise.
521      */
umtsAuthFailedResponse(int id)522     public boolean umtsAuthFailedResponse(int id) {
523         return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure();
524     }
525 
526     /**
527      * Send the eap identity response for the currently configured network.
528      *
529      * @param response String to send.
530      * @return true if succeeds, false otherwise.
531      */
simIdentityResponse(int id, String response)532     public boolean simIdentityResponse(int id, String response) {
533         return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(response);
534     }
535 
536     /**
537      * This get anonymous identity from supplicant and returns it as a string.
538      *
539      * @return anonymous identity string if succeeds, null otherwise.
540      */
getEapAnonymousIdentity()541     public String getEapAnonymousIdentity() {
542         return mSupplicantStaIfaceHal.getCurrentNetworkEapAnonymousIdentity();
543     }
544 
545     /**
546      * Start WPS pin registrar operation with the specified peer and pin.
547      *
548      * @param bssid BSSID of the peer.
549      * @param pin Pin to be used.
550      * @return true if request is sent successfully, false otherwise.
551      */
startWpsRegistrar(String bssid, String pin)552     public boolean startWpsRegistrar(String bssid, String pin) {
553         return mSupplicantStaIfaceHal.startWpsRegistrar(bssid, pin);
554     }
555 
556     /**
557      * Cancels any ongoing WPS requests.
558      *
559      * @return true if request is sent successfully, false otherwise.
560      */
cancelWps()561     public boolean cancelWps() {
562         return mSupplicantStaIfaceHal.cancelWps();
563     }
564 
565     /**
566      * Set WPS device name.
567      *
568      * @param name String to be set.
569      * @return true if request is sent successfully, false otherwise.
570      */
setDeviceName(String name)571     public boolean setDeviceName(String name) {
572         return mSupplicantStaIfaceHal.setWpsDeviceName(name);
573     }
574 
575     /**
576      * Set WPS device type.
577      *
578      * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg>
579      * @return true if request is sent successfully, false otherwise.
580      */
setDeviceType(String type)581     public boolean setDeviceType(String type) {
582         return mSupplicantStaIfaceHal.setWpsDeviceType(type);
583     }
584 
585     /**
586      * Set WPS config methods
587      *
588      * @param cfg List of config methods.
589      * @return true if request is sent successfully, false otherwise.
590      */
setConfigMethods(String cfg)591     public boolean setConfigMethods(String cfg) {
592         return mSupplicantStaIfaceHal.setWpsConfigMethods(cfg);
593     }
594 
595     /**
596      * Set WPS manufacturer.
597      *
598      * @param value String to be set.
599      * @return true if request is sent successfully, false otherwise.
600      */
setManufacturer(String value)601     public boolean setManufacturer(String value) {
602         return mSupplicantStaIfaceHal.setWpsManufacturer(value);
603     }
604 
605     /**
606      * Set WPS model name.
607      *
608      * @param value String to be set.
609      * @return true if request is sent successfully, false otherwise.
610      */
setModelName(String value)611     public boolean setModelName(String value) {
612         return mSupplicantStaIfaceHal.setWpsModelName(value);
613     }
614 
615     /**
616      * Set WPS model number.
617      *
618      * @param value String to be set.
619      * @return true if request is sent successfully, false otherwise.
620      */
setModelNumber(String value)621     public boolean setModelNumber(String value) {
622         return mSupplicantStaIfaceHal.setWpsModelNumber(value);
623     }
624 
625     /**
626      * Set WPS serial number.
627      *
628      * @param value String to be set.
629      * @return true if request is sent successfully, false otherwise.
630      */
setSerialNumber(String value)631     public boolean setSerialNumber(String value) {
632         return mSupplicantStaIfaceHal.setWpsSerialNumber(value);
633     }
634 
635     /**
636      * Enable or disable power save mode.
637      *
638      * @param enabled true to enable, false to disable.
639      */
setPowerSave(boolean enabled)640     public void setPowerSave(boolean enabled) {
641         mSupplicantStaIfaceHal.setPowerSave(enabled);
642     }
643 
644     /**
645      * Set concurrency priority between P2P & STA operations.
646      *
647      * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations,
648      *                            false otherwise.
649      * @return true if request is sent successfully, false otherwise.
650      */
setConcurrencyPriority(boolean isStaHigherPriority)651     public boolean setConcurrencyPriority(boolean isStaHigherPriority) {
652         return mSupplicantStaIfaceHal.setConcurrencyPriority(isStaHigherPriority);
653     }
654 
655     /**
656      * Enable/Disable auto reconnect functionality in wpa_supplicant.
657      *
658      * @param enable true to enable auto reconnecting, false to disable.
659      * @return true if request is sent successfully, false otherwise.
660      */
enableStaAutoReconnect(boolean enable)661     public boolean enableStaAutoReconnect(boolean enable) {
662         return mSupplicantStaIfaceHal.enableAutoReconnect(enable);
663     }
664 
665     /**
666      * Migrate all the configured networks from wpa_supplicant.
667      *
668      * @param configs       Map of configuration key to configuration objects corresponding to all
669      *                      the networks.
670      * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf
671      * @return Max priority of all the configs.
672      */
migrateNetworksFromSupplicant(Map<String, WifiConfiguration> configs, SparseArray<Map<String, String>> networkExtras)673     public boolean migrateNetworksFromSupplicant(Map<String, WifiConfiguration> configs,
674                                                  SparseArray<Map<String, String>> networkExtras) {
675         return mSupplicantStaIfaceHal.loadNetworks(configs, networkExtras);
676     }
677 
678     /**
679      * Add the provided network configuration to wpa_supplicant and initiate connection to it.
680      * This method does the following:
681      * 1. Abort any ongoing scan to unblock the connection request.
682      * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect).
683      * 3. Add a new network to wpa_supplicant.
684      * 4. Save the provided configuration to wpa_supplicant.
685      * 5. Select the new network in wpa_supplicant.
686      * 6. Triggers reconnect command to wpa_supplicant.
687      *
688      * @param configuration WifiConfiguration parameters for the provided network.
689      * @return {@code true} if it succeeds, {@code false} otherwise
690      */
connectToNetwork(WifiConfiguration configuration)691     public boolean connectToNetwork(WifiConfiguration configuration) {
692         // Abort ongoing scan before connect() to unblock connection request.
693         mWificondControl.abortScan();
694         return mSupplicantStaIfaceHal.connectToNetwork(configuration);
695     }
696 
697     /**
698      * Initiates roaming to the already configured network in wpa_supplicant. If the network
699      * configuration provided does not match the already configured network, then this triggers
700      * a new connection attempt (instead of roam).
701      * 1. Abort any ongoing scan to unblock the roam request.
702      * 2. First check if we're attempting to connect to the same network as we currently have
703      * configured.
704      * 3. Set the new bssid for the network in wpa_supplicant.
705      * 4. Triggers reassociate command to wpa_supplicant.
706      *
707      * @param configuration WifiConfiguration parameters for the provided network.
708      * @return {@code true} if it succeeds, {@code false} otherwise
709      */
roamToNetwork(WifiConfiguration configuration)710     public boolean roamToNetwork(WifiConfiguration configuration) {
711         // Abort ongoing scan before connect() to unblock roaming request.
712         mWificondControl.abortScan();
713         return mSupplicantStaIfaceHal.roamToNetwork(configuration);
714     }
715 
716     /**
717      * Get the framework network ID corresponding to the provided supplicant network ID for the
718      * network configured in wpa_supplicant.
719      *
720      * @param supplicantNetworkId network ID in wpa_supplicant for the network.
721      * @return Corresponding framework network ID if found, -1 if network not found.
722      */
getFrameworkNetworkId(int supplicantNetworkId)723     public int getFrameworkNetworkId(int supplicantNetworkId) {
724         return supplicantNetworkId;
725     }
726 
727     /**
728      * Remove all the networks.
729      *
730      * @return {@code true} if it succeeds, {@code false} otherwise
731      */
removeAllNetworks()732     public boolean removeAllNetworks() {
733         return mSupplicantStaIfaceHal.removeAllNetworks();
734     }
735 
736     /**
737      * Set the BSSID for the currently configured network in wpa_supplicant.
738      *
739      * @return true if successful, false otherwise.
740      */
setConfiguredNetworkBSSID(String bssid)741     public boolean setConfiguredNetworkBSSID(String bssid) {
742         return mSupplicantStaIfaceHal.setCurrentNetworkBssid(bssid);
743     }
744 
745     /**
746      * Initiate ANQP query.
747      *
748      * @param bssid BSSID of the AP to be queried
749      * @param anqpIds Set of anqp IDs.
750      * @param hs20Subtypes Set of HS20 subtypes.
751      * @return true on success, false otherwise.
752      */
requestAnqp(String bssid, Set<Integer> anqpIds, Set<Integer> hs20Subtypes)753     public boolean requestAnqp(String bssid, Set<Integer> anqpIds, Set<Integer> hs20Subtypes) {
754         if (bssid == null || ((anqpIds == null || anqpIds.isEmpty())
755                 && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) {
756             Log.e(mTAG, "Invalid arguments for ANQP request.");
757             return false;
758         }
759         ArrayList<Short> anqpIdList = new ArrayList<>();
760         for (Integer anqpId : anqpIds) {
761             anqpIdList.add(anqpId.shortValue());
762         }
763         ArrayList<Integer> hs20SubtypeList = new ArrayList<>();
764         hs20SubtypeList.addAll(hs20Subtypes);
765         return mSupplicantStaIfaceHal.initiateAnqpQuery(bssid, anqpIdList, hs20SubtypeList);
766     }
767 
768     /**
769      * Request a passpoint icon file |filename| from the specified AP |bssid|.
770      * @param bssid BSSID of the AP
771      * @param fileName name of the icon file
772      * @return true if request is sent successfully, false otherwise
773      */
requestIcon(String bssid, String fileName)774     public boolean requestIcon(String  bssid, String fileName) {
775         if (bssid == null || fileName == null) {
776             Log.e(mTAG, "Invalid arguments for Icon request.");
777             return false;
778         }
779         return mSupplicantStaIfaceHal.initiateHs20IconQuery(bssid, fileName);
780     }
781 
782     /**
783      * Get the currently configured network's WPS NFC token.
784      *
785      * @return Hex string corresponding to the WPS NFC token.
786      */
getCurrentNetworkWpsNfcConfigurationToken()787     public String getCurrentNetworkWpsNfcConfigurationToken() {
788         return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken();
789     }
790 
791     /** Remove the request |networkId| from supplicant if it's the current network,
792      * if the current configured network matches |networkId|.
793      *
794      * @param networkId network id of the network to be removed from supplicant.
795      */
removeNetworkIfCurrent(int networkId)796     public void removeNetworkIfCurrent(int networkId) {
797         mSupplicantStaIfaceHal.removeNetworkIfCurrent(networkId);
798     }
799 
800     /********************************************************
801      * Vendor HAL operations
802      ********************************************************/
803     /**
804      * Callback to notify vendor HAL death.
805      */
806     public interface VendorHalDeathEventHandler {
807         /**
808          * Invoked when the vendor HAL dies.
809          */
onDeath()810         void onDeath();
811     }
812 
813     /**
814      * Initializes the vendor HAL. This is just used to initialize the {@link HalDeviceManager}.
815      */
initializeVendorHal(VendorHalDeathEventHandler handler)816     public boolean initializeVendorHal(VendorHalDeathEventHandler handler) {
817         return mWifiVendorHal.initialize(handler);
818     }
819 
820     /**
821      * Bring up the Vendor HAL and configure for STA mode or AP mode, if vendor HAL is supported.
822      *
823      * @param isStaMode true to start HAL in STA mode, false to start in AP mode.
824      * @return false if the HAL start fails, true if successful or if vendor HAL not supported.
825      */
startHalIfNecessary(boolean isStaMode)826     private boolean startHalIfNecessary(boolean isStaMode) {
827         if (!mWifiVendorHal.isVendorHalSupported()) {
828             Log.i(mTAG, "Vendor HAL not supported, Ignore start...");
829             return true;
830         }
831         return mWifiVendorHal.startVendorHal(isStaMode);
832     }
833 
834     /**
835      * Stops the HAL, if vendor HAL is supported.
836      */
stopHalIfNecessary()837     private void stopHalIfNecessary() {
838         if (!mWifiVendorHal.isVendorHalSupported()) {
839             Log.i(mTAG, "Vendor HAL not supported, Ignore stop...");
840             return;
841         }
842         mWifiVendorHal.stopVendorHal();
843     }
844 
845     /**
846      * Tests whether the HAL is running or not
847      */
isHalStarted()848     public boolean isHalStarted() {
849         return mWifiVendorHal.isHalStarted();
850     }
851 
852     // TODO: Change variable names to camel style.
853     public static class ScanCapabilities {
854         public int  max_scan_cache_size;
855         public int  max_scan_buckets;
856         public int  max_ap_cache_per_scan;
857         public int  max_rssi_sample_size;
858         public int  max_scan_reporting_threshold;
859     }
860 
861     /**
862      * Gets the scan capabilities
863      *
864      * @param capabilities object to be filled in
865      * @return true for success. false for failure
866      */
getBgScanCapabilities(ScanCapabilities capabilities)867     public boolean getBgScanCapabilities(ScanCapabilities capabilities) {
868         return mWifiVendorHal.getBgScanCapabilities(capabilities);
869     }
870 
871     public static class ChannelSettings {
872         public int frequency;
873         public int dwell_time_ms;
874         public boolean passive;
875     }
876 
877     public static class BucketSettings {
878         public int bucket;
879         public int band;
880         public int period_ms;
881         public int max_period_ms;
882         public int step_count;
883         public int report_events;
884         public int num_channels;
885         public ChannelSettings[] channels;
886     }
887 
888     /**
889      * Network parameters for hidden networks to be scanned for.
890      */
891     public static class HiddenNetwork {
892         public String ssid;
893 
894         @Override
equals(Object otherObj)895         public boolean equals(Object otherObj) {
896             if (this == otherObj) {
897                 return true;
898             } else if (otherObj == null || getClass() != otherObj.getClass()) {
899                 return false;
900             }
901             HiddenNetwork other = (HiddenNetwork) otherObj;
902             return Objects.equals(ssid, other.ssid);
903         }
904 
905         @Override
hashCode()906         public int hashCode() {
907             return (ssid == null ? 0 : ssid.hashCode());
908         }
909     }
910 
911     public static class ScanSettings {
912         public int base_period_ms;
913         public int max_ap_per_scan;
914         public int report_threshold_percent;
915         public int report_threshold_num_scans;
916         public int num_buckets;
917         /* Not used for bg scans. Only works for single scans. */
918         public HiddenNetwork[] hiddenNetworks;
919         public BucketSettings[] buckets;
920     }
921 
922     /**
923      * Network parameters to start PNO scan.
924      */
925     public static class PnoNetwork {
926         public String ssid;
927         public byte flags;
928         public byte auth_bit_field;
929 
930         @Override
equals(Object otherObj)931         public boolean equals(Object otherObj) {
932             if (this == otherObj) {
933                 return true;
934             } else if (otherObj == null || getClass() != otherObj.getClass()) {
935                 return false;
936             }
937             PnoNetwork other = (PnoNetwork) otherObj;
938             return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags)
939                     && (auth_bit_field == other.auth_bit_field));
940         }
941 
942         @Override
hashCode()943         public int hashCode() {
944             int result = (ssid == null ? 0 : ssid.hashCode());
945             result ^= ((int) flags * 31) + ((int) auth_bit_field << 8);
946             return result;
947         }
948     }
949 
950     /**
951      * Parameters to start PNO scan. This holds the list of networks which are going to used for
952      * PNO scan.
953      */
954     public static class PnoSettings {
955         public int min5GHzRssi;
956         public int min24GHzRssi;
957         public int initialScoreMax;
958         public int currentConnectionBonus;
959         public int sameNetworkBonus;
960         public int secureBonus;
961         public int band5GHzBonus;
962         public int periodInMs;
963         public boolean isConnected;
964         public PnoNetwork[] networkList;
965     }
966 
967     public static interface ScanEventHandler {
968         /**
969          * Called for each AP as it is found with the entire contents of the beacon/probe response.
970          * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified.
971          */
onFullScanResult(ScanResult fullScanResult, int bucketsScanned)972         void onFullScanResult(ScanResult fullScanResult, int bucketsScanned);
973         /**
974          * Callback on an event during a gscan scan.
975          * See WifiNative.WIFI_SCAN_* for possible values.
976          */
onScanStatus(int event)977         void onScanStatus(int event);
978         /**
979          * Called with the current cached scan results when gscan is paused.
980          */
onScanPaused(WifiScanner.ScanData[] data)981         void onScanPaused(WifiScanner.ScanData[] data);
982         /**
983          * Called with the current cached scan results when gscan is resumed.
984          */
onScanRestarted()985         void onScanRestarted();
986     }
987 
988     /**
989      * Handler to notify the occurrence of various events during PNO scan.
990      */
991     public interface PnoEventHandler {
992         /**
993          * Callback to notify when one of the shortlisted networks is found during PNO scan.
994          * @param results List of Scan results received.
995          */
onPnoNetworkFound(ScanResult[] results)996         void onPnoNetworkFound(ScanResult[] results);
997 
998         /**
999          * Callback to notify when the PNO scan schedule fails.
1000          */
onPnoScanFailed()1001         void onPnoScanFailed();
1002     }
1003 
1004     public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0;
1005     public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1;
1006     public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2;
1007     public static final int WIFI_SCAN_FAILED = 3;
1008 
1009     /**
1010      * Starts a background scan.
1011      * Any ongoing scan will be stopped first
1012      *
1013      * @param settings     to control the scan
1014      * @param eventHandler to call with the results
1015      * @return true for success
1016      */
startBgScan(ScanSettings settings, ScanEventHandler eventHandler)1017     public boolean startBgScan(ScanSettings settings, ScanEventHandler eventHandler) {
1018         return mWifiVendorHal.startBgScan(settings, eventHandler);
1019     }
1020 
1021     /**
1022      * Stops any ongoing backgound scan
1023      */
stopBgScan()1024     public void stopBgScan() {
1025         mWifiVendorHal.stopBgScan();
1026     }
1027 
1028     /**
1029      * Pauses an ongoing backgound scan
1030      */
pauseBgScan()1031     public void pauseBgScan() {
1032         mWifiVendorHal.pauseBgScan();
1033     }
1034 
1035     /**
1036      * Restarts a paused scan
1037      */
restartBgScan()1038     public void restartBgScan() {
1039         mWifiVendorHal.restartBgScan();
1040     }
1041 
1042     /**
1043      * Gets the latest scan results received.
1044      */
getBgScanResults()1045     public WifiScanner.ScanData[] getBgScanResults() {
1046         return mWifiVendorHal.getBgScanResults();
1047     }
1048 
getWifiLinkLayerStats(String iface)1049     public WifiLinkLayerStats getWifiLinkLayerStats(String iface) {
1050         return mWifiVendorHal.getWifiLinkLayerStats();
1051     }
1052 
1053     /**
1054      * Get the supported features
1055      *
1056      * @return bitmask defined by WifiManager.WIFI_FEATURE_*
1057      */
getSupportedFeatureSet()1058     public int getSupportedFeatureSet() {
1059         return mWifiVendorHal.getSupportedFeatureSet();
1060     }
1061 
1062     public static interface RttEventHandler {
onRttResults(RttManager.RttResult[] result)1063         void onRttResults(RttManager.RttResult[] result);
1064     }
1065 
1066     /**
1067      * Starts a new rtt request
1068      *
1069      * @param params RTT request params. Refer to {@link RttManager#RttParams}.
1070      * @param handler Callback to be invoked to notify any results.
1071      * @return true if the request was successful, false otherwise.
1072      */
requestRtt( RttManager.RttParams[] params, RttEventHandler handler)1073     public boolean requestRtt(
1074             RttManager.RttParams[] params, RttEventHandler handler) {
1075         return mWifiVendorHal.requestRtt(params, handler);
1076     }
1077 
1078     /**
1079      * Cancels an outstanding rtt request
1080      *
1081      * @param params RTT request params. Refer to {@link RttManager#RttParams}
1082      * @return true if there was an outstanding request and it was successfully cancelled
1083      */
cancelRtt(RttManager.RttParams[] params)1084     public boolean cancelRtt(RttManager.RttParams[] params) {
1085         return mWifiVendorHal.cancelRtt(params);
1086     }
1087 
1088     /**
1089      * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder
1090      * role is successfully enabled, {@code null} otherwise.
1091      *
1092      * @param timeoutSeconds timeout to use for the responder.
1093      */
1094     @Nullable
enableRttResponder(int timeoutSeconds)1095     public ResponderConfig enableRttResponder(int timeoutSeconds) {
1096         return mWifiVendorHal.enableRttResponder(timeoutSeconds);
1097     }
1098 
1099     /**
1100      * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled,
1101      * {@code false} otherwise.
1102      */
disableRttResponder()1103     public boolean disableRttResponder() {
1104         return mWifiVendorHal.disableRttResponder();
1105     }
1106 
1107     /**
1108      * Set the MAC OUI during scanning.
1109      * An OUI {Organizationally Unique Identifier} is a 24-bit number that
1110      * uniquely identifies a vendor or manufacturer.
1111      *
1112      * @param oui OUI to set.
1113      * @return true for success
1114      */
setScanningMacOui(byte[] oui)1115     public boolean setScanningMacOui(byte[] oui) {
1116         return mWifiVendorHal.setScanningMacOui(oui);
1117     }
1118 
1119     /**
1120      * Query the list of valid frequencies for the provided band.
1121      * The result depends on the on the country code that has been set.
1122      *
1123      * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants.
1124      * @return frequencies vector of valid frequencies (MHz), or null for error.
1125      * @throws IllegalArgumentException if band is not recognized.
1126      */
getChannelsForBand(int band)1127     public int [] getChannelsForBand(int band) {
1128         return mWifiVendorHal.getChannelsForBand(band);
1129     }
1130 
1131     /**
1132      * Indicates whether getChannelsForBand is supported.
1133      *
1134      * @return true if it is.
1135      */
isGetChannelsForBandSupported()1136     public boolean isGetChannelsForBandSupported() {
1137         return mWifiVendorHal.isGetChannelsForBandSupported();
1138     }
1139 
1140     /**
1141      * RTT (Round Trip Time) measurement capabilities of the device.
1142      */
getRttCapabilities()1143     public RttManager.RttCapabilities getRttCapabilities() {
1144         return mWifiVendorHal.getRttCapabilities();
1145     }
1146 
1147     /**
1148      * Get the APF (Android Packet Filter) capabilities of the device
1149      */
getApfCapabilities()1150     public ApfCapabilities getApfCapabilities() {
1151         return mWifiVendorHal.getApfCapabilities();
1152     }
1153 
1154     /**
1155      * Installs an APF program on this iface, replacing any existing program.
1156      *
1157      * @param filter is the android packet filter program
1158      * @return true for success
1159      */
installPacketFilter(byte[] filter)1160     public boolean installPacketFilter(byte[] filter) {
1161         return mWifiVendorHal.installPacketFilter(filter);
1162     }
1163 
1164     /**
1165      * Set country code for this AP iface.
1166      *
1167      * @param countryCode - two-letter country code (as ISO 3166)
1168      * @return true for success
1169      */
setCountryCodeHal(String countryCode)1170     public boolean setCountryCodeHal(String countryCode) {
1171         return mWifiVendorHal.setCountryCodeHal(countryCode);
1172     }
1173 
1174     //---------------------------------------------------------------------------------
1175     /* Wifi Logger commands/events */
1176     public static interface WifiLoggerEventHandler {
onRingBufferData(RingBufferStatus status, byte[] buffer)1177         void onRingBufferData(RingBufferStatus status, byte[] buffer);
onWifiAlert(int errorCode, byte[] buffer)1178         void onWifiAlert(int errorCode, byte[] buffer);
1179     }
1180 
1181     /**
1182      * Registers the logger callback and enables alerts.
1183      * Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked.
1184      *
1185      * @param handler Callback to be invoked.
1186      * @return true on success, false otherwise.
1187      */
setLoggingEventHandler(WifiLoggerEventHandler handler)1188     public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) {
1189         return mWifiVendorHal.setLoggingEventHandler(handler);
1190     }
1191 
1192     /**
1193      * Control debug data collection
1194      *
1195      * @param verboseLevel 0 to 3, inclusive. 0 stops logging.
1196      * @param flags        Ignored.
1197      * @param maxInterval  Maximum interval between reports; ignore if 0.
1198      * @param minDataSize  Minimum data size in buffer for report; ignore if 0.
1199      * @param ringName     Name of the ring for which data collection is to start.
1200      * @return true for success, false otherwise.
1201      */
startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval, int minDataSize, String ringName)1202     public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval,
1203             int minDataSize, String ringName){
1204         return mWifiVendorHal.startLoggingRingBuffer(
1205                 verboseLevel, flags, maxInterval, minDataSize, ringName);
1206     }
1207 
1208     /**
1209      * Logger features exposed.
1210      * This is a no-op now, will always return -1.
1211      *
1212      * @return true on success, false otherwise.
1213      */
getSupportedLoggerFeatureSet()1214     public int getSupportedLoggerFeatureSet() {
1215         return mWifiVendorHal.getSupportedLoggerFeatureSet();
1216     }
1217 
1218     /**
1219      * Stops all logging and resets the logger callback.
1220      * This stops both the alerts and ring buffer data collection.
1221      * @return true on success, false otherwise.
1222      */
resetLogHandler()1223     public boolean resetLogHandler() {
1224         return mWifiVendorHal.resetLogHandler();
1225     }
1226 
1227     /**
1228      * Vendor-provided wifi driver version string
1229      *
1230      * @return String returned from the HAL.
1231      */
getDriverVersion()1232     public String getDriverVersion() {
1233         return mWifiVendorHal.getDriverVersion();
1234     }
1235 
1236     /**
1237      * Vendor-provided wifi firmware version string
1238      *
1239      * @return String returned from the HAL.
1240      */
getFirmwareVersion()1241     public String getFirmwareVersion() {
1242         return mWifiVendorHal.getFirmwareVersion();
1243     }
1244 
1245     public static class RingBufferStatus{
1246         String name;
1247         int flag;
1248         int ringBufferId;
1249         int ringBufferByteSize;
1250         int verboseLevel;
1251         int writtenBytes;
1252         int readBytes;
1253         int writtenRecords;
1254 
1255         // Bit masks for interpreting |flag|
1256         public static final int HAS_BINARY_ENTRIES = (1 << 0);
1257         public static final int HAS_ASCII_ENTRIES = (1 << 1);
1258         public static final int HAS_PER_PACKET_ENTRIES = (1 << 2);
1259 
1260         @Override
toString()1261         public String toString() {
1262             return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId +
1263                     " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel +
1264                     " writtenBytes: " + writtenBytes + " readBytes: " + readBytes +
1265                     " writtenRecords: " + writtenRecords;
1266         }
1267     }
1268 
1269     /**
1270      * API to get the status of all ring buffers supported by driver
1271      */
getRingBufferStatus()1272     public RingBufferStatus[] getRingBufferStatus() {
1273         return mWifiVendorHal.getRingBufferStatus();
1274     }
1275 
1276     /**
1277      * Indicates to driver that all the data has to be uploaded urgently
1278      *
1279      * @param ringName Name of the ring buffer requested.
1280      * @return true on success, false otherwise.
1281      */
getRingBufferData(String ringName)1282     public boolean getRingBufferData(String ringName) {
1283         return mWifiVendorHal.getRingBufferData(ringName);
1284     }
1285 
1286     /**
1287      * Request vendor debug info from the firmware
1288      *
1289      * @return Raw data obtained from the HAL.
1290      */
getFwMemoryDump()1291     public byte[] getFwMemoryDump() {
1292         return mWifiVendorHal.getFwMemoryDump();
1293     }
1294 
1295     /**
1296      * Request vendor debug info from the driver
1297      *
1298      * @return Raw data obtained from the HAL.
1299      */
getDriverStateDump()1300     public byte[] getDriverStateDump() {
1301         return mWifiVendorHal.getDriverStateDump();
1302     }
1303 
1304     //---------------------------------------------------------------------------------
1305     /* Packet fate API */
1306 
1307     @Immutable
1308     abstract static class FateReport {
1309         final static int USEC_PER_MSEC = 1000;
1310         // The driver timestamp is a 32-bit counter, in microseconds. This field holds the
1311         // maximal value of a driver timestamp in milliseconds.
1312         final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000);
1313         final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
1314 
1315         final byte mFate;
1316         final long mDriverTimestampUSec;
1317         final byte mFrameType;
1318         final byte[] mFrameBytes;
1319         final long mEstimatedWallclockMSec;
1320 
FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes)1321         FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
1322             mFate = fate;
1323             mDriverTimestampUSec = driverTimestampUSec;
1324             mEstimatedWallclockMSec =
1325                     convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec);
1326             mFrameType = frameType;
1327             mFrameBytes = frameBytes;
1328         }
1329 
toTableRowString()1330         public String toTableRowString() {
1331             StringWriter sw = new StringWriter();
1332             PrintWriter pw = new PrintWriter(sw);
1333             FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
1334             dateFormatter.setTimeZone(TimeZone.getDefault());
1335             pw.format("%-15s  %12s  %-9s  %-32s  %-12s  %-23s  %s\n",
1336                     mDriverTimestampUSec,
1337                     dateFormatter.format(new Date(mEstimatedWallclockMSec)),
1338                     directionToString(), fateToString(), parser.mMostSpecificProtocolString,
1339                     parser.mTypeString, parser.mResultString);
1340             return sw.toString();
1341         }
1342 
toVerboseStringWithPiiAllowed()1343         public String toVerboseStringWithPiiAllowed() {
1344             StringWriter sw = new StringWriter();
1345             PrintWriter pw = new PrintWriter(sw);
1346             FrameParser parser = new FrameParser(mFrameType, mFrameBytes);
1347             pw.format("Frame direction: %s\n", directionToString());
1348             pw.format("Frame timestamp: %d\n", mDriverTimestampUSec);
1349             pw.format("Frame fate: %s\n", fateToString());
1350             pw.format("Frame type: %s\n", frameTypeToString(mFrameType));
1351             pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString);
1352             pw.format("Frame protocol type: %s\n", parser.mTypeString);
1353             pw.format("Frame length: %d\n", mFrameBytes.length);
1354             pw.append("Frame bytes");
1355             pw.append(HexDump.dumpHexString(mFrameBytes));  // potentially contains PII
1356             pw.append("\n");
1357             return sw.toString();
1358         }
1359 
1360         /* Returns a header to match the output of toTableRowString(). */
getTableHeader()1361         public static String getTableHeader() {
1362             StringWriter sw = new StringWriter();
1363             PrintWriter pw = new PrintWriter(sw);
1364             pw.format("\n%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
1365                     "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result");
1366             pw.format("%-15s  %-12s  %-9s  %-32s  %-12s  %-23s  %s\n",
1367                     "---------", "--------", "---------", "----", "--------", "----", "------");
1368             return sw.toString();
1369         }
1370 
directionToString()1371         protected abstract String directionToString();
1372 
fateToString()1373         protected abstract String fateToString();
1374 
frameTypeToString(byte frameType)1375         private static String frameTypeToString(byte frameType) {
1376             switch (frameType) {
1377                 case WifiLoggerHal.FRAME_TYPE_UNKNOWN:
1378                     return "unknown";
1379                 case WifiLoggerHal.FRAME_TYPE_ETHERNET_II:
1380                     return "data";
1381                 case WifiLoggerHal.FRAME_TYPE_80211_MGMT:
1382                     return "802.11 management";
1383                 default:
1384                     return Byte.toString(frameType);
1385             }
1386         }
1387 
1388         /**
1389          * Converts a driver timestamp to a wallclock time, based on the current
1390          * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of
1391          * microseconds, with the same base as BOOTTIME.
1392          */
convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec)1393         private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) {
1394             final long wallclockMillisNow = System.currentTimeMillis();
1395             final long boottimeMillisNow = SystemClock.elapsedRealtime();
1396             final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC;
1397 
1398             long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC;
1399             if (boottimeTimestampMillis < driverTimestampMillis) {
1400                 // The 32-bit microsecond count has wrapped between the time that the driver
1401                 // recorded the packet, and the call to this function. Adjust the BOOTTIME
1402                 // timestamp, to compensate.
1403                 //
1404                 // Note that overflow is not a concern here, since the result is less than
1405                 // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above,
1406                 // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since
1407                 // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit
1408                 // within a long.
1409                 boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC;
1410             }
1411 
1412             final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis;
1413             return wallclockMillisNow - millisSincePacketTimestamp;
1414         }
1415     }
1416 
1417     /**
1418      * Represents the fate information for one outbound packet.
1419      */
1420     @Immutable
1421     public static final class TxFateReport extends FateReport {
TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes)1422         TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
1423             super(fate, driverTimestampUSec, frameType, frameBytes);
1424         }
1425 
1426         @Override
directionToString()1427         protected String directionToString() {
1428             return "TX";
1429         }
1430 
1431         @Override
fateToString()1432         protected String fateToString() {
1433             switch (mFate) {
1434                 case WifiLoggerHal.TX_PKT_FATE_ACKED:
1435                     return "acked";
1436                 case WifiLoggerHal.TX_PKT_FATE_SENT:
1437                     return "sent";
1438                 case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED:
1439                     return "firmware queued";
1440                 case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID:
1441                     return "firmware dropped (invalid frame)";
1442                 case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS:
1443                     return "firmware dropped (no bufs)";
1444                 case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER:
1445                     return "firmware dropped (other)";
1446                 case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED:
1447                     return "driver queued";
1448                 case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID:
1449                     return "driver dropped (invalid frame)";
1450                 case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS:
1451                     return "driver dropped (no bufs)";
1452                 case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER:
1453                     return "driver dropped (other)";
1454                 default:
1455                     return Byte.toString(mFate);
1456             }
1457         }
1458     }
1459 
1460     /**
1461      * Represents the fate information for one inbound packet.
1462      */
1463     @Immutable
1464     public static final class RxFateReport extends FateReport {
RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes)1465         RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) {
1466             super(fate, driverTimestampUSec, frameType, frameBytes);
1467         }
1468 
1469         @Override
directionToString()1470         protected String directionToString() {
1471             return "RX";
1472         }
1473 
1474         @Override
fateToString()1475         protected String fateToString() {
1476             switch (mFate) {
1477                 case WifiLoggerHal.RX_PKT_FATE_SUCCESS:
1478                     return "success";
1479                 case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED:
1480                     return "firmware queued";
1481                 case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER:
1482                     return "firmware dropped (filter)";
1483                 case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID:
1484                     return "firmware dropped (invalid frame)";
1485                 case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS:
1486                     return "firmware dropped (no bufs)";
1487                 case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER:
1488                     return "firmware dropped (other)";
1489                 case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED:
1490                     return "driver queued";
1491                 case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER:
1492                     return "driver dropped (filter)";
1493                 case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID:
1494                     return "driver dropped (invalid frame)";
1495                 case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS:
1496                     return "driver dropped (no bufs)";
1497                 case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER:
1498                     return "driver dropped (other)";
1499                 default:
1500                     return Byte.toString(mFate);
1501             }
1502         }
1503     }
1504 
1505     /**
1506      * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started.
1507      *
1508      * @return true for success, false otherwise.
1509      */
startPktFateMonitoring()1510     public boolean startPktFateMonitoring() {
1511         return mWifiVendorHal.startPktFateMonitoring();
1512     }
1513 
1514     /**
1515      * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started.
1516      *
1517      * @return true for success, false otherwise.
1518      */
getTxPktFates(TxFateReport[] reportBufs)1519     public boolean getTxPktFates(TxFateReport[] reportBufs) {
1520         return mWifiVendorHal.getTxPktFates(reportBufs);
1521     }
1522 
1523     /**
1524      * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started.
1525      */
getRxPktFates(RxFateReport[] reportBufs)1526     public boolean getRxPktFates(RxFateReport[] reportBufs) {
1527         return mWifiVendorHal.getRxPktFates(reportBufs);
1528     }
1529 
1530     /**
1531      * Set the PNO settings & the network list in HAL to start PNO.
1532      * @param settings PNO settings and network list.
1533      * @param eventHandler Handler to receive notifications back during PNO scan.
1534      * @return true if success, false otherwise
1535      */
setPnoList(PnoSettings settings, PnoEventHandler eventHandler)1536     public boolean setPnoList(PnoSettings settings, PnoEventHandler eventHandler) {
1537         Log.e(mTAG, "setPnoList not supported");
1538         return false;
1539     }
1540 
1541     /**
1542      * Reset the PNO settings in HAL to stop PNO.
1543      * @return true if success, false otherwise
1544      */
resetPnoList()1545     public boolean resetPnoList() {
1546         Log.e(mTAG, "resetPnoList not supported");
1547         return false;
1548     }
1549 
1550     /**
1551      * Start sending the specified keep alive packets periodically.
1552      *
1553      * @param slot Integer used to identify each request.
1554      * @param keepAlivePacket Raw packet contents to send.
1555      * @param period Period to use for sending these packets.
1556      * @return 0 for success, -1 for error
1557      */
startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket, int period)1558     public int startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket,
1559                                            int period) {
1560         String[] macAddrStr = getMacAddress().split(":");
1561         byte[] srcMac = new byte[6];
1562         for (int i = 0; i < 6; i++) {
1563             Integer hexVal = Integer.parseInt(macAddrStr[i], 16);
1564             srcMac[i] = hexVal.byteValue();
1565         }
1566         return mWifiVendorHal.startSendingOffloadedPacket(
1567                 slot, srcMac, keepAlivePacket, period);
1568     }
1569 
1570     /**
1571      * Stop sending the specified keep alive packets.
1572      *
1573      * @param slot id - same as startSendingOffloadedPacket call.
1574      * @return 0 for success, -1 for error
1575      */
stopSendingOffloadedPacket(int slot)1576     public int stopSendingOffloadedPacket(int slot) {
1577         return mWifiVendorHal.stopSendingOffloadedPacket(slot);
1578     }
1579 
1580     public static interface WifiRssiEventHandler {
onRssiThresholdBreached(byte curRssi)1581         void onRssiThresholdBreached(byte curRssi);
1582     }
1583 
1584     /**
1585      * Start RSSI monitoring on the currently connected access point.
1586      *
1587      * @param maxRssi          Maximum RSSI threshold.
1588      * @param minRssi          Minimum RSSI threshold.
1589      * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi
1590      * @return 0 for success, -1 for failure
1591      */
startRssiMonitoring(byte maxRssi, byte minRssi, WifiRssiEventHandler rssiEventHandler)1592     public int startRssiMonitoring(byte maxRssi, byte minRssi,
1593                                    WifiRssiEventHandler rssiEventHandler) {
1594         return mWifiVendorHal.startRssiMonitoring(maxRssi, minRssi, rssiEventHandler);
1595     }
1596 
stopRssiMonitoring()1597     public int stopRssiMonitoring() {
1598         return mWifiVendorHal.stopRssiMonitoring();
1599     }
1600 
1601     /**
1602      * Fetch the host wakeup reasons stats from wlan driver.
1603      *
1604      * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
1605      */
getWlanWakeReasonCount()1606     public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
1607         return mWifiVendorHal.getWlanWakeReasonCount();
1608     }
1609 
1610     /**
1611      * Enable/Disable Neighbour discovery offload functionality in the firmware.
1612      *
1613      * @param enabled true to enable, false to disable.
1614      * @return true for success, false otherwise.
1615      */
configureNeighborDiscoveryOffload(boolean enabled)1616     public boolean configureNeighborDiscoveryOffload(boolean enabled) {
1617         return mWifiVendorHal.configureNeighborDiscoveryOffload(enabled);
1618     }
1619 
1620     // Firmware roaming control.
1621 
1622     /**
1623      * Class to retrieve firmware roaming capability parameters.
1624      */
1625     public static class RoamingCapabilities {
1626         public int  maxBlacklistSize;
1627         public int  maxWhitelistSize;
1628     }
1629 
1630     /**
1631      * Query the firmware roaming capabilities.
1632      * @return true for success, false otherwise.
1633      */
getRoamingCapabilities(RoamingCapabilities capabilities)1634     public boolean getRoamingCapabilities(RoamingCapabilities capabilities) {
1635         return mWifiVendorHal.getRoamingCapabilities(capabilities);
1636     }
1637 
1638     /**
1639      * Macros for controlling firmware roaming.
1640      */
1641     public static final int DISABLE_FIRMWARE_ROAMING = 0;
1642     public static final int ENABLE_FIRMWARE_ROAMING = 1;
1643 
1644     /**
1645      * Enable/disable firmware roaming.
1646      *
1647      * @return error code returned from HAL.
1648      */
enableFirmwareRoaming(int state)1649     public int enableFirmwareRoaming(int state) {
1650         return mWifiVendorHal.enableFirmwareRoaming(state);
1651     }
1652 
1653     /**
1654      * Class for specifying the roaming configurations.
1655      */
1656     public static class RoamingConfig {
1657         public ArrayList<String> blacklistBssids;
1658         public ArrayList<String> whitelistSsids;
1659     }
1660 
1661     /**
1662      * Set firmware roaming configurations.
1663      */
configureRoaming(RoamingConfig config)1664     public boolean configureRoaming(RoamingConfig config) {
1665         Log.d(mTAG, "configureRoaming ");
1666         return mWifiVendorHal.configureRoaming(config);
1667     }
1668 
1669     /**
1670      * Reset firmware roaming configuration.
1671      */
resetRoamingConfiguration()1672     public boolean resetRoamingConfiguration() {
1673         // Pass in an empty RoamingConfig object which translates to zero size
1674         // blacklist and whitelist to reset the firmware roaming configuration.
1675         return mWifiVendorHal.configureRoaming(new RoamingConfig());
1676     }
1677 
1678     /********************************************************
1679      * JNI operations
1680      ********************************************************/
1681     /* Register native functions */
1682     static {
1683         /* Native functions are defined in libwifi-service.so */
1684         System.loadLibrary("wifi-service");
registerNatives()1685         registerNatives();
1686     }
1687 
registerNatives()1688     private static native int registerNatives();
1689     /* kernel logging support */
readKernelLogNative()1690     private static native byte[] readKernelLogNative();
1691 
1692     /**
1693      * Fetches the latest kernel logs.
1694      */
readKernelLog()1695     public synchronized String readKernelLog() {
1696         byte[] bytes = readKernelLogNative();
1697         if (bytes != null) {
1698             CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
1699             try {
1700                 CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
1701                 return decoded.toString();
1702             } catch (CharacterCodingException cce) {
1703                 return new String(bytes, StandardCharsets.ISO_8859_1);
1704             }
1705         } else {
1706             return "*** failed to read kernel log ***";
1707         }
1708     }
1709 }
1710