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