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 com.android.server.wifi.hal.WifiHalAidlImpl.isServiceVersionAtLeast; 20 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.content.Context; 24 import android.hardware.wifi.CachedScanData; 25 import android.hardware.wifi.CachedScanResult; 26 import android.hardware.wifi.IWifiStaIfaceEventCallback; 27 import android.hardware.wifi.Ssid; 28 import android.hardware.wifi.StaApfPacketFilterCapabilities; 29 import android.hardware.wifi.StaBackgroundScanBucketEventReportSchemeMask; 30 import android.hardware.wifi.StaBackgroundScanBucketParameters; 31 import android.hardware.wifi.StaBackgroundScanCapabilities; 32 import android.hardware.wifi.StaBackgroundScanParameters; 33 import android.hardware.wifi.StaLinkLayerIfaceStats; 34 import android.hardware.wifi.StaLinkLayerLinkStats; 35 import android.hardware.wifi.StaLinkLayerRadioStats; 36 import android.hardware.wifi.StaLinkLayerStats; 37 import android.hardware.wifi.StaPeerInfo; 38 import android.hardware.wifi.StaRateStat; 39 import android.hardware.wifi.StaRoamingCapabilities; 40 import android.hardware.wifi.StaRoamingConfig; 41 import android.hardware.wifi.StaRoamingState; 42 import android.hardware.wifi.StaScanData; 43 import android.hardware.wifi.StaScanDataFlagMask; 44 import android.hardware.wifi.StaScanResult; 45 import android.hardware.wifi.TwtSession; 46 import android.hardware.wifi.TwtSessionStats; 47 import android.hardware.wifi.WifiBand; 48 import android.hardware.wifi.WifiChannelStats; 49 import android.hardware.wifi.WifiDebugPacketFateFrameType; 50 import android.hardware.wifi.WifiDebugRxPacketFate; 51 import android.hardware.wifi.WifiDebugRxPacketFateReport; 52 import android.hardware.wifi.WifiDebugTxPacketFate; 53 import android.hardware.wifi.WifiDebugTxPacketFateReport; 54 import android.hardware.wifi.WifiRatePreamble; 55 import android.hardware.wifi.WifiStatusCode; 56 import android.net.MacAddress; 57 import android.net.apf.ApfCapabilities; 58 import android.net.wifi.ScanResult; 59 import android.net.wifi.WifiAnnotations; 60 import android.net.wifi.WifiManager; 61 import android.net.wifi.WifiManager.RoamingMode; 62 import android.net.wifi.WifiScanner; 63 import android.net.wifi.WifiSsid; 64 import android.net.wifi.WifiUsabilityStatsEntry; 65 import android.net.wifi.twt.TwtRequest; 66 import android.net.wifi.twt.TwtSessionCallback; 67 import android.os.Bundle; 68 import android.os.RemoteException; 69 import android.os.ServiceSpecificException; 70 import android.util.Log; 71 72 import com.android.internal.annotations.VisibleForTesting; 73 import com.android.server.wifi.SsidTranslator; 74 import com.android.server.wifi.WifiLinkLayerStats; 75 import com.android.server.wifi.WifiLoggerHal; 76 import com.android.server.wifi.WifiNative; 77 import com.android.server.wifi.util.BitMask; 78 import com.android.server.wifi.util.HalAidlUtil; 79 import com.android.server.wifi.util.NativeUtil; 80 import com.android.wifi.resources.R; 81 82 import java.util.ArrayList; 83 import java.util.List; 84 85 /** 86 * AIDL implementation of the IWifiStaIface interface. 87 */ 88 public class WifiStaIfaceAidlImpl implements IWifiStaIface { 89 private static final String TAG = "WifiStaIfaceAidlImpl"; 90 private android.hardware.wifi.IWifiStaIface mWifiStaIface; 91 private IWifiStaIfaceEventCallback mHalCallback; 92 private WifiStaIface.Callback mFrameworkCallback; 93 private final Object mLock = new Object(); 94 private String mIfaceName; 95 private Context mContext; 96 private SsidTranslator mSsidTranslator; 97 98 private final boolean mWifiLinkLayerAllRadiosStatsAggregationEnabled; 99 WifiStaIfaceAidlImpl(@onNull android.hardware.wifi.IWifiStaIface staIface, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)100 public WifiStaIfaceAidlImpl(@NonNull android.hardware.wifi.IWifiStaIface staIface, 101 @NonNull Context context, @NonNull SsidTranslator ssidTranslator) { 102 mWifiStaIface = staIface; 103 mContext = context; 104 mSsidTranslator = ssidTranslator; 105 mHalCallback = new StaIfaceEventCallback(); 106 mWifiLinkLayerAllRadiosStatsAggregationEnabled = mContext.getResources() 107 .getBoolean(R.bool.config_wifiLinkLayerAllRadiosStatsAggregationEnabled); 108 } 109 110 /** 111 * See comments for {@link IWifiStaIface#registerFrameworkCallback(WifiStaIface.Callback)} 112 */ 113 @Override registerFrameworkCallback(WifiStaIface.Callback callback)114 public boolean registerFrameworkCallback(WifiStaIface.Callback callback) { 115 final String methodStr = "registerFrameworkCallback"; 116 synchronized (mLock) { 117 if (!checkIfaceAndLogFailure(methodStr)) return false; 118 if (mFrameworkCallback != null) { 119 Log.e(TAG, "Framework callback is already registered"); 120 return false; 121 } else if (callback == null) { 122 Log.e(TAG, "Cannot register a null callback"); 123 return false; 124 } 125 126 try { 127 mWifiStaIface.registerEventCallback(mHalCallback); 128 mFrameworkCallback = callback; 129 return true; 130 } catch (RemoteException e) { 131 handleRemoteException(e, methodStr); 132 } catch (ServiceSpecificException e) { 133 handleServiceSpecificException(e, methodStr); 134 } 135 return false; 136 } 137 } 138 139 /** 140 * See comments for {@link IWifiStaIface#getName()} 141 */ 142 @Override 143 @Nullable getName()144 public String getName() { 145 final String methodStr = "getName"; 146 synchronized (mLock) { 147 if (!checkIfaceAndLogFailure(methodStr)) return null; 148 if (mIfaceName != null) return mIfaceName; 149 try { 150 String ifaceName = mWifiStaIface.getName(); 151 mIfaceName = ifaceName; 152 return mIfaceName; 153 } catch (RemoteException e) { 154 handleRemoteException(e, methodStr); 155 } catch (ServiceSpecificException e) { 156 handleServiceSpecificException(e, methodStr); 157 } 158 return null; 159 } 160 } 161 162 /** 163 * See comments for {@link IWifiStaIface#configureRoaming(List, List)} 164 */ 165 @Override configureRoaming(List<MacAddress> bssidBlocklist, List<byte[]> ssidAllowlist)166 public boolean configureRoaming(List<MacAddress> bssidBlocklist, 167 List<byte[]> ssidAllowlist) { 168 final String methodStr = "configureRoaming"; 169 synchronized (mLock) { 170 try { 171 if (!checkIfaceAndLogFailure(methodStr)) return false; 172 StaRoamingConfig config = 173 frameworkToHalStaRoamingConfig(bssidBlocklist, ssidAllowlist); 174 mWifiStaIface.configureRoaming(config); 175 return true; 176 } catch (RemoteException e) { 177 handleRemoteException(e, methodStr); 178 } catch (ServiceSpecificException e) { 179 handleServiceSpecificException(e, methodStr); 180 } 181 return false; 182 } 183 } 184 185 /** 186 * See comments for {@link IWifiStaIface#enableLinkLayerStatsCollection(boolean)} 187 */ 188 @Override enableLinkLayerStatsCollection(boolean debug)189 public boolean enableLinkLayerStatsCollection(boolean debug) { 190 final String methodStr = "enableLinkLayerStatsCollection"; 191 synchronized (mLock) { 192 try { 193 if (!checkIfaceAndLogFailure(methodStr)) return false; 194 mWifiStaIface.enableLinkLayerStatsCollection(debug); 195 return true; 196 } catch (RemoteException e) { 197 handleRemoteException(e, methodStr); 198 } catch (ServiceSpecificException e) { 199 handleServiceSpecificException(e, methodStr); 200 } 201 return false; 202 } 203 } 204 205 /** 206 * See comments for {@link IWifiStaIface#enableNdOffload(boolean)} 207 */ 208 @Override enableNdOffload(boolean enable)209 public boolean enableNdOffload(boolean enable) { 210 final String methodStr = "enableNdOffload"; 211 synchronized (mLock) { 212 try { 213 if (!checkIfaceAndLogFailure(methodStr)) return false; 214 mWifiStaIface.enableNdOffload(enable); 215 return true; 216 } catch (RemoteException e) { 217 handleRemoteException(e, methodStr); 218 } catch (ServiceSpecificException e) { 219 handleServiceSpecificException(e, methodStr); 220 } 221 return false; 222 } 223 } 224 225 /** 226 * See comments for {@link IWifiStaIface#getApfPacketFilterCapabilities()} 227 */ 228 @Override getApfPacketFilterCapabilities()229 public ApfCapabilities getApfPacketFilterCapabilities() { 230 final String methodStr = "getApfPacketFilterCapabilities"; 231 final ApfCapabilities defaultVal = new ApfCapabilities(0, 0, 0); 232 synchronized (mLock) { 233 try { 234 if (!checkIfaceAndLogFailure(methodStr)) return defaultVal; 235 StaApfPacketFilterCapabilities halCaps = 236 mWifiStaIface.getApfPacketFilterCapabilities(); 237 return new ApfCapabilities( 238 halCaps.version, // apfVersionSupported 239 halCaps.maxLength, // maximumApfProgramSize 240 android.system.OsConstants.ARPHRD_ETHER); // apfPacketFormat 241 } catch (RemoteException e) { 242 handleRemoteException(e, methodStr); 243 } catch (ServiceSpecificException e) { 244 handleServiceSpecificException(e, methodStr); 245 } 246 return defaultVal; 247 } 248 } 249 250 /** 251 * See comments for {@link IWifiStaIface#getBackgroundScanCapabilities()} 252 */ 253 @Override 254 @Nullable getBackgroundScanCapabilities()255 public WifiNative.ScanCapabilities getBackgroundScanCapabilities() { 256 final String methodStr = "getBackgroundScanCapabilities"; 257 synchronized (mLock) { 258 if (!checkIfaceAndLogFailure(methodStr)) { 259 return null; 260 } 261 try { 262 StaBackgroundScanCapabilities halCaps = 263 mWifiStaIface.getBackgroundScanCapabilities(); 264 WifiNative.ScanCapabilities frameworkCaps = new WifiNative.ScanCapabilities(); 265 frameworkCaps.max_scan_cache_size = halCaps.maxCacheSize; 266 frameworkCaps.max_ap_cache_per_scan = halCaps.maxApCachePerScan; 267 frameworkCaps.max_scan_buckets = halCaps.maxBuckets; 268 frameworkCaps.max_rssi_sample_size = 0; 269 frameworkCaps.max_scan_reporting_threshold = halCaps.maxReportingThreshold; 270 return frameworkCaps; 271 } catch (RemoteException e) { 272 handleRemoteException(e, methodStr); 273 } catch (ServiceSpecificException e) { 274 handleServiceSpecificException(e, methodStr); 275 } 276 return null; 277 } 278 } 279 280 /** 281 * See comments for {@link IWifiStaIface#getCapabilities()} 282 */ 283 @Override getCapabilities()284 public long getCapabilities() { 285 final String methodStr = "getCapabilities"; 286 synchronized (mLock) { 287 try { 288 if (!checkIfaceAndLogFailure(methodStr)) return 0L; 289 long halFeatureSet = mWifiStaIface.getFeatureSet(); 290 return halToFrameworkStaFeatureSet(halFeatureSet); 291 } catch (RemoteException e) { 292 handleRemoteException(e, methodStr); 293 } catch (ServiceSpecificException e) { 294 handleServiceSpecificException(e, methodStr); 295 } 296 return 0L; 297 } 298 } 299 300 /** 301 * See comments for {@link IWifiStaIface#getDebugRxPacketFates()} 302 */ 303 @Override getDebugRxPacketFates()304 public List<WifiNative.RxFateReport> getDebugRxPacketFates() { 305 final String methodStr = "getDebugRxPacketFates"; 306 List<WifiNative.RxFateReport> fateReports = new ArrayList<>(); 307 synchronized (mLock) { 308 try { 309 if (!checkIfaceAndLogFailure(methodStr)) return fateReports; 310 WifiDebugRxPacketFateReport[] halReports = mWifiStaIface.getDebugRxPacketFates(); 311 for (WifiDebugRxPacketFateReport report : halReports) { 312 if (fateReports.size() >= WifiLoggerHal.MAX_FATE_LOG_LEN) break; 313 byte code = halToFrameworkRxPktFate(report.fate); 314 long us = report.frameInfo.driverTimestampUsec; 315 byte type = halToFrameworkPktFateFrameType(report.frameInfo.frameType); 316 byte[] frame = report.frameInfo.frameContent; 317 fateReports.add(new WifiNative.RxFateReport(code, us, type, frame)); 318 } 319 } catch (RemoteException e) { 320 handleRemoteException(e, methodStr); 321 } catch (ServiceSpecificException e) { 322 handleServiceSpecificException(e, methodStr); 323 } catch (IllegalArgumentException e) { 324 handleIllegalArgumentException(e, methodStr); 325 return new ArrayList<>(); 326 } 327 return fateReports; 328 } 329 } 330 331 /** 332 * See comments for {@link IWifiStaIface#getDebugTxPacketFates()} 333 */ 334 @Override getDebugTxPacketFates()335 public List<WifiNative.TxFateReport> getDebugTxPacketFates() { 336 final String methodStr = "getDebugTxPacketFates"; 337 List<WifiNative.TxFateReport> fateReports = new ArrayList<>(); 338 synchronized (mLock) { 339 try { 340 if (!checkIfaceAndLogFailure(methodStr)) return fateReports; 341 WifiDebugTxPacketFateReport[] halReports = mWifiStaIface.getDebugTxPacketFates(); 342 for (WifiDebugTxPacketFateReport report : halReports) { 343 if (fateReports.size() >= WifiLoggerHal.MAX_FATE_LOG_LEN) break; 344 byte code = halToFrameworkTxPktFate(report.fate); 345 long us = report.frameInfo.driverTimestampUsec; 346 byte type = halToFrameworkPktFateFrameType(report.frameInfo.frameType); 347 byte[] frame = report.frameInfo.frameContent; 348 fateReports.add(new WifiNative.TxFateReport(code, us, type, frame)); 349 } 350 } catch (RemoteException e) { 351 handleRemoteException(e, methodStr); 352 } catch (ServiceSpecificException e) { 353 handleServiceSpecificException(e, methodStr); 354 } catch (IllegalArgumentException e) { 355 handleIllegalArgumentException(e, methodStr); 356 return new ArrayList<>(); 357 } 358 return fateReports; 359 } 360 } 361 362 /** 363 * See comments for {@link IWifiStaIface#getFactoryMacAddress()} 364 */ 365 @Override 366 @Nullable getFactoryMacAddress()367 public MacAddress getFactoryMacAddress() { 368 final String methodStr = "getFactoryMacAddress"; 369 byte[] macBytes; 370 synchronized (mLock) { 371 try { 372 if (!checkIfaceAndLogFailure(methodStr)) return null; 373 macBytes = mWifiStaIface.getFactoryMacAddress(); 374 return MacAddress.fromBytes(macBytes); 375 } catch (RemoteException e) { 376 handleRemoteException(e, methodStr); 377 } catch (ServiceSpecificException e) { 378 handleServiceSpecificException(e, methodStr); 379 } catch (IllegalArgumentException e) { 380 Log.e(TAG, "Invalid MAC address received: " + e); 381 } 382 return null; 383 } 384 } 385 386 /** 387 * See comments for {@link IWifiStaIface#getCachedScanData()} 388 */ 389 @Override 390 @Nullable getCachedScanData()391 public WifiScanner.ScanData getCachedScanData() { 392 final String methodStr = "getCachedScanData"; 393 synchronized (mLock) { 394 try { 395 if (!checkIfaceAndLogFailure(methodStr)) return null; 396 CachedScanData scanData = mWifiStaIface.getCachedScanData(); 397 return halToFrameworkCachedScanData(scanData); 398 } catch (RemoteException e) { 399 handleRemoteException(e, methodStr); 400 } catch (ServiceSpecificException e) { 401 handleServiceSpecificException(e, methodStr); 402 } 403 return null; 404 } 405 } 406 407 408 /** 409 * See comments for {@link IWifiStaIface#getLinkLayerStats()} 410 */ 411 @Override 412 @Nullable getLinkLayerStats()413 public WifiLinkLayerStats getLinkLayerStats() { 414 final String methodStr = "getLinkLayerStats"; 415 synchronized (mLock) { 416 try { 417 if (!checkIfaceAndLogFailure(methodStr)) return null; 418 StaLinkLayerStats halStats = mWifiStaIface.getLinkLayerStats(); 419 return halToFrameworkLinkLayerStats(halStats); 420 } catch (RemoteException e) { 421 handleRemoteException(e, methodStr); 422 } catch (ServiceSpecificException e) { 423 handleServiceSpecificException(e, methodStr); 424 } catch (IllegalArgumentException e) { 425 // May indicate a malformed return value in the HAL. 426 Log.wtf(TAG, methodStr + " encountered IllegalArgumentException: " + e); 427 } 428 return null; 429 } 430 } 431 432 /** 433 * See comments for {@link IWifiStaIface#getRoamingCapabilities()} 434 */ 435 @Override 436 @Nullable getRoamingCapabilities()437 public WifiNative.RoamingCapabilities getRoamingCapabilities() { 438 final String methodStr = "getRoamingCapabilities"; 439 synchronized (mLock) { 440 try { 441 if (!checkIfaceAndLogFailure(methodStr)) return null; 442 StaRoamingCapabilities halCaps = mWifiStaIface.getRoamingCapabilities(); 443 WifiNative.RoamingCapabilities out = new WifiNative.RoamingCapabilities(); 444 out.maxBlocklistSize = halCaps.maxBlocklistSize; 445 out.maxAllowlistSize = halCaps.maxAllowlistSize; 446 return out; 447 } catch (RemoteException e) { 448 handleRemoteException(e, methodStr); 449 } catch (ServiceSpecificException e) { 450 handleServiceSpecificException(e, methodStr); 451 } 452 return null; 453 } 454 } 455 456 /** 457 * See comments for {@link IWifiStaIface#installApfPacketFilter(byte[])} 458 */ 459 @Override installApfPacketFilter(byte[] program)460 public boolean installApfPacketFilter(byte[] program) { 461 final String methodStr = "installApfPacketFilter"; 462 synchronized (mLock) { 463 try { 464 if (!checkIfaceAndLogFailure(methodStr)) return false; 465 mWifiStaIface.installApfPacketFilter(program); 466 return true; 467 } catch (RemoteException e) { 468 handleRemoteException(e, methodStr); 469 } catch (ServiceSpecificException e) { 470 handleServiceSpecificException(e, methodStr); 471 } 472 return false; 473 } 474 } 475 476 /** 477 * See comments for {@link IWifiStaIface#readApfPacketFilterData()} 478 */ 479 @Override 480 @Nullable readApfPacketFilterData()481 public byte[] readApfPacketFilterData() { 482 final String methodStr = "readApfPacketFilterData"; 483 synchronized (mLock) { 484 try { 485 if (!checkIfaceAndLogFailure(methodStr)) return null; 486 return mWifiStaIface.readApfPacketFilterData(); 487 } catch (RemoteException e) { 488 handleRemoteException(e, methodStr); 489 } catch (ServiceSpecificException e) { 490 handleServiceSpecificException(e, methodStr); 491 } 492 return null; 493 } 494 } 495 496 /** 497 * See comments for {@link IWifiStaIface#setMacAddress(MacAddress)} 498 */ 499 @Override setMacAddress(MacAddress mac)500 public boolean setMacAddress(MacAddress mac) { 501 final String methodStr = "setMacAddress"; 502 synchronized (mLock) { 503 try { 504 if (!checkIfaceAndLogFailure(methodStr)) return false; 505 mWifiStaIface.setMacAddress(mac.toByteArray()); 506 return true; 507 } catch (RemoteException e) { 508 handleRemoteException(e, methodStr); 509 } catch (ServiceSpecificException e) { 510 handleServiceSpecificException(e, methodStr); 511 } 512 return false; 513 } 514 } 515 516 /** 517 * See comments for {@link IWifiStaIface#setRoamingState(int)} 518 */ setRoamingState( @ifiNative.RoamingEnableState int state)519 @Override public @WifiNative.RoamingEnableStatus int setRoamingState( 520 @WifiNative.RoamingEnableState int state) { 521 final String methodStr = "setRoamingState"; 522 final int errorCode = WifiStaIface.SET_ROAMING_STATE_FAILURE_CODE; 523 final byte halState = frameworkToHalStaRoamingState(state); 524 if (halState == -1) return errorCode; 525 526 synchronized (mLock) { 527 try { 528 if (!checkIfaceAndLogFailure(methodStr)) return errorCode; 529 mWifiStaIface.setRoamingState(halState); 530 return WifiNative.SET_FIRMWARE_ROAMING_SUCCESS; 531 } catch (RemoteException e) { 532 handleRemoteException(e, methodStr); 533 } catch (ServiceSpecificException e) { 534 if (e.errorCode == WifiStatusCode.ERROR_BUSY) { 535 return WifiNative.SET_FIRMWARE_ROAMING_BUSY; 536 } 537 handleServiceSpecificException(e, methodStr); 538 } 539 return errorCode; 540 } 541 } 542 543 /** 544 * See comments for {@link IWifiStaIface#setScanMode(boolean)} 545 */ 546 @Override setScanMode(boolean enable)547 public boolean setScanMode(boolean enable) { 548 final String methodStr = "setScanMode"; 549 synchronized (mLock) { 550 try { 551 if (!checkIfaceAndLogFailure(methodStr)) return false; 552 mWifiStaIface.setScanMode(enable); 553 return true; 554 } catch (RemoteException e) { 555 handleRemoteException(e, methodStr); 556 } catch (ServiceSpecificException e) { 557 handleServiceSpecificException(e, methodStr); 558 } 559 return false; 560 } 561 } 562 563 /** 564 * See comments for 565 * {@link IWifiStaIface#startBackgroundScan(int, WifiStaIface.StaBackgroundScanParameters)} 566 */ 567 @Override startBackgroundScan(int cmdId, WifiStaIface.StaBackgroundScanParameters params)568 public boolean startBackgroundScan(int cmdId, WifiStaIface.StaBackgroundScanParameters params) { 569 final String methodStr = "startBackgroundScan"; 570 synchronized (mLock) { 571 try { 572 if (!checkIfaceAndLogFailure(methodStr)) return false; 573 StaBackgroundScanParameters halParams = frameworkToHalBackgroundScanParams(params); 574 mWifiStaIface.startBackgroundScan(cmdId, halParams); 575 return true; 576 } catch (RemoteException e) { 577 handleRemoteException(e, methodStr); 578 } catch (ServiceSpecificException e) { 579 handleServiceSpecificException(e, methodStr); 580 } catch (IllegalArgumentException e) { 581 handleIllegalArgumentException(e, methodStr); 582 } 583 return false; 584 } 585 } 586 587 /** 588 * See comments for {@link IWifiStaIface#startDebugPacketFateMonitoring()} 589 */ 590 @Override startDebugPacketFateMonitoring()591 public boolean startDebugPacketFateMonitoring() { 592 final String methodStr = "startDebugPacketFateMonitoring"; 593 synchronized (mLock) { 594 try { 595 if (!checkIfaceAndLogFailure(methodStr)) return false; 596 mWifiStaIface.startDebugPacketFateMonitoring(); 597 return true; 598 } catch (RemoteException e) { 599 handleRemoteException(e, methodStr); 600 } catch (ServiceSpecificException e) { 601 handleServiceSpecificException(e, methodStr); 602 } 603 return false; 604 } 605 } 606 607 /** 608 * See comments for 609 * {@link IWifiStaIface#startRssiMonitoring(int, int, int)} 610 */ 611 @Override startRssiMonitoring(int cmdId, int maxRssi, int minRssi)612 public boolean startRssiMonitoring(int cmdId, int maxRssi, int minRssi) { 613 final String methodStr = "startRssiMonitoring"; 614 synchronized (mLock) { 615 try { 616 if (!checkIfaceAndLogFailure(methodStr)) return false; 617 mWifiStaIface.startRssiMonitoring(cmdId, maxRssi, minRssi); 618 return true; 619 } catch (RemoteException e) { 620 handleRemoteException(e, methodStr); 621 } catch (ServiceSpecificException e) { 622 handleServiceSpecificException(e, methodStr); 623 } 624 return false; 625 } 626 } 627 628 /** 629 * See comments for {@link IWifiStaIface#startSendingKeepAlivePackets(int, byte[], int, 630 * MacAddress, MacAddress, int)} 631 */ 632 @Override startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType, MacAddress srcAddress, MacAddress dstAddress, int periodInMs)633 public boolean startSendingKeepAlivePackets(int cmdId, byte[] ipPacketData, int etherType, 634 MacAddress srcAddress, MacAddress dstAddress, int periodInMs) { 635 final String methodStr = "startSendingKeepAlivePackets"; 636 synchronized (mLock) { 637 try { 638 if (!checkIfaceAndLogFailure(methodStr)) return false; 639 mWifiStaIface.startSendingKeepAlivePackets(cmdId, ipPacketData, (char) etherType, 640 srcAddress.toByteArray(), dstAddress.toByteArray(), periodInMs); 641 return true; 642 } catch (RemoteException e) { 643 handleRemoteException(e, methodStr); 644 } catch (ServiceSpecificException e) { 645 handleServiceSpecificException(e, methodStr); 646 } 647 return false; 648 } 649 } 650 651 /** 652 * See comments for {@link IWifiStaIface#stopBackgroundScan(int)} 653 */ 654 @Override stopBackgroundScan(int cmdId)655 public boolean stopBackgroundScan(int cmdId) { 656 final String methodStr = "stopBackgroundScan"; 657 synchronized (mLock) { 658 try { 659 if (!checkIfaceAndLogFailure(methodStr)) return false; 660 mWifiStaIface.stopBackgroundScan(cmdId); 661 return true; 662 } catch (RemoteException e) { 663 handleRemoteException(e, methodStr); 664 } catch (ServiceSpecificException e) { 665 handleServiceSpecificException(e, methodStr); 666 } 667 return false; 668 } 669 } 670 671 /** 672 * See comments for {@link IWifiStaIface#stopRssiMonitoring(int)} 673 */ 674 @Override stopRssiMonitoring(int cmdId)675 public boolean stopRssiMonitoring(int cmdId) { 676 final String methodStr = "stopRssiMonitoring"; 677 synchronized (mLock) { 678 try { 679 if (!checkIfaceAndLogFailure(methodStr)) return false; 680 mWifiStaIface.stopRssiMonitoring(cmdId); 681 return true; 682 } catch (RemoteException e) { 683 handleRemoteException(e, methodStr); 684 } catch (ServiceSpecificException e) { 685 handleServiceSpecificException(e, methodStr); 686 } 687 return false; 688 } 689 } 690 691 /** 692 * See comments for {@link IWifiStaIface#stopSendingKeepAlivePackets(int)} 693 */ 694 @Override stopSendingKeepAlivePackets(int cmdId)695 public boolean stopSendingKeepAlivePackets(int cmdId) { 696 final String methodStr = "stopSendingKeepAlivePackets"; 697 synchronized (mLock) { 698 try { 699 if (!checkIfaceAndLogFailure(methodStr)) return false; 700 mWifiStaIface.stopSendingKeepAlivePackets(cmdId); 701 return true; 702 } catch (RemoteException e) { 703 handleRemoteException(e, methodStr); 704 } catch (ServiceSpecificException e) { 705 handleServiceSpecificException(e, methodStr); 706 } 707 return false; 708 } 709 } 710 711 /** 712 * See comments for {@link IWifiStaIface#setDtimMultiplier(int)} 713 */ 714 @Override setDtimMultiplier(int multiplier)715 public boolean setDtimMultiplier(int multiplier) { 716 final String methodStr = "setDtimMultiplier"; 717 synchronized (mLock) { 718 try { 719 if (!checkIfaceAndLogFailure(methodStr)) return false; 720 mWifiStaIface.setDtimMultiplier(multiplier); 721 return true; 722 } catch (RemoteException e) { 723 handleRemoteException(e, methodStr); 724 } catch (ServiceSpecificException e) { 725 handleServiceSpecificException(e, methodStr); 726 } 727 return false; 728 } 729 } 730 731 /** 732 * See comments for {@link IWifiStaIface#setRoamingMode(int)} 733 */ setRoamingMode(@oamingMode int roamingMode)734 public @WifiStatusCode int setRoamingMode(@RoamingMode int roamingMode) { 735 final String methodStr = "setRoamingMode"; 736 @WifiStatusCode int errorCode = WifiStatusCode.ERROR_UNKNOWN; 737 synchronized (mLock) { 738 try { 739 if (checkIfaceAndLogFailure(methodStr)) { 740 mWifiStaIface.setRoamingState(frameworkToHalRoamingMode(roamingMode)); 741 errorCode = WifiStatusCode.SUCCESS; 742 } 743 } catch (RemoteException e) { 744 handleRemoteException(e, methodStr); 745 errorCode = WifiStatusCode.ERROR_NOT_STARTED; 746 } catch (ServiceSpecificException e) { 747 handleServiceSpecificException(e, methodStr); 748 errorCode = e.errorCode; 749 } catch (IllegalArgumentException e) { 750 handleIllegalArgumentException(e, methodStr); 751 errorCode = WifiStatusCode.ERROR_INVALID_ARGS; 752 } 753 return errorCode; 754 } 755 } 756 frameworkToHalRoamingMode( @ifiManager.RoamingMode int mode)757 private static byte frameworkToHalRoamingMode( 758 @WifiManager.RoamingMode int mode) { 759 switch (mode) { 760 case WifiManager.ROAMING_MODE_NONE: 761 return StaRoamingState.DISABLED; 762 case WifiManager.ROAMING_MODE_NORMAL: 763 return StaRoamingState.ENABLED; 764 case WifiManager.ROAMING_MODE_AGGRESSIVE: 765 return StaRoamingState.AGGRESSIVE; 766 default: 767 throw new IllegalArgumentException("frameworkToHalRoamingMode Invalid mode: " 768 + mode); 769 } 770 } 771 772 /** 773 * Get target wake time (TWT) capabilities. 774 * 775 * @return TWT capabilities as Bundle 776 */ 777 @Override getTwtCapabilities()778 public Bundle getTwtCapabilities() { 779 final String methodStr = "getTwtCapabilities"; 780 synchronized (mLock) { 781 try { 782 if (!isServiceVersionAtLeast(2) || !checkIfaceAndLogFailure(methodStr)) { 783 return null; 784 } 785 android.hardware.wifi.TwtCapabilities halTwtCapabilities = 786 mWifiStaIface.twtGetCapabilities(); 787 if (halTwtCapabilities == null) return null; 788 Bundle twtCapabilities = new Bundle(); 789 twtCapabilities.putBoolean(WifiManager.TWT_CAPABILITIES_KEY_BOOLEAN_TWT_REQUESTER, 790 halTwtCapabilities.isTwtRequesterSupported); 791 twtCapabilities.putInt( 792 WifiManager.TWT_CAPABILITIES_KEY_INT_MIN_WAKE_DURATION_MICROS, 793 halTwtCapabilities.minWakeDurationUs); 794 twtCapabilities.putInt( 795 WifiManager.TWT_CAPABILITIES_KEY_INT_MAX_WAKE_DURATION_MICROS, 796 halTwtCapabilities.maxWakeDurationUs); 797 twtCapabilities.putLong( 798 WifiManager.TWT_CAPABILITIES_KEY_LONG_MIN_WAKE_INTERVAL_MICROS, 799 halTwtCapabilities.minWakeIntervalUs); 800 twtCapabilities.putLong( 801 WifiManager.TWT_CAPABILITIES_KEY_LONG_MAX_WAKE_INTERVAL_MICROS, 802 halTwtCapabilities.maxWakeIntervalUs); 803 return twtCapabilities; 804 } catch (RemoteException e) { 805 handleRemoteException(e, methodStr); 806 } catch (ServiceSpecificException e) { 807 handleServiceSpecificException(e, methodStr); 808 } 809 return null; 810 } 811 } 812 813 /** 814 * Set up a TWT session 815 * 816 * @param cmdId Command ID to use for this invocation. 817 * @param twtRequest TWT request configuration to setup TWT session 818 * @return true if successful, false otherwise. 819 */ 820 @Override setupTwtSession(int cmdId, TwtRequest twtRequest)821 public boolean setupTwtSession(int cmdId, TwtRequest twtRequest) { 822 final String methodStr = "setupTwtSession"; 823 synchronized (mLock) { 824 try { 825 if (!isServiceVersionAtLeast(2) || !checkIfaceAndLogFailure(methodStr)) { 826 return false; 827 } 828 android.hardware.wifi.TwtRequest halTwtRequest = 829 new android.hardware.wifi.TwtRequest(); 830 halTwtRequest.maxWakeDurationUs = twtRequest.getMaxWakeDurationMicros(); 831 halTwtRequest.minWakeDurationUs = twtRequest.getMinWakeDurationMicros(); 832 halTwtRequest.maxWakeIntervalUs = twtRequest.getMaxWakeIntervalMicros(); 833 halTwtRequest.minWakeIntervalUs = twtRequest.getMinWakeIntervalMicros(); 834 mWifiStaIface.twtSessionSetup(cmdId, halTwtRequest); 835 return true; 836 } catch (RemoteException e) { 837 handleRemoteException(e, methodStr); 838 } catch (ServiceSpecificException e) { 839 handleServiceSpecificException(e, methodStr); 840 } 841 return false; 842 } 843 } 844 845 /** 846 * Teardown a TWT session. 847 * 848 * @param cmdId Command ID to use for this invocation. 849 * @param sessionId TWT session identifier 850 * @return true if successful, false otherwise. 851 */ 852 @Override tearDownTwtSession(int cmdId, int sessionId)853 public boolean tearDownTwtSession(int cmdId, int sessionId) { 854 final String methodStr = "tearDownTwtSession"; 855 synchronized (mLock) { 856 try { 857 if (!isServiceVersionAtLeast(2) || !checkIfaceAndLogFailure(methodStr)) { 858 return false; 859 } 860 mWifiStaIface.twtSessionTeardown(cmdId, sessionId); 861 return true; 862 } catch (RemoteException e) { 863 handleRemoteException(e, methodStr); 864 } catch (ServiceSpecificException e) { 865 handleServiceSpecificException(e, methodStr); 866 } 867 return false; 868 } 869 } 870 871 /** 872 * Get stats for the TWT session. 873 * 874 * @param cmdId Command ID to use for this invocation. 875 * @param sessionId TWT session identifier 876 * @return true if successful, false otherwise. 877 */ 878 @Override getStatsTwtSession(int cmdId, int sessionId)879 public boolean getStatsTwtSession(int cmdId, int sessionId) { 880 final String methodStr = "getStatsTwtSession"; 881 synchronized (mLock) { 882 try { 883 if (!isServiceVersionAtLeast(2) || !checkIfaceAndLogFailure(methodStr)) { 884 return false; 885 } 886 mWifiStaIface.twtSessionGetStats(cmdId, sessionId); 887 return true; 888 } catch (RemoteException e) { 889 handleRemoteException(e, methodStr); 890 } catch (ServiceSpecificException e) { 891 handleServiceSpecificException(e, methodStr); 892 } 893 return false; 894 } 895 } 896 897 private class StaIfaceEventCallback extends IWifiStaIfaceEventCallback.Stub { 898 @Override onBackgroundScanFailure(int cmdId)899 public void onBackgroundScanFailure(int cmdId) { 900 if (mFrameworkCallback == null) return; 901 mFrameworkCallback.onBackgroundScanFailure(cmdId); 902 } 903 904 @Override onBackgroundFullScanResult(int cmdId, int bucketsScanned, StaScanResult result)905 public void onBackgroundFullScanResult(int cmdId, int bucketsScanned, 906 StaScanResult result) { 907 if (mFrameworkCallback == null) return; 908 ScanResult frameworkScanResult = halToFrameworkScanResult(result); 909 if (frameworkScanResult == null) { 910 Log.e(TAG, "Unable to convert scan result from HAL to framework"); 911 return; 912 } 913 mFrameworkCallback.onBackgroundFullScanResult(cmdId, bucketsScanned, 914 frameworkScanResult); 915 } 916 917 @Override onBackgroundScanResults(int cmdId, StaScanData[] scanDatas)918 public void onBackgroundScanResults(int cmdId, StaScanData[] scanDatas) { 919 if (mFrameworkCallback == null) return; 920 WifiScanner.ScanData[] frameworkScanDatas = halToFrameworkScanDatas(cmdId, scanDatas); 921 mFrameworkCallback.onBackgroundScanResults(cmdId, frameworkScanDatas); 922 } 923 924 @Override onRssiThresholdBreached(int cmdId, byte[ ] currBssid, int currRssi)925 public void onRssiThresholdBreached(int cmdId, byte[/* 6 */] currBssid, int currRssi) { 926 if (mFrameworkCallback == null) return; 927 mFrameworkCallback.onRssiThresholdBreached(cmdId, currBssid, currRssi); 928 } 929 930 @Override getInterfaceHash()931 public String getInterfaceHash() { 932 return IWifiStaIfaceEventCallback.HASH; 933 } 934 935 @Override getInterfaceVersion()936 public int getInterfaceVersion() { 937 return IWifiStaIfaceEventCallback.VERSION; 938 } 939 940 @Override onTwtFailure(int cmdId, byte twtErrorCode)941 public void onTwtFailure(int cmdId, byte twtErrorCode) { 942 if (mFrameworkCallback == null) return; 943 @TwtErrorCode int errorCode; 944 switch (twtErrorCode) { 945 case TwtErrorCode.INVALID_PARAMS: 946 errorCode = TwtSessionCallback.TWT_ERROR_CODE_INVALID_PARAMS; 947 break; 948 case TwtErrorCode.MAX_SESSION_REACHED: 949 errorCode = TwtSessionCallback.TWT_ERROR_CODE_MAX_SESSIONS_REACHED; 950 break; 951 case TwtErrorCode.NOT_AVAILABLE: 952 errorCode = TwtSessionCallback.TWT_ERROR_CODE_NOT_AVAILABLE; 953 break; 954 case TwtErrorCode.NOT_SUPPORTED: 955 errorCode = TwtSessionCallback.TWT_ERROR_CODE_NOT_SUPPORTED; 956 break; 957 case TwtErrorCode.PEER_NOT_SUPPORTED: 958 errorCode = TwtSessionCallback.TWT_ERROR_CODE_AP_NOT_SUPPORTED; 959 break; 960 case TwtErrorCode.PEER_REJECTED: 961 errorCode = TwtSessionCallback.TWT_ERROR_CODE_AP_REJECTED; 962 break; 963 case TwtErrorCode.TIMEOUT: 964 errorCode = TwtSessionCallback.TWT_ERROR_CODE_TIMEOUT; 965 break; 966 case TwtErrorCode.ALREADY_RESUMED: 967 case TwtErrorCode.ALREADY_SUSPENDED: 968 case TwtErrorCode.FAILURE_UNKNOWN: 969 default: 970 errorCode = TwtSessionCallback.TWT_REASON_CODE_UNKNOWN; 971 } 972 mFrameworkCallback.onTwtFailure(cmdId, errorCode); 973 } 974 975 @Override onTwtSessionCreate(int cmdId, TwtSession twtSession)976 public void onTwtSessionCreate(int cmdId, TwtSession twtSession) { 977 if (mFrameworkCallback == null || twtSession == null) return; 978 mFrameworkCallback.onTwtSessionCreate(cmdId, twtSession.wakeDurationUs, 979 twtSession.wakeDurationUs, twtSession.mloLinkId, twtSession.sessionId); 980 } 981 982 @Override onTwtSessionUpdate(int cmdId, TwtSession twtSession)983 public void onTwtSessionUpdate(int cmdId, TwtSession twtSession) { 984 //TODO: Implementation 985 } 986 987 @Override onTwtSessionResume(int cmdId, int sessionId)988 public void onTwtSessionResume(int cmdId, int sessionId) { 989 //TODO: Implementation 990 } 991 992 @Override onTwtSessionSuspend(int cmdId, int sessionId)993 public void onTwtSessionSuspend(int cmdId, int sessionId) { 994 //TODO: Implementation 995 } 996 997 @Override onTwtSessionTeardown(int cmdId, int twtSessionId, byte twtReasonCode)998 public void onTwtSessionTeardown(int cmdId, int twtSessionId, byte twtReasonCode) { 999 if (mFrameworkCallback == null) return; 1000 @TwtTeardownReasonCode int reasonCode; 1001 switch (twtReasonCode) { 1002 case TwtTeardownReasonCode.INTERNALLY_INITIATED: 1003 reasonCode = TwtSessionCallback.TWT_REASON_CODE_INTERNALLY_INITIATED; 1004 break; 1005 case TwtTeardownReasonCode.LOCALLY_REQUESTED: 1006 reasonCode = TwtSessionCallback.TWT_REASON_CODE_LOCALLY_REQUESTED; 1007 break; 1008 case TwtTeardownReasonCode.PEER_INITIATED: 1009 reasonCode = TwtSessionCallback.TWT_REASON_CODE_PEER_INITIATED; 1010 break; 1011 case TwtTeardownReasonCode.UNKNOWN: 1012 default: 1013 reasonCode = TwtSessionCallback.TWT_REASON_CODE_UNKNOWN; 1014 } 1015 mFrameworkCallback.onTwtSessionTeardown(cmdId, twtSessionId, reasonCode); 1016 } 1017 1018 @Override onTwtSessionStats(int cmdId, int twtSessionId, TwtSessionStats twtSessionStats)1019 public void onTwtSessionStats(int cmdId, int twtSessionId, 1020 TwtSessionStats twtSessionStats) { 1021 if (mFrameworkCallback == null) return; 1022 Bundle twtStats = new Bundle(); 1023 twtStats.putInt( 1024 android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_COUNT, 1025 twtSessionStats.avgTxPktCount); 1026 twtStats.putInt( 1027 android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_TX_PACKET_SIZE, 1028 twtSessionStats.avgTxPktSize); 1029 twtStats.putInt( 1030 android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_COUNT, 1031 twtSessionStats.avgRxPktCount); 1032 twtStats.putInt( 1033 android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_RX_PACKET_SIZE, 1034 twtSessionStats.avgRxPktSize); 1035 twtStats.putInt( 1036 android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS, 1037 twtSessionStats.avgEospDurationUs); 1038 twtStats.putInt( 1039 android.net.wifi.twt.TwtSession.TWT_STATS_KEY_INT_AVERAGE_EOSP_DURATION_MICROS, 1040 twtSessionStats.eospCount); 1041 mFrameworkCallback.onTwtSessionStats(cmdId, twtSessionId, twtStats); 1042 } 1043 } 1044 1045 // Utilities 1046 1047 // Only sets the fields of ScanResult used by Gscan clients. halToFrameworkScanResult(StaScanResult scanResult)1048 private ScanResult halToFrameworkScanResult(StaScanResult scanResult) { 1049 if (scanResult == null) return null; 1050 WifiSsid originalSsid = WifiSsid.fromBytes(scanResult.ssid); 1051 MacAddress bssid; 1052 try { 1053 bssid = MacAddress.fromString(NativeUtil.macAddressFromByteArray(scanResult.bssid)); 1054 } catch (IllegalArgumentException e) { 1055 Log.e(TAG, "Failed to get BSSID of scan result: " + e); 1056 return null; 1057 } 1058 ScanResult frameworkScanResult = new ScanResult(); 1059 frameworkScanResult.setWifiSsid(mSsidTranslator.getTranslatedSsidAndRecordBssidCharset( 1060 originalSsid, bssid)); 1061 frameworkScanResult.BSSID = bssid.toString(); 1062 frameworkScanResult.level = scanResult.rssi; 1063 frameworkScanResult.frequency = scanResult.frequency; 1064 frameworkScanResult.timestamp = scanResult.timeStampInUs; 1065 return frameworkScanResult; 1066 } 1067 aidlToFrameworkScanResults(StaScanResult[] scanResults)1068 private ScanResult[] aidlToFrameworkScanResults(StaScanResult[] scanResults) { 1069 if (scanResults == null || scanResults.length == 0) return new ScanResult[0]; 1070 ScanResult[] frameworkScanResults = new ScanResult[scanResults.length]; 1071 int i = 0; 1072 for (StaScanResult scanResult : scanResults) { 1073 ScanResult frameworkScanResult = halToFrameworkScanResult(scanResult); 1074 if (frameworkScanResult == null) { 1075 Log.e(TAG, "halToFrameworkScanResults: unable to convert hidl to framework " 1076 + "scan result!"); 1077 continue; 1078 } 1079 frameworkScanResults[i++] = frameworkScanResult; 1080 } 1081 return frameworkScanResults; 1082 } 1083 halToFrameworkScanDataFlags(int flag)1084 private static int halToFrameworkScanDataFlags(int flag) { 1085 if (flag == StaScanDataFlagMask.INTERRUPTED) { 1086 return 1; 1087 } else { 1088 return 0; 1089 } 1090 } 1091 halToFrameworkScanDatas(int cmdId, StaScanData[] scanDatas)1092 private WifiScanner.ScanData[] halToFrameworkScanDatas(int cmdId, StaScanData[] scanDatas) { 1093 if (scanDatas == null || scanDatas.length == 0) return new WifiScanner.ScanData[0]; 1094 WifiScanner.ScanData[] frameworkScanDatas = new WifiScanner.ScanData[scanDatas.length]; 1095 int i = 0; 1096 for (StaScanData scanData : scanDatas) { 1097 int flags = halToFrameworkScanDataFlags(scanData.flags); 1098 ScanResult[] frameworkScanResults = aidlToFrameworkScanResults(scanData.results); 1099 frameworkScanDatas[i++] = 1100 new WifiScanner.ScanData(cmdId, flags, scanData.bucketsScanned, 1101 WifiScanner.WIFI_BAND_UNSPECIFIED, frameworkScanResults); 1102 } 1103 return frameworkScanDatas; 1104 } 1105 1106 @WifiAnnotations.WifiStandard wifiRatePreambleToWifiStandard(int wifiRatePreamble)1107 private static int wifiRatePreambleToWifiStandard(int wifiRatePreamble) { 1108 switch (wifiRatePreamble) { 1109 case WifiRatePreamble.CCK: 1110 case WifiRatePreamble.OFDM: 1111 return ScanResult.WIFI_STANDARD_LEGACY; 1112 case WifiRatePreamble.HT: 1113 return ScanResult.WIFI_STANDARD_11N; 1114 case WifiRatePreamble.VHT: 1115 return ScanResult.WIFI_STANDARD_11AC; 1116 case WifiRatePreamble.HE: 1117 return ScanResult.WIFI_STANDARD_11AX; 1118 case WifiRatePreamble.EHT: 1119 return ScanResult.WIFI_STANDARD_11BE; 1120 default: 1121 return ScanResult.WIFI_STANDARD_UNKNOWN; 1122 } 1123 } 1124 halToFrameworkCachedScanResult(CachedScanResult scanResult)1125 private ScanResult halToFrameworkCachedScanResult(CachedScanResult scanResult) { 1126 if (scanResult == null) return null; 1127 WifiSsid originalSsid = WifiSsid.fromBytes(scanResult.ssid); 1128 MacAddress bssid; 1129 try { 1130 bssid = MacAddress.fromString(NativeUtil.macAddressFromByteArray(scanResult.bssid)); 1131 } catch (IllegalArgumentException e) { 1132 Log.e(TAG, "Failed to get BSSID of scan result: " + e); 1133 return null; 1134 } 1135 ScanResult frameworkScanResult = new ScanResult(); 1136 frameworkScanResult.setWifiSsid(mSsidTranslator.getTranslatedSsidAndRecordBssidCharset( 1137 originalSsid, bssid)); 1138 frameworkScanResult.BSSID = bssid.toString(); 1139 frameworkScanResult.level = scanResult.rssiDbm; 1140 frameworkScanResult.frequency = scanResult.frequencyMhz; 1141 frameworkScanResult.timestamp = scanResult.timeStampInUs; 1142 frameworkScanResult.channelWidth = HalAidlUtil 1143 .getChannelBandwidthFromHal(scanResult.channelWidthMhz); 1144 frameworkScanResult.setWifiStandard( 1145 wifiRatePreambleToWifiStandard(scanResult.preambleType)); 1146 return frameworkScanResult; 1147 } 1148 aidlToFrameworkCachedScanResults(CachedScanResult[] cachedScanResults)1149 private ScanResult[] aidlToFrameworkCachedScanResults(CachedScanResult[] cachedScanResults) { 1150 if (cachedScanResults == null) return new ScanResult[0]; 1151 List<ScanResult> frameworkScanResults = new ArrayList<>(); 1152 for (CachedScanResult cachedScanResult : cachedScanResults) { 1153 ScanResult frameworkScanResult = halToFrameworkCachedScanResult(cachedScanResult); 1154 if (frameworkScanResult == null) { 1155 Log.e(TAG, "aidlToFrameworkCachedScanResults: unable to convert aidl to framework " 1156 + "scan result!"); 1157 continue; 1158 } 1159 frameworkScanResults.add(frameworkScanResult); 1160 } 1161 return frameworkScanResults.toArray(new ScanResult[0]); 1162 } 1163 halToFrameworkCachedScanData(CachedScanData cachedScanData)1164 private WifiScanner.ScanData halToFrameworkCachedScanData(CachedScanData cachedScanData) { 1165 if (cachedScanData == null) return null; 1166 ScanResult[] scanResults = aidlToFrameworkCachedScanResults( 1167 cachedScanData.cachedScanResults); 1168 1169 // Todo b/319658055: map cachedScanData.scannedFrequenciesMhz to WifiScanner.WifiBand 1170 WifiScanner.ScanData frameworkScanData = new WifiScanner.ScanData(0, 0, 1171 0, WifiScanner.WIFI_BAND_UNSPECIFIED, scanResults); 1172 1173 return frameworkScanData; 1174 } 1175 frameworkToHalStaRoamingConfig(List<MacAddress> bssidBlocklist, List<byte[]> ssidAllowlist)1176 private static StaRoamingConfig frameworkToHalStaRoamingConfig(List<MacAddress> bssidBlocklist, 1177 List<byte[]> ssidAllowlist) { 1178 StaRoamingConfig config = new StaRoamingConfig(); 1179 config.bssidBlocklist = new android.hardware.wifi.MacAddress[bssidBlocklist.size()]; 1180 config.ssidAllowlist = new Ssid[ssidAllowlist.size()]; 1181 for (int i = 0; i < bssidBlocklist.size(); i++) { 1182 android.hardware.wifi.MacAddress mac = new android.hardware.wifi.MacAddress(); 1183 mac.data = bssidBlocklist.get(i).toByteArray(); 1184 config.bssidBlocklist[i] = mac; 1185 } 1186 for (int i = 0; i < ssidAllowlist.size(); i++) { 1187 Ssid ssid = new Ssid(); 1188 ssid.data = ssidAllowlist.get(i); 1189 config.ssidAllowlist[i] = ssid; 1190 } 1191 return config; 1192 } 1193 halToFrameworkPktFateFrameType(int type)1194 private static byte halToFrameworkPktFateFrameType(int type) throws IllegalArgumentException { 1195 switch (type) { 1196 case WifiDebugPacketFateFrameType.UNKNOWN: 1197 return WifiLoggerHal.FRAME_TYPE_UNKNOWN; 1198 case WifiDebugPacketFateFrameType.ETHERNET_II: 1199 return WifiLoggerHal.FRAME_TYPE_ETHERNET_II; 1200 case WifiDebugPacketFateFrameType.MGMT_80211: 1201 return WifiLoggerHal.FRAME_TYPE_80211_MGMT; 1202 default: 1203 throw new IllegalArgumentException("bad " + type); 1204 } 1205 } 1206 halToFrameworkRxPktFate(int type)1207 private static byte halToFrameworkRxPktFate(int type) throws IllegalArgumentException { 1208 switch (type) { 1209 case WifiDebugRxPacketFate.SUCCESS: 1210 return WifiLoggerHal.RX_PKT_FATE_SUCCESS; 1211 case WifiDebugRxPacketFate.FW_QUEUED: 1212 return WifiLoggerHal.RX_PKT_FATE_FW_QUEUED; 1213 case WifiDebugRxPacketFate.FW_DROP_FILTER: 1214 return WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER; 1215 case WifiDebugRxPacketFate.FW_DROP_INVALID: 1216 return WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID; 1217 case WifiDebugRxPacketFate.FW_DROP_NOBUFS: 1218 return WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS; 1219 case WifiDebugRxPacketFate.FW_DROP_OTHER: 1220 return WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER; 1221 case WifiDebugRxPacketFate.DRV_QUEUED: 1222 return WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED; 1223 case WifiDebugRxPacketFate.DRV_DROP_FILTER: 1224 return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER; 1225 case WifiDebugRxPacketFate.DRV_DROP_INVALID: 1226 return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID; 1227 case WifiDebugRxPacketFate.DRV_DROP_NOBUFS: 1228 return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS; 1229 case WifiDebugRxPacketFate.DRV_DROP_OTHER: 1230 return WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER; 1231 default: 1232 throw new IllegalArgumentException("bad " + type); 1233 } 1234 } 1235 halToFrameworkTxPktFate(int type)1236 private static byte halToFrameworkTxPktFate(int type) throws IllegalArgumentException { 1237 switch (type) { 1238 case WifiDebugTxPacketFate.ACKED: 1239 return WifiLoggerHal.TX_PKT_FATE_ACKED; 1240 case WifiDebugTxPacketFate.SENT: 1241 return WifiLoggerHal.TX_PKT_FATE_SENT; 1242 case WifiDebugTxPacketFate.FW_QUEUED: 1243 return WifiLoggerHal.TX_PKT_FATE_FW_QUEUED; 1244 case WifiDebugTxPacketFate.FW_DROP_INVALID: 1245 return WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID; 1246 case WifiDebugTxPacketFate.FW_DROP_NOBUFS: 1247 return WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS; 1248 case WifiDebugTxPacketFate.FW_DROP_OTHER: 1249 return WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER; 1250 case WifiDebugTxPacketFate.DRV_QUEUED: 1251 return WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED; 1252 case WifiDebugTxPacketFate.DRV_DROP_INVALID: 1253 return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID; 1254 case WifiDebugTxPacketFate.DRV_DROP_NOBUFS: 1255 return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS; 1256 case WifiDebugTxPacketFate.DRV_DROP_OTHER: 1257 return WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER; 1258 default: 1259 throw new IllegalArgumentException("bad " + type); 1260 } 1261 } 1262 hasCapability(long capabilities, long desiredCapability)1263 private static boolean hasCapability(long capabilities, long desiredCapability) { 1264 return (capabilities & desiredCapability) != 0; 1265 } 1266 1267 @VisibleForTesting halToFrameworkStaFeatureSet(long halFeatureSet)1268 protected static long halToFrameworkStaFeatureSet(long halFeatureSet) { 1269 long features = 0; 1270 if (hasCapability(halFeatureSet, 1271 android.hardware.wifi.IWifiStaIface.FeatureSetMask.HOTSPOT)) { 1272 features |= WifiManager.WIFI_FEATURE_PASSPOINT; 1273 } 1274 if (hasCapability(halFeatureSet, 1275 android.hardware.wifi.IWifiStaIface.FeatureSetMask.BACKGROUND_SCAN)) { 1276 features |= WifiManager.WIFI_FEATURE_SCANNER; 1277 } 1278 if (hasCapability(halFeatureSet, 1279 android.hardware.wifi.IWifiStaIface.FeatureSetMask.PNO)) { 1280 features |= WifiManager.WIFI_FEATURE_PNO; 1281 } 1282 if (hasCapability(halFeatureSet, 1283 android.hardware.wifi.IWifiStaIface.FeatureSetMask.TDLS)) { 1284 features |= WifiManager.WIFI_FEATURE_TDLS; 1285 } 1286 if (hasCapability(halFeatureSet, 1287 android.hardware.wifi.IWifiStaIface.FeatureSetMask.TDLS_OFFCHANNEL)) { 1288 features |= WifiManager.WIFI_FEATURE_TDLS_OFFCHANNEL; 1289 } 1290 if (hasCapability(halFeatureSet, 1291 android.hardware.wifi.IWifiStaIface.FeatureSetMask.LINK_LAYER_STATS)) { 1292 features |= WifiManager.WIFI_FEATURE_LINK_LAYER_STATS; 1293 } 1294 if (hasCapability(halFeatureSet, 1295 android.hardware.wifi.IWifiStaIface.FeatureSetMask.RSSI_MONITOR)) { 1296 features |= WifiManager.WIFI_FEATURE_RSSI_MONITOR; 1297 } 1298 if (hasCapability(halFeatureSet, 1299 android.hardware.wifi.IWifiStaIface.FeatureSetMask.KEEP_ALIVE)) { 1300 features |= WifiManager.WIFI_FEATURE_MKEEP_ALIVE; 1301 } 1302 if (hasCapability(halFeatureSet, 1303 android.hardware.wifi.IWifiStaIface.FeatureSetMask.ND_OFFLOAD)) { 1304 features |= WifiManager.WIFI_FEATURE_CONFIG_NDO; 1305 } 1306 if (hasCapability(halFeatureSet, 1307 android.hardware.wifi.IWifiStaIface.FeatureSetMask.CONTROL_ROAMING)) { 1308 features |= WifiManager.WIFI_FEATURE_CONTROL_ROAMING; 1309 } 1310 if (hasCapability(halFeatureSet, 1311 android.hardware.wifi.IWifiStaIface.FeatureSetMask.PROBE_IE_ALLOWLIST)) { 1312 features |= WifiManager.WIFI_FEATURE_IE_WHITELIST; 1313 } 1314 if (hasCapability(halFeatureSet, 1315 android.hardware.wifi.IWifiStaIface.FeatureSetMask.SCAN_RAND)) { 1316 features |= WifiManager.WIFI_FEATURE_SCAN_RAND; 1317 } 1318 if (hasCapability(halFeatureSet, 1319 android.hardware.wifi.IWifiStaIface.FeatureSetMask.ROAMING_MODE_CONTROL)) { 1320 features |= WifiManager.WIFI_FEATURE_AGGRESSIVE_ROAMING_MODE_SUPPORT; 1321 } 1322 return features; 1323 } 1324 1325 @VisibleForTesting halToFrameworkLinkLayerStats(StaLinkLayerStats stats)1326 WifiLinkLayerStats halToFrameworkLinkLayerStats(StaLinkLayerStats stats) { 1327 if (stats == null) return null; 1328 WifiLinkLayerStats out = new WifiLinkLayerStats(); 1329 setIfaceStats(out, stats.iface); 1330 setRadioStats(out, stats.radios); 1331 out.timeStampInMs = stats.timeStampInMs; 1332 out.version = WifiLinkLayerStats.V1_5; // only used in unit tests, keep latest HIDL 1333 return out; 1334 } 1335 setIfaceStats(WifiLinkLayerStats stats, StaLinkLayerIfaceStats iface)1336 private static void setIfaceStats(WifiLinkLayerStats stats, 1337 StaLinkLayerIfaceStats iface) { 1338 int linkIndex = 0; 1339 if (iface == null || iface.links == null) return; 1340 stats.links = new WifiLinkLayerStats.LinkSpecificStats[iface.links.length]; 1341 for (StaLinkLayerLinkStats link : iface.links) { 1342 setIfaceStatsPerLinkFromAidl(stats, link, linkIndex); 1343 linkIndex++; 1344 } 1345 } 1346 halToFrameworkLinkState( int powerState)1347 private static @WifiUsabilityStatsEntry.LinkState int halToFrameworkLinkState( 1348 int powerState) { 1349 switch(powerState) { 1350 case StaLinkLayerLinkStats.StaLinkState.NOT_IN_USE: 1351 return WifiUsabilityStatsEntry.LINK_STATE_NOT_IN_USE; 1352 case StaLinkLayerLinkStats.StaLinkState.IN_USE: 1353 return WifiUsabilityStatsEntry.LINK_STATE_IN_USE; 1354 default: 1355 return WifiUsabilityStatsEntry.LINK_STATE_UNKNOWN; 1356 } 1357 } 1358 setIfaceStatsPerLinkFromAidl(WifiLinkLayerStats stats, StaLinkLayerLinkStats aidlStats, int linkIndex)1359 private static void setIfaceStatsPerLinkFromAidl(WifiLinkLayerStats stats, 1360 StaLinkLayerLinkStats aidlStats, int linkIndex) { 1361 if (aidlStats == null) return; 1362 stats.links[linkIndex] = new WifiLinkLayerStats.LinkSpecificStats(); 1363 stats.links[linkIndex].link_id = aidlStats.linkId; 1364 stats.links[linkIndex].state = halToFrameworkLinkState(aidlStats.state); 1365 stats.links[linkIndex].radio_id = aidlStats.radioId; 1366 stats.links[linkIndex].frequencyMhz = aidlStats.frequencyMhz; 1367 stats.links[linkIndex].beacon_rx = aidlStats.beaconRx; 1368 stats.links[linkIndex].rssi_mgmt = aidlStats.avgRssiMgmt; 1369 // Statistics are broken out by Wireless Multimedia Extensions categories 1370 // WME Best Effort Access Category 1371 stats.links[linkIndex].rxmpdu_be = aidlStats.wmeBePktStats.rxMpdu; 1372 stats.links[linkIndex].txmpdu_be = aidlStats.wmeBePktStats.txMpdu; 1373 stats.links[linkIndex].lostmpdu_be = aidlStats.wmeBePktStats.lostMpdu; 1374 stats.links[linkIndex].retries_be = aidlStats.wmeBePktStats.retries; 1375 // WME Background Access Category 1376 stats.links[linkIndex].rxmpdu_bk = aidlStats.wmeBkPktStats.rxMpdu; 1377 stats.links[linkIndex].txmpdu_bk = aidlStats.wmeBkPktStats.txMpdu; 1378 stats.links[linkIndex].lostmpdu_bk = aidlStats.wmeBkPktStats.lostMpdu; 1379 stats.links[linkIndex].retries_bk = aidlStats.wmeBkPktStats.retries; 1380 // WME Video Access Category 1381 stats.links[linkIndex].rxmpdu_vi = aidlStats.wmeViPktStats.rxMpdu; 1382 stats.links[linkIndex].txmpdu_vi = aidlStats.wmeViPktStats.txMpdu; 1383 stats.links[linkIndex].lostmpdu_vi = aidlStats.wmeViPktStats.lostMpdu; 1384 stats.links[linkIndex].retries_vi = aidlStats.wmeViPktStats.retries; 1385 // WME Voice Access Category 1386 stats.links[linkIndex].rxmpdu_vo = aidlStats.wmeVoPktStats.rxMpdu; 1387 stats.links[linkIndex].txmpdu_vo = aidlStats.wmeVoPktStats.txMpdu; 1388 stats.links[linkIndex].lostmpdu_vo = aidlStats.wmeVoPktStats.lostMpdu; 1389 stats.links[linkIndex].retries_vo = aidlStats.wmeVoPktStats.retries; 1390 // WME Best Effort Access Category 1391 stats.links[linkIndex].contentionTimeMinBeInUsec = 1392 aidlStats.wmeBeContentionTimeStats.contentionTimeMinInUsec; 1393 stats.links[linkIndex].contentionTimeMaxBeInUsec = 1394 aidlStats.wmeBeContentionTimeStats.contentionTimeMaxInUsec; 1395 stats.links[linkIndex].contentionTimeAvgBeInUsec = 1396 aidlStats.wmeBeContentionTimeStats.contentionTimeAvgInUsec; 1397 stats.links[linkIndex].contentionNumSamplesBe = 1398 aidlStats.wmeBeContentionTimeStats.contentionNumSamples; 1399 // WME Background Access Category 1400 stats.links[linkIndex].contentionTimeMinBkInUsec = 1401 aidlStats.wmeBkContentionTimeStats.contentionTimeMinInUsec; 1402 stats.links[linkIndex].contentionTimeMaxBkInUsec = 1403 aidlStats.wmeBkContentionTimeStats.contentionTimeMaxInUsec; 1404 stats.links[linkIndex].contentionTimeAvgBkInUsec = 1405 aidlStats.wmeBkContentionTimeStats.contentionTimeAvgInUsec; 1406 stats.links[linkIndex].contentionNumSamplesBk = 1407 aidlStats.wmeBkContentionTimeStats.contentionNumSamples; 1408 // WME Video Access Category 1409 stats.links[linkIndex].contentionTimeMinViInUsec = 1410 aidlStats.wmeViContentionTimeStats.contentionTimeMinInUsec; 1411 stats.links[linkIndex].contentionTimeMaxViInUsec = 1412 aidlStats.wmeViContentionTimeStats.contentionTimeMaxInUsec; 1413 stats.links[linkIndex].contentionTimeAvgViInUsec = 1414 aidlStats.wmeViContentionTimeStats.contentionTimeAvgInUsec; 1415 stats.links[linkIndex].contentionNumSamplesVi = 1416 aidlStats.wmeViContentionTimeStats.contentionNumSamples; 1417 // WME Voice Access Category 1418 stats.links[linkIndex].contentionTimeMinVoInUsec = 1419 aidlStats.wmeVoContentionTimeStats.contentionTimeMinInUsec; 1420 stats.links[linkIndex].contentionTimeMaxVoInUsec = 1421 aidlStats.wmeVoContentionTimeStats.contentionTimeMaxInUsec; 1422 stats.links[linkIndex].contentionTimeAvgVoInUsec = 1423 aidlStats.wmeVoContentionTimeStats.contentionTimeAvgInUsec; 1424 stats.links[linkIndex].contentionNumSamplesVo = 1425 aidlStats.wmeVoContentionTimeStats.contentionNumSamples; 1426 stats.links[linkIndex].timeSliceDutyCycleInPercent = aidlStats.timeSliceDutyCycleInPercent; 1427 // Peer information statistics 1428 stats.links[linkIndex].peerInfo = new WifiLinkLayerStats.PeerInfo[aidlStats.peers.length]; 1429 for (int i = 0; i < stats.links[linkIndex].peerInfo.length; i++) { 1430 WifiLinkLayerStats.PeerInfo peer = new WifiLinkLayerStats.PeerInfo(); 1431 StaPeerInfo staPeerInfo = aidlStats.peers[i]; 1432 peer.staCount = (short) staPeerInfo.staCount; 1433 peer.chanUtil = (short) staPeerInfo.chanUtil; 1434 WifiLinkLayerStats.RateStat[] rateStats = 1435 new WifiLinkLayerStats.RateStat[staPeerInfo.rateStats.length]; 1436 for (int j = 0; j < staPeerInfo.rateStats.length; j++) { 1437 rateStats[j] = new WifiLinkLayerStats.RateStat(); 1438 StaRateStat staRateStat = staPeerInfo.rateStats[j]; 1439 rateStats[j].preamble = staRateStat.rateInfo.preamble; 1440 rateStats[j].nss = staRateStat.rateInfo.nss; 1441 rateStats[j].bw = staRateStat.rateInfo.bw; 1442 rateStats[j].rateMcsIdx = staRateStat.rateInfo.rateMcsIdx; 1443 rateStats[j].bitRateInKbps = staRateStat.rateInfo.bitRateInKbps; 1444 rateStats[j].txMpdu = staRateStat.txMpdu; 1445 rateStats[j].rxMpdu = staRateStat.rxMpdu; 1446 rateStats[j].mpduLost = staRateStat.mpduLost; 1447 rateStats[j].retries = staRateStat.retries; 1448 } 1449 peer.rateStats = rateStats; 1450 stats.links[linkIndex].peerInfo[i] = peer; 1451 } 1452 } 1453 setRadioStats(WifiLinkLayerStats stats, StaLinkLayerRadioStats[] radios)1454 private void setRadioStats(WifiLinkLayerStats stats, StaLinkLayerRadioStats[] radios) { 1455 if (radios == null) return; 1456 int radioIndex = 0; 1457 stats.radioStats = new WifiLinkLayerStats.RadioStat[radios.length]; 1458 for (StaLinkLayerRadioStats radioStats : radios) { 1459 WifiLinkLayerStats.RadioStat radio = new WifiLinkLayerStats.RadioStat(); 1460 setFrameworkPerRadioStatsFromAidl(radio, radioStats); 1461 stats.radioStats[radioIndex] = radio; 1462 aggregateFrameworkRadioStatsFromAidl(radioIndex, stats, radioStats); 1463 radioIndex++; 1464 } 1465 } 1466 setFrameworkPerRadioStatsFromAidl(WifiLinkLayerStats.RadioStat radio, StaLinkLayerRadioStats aidlRadioStats)1467 private static void setFrameworkPerRadioStatsFromAidl(WifiLinkLayerStats.RadioStat radio, 1468 StaLinkLayerRadioStats aidlRadioStats) { 1469 radio.radio_id = aidlRadioStats.radioId; 1470 radio.on_time = aidlRadioStats.onTimeInMs; 1471 radio.tx_time = aidlRadioStats.txTimeInMs; 1472 radio.rx_time = aidlRadioStats.rxTimeInMs; 1473 radio.on_time_scan = aidlRadioStats.onTimeInMsForScan; 1474 radio.on_time_nan_scan = aidlRadioStats.onTimeInMsForNanScan; 1475 radio.on_time_background_scan = aidlRadioStats.onTimeInMsForBgScan; 1476 radio.on_time_roam_scan = aidlRadioStats.onTimeInMsForRoamScan; 1477 radio.on_time_pno_scan = aidlRadioStats.onTimeInMsForPnoScan; 1478 radio.on_time_hs20_scan = aidlRadioStats.onTimeInMsForHs20Scan; 1479 /* Copy list of channel stats */ 1480 for (WifiChannelStats channelStats : aidlRadioStats.channelStats) { 1481 WifiLinkLayerStats.ChannelStats channelStatsEntry = 1482 new WifiLinkLayerStats.ChannelStats(); 1483 channelStatsEntry.frequency = channelStats.channel.centerFreq; 1484 channelStatsEntry.radioOnTimeMs = channelStats.onTimeInMs; 1485 channelStatsEntry.ccaBusyTimeMs = channelStats.ccaBusyTimeInMs; 1486 radio.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry); 1487 } 1488 } 1489 aggregateFrameworkRadioStatsFromAidl(int radioIndex, WifiLinkLayerStats stats, StaLinkLayerRadioStats aidlRadioStats)1490 private void aggregateFrameworkRadioStatsFromAidl(int radioIndex, 1491 WifiLinkLayerStats stats, StaLinkLayerRadioStats aidlRadioStats) { 1492 if (!mWifiLinkLayerAllRadiosStatsAggregationEnabled && radioIndex > 0) { 1493 return; 1494 } 1495 // Aggregate the radio stats from all the radios 1496 stats.on_time += aidlRadioStats.onTimeInMs; 1497 stats.tx_time += aidlRadioStats.txTimeInMs; 1498 // Aggregate tx_time_per_level based on the assumption that the length of 1499 // txTimeInMsPerLevel is the same across all radios. So txTimeInMsPerLevel on other 1500 // radios at array indices greater than the length of first radio will be dropped. 1501 if (stats.tx_time_per_level == null) { 1502 stats.tx_time_per_level = new int[aidlRadioStats.txTimeInMsPerLevel.length]; 1503 } 1504 for (int i = 0; i < aidlRadioStats.txTimeInMsPerLevel.length 1505 && i < stats.tx_time_per_level.length; i++) { 1506 stats.tx_time_per_level[i] += aidlRadioStats.txTimeInMsPerLevel[i]; 1507 } 1508 stats.rx_time += aidlRadioStats.rxTimeInMs; 1509 stats.on_time_scan += aidlRadioStats.onTimeInMsForScan; 1510 stats.on_time_nan_scan += aidlRadioStats.onTimeInMsForNanScan; 1511 stats.on_time_background_scan += aidlRadioStats.onTimeInMsForBgScan; 1512 stats.on_time_roam_scan += aidlRadioStats.onTimeInMsForRoamScan; 1513 stats.on_time_pno_scan += aidlRadioStats.onTimeInMsForPnoScan; 1514 stats.on_time_hs20_scan += aidlRadioStats.onTimeInMsForHs20Scan; 1515 /* Copy list of channel stats */ 1516 for (WifiChannelStats channelStats : aidlRadioStats.channelStats) { 1517 WifiLinkLayerStats.ChannelStats channelStatsEntry = 1518 stats.channelStatsMap.get(channelStats.channel.centerFreq); 1519 if (channelStatsEntry == null) { 1520 channelStatsEntry = new WifiLinkLayerStats.ChannelStats(); 1521 channelStatsEntry.frequency = channelStats.channel.centerFreq; 1522 stats.channelStatsMap.put(channelStats.channel.centerFreq, channelStatsEntry); 1523 } 1524 channelStatsEntry.radioOnTimeMs += channelStats.onTimeInMs; 1525 channelStatsEntry.ccaBusyTimeMs += channelStats.ccaBusyTimeInMs; 1526 } 1527 stats.numRadios++; 1528 } 1529 frameworkToHalStaRoamingState(@ifiNative.RoamingEnableState int state)1530 private static byte frameworkToHalStaRoamingState(@WifiNative.RoamingEnableState int state) { 1531 switch (state) { 1532 case WifiNative.DISABLE_FIRMWARE_ROAMING: 1533 return StaRoamingState.DISABLED; 1534 case WifiNative.ENABLE_FIRMWARE_ROAMING: 1535 return StaRoamingState.ENABLED; 1536 default: 1537 Log.e(TAG, "Invalid firmware roaming state enum: " + state); 1538 return -1; 1539 } 1540 } 1541 frameworkToHalBackgroundScanParams( WifiStaIface.StaBackgroundScanParameters frameworkParams)1542 private static StaBackgroundScanParameters frameworkToHalBackgroundScanParams( 1543 WifiStaIface.StaBackgroundScanParameters frameworkParams) 1544 throws IllegalArgumentException { 1545 StaBackgroundScanParameters halParams = new StaBackgroundScanParameters(); 1546 halParams.basePeriodInMs = frameworkParams.basePeriodInMs; 1547 halParams.maxApPerScan = frameworkParams.maxApPerScan; 1548 halParams.reportThresholdPercent = frameworkParams.reportThresholdPercent; 1549 halParams.reportThresholdNumScans = frameworkParams.reportThresholdNumScans; 1550 int numBuckets = frameworkParams.buckets != null ? frameworkParams.buckets.size() : 0; 1551 halParams.buckets = new android.hardware.wifi.StaBackgroundScanBucketParameters[numBuckets]; 1552 if (frameworkParams.buckets != null) { 1553 for (int i = 0; i < numBuckets; i++) { 1554 halParams.buckets[i] = frameworkToHalBucketParams(frameworkParams.buckets.get(i)); 1555 } 1556 } 1557 return halParams; 1558 } 1559 frameworkToHalBucketParams( WifiNative.BucketSettings frameworkBucket)1560 private static StaBackgroundScanBucketParameters frameworkToHalBucketParams( 1561 WifiNative.BucketSettings frameworkBucket) throws IllegalArgumentException { 1562 StaBackgroundScanBucketParameters halBucket = new StaBackgroundScanBucketParameters(); 1563 halBucket.bucketIdx = frameworkBucket.bucket; 1564 halBucket.band = frameworkToHalWifiBand(frameworkBucket.band); 1565 int numChannels = frameworkBucket.channels != null ? frameworkBucket.channels.length : 0; 1566 halBucket.frequencies = new int[numChannels]; 1567 if (frameworkBucket.channels != null) { 1568 for (int i = 0; i < frameworkBucket.channels.length; i++) { 1569 halBucket.frequencies[i] = frameworkBucket.channels[i].frequency; 1570 } 1571 } 1572 halBucket.periodInMs = frameworkBucket.period_ms; 1573 halBucket.eventReportScheme = frameworkToHalReportSchemeMask(frameworkBucket.report_events); 1574 halBucket.exponentialMaxPeriodInMs = frameworkBucket.max_period_ms; 1575 // Although HAL API allows configurable base value for the truncated 1576 // exponential back off scan. Native API and above support only 1577 // truncated binary exponential back off scan. 1578 // Hard code value of base to 2 here. 1579 halBucket.exponentialBase = 2; 1580 halBucket.exponentialStepCount = frameworkBucket.step_count; 1581 return halBucket; 1582 } 1583 frameworkToHalWifiBand(int frameworkBand)1584 private static int frameworkToHalWifiBand(int frameworkBand) throws IllegalArgumentException { 1585 switch (frameworkBand) { 1586 case WifiScanner.WIFI_BAND_UNSPECIFIED: 1587 return WifiBand.BAND_UNSPECIFIED; 1588 case WifiScanner.WIFI_BAND_24_GHZ: 1589 return WifiBand.BAND_24GHZ; 1590 case WifiScanner.WIFI_BAND_5_GHZ: 1591 return WifiBand.BAND_5GHZ; 1592 case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: 1593 return WifiBand.BAND_5GHZ_DFS; 1594 case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS: 1595 return WifiBand.BAND_5GHZ_WITH_DFS; 1596 case WifiScanner.WIFI_BAND_BOTH: 1597 return WifiBand.BAND_24GHZ_5GHZ; 1598 case WifiScanner.WIFI_BAND_BOTH_WITH_DFS: 1599 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS; 1600 case WifiScanner.WIFI_BAND_6_GHZ: 1601 return WifiBand.BAND_6GHZ; 1602 case WifiScanner.WIFI_BAND_24_5_6_GHZ: 1603 return WifiBand.BAND_24GHZ_5GHZ_6GHZ; 1604 case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ: 1605 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ; 1606 case WifiScanner.WIFI_BAND_60_GHZ: 1607 return WifiBand.BAND_60GHZ; 1608 case WifiScanner.WIFI_BAND_24_5_6_60_GHZ: 1609 return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ; 1610 case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ: 1611 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ; 1612 case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS: 1613 default: 1614 throw new IllegalArgumentException("bad band " + frameworkBand); 1615 } 1616 } 1617 frameworkToHalReportSchemeMask(int reportUnderscoreEvents)1618 private static int frameworkToHalReportSchemeMask(int reportUnderscoreEvents) 1619 throws IllegalArgumentException { 1620 int ans = 0; 1621 BitMask in = new BitMask(reportUnderscoreEvents); 1622 if (in.testAndClear(WifiScanner.REPORT_EVENT_AFTER_EACH_SCAN)) { 1623 ans |= StaBackgroundScanBucketEventReportSchemeMask.EACH_SCAN; 1624 } 1625 if (in.testAndClear(WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT)) { 1626 ans |= StaBackgroundScanBucketEventReportSchemeMask.FULL_RESULTS; 1627 } 1628 if (in.testAndClear(WifiScanner.REPORT_EVENT_NO_BATCH)) { 1629 ans |= StaBackgroundScanBucketEventReportSchemeMask.NO_BATCH; 1630 } 1631 if (in.value != 0) throw new IllegalArgumentException("bad " + reportUnderscoreEvents); 1632 return ans; 1633 } 1634 checkIfaceAndLogFailure(String methodStr)1635 private boolean checkIfaceAndLogFailure(String methodStr) { 1636 if (mWifiStaIface == null) { 1637 Log.e(TAG, "Unable to call " + methodStr + " because iface is null."); 1638 return false; 1639 } 1640 return true; 1641 } 1642 handleRemoteException(RemoteException e, String methodStr)1643 private void handleRemoteException(RemoteException e, String methodStr) { 1644 mWifiStaIface = null; 1645 mIfaceName = null; 1646 Log.e(TAG, methodStr + " failed with remote exception: " + e); 1647 } 1648 handleServiceSpecificException(ServiceSpecificException e, String methodStr)1649 private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) { 1650 Log.e(TAG, methodStr + " failed with service-specific exception: " + e); 1651 } 1652 handleIllegalArgumentException(IllegalArgumentException e, String methodStr)1653 private void handleIllegalArgumentException(IllegalArgumentException e, String methodStr) { 1654 Log.e(TAG, methodStr + " failed with illegal argument exception: " + e); 1655 } 1656 } 1657