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