WifiVendorHal.java revision 4f2049a015722cae0f0169379d499d5d4fc98e30
1/* 2 * Copyright (C) 2017 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 */ 16package com.android.server.wifi; 17 18import android.annotation.Nullable; 19import android.hardware.wifi.V1_0.IWifiApIface; 20import android.hardware.wifi.V1_0.IWifiChip; 21import android.hardware.wifi.V1_0.IWifiIface; 22import android.hardware.wifi.V1_0.IWifiRttController; 23import android.hardware.wifi.V1_0.IWifiStaIface; 24import android.hardware.wifi.V1_0.StaRoamingConfig; 25import android.hardware.wifi.V1_0.StaRoamingState; 26import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats; 27import android.hardware.wifi.V1_0.WifiStatus; 28import android.hardware.wifi.V1_0.WifiStatusCode; 29import android.net.apf.ApfCapabilities; 30import android.net.wifi.RttManager; 31import android.net.wifi.RttManager.ResponderConfig; 32import android.net.wifi.WifiInfo; 33import android.net.wifi.WifiLinkLayerStats; 34import android.net.wifi.WifiScanner; 35import android.net.wifi.WifiWakeReasonAndCounts; 36import android.os.HandlerThread; 37import android.os.RemoteException; 38import android.util.Log; 39import android.util.MutableBoolean; 40 41import com.android.internal.annotations.VisibleForTesting; 42import com.android.server.connectivity.KeepalivePacketData; 43 44/** 45 * Vendor HAL via HIDL 46 */ 47public class WifiVendorHal { 48 49 private static final String TAG = "WifiVendorHal"; 50 51 // Vendor HAL HIDL interface objects. 52 private IWifiChip mIWifiChip; 53 private IWifiStaIface mIWifiStaIface; 54 private IWifiApIface mIWifiApIface; 55 private IWifiRttController mIWifiRttController; 56 private final HalDeviceManager mHalDeviceManager; 57 private final HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks; 58 private final HandlerThread mWifiStateMachineHandlerThread; 59 60 public WifiVendorHal(HalDeviceManager halDeviceManager, 61 HandlerThread wifiStateMachineHandlerThread) { 62 mHalDeviceManager = halDeviceManager; 63 mWifiStateMachineHandlerThread = wifiStateMachineHandlerThread; 64 mHalDeviceManagerStatusCallbacks = new HalDeviceManagerStatusListener(); 65 } 66 67 // TODO(mplass): figure out where we need locking in hidl world. b/33383725 68 public static final Object sLock = new Object(); 69 70 private void handleRemoteException(RemoteException e) { 71 kilroy(); 72 Log.e(TAG, "RemoteException in HIDL call " + e); 73 } 74 75 private void noteHidlError(WifiStatus status, String culprit) { 76 kilroy(); 77 Log.e(TAG, "Error in " + culprit + " code: " + status.code 78 + " (" + status.description + ")"); 79 } 80 81 /** 82 * Initialize the Hal device manager and register for status callbacks. 83 * @return 84 */ 85 public boolean initialize() { 86 mHalDeviceManager.initialize(); 87 mHalDeviceManager.registerStatusListener( 88 mHalDeviceManagerStatusCallbacks, mWifiStateMachineHandlerThread.getLooper()); 89 return true; 90 } 91 92 /** 93 * Bring up the HIDL Vendor HAL and configure for AP (Access Point) mode 94 * @return true for success 95 */ 96 public boolean startVendorHalAp() { 97 return startVendorHal(AP_MODE); 98 } 99 100 /** 101 * Bring up the HIDL Vendor HAL and configure for STA (Station) mode 102 * @return true for success 103 */ 104 public boolean startVendorHalSta() { 105 return startVendorHal(STA_MODE); 106 } 107 108 109 public static final boolean STA_MODE = true; 110 public static final boolean AP_MODE = false; 111 112 /** 113 * Bring up the HIDL Vendor HAL and configure for STA mode or AP mode. 114 * 115 * @param isStaMode true to start HAL in STA mode, false to start in AP mode. 116 */ 117 public boolean startVendorHal(boolean isStaMode) { 118 if (!mHalDeviceManager.start()) { 119 Log.e(TAG, "Failed to start the vendor HAL"); 120 return false; 121 } 122 IWifiIface iface; 123 if (isStaMode) { 124 mIWifiStaIface = mHalDeviceManager.createStaIface(null, null); 125 if (mIWifiStaIface == null) { 126 Log.e(TAG, "Failed to create STA Iface. Vendor Hal start failed"); 127 mHalDeviceManager.stop(); 128 return false; 129 } 130 iface = (IWifiIface) mIWifiStaIface; 131 mIWifiRttController = mHalDeviceManager.createRttController(iface); 132 if (mIWifiRttController == null) { 133 Log.e(TAG, "Failed to create RTT controller. Vendor Hal start failed"); 134 stopVendorHal(); 135 return false; 136 } 137 enableLinkLayerStats(); 138 } else { 139 mIWifiApIface = mHalDeviceManager.createApIface(null, null); 140 if (mIWifiApIface == null) { 141 Log.e(TAG, "Failed to create AP Iface. Vendor Hal start failed"); 142 stopVendorHal(); 143 return false; 144 } 145 iface = (IWifiIface) mIWifiApIface; 146 } 147 mIWifiChip = mHalDeviceManager.getChip(iface); 148 if (mIWifiChip == null) { 149 Log.e(TAG, "Failed to get the chip created for the Iface. Vendor Hal start failed"); 150 stopVendorHal(); 151 return false; 152 } 153 Log.i(TAG, "Vendor Hal started successfully"); 154 return true; 155 } 156 157 /** 158 * Stops the HAL 159 */ 160 public void stopVendorHal() { 161 mHalDeviceManager.stop(); 162 Log.i(TAG, "Vendor Hal stopped"); 163 } 164 165 /** 166 * Tests whether the HAL is running or not 167 */ 168 public boolean isHalStarted() { 169 return (mIWifiStaIface != null || mIWifiApIface != null); 170 } 171 172 /** 173 * Gets the scan capabilities 174 * 175 * @param capabilities object to be filled in 176 * @return true for success. false for failure 177 */ 178 public boolean getScanCapabilities(WifiNative.ScanCapabilities capabilities) { 179 kilroy(); 180 throw new UnsupportedOperationException(); 181 } 182 183 /** 184 * to be implemented 185 */ 186 public boolean startScan(WifiNative.ScanSettings settings, 187 WifiNative.ScanEventHandler eventHandler) { 188 kilroy(); 189 throw new UnsupportedOperationException(); 190 } 191 192 /** 193 * to be implemented 194 */ 195 public void stopScan() { 196 kilroy(); 197 throw new UnsupportedOperationException(); 198 } 199 200 /** 201 * to be implemented 202 */ 203 public void pauseScan() { 204 kilroy(); 205 throw new UnsupportedOperationException(); 206 } 207 208 /** 209 * to be implemented 210 */ 211 public void restartScan() { 212 kilroy(); 213 throw new UnsupportedOperationException(); 214 } 215 216 /** 217 * to be implemented 218 */ 219 public WifiScanner.ScanData[] getScanResults(boolean flush) { 220 kilroy(); 221 throw new UnsupportedOperationException(); 222 } 223 224 /** 225 * Get the link layer statistics 226 * 227 * Note - we always enable link layer stats on a STA interface. 228 * 229 * @return the statistics, or null if unable to do so 230 */ 231 public WifiLinkLayerStats getWifiLinkLayerStats() { 232 kilroy(); 233 synchronized (sLock) { 234 try { 235 if (mIWifiStaIface == null) return null; 236 kilroy(); 237 WifiLinkLayerStats out = new WifiLinkLayerStats(); 238 MutableBoolean ok = new MutableBoolean(false); 239 kilroy(); 240 mIWifiStaIface.getLinkLayerStats((status, stats) -> { 241 kilroy(); 242 if (status.code != WifiStatusCode.SUCCESS) return; 243 out.status = 0; // TODO 244 out.SSID = null; // TODO 245 out.BSSID = null; // TODO 246 out.beacon_rx = stats.iface.beaconRx; 247 out.rssi_mgmt = stats.iface.avgRssiMgmt; 248 /* WME Best Effort Access Category */ 249 out.rxmpdu_be = stats.iface.wmeBePktStats.rxMpdu; 250 out.txmpdu_be = stats.iface.wmeBePktStats.txMpdu; 251 out.lostmpdu_be = stats.iface.wmeBePktStats.lostMpdu; 252 out.retries_be = stats.iface.wmeBePktStats.retries; 253 /* WME Background Access Category */ 254 out.rxmpdu_bk = stats.iface.wmeBkPktStats.rxMpdu; 255 out.txmpdu_bk = stats.iface.wmeBkPktStats.txMpdu; 256 out.lostmpdu_bk = stats.iface.wmeBkPktStats.lostMpdu; 257 out.retries_bk = stats.iface.wmeBkPktStats.retries; 258 /* WME Video Access Category */ 259 out.rxmpdu_vi = stats.iface.wmeViPktStats.rxMpdu; 260 out.txmpdu_vi = stats.iface.wmeViPktStats.txMpdu; 261 out.lostmpdu_vi = stats.iface.wmeViPktStats.lostMpdu; 262 out.retries_vi = stats.iface.wmeViPktStats.retries; 263 /* WME Voice Access Category */ 264 out.rxmpdu_vo = stats.iface.wmeVoPktStats.rxMpdu; 265 out.txmpdu_vo = stats.iface.wmeVoPktStats.txMpdu; 266 out.lostmpdu_vo = stats.iface.wmeVoPktStats.lostMpdu; 267 out.retries_vo = stats.iface.wmeVoPktStats.retries; 268 out.on_time = stats.radio.onTimeInMs; 269 out.tx_time = stats.radio.txTimeInMs; 270 out.tx_time_per_level = new int[stats.radio.txTimeInMsPerLevel.size()]; 271 for (int i = 0; i < out.tx_time_per_level.length; i++) { 272 out.tx_time_per_level[i] = stats.radio.txTimeInMsPerLevel.get(i); 273 } 274 out.rx_time = stats.radio.rxTimeInMs; 275 out.on_time_scan = stats.radio.onTimeInMsForScan; 276 kilroy(); 277 ok.value = true; 278 } 279 ); 280 return ok.value ? out : null; 281 } catch (RemoteException e) { 282 kilroy(); 283 handleRemoteException(e); 284 return null; 285 } 286 } 287 } 288 289 @VisibleForTesting 290 boolean mLinkLayerStatsDebug = false; // Passed to Hal 291 292 /** 293 * Enables the linkLayerStats in the Hal. 294 * 295 * This is called unconditionally whenever we create a STA interface. 296 * 297 */ 298 private void enableLinkLayerStats() { 299 synchronized (sLock) { 300 try { 301 kilroy(); 302 WifiStatus status; 303 status = mIWifiStaIface.enableLinkLayerStatsCollection(mLinkLayerStatsDebug); 304 if (status.code != WifiStatusCode.SUCCESS) { 305 kilroy(); 306 Log.e(TAG, "unable to enable link layer stats collection"); 307 } 308 } catch (RemoteException e) { 309 kilroy(); 310 handleRemoteException(e); 311 } 312 } 313 } 314 315 /** 316 * Get the supported features 317 * 318 * @return bitmask defined by WifiManager.WIFI_FEATURE_* 319 */ 320 public int getSupportedFeatureSet() { 321 kilroy(); 322 throw new UnsupportedOperationException(); 323 } 324 325 /* RTT related commands/events */ 326 327 /** 328 * Starts a new rtt request 329 * 330 * @param params 331 * @param handler 332 * @return success indication 333 */ 334 public boolean requestRtt(RttManager.RttParams[] params, WifiNative.RttEventHandler handler) { 335 kilroy(); 336 throw new UnsupportedOperationException(); 337 } 338 339 /** 340 * Cancels an outstanding rtt request 341 * 342 * @param params 343 * @return true if there was an outstanding request and it was successfully cancelled 344 */ 345 public boolean cancelRtt(RttManager.RttParams[] params) { 346 kilroy(); 347 throw new UnsupportedOperationException(); 348 } 349 350 /** 351 * Enables RTT responder role on the device. 352 * 353 * @return {@link ResponderConfig} if the responder role is successfully enabled, 354 * {@code null} otherwise. 355 */ 356 @Nullable 357 public ResponderConfig enableRttResponder(int timeoutSeconds) { 358 kilroy(); 359 throw new UnsupportedOperationException(); 360 } 361 362 /** 363 * Disables RTT responder role. 364 * 365 * @return {@code true} if responder role is successfully disabled, 366 * {@code false} otherwise. 367 */ 368 public boolean disableRttResponder() { 369 kilroy(); 370 throw new UnsupportedOperationException(); 371 } 372 373 /** 374 * not supported 375 */ 376 public boolean setScanningMacOui(byte[] oui) { 377 kilroy(); 378 throw new UnsupportedOperationException(); 379 } 380 381 /** 382 * not supported 383 */ 384 public int[] getChannelsForBand(int band) { 385 kilroy(); 386 throw new UnsupportedOperationException(); 387 } 388 389 /** 390 * not supported 391 */ 392 public boolean isGetChannelsForBandSupported() { 393 kilroy(); 394 throw new UnsupportedOperationException(); 395 } 396 397 /** 398 * Set DFS - actually, this is always on. 399 * 400 * @param dfsOn 401 * @return success indication 402 */ 403 public boolean setDfsFlag(boolean dfsOn) { 404 kilroy(); 405 throw new UnsupportedOperationException(); 406 } 407 408 /** 409 * RTT (Round Trip Time) measurement capabilities of the device. 410 */ 411 public RttManager.RttCapabilities getRttCapabilities() { 412 kilroy(); 413 throw new UnsupportedOperationException(); 414 } 415 416 /** 417 * Get the APF (Android Packet Filter) capabilities of the device 418 */ 419 public ApfCapabilities getApfCapabilities() { 420 kilroy(); 421 throw new UnsupportedOperationException(); 422 } 423 424 private static final ApfCapabilities sNoApfCapabilities = new ApfCapabilities(0, 0, 0); 425 426 /** 427 * Installs an APF program on this iface, replacing an existing 428 * program if present. 429 */ 430 public boolean installPacketFilter(byte[] filter) { 431 kilroy(); 432 throw new UnsupportedOperationException(); 433 } 434 435 436 /** 437 * to be implemented 438 */ 439 public boolean setCountryCodeHal(String countryCode) { 440 kilroy(); 441 throw new UnsupportedOperationException(); 442 } 443 444 /** 445 * not to be implemented 446 */ 447 public boolean enableDisableTdls(boolean enable, String macAdd, 448 WifiNative.TdlsEventHandler tdlsCallBack) { 449 kilroy(); 450 throw new UnsupportedOperationException(); 451 } 452 453 /** 454 * not to be implemented 455 */ 456 public WifiNative.TdlsStatus getTdlsStatus(String macAdd) { 457 kilroy(); 458 throw new UnsupportedOperationException(); 459 } 460 461 /** 462 * not to be implemented 463 */ 464 public WifiNative.TdlsCapabilities getTdlsCapabilities() { 465 kilroy(); 466 throw new UnsupportedOperationException(); 467 } 468 469 /** 470 * to be implemented 471 */ 472 public boolean setLoggingEventHandler(WifiNative.WifiLoggerEventHandler handler) { 473 kilroy(); 474 throw new UnsupportedOperationException(); 475 } 476 477 /** 478 * Control debug data collection 479 * 480 * @param verboseLevel 0 to 3, inclusive. 0 stops logging. 481 * @param flags Ignored. 482 * @param maxIntervalInSec Maximum interval between reports; ignore if 0. 483 * @param minDataSizeInBytes Minimum data size in buffer for report; ignore if 0. 484 * @param ringName Name of the ring for which data collection is to start. 485 * @return true for success 486 */ 487 public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxIntervalInSec, 488 int minDataSizeInBytes, String ringName) { 489 kilroy(); 490 throw new UnsupportedOperationException(); 491 } 492 493 /** 494 * Pointlessly fail 495 * 496 * @return -1 497 */ 498 public int getSupportedLoggerFeatureSet() { 499 return -1; 500 } 501 502 /** 503 * to be implemented 504 */ 505 public boolean resetLogHandler() { 506 kilroy(); 507 throw new UnsupportedOperationException(); 508 } 509 510 private String mDriverDescription; 511 512 /** 513 * Vendor-provided wifi driver version string 514 */ 515 public String getDriverVersion() { 516 kilroy(); 517 throw new UnsupportedOperationException(); 518 } 519 520 private String mFirmwareDescription; 521 522 /** 523 * Vendor-provided wifi firmware version string 524 */ 525 public String getFirmwareVersion() { 526 kilroy(); 527 throw new UnsupportedOperationException(); 528 } 529 530 /** 531 * API to get the status of all ring buffers supported by driver 532 */ 533 public WifiNative.RingBufferStatus[] getRingBufferStatus() { 534 kilroy(); 535 throw new UnsupportedOperationException(); 536 } 537 538 /** 539 * indicates to driver that all 540 * the data has to be uploaded urgently 541 */ 542 public boolean getRingBufferData(String ringName) { 543 kilroy(); 544 throw new UnsupportedOperationException(); 545 } 546 547 /** 548 * to be implemented via mIWifiChip.requestFirmwareDebugDump 549 */ 550 public byte[] getFwMemoryDump() { 551 kilroy(); 552 throw new UnsupportedOperationException(); 553 } 554 555 /** 556 * Request vendor debug info from the driver 557 */ 558 public byte[] getDriverStateDump() { 559 kilroy(); 560 throw new UnsupportedOperationException(); 561 } 562 563 /** 564 * Start packet fate monitoring 565 * <p> 566 * Once started, monitoring remains active until HAL is unloaded. 567 * 568 * @return true for success 569 */ 570 public boolean startPktFateMonitoring() { 571 kilroy(); 572 throw new UnsupportedOperationException(); 573 } 574 575 /** 576 * Retrieve fates of outbound packets 577 * <p> 578 * Reports the outbound frames for the most recent association (space allowing). 579 * 580 * @param reportBufs 581 * @return true for success 582 */ 583 public boolean getTxPktFates(WifiNative.TxFateReport[] reportBufs) { 584 kilroy(); 585 throw new UnsupportedOperationException(); 586 } 587 588 /** 589 * Retrieve fates of inbound packets 590 * <p> 591 * Reports the inbound frames for the most recent association (space allowing). 592 * 593 * @param reportBufs 594 * @return true for success 595 */ 596 public boolean getRxPktFates(WifiNative.RxFateReport[] reportBufs) { 597 kilroy(); 598 throw new UnsupportedOperationException(); 599 } 600 601 /** 602 * Start sending the specified keep alive packets periodically. 603 * 604 * @return 0 for success, -1 for error 605 */ 606 public int startSendingOffloadedPacket( 607 int slot, KeepalivePacketData keepAlivePacket, int periodInMs) { 608 kilroy(); 609 throw new UnsupportedOperationException(); 610 } 611 612 /** 613 * Stop sending the specified keep alive packets. 614 * 615 * @param slot id - same as startSendingOffloadedPacket call. 616 * @return 0 for success, -1 for error 617 */ 618 public int stopSendingOffloadedPacket(int slot) { 619 kilroy(); 620 throw new UnsupportedOperationException(); 621 } 622 623 /** 624 * Start RSSI monitoring on the currently connected access point. 625 * 626 * @param maxRssi Maximum RSSI threshold. 627 * @param minRssi Minimum RSSI threshold. 628 * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi 629 * @return 0 for success, -1 for failure 630 */ 631 public int startRssiMonitoring(byte maxRssi, byte minRssi, 632 WifiNative.WifiRssiEventHandler rssiEventHandler) { 633 kilroy(); 634 throw new UnsupportedOperationException(); 635 } 636 637 /** 638 * Stop RSSI monitoring 639 * 640 * @return 0 for success, -1 for failure 641 */ 642 public int stopRssiMonitoring() { 643 kilroy(); 644 throw new UnsupportedOperationException(); 645 } 646 647 private WifiDebugHostWakeReasonStats mWifiDebugHostWakeReasonStats; 648 649 /** 650 * Fetch the host wakeup reasons stats from wlan driver. 651 * 652 * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver. 653 */ 654 public WifiWakeReasonAndCounts getWlanWakeReasonCount() { 655 kilroy(); 656 throw new UnsupportedOperationException(); 657 } 658 659 /** 660 * Enable/Disable Neighbour discovery offload functionality in the firmware. 661 */ 662 public boolean configureNeighborDiscoveryOffload(boolean enabled) { 663 kilroy(); 664 throw new UnsupportedOperationException(); 665 } 666 667 // Firmware roaming control. 668 669 /** 670 * Query the firmware roaming capabilities. 671 * 672 * @param capabilities object to be filled in 673 * @return true for success; false for failure 674 */ 675 public boolean getRoamingCapabilities(WifiNative.RoamingCapabilities capabilities) { 676 kilroy(); 677 synchronized (sLock) { 678 kilroy(); 679 try { 680 kilroy(); 681 if (!isHalStarted()) return false; 682 MutableBoolean ok = new MutableBoolean(false); 683 WifiNative.RoamingCapabilities out = capabilities; 684 mIWifiStaIface.getRoamingCapabilities((status, cap) -> { 685 kilroy(); 686 if (status.code != WifiStatusCode.SUCCESS) return; 687 out.maxBlacklistSize = cap.maxBlacklistSize; 688 out.maxWhitelistSize = cap.maxWhitelistSize; 689 ok.value = true; 690 }); 691 return ok.value; 692 } catch (RemoteException e) { 693 kilroy(); 694 handleRemoteException(e); 695 return false; 696 } 697 } 698 } 699 700 /** 701 * Enable/disable firmware roaming. 702 * 703 * @param state the intended roaming state 704 * @return SUCCESS, FAILURE, or BUSY 705 */ 706 public int enableFirmwareRoaming(int state) { 707 kilroy(); 708 synchronized (sLock) { 709 kilroy(); 710 try { 711 kilroy(); 712 if (!isHalStarted()) return WifiStatusCode.ERROR_NOT_STARTED; 713 byte val; 714 switch (state) { 715 case WifiNative.DISABLE_FIRMWARE_ROAMING: 716 val = StaRoamingState.DISABLED; 717 break; 718 case WifiNative.ENABLE_FIRMWARE_ROAMING: 719 val = StaRoamingState.ENABLED; 720 break; 721 default: 722 Log.e(TAG, "enableFirmwareRoaming invalid argument " + state); 723 return WifiStatusCode.ERROR_INVALID_ARGS; 724 } 725 726 kilroy(); 727 WifiStatus status = mIWifiStaIface.setRoamingState(val); 728 Log.d(TAG, "setRoamingState returned " + status.code); 729 return status.code; 730 } catch (RemoteException e) { 731 kilroy(); 732 handleRemoteException(e); 733 return WifiStatusCode.ERROR_UNKNOWN; 734 } 735 } 736 } 737 738 /** 739 * Set firmware roaming configurations. 740 * 741 * @param config new roaming configuration object 742 * @return true for success; false for failure 743 */ 744 public boolean configureRoaming(WifiNative.RoamingConfig config) { 745 kilroy(); 746 synchronized (sLock) { 747 kilroy(); 748 try { 749 kilroy(); 750 if (!isHalStarted()) return false; 751 StaRoamingConfig roamingConfig = new StaRoamingConfig(); 752 753 // parse the blacklist BSSIDs if any 754 if (config.blacklistBssids != null) { 755 kilroy(); 756 for (String bssid : config.blacklistBssids) { 757 String unquotedMacStr = WifiInfo.removeDoubleQuotes(bssid); 758 byte[] mac = new byte[6]; 759 parseUnquotedMacStrToByteArray(unquotedMacStr, mac); 760 roamingConfig.bssidBlacklist.add(mac); 761 } 762 } 763 764 // parse the whitelist SSIDs if any 765 if (config.whitelistSsids != null) { 766 kilroy(); 767 for (String ssidStr : config.whitelistSsids) { 768 String unquotedSsidStr = WifiInfo.removeDoubleQuotes(ssidStr); 769 770 int len = unquotedSsidStr.length(); 771 if (len > 32) { 772 Log.e(TAG, "configureRoaming: skip invalid SSID " + unquotedSsidStr); 773 continue; 774 } 775 byte[] ssid = new byte[len]; 776 for (int i = 0; i < len; i++) { 777 ssid[i] = (byte) unquotedSsidStr.charAt(i); 778 } 779 roamingConfig.ssidWhitelist.add(ssid); 780 } 781 } 782 783 kilroy(); 784 WifiStatus status = mIWifiStaIface.configureRoaming(roamingConfig); 785 if (status.code != WifiStatusCode.SUCCESS) { 786 kilroy(); 787 noteHidlError(status, "configureRoaming"); 788 return false; 789 } 790 } catch (RemoteException e) { 791 kilroy(); 792 handleRemoteException(e); 793 return false; 794 } 795 kilroy(); 796 return true; 797 } 798 } 799 800 /** 801 * Helper function that parses unquoted MAC address string to a byte array 802 * 803 * @param macWithColons mac address string without double quotes 804 * @param mac an array of 6 bytes to receive the parsed mac address 805 */ 806 @VisibleForTesting 807 void parseUnquotedMacStrToByteArray(String macWithColons, byte[] mac) { 808 String[] macAddrStr = macWithColons.split(":"); 809 for (int i = 0; i < 6; i++) { 810 Integer hexVal = Integer.parseInt(macAddrStr[i], 16); 811 mac[i] = hexVal.byteValue(); 812 } 813 } 814 815 StackTraceElement[] mTrace; 816 817 private void kilroy() { 818 Thread cur = Thread.currentThread(); 819 mTrace = cur.getStackTrace(); 820 StackTraceElement s = mTrace[3]; 821 String name = s.getMethodName(); 822 if (name.contains("lambda$")) { 823 // Try to find a friendlier method name 824 String myFile = s.getFileName(); 825 if (myFile != null) { 826 for (int i = 4; i < mTrace.length; i++) { 827 if (myFile.equals(mTrace[i].getFileName())) { 828 name = mTrace[i].getMethodName(); 829 break; 830 } 831 } 832 } 833 } 834 Log.e(TAG, "th " + cur.getId() + " line " + s.getLineNumber() + " " + name); 835 } 836 837 /** 838 * Hal Device Manager callbacks. 839 */ 840 public class HalDeviceManagerStatusListener implements HalDeviceManager.ManagerStatusListener { 841 @Override 842 public void onStatusChanged() { 843 boolean isReady = mHalDeviceManager.isReady(); 844 boolean isStarted = mHalDeviceManager.isStarted(); 845 846 Log.i(TAG, "Device Manager onStatusChanged. isReady(): " + isReady 847 + ", isStarted(): " + isStarted); 848 // Reset all our cached handles. 849 if (!isReady || !isStarted) { 850 kilroy(); 851 mIWifiChip = null; 852 mIWifiStaIface = null; 853 mIWifiApIface = null; 854 mIWifiRttController = null; 855 mDriverDescription = null; 856 mFirmwareDescription = null; 857 } 858 } 859 } 860} 861