• 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 static android.net.wifi.WifiManager.ROAMING_MODE_NORMAL;
20 
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.content.Context;
24 import android.hardware.wifi.WifiStatusCode;
25 import android.net.MacAddress;
26 import android.net.apf.ApfCapabilities;
27 import android.net.wifi.ScanResult;
28 import android.net.wifi.WifiManager.RoamingMode;
29 import android.net.wifi.WifiScanner;
30 import android.net.wifi.twt.TwtRequest;
31 import android.net.wifi.twt.TwtSessionCallback;
32 import android.os.Bundle;
33 import android.util.Log;
34 
35 import com.android.server.wifi.SsidTranslator;
36 import com.android.server.wifi.WifiLinkLayerStats;
37 import com.android.server.wifi.WifiNative;
38 
39 import java.util.ArrayList;
40 import java.util.BitSet;
41 import java.util.List;
42 import java.util.function.Supplier;
43 
44 /**
45  * Wrapper around a WifiStaIface.
46  * May be initialized using a HIDL or AIDL WifiStaIface.
47  */
48 public class WifiStaIface implements WifiHal.WifiInterface {
49     private static final String TAG = "WifiStaIface";
50     private final IWifiStaIface mWifiStaIface;
51 
52     public static final int SET_ROAMING_STATE_FAILURE_CODE =
53             WifiNative.SET_FIRMWARE_ROAMING_FAILURE;
54 
55     /**
56      * Parameters for a background scan request.
57      */
58     public static class StaBackgroundScanParameters {
59         public int basePeriodInMs;
60         public int maxApPerScan;
61         public int reportThresholdPercent;
62         public int reportThresholdNumScans;
63         public List<WifiNative.BucketSettings> buckets;
64 
StaBackgroundScanParameters(int inBasePeriodInMs, int inMaxApPerScan, int inReportThresholdPercent, int inReportThresholdNumScans, List<WifiNative.BucketSettings> inBuckets)65         public StaBackgroundScanParameters(int inBasePeriodInMs, int inMaxApPerScan,
66                 int inReportThresholdPercent, int inReportThresholdNumScans,
67                 List<WifiNative.BucketSettings> inBuckets) {
68             basePeriodInMs = inBasePeriodInMs;
69             maxApPerScan = inMaxApPerScan;
70             reportThresholdPercent = inReportThresholdPercent;
71             reportThresholdNumScans = inReportThresholdNumScans;
72             buckets = inBuckets;
73         }
74     }
75 
76     /**
77      * Framework callback object. Will get called when the equivalent events are received
78      * from the HAL.
79      */
80     public interface Callback {
81         /**
82          * Called for each received beacon/probe response for a scan with the
83          * |REPORT_EVENTS_FULL_RESULTS| flag set in
84          * |StaBackgroundScanBucketParameters.eventReportScheme|.
85          *
86          * @param cmdId Command ID corresponding to the request.
87          * @param bucketsScanned Bitset where each bit indicates if the bucket with
88          *        that index (starting at 0) was scanned.
89          * @param result Full scan result for an AP.
90          */
onBackgroundFullScanResult(int cmdId, int bucketsScanned, ScanResult result)91         void onBackgroundFullScanResult(int cmdId, int bucketsScanned, ScanResult result);
92 
93         /**
94          * Callback indicating that an ongoing background scan request has failed.
95          * The background scan needs to be restarted to continue scanning.
96          *
97          * @param cmdId Command ID corresponding to the request.
98          */
onBackgroundScanFailure(int cmdId)99         void onBackgroundScanFailure(int cmdId);
100 
101         /**
102          * Called when the |StaBackgroundScanBucketParameters.eventReportScheme| flags
103          * for at least one bucket that was just scanned was |REPORT_EVENTS_EACH_SCAN|,
104          * or one of the configured thresholds was breached.
105          *
106          * @param cmdId Command ID corresponding to the request.
107          * @param scanDatas List of scan results for all APs seen since the last callback.
108          */
onBackgroundScanResults(int cmdId, WifiScanner.ScanData[] scanDatas)109         void onBackgroundScanResults(int cmdId, WifiScanner.ScanData[] scanDatas);
110 
111         /**
112          * Called when the RSSI of the currently connected access point goes beyond the
113          * thresholds set via
114          * {@link IWifiStaIface#startRssiMonitoring(int, int, int)}
115          *
116          * @param cmdId Command ID corresponding to the request.
117          * @param currBssid BSSID of the currently connected access point.
118          * @param currRssi RSSI of the currently connected access point.
119          */
onRssiThresholdBreached(int cmdId, byte[] currBssid, int currRssi)120         void onRssiThresholdBreached(int cmdId, byte[] currBssid, int currRssi);
121 
122         /**
123          * Called when TWT operation fails.
124          *
125          * @param cmdId Unique command id which is failed
126          * @param twtErrorCode Error code
127          */
onTwtFailure(int cmdId, @TwtSessionCallback.TwtErrorCode int twtErrorCode)128         void onTwtFailure(int cmdId, @TwtSessionCallback.TwtErrorCode int twtErrorCode);
129 
130         /**
131          * Called when {@link WifiStaIface#setupTwtSession(int, TwtRequest)} succeeds.
132          *
133          * @param cmdId Unique command id used in
134          *              {@link WifiStaIface#setupTwtSession(int, TwtRequest)}
135          * @param wakeDurationUs TWT wake duration for the session in microseconds
136          * @param wakeIntervalUs TWT wake interval for the session in microseconds
137          * @param linkId Multi link operation link id
138          * @param sessionId TWT session id
139          */
onTwtSessionCreate(int cmdId, int wakeDurationUs, long wakeIntervalUs, int linkId, int sessionId)140         void onTwtSessionCreate(int cmdId, int wakeDurationUs, long wakeIntervalUs, int linkId,
141                 int sessionId);
142 
143         /**
144          * Called when TWT session is torndown by {@link WifiStaIface#tearDownTwtSession(int, int)}.
145          * Can also be called unsolicitedly by the vendor software with proper reason code.
146          *
147          * @param cmdId Unique command id used in {@link WifiStaIface#tearDownTwtSession(int, int)}
148          * @param twtSessionId TWT session Id
149          * @param twtReasonCode Reason code for teardown
150          */
onTwtSessionTeardown(int cmdId, int twtSessionId, @TwtSessionCallback.TwtReasonCode int twtReasonCode)151         void onTwtSessionTeardown(int cmdId, int twtSessionId,
152                 @TwtSessionCallback.TwtReasonCode int twtReasonCode);
153 
154         /**
155          * Called as a response to {@link WifiStaIface#getStatsTwtSession(int, int)}
156          *
157          * @param cmdId Unique command id used in {@link WifiStaIface#getStatsTwtSession(int, int)}
158          * @param twtSessionId TWT session Id
159          * @param twtStats TWT stats bundle
160          */
onTwtSessionStats(int cmdId, int twtSessionId, Bundle twtStats)161         void onTwtSessionStats(int cmdId, int twtSessionId, Bundle twtStats);
162     }
163 
WifiStaIface(@onNull android.hardware.wifi.V1_0.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)164     public WifiStaIface(@NonNull android.hardware.wifi.V1_0.IWifiStaIface staIface,
165             @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
166         mWifiStaIface = createWifiStaIfaceHidlImplMockable(staIface, context, ssidTranslator);
167     }
168 
WifiStaIface(@onNull android.hardware.wifi.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)169     public WifiStaIface(@NonNull android.hardware.wifi.IWifiStaIface staIface,
170             @NonNull Context context, @NonNull SsidTranslator ssidTranslator) {
171         mWifiStaIface = createWifiStaIfaceAidlImplMockable(staIface, context, ssidTranslator);
172     }
173 
createWifiStaIfaceHidlImplMockable( android.hardware.wifi.V1_0.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)174     protected WifiStaIfaceHidlImpl createWifiStaIfaceHidlImplMockable(
175             android.hardware.wifi.V1_0.IWifiStaIface staIface, @NonNull Context context,
176             @NonNull SsidTranslator ssidTranslator) {
177         return new WifiStaIfaceHidlImpl(staIface, context, ssidTranslator);
178     }
179 
createWifiStaIfaceAidlImplMockable( android.hardware.wifi.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)180     protected WifiStaIfaceAidlImpl createWifiStaIfaceAidlImplMockable(
181             android.hardware.wifi.IWifiStaIface staIface, @NonNull Context context,
182             @NonNull SsidTranslator ssidTranslator) {
183         return new WifiStaIfaceAidlImpl(staIface, context, ssidTranslator);
184     }
185 
validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier)186     private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) {
187         if (mWifiStaIface == null) {
188             Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiStaIface is null");
189             return defaultVal;
190         }
191         return supplier.get();
192     }
193 
194     /**
195      * See comments for {@link IWifiStaIface#registerFrameworkCallback(Callback)}
196      */
registerFrameworkCallback(Callback callback)197     public boolean registerFrameworkCallback(Callback callback) {
198         return validateAndCall("registerFrameworkCallback", false,
199                 () -> mWifiStaIface.registerFrameworkCallback(callback));
200     }
201 
202     /**
203      * See comments for {@link IWifiStaIface#getName()}
204      */
205     @Override
206     @Nullable
getName()207     public String getName() {
208         return validateAndCall("getName", null,
209                 () -> mWifiStaIface.getName());
210     }
211 
212     /**
213      * See comments for {@link IWifiStaIface#configureRoaming(List, List)}
214      */
configureRoaming(List<MacAddress> bssidBlocklist, List<byte[]> ssidAllowlist)215     public boolean configureRoaming(List<MacAddress> bssidBlocklist,
216             List<byte[]> ssidAllowlist) {
217         return validateAndCall("configureRoaming", false,
218                 () -> mWifiStaIface.configureRoaming(bssidBlocklist, ssidAllowlist));
219     }
220 
221     /**
222      * See comments for {@link IWifiStaIface#enableLinkLayerStatsCollection(boolean)}
223      */
enableLinkLayerStatsCollection(boolean debug)224     public boolean enableLinkLayerStatsCollection(boolean debug) {
225         return validateAndCall("enableLinkLayerStatsCollection", false,
226                 () -> mWifiStaIface.enableLinkLayerStatsCollection(debug));
227     }
228 
229     /**
230      * See comments for {@link IWifiStaIface#enableNdOffload(boolean)}
231      */
enableNdOffload(boolean enable)232     public boolean enableNdOffload(boolean enable) {
233         return validateAndCall("enableNdOffload", false,
234                 () -> mWifiStaIface.enableNdOffload(enable));
235     }
236 
237     /**
238      * See comments for {@link IWifiStaIface#getApfPacketFilterCapabilities()}
239      */
getApfPacketFilterCapabilities()240     public ApfCapabilities getApfPacketFilterCapabilities() {
241         return validateAndCall("getApfPacketFilterCapabilities", new ApfCapabilities(0, 0, 0),
242                 () -> mWifiStaIface.getApfPacketFilterCapabilities());
243     }
244 
245     /**
246      * See comments for {@link IWifiStaIface#getBackgroundScanCapabilities()}
247      */
248     @Nullable
getBackgroundScanCapabilities()249     public WifiNative.ScanCapabilities getBackgroundScanCapabilities() {
250         return validateAndCall("getBackgroundScanCapabilities", null,
251                 () -> mWifiStaIface.getBackgroundScanCapabilities());
252     }
253 
254     /**
255      * See comments for {@link IWifiStaIface#getCapabilities()}
256      */
getCapabilities()257     public BitSet getCapabilities() {
258         return validateAndCall("getCapabilities", new BitSet(),
259                 () -> mWifiStaIface.getCapabilities());
260     }
261 
262     /**
263      * See comments for {@link IWifiStaIface#getDebugRxPacketFates()}
264      */
getDebugRxPacketFates()265     public List<WifiNative.RxFateReport> getDebugRxPacketFates() {
266         return validateAndCall("getDebugRxPacketFates", new ArrayList<>(),
267                 () -> mWifiStaIface.getDebugRxPacketFates());
268     }
269 
270     /**
271      * See comments for {@link IWifiStaIface#getDebugTxPacketFates()}
272      */
getDebugTxPacketFates()273     public List<WifiNative.TxFateReport> getDebugTxPacketFates() {
274         return validateAndCall("getDebugTxPacketFates", new ArrayList<>(),
275                 () -> mWifiStaIface.getDebugTxPacketFates());
276     }
277 
278     /**
279      * See comments for {@link IWifiStaIface#getFactoryMacAddress()}
280      */
281     @Nullable
getFactoryMacAddress()282     public MacAddress getFactoryMacAddress() {
283         return validateAndCall("getFactoryMacAddress", null,
284                 () -> mWifiStaIface.getFactoryMacAddress());
285     }
286 
287     /**
288      * See comments for {@link IWifiStaIface#getCachedScanData()}
289      */
290     @Nullable
getCachedScanData()291     public WifiScanner.ScanData getCachedScanData() {
292         return validateAndCall("getCachedScanData", null,
293                 () -> mWifiStaIface.getCachedScanData());
294     }
295 
296 
297     /**
298      * See comments for {@link IWifiStaIface#getLinkLayerStats()}
299      */
300     @Nullable
getLinkLayerStats()301     public WifiLinkLayerStats getLinkLayerStats() {
302         return validateAndCall("getLinkLayerStats", null,
303                 () -> mWifiStaIface.getLinkLayerStats());
304     }
305 
306     /**
307      * See comments for {@link IWifiStaIface#getRoamingCapabilities()}
308      */
309     @Nullable
getRoamingCapabilities()310     public WifiNative.RoamingCapabilities getRoamingCapabilities() {
311         return validateAndCall("getRoamingCapabilities", null,
312                 () -> mWifiStaIface.getRoamingCapabilities());
313     }
314 
315     /**
316      * See comments for {@link IWifiStaIface#installApfPacketFilter(byte[])}
317      */
installApfPacketFilter(byte[] program)318     public boolean installApfPacketFilter(byte[] program) {
319         return validateAndCall("installApfPacketFilter", false,
320                 () -> mWifiStaIface.installApfPacketFilter(program));
321     }
322 
323     /**
324      * See comments for {@link IWifiStaIface#readApfPacketFilterData()}
325      */
326     @Nullable
readApfPacketFilterData()327     public byte[] readApfPacketFilterData() {
328         return validateAndCall("readApfPacketFilterData", null,
329                 () -> mWifiStaIface.readApfPacketFilterData());
330     }
331 
332     /**
333      * See comments for {@link IWifiStaIface#setMacAddress(MacAddress)}
334      */
setMacAddress(MacAddress mac)335     public boolean setMacAddress(MacAddress mac) {
336         return validateAndCall("setMacAddress", false,
337                 () -> mWifiStaIface.setMacAddress(mac));
338     }
339 
340     /**
341      * See comments for {@link IWifiStaIface#setRoamingState(int)}
342      */
setRoamingState( @ifiNative.RoamingEnableState int state)343     public @WifiNative.RoamingEnableStatus int setRoamingState(
344             @WifiNative.RoamingEnableState int state) {
345         return validateAndCall("setRoamingState", SET_ROAMING_STATE_FAILURE_CODE,
346                 () -> mWifiStaIface.setRoamingState(state));
347     }
348 
349     /**
350      * See comments for {@link IWifiStaIface#setScanMode(boolean)}
351      */
setScanMode(boolean enable)352     public boolean setScanMode(boolean enable) {
353         return validateAndCall("setScanMode", false,
354                 () -> mWifiStaIface.setScanMode(enable));
355     }
356 
357     /**
358      * See comments for {@link IWifiStaIface#startBackgroundScan(int, StaBackgroundScanParameters)}
359      */
startBackgroundScan(int cmdId, StaBackgroundScanParameters params)360     public boolean startBackgroundScan(int cmdId, StaBackgroundScanParameters params) {
361         return validateAndCall("startBackgroundScan", false,
362                 () -> mWifiStaIface.startBackgroundScan(cmdId, params));
363     }
364 
365     /**
366      * See comments for {@link IWifiStaIface#startDebugPacketFateMonitoring()}
367      */
startDebugPacketFateMonitoring()368     public boolean startDebugPacketFateMonitoring() {
369         return validateAndCall("startDebugPacketFateMonitoring", false,
370                 () -> mWifiStaIface.startDebugPacketFateMonitoring());
371     }
372 
373     /**
374      * See comments for {@link IWifiStaIface#startRssiMonitoring(int, int, int)}
375      */
startRssiMonitoring(int cmdId, int maxRssi, int minRssi)376     public boolean startRssiMonitoring(int cmdId, int maxRssi, int minRssi) {
377         return validateAndCall("startRssiMonitoring", false,
378                 () -> mWifiStaIface.startRssiMonitoring(cmdId, maxRssi, minRssi));
379     }
380 
381     /**
382      * See comments for {@link IWifiStaIface#startSendingKeepAlivePackets(int, byte[], int,
383      *                         MacAddress, MacAddress, int)}
384      */
startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType, MacAddress srcAddress, MacAddress dstAddress, int periodInMs)385     public boolean startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType,
386             MacAddress srcAddress, MacAddress dstAddress, int periodInMs) {
387         return validateAndCall("startSendingKeepAlivePackets", false,
388                 () -> mWifiStaIface.startSendingKeepAlivePackets(cmdId, ipPacketData, etherType,
389                         srcAddress, dstAddress, periodInMs));
390     }
391 
392     /**
393      * See comments for {@link IWifiStaIface#stopBackgroundScan(int)}
394      */
stopBackgroundScan(int cmdId)395     public boolean stopBackgroundScan(int cmdId) {
396         return validateAndCall("stopBackgroundScan", false,
397                 () -> mWifiStaIface.stopBackgroundScan(cmdId));
398     }
399 
400     /**
401      * See comments for {@link IWifiStaIface#stopRssiMonitoring(int)}
402      */
stopRssiMonitoring(int cmdId)403     public boolean stopRssiMonitoring(int cmdId) {
404         return validateAndCall("stopRssiMonitoring", false,
405                 () -> mWifiStaIface.stopRssiMonitoring(cmdId));
406     }
407 
408     /**
409      * See comments for {@link IWifiStaIface#stopSendingKeepAlivePackets(int)}
410      */
stopSendingKeepAlivePackets(int cmdId)411     public boolean stopSendingKeepAlivePackets(int cmdId) {
412         return validateAndCall("stopSendingKeepAlivePackets", false,
413                 () -> mWifiStaIface.stopSendingKeepAlivePackets(cmdId));
414     }
415 
416     /**
417      * See comments for {@link IWifiStaIface#setDtimMultiplier(int)}
418      */
setDtimMultiplier(int multiplier)419     public boolean setDtimMultiplier(int multiplier) {
420         return validateAndCall("setDtimMultiplier", false,
421                 () -> mWifiStaIface.setDtimMultiplier(multiplier));
422     }
423 
424     /**
425      * See comments for {@link IWifiStaIface#setRoamingMode(int)}
426      */
setRoamingMode(@oamingMode int roamingMode)427     public @WifiStatusCode int setRoamingMode(@RoamingMode int roamingMode) {
428         return validateAndCall("setRoamingMode", ROAMING_MODE_NORMAL,
429                 () -> mWifiStaIface.setRoamingMode(roamingMode));
430     }
431 
432     /**
433      * See {@link IWifiStaIface#getTwtCapabilities()}
434      */
getTwtCapabilities()435     public Bundle getTwtCapabilities() {
436         return validateAndCall("getTwtCapabilities", null,
437                 () -> mWifiStaIface.getTwtCapabilities());
438     }
439 
440     /**
441      * See {@link IWifiStaIface#setupTwtSession(int, TwtRequest)}
442      */
setupTwtSession(int cmdId, TwtRequest twtRequest)443     public boolean setupTwtSession(int cmdId, TwtRequest twtRequest) {
444         return validateAndCall("setupTwtSession", false,
445                 () -> mWifiStaIface.setupTwtSession(cmdId, twtRequest));
446     }
447 
448     /**
449      * See {@link IWifiStaIface#tearDownTwtSession(int, int)}
450      */
tearDownTwtSession(int commandId, int sessionId)451     public boolean tearDownTwtSession(int commandId, int sessionId) {
452         return validateAndCall("tearDownTwtSession", false,
453                 () -> mWifiStaIface.tearDownTwtSession(commandId, sessionId));
454     }
455 
456     /**
457      * See {@link IWifiStaIface#getStatsTwtSession(int, int)}
458      */
getStatsTwtSession(int commandId, int sessionId)459     public boolean getStatsTwtSession(int commandId, int sessionId) {
460         return validateAndCall("getStatsTwtSession", false,
461                 () -> mWifiStaIface.getStatsTwtSession(commandId, sessionId));
462     }
463 }
464 
465