• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.hal;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.content.Context;
23 import android.hardware.wifi.WifiStatusCode;
24 import android.net.wifi.CoexUnsafeChannel;
25 import android.net.wifi.WifiAvailableChannel;
26 import android.net.wifi.WifiManager;
27 import android.net.wifi.WifiScanner;
28 import android.util.Log;
29 
30 import com.android.server.wifi.SarInfo;
31 import com.android.server.wifi.SsidTranslator;
32 import com.android.server.wifi.WifiNative;
33 import com.android.server.wifi.WlanWakeReasonAndCounts;
34 import com.android.server.wifi.util.GeneralUtil.Mutable;
35 import com.android.server.wifi.util.NativeUtil;
36 
37 import java.lang.annotation.Retention;
38 import java.lang.annotation.RetentionPolicy;
39 import java.util.List;
40 import java.util.function.Supplier;
41 
42 /**
43  * Wrapper around a WifiChip.
44  * May be initialized using a HIDL or AIDL WifiChip.
45  */
46 public class WifiChip {
47     public static final String TAG = "WifiChip";
48     private IWifiChip mWifiChip;
49 
50     /**
51      * Interface concurrency types used in reporting device concurrency capabilities.
52      */
53     public static final int IFACE_CONCURRENCY_TYPE_STA = 0;
54     public static final int IFACE_CONCURRENCY_TYPE_AP = 1;
55     public static final int IFACE_CONCURRENCY_TYPE_AP_BRIDGED = 2;
56     public static final int IFACE_CONCURRENCY_TYPE_P2P = 3;
57     public static final int IFACE_CONCURRENCY_TYPE_NAN = 4;
58 
59     @IntDef(prefix = { "IFACE_CONCURRENCY_TYPE_" }, value = {
60             IFACE_CONCURRENCY_TYPE_STA,
61             IFACE_CONCURRENCY_TYPE_AP,
62             IFACE_CONCURRENCY_TYPE_AP_BRIDGED,
63             IFACE_CONCURRENCY_TYPE_P2P,
64             IFACE_CONCURRENCY_TYPE_NAN,
65     })
66     @Retention(RetentionPolicy.SOURCE)
67     public @interface IfaceConcurrencyType {}
68 
69     /**
70      * Supported interface types.
71      */
72     public static final int IFACE_TYPE_STA = 0;
73     public static final int IFACE_TYPE_AP = 1;
74     public static final int IFACE_TYPE_P2P = 2;
75     public static final int IFACE_TYPE_NAN = 3;
76 
77     @IntDef(prefix = { "IFACE_TYPE_" }, value = {
78             IFACE_TYPE_STA,
79             IFACE_TYPE_AP,
80             IFACE_TYPE_P2P,
81             IFACE_TYPE_NAN,
82     })
83     @Retention(RetentionPolicy.SOURCE)
84     public @interface IfaceType {}
85 
86     /**
87      * Antenna configurations.
88      */
89     public static final int WIFI_ANTENNA_MODE_UNSPECIFIED = 0;
90     public static final int WIFI_ANTENNA_MODE_1X1 = 1;
91     public static final int WIFI_ANTENNA_MODE_2X2 = 2;
92     public static final int WIFI_ANTENNA_MODE_3X3 = 3;
93     public static final int WIFI_ANTENNA_MODE_4X4 = 4;
94 
95     @IntDef(prefix = { "WIFI_ANTENNA_MODE_" }, value = {
96             WIFI_ANTENNA_MODE_UNSPECIFIED,
97             WIFI_ANTENNA_MODE_1X1,
98             WIFI_ANTENNA_MODE_2X2,
99             WIFI_ANTENNA_MODE_3X3,
100             WIFI_ANTENNA_MODE_4X4,
101     })
102     @Retention(RetentionPolicy.SOURCE)
103     public @interface WifiAntennaMode {}
104 
105     /**
106      * Response containing a value and a status code.
107      *
108      * @param <T> Type of value that should be returned.
109      */
110     public static class Response<T> {
111         private Mutable<T> mMutable;
112         private int mStatusCode;
113 
Response(T initialValue)114         public Response(T initialValue) {
115             mMutable = new Mutable<>(initialValue);
116             mStatusCode = WifiHal.WIFI_STATUS_ERROR_UNKNOWN;
117         }
118 
setValue(T value)119         public void setValue(T value) {
120             mMutable.value = value;
121         }
122 
getValue()123         public T getValue() {
124             return mMutable.value;
125         }
126 
setStatusCode(@ifiHal.WifiStatusCode int statusCode)127         public void setStatusCode(@WifiHal.WifiStatusCode int statusCode) {
128             mStatusCode = statusCode;
129         }
130 
getStatusCode()131         public @WifiHal.WifiStatusCode int getStatusCode() {
132             return mStatusCode;
133         }
134     }
135 
136     /**
137      * Set of interface concurrency types, along with the maximum number of interfaces that can have
138      * one of the specified concurrency types for a given ChipConcurrencyCombination. See
139      * ChipConcurrencyCombination below for examples.
140      */
141     public static class ChipConcurrencyCombinationLimit {
142         public final int maxIfaces;
143         public final @IfaceConcurrencyType List<Integer> types;
144 
ChipConcurrencyCombinationLimit(int inMaxIfaces, @IfaceConcurrencyType List<Integer> inTypes)145         public ChipConcurrencyCombinationLimit(int inMaxIfaces,
146                 @IfaceConcurrencyType List<Integer> inTypes) {
147             maxIfaces = inMaxIfaces;
148             types = inTypes;
149         }
150 
151         @Override
toString()152         public String toString() {
153             return "{maxIfaces=" + maxIfaces + ", types=" + types + "}";
154         }
155     }
156 
157     /**
158      * Set of interfaces that can operate concurrently when in a given mode.
159      *
160      * For example:
161      *   [{STA} <= 2]
162      *       At most two STA interfaces are supported
163      *       [], [STA], [STA+STA]
164      *
165      *   [{STA} <= 1, {NAN} <= 1, {AP_BRIDGED} <= 1]
166      *       Any combination of STA, NAN, AP_BRIDGED
167      *       [], [STA], [NAN], [AP_BRIDGED], [STA+NAN], [STA+AP_BRIDGED], [NAN+AP_BRIDGED],
168      *       [STA+NAN+AP_BRIDGED]
169      *
170      *   [{STA} <= 1, {NAN,P2P} <= 1]
171      *       Optionally a STA and either NAN or P2P
172      *       [], [STA], [STA+NAN], [STA+P2P], [NAN], [P2P]
173      *       Not included [NAN+P2P], [STA+NAN+P2P]
174      *
175      *   [{STA} <= 1, {STA,NAN} <= 1]
176      *       Optionally a STA and either a second STA or a NAN
177      *       [], [STA], [STA+NAN], [STA+STA], [NAN]
178      *       Not included [STA+STA+NAN]
179      */
180     public static class ChipConcurrencyCombination {
181         public final List<ChipConcurrencyCombinationLimit> limits;
182 
ChipConcurrencyCombination(List<ChipConcurrencyCombinationLimit> inLimits)183         public ChipConcurrencyCombination(List<ChipConcurrencyCombinationLimit> inLimits) {
184             limits = inLimits;
185         }
186 
187         @Override
toString()188         public String toString() {
189             return "{limits=" + limits + "}";
190         }
191     }
192 
193     /**
194      * A mode that the chip can be put in. A mode defines a set of constraints on
195      * the interfaces that can exist while in that mode. Modes define a unit of
196      * configuration where all interfaces must be torn down to switch to a
197      * different mode. Some HALs may only have a single mode, but an example where
198      * multiple modes would be required is if a chip has different firmwares with
199      * different capabilities.
200      *
201      * When in a mode, it must be possible to perform any combination of creating
202      * and removing interfaces as long as at least one of the
203      * ChipConcurrencyCombinations is satisfied. This means that if a chip has two
204      * available combinations, [{STA} <= 1] and [{AP_BRIDGED} <= 1] then it is expected
205      * that exactly one STA type or one AP_BRIDGED type can be created, but it
206      * is not expected that both a STA and AP_BRIDGED type  could be created. If it
207      * was then there would be a single available combination
208      * [{STA} <=1, {AP_BRIDGED} <= 1].
209      *
210      * When switching between two available combinations it is expected that
211      * interfaces only supported by the initial combination must be removed until
212      * the target combination is also satisfied. At that point new interfaces
213      * satisfying only the target combination can be added (meaning the initial
214      * combination limits will no longer satisfied). The addition of these new
215      * interfaces must not impact the existence of interfaces that satisfy both
216      * combinations.
217      *
218      * For example, a chip with available combinations:
219      *     [{STA} <= 2, {NAN} <=1] and [{STA} <=1, {NAN} <= 1, {AP_BRIDGED} <= 1}]
220      * If the chip currently has 3 interfaces STA, STA and NAN and wants to add an
221      * AP_BRIDGED interface in place of one of the STAs, then one of the STA interfaces
222      * must be removed first, and then the AP interface can be created after
223      * the STA has been torn down. During this process the remaining STA and NAN
224      * interfaces must not be removed/recreated.
225      *
226      * If a chip does not support this kind of reconfiguration in this mode then
227      * the combinations must be separated into two separate modes. Before
228      * switching modes, all interfaces must be torn down, the mode switch must be
229      * enacted, and when it completes the new interfaces must be brought up.
230      */
231     public static class ChipMode {
232         public final int id;
233         public final List<ChipConcurrencyCombination> availableCombinations;
234 
ChipMode(int inId, List<ChipConcurrencyCombination> inAvailableCombinations)235         public ChipMode(int inId, List<ChipConcurrencyCombination> inAvailableCombinations) {
236             id = inId;
237             availableCombinations = inAvailableCombinations;
238         }
239 
240         @Override
toString()241         public String toString() {
242             return "{id=" + id + ", availableCombinations=" + availableCombinations + "}";
243         }
244     }
245 
246     /**
247      * Wifi radio configuration.
248      */
249     public static class WifiRadioConfiguration {
250         public final @WifiScanner.WifiBand int bandInfo;
251         public final @WifiAntennaMode int antennaMode;
252 
WifiRadioConfiguration(int inBandInfo, int inAntennaMode)253         public WifiRadioConfiguration(int inBandInfo, int inAntennaMode) {
254             bandInfo = inBandInfo;
255             antennaMode = inAntennaMode;
256         }
257 
258         @Override
toString()259         public String toString() {
260             return "{bandInfo=" + bandInfo + ", antennaMode=" + antennaMode + "}";
261         }
262     }
263 
264     /**
265      * Wifi radio combination.
266      */
267     public static class WifiRadioCombination {
268         public final List<WifiRadioConfiguration> radioConfigurations;
269 
WifiRadioCombination(List<WifiRadioConfiguration> inRadioConfigurations)270         public WifiRadioCombination(List<WifiRadioConfiguration> inRadioConfigurations) {
271             radioConfigurations = inRadioConfigurations;
272         }
273 
274         @Override
toString()275         public String toString() {
276             return "{radioConfigurations=" + radioConfigurations + "}";
277         }
278     }
279 
280     /**
281      * Wifi Chip capabilities.
282      */
283     public static class WifiChipCapabilities {
284         /**
285          * Maximum number of links supported by the chip for MLO association.
286          *
287          * Note: This is a static configuration of the chip.
288          */
289         public final int maxMloAssociationLinkCount;
290         /**
291          * Maximum number of STR links used in Multi-Link Operation. The maximum
292          * number of STR links used for MLO can be different from the number of
293          * radios supported by the chip.
294          *
295          * Note: This is a static configuration of the chip.
296          */
297         public final int maxMloStrLinkCount;
298         /**
299          * Maximum number of concurrent TDLS sessions that can be enabled
300          * by framework via
301          * {@link android.hardware.wifi.supplicant.ISupplicantStaIface#initiateTdlsSetup(byte[])}.
302          */
303         public final int maxConcurrentTdlsSessionCount;
304 
WifiChipCapabilities(int maxMloAssociationLinkCount, int maxMloStrLinkCount, int maxConcurrentTdlsSessionCount)305         public WifiChipCapabilities(int maxMloAssociationLinkCount, int maxMloStrLinkCount,
306                 int maxConcurrentTdlsSessionCount) {
307             this.maxMloAssociationLinkCount = maxMloAssociationLinkCount;
308             this.maxMloStrLinkCount = maxMloStrLinkCount;
309             this.maxConcurrentTdlsSessionCount = maxConcurrentTdlsSessionCount;
310         }
311 
312         @Override
toString()313         public String toString() {
314             return "{maxMloAssociationLinkCount=" + maxMloAssociationLinkCount
315                     + ", maxMloStrLinkCount=" + maxMloStrLinkCount
316                     + ", maxConcurrentTdlsSessionCount=" + maxConcurrentTdlsSessionCount + "}";
317         }
318     }
319 
320     /**
321      * Information about the version of the driver and firmware running this chip.
322      *
323      * The information in these ASCII strings are vendor specific and does not
324      * need to follow any particular format. It may be dumped as part of the bug
325      * report.
326      */
327     public static class ChipDebugInfo {
328         public final String driverDescription;
329         public final String firmwareDescription;
330 
ChipDebugInfo(String inDriverDescription, String inFirmwareDescription)331         public ChipDebugInfo(String inDriverDescription, String inFirmwareDescription) {
332             driverDescription = inDriverDescription;
333             firmwareDescription = inFirmwareDescription;
334         }
335     }
336 
337     /**
338      * State of an iface operating on the radio chain (hardware MAC) on the device.
339      */
340     public static class IfaceInfo {
341         public final String name;
342         public final int channel;
343 
IfaceInfo(String inName, int inChannel)344         public IfaceInfo(String inName, int inChannel) {
345             name = inName;
346             channel = inChannel;
347         }
348     }
349 
350     /**
351      * State of a hardware radio chain (hardware MAC) on the device.
352      */
353     public static class RadioModeInfo {
354         public final int radioId;
355         public final @WifiScanner.WifiBand int bandInfo;
356         public final List<IfaceInfo> ifaceInfos;
357 
RadioModeInfo(int inRadioId, @WifiScanner.WifiBand int inBandInfo, List<IfaceInfo> inIfaceInfos)358         public RadioModeInfo(int inRadioId, @WifiScanner.WifiBand int inBandInfo,
359                 List<IfaceInfo> inIfaceInfos) {
360             radioId = inRadioId;
361             bandInfo = inBandInfo;
362             ifaceInfos = inIfaceInfos;
363         }
364     }
365 
366     /**
367      * Framework callback object. Will get called when the equivalent events are received
368      * from the HAL.
369      */
370     public interface Callback {
371         /**
372          * Indicates that a chip reconfiguration failed. This is a fatal
373          * error and any iface objects available previously must be considered
374          * invalid. The client can attempt to recover by trying to reconfigure the
375          * chip again using {@link IWifiChip#configureChip(int)}.
376          *
377          * @param status Failure reason code.
378          */
onChipReconfigureFailure(int status)379         void onChipReconfigureFailure(int status);
380 
381         /**
382          * Indicates that the chip has been reconfigured successfully. At
383          * this point, the interfaces available in the mode must be able to be
384          * configured. When this is called, any previous iface objects must be
385          * considered invalid.
386          *
387          * @param modeId The mode that the chip switched to, corresponding to the id
388          *        property of the target ChipMode.
389          */
onChipReconfigured(int modeId)390         void onChipReconfigured(int modeId);
391 
392         /**
393          * Indicates that the chip has encountered a fatal error.
394          * Client must not attempt to parse either the errorCode or debugData.
395          * Must only be captured in a bugreport.
396          *
397          * @param errorCode Vendor defined error code.
398          * @param debugData Vendor defined data used for debugging.
399          */
onDebugErrorAlert(int errorCode, byte[] debugData)400         void onDebugErrorAlert(int errorCode, byte[] debugData);
401 
402         /**
403          * Reports debug ring buffer data.
404          *
405          * The ring buffer data collection is event based:
406          * - Driver calls this callback when new records are available, the
407          *   |WifiDebugRingBufferStatus| passed up to framework in the callback
408          *   indicates to framework if more data is available in the ring buffer.
409          *   It is not expected that driver will necessarily always empty the ring
410          *   immediately as data is available. Instead the driver will report data
411          *   every X seconds, or if N bytes are available, based on the parameters
412          *   set via |startLoggingToDebugRingBuffer|.
413          * - In the case where a bug report has to be captured, the framework will
414          *   require driver to upload all data immediately. This is indicated to
415          *   driver when framework calls |forceDumpToDebugRingBuffer|. The driver
416          *   will start sending all available data in the indicated ring by repeatedly
417          *   invoking this callback.
418          *
419          * @param status Status of the corresponding ring buffer. This should
420          *         contain the name of the ring buffer on which the data is
421          *         available.
422          * @param data Raw bytes of data sent by the driver. Must be dumped
423          *         out to a bugreport and post processed.
424          */
onDebugRingBufferDataAvailable(WifiNative.RingBufferStatus status, byte[] data)425         void onDebugRingBufferDataAvailable(WifiNative.RingBufferStatus status, byte[] data);
426 
427         /**
428          * Indicates that a new iface has been added to the chip.
429          *
430          * @param type Type of iface added.
431          * @param name Name of iface added.
432          */
onIfaceAdded(@faceType int type, String name)433         void onIfaceAdded(@IfaceType int type, String name);
434 
435         /**
436          * Indicates that an existing iface has been removed from the chip.
437          *
438          * @param type Type of iface removed.
439          * @param name Name of iface removed.
440          */
onIfaceRemoved(@faceType int type, String name)441         void onIfaceRemoved(@IfaceType int type, String name);
442 
443         /**
444          * Indicates a radio mode change.
445          * Radio mode change could be a result of:
446          * a) Bringing up concurrent interfaces (ex. STA + AP).
447          * b) Change in operating band of one of the concurrent interfaces
448          * (ex. STA connection moved from 2.4G to 5G)
449          *
450          * @param radioModeInfos List of RadioModeInfo structures for each
451          *        radio chain (hardware MAC) on the device.
452          */
onRadioModeChange(List<RadioModeInfo> radioModeInfos)453         void onRadioModeChange(List<RadioModeInfo> radioModeInfos);
454     }
455 
WifiChip(@onNull android.hardware.wifi.V1_0.IWifiChip chip, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)456     public WifiChip(@NonNull android.hardware.wifi.V1_0.IWifiChip chip,
457             @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
458         mWifiChip = createWifiChipHidlImplMockable(chip, context, ssidTranslator);
459     }
460 
WifiChip(@onNull android.hardware.wifi.IWifiChip chip, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)461     public WifiChip(@NonNull android.hardware.wifi.IWifiChip chip,
462             @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
463         mWifiChip = createWifiChipAidlImplMockable(chip, context, ssidTranslator);
464     }
465 
createWifiChipHidlImplMockable( @onNull android.hardware.wifi.V1_0.IWifiChip chip, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)466     protected WifiChipHidlImpl createWifiChipHidlImplMockable(
467             @NonNull android.hardware.wifi.V1_0.IWifiChip chip,
468             @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
469         return new WifiChipHidlImpl(chip, context, ssidTranslator);
470     }
471 
createWifiChipAidlImplMockable( @onNull android.hardware.wifi.IWifiChip chip, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)472     protected WifiChipAidlImpl createWifiChipAidlImplMockable(
473             @NonNull android.hardware.wifi.IWifiChip chip,
474             @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
475         return new WifiChipAidlImpl(chip, context, ssidTranslator);
476     }
477 
validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier)478     private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
479         if (mWifiChip == null) {
480             Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiChip is null");
481             return defaultVal;
482         }
483         return supplier.get();
484     }
485 
486     /**
487      * See comments for {@link IWifiChip#configureChip(int)}
488      */
configureChip(int modeId)489     public boolean configureChip(int modeId) {
490         return validateAndCall("configureChip", false,
491                 () -> mWifiChip.configureChip(modeId));
492     }
493 
494     /**
495      * See comments for {@link IWifiChip#createApIface()}
496      */
497     @Nullable
createApIface()498     public WifiApIface createApIface() {
499         return validateAndCall("createApIface", null,
500                 () -> mWifiChip.createApIface());
501     }
502 
503     /**
504      * See comments for {@link IWifiChip#createBridgedApIface()}
505      */
506     @Nullable
createBridgedApIface()507     public WifiApIface createBridgedApIface() {
508         return validateAndCall("createBridgedApIface", null,
509                 () -> mWifiChip.createBridgedApIface());
510     }
511 
512     /**
513      * See comments for {@link IWifiChip#createNanIface()}
514      */
515     @Nullable
createNanIface()516     public WifiNanIface createNanIface() {
517         return validateAndCall("createNanIface", null,
518                 () -> mWifiChip.createNanIface());
519     }
520 
521     /**
522      * See comments for {@link IWifiChip#createP2pIface()}
523      */
524     @Nullable
createP2pIface()525     public WifiP2pIface createP2pIface() {
526         return validateAndCall("createP2pIface", null,
527                 () -> mWifiChip.createP2pIface());
528     }
529 
530     /**
531      * See comments for {@link IWifiChip#createRttController()}
532      */
533     @Nullable
createRttController()534     public WifiRttController createRttController() {
535         return validateAndCall("createRttController", null,
536                 () -> mWifiChip.createRttController());
537     }
538 
539     /**
540      * See comments for {@link IWifiChip#createStaIface()}
541      */
542     @Nullable
createStaIface()543     public WifiStaIface createStaIface() {
544         return validateAndCall("createStaIface", null,
545                 () -> mWifiChip.createStaIface());
546     }
547 
548     /**
549      * See comments for {@link IWifiChip#enableDebugErrorAlerts(boolean)}
550      */
enableDebugErrorAlerts(boolean enable)551     public boolean enableDebugErrorAlerts(boolean enable) {
552         return validateAndCall("enableDebugErrorAlerts", false,
553                 () -> mWifiChip.enableDebugErrorAlerts(enable));
554     }
555 
556     /**
557      * See comments for {@link IWifiChip#flushRingBufferToFile()}
558      */
flushRingBufferToFile()559     public boolean flushRingBufferToFile() {
560         return validateAndCall("flushRingBufferToFile", false,
561                 () -> mWifiChip.flushRingBufferToFile());
562     }
563 
564     /**
565      * See comments for {@link IWifiChip#forceDumpToDebugRingBuffer(String)}
566      */
forceDumpToDebugRingBuffer(String ringName)567     public boolean forceDumpToDebugRingBuffer(String ringName) {
568         return validateAndCall("forceDumpToDebugRingBuffer", false,
569                 () -> mWifiChip.forceDumpToDebugRingBuffer(ringName));
570     }
571 
572     /**
573      * See comments for {@link IWifiChip#getApIface(String)}
574      */
575     @Nullable
getApIface(String ifaceName)576     public WifiApIface getApIface(String ifaceName) {
577         return validateAndCall("getApIface", null,
578                 () -> mWifiChip.getApIface(ifaceName));
579     }
580 
581     /**
582      * See comments for {@link IWifiChip#getApIfaceNames()}
583      */
584     @Nullable
getApIfaceNames()585     public List<String> getApIfaceNames() {
586         return validateAndCall("getApIfaceNames", null,
587                 () -> mWifiChip.getApIfaceNames());
588     }
589 
590     /**
591      * See comments for {@link IWifiChip#getAvailableModes()}
592      */
593     @Nullable
getAvailableModes()594     public List<WifiChip.ChipMode> getAvailableModes() {
595         return validateAndCall("getAvailableModes", null,
596                 () -> mWifiChip.getAvailableModes());
597     }
598 
599     /**
600      * See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()}
601      */
getCapabilitiesBeforeIfacesExist()602     public Response<Long> getCapabilitiesBeforeIfacesExist() {
603         return validateAndCall("getCapabilitiesBeforeIfacesExist", new Response<>(0L),
604                 () -> mWifiChip.getCapabilitiesBeforeIfacesExist());
605     }
606 
607     /**
608      * See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()}
609      */
getCapabilitiesAfterIfacesExist()610     public Response<Long> getCapabilitiesAfterIfacesExist() {
611         return validateAndCall("getCapabilitiesAfterIfacesExist", new Response<>(0L),
612                 () -> mWifiChip.getCapabilitiesAfterIfacesExist());
613     }
614 
615     /**
616      * See comments for {@link IWifiChip#getDebugHostWakeReasonStats()}
617      */
618     @Nullable
getDebugHostWakeReasonStats()619     public WlanWakeReasonAndCounts getDebugHostWakeReasonStats() {
620         return validateAndCall("getDebugHostWakeReasonStats", null,
621                 () -> mWifiChip.getDebugHostWakeReasonStats());
622     }
623 
624     /**
625      * See comments for {@link IWifiChip#getDebugRingBuffersStatus()}
626      */
627     @Nullable
getDebugRingBuffersStatus()628     public List<WifiNative.RingBufferStatus> getDebugRingBuffersStatus() {
629         return validateAndCall("getDebugRingBuffersStatus", null,
630                 () -> mWifiChip.getDebugRingBuffersStatus());
631     }
632 
633     /**
634      * See comments for {@link IWifiChip#getId()}
635      */
getId()636     public int getId() {
637         return validateAndCall("getId", -1, () -> mWifiChip.getId());
638     }
639 
640     /**
641      * See comments for {@link IWifiChip#getMode()}
642      */
getMode()643     public Response<Integer> getMode() {
644         return validateAndCall("getMode", new Response<>(0), () -> mWifiChip.getMode());
645     }
646 
647     /**
648      * See comments for {@link IWifiChip#getNanIface(String)}
649      */
650     @Nullable
getNanIface(String ifaceName)651     public WifiNanIface getNanIface(String ifaceName) {
652         return validateAndCall("getNanIface", null,
653                 () -> mWifiChip.getNanIface(ifaceName));
654     }
655 
656     /**
657      * See comments for {@link IWifiChip#getNanIfaceNames()}
658      */
659     @Nullable
getNanIfaceNames()660     public List<String> getNanIfaceNames() {
661         return validateAndCall("getNanIfaceNames", null,
662                 () -> mWifiChip.getNanIfaceNames());
663     }
664 
665     /**
666      * See comments for {@link IWifiChip#getP2pIface(String)}
667      */
668     @Nullable
getP2pIface(String ifaceName)669     public WifiP2pIface getP2pIface(String ifaceName) {
670         return validateAndCall("getP2pIface", null,
671                 () -> mWifiChip.getP2pIface(ifaceName));
672     }
673 
674     /**
675      * See comments for {@link IWifiChip#getP2pIfaceNames()}
676      */
677     @Nullable
getP2pIfaceNames()678     public List<String> getP2pIfaceNames() {
679         return validateAndCall("getP2pIfaceNames", null,
680                 () -> mWifiChip.getP2pIfaceNames());
681     }
682 
683     /**
684      * See comments for {@link IWifiChip#getStaIface(String)}
685      */
686     @Nullable
getStaIface(String ifaceName)687     public WifiStaIface getStaIface(String ifaceName) {
688         return validateAndCall("getStaIface", null,
689                 () -> mWifiChip.getStaIface(ifaceName));
690     }
691 
692     /**
693      * See comments for {@link IWifiChip#getStaIfaceNames()}
694      */
695     @Nullable
getStaIfaceNames()696     public List<String> getStaIfaceNames() {
697         return validateAndCall("getStaIfaceNames", null,
698                 () -> mWifiChip.getStaIfaceNames());
699     }
700 
701     /**
702      * See comments for {@link IWifiChip#getSupportedRadioCombinations()}
703      */
704     @Nullable
getSupportedRadioCombinations()705     public List<WifiChip.WifiRadioCombination> getSupportedRadioCombinations() {
706         return validateAndCall("getSupportedRadioCombinations", null,
707                 () -> mWifiChip.getSupportedRadioCombinations());
708     }
709 
710     /**
711      * See comments for {@link IWifiChip#getWifiChipCapabilities()}
712      */
713     @Nullable
getWifiChipCapabilities()714     public WifiChipCapabilities getWifiChipCapabilities() {
715         return validateAndCall("getWifiChipCapabilities", null,
716                 () -> mWifiChip.getWifiChipCapabilities());
717     }
718 
719     /**
720      * See comments for {@link IWifiChip#getUsableChannels(int, int, int)}
721      */
722     @Nullable
getUsableChannels(@ifiScanner.WifiBand int band, @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter)723     public List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band,
724             @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter) {
725         return validateAndCall("getUsableChannels", null,
726                 () -> mWifiChip.getUsableChannels(band, mode, filter));
727     }
728 
729     /**
730      * See comments for {@link IWifiChip#registerCallback(Callback)}
731      */
registerCallback(WifiChip.Callback callback)732     public boolean registerCallback(WifiChip.Callback callback) {
733         return validateAndCall("registerCallback", false,
734                 () -> mWifiChip.registerCallback(callback));
735     }
736 
737     /**
738      * See comments for {@link IWifiChip#removeApIface(String)}
739      */
removeApIface(String ifaceName)740     public boolean removeApIface(String ifaceName) {
741         return validateAndCall("removeApIface", false,
742                 () -> mWifiChip.removeApIface(ifaceName));
743     }
744 
745     /**
746      * See comments for {@link IWifiChip#removeIfaceInstanceFromBridgedApIface(String, String)}
747      */
removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName)748     public boolean removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName) {
749         return validateAndCall("removeIfaceInstanceFromBridgedApIface", false,
750                 () -> mWifiChip.removeIfaceInstanceFromBridgedApIface(brIfaceName, ifaceName));
751     }
752 
753     /**
754      * See comments for {@link IWifiChip#removeNanIface(String)}
755      */
removeNanIface(String ifaceName)756     public boolean removeNanIface(String ifaceName) {
757         return validateAndCall("removeNanIface", false,
758                 () -> mWifiChip.removeNanIface(ifaceName));
759     }
760 
761     /**
762      * See comments for {@link IWifiChip#removeP2pIface(String)}
763      */
removeP2pIface(String ifaceName)764     public boolean removeP2pIface(String ifaceName) {
765         return validateAndCall("removeP2pIface", false,
766                 () -> mWifiChip.removeP2pIface(ifaceName));
767     }
768 
769     /**
770      * See comments for {@link IWifiChip#removeStaIface(String)}
771      */
removeStaIface(String ifaceName)772     public boolean removeStaIface(String ifaceName) {
773         return validateAndCall("removeStaIface", false,
774                 () -> mWifiChip.removeStaIface(ifaceName));
775     }
776 
777     /**
778      * See comments for {@link IWifiChip#requestChipDebugInfo()}
779      */
780     @Nullable
requestChipDebugInfo()781     public WifiChip.ChipDebugInfo requestChipDebugInfo() {
782         return validateAndCall("requestChipDebugInfo", null,
783                 () -> mWifiChip.requestChipDebugInfo());
784     }
785 
786     /**
787      * See comments for {@link IWifiChip#requestDriverDebugDump()}
788      */
789     @Nullable
requestDriverDebugDump()790     public byte[] requestDriverDebugDump() {
791         return validateAndCall("requestDriverDebugDump", null,
792                 () -> mWifiChip.requestDriverDebugDump());
793     }
794 
795     /**
796      * See comments for {@link IWifiChip#requestFirmwareDebugDump()}
797      */
798     @Nullable
requestFirmwareDebugDump()799     public byte[] requestFirmwareDebugDump() {
800         return validateAndCall("requestFirmwareDebugDump", null,
801                 () -> mWifiChip.requestFirmwareDebugDump());
802     }
803 
804     /**
805      * See comments for {@link IWifiChip#selectTxPowerScenario(SarInfo)}
806      */
selectTxPowerScenario(SarInfo sarInfo)807     public boolean selectTxPowerScenario(SarInfo sarInfo) {
808         return validateAndCall("selectTxPowerScenario", false,
809                 () -> mWifiChip.selectTxPowerScenario(sarInfo));
810     }
811 
812     /**
813      * See comments for {@link IWifiChip#setCoexUnsafeChannels(List, int)}
814      */
setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions)815     public boolean setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions) {
816         return validateAndCall("setCoexUnsafeChannels", false,
817                 () -> mWifiChip.setCoexUnsafeChannels(unsafeChannels, restrictions));
818     }
819 
820     /**
821      * See comments for {@link IWifiChip#setCountryCode(byte[])}
822      */
setCountryCode(String countryCode)823     public boolean setCountryCode(String countryCode) {
824         if (countryCode == null || countryCode.length() != 2) {
825             Log.e(TAG, "Invalid country code " + countryCode);
826             return false;
827         }
828         try {
829             final byte[] code = NativeUtil.stringToByteArray(countryCode);
830             return validateAndCall("setCountryCode", false,
831                     () -> mWifiChip.setCountryCode(code));
832         } catch (IllegalArgumentException e) {
833             Log.e(TAG, "Invalid country code " + countryCode + ", error: " + e);
834             return false;
835         }
836     }
837 
838     /**
839      * See comments for {@link IWifiChip#setLowLatencyMode(boolean)}
840      */
setLowLatencyMode(boolean enable)841     public boolean setLowLatencyMode(boolean enable) {
842         return validateAndCall("setLowLatencyMode", false,
843                 () -> mWifiChip.setLowLatencyMode(enable));
844     }
845 
846     /**
847      * See comments for {@link IWifiChip#setMultiStaPrimaryConnection(String)}
848      */
setMultiStaPrimaryConnection(String ifaceName)849     public boolean setMultiStaPrimaryConnection(String ifaceName) {
850         return validateAndCall("setMultiStaPrimaryConnection", false,
851                 () -> mWifiChip.setMultiStaPrimaryConnection(ifaceName));
852     }
853 
854     /**
855      * See comments for {@link IWifiChip#setMultiStaUseCase(int)}
856      */
setMultiStaUseCase(@ifiNative.MultiStaUseCase int useCase)857     public boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) {
858         return validateAndCall("setMultiStaUseCase", false,
859                 () -> mWifiChip.setMultiStaUseCase(useCase));
860     }
861 
862     /**
863      * See comments for {@link IWifiChip#startLoggingToDebugRingBuffer(String, int, int, int)}
864      */
startLoggingToDebugRingBuffer(String ringName, int verboseLevel, int maxIntervalInSec, int minDataSizeInBytes)865     public boolean startLoggingToDebugRingBuffer(String ringName, int verboseLevel,
866             int maxIntervalInSec, int minDataSizeInBytes) {
867         return validateAndCall("startLoggingToDebugRingBuffer", false,
868                 () -> mWifiChip.startLoggingToDebugRingBuffer(ringName, verboseLevel,
869                         maxIntervalInSec, minDataSizeInBytes));
870     }
871 
872     /**
873      * See comments for {@link IWifiChip#stopLoggingToDebugRingBuffer()}
874      */
stopLoggingToDebugRingBuffer()875     public boolean stopLoggingToDebugRingBuffer() {
876         return validateAndCall("stopLoggingToDebugRingBuffer", false,
877                 () -> mWifiChip.stopLoggingToDebugRingBuffer());
878     }
879 
880     /**
881      * See comments for {@link IWifiChip#triggerSubsystemRestart()}
882      */
triggerSubsystemRestart()883     public boolean triggerSubsystemRestart() {
884         return validateAndCall("triggerSubsystemRestart", false,
885                 () -> mWifiChip.triggerSubsystemRestart());
886     }
887 
888     /**
889      * See comments for {@link IWifiChip#setMloMode(int)}.
890      */
setMloMode(@ifiManager.MloMode int mode)891     public @WifiStatusCode int setMloMode(@WifiManager.MloMode int mode) {
892         return validateAndCall("setMloMode", WifiStatusCode.ERROR_NOT_STARTED,
893                 () -> mWifiChip.setMloMode(mode));
894     }
895 
896     /**
897      * See comments for {@link IWifiChip#enableStaChannelForPeerNetwork(boolean, boolean)}
898      */
enableStaChannelForPeerNetwork(boolean enableIndoorChannel, boolean enableDfsChannel)899     public boolean enableStaChannelForPeerNetwork(boolean enableIndoorChannel,
900             boolean enableDfsChannel) {
901         return validateAndCall("enableStaChannelForPeerNetwork", false,
902                 () -> mWifiChip.enableStaChannelForPeerNetwork(enableIndoorChannel,
903                         enableDfsChannel));
904     }
905 }
906