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