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.NonNull; 20 import android.annotation.Nullable; 21 import android.content.Context; 22 import android.net.MacAddress; 23 import android.net.apf.ApfCapabilities; 24 import android.net.wifi.ScanResult; 25 import android.net.wifi.WifiScanner; 26 import android.util.Log; 27 28 import com.android.server.wifi.SsidTranslator; 29 import com.android.server.wifi.WifiLinkLayerStats; 30 import com.android.server.wifi.WifiNative; 31 32 import java.util.ArrayList; 33 import java.util.List; 34 import java.util.function.Supplier; 35 36 /** 37 * Wrapper around a WifiStaIface. 38 * May be initialized using a HIDL or AIDL WifiStaIface. 39 */ 40 public class WifiStaIface implements WifiHal.WifiInterface { 41 private static final String TAG = "WifiStaIface"; 42 private final IWifiStaIface mWifiStaIface; 43 44 public static final int SET_ROAMING_STATE_FAILURE_CODE = 45 WifiNative.SET_FIRMWARE_ROAMING_FAILURE; 46 47 /** 48 * Parameters for a background scan request. 49 */ 50 public static class StaBackgroundScanParameters { 51 public int basePeriodInMs; 52 public int maxApPerScan; 53 public int reportThresholdPercent; 54 public int reportThresholdNumScans; 55 public List<WifiNative.BucketSettings> buckets; 56 StaBackgroundScanParameters(int inBasePeriodInMs, int inMaxApPerScan, int inReportThresholdPercent, int inReportThresholdNumScans, List<WifiNative.BucketSettings> inBuckets)57 public StaBackgroundScanParameters(int inBasePeriodInMs, int inMaxApPerScan, 58 int inReportThresholdPercent, int inReportThresholdNumScans, 59 List<WifiNative.BucketSettings> inBuckets) { 60 basePeriodInMs = inBasePeriodInMs; 61 maxApPerScan = inMaxApPerScan; 62 reportThresholdPercent = inReportThresholdPercent; 63 reportThresholdNumScans = inReportThresholdNumScans; 64 buckets = inBuckets; 65 } 66 } 67 68 /** 69 * Framework callback object. Will get called when the equivalent events are received 70 * from the HAL. 71 */ 72 public interface Callback { 73 /** 74 * Called for each received beacon/probe response for a scan with the 75 * |REPORT_EVENTS_FULL_RESULTS| flag set in 76 * |StaBackgroundScanBucketParameters.eventReportScheme|. 77 * 78 * @param cmdId Command ID corresponding to the request. 79 * @param bucketsScanned Bitset where each bit indicates if the bucket with 80 * that index (starting at 0) was scanned. 81 * @param result Full scan result for an AP. 82 */ onBackgroundFullScanResult(int cmdId, int bucketsScanned, ScanResult result)83 void onBackgroundFullScanResult(int cmdId, int bucketsScanned, ScanResult result); 84 85 /** 86 * Callback indicating that an ongoing background scan request has failed. 87 * The background scan needs to be restarted to continue scanning. 88 * 89 * @param cmdId Command ID corresponding to the request. 90 */ onBackgroundScanFailure(int cmdId)91 void onBackgroundScanFailure(int cmdId); 92 93 /** 94 * Called when the |StaBackgroundScanBucketParameters.eventReportScheme| flags 95 * for at least one bucket that was just scanned was |REPORT_EVENTS_EACH_SCAN|, 96 * or one of the configured thresholds was breached. 97 * 98 * @param cmdId Command ID corresponding to the request. 99 * @param scanDatas List of scan results for all APs seen since the last callback. 100 */ onBackgroundScanResults(int cmdId, WifiScanner.ScanData[] scanDatas)101 void onBackgroundScanResults(int cmdId, WifiScanner.ScanData[] scanDatas); 102 103 /** 104 * Called when the RSSI of the currently connected access point goes beyond the 105 * thresholds set via 106 * {@link IWifiStaIface#startRssiMonitoring(int, int, int)} 107 * 108 * @param cmdId Command ID corresponding to the request. 109 * @param currBssid BSSID of the currently connected access point. 110 * @param currRssi RSSI of the currently connected access point. 111 */ onRssiThresholdBreached(int cmdId, byte[] currBssid, int currRssi)112 void onRssiThresholdBreached(int cmdId, byte[] currBssid, int currRssi); 113 } 114 WifiStaIface(@onNull android.hardware.wifi.V1_0.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)115 public WifiStaIface(@NonNull android.hardware.wifi.V1_0.IWifiStaIface staIface, 116 @NonNull Context context, @NonNull SsidTranslator ssidTranslator) { 117 mWifiStaIface = createWifiStaIfaceHidlImplMockable(staIface, context, ssidTranslator); 118 } 119 WifiStaIface(@onNull android.hardware.wifi.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)120 public WifiStaIface(@NonNull android.hardware.wifi.IWifiStaIface staIface, 121 @NonNull Context context, @NonNull SsidTranslator ssidTranslator) { 122 mWifiStaIface = createWifiStaIfaceAidlImplMockable(staIface, context, ssidTranslator); 123 } 124 createWifiStaIfaceHidlImplMockable( android.hardware.wifi.V1_0.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)125 protected WifiStaIfaceHidlImpl createWifiStaIfaceHidlImplMockable( 126 android.hardware.wifi.V1_0.IWifiStaIface staIface, @NonNull Context context, 127 @NonNull SsidTranslator ssidTranslator) { 128 return new WifiStaIfaceHidlImpl(staIface, context, ssidTranslator); 129 } 130 createWifiStaIfaceAidlImplMockable( android.hardware.wifi.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)131 protected WifiStaIfaceAidlImpl createWifiStaIfaceAidlImplMockable( 132 android.hardware.wifi.IWifiStaIface staIface, @NonNull Context context, 133 @NonNull SsidTranslator ssidTranslator) { 134 return new WifiStaIfaceAidlImpl(staIface, context, ssidTranslator); 135 } 136 validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier)137 private <T> T validateAndCall(String methodStr, T defaultVal, @NonNull Supplier<T> supplier) { 138 if (mWifiStaIface == null) { 139 Log.wtf(TAG, "Cannot call " + methodStr + " because mWifiStaIface is null"); 140 return defaultVal; 141 } 142 return supplier.get(); 143 } 144 145 /** 146 * See comments for {@link IWifiStaIface#registerFrameworkCallback(Callback)} 147 */ registerFrameworkCallback(Callback callback)148 public boolean registerFrameworkCallback(Callback callback) { 149 return validateAndCall("registerFrameworkCallback", false, 150 () -> mWifiStaIface.registerFrameworkCallback(callback)); 151 } 152 153 /** 154 * See comments for {@link IWifiStaIface#getName()} 155 */ 156 @Override 157 @Nullable getName()158 public String getName() { 159 return validateAndCall("getName", null, 160 () -> mWifiStaIface.getName()); 161 } 162 163 /** 164 * See comments for {@link IWifiStaIface#configureRoaming(List, List)} 165 */ configureRoaming(List<MacAddress> bssidBlocklist, List<byte[]> ssidAllowlist)166 public boolean configureRoaming(List<MacAddress> bssidBlocklist, 167 List<byte[]> ssidAllowlist) { 168 return validateAndCall("configureRoaming", false, 169 () -> mWifiStaIface.configureRoaming(bssidBlocklist, ssidAllowlist)); 170 } 171 172 /** 173 * See comments for {@link IWifiStaIface#enableLinkLayerStatsCollection(boolean)} 174 */ enableLinkLayerStatsCollection(boolean debug)175 public boolean enableLinkLayerStatsCollection(boolean debug) { 176 return validateAndCall("enableLinkLayerStatsCollection", false, 177 () -> mWifiStaIface.enableLinkLayerStatsCollection(debug)); 178 } 179 180 /** 181 * See comments for {@link IWifiStaIface#enableNdOffload(boolean)} 182 */ enableNdOffload(boolean enable)183 public boolean enableNdOffload(boolean enable) { 184 return validateAndCall("enableNdOffload", false, 185 () -> mWifiStaIface.enableNdOffload(enable)); 186 } 187 188 /** 189 * See comments for {@link IWifiStaIface#getApfPacketFilterCapabilities()} 190 */ getApfPacketFilterCapabilities()191 public ApfCapabilities getApfPacketFilterCapabilities() { 192 return validateAndCall("getApfPacketFilterCapabilities", new ApfCapabilities(0, 0, 0), 193 () -> mWifiStaIface.getApfPacketFilterCapabilities()); 194 } 195 196 /** 197 * See comments for {@link IWifiStaIface#getBackgroundScanCapabilities()} 198 */ 199 @Nullable getBackgroundScanCapabilities()200 public WifiNative.ScanCapabilities getBackgroundScanCapabilities() { 201 return validateAndCall("getBackgroundScanCapabilities", null, 202 () -> mWifiStaIface.getBackgroundScanCapabilities()); 203 } 204 205 /** 206 * See comments for {@link IWifiStaIface#getCapabilities()} 207 */ getCapabilities()208 public long getCapabilities() { 209 return validateAndCall("getCapabilities", 0L, 210 () -> mWifiStaIface.getCapabilities()); 211 } 212 213 /** 214 * See comments for {@link IWifiStaIface#getDebugRxPacketFates()} 215 */ getDebugRxPacketFates()216 public List<WifiNative.RxFateReport> getDebugRxPacketFates() { 217 return validateAndCall("getDebugRxPacketFates", new ArrayList<>(), 218 () -> mWifiStaIface.getDebugRxPacketFates()); 219 } 220 221 /** 222 * See comments for {@link IWifiStaIface#getDebugTxPacketFates()} 223 */ getDebugTxPacketFates()224 public List<WifiNative.TxFateReport> getDebugTxPacketFates() { 225 return validateAndCall("getDebugTxPacketFates", new ArrayList<>(), 226 () -> mWifiStaIface.getDebugTxPacketFates()); 227 } 228 229 /** 230 * See comments for {@link IWifiStaIface#getFactoryMacAddress()} 231 */ 232 @Nullable getFactoryMacAddress()233 public MacAddress getFactoryMacAddress() { 234 return validateAndCall("getFactoryMacAddress", null, 235 () -> mWifiStaIface.getFactoryMacAddress()); 236 } 237 238 /** 239 * See comments for {@link IWifiStaIface#getLinkLayerStats()} 240 */ 241 @Nullable getLinkLayerStats()242 public WifiLinkLayerStats getLinkLayerStats() { 243 return validateAndCall("getLinkLayerStats", null, 244 () -> mWifiStaIface.getLinkLayerStats()); 245 } 246 247 /** 248 * See comments for {@link IWifiStaIface#getRoamingCapabilities()} 249 */ 250 @Nullable getRoamingCapabilities()251 public WifiNative.RoamingCapabilities getRoamingCapabilities() { 252 return validateAndCall("getRoamingCapabilities", null, 253 () -> mWifiStaIface.getRoamingCapabilities()); 254 } 255 256 /** 257 * See comments for {@link IWifiStaIface#installApfPacketFilter(byte[])} 258 */ installApfPacketFilter(byte[] program)259 public boolean installApfPacketFilter(byte[] program) { 260 return validateAndCall("installApfPacketFilter", false, 261 () -> mWifiStaIface.installApfPacketFilter(program)); 262 } 263 264 /** 265 * See comments for {@link IWifiStaIface#readApfPacketFilterData()} 266 */ 267 @Nullable readApfPacketFilterData()268 public byte[] readApfPacketFilterData() { 269 return validateAndCall("readApfPacketFilterData", null, 270 () -> mWifiStaIface.readApfPacketFilterData()); 271 } 272 273 /** 274 * See comments for {@link IWifiStaIface#setMacAddress(MacAddress)} 275 */ setMacAddress(MacAddress mac)276 public boolean setMacAddress(MacAddress mac) { 277 return validateAndCall("setMacAddress", false, 278 () -> mWifiStaIface.setMacAddress(mac)); 279 } 280 281 /** 282 * See comments for {@link IWifiStaIface#setRoamingState(int)} 283 */ setRoamingState( @ifiNative.RoamingEnableState int state)284 public @WifiNative.RoamingEnableStatus int setRoamingState( 285 @WifiNative.RoamingEnableState int state) { 286 return validateAndCall("setRoamingState", SET_ROAMING_STATE_FAILURE_CODE, 287 () -> mWifiStaIface.setRoamingState(state)); 288 } 289 290 /** 291 * See comments for {@link IWifiStaIface#setScanMode(boolean)} 292 */ setScanMode(boolean enable)293 public boolean setScanMode(boolean enable) { 294 return validateAndCall("setScanMode", false, 295 () -> mWifiStaIface.setScanMode(enable)); 296 } 297 298 /** 299 * See comments for {@link IWifiStaIface#startBackgroundScan(int, StaBackgroundScanParameters)} 300 */ startBackgroundScan(int cmdId, StaBackgroundScanParameters params)301 public boolean startBackgroundScan(int cmdId, StaBackgroundScanParameters params) { 302 return validateAndCall("startBackgroundScan", false, 303 () -> mWifiStaIface.startBackgroundScan(cmdId, params)); 304 } 305 306 /** 307 * See comments for {@link IWifiStaIface#startDebugPacketFateMonitoring()} 308 */ startDebugPacketFateMonitoring()309 public boolean startDebugPacketFateMonitoring() { 310 return validateAndCall("startDebugPacketFateMonitoring", false, 311 () -> mWifiStaIface.startDebugPacketFateMonitoring()); 312 } 313 314 /** 315 * See comments for {@link IWifiStaIface#startRssiMonitoring(int, int, int)} 316 */ startRssiMonitoring(int cmdId, int maxRssi, int minRssi)317 public boolean startRssiMonitoring(int cmdId, int maxRssi, int minRssi) { 318 return validateAndCall("startRssiMonitoring", false, 319 () -> mWifiStaIface.startRssiMonitoring(cmdId, maxRssi, minRssi)); 320 } 321 322 /** 323 * See comments for {@link IWifiStaIface#startSendingKeepAlivePackets(int, byte[], int, 324 * MacAddress, MacAddress, int)} 325 */ startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType, MacAddress srcAddress, MacAddress dstAddress, int periodInMs)326 public boolean startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType, 327 MacAddress srcAddress, MacAddress dstAddress, int periodInMs) { 328 return validateAndCall("startSendingKeepAlivePackets", false, 329 () -> mWifiStaIface.startSendingKeepAlivePackets(cmdId, ipPacketData, etherType, 330 srcAddress, dstAddress, periodInMs)); 331 } 332 333 /** 334 * See comments for {@link IWifiStaIface#stopBackgroundScan(int)} 335 */ stopBackgroundScan(int cmdId)336 public boolean stopBackgroundScan(int cmdId) { 337 return validateAndCall("stopBackgroundScan", false, 338 () -> mWifiStaIface.stopBackgroundScan(cmdId)); 339 } 340 341 /** 342 * See comments for {@link IWifiStaIface#stopRssiMonitoring(int)} 343 */ stopRssiMonitoring(int cmdId)344 public boolean stopRssiMonitoring(int cmdId) { 345 return validateAndCall("stopRssiMonitoring", false, 346 () -> mWifiStaIface.stopRssiMonitoring(cmdId)); 347 } 348 349 /** 350 * See comments for {@link IWifiStaIface#stopSendingKeepAlivePackets(int)} 351 */ stopSendingKeepAlivePackets(int cmdId)352 public boolean stopSendingKeepAlivePackets(int cmdId) { 353 return validateAndCall("stopSendingKeepAlivePackets", false, 354 () -> mWifiStaIface.stopSendingKeepAlivePackets(cmdId)); 355 } 356 357 /** 358 * See comments for {@link IWifiStaIface#setDtimMultiplier(int)} 359 */ setDtimMultiplier(int multiplier)360 public boolean setDtimMultiplier(int multiplier) { 361 return validateAndCall("setDtimMultiplier", false, 362 () -> mWifiStaIface.setDtimMultiplier(multiplier)); 363 } 364 } 365