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.hardware.wifi.WifiChannelWidthInMhz.WIDTH_160; 20 import static android.hardware.wifi.WifiChannelWidthInMhz.WIDTH_320; 21 import static android.hardware.wifi.WifiChannelWidthInMhz.WIDTH_40; 22 import static android.hardware.wifi.WifiChannelWidthInMhz.WIDTH_80; 23 import static android.hardware.wifi.WifiChannelWidthInMhz.WIDTH_80P80; 24 import static android.net.wifi.CoexUnsafeChannel.POWER_CAP_NONE; 25 26 import android.annotation.NonNull; 27 import android.annotation.Nullable; 28 import android.content.Context; 29 import android.hardware.wifi.AfcChannelAllowance; 30 import android.hardware.wifi.AvailableAfcChannelInfo; 31 import android.hardware.wifi.AvailableAfcFrequencyInfo; 32 import android.hardware.wifi.IWifiApIface; 33 import android.hardware.wifi.IWifiChip.ChannelCategoryMask; 34 import android.hardware.wifi.IWifiChip.CoexRestriction; 35 import android.hardware.wifi.IWifiChip.FeatureSetMask; 36 import android.hardware.wifi.IWifiChip.LatencyMode; 37 import android.hardware.wifi.IWifiChip.MultiStaUseCase; 38 import android.hardware.wifi.IWifiChip.TxPowerScenario; 39 import android.hardware.wifi.IWifiChip.UsableChannelFilter; 40 import android.hardware.wifi.IWifiChip.VoipMode; 41 import android.hardware.wifi.IWifiChipEventCallback; 42 import android.hardware.wifi.IWifiNanIface; 43 import android.hardware.wifi.IWifiP2pIface; 44 import android.hardware.wifi.IWifiRttController; 45 import android.hardware.wifi.IWifiStaIface; 46 import android.hardware.wifi.IfaceConcurrencyType; 47 import android.hardware.wifi.IfaceType; 48 import android.hardware.wifi.WifiAntennaMode; 49 import android.hardware.wifi.WifiBand; 50 import android.hardware.wifi.WifiChipCapabilities; 51 import android.hardware.wifi.WifiDebugHostWakeReasonStats; 52 import android.hardware.wifi.WifiDebugRingBufferFlags; 53 import android.hardware.wifi.WifiDebugRingBufferStatus; 54 import android.hardware.wifi.WifiIfaceMode; 55 import android.hardware.wifi.WifiRadioCombination; 56 import android.hardware.wifi.WifiRadioConfiguration; 57 import android.hardware.wifi.WifiStatusCode; 58 import android.hardware.wifi.WifiUsableChannel; 59 import android.net.wifi.CoexUnsafeChannel; 60 import android.net.wifi.OuiKeyedData; 61 import android.net.wifi.ScanResult; 62 import android.net.wifi.WifiAnnotations; 63 import android.net.wifi.WifiAvailableChannel; 64 import android.net.wifi.WifiManager; 65 import android.net.wifi.WifiScanner; 66 import android.os.RemoteException; 67 import android.os.ServiceSpecificException; 68 import android.util.Log; 69 70 import com.android.internal.annotations.VisibleForTesting; 71 import com.android.modules.utils.build.SdkLevel; 72 import com.android.server.wifi.SarInfo; 73 import com.android.server.wifi.SsidTranslator; 74 import com.android.server.wifi.WifiNative; 75 import com.android.server.wifi.WlanWakeReasonAndCounts; 76 import com.android.server.wifi.util.BitMask; 77 import com.android.server.wifi.util.HalAidlUtil; 78 79 import java.util.ArrayList; 80 import java.util.Arrays; 81 import java.util.List; 82 83 /** 84 * AIDL implementation of the WifiChip interface. 85 */ 86 public class WifiChipAidlImpl implements IWifiChip { 87 private static final String TAG = "WifiChipAidlImpl"; 88 private android.hardware.wifi.IWifiChip mWifiChip; 89 private android.hardware.wifi.IWifiChipEventCallback mHalCallback; 90 private WifiChip.Callback mFrameworkCallback; 91 private final Object mLock = new Object(); 92 private Context mContext; 93 private SsidTranslator mSsidTranslator; 94 private long mHalFeatureSet; 95 WifiChipAidlImpl(@onNull android.hardware.wifi.IWifiChip chip, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)96 public WifiChipAidlImpl(@NonNull android.hardware.wifi.IWifiChip chip, 97 @NonNull Context context, @NonNull SsidTranslator ssidTranslator) { 98 mWifiChip = chip; 99 mContext = context; 100 mSsidTranslator = ssidTranslator; 101 } 102 103 /** 104 * See comments for {@link IWifiChip#configureChip(int)} 105 */ 106 @Override configureChip(int modeId)107 public boolean configureChip(int modeId) { 108 final String methodStr = "configureChip"; 109 synchronized (mLock) { 110 try { 111 if (!checkIfaceAndLogFailure(methodStr)) return false; 112 mWifiChip.configureChip(modeId); 113 return true; 114 } catch (RemoteException e) { 115 handleRemoteException(e, methodStr); 116 } catch (ServiceSpecificException e) { 117 handleServiceSpecificException(e, methodStr); 118 } 119 return false; 120 } 121 } 122 123 /** 124 * See comments for {@link IWifiChip#createApIface(List)} 125 */ 126 @Override 127 @Nullable createApIface(@onNull List<OuiKeyedData> vendorData)128 public WifiApIface createApIface(@NonNull List<OuiKeyedData> vendorData) { 129 final String methodStr = "createApIface"; 130 synchronized (mLock) { 131 try { 132 if (!checkIfaceAndLogFailure(methodStr)) return null; 133 IWifiApIface iface; 134 if (WifiHalAidlImpl.isServiceVersionAtLeast(2) && !vendorData.isEmpty()) { 135 android.hardware.wifi.common.OuiKeyedData[] halVendorData = 136 HalAidlUtil.frameworkToHalOuiKeyedDataList(vendorData); 137 iface = mWifiChip.createApOrBridgedApIface( 138 IfaceConcurrencyType.AP, halVendorData); 139 } else { 140 iface = mWifiChip.createApIface(); 141 } 142 return new WifiApIface(iface); 143 } catch (RemoteException e) { 144 handleRemoteException(e, methodStr); 145 } catch (ServiceSpecificException e) { 146 handleServiceSpecificException(e, methodStr); 147 } 148 return null; 149 } 150 } 151 152 /** 153 * See comments for {@link IWifiChip#createBridgedApIface(List)} 154 */ 155 @Override 156 @Nullable createBridgedApIface(@onNull List<OuiKeyedData> vendorData)157 public WifiApIface createBridgedApIface(@NonNull List<OuiKeyedData> vendorData) { 158 final String methodStr = "createBridgedApIface"; 159 synchronized (mLock) { 160 try { 161 if (!checkIfaceAndLogFailure(methodStr)) return null; 162 IWifiApIface iface; 163 if (WifiHalAidlImpl.isServiceVersionAtLeast(2) && !vendorData.isEmpty()) { 164 android.hardware.wifi.common.OuiKeyedData[] halVendorData = 165 HalAidlUtil.frameworkToHalOuiKeyedDataList(vendorData); 166 iface = mWifiChip.createApOrBridgedApIface( 167 IfaceConcurrencyType.AP_BRIDGED, halVendorData); 168 } else { 169 iface = mWifiChip.createBridgedApIface(); 170 } 171 return new WifiApIface(iface); 172 } catch (RemoteException e) { 173 handleRemoteException(e, methodStr); 174 } catch (ServiceSpecificException e) { 175 handleServiceSpecificException(e, methodStr); 176 } 177 return null; 178 } 179 } 180 181 /** 182 * See comments for {@link IWifiChip#createNanIface()} 183 */ 184 @Override 185 @Nullable createNanIface()186 public WifiNanIface createNanIface() { 187 final String methodStr = "createNanIface"; 188 synchronized (mLock) { 189 try { 190 if (!checkIfaceAndLogFailure(methodStr)) return null; 191 IWifiNanIface iface = mWifiChip.createNanIface(); 192 return new WifiNanIface(iface); 193 } catch (RemoteException e) { 194 handleRemoteException(e, methodStr); 195 } catch (ServiceSpecificException e) { 196 handleServiceSpecificException(e, methodStr); 197 } 198 return null; 199 } 200 } 201 202 /** 203 * See comments for {@link IWifiChip#createP2pIface()} 204 */ 205 @Override 206 @Nullable createP2pIface()207 public WifiP2pIface createP2pIface() { 208 final String methodStr = "createP2pIface"; 209 synchronized (mLock) { 210 try { 211 if (!checkIfaceAndLogFailure(methodStr)) return null; 212 IWifiP2pIface iface = mWifiChip.createP2pIface(); 213 return new WifiP2pIface(iface); 214 } catch (RemoteException e) { 215 handleRemoteException(e, methodStr); 216 } catch (ServiceSpecificException e) { 217 handleServiceSpecificException(e, methodStr); 218 } 219 return null; 220 } 221 } 222 223 /** 224 * See comments for {@link IWifiChip#createRttController()} 225 */ 226 @Override 227 @Nullable createRttController()228 public WifiRttController createRttController() { 229 final String methodStr = "createRttController"; 230 synchronized (mLock) { 231 try { 232 if (!checkIfaceAndLogFailure(methodStr)) return null; 233 IWifiRttController rttController = mWifiChip.createRttController(null); 234 return new WifiRttController(rttController); 235 } catch (RemoteException e) { 236 handleRemoteException(e, methodStr); 237 } catch (ServiceSpecificException e) { 238 handleServiceSpecificException(e, methodStr); 239 } 240 return null; 241 } 242 } 243 244 /** 245 * See comments for {@link IWifiChip#createStaIface()} 246 */ 247 @Override 248 @Nullable createStaIface()249 public WifiStaIface createStaIface() { 250 final String methodStr = "createStaIface"; 251 synchronized (mLock) { 252 try { 253 if (!checkIfaceAndLogFailure(methodStr)) return null; 254 IWifiStaIface iface = mWifiChip.createStaIface(); 255 return new WifiStaIface(iface, mContext, mSsidTranslator); 256 } catch (RemoteException e) { 257 handleRemoteException(e, methodStr); 258 } catch (ServiceSpecificException e) { 259 handleServiceSpecificException(e, methodStr); 260 } 261 return null; 262 } 263 } 264 265 /** 266 * See comments for {@link IWifiChip#enableDebugErrorAlerts(boolean)} 267 */ 268 @Override enableDebugErrorAlerts(boolean enable)269 public boolean enableDebugErrorAlerts(boolean enable) { 270 final String methodStr = "enableDebugErrorAlerts"; 271 synchronized (mLock) { 272 try { 273 if (!checkIfaceAndLogFailure(methodStr)) return false; 274 mWifiChip.enableDebugErrorAlerts(enable); 275 return true; 276 } catch (RemoteException e) { 277 handleRemoteException(e, methodStr); 278 } catch (ServiceSpecificException e) { 279 handleServiceSpecificException(e, methodStr); 280 } 281 return false; 282 } 283 } 284 285 /** 286 * See comments for {@link IWifiChip#flushRingBufferToFile()} 287 */ 288 @Override flushRingBufferToFile()289 public boolean flushRingBufferToFile() { 290 final String methodStr = "flushRingBufferToFile"; 291 synchronized (mLock) { 292 try { 293 if (!checkIfaceAndLogFailure(methodStr)) return false; 294 mWifiChip.flushRingBufferToFile(); 295 return true; 296 } catch (RemoteException e) { 297 handleRemoteException(e, methodStr); 298 } catch (ServiceSpecificException e) { 299 handleServiceSpecificException(e, methodStr); 300 } 301 return false; 302 } 303 } 304 305 /** 306 * See comments for {@link IWifiChip#forceDumpToDebugRingBuffer(String)} 307 */ 308 @Override forceDumpToDebugRingBuffer(String ringName)309 public boolean forceDumpToDebugRingBuffer(String ringName) { 310 final String methodStr = "forceDumpToDebugRingBuffer"; 311 synchronized (mLock) { 312 try { 313 if (!checkIfaceAndLogFailure(methodStr)) return false; 314 mWifiChip.forceDumpToDebugRingBuffer(ringName); 315 return true; 316 } catch (RemoteException e) { 317 handleRemoteException(e, methodStr); 318 } catch (ServiceSpecificException e) { 319 handleServiceSpecificException(e, methodStr); 320 } 321 return false; 322 } 323 } 324 325 /** 326 * See comments for {@link IWifiChip#getApIface(String)} 327 */ 328 @Override 329 @Nullable getApIface(String ifaceName)330 public WifiApIface getApIface(String ifaceName) { 331 final String methodStr = "getApIface"; 332 synchronized (mLock) { 333 try { 334 if (!checkIfaceAndLogFailure(methodStr)) return null; 335 IWifiApIface iface = mWifiChip.getApIface(ifaceName); 336 return new WifiApIface(iface); 337 } catch (RemoteException e) { 338 handleRemoteException(e, methodStr); 339 } catch (ServiceSpecificException e) { 340 handleServiceSpecificException(e, methodStr); 341 } 342 return null; 343 } 344 } 345 346 /** 347 * See comments for {@link IWifiChip#getApIfaceNames()} 348 */ 349 @Override 350 @Nullable getApIfaceNames()351 public List<String> getApIfaceNames() { 352 final String methodStr = "getApIfaceNames"; 353 synchronized (mLock) { 354 try { 355 if (!checkIfaceAndLogFailure(methodStr)) return null; 356 String[] ifaceNames = mWifiChip.getApIfaceNames(); 357 return Arrays.asList(ifaceNames); 358 } catch (RemoteException e) { 359 handleRemoteException(e, methodStr); 360 } catch (ServiceSpecificException e) { 361 handleServiceSpecificException(e, methodStr); 362 } 363 return null; 364 } 365 } 366 367 /** 368 * See comments for {@link IWifiChip#getAvailableModes()} 369 */ 370 @Override 371 @Nullable getAvailableModes()372 public List<WifiChip.ChipMode> getAvailableModes() { 373 final String methodStr = "getAvailableModes"; 374 synchronized (mLock) { 375 try { 376 if (!checkIfaceAndLogFailure(methodStr)) return null; 377 android.hardware.wifi.IWifiChip.ChipMode[] halModes = mWifiChip.getAvailableModes(); 378 return halToFrameworkChipModeList(halModes); 379 } catch (RemoteException e) { 380 handleRemoteException(e, methodStr); 381 } catch (ServiceSpecificException e) { 382 handleServiceSpecificException(e, methodStr); 383 } 384 return null; 385 } 386 } 387 388 /** 389 * See comments for {@link IWifiChip#getCapabilitiesBeforeIfacesExist()} 390 */ 391 @Override getCapabilitiesBeforeIfacesExist()392 public WifiChip.Response<Long> getCapabilitiesBeforeIfacesExist() { 393 final String methodStr = "getCapabilitiesBeforeIfacesExist"; 394 return getCapabilitiesInternal(methodStr); 395 } 396 397 /** 398 * See comments for {@link IWifiChip#getCapabilitiesAfterIfacesExist()} 399 */ 400 @Override getCapabilitiesAfterIfacesExist()401 public WifiChip.Response<Long> getCapabilitiesAfterIfacesExist() { 402 final String methodStr = "getCapabilitiesAfterIfacesExist"; 403 return getCapabilitiesInternal(methodStr); 404 } 405 getCapabilitiesInternal(String methodStr)406 private WifiChip.Response<Long> getCapabilitiesInternal(String methodStr) { 407 // getCapabilities uses the same logic in AIDL, regardless of whether the call 408 // happens before or after any interfaces have been created. 409 WifiChip.Response<Long> featuresResp = new WifiChip.Response<>(0L); 410 synchronized (mLock) { 411 try { 412 if (!checkIfaceAndLogFailure(methodStr)) return featuresResp; 413 mHalFeatureSet = mWifiChip.getFeatureSet(); 414 featuresResp.setValue(halToFrameworkChipFeatureSet(mHalFeatureSet)); 415 featuresResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS); 416 } catch (RemoteException e) { 417 handleRemoteException(e, methodStr); 418 featuresResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION); 419 } catch (ServiceSpecificException e) { 420 handleServiceSpecificException(e, methodStr); 421 // TODO: convert to framework status code once WifiHalAidlImpl exists 422 featuresResp.setStatusCode(e.errorCode); 423 } 424 return featuresResp; 425 } 426 } 427 428 /** 429 * See comments for {@link IWifiChip#getDebugHostWakeReasonStats()} 430 */ 431 @Override 432 @Nullable getDebugHostWakeReasonStats()433 public WlanWakeReasonAndCounts getDebugHostWakeReasonStats() { 434 final String methodStr = "getDebugHostWakeReasonStats"; 435 synchronized (mLock) { 436 try { 437 if (!checkIfaceAndLogFailure(methodStr)) return null; 438 WifiDebugHostWakeReasonStats stats = mWifiChip.getDebugHostWakeReasonStats(); 439 return halToFrameworkWakeReasons(stats); 440 } catch (RemoteException e) { 441 handleRemoteException(e, methodStr); 442 } catch (ServiceSpecificException e) { 443 handleServiceSpecificException(e, methodStr); 444 } 445 return null; 446 } 447 } 448 449 /** 450 * See comments for {@link IWifiChip#getDebugRingBuffersStatus()} 451 */ 452 @Override 453 @Nullable getDebugRingBuffersStatus()454 public List<WifiNative.RingBufferStatus> getDebugRingBuffersStatus() { 455 final String methodStr = "getDebugRingBuffersStatus"; 456 synchronized (mLock) { 457 try { 458 if (!checkIfaceAndLogFailure(methodStr)) return null; 459 WifiDebugRingBufferStatus[] stats = mWifiChip.getDebugRingBuffersStatus(); 460 return halToFrameworkRingBufferStatusList(stats); 461 } catch (RemoteException e) { 462 handleRemoteException(e, methodStr); 463 } catch (ServiceSpecificException e) { 464 handleServiceSpecificException(e, methodStr); 465 } catch (IllegalArgumentException e) { 466 handleIllegalArgumentException(e, methodStr); 467 } 468 return null; 469 } 470 } 471 472 /** 473 * See comments for {@link IWifiChip#getId()} 474 */ 475 @Override getId()476 public int getId() { 477 final String methodStr = "getId"; 478 synchronized (mLock) { 479 try { 480 if (!checkIfaceAndLogFailure(methodStr)) return -1; 481 return mWifiChip.getId(); 482 } catch (RemoteException e) { 483 handleRemoteException(e, methodStr); 484 } catch (ServiceSpecificException e) { 485 handleServiceSpecificException(e, methodStr); 486 } 487 return -1; 488 } 489 } 490 491 /** 492 * See comments for {@link IWifiChip#getMode()} 493 */ 494 @Override getMode()495 public WifiChip.Response<Integer> getMode() { 496 final String methodStr = "getMode"; 497 WifiChip.Response<Integer> modeResp = new WifiChip.Response<>(0); 498 synchronized (mLock) { 499 try { 500 if (!checkIfaceAndLogFailure(methodStr)) return modeResp; 501 int mode = mWifiChip.getMode(); 502 modeResp.setValue(mode); 503 modeResp.setStatusCode(WifiHal.WIFI_STATUS_SUCCESS); 504 } catch (RemoteException e) { 505 handleRemoteException(e, methodStr); 506 modeResp.setStatusCode(WifiHal.WIFI_STATUS_ERROR_REMOTE_EXCEPTION); 507 } catch (ServiceSpecificException e) { 508 handleServiceSpecificException(e, methodStr); 509 // TODO: convert to framework status code once WifiHalAidlImpl exists 510 modeResp.setStatusCode(e.errorCode); 511 } 512 return modeResp; 513 } 514 } 515 516 /** 517 * See comments for {@link IWifiChip#getNanIface(String)} 518 */ 519 @Override 520 @Nullable getNanIface(String ifaceName)521 public WifiNanIface getNanIface(String ifaceName) { 522 final String methodStr = "getNanIface"; 523 synchronized (mLock) { 524 try { 525 if (!checkIfaceAndLogFailure(methodStr)) return null; 526 IWifiNanIface iface = mWifiChip.getNanIface(ifaceName); 527 return new WifiNanIface(iface); 528 } catch (RemoteException e) { 529 handleRemoteException(e, methodStr); 530 } catch (ServiceSpecificException e) { 531 handleServiceSpecificException(e, methodStr); 532 } 533 return null; 534 } 535 } 536 537 /** 538 * See comments for {@link IWifiChip#getNanIfaceNames()} 539 */ 540 @Override 541 @Nullable getNanIfaceNames()542 public List<String> getNanIfaceNames() { 543 final String methodStr = "getNanIfaceNames"; 544 synchronized (mLock) { 545 try { 546 if (!checkIfaceAndLogFailure(methodStr)) return null; 547 String[] ifaceNames = mWifiChip.getNanIfaceNames(); 548 return Arrays.asList(ifaceNames); 549 } catch (RemoteException e) { 550 handleRemoteException(e, methodStr); 551 } catch (ServiceSpecificException e) { 552 handleServiceSpecificException(e, methodStr); 553 } 554 return null; 555 } 556 } 557 558 /** 559 * See comments for {@link IWifiChip#getP2pIface(String)} 560 */ 561 @Override 562 @Nullable getP2pIface(String ifaceName)563 public WifiP2pIface getP2pIface(String ifaceName) { 564 final String methodStr = "getP2pIface"; 565 synchronized (mLock) { 566 try { 567 if (!checkIfaceAndLogFailure(methodStr)) return null; 568 IWifiP2pIface iface = mWifiChip.getP2pIface(ifaceName); 569 return new WifiP2pIface(iface); 570 } catch (RemoteException e) { 571 handleRemoteException(e, methodStr); 572 } catch (ServiceSpecificException e) { 573 handleServiceSpecificException(e, methodStr); 574 } 575 return null; 576 } 577 } 578 579 /** 580 * See comments for {@link IWifiChip#getP2pIfaceNames()} 581 */ 582 @Override 583 @Nullable getP2pIfaceNames()584 public List<String> getP2pIfaceNames() { 585 final String methodStr = "getP2pIfaceNames"; 586 synchronized (mLock) { 587 try { 588 if (!checkIfaceAndLogFailure(methodStr)) return null; 589 String[] ifaceNames = mWifiChip.getP2pIfaceNames(); 590 return Arrays.asList(ifaceNames); 591 } catch (RemoteException e) { 592 handleRemoteException(e, methodStr); 593 } catch (ServiceSpecificException e) { 594 handleServiceSpecificException(e, methodStr); 595 } 596 return null; 597 } 598 } 599 600 /** 601 * See comments for {@link IWifiChip#getStaIface(String)} 602 */ 603 @Override 604 @Nullable getStaIface(String ifaceName)605 public WifiStaIface getStaIface(String ifaceName) { 606 final String methodStr = "getStaIface"; 607 synchronized (mLock) { 608 try { 609 if (!checkIfaceAndLogFailure(methodStr)) return null; 610 IWifiStaIface iface = mWifiChip.getStaIface(ifaceName); 611 return new WifiStaIface(iface, mContext, mSsidTranslator); 612 } catch (RemoteException e) { 613 handleRemoteException(e, methodStr); 614 } catch (ServiceSpecificException e) { 615 handleServiceSpecificException(e, methodStr); 616 } 617 return null; 618 } 619 } 620 621 /** 622 * See comments for {@link IWifiChip#getStaIfaceNames()} 623 */ 624 @Override 625 @Nullable getStaIfaceNames()626 public List<String> getStaIfaceNames() { 627 final String methodStr = "getStaIfaceNames"; 628 synchronized (mLock) { 629 try { 630 if (!checkIfaceAndLogFailure(methodStr)) return null; 631 String[] ifaceNames = mWifiChip.getStaIfaceNames(); 632 return Arrays.asList(ifaceNames); 633 } catch (RemoteException e) { 634 handleRemoteException(e, methodStr); 635 } catch (ServiceSpecificException e) { 636 handleServiceSpecificException(e, methodStr); 637 } 638 return null; 639 } 640 } 641 642 /** 643 * See comments for {@link IWifiChip#getSupportedRadioCombinations()} 644 */ 645 @Override 646 @Nullable getSupportedRadioCombinations()647 public List<WifiChip.WifiRadioCombination> getSupportedRadioCombinations() { 648 final String methodStr = "getSupportedRadioCombinations"; 649 synchronized (mLock) { 650 try { 651 if (!checkIfaceAndLogFailure(methodStr)) return null; 652 WifiRadioCombination[] halCombos = mWifiChip.getSupportedRadioCombinations(); 653 return halToFrameworkRadioCombinations(halCombos); 654 } catch (RemoteException e) { 655 handleRemoteException(e, methodStr); 656 } catch (ServiceSpecificException e) { 657 handleServiceSpecificException(e, methodStr); 658 } 659 return null; 660 } 661 } 662 663 /** 664 * See comments for {@link IWifiChip#getWifiChipCapabilities()} 665 */ getWifiChipCapabilities()666 public WifiChip.WifiChipCapabilities getWifiChipCapabilities() { 667 final String methodStr = "getWifiChipCapabilities"; 668 synchronized (mLock) { 669 try { 670 if (!checkIfaceAndLogFailure(methodStr)) return null; 671 WifiChipCapabilities halCapab = mWifiChip.getWifiChipCapabilities(); 672 return halToFrameworkWifiChipCapabilities(halCapab); 673 } catch (RemoteException e) { 674 handleRemoteException(e, methodStr); 675 } catch (ServiceSpecificException e) { 676 handleServiceSpecificException(e, methodStr); 677 } 678 return null; 679 } 680 } 681 682 /** 683 * See comments for {@link IWifiChip#getUsableChannels(int, int, int)} 684 */ 685 @Override 686 @Nullable getUsableChannels(@ifiScanner.WifiBand int band, @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter)687 public List<WifiAvailableChannel> getUsableChannels(@WifiScanner.WifiBand int band, 688 @WifiAvailableChannel.OpMode int mode, @WifiAvailableChannel.Filter int filter) { 689 final String methodStr = "getUsableChannels"; 690 synchronized (mLock) { 691 try { 692 if (!checkIfaceAndLogFailure(methodStr)) return null; 693 WifiUsableChannel[] halChannels = mWifiChip.getUsableChannels( 694 frameworkToHalWifiBand(band), 695 frameworkToHalIfaceMode(mode), 696 frameworkToHalUsableFilter(filter)); 697 List<WifiAvailableChannel> frameworkChannels = new ArrayList<>(); 698 for (WifiUsableChannel ch : halChannels) { 699 frameworkChannels.add(new WifiAvailableChannel( 700 ch.channel, halToFrameworkIfaceMode(ch.ifaceModeMask), 701 halToFrameworkChannelWidth(ch.channelBandwidth))); 702 } 703 return frameworkChannels; 704 } catch (RemoteException e) { 705 handleRemoteException(e, methodStr); 706 } catch (ServiceSpecificException e) { 707 handleServiceSpecificException(e, methodStr); 708 } catch (IllegalArgumentException e) { 709 handleIllegalArgumentException(e, methodStr); 710 } 711 return null; 712 } 713 } 714 halToFrameworkChannelWidth(int channelBandwidth)715 private @WifiAnnotations.ChannelWidth int halToFrameworkChannelWidth(int channelBandwidth) { 716 switch(channelBandwidth) { 717 case WIDTH_40: 718 return ScanResult.CHANNEL_WIDTH_40MHZ; 719 case WIDTH_80: 720 return ScanResult.CHANNEL_WIDTH_80MHZ; 721 case WIDTH_160: 722 return ScanResult.CHANNEL_WIDTH_160MHZ; 723 case WIDTH_80P80: 724 return ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ; 725 case WIDTH_320: 726 return ScanResult.CHANNEL_WIDTH_320MHZ; 727 default: 728 return ScanResult.CHANNEL_WIDTH_20MHZ; 729 } 730 } 731 732 /** 733 * See comments for {@link IWifiChip#registerCallback(WifiChip.Callback)} 734 */ 735 @Override registerCallback(WifiChip.Callback callback)736 public boolean registerCallback(WifiChip.Callback callback) { 737 final String methodStr = "registerCallback"; 738 synchronized (mLock) { 739 if (!checkIfaceAndLogFailure(methodStr)) return false; 740 if (mFrameworkCallback != null) { 741 Log.e(TAG, "Framework callback is already registered"); 742 return false; 743 } else if (callback == null) { 744 Log.e(TAG, "Cannot register a null callback"); 745 return false; 746 } 747 748 try { 749 mHalCallback = new ChipEventCallback(); 750 mWifiChip.registerEventCallback(mHalCallback); 751 mFrameworkCallback = callback; 752 return true; 753 } catch (RemoteException e) { 754 handleRemoteException(e, methodStr); 755 } catch (ServiceSpecificException e) { 756 handleServiceSpecificException(e, methodStr); 757 } 758 return false; 759 } 760 } 761 762 /** 763 * See comments for {@link IWifiChip#removeApIface(String)} 764 */ 765 @Override removeApIface(String ifaceName)766 public boolean removeApIface(String ifaceName) { 767 final String methodStr = "removeApIface"; 768 synchronized (mLock) { 769 try { 770 if (!checkIfaceAndLogFailure(methodStr)) return false; 771 mWifiChip.removeApIface(ifaceName); 772 return true; 773 } catch (RemoteException e) { 774 handleRemoteException(e, methodStr); 775 } catch (ServiceSpecificException e) { 776 handleServiceSpecificException(e, methodStr); 777 } 778 return false; 779 } 780 } 781 782 /** 783 * See comments for {@link IWifiChip#removeIfaceInstanceFromBridgedApIface(String, String)} 784 */ 785 @Override removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName)786 public boolean removeIfaceInstanceFromBridgedApIface(String brIfaceName, String ifaceName) { 787 final String methodStr = "removeIfaceInstanceFromBridgedApIface"; 788 synchronized (mLock) { 789 try { 790 if (!checkIfaceAndLogFailure(methodStr)) return false; 791 mWifiChip.removeIfaceInstanceFromBridgedApIface(brIfaceName, ifaceName); 792 return true; 793 } catch (RemoteException e) { 794 handleRemoteException(e, methodStr); 795 } catch (ServiceSpecificException e) { 796 handleServiceSpecificException(e, methodStr); 797 } 798 return false; 799 } 800 } 801 802 /** 803 * See comments for {@link IWifiChip#removeNanIface(String)} 804 */ 805 @Override removeNanIface(String ifaceName)806 public boolean removeNanIface(String ifaceName) { 807 final String methodStr = "removeNanIface"; 808 synchronized (mLock) { 809 try { 810 if (!checkIfaceAndLogFailure(methodStr)) return false; 811 mWifiChip.removeNanIface(ifaceName); 812 return true; 813 } catch (RemoteException e) { 814 handleRemoteException(e, methodStr); 815 } catch (ServiceSpecificException e) { 816 handleServiceSpecificException(e, methodStr); 817 } 818 return false; 819 } 820 } 821 822 /** 823 * See comments for {@link IWifiChip#removeP2pIface(String)} 824 */ 825 @Override removeP2pIface(String ifaceName)826 public boolean removeP2pIface(String ifaceName) { 827 final String methodStr = "removeP2pIface"; 828 synchronized (mLock) { 829 try { 830 if (!checkIfaceAndLogFailure(methodStr)) return false; 831 mWifiChip.removeP2pIface(ifaceName); 832 return true; 833 } catch (RemoteException e) { 834 handleRemoteException(e, methodStr); 835 } catch (ServiceSpecificException e) { 836 handleServiceSpecificException(e, methodStr); 837 } 838 return false; 839 } 840 } 841 842 /** 843 * See comments for {@link IWifiChip#removeStaIface(String)} 844 */ 845 @Override removeStaIface(String ifaceName)846 public boolean removeStaIface(String ifaceName) { 847 final String methodStr = "removeStaIface"; 848 synchronized (mLock) { 849 try { 850 if (!checkIfaceAndLogFailure(methodStr)) return false; 851 mWifiChip.removeStaIface(ifaceName); 852 return true; 853 } catch (RemoteException e) { 854 handleRemoteException(e, methodStr); 855 } catch (ServiceSpecificException e) { 856 handleServiceSpecificException(e, methodStr); 857 } 858 return false; 859 } 860 } 861 862 /** 863 * See comments for {@link IWifiChip#requestChipDebugInfo()} 864 */ 865 @Override 866 @Nullable requestChipDebugInfo()867 public WifiChip.ChipDebugInfo requestChipDebugInfo() { 868 final String methodStr = "requestChipDebugInfo"; 869 synchronized (mLock) { 870 try { 871 if (!checkIfaceAndLogFailure(methodStr)) return null; 872 android.hardware.wifi.IWifiChip.ChipDebugInfo info = 873 mWifiChip.requestChipDebugInfo(); 874 return new WifiChip.ChipDebugInfo(info.driverDescription, info.firmwareDescription); 875 } catch (RemoteException e) { 876 handleRemoteException(e, methodStr); 877 } catch (ServiceSpecificException e) { 878 handleServiceSpecificException(e, methodStr); 879 } 880 return null; 881 } 882 } 883 884 /** 885 * See comments for {@link IWifiChip#requestDriverDebugDump()} 886 */ 887 @Override 888 @Nullable requestDriverDebugDump()889 public byte[] requestDriverDebugDump() { 890 final String methodStr = "requestDriverDebugDump"; 891 synchronized (mLock) { 892 try { 893 if (!checkIfaceAndLogFailure(methodStr)) return null; 894 return mWifiChip.requestDriverDebugDump(); 895 } catch (RemoteException e) { 896 handleRemoteException(e, methodStr); 897 } catch (ServiceSpecificException e) { 898 handleServiceSpecificException(e, methodStr); 899 } 900 return null; 901 } 902 } 903 904 /** 905 * See comments for {@link IWifiChip#requestFirmwareDebugDump()} 906 */ 907 @Override 908 @Nullable requestFirmwareDebugDump()909 public byte[] requestFirmwareDebugDump() { 910 final String methodStr = "requestFirmwareDebugDump"; 911 synchronized (mLock) { 912 try { 913 if (!checkIfaceAndLogFailure(methodStr)) return null; 914 return mWifiChip.requestFirmwareDebugDump(); 915 } catch (RemoteException e) { 916 handleRemoteException(e, methodStr); 917 } catch (ServiceSpecificException e) { 918 handleServiceSpecificException(e, methodStr); 919 } 920 return null; 921 } 922 } 923 924 /** 925 * See comments for {@link IWifiChip#selectTxPowerScenario(SarInfo)} 926 */ 927 @Override selectTxPowerScenario(SarInfo sarInfo)928 public boolean selectTxPowerScenario(SarInfo sarInfo) { 929 final String methodStr = "selectTxPowerScenario"; 930 synchronized (mLock) { 931 try { 932 if (!checkIfaceAndLogFailure(methodStr)) return false; 933 if (sarPowerBackoffRequired(sarInfo)) { 934 // Power backoff is needed, so calculate and set the required scenario. 935 int halScenario = frameworkToHalTxPowerScenario(sarInfo); 936 if (sarInfo.setSarScenarioNeeded(halScenario)) { 937 Log.d(TAG, "Attempting to set SAR scenario to " + halScenario); 938 mWifiChip.selectTxPowerScenario(halScenario); 939 } 940 // Reaching here means that setting SAR scenario would be redundant, 941 // do nothing and return with success. 942 return true; 943 } 944 945 // We don't need to perform power backoff, so attempt to reset the SAR scenario. 946 if (sarInfo.resetSarScenarioNeeded()) { 947 Log.d(TAG, "Attempting to reset the SAR scenario"); 948 mWifiChip.resetTxPowerScenario(); 949 } 950 951 // If no if-statement was executed, then setting/resetting the SAR scenario would 952 // have been redundant. Do nothing and return with success. 953 return true; 954 } catch (RemoteException e) { 955 handleRemoteException(e, methodStr); 956 } catch (ServiceSpecificException e) { 957 handleServiceSpecificException(e, methodStr); 958 } catch (IllegalArgumentException e) { 959 handleIllegalArgumentException(e, methodStr); 960 } 961 return false; 962 } 963 } 964 965 /** 966 * See comments for {@link IWifiChip#setCoexUnsafeChannels(List, int)} 967 */ 968 @Override setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions)969 public boolean setCoexUnsafeChannels(List<CoexUnsafeChannel> unsafeChannels, int restrictions) { 970 final String methodStr = "setCoexUnsafeChannels"; 971 synchronized (mLock) { 972 try { 973 if (!checkIfaceAndLogFailure(methodStr)) return false; 974 android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] halChannels = 975 frameworkToHalCoexUnsafeChannels(unsafeChannels); 976 int halRestrictions = frameworkToHalCoexRestrictions(restrictions); 977 mWifiChip.setCoexUnsafeChannels(halChannels, halRestrictions); 978 return true; 979 } catch (RemoteException e) { 980 handleRemoteException(e, methodStr); 981 } catch (ServiceSpecificException e) { 982 handleServiceSpecificException(e, methodStr); 983 } 984 return false; 985 } 986 } 987 988 /** 989 * See comments for {@link IWifiChip#setCountryCode(byte[])} 990 */ 991 @Override setCountryCode(byte[] code)992 public boolean setCountryCode(byte[] code) { 993 final String methodStr = "setCountryCode"; 994 synchronized (mLock) { 995 try { 996 if (!checkIfaceAndLogFailure(methodStr)) return false; 997 mWifiChip.setCountryCode(code); 998 return true; 999 } catch (RemoteException e) { 1000 handleRemoteException(e, methodStr); 1001 } catch (ServiceSpecificException e) { 1002 handleServiceSpecificException(e, methodStr); 1003 } 1004 return false; 1005 } 1006 } 1007 1008 /** 1009 * See comments for {@link IWifiChip#setLowLatencyMode(boolean)} 1010 */ 1011 @Override setLowLatencyMode(boolean enable)1012 public boolean setLowLatencyMode(boolean enable) { 1013 final String methodStr = "setLowLatencyMode"; 1014 synchronized (mLock) { 1015 try { 1016 if (!checkIfaceAndLogFailure(methodStr)) return false; 1017 int mode = enable ? LatencyMode.LOW : LatencyMode.NORMAL; 1018 mWifiChip.setLatencyMode(mode); 1019 return true; 1020 } catch (RemoteException e) { 1021 handleRemoteException(e, methodStr); 1022 } catch (ServiceSpecificException e) { 1023 handleServiceSpecificException(e, methodStr); 1024 } 1025 return false; 1026 } 1027 } 1028 1029 /** 1030 * See comments for {@link IWifiChip#setMultiStaPrimaryConnection(String)} 1031 */ 1032 @Override setMultiStaPrimaryConnection(String ifaceName)1033 public boolean setMultiStaPrimaryConnection(String ifaceName) { 1034 final String methodStr = "setMultiStaPrimaryConnection"; 1035 synchronized (mLock) { 1036 try { 1037 if (!checkIfaceAndLogFailure(methodStr)) return false; 1038 mWifiChip.setMultiStaPrimaryConnection(ifaceName); 1039 return true; 1040 } catch (RemoteException e) { 1041 handleRemoteException(e, methodStr); 1042 } catch (ServiceSpecificException e) { 1043 handleServiceSpecificException(e, methodStr); 1044 } 1045 return false; 1046 } 1047 } 1048 1049 /** 1050 * See comments for {@link IWifiChip#setMultiStaUseCase(int)} 1051 */ 1052 @Override setMultiStaUseCase(@ifiNative.MultiStaUseCase int useCase)1053 public boolean setMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) { 1054 final String methodStr = "setMultiStaUseCase"; 1055 synchronized (mLock) { 1056 try { 1057 if (!checkIfaceAndLogFailure(methodStr)) return false; 1058 mWifiChip.setMultiStaUseCase(frameworkToHalMultiStaUseCase(useCase)); 1059 return true; 1060 } catch (RemoteException e) { 1061 handleRemoteException(e, methodStr); 1062 } catch (ServiceSpecificException e) { 1063 handleServiceSpecificException(e, methodStr); 1064 } catch (IllegalArgumentException e) { 1065 handleIllegalArgumentException(e, methodStr); 1066 } 1067 return false; 1068 } 1069 } 1070 1071 /** 1072 * See comments for {@link IWifiChip#startLoggingToDebugRingBuffer(String, int, int, int)} 1073 */ 1074 @Override startLoggingToDebugRingBuffer(String ringName, int verboseLevel, int maxIntervalInSec, int minDataSizeInBytes)1075 public boolean startLoggingToDebugRingBuffer(String ringName, int verboseLevel, 1076 int maxIntervalInSec, int minDataSizeInBytes) { 1077 final String methodStr = "startLoggingToDebugRingBuffer"; 1078 synchronized (mLock) { 1079 try { 1080 if (!checkIfaceAndLogFailure(methodStr)) return false; 1081 mWifiChip.startLoggingToDebugRingBuffer( 1082 ringName, verboseLevel, maxIntervalInSec, minDataSizeInBytes); 1083 return true; 1084 } catch (RemoteException e) { 1085 handleRemoteException(e, methodStr); 1086 } catch (ServiceSpecificException e) { 1087 handleServiceSpecificException(e, methodStr); 1088 } 1089 return false; 1090 } 1091 } 1092 1093 /** 1094 * See comments for {@link IWifiChip#stopLoggingToDebugRingBuffer()} 1095 */ 1096 @Override stopLoggingToDebugRingBuffer()1097 public boolean stopLoggingToDebugRingBuffer() { 1098 final String methodStr = "stopLoggingToDebugRingBuffer"; 1099 synchronized (mLock) { 1100 try { 1101 if (!checkIfaceAndLogFailure(methodStr)) return false; 1102 mWifiChip.stopLoggingToDebugRingBuffer(); 1103 return true; 1104 } catch (RemoteException e) { 1105 handleRemoteException(e, methodStr); 1106 } catch (ServiceSpecificException e) { 1107 handleServiceSpecificException(e, methodStr); 1108 } 1109 return false; 1110 } 1111 } 1112 1113 /** 1114 * See comments for {@link IWifiChip#triggerSubsystemRestart()} 1115 */ 1116 @Override triggerSubsystemRestart()1117 public boolean triggerSubsystemRestart() { 1118 final String methodStr = "triggerSubsystemRestart"; 1119 synchronized (mLock) { 1120 try { 1121 if (!checkIfaceAndLogFailure(methodStr)) return false; 1122 mWifiChip.triggerSubsystemRestart(); 1123 return true; 1124 } catch (RemoteException e) { 1125 handleRemoteException(e, methodStr); 1126 } catch (ServiceSpecificException e) { 1127 handleServiceSpecificException(e, methodStr); 1128 } 1129 return false; 1130 } 1131 } 1132 1133 /** 1134 * See comments for {@link IWifiChip#enableStaChannelForPeerNetwork(boolean, boolean)} 1135 */ 1136 @Override enableStaChannelForPeerNetwork(boolean enableIndoorChannel, boolean enableDfsChannel)1137 public boolean enableStaChannelForPeerNetwork(boolean enableIndoorChannel, 1138 boolean enableDfsChannel) { 1139 final String methodStr = "enableStaChannelForPeerNetwork"; 1140 synchronized (mLock) { 1141 try { 1142 if (!checkIfaceAndLogFailure(methodStr)) return false; 1143 int halChannelCategoryEnableFlag = 0; 1144 if (enableIndoorChannel) { 1145 halChannelCategoryEnableFlag |= ChannelCategoryMask.INDOOR_CHANNEL; 1146 } 1147 if (enableDfsChannel) { 1148 halChannelCategoryEnableFlag |= ChannelCategoryMask.DFS_CHANNEL; 1149 } 1150 mWifiChip.enableStaChannelForPeerNetwork(halChannelCategoryEnableFlag); 1151 return true; 1152 } catch (RemoteException e) { 1153 handleRemoteException(e, methodStr); 1154 } catch (ServiceSpecificException e) { 1155 handleServiceSpecificException(e, methodStr); 1156 } 1157 return false; 1158 } 1159 } 1160 1161 /** 1162 * See comments for {@link IWifiChip#setVoipMode(int)} 1163 */ 1164 @Override setVoipMode(@ifiChip.WifiVoipMode int mode)1165 public boolean setVoipMode(@WifiChip.WifiVoipMode int mode) { 1166 final String methodStr = "setVoipMode"; 1167 synchronized (mLock) { 1168 try { 1169 if (!checkIfaceAndLogFailure(methodStr) 1170 || !WifiHalAidlImpl.isServiceVersionAtLeast(2) 1171 || !bitmapContains(mHalFeatureSet, FeatureSetMask.SET_VOIP_MODE)) { 1172 return false; 1173 } 1174 mWifiChip.setVoipMode(frameworkToHalVoipMode(mode)); 1175 return true; 1176 } catch (RemoteException e) { 1177 handleRemoteException(e, methodStr); 1178 } catch (ServiceSpecificException e) { 1179 handleServiceSpecificException(e, methodStr); 1180 } catch (IllegalArgumentException e) { 1181 handleIllegalArgumentException(e, methodStr); 1182 } 1183 return false; 1184 } 1185 } 1186 1187 private class ChipEventCallback extends IWifiChipEventCallback.Stub { 1188 @Override onChipReconfigured(int modeId)1189 public void onChipReconfigured(int modeId) throws RemoteException { 1190 if (mFrameworkCallback == null) return; 1191 mFrameworkCallback.onChipReconfigured(modeId); 1192 } 1193 1194 @Override onChipReconfigureFailure(int statusCode)1195 public void onChipReconfigureFailure(int statusCode) { 1196 if (mFrameworkCallback == null) return; 1197 // TODO: convert to framework status code once WifiHalAidlImpl exists 1198 mFrameworkCallback.onChipReconfigureFailure(statusCode); 1199 } 1200 1201 @Override onIfaceAdded(int type, String name)1202 public void onIfaceAdded(int type, String name) { 1203 if (mFrameworkCallback == null) return; 1204 mFrameworkCallback.onIfaceAdded(halToFrameworkIfaceType(type), name); 1205 } 1206 1207 @Override onIfaceRemoved(int type, String name)1208 public void onIfaceRemoved(int type, String name) { 1209 if (mFrameworkCallback == null) return; 1210 mFrameworkCallback.onIfaceRemoved(halToFrameworkIfaceType(type), name); 1211 } 1212 1213 @Override onDebugRingBufferDataAvailable(WifiDebugRingBufferStatus status, byte[] data)1214 public void onDebugRingBufferDataAvailable(WifiDebugRingBufferStatus status, byte[] data) { 1215 if (mFrameworkCallback == null) return; 1216 try { 1217 mFrameworkCallback.onDebugRingBufferDataAvailable( 1218 halToFrameworkRingBufferStatus(status), data); 1219 } catch (IllegalArgumentException e) { 1220 handleIllegalArgumentException(e, "onDebugRingBufferDataAvailable"); 1221 } 1222 } 1223 1224 @Override onDebugErrorAlert(int errorCode, byte[] debugData)1225 public void onDebugErrorAlert(int errorCode, byte[] debugData) { 1226 if (mFrameworkCallback == null) return; 1227 mFrameworkCallback.onDebugErrorAlert(errorCode, debugData); 1228 } 1229 1230 @Override onRadioModeChange(RadioModeInfo[] radioModeInfoList)1231 public void onRadioModeChange(RadioModeInfo[] radioModeInfoList) { 1232 if (mFrameworkCallback == null) return; 1233 List<WifiChip.RadioModeInfo> frameworkRadioModeInfos = new ArrayList<>(); 1234 for (RadioModeInfo radioInfo : radioModeInfoList) { 1235 List<WifiChip.IfaceInfo> frameworkIfaceInfos = new ArrayList<>(); 1236 for (IfaceInfo ifaceInfo : radioInfo.ifaceInfos) { 1237 frameworkIfaceInfos.add( 1238 new WifiChip.IfaceInfo(ifaceInfo.name, ifaceInfo.channel)); 1239 } 1240 frameworkRadioModeInfos.add( 1241 new WifiChip.RadioModeInfo( 1242 radioInfo.radioId, radioInfo.bandInfo, frameworkIfaceInfos)); 1243 } 1244 mFrameworkCallback.onRadioModeChange(frameworkRadioModeInfos); 1245 } 1246 1247 @Override getInterfaceHash()1248 public String getInterfaceHash() { 1249 return IWifiChipEventCallback.HASH; 1250 } 1251 1252 @Override getInterfaceVersion()1253 public int getInterfaceVersion() { 1254 return IWifiChipEventCallback.VERSION; 1255 } 1256 } 1257 1258 1259 // Utilities 1260 halToFrameworkIfaceConcurrencyType(int type)1261 private static @WifiChip.IfaceConcurrencyType int halToFrameworkIfaceConcurrencyType(int type) { 1262 switch (type) { 1263 case IfaceConcurrencyType.STA: 1264 return WifiChip.IFACE_CONCURRENCY_TYPE_STA; 1265 case IfaceConcurrencyType.AP: 1266 return WifiChip.IFACE_CONCURRENCY_TYPE_AP; 1267 case IfaceConcurrencyType.AP_BRIDGED: 1268 return WifiChip.IFACE_CONCURRENCY_TYPE_AP_BRIDGED; 1269 case IfaceConcurrencyType.P2P: 1270 return WifiChip.IFACE_CONCURRENCY_TYPE_P2P; 1271 case IfaceConcurrencyType.NAN_IFACE: 1272 return WifiChip.IFACE_CONCURRENCY_TYPE_NAN; 1273 default: 1274 Log.e(TAG, "Invalid IfaceConcurrencyType received: " + type); 1275 return -1; 1276 } 1277 } 1278 halToFrameworkIfaceType(int type)1279 private static @WifiChip.IfaceType int halToFrameworkIfaceType(int type) { 1280 switch (type) { 1281 case IfaceType.STA: 1282 return WifiChip.IFACE_TYPE_STA; 1283 case IfaceType.AP: 1284 return WifiChip.IFACE_TYPE_AP; 1285 case IfaceType.P2P: 1286 return WifiChip.IFACE_TYPE_P2P; 1287 case IfaceType.NAN_IFACE: 1288 return WifiChip.IFACE_TYPE_NAN; 1289 default: 1290 Log.e(TAG, "Invalid IfaceType received: " + type); 1291 return -1; 1292 } 1293 } 1294 halToFrameworkRingBufferStatusList( WifiDebugRingBufferStatus[] ringBuffers)1295 private static @Nullable List<WifiNative.RingBufferStatus> halToFrameworkRingBufferStatusList( 1296 WifiDebugRingBufferStatus[] ringBuffers) throws IllegalArgumentException { 1297 if (ringBuffers == null) return null; 1298 List<WifiNative.RingBufferStatus> ans = new ArrayList<>(); 1299 for (WifiDebugRingBufferStatus b : ringBuffers) { 1300 ans.add(halToFrameworkRingBufferStatus(b)); 1301 } 1302 return ans; 1303 } 1304 halToFrameworkRingBufferStatus( WifiDebugRingBufferStatus h)1305 private static WifiNative.RingBufferStatus halToFrameworkRingBufferStatus( 1306 WifiDebugRingBufferStatus h) throws IllegalArgumentException { 1307 WifiNative.RingBufferStatus ans = new WifiNative.RingBufferStatus(); 1308 ans.name = h.ringName; 1309 ans.flag = halToFrameworkRingBufferFlags(h.flags); 1310 ans.ringBufferId = h.ringId; 1311 ans.ringBufferByteSize = h.sizeInBytes; 1312 ans.verboseLevel = h.verboseLevel; 1313 // Remaining fields are unavailable 1314 // writtenBytes; 1315 // readBytes; 1316 // writtenRecords; 1317 return ans; 1318 } 1319 halToFrameworkRingBufferFlags(int wifiDebugRingBufferFlag)1320 private static int halToFrameworkRingBufferFlags(int wifiDebugRingBufferFlag) 1321 throws IllegalArgumentException { 1322 BitMask checkoff = new BitMask(wifiDebugRingBufferFlag); 1323 int flags = 0; 1324 if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES)) { 1325 flags |= WifiNative.RingBufferStatus.HAS_BINARY_ENTRIES; 1326 } 1327 if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES)) { 1328 flags |= WifiNative.RingBufferStatus.HAS_ASCII_ENTRIES; 1329 } 1330 if (checkoff.testAndClear(WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES)) { 1331 flags |= WifiNative.RingBufferStatus.HAS_PER_PACKET_ENTRIES; 1332 } 1333 if (checkoff.value != 0) { 1334 throw new IllegalArgumentException("Unknown WifiDebugRingBufferFlag " + checkoff.value); 1335 } 1336 return flags; 1337 } 1338 halToFrameworkWakeReasons( WifiDebugHostWakeReasonStats h)1339 private static WlanWakeReasonAndCounts halToFrameworkWakeReasons( 1340 WifiDebugHostWakeReasonStats h) { 1341 if (h == null) return null; 1342 WlanWakeReasonAndCounts ans = new WlanWakeReasonAndCounts(); 1343 ans.totalCmdEventWake = h.totalCmdEventWakeCnt; 1344 ans.totalDriverFwLocalWake = h.totalDriverFwLocalWakeCnt; 1345 ans.totalRxDataWake = h.totalRxPacketWakeCnt; 1346 ans.rxUnicast = h.rxPktWakeDetails.rxUnicastCnt; 1347 ans.rxMulticast = h.rxPktWakeDetails.rxMulticastCnt; 1348 ans.rxBroadcast = h.rxPktWakeDetails.rxBroadcastCnt; 1349 ans.icmp = h.rxIcmpPkWakeDetails.icmpPkt; 1350 ans.icmp6 = h.rxIcmpPkWakeDetails.icmp6Pkt; 1351 ans.icmp6Ra = h.rxIcmpPkWakeDetails.icmp6Ra; 1352 ans.icmp6Na = h.rxIcmpPkWakeDetails.icmp6Na; 1353 ans.icmp6Ns = h.rxIcmpPkWakeDetails.icmp6Ns; 1354 ans.ipv4RxMulticast = h.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt; 1355 ans.ipv6Multicast = h.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt; 1356 ans.otherRxMulticast = h.rxMulticastPkWakeDetails.otherRxMulticastAddrCnt; 1357 ans.cmdEventWakeCntArray = h.cmdEventWakeCntPerType; 1358 ans.driverFWLocalWakeCntArray = h.driverFwLocalWakeCntPerType; 1359 return ans; 1360 } 1361 frameworkToHalMultiStaUseCase(@ifiNative.MultiStaUseCase int useCase)1362 private static byte frameworkToHalMultiStaUseCase(@WifiNative.MultiStaUseCase int useCase) 1363 throws IllegalArgumentException { 1364 switch (useCase) { 1365 case WifiNative.DUAL_STA_TRANSIENT_PREFER_PRIMARY: 1366 return MultiStaUseCase.DUAL_STA_TRANSIENT_PREFER_PRIMARY; 1367 case WifiNative.DUAL_STA_NON_TRANSIENT_UNBIASED: 1368 return MultiStaUseCase.DUAL_STA_NON_TRANSIENT_UNBIASED; 1369 default: 1370 throw new IllegalArgumentException("Invalid use case " + useCase); 1371 } 1372 } 1373 1374 private static @NonNull android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] frameworkToHalCoexUnsafeChannels( @onNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels)1375 frameworkToHalCoexUnsafeChannels( 1376 @NonNull List<android.net.wifi.CoexUnsafeChannel> frameworkUnsafeChannels) { 1377 final ArrayList<android.hardware.wifi.IWifiChip.CoexUnsafeChannel> halList = 1378 new ArrayList<>(); 1379 if (!SdkLevel.isAtLeastS()) { 1380 return new android.hardware.wifi.IWifiChip.CoexUnsafeChannel[0]; 1381 } 1382 for (android.net.wifi.CoexUnsafeChannel frameworkUnsafeChannel : frameworkUnsafeChannels) { 1383 final android.hardware.wifi.IWifiChip.CoexUnsafeChannel halUnsafeChannel = 1384 new android.hardware.wifi.IWifiChip.CoexUnsafeChannel(); 1385 switch (frameworkUnsafeChannel.getBand()) { 1386 case (WifiScanner.WIFI_BAND_24_GHZ): 1387 halUnsafeChannel.band = WifiBand.BAND_24GHZ; 1388 break; 1389 case (WifiScanner.WIFI_BAND_5_GHZ): 1390 halUnsafeChannel.band = WifiBand.BAND_5GHZ; 1391 break; 1392 case (WifiScanner.WIFI_BAND_6_GHZ): 1393 halUnsafeChannel.band = WifiBand.BAND_6GHZ; 1394 break; 1395 case (WifiScanner.WIFI_BAND_60_GHZ): 1396 halUnsafeChannel.band = WifiBand.BAND_60GHZ; 1397 break; 1398 default: 1399 Log.e(TAG, "Tried to set unsafe channel with unknown band: " 1400 + frameworkUnsafeChannel.getBand()); 1401 continue; 1402 } 1403 halUnsafeChannel.channel = frameworkUnsafeChannel.getChannel(); 1404 final int powerCapDbm = frameworkUnsafeChannel.getPowerCapDbm(); 1405 if (powerCapDbm != POWER_CAP_NONE) { 1406 halUnsafeChannel.powerCapDbm = powerCapDbm; 1407 } else { 1408 halUnsafeChannel.powerCapDbm = 1409 android.hardware.wifi.IWifiChip.NO_POWER_CAP_CONSTANT; 1410 } 1411 halList.add(halUnsafeChannel); 1412 } 1413 1414 android.hardware.wifi.IWifiChip.CoexUnsafeChannel[] halArray = 1415 new android.hardware.wifi.IWifiChip.CoexUnsafeChannel[halList.size()]; 1416 for (int i = 0; i < halList.size(); i++) { 1417 halArray[i] = halList.get(i); 1418 } 1419 return halArray; 1420 } 1421 frameworkToHalCoexRestrictions( @ifiManager.CoexRestriction int restrictions)1422 private static int frameworkToHalCoexRestrictions( 1423 @WifiManager.CoexRestriction int restrictions) { 1424 int halRestrictions = 0; 1425 if (!SdkLevel.isAtLeastS()) { 1426 return halRestrictions; 1427 } 1428 if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_DIRECT) != 0) { 1429 halRestrictions |= CoexRestriction.WIFI_DIRECT; 1430 } 1431 if ((restrictions & WifiManager.COEX_RESTRICTION_SOFTAP) != 0) { 1432 halRestrictions |= CoexRestriction.SOFTAP; 1433 } 1434 if ((restrictions & WifiManager.COEX_RESTRICTION_WIFI_AWARE) != 0) { 1435 halRestrictions |= CoexRestriction.WIFI_AWARE; 1436 } 1437 return halRestrictions; 1438 } 1439 1440 /** 1441 * Check if we need to backoff wifi Tx power due to SAR requirements. 1442 */ sarPowerBackoffRequired(SarInfo sarInfo)1443 private static boolean sarPowerBackoffRequired(SarInfo sarInfo) { 1444 if (sarInfo.sarSapSupported && sarInfo.isWifiSapEnabled) { 1445 return true; 1446 } 1447 if (sarInfo.sarVoiceCallSupported && (sarInfo.isVoiceCall || sarInfo.isEarPieceActive)) { 1448 return true; 1449 } 1450 return false; 1451 } 1452 1453 /** 1454 * Maps the information in the SarInfo instance to a TxPowerScenario. 1455 * If SAR SoftAP input is supported, we make these assumptions: 1456 * - All voice calls are treated as if device is near the head. 1457 * - SoftAP scenario is treated as if device is near the body. 1458 * If SoftAP is not supported, the only valid scenario is when a voice call is ongoing. 1459 */ frameworkToHalTxPowerScenario(SarInfo sarInfo)1460 private static int frameworkToHalTxPowerScenario(SarInfo sarInfo) 1461 throws IllegalArgumentException { 1462 if (sarInfo.sarSapSupported && sarInfo.sarVoiceCallSupported) { 1463 if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) { 1464 return TxPowerScenario.ON_HEAD_CELL_ON; 1465 } else if (sarInfo.isWifiSapEnabled) { 1466 return TxPowerScenario.ON_BODY_CELL_ON; 1467 } else { 1468 throw new IllegalArgumentException("bad scenario: no voice call/softAP active"); 1469 } 1470 } else if (sarInfo.sarVoiceCallSupported) { 1471 if (sarInfo.isVoiceCall || sarInfo.isEarPieceActive) { 1472 return TxPowerScenario.VOICE_CALL; 1473 } else { 1474 throw new IllegalArgumentException("bad scenario: voice call not active"); 1475 } 1476 } else { 1477 throw new IllegalArgumentException("Invalid case: voice call not supported"); 1478 } 1479 } 1480 frameworkToHalWifiBand(int frameworkBand)1481 private static int frameworkToHalWifiBand(int frameworkBand) throws IllegalArgumentException { 1482 switch (frameworkBand) { 1483 case WifiScanner.WIFI_BAND_UNSPECIFIED: 1484 return WifiBand.BAND_UNSPECIFIED; 1485 case WifiScanner.WIFI_BAND_24_GHZ: 1486 return WifiBand.BAND_24GHZ; 1487 case WifiScanner.WIFI_BAND_5_GHZ: 1488 return WifiBand.BAND_5GHZ; 1489 case WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY: 1490 return WifiBand.BAND_5GHZ_DFS; 1491 case WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS: 1492 return WifiBand.BAND_5GHZ_WITH_DFS; 1493 case WifiScanner.WIFI_BAND_BOTH: 1494 return WifiBand.BAND_24GHZ_5GHZ; 1495 case WifiScanner.WIFI_BAND_BOTH_WITH_DFS: 1496 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS; 1497 case WifiScanner.WIFI_BAND_6_GHZ: 1498 return WifiBand.BAND_6GHZ; 1499 case WifiScanner.WIFI_BAND_24_5_6_GHZ: 1500 return WifiBand.BAND_24GHZ_5GHZ_6GHZ; 1501 case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_GHZ: 1502 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ; 1503 case WifiScanner.WIFI_BAND_60_GHZ: 1504 return WifiBand.BAND_60GHZ; 1505 case WifiScanner.WIFI_BAND_24_5_6_60_GHZ: 1506 return WifiBand.BAND_24GHZ_5GHZ_6GHZ_60GHZ; 1507 case WifiScanner.WIFI_BAND_24_5_WITH_DFS_6_60_GHZ: 1508 return WifiBand.BAND_24GHZ_5GHZ_WITH_DFS_6GHZ_60GHZ; 1509 case WifiScanner.WIFI_BAND_24_GHZ_WITH_5GHZ_DFS: 1510 default: 1511 throw new IllegalArgumentException("bad band " + frameworkBand); 1512 } 1513 } 1514 frameworkToHalIfaceMode(@ifiAvailableChannel.OpMode int mode)1515 private static int frameworkToHalIfaceMode(@WifiAvailableChannel.OpMode int mode) { 1516 int halMode = 0; 1517 if ((mode & WifiAvailableChannel.OP_MODE_STA) != 0) { 1518 halMode |= WifiIfaceMode.IFACE_MODE_STA; 1519 } 1520 if ((mode & WifiAvailableChannel.OP_MODE_SAP) != 0) { 1521 halMode |= WifiIfaceMode.IFACE_MODE_SOFTAP; 1522 } 1523 if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI) != 0) { 1524 halMode |= WifiIfaceMode.IFACE_MODE_P2P_CLIENT; 1525 } 1526 if ((mode & WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO) != 0) { 1527 halMode |= WifiIfaceMode.IFACE_MODE_P2P_GO; 1528 } 1529 if ((mode & WifiAvailableChannel.OP_MODE_WIFI_AWARE) != 0) { 1530 halMode |= WifiIfaceMode.IFACE_MODE_NAN; 1531 } 1532 if ((mode & WifiAvailableChannel.OP_MODE_TDLS) != 0) { 1533 halMode |= WifiIfaceMode.IFACE_MODE_TDLS; 1534 } 1535 return halMode; 1536 } 1537 halToFrameworkIfaceMode(int halMode)1538 private static @WifiAvailableChannel.OpMode int halToFrameworkIfaceMode(int halMode) { 1539 int mode = 0; 1540 if ((halMode & WifiIfaceMode.IFACE_MODE_STA) != 0) { 1541 mode |= WifiAvailableChannel.OP_MODE_STA; 1542 } 1543 if ((halMode & WifiIfaceMode.IFACE_MODE_SOFTAP) != 0) { 1544 mode |= WifiAvailableChannel.OP_MODE_SAP; 1545 } 1546 if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_CLIENT) != 0) { 1547 mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_CLI; 1548 } 1549 if ((halMode & WifiIfaceMode.IFACE_MODE_P2P_GO) != 0) { 1550 mode |= WifiAvailableChannel.OP_MODE_WIFI_DIRECT_GO; 1551 } 1552 if ((halMode & WifiIfaceMode.IFACE_MODE_NAN) != 0) { 1553 mode |= WifiAvailableChannel.OP_MODE_WIFI_AWARE; 1554 } 1555 if ((halMode & WifiIfaceMode.IFACE_MODE_TDLS) != 0) { 1556 mode |= WifiAvailableChannel.OP_MODE_TDLS; 1557 } 1558 return mode; 1559 } 1560 frameworkToHalUsableFilter(@ifiAvailableChannel.Filter int filter)1561 private static int frameworkToHalUsableFilter(@WifiAvailableChannel.Filter int filter) { 1562 int halFilter = 0; // O implies no additional filter other than regulatory (default) 1563 if ((filter & WifiAvailableChannel.FILTER_CONCURRENCY) != 0) { 1564 halFilter |= UsableChannelFilter.CONCURRENCY; 1565 } 1566 if ((filter & WifiAvailableChannel.FILTER_CELLULAR_COEXISTENCE) != 0) { 1567 halFilter |= UsableChannelFilter.CELLULAR_COEXISTENCE; 1568 } 1569 if ((filter & WifiAvailableChannel.FILTER_NAN_INSTANT_MODE) != 0) { 1570 halFilter |= UsableChannelFilter.NAN_INSTANT_MODE; 1571 } 1572 1573 return halFilter; 1574 } 1575 frameworkToHalVoipMode(@ifiChip.WifiVoipMode int mode)1576 private static int frameworkToHalVoipMode(@WifiChip.WifiVoipMode int mode) 1577 throws IllegalArgumentException { 1578 switch (mode) { 1579 case WifiChip.WIFI_VOIP_MODE_OFF: 1580 return VoipMode.OFF; 1581 case WifiChip.WIFI_VOIP_MODE_VOICE: 1582 return VoipMode.VOICE; 1583 default: 1584 throw new IllegalArgumentException("bad voip mode " + mode); 1585 } 1586 } 1587 bitmapContains(long bitmap, long expectedBit)1588 private static boolean bitmapContains(long bitmap, long expectedBit) { 1589 return (bitmap & expectedBit) != 0; 1590 } 1591 1592 @VisibleForTesting halToFrameworkChipFeatureSet(long halFeatureSet)1593 protected static long halToFrameworkChipFeatureSet(long halFeatureSet) { 1594 long features = 0; 1595 if (bitmapContains(halFeatureSet, FeatureSetMask.SET_TX_POWER_LIMIT)) { 1596 features |= WifiManager.WIFI_FEATURE_TX_POWER_LIMIT; 1597 } 1598 if (bitmapContains(halFeatureSet, FeatureSetMask.D2D_RTT)) { 1599 features |= WifiManager.WIFI_FEATURE_D2D_RTT; 1600 } 1601 if (bitmapContains(halFeatureSet, FeatureSetMask.D2AP_RTT)) { 1602 features |= WifiManager.WIFI_FEATURE_D2AP_RTT; 1603 } 1604 if (bitmapContains(halFeatureSet, FeatureSetMask.SET_LATENCY_MODE)) { 1605 features |= WifiManager.WIFI_FEATURE_LOW_LATENCY; 1606 } 1607 if (bitmapContains(halFeatureSet, FeatureSetMask.P2P_RAND_MAC)) { 1608 features |= WifiManager.WIFI_FEATURE_P2P_RAND_MAC; 1609 } 1610 if (bitmapContains(halFeatureSet, FeatureSetMask.WIGIG)) { 1611 features |= WifiManager.WIFI_FEATURE_INFRA_60G; 1612 } 1613 if (bitmapContains(halFeatureSet, FeatureSetMask.T2LM_NEGOTIATION)) { 1614 features |= WifiManager.WIFI_FEATURE_T2LM_NEGOTIATION; 1615 } 1616 return features; 1617 } 1618 halToFrameworkWifiBand(int halBand)1619 private static int halToFrameworkWifiBand(int halBand) { 1620 int frameworkBand = 0; 1621 if (bitmapContains(halBand, WifiBand.BAND_24GHZ)) { 1622 frameworkBand |= WifiScanner.WIFI_BAND_24_GHZ; 1623 } 1624 if (bitmapContains(halBand, WifiBand.BAND_5GHZ)) { 1625 frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ; 1626 } 1627 if (bitmapContains(halBand, WifiBand.BAND_5GHZ_DFS)) { 1628 frameworkBand |= WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY; 1629 } 1630 if (bitmapContains(halBand, WifiBand.BAND_6GHZ)) { 1631 frameworkBand |= WifiScanner.WIFI_BAND_6_GHZ; 1632 } 1633 if (bitmapContains(halBand, WifiBand.BAND_60GHZ)) { 1634 frameworkBand |= WifiScanner.WIFI_BAND_60_GHZ; 1635 } 1636 return frameworkBand; 1637 } 1638 halToFrameworkAntennaMode(int mode)1639 private static @WifiChip.WifiAntennaMode int halToFrameworkAntennaMode(int mode) { 1640 switch (mode) { 1641 case WifiAntennaMode.WIFI_ANTENNA_MODE_UNSPECIFIED: 1642 return WifiChip.WIFI_ANTENNA_MODE_UNSPECIFIED; 1643 case WifiAntennaMode.WIFI_ANTENNA_MODE_1X1: 1644 return WifiChip.WIFI_ANTENNA_MODE_1X1; 1645 case WifiAntennaMode.WIFI_ANTENNA_MODE_2X2: 1646 return WifiChip.WIFI_ANTENNA_MODE_2X2; 1647 case WifiAntennaMode.WIFI_ANTENNA_MODE_3X3: 1648 return WifiChip.WIFI_ANTENNA_MODE_3X3; 1649 case WifiAntennaMode.WIFI_ANTENNA_MODE_4X4: 1650 return WifiChip.WIFI_ANTENNA_MODE_4X4; 1651 default: 1652 Log.e(TAG, "Invalid WifiAntennaMode: " + mode); 1653 return WifiChip.WIFI_ANTENNA_MODE_UNSPECIFIED; 1654 } 1655 } 1656 halToFrameworkChipModeList( android.hardware.wifi.IWifiChip.ChipMode[] halModes)1657 private static List<WifiChip.ChipMode> halToFrameworkChipModeList( 1658 android.hardware.wifi.IWifiChip.ChipMode[] halModes) { 1659 List<WifiChip.ChipMode> frameworkModes = new ArrayList<>(); 1660 for (android.hardware.wifi.IWifiChip.ChipMode halMode : halModes) { 1661 frameworkModes.add(halToFrameworkChipMode(halMode)); 1662 } 1663 return frameworkModes; 1664 } 1665 halToFrameworkChipMode( android.hardware.wifi.IWifiChip.ChipMode halMode)1666 private static WifiChip.ChipMode halToFrameworkChipMode( 1667 android.hardware.wifi.IWifiChip.ChipMode halMode) { 1668 List<WifiChip.ChipConcurrencyCombination> frameworkCombos = new ArrayList<>(); 1669 for (android.hardware.wifi.IWifiChip.ChipConcurrencyCombination halCombo : 1670 halMode.availableCombinations) { 1671 frameworkCombos.add(halToFrameworkChipConcurrencyCombination(halCombo)); 1672 } 1673 return new WifiChip.ChipMode(halMode.id, frameworkCombos); 1674 } 1675 halToFrameworkChipConcurrencyCombination( android.hardware.wifi.IWifiChip.ChipConcurrencyCombination halCombo)1676 private static WifiChip.ChipConcurrencyCombination halToFrameworkChipConcurrencyCombination( 1677 android.hardware.wifi.IWifiChip.ChipConcurrencyCombination halCombo) { 1678 List<WifiChip.ChipConcurrencyCombinationLimit> frameworkLimits = new ArrayList<>(); 1679 for (android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit halLimit : 1680 halCombo.limits) { 1681 frameworkLimits.add(halToFrameworkChipConcurrencyCombinationLimit(halLimit)); 1682 } 1683 return new WifiChip.ChipConcurrencyCombination(frameworkLimits); 1684 } 1685 1686 private static WifiChip.ChipConcurrencyCombinationLimit halToFrameworkChipConcurrencyCombinationLimit( android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit halLimit)1687 halToFrameworkChipConcurrencyCombinationLimit( 1688 android.hardware.wifi.IWifiChip.ChipConcurrencyCombinationLimit halLimit) { 1689 List<Integer> frameworkTypes = new ArrayList<>(); 1690 for (int halType : halLimit.types) { 1691 frameworkTypes.add(halToFrameworkIfaceConcurrencyType(halType)); 1692 } 1693 return new WifiChip.ChipConcurrencyCombinationLimit(halLimit.maxIfaces, frameworkTypes); 1694 } 1695 halToFrameworkRadioCombinations( WifiRadioCombination[] halCombos)1696 private static List<WifiChip.WifiRadioCombination> halToFrameworkRadioCombinations( 1697 WifiRadioCombination[] halCombos) { 1698 List<WifiChip.WifiRadioCombination> frameworkCombos = new ArrayList<>(); 1699 for (WifiRadioCombination combo : halCombos) { 1700 frameworkCombos.add(halToFrameworkRadioCombination(combo)); 1701 } 1702 return frameworkCombos; 1703 } 1704 1705 /** 1706 * Converts the framework version of an AvailableAfcFrequencyInfo object to its AIDL equivalent. 1707 */ frameworkToHalAvailableAfcFrequencyInfo( WifiChip.AvailableAfcFrequencyInfo availableFrequencyInfo)1708 private static AvailableAfcFrequencyInfo frameworkToHalAvailableAfcFrequencyInfo( 1709 WifiChip.AvailableAfcFrequencyInfo availableFrequencyInfo) { 1710 if (availableFrequencyInfo == null) { 1711 return null; 1712 } 1713 1714 AvailableAfcFrequencyInfo halAvailableAfcFrequencyInfo = new AvailableAfcFrequencyInfo(); 1715 halAvailableAfcFrequencyInfo.startFrequencyMhz = availableFrequencyInfo.startFrequencyMhz; 1716 halAvailableAfcFrequencyInfo.endFrequencyMhz = availableFrequencyInfo.endFrequencyMhz; 1717 halAvailableAfcFrequencyInfo.maxPsd = availableFrequencyInfo.maxPsdDbmPerMhz; 1718 1719 return halAvailableAfcFrequencyInfo; 1720 } 1721 1722 /** 1723 * Converts the framework version of an AvailableAfcChannelInfo object to its AIDL equivalent. 1724 */ frameworkToHalAvailableAfcChannelInfo( WifiChip.AvailableAfcChannelInfo availableChannelInfo)1725 private static AvailableAfcChannelInfo frameworkToHalAvailableAfcChannelInfo( 1726 WifiChip.AvailableAfcChannelInfo availableChannelInfo) { 1727 if (availableChannelInfo == null) { 1728 return null; 1729 } 1730 1731 AvailableAfcChannelInfo halAvailableAfcChannelInfo = new AvailableAfcChannelInfo(); 1732 halAvailableAfcChannelInfo.globalOperatingClass = availableChannelInfo.globalOperatingClass; 1733 halAvailableAfcChannelInfo.channelCfi = availableChannelInfo.channelCfi; 1734 halAvailableAfcChannelInfo.maxEirpDbm = availableChannelInfo.maxEirpDbm; 1735 1736 return halAvailableAfcChannelInfo; 1737 } 1738 frameworkToHalAfcChannelAllowance( WifiChip.AfcChannelAllowance afcChannelAllowance)1739 private static AfcChannelAllowance frameworkToHalAfcChannelAllowance( 1740 WifiChip.AfcChannelAllowance afcChannelAllowance) { 1741 AfcChannelAllowance halAfcChannelAllowance = new AfcChannelAllowance(); 1742 1743 // convert allowed frequencies and channels to their HAL version 1744 if (afcChannelAllowance.availableAfcFrequencyInfos == null) { 1745 // this should not be left uninitialized, or it may result in an exception 1746 halAfcChannelAllowance.availableAfcFrequencyInfos = new AvailableAfcFrequencyInfo[0]; 1747 } else { 1748 halAfcChannelAllowance.availableAfcFrequencyInfos = new AvailableAfcFrequencyInfo[ 1749 afcChannelAllowance.availableAfcFrequencyInfos.size()]; 1750 1751 for (int i = 0; i < afcChannelAllowance.availableAfcFrequencyInfos.size(); ++i) { 1752 halAfcChannelAllowance.availableAfcFrequencyInfos[i] = 1753 frameworkToHalAvailableAfcFrequencyInfo( 1754 afcChannelAllowance.availableAfcFrequencyInfos.get(i)); 1755 } 1756 } 1757 1758 if (afcChannelAllowance.availableAfcChannelInfos == null) { 1759 // this should not be left uninitialized, or it may result in an exception 1760 halAfcChannelAllowance.availableAfcChannelInfos = new AvailableAfcChannelInfo[0]; 1761 } else { 1762 halAfcChannelAllowance.availableAfcChannelInfos = new AvailableAfcChannelInfo[ 1763 afcChannelAllowance.availableAfcChannelInfos.size()]; 1764 1765 for (int i = 0; i < afcChannelAllowance.availableAfcChannelInfos.size(); ++i) { 1766 halAfcChannelAllowance.availableAfcChannelInfos[i] = 1767 frameworkToHalAvailableAfcChannelInfo( 1768 afcChannelAllowance.availableAfcChannelInfos.get(i)); 1769 } 1770 } 1771 1772 halAfcChannelAllowance.availabilityExpireTimeMs = 1773 afcChannelAllowance.availabilityExpireTimeMs; 1774 1775 return halAfcChannelAllowance; 1776 } 1777 halToFrameworkWifiChipCapabilities( WifiChipCapabilities halCapabilities)1778 private static WifiChip.WifiChipCapabilities halToFrameworkWifiChipCapabilities( 1779 WifiChipCapabilities halCapabilities) { 1780 return new WifiChip.WifiChipCapabilities(halCapabilities.maxMloAssociationLinkCount, 1781 halCapabilities.maxMloStrLinkCount, halCapabilities.maxConcurrentTdlsSessionCount); 1782 } 1783 halToFrameworkRadioCombination( WifiRadioCombination halCombo)1784 private static WifiChip.WifiRadioCombination halToFrameworkRadioCombination( 1785 WifiRadioCombination halCombo) { 1786 List<WifiChip.WifiRadioConfiguration> frameworkConfigs = new ArrayList<>(); 1787 for (WifiRadioConfiguration config : halCombo.radioConfigurations) { 1788 frameworkConfigs.add(halToFrameworkRadioConfiguration(config)); 1789 } 1790 return new WifiChip.WifiRadioCombination(frameworkConfigs); 1791 } 1792 halToFrameworkRadioConfiguration( WifiRadioConfiguration halConfig)1793 private static WifiChip.WifiRadioConfiguration halToFrameworkRadioConfiguration( 1794 WifiRadioConfiguration halConfig) { 1795 return new WifiChip.WifiRadioConfiguration(halToFrameworkWifiBand(halConfig.bandInfo), 1796 halToFrameworkAntennaMode(halConfig.antennaMode)); 1797 } 1798 checkIfaceAndLogFailure(String methodStr)1799 private boolean checkIfaceAndLogFailure(String methodStr) { 1800 if (mWifiChip == null) { 1801 Log.e(TAG, "Unable to call " + methodStr + " because iface is null."); 1802 return false; 1803 } 1804 return true; 1805 } 1806 handleRemoteException(RemoteException e, String methodStr)1807 private void handleRemoteException(RemoteException e, String methodStr) { 1808 mWifiChip = null; 1809 Log.e(TAG, methodStr + " failed with remote exception: " + e); 1810 } 1811 handleServiceSpecificException(ServiceSpecificException e, String methodStr)1812 private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) { 1813 Log.e(TAG, methodStr + " failed with service-specific exception: " + e); 1814 } 1815 handleIllegalArgumentException(IllegalArgumentException e, String methodStr)1816 private void handleIllegalArgumentException(IllegalArgumentException e, String methodStr) { 1817 Log.e(TAG, methodStr + " failed with illegal argument exception: " + e); 1818 } 1819 1820 /** 1821 * See comments for {@link IWifiChip#setMloMode(int)}. 1822 */ 1823 @Override setMloMode(@ifiManager.MloMode int mode)1824 public @WifiStatusCode int setMloMode(@WifiManager.MloMode int mode) { 1825 final String methodStr = "setMloMode"; 1826 @WifiStatusCode int errorCode = WifiStatusCode.ERROR_UNKNOWN; 1827 synchronized (mLock) { 1828 try { 1829 if (checkIfaceAndLogFailure(methodStr)) { 1830 mWifiChip.setMloMode(frameworkToAidlMloMode(mode)); 1831 errorCode = WifiStatusCode.SUCCESS; 1832 } 1833 } catch (RemoteException e) { 1834 handleRemoteException(e, methodStr); 1835 } catch (ServiceSpecificException e) { 1836 handleServiceSpecificException(e, methodStr); 1837 errorCode = e.errorCode; 1838 } catch (IllegalArgumentException e) { 1839 handleIllegalArgumentException(e, methodStr); 1840 errorCode = WifiStatusCode.ERROR_INVALID_ARGS; 1841 } 1842 return errorCode; 1843 } 1844 } 1845 1846 /** 1847 * See comments for {@link IWifiChip#setAfcChannelAllowance(WifiChip.AfcChannelAllowance)} 1848 */ 1849 @Override setAfcChannelAllowance(WifiChip.AfcChannelAllowance afcChannelAllowance)1850 public boolean setAfcChannelAllowance(WifiChip.AfcChannelAllowance afcChannelAllowance) { 1851 final String methodStr = "setAfcChannelAllowance"; 1852 1853 try { 1854 AfcChannelAllowance halAfcChannelAllowance = 1855 frameworkToHalAfcChannelAllowance(afcChannelAllowance); 1856 mWifiChip.setAfcChannelAllowance(halAfcChannelAllowance); 1857 return true; 1858 } catch (RemoteException e) { 1859 handleRemoteException(e, methodStr); 1860 } catch (ServiceSpecificException e) { 1861 handleServiceSpecificException(e, methodStr); 1862 } 1863 return false; 1864 } 1865 frameworkToAidlMloMode( @ifiManager.MloMode int mode)1866 private @android.hardware.wifi.IWifiChip.ChipMloMode int frameworkToAidlMloMode( 1867 @WifiManager.MloMode int mode) { 1868 switch(mode) { 1869 case WifiManager.MLO_MODE_DEFAULT: 1870 return android.hardware.wifi.IWifiChip.ChipMloMode.DEFAULT; 1871 case WifiManager.MLO_MODE_LOW_LATENCY: 1872 return android.hardware.wifi.IWifiChip.ChipMloMode.LOW_LATENCY; 1873 case WifiManager.MLO_MODE_HIGH_THROUGHPUT: 1874 return android.hardware.wifi.IWifiChip.ChipMloMode.HIGH_THROUGHPUT; 1875 case WifiManager.MLO_MODE_LOW_POWER: 1876 return android.hardware.wifi.IWifiChip.ChipMloMode.LOW_POWER; 1877 default: 1878 throw new IllegalArgumentException("frameworkToAidlMloMode: Invalid mode: " + mode); 1879 } 1880 } 1881 } 1882