1 /* 2 * Copyright (C) 2008 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; 18 19 import android.annotation.Nullable; 20 import android.net.apf.ApfCapabilities; 21 import android.net.wifi.IApInterface; 22 import android.net.wifi.IClientInterface; 23 import android.net.wifi.RttManager; 24 import android.net.wifi.RttManager.ResponderConfig; 25 import android.net.wifi.ScanResult; 26 import android.net.wifi.WifiConfiguration; 27 import android.net.wifi.WifiLinkLayerStats; 28 import android.net.wifi.WifiScanner; 29 import android.net.wifi.WifiWakeReasonAndCounts; 30 import android.os.SystemClock; 31 import android.util.Log; 32 import android.util.Pair; 33 import android.util.SparseArray; 34 35 import com.android.internal.annotations.Immutable; 36 import com.android.internal.util.HexDump; 37 import com.android.server.connectivity.KeepalivePacketData; 38 import com.android.server.wifi.util.FrameParser; 39 40 import java.io.PrintWriter; 41 import java.io.StringWriter; 42 import java.nio.ByteBuffer; 43 import java.nio.CharBuffer; 44 import java.nio.charset.CharacterCodingException; 45 import java.nio.charset.CharsetDecoder; 46 import java.nio.charset.StandardCharsets; 47 import java.text.SimpleDateFormat; 48 import java.util.ArrayList; 49 import java.util.Date; 50 import java.util.Map; 51 import java.util.Objects; 52 import java.util.Set; 53 import java.util.TimeZone; 54 55 56 /** 57 * Native calls for bring up/shut down of the supplicant daemon and for 58 * sending requests to the supplicant daemon 59 * 60 * {@hide} 61 */ 62 public class WifiNative { 63 private final String mTAG; 64 private final String mInterfaceName; 65 private final SupplicantStaIfaceHal mSupplicantStaIfaceHal; 66 private final WifiVendorHal mWifiVendorHal; 67 private final WificondControl mWificondControl; 68 WifiNative(String interfaceName, WifiVendorHal vendorHal, SupplicantStaIfaceHal staIfaceHal, WificondControl condControl)69 public WifiNative(String interfaceName, WifiVendorHal vendorHal, 70 SupplicantStaIfaceHal staIfaceHal, WificondControl condControl) { 71 mTAG = "WifiNative-" + interfaceName; 72 mInterfaceName = interfaceName; 73 mWifiVendorHal = vendorHal; 74 mSupplicantStaIfaceHal = staIfaceHal; 75 mWificondControl = condControl; 76 } 77 getInterfaceName()78 public String getInterfaceName() { 79 return mInterfaceName; 80 } 81 82 /** 83 * Enable verbose logging for all sub modules. 84 */ enableVerboseLogging(int verbose)85 public void enableVerboseLogging(int verbose) { 86 mWificondControl.enableVerboseLogging(verbose > 0 ? true : false); 87 mSupplicantStaIfaceHal.enableVerboseLogging(verbose > 0); 88 mWifiVendorHal.enableVerboseLogging(verbose > 0); 89 } 90 91 /******************************************************** 92 * Native Initialization/Deinitialization 93 ********************************************************/ 94 public static final int SETUP_SUCCESS = 0; 95 public static final int SETUP_FAILURE_HAL = 1; 96 public static final int SETUP_FAILURE_WIFICOND = 2; 97 98 /** 99 * Setup wifi native for Client mode operations. 100 * 101 * 1. Starts the Wifi HAL and configures it in client/STA mode. 102 * 2. Setup Wificond to operate in client mode and retrieve the handle to use for client 103 * operations. 104 * 105 * @return Pair of <Integer, IClientInterface> to indicate the status and the associated wificond 106 * client interface binder handler (will be null on failure). 107 */ setupForClientMode()108 public Pair<Integer, IClientInterface> setupForClientMode() { 109 if (!startHalIfNecessary(true)) { 110 Log.e(mTAG, "Failed to start HAL for client mode"); 111 return Pair.create(SETUP_FAILURE_HAL, null); 112 } 113 IClientInterface iClientInterface = mWificondControl.setupDriverForClientMode(); 114 if (iClientInterface == null) { 115 return Pair.create(SETUP_FAILURE_WIFICOND, null); 116 } 117 return Pair.create(SETUP_SUCCESS, iClientInterface); 118 } 119 120 /** 121 * Setup wifi native for AP mode operations. 122 * 123 * 1. Starts the Wifi HAL and configures it in AP mode. 124 * 2. Setup Wificond to operate in AP mode and retrieve the handle to use for ap operations. 125 * 126 * @return Pair of <Integer, IApInterface> to indicate the status and the associated wificond 127 * AP interface binder handler (will be null on failure). 128 */ setupForSoftApMode()129 public Pair<Integer, IApInterface> setupForSoftApMode() { 130 if (!startHalIfNecessary(false)) { 131 Log.e(mTAG, "Failed to start HAL for AP mode"); 132 return Pair.create(SETUP_FAILURE_HAL, null); 133 } 134 IApInterface iApInterface = mWificondControl.setupDriverForSoftApMode(); 135 if (iApInterface == null) { 136 return Pair.create(SETUP_FAILURE_WIFICOND, null); 137 } 138 return Pair.create(SETUP_SUCCESS, iApInterface); 139 } 140 141 /** 142 * Teardown all mode configurations in wifi native. 143 * 144 * 1. Stops the Wifi HAL. 145 * 2. Tears down all the interfaces from Wificond. 146 */ tearDown()147 public void tearDown() { 148 stopHalIfNecessary(); 149 if (!mWificondControl.tearDownInterfaces()) { 150 // TODO(b/34859006): Handle failures. 151 Log.e(mTAG, "Failed to teardown interfaces from Wificond"); 152 } 153 } 154 155 /******************************************************** 156 * Wificond operations 157 ********************************************************/ 158 /** 159 * Result of a signal poll. 160 */ 161 public static class SignalPollResult { 162 // RSSI value in dBM. 163 public int currentRssi; 164 //Transmission bit rate in Mbps. 165 public int txBitrate; 166 // Association frequency in MHz. 167 public int associationFrequency; 168 } 169 170 /** 171 * WiFi interface transimission counters. 172 */ 173 public static class TxPacketCounters { 174 // Number of successfully transmitted packets. 175 public int txSucceeded; 176 // Number of tramsmission failures. 177 public int txFailed; 178 } 179 180 /** 181 * Disable wpa_supplicant via wificond. 182 * @return Returns true on success. 183 */ disableSupplicant()184 public boolean disableSupplicant() { 185 return mWificondControl.disableSupplicant(); 186 } 187 188 /** 189 * Enable wpa_supplicant via wificond. 190 * @return Returns true on success. 191 */ enableSupplicant()192 public boolean enableSupplicant() { 193 return mWificondControl.enableSupplicant(); 194 } 195 196 /** 197 * Request signal polling to wificond. 198 * Returns an SignalPollResult object. 199 * Returns null on failure. 200 */ signalPoll()201 public SignalPollResult signalPoll() { 202 return mWificondControl.signalPoll(); 203 } 204 205 /** 206 * Fetch TX packet counters on current connection from wificond. 207 * Returns an TxPacketCounters object. 208 * Returns null on failure. 209 */ getTxPacketCounters()210 public TxPacketCounters getTxPacketCounters() { 211 return mWificondControl.getTxPacketCounters(); 212 } 213 214 /** 215 * Start a scan using wificond for the given parameters. 216 * @param freqs list of frequencies to scan for, if null scan all supported channels. 217 * @param hiddenNetworkSSIDs List of hidden networks to be scanned for. 218 * @return Returns true on success. 219 */ scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs)220 public boolean scan(Set<Integer> freqs, Set<String> hiddenNetworkSSIDs) { 221 return mWificondControl.scan(freqs, hiddenNetworkSSIDs); 222 } 223 224 /** 225 * Fetch the latest scan result from kernel via wificond. 226 * @return Returns an ArrayList of ScanDetail. 227 * Returns an empty ArrayList on failure. 228 */ getScanResults()229 public ArrayList<ScanDetail> getScanResults() { 230 return mWificondControl.getScanResults(WificondControl.SCAN_TYPE_SINGLE_SCAN); 231 } 232 233 /** 234 * Fetch the latest scan result from kernel via wificond. 235 * @return Returns an ArrayList of ScanDetail. 236 * Returns an empty ArrayList on failure. 237 */ getPnoScanResults()238 public ArrayList<ScanDetail> getPnoScanResults() { 239 return mWificondControl.getScanResults(WificondControl.SCAN_TYPE_PNO_SCAN); 240 } 241 242 /** 243 * Start PNO scan. 244 * @param pnoSettings Pno scan configuration. 245 * @return true on success. 246 */ startPnoScan(PnoSettings pnoSettings)247 public boolean startPnoScan(PnoSettings pnoSettings) { 248 return mWificondControl.startPnoScan(pnoSettings); 249 } 250 251 /** 252 * Stop PNO scan. 253 * @return true on success. 254 */ stopPnoScan()255 public boolean stopPnoScan() { 256 return mWificondControl.stopPnoScan(); 257 } 258 259 /******************************************************** 260 * Supplicant operations 261 ********************************************************/ 262 263 /** 264 * This method is called repeatedly until the connection to wpa_supplicant is established. 265 * 266 * @return true if connection is established, false otherwise. 267 * TODO: Add unit tests for these once we remove the legacy code. 268 */ connectToSupplicant()269 public boolean connectToSupplicant() { 270 // Start initialization if not already started. 271 if (!mSupplicantStaIfaceHal.isInitializationStarted() 272 && !mSupplicantStaIfaceHal.initialize()) { 273 return false; 274 } 275 // Check if the initialization is complete. 276 return mSupplicantStaIfaceHal.isInitializationComplete(); 277 } 278 279 /** 280 * Close supplicant connection. 281 */ closeSupplicantConnection()282 public void closeSupplicantConnection() { 283 // Nothing to do for HIDL. 284 } 285 286 /** 287 * Set supplicant log level 288 * 289 * @param turnOnVerbose Whether to turn on verbose logging or not. 290 */ setSupplicantLogLevel(boolean turnOnVerbose)291 public void setSupplicantLogLevel(boolean turnOnVerbose) { 292 mSupplicantStaIfaceHal.setLogLevel(turnOnVerbose); 293 } 294 295 /** 296 * Trigger a reconnection if the iface is disconnected. 297 * 298 * @return true if request is sent successfully, false otherwise. 299 */ reconnect()300 public boolean reconnect() { 301 return mSupplicantStaIfaceHal.reconnect(); 302 } 303 304 /** 305 * Trigger a reassociation even if the iface is currently connected. 306 * 307 * @return true if request is sent successfully, false otherwise. 308 */ reassociate()309 public boolean reassociate() { 310 return mSupplicantStaIfaceHal.reassociate(); 311 } 312 313 /** 314 * Trigger a disconnection from the currently connected network. 315 * 316 * @return true if request is sent successfully, false otherwise. 317 */ disconnect()318 public boolean disconnect() { 319 return mSupplicantStaIfaceHal.disconnect(); 320 } 321 322 /** 323 * Makes a callback to HIDL to getMacAddress from supplicant 324 * 325 * @return string containing the MAC address, or null on a failed call 326 */ getMacAddress()327 public String getMacAddress() { 328 return mSupplicantStaIfaceHal.getMacAddress(); 329 } 330 331 public static final int RX_FILTER_TYPE_V4_MULTICAST = 0; 332 public static final int RX_FILTER_TYPE_V6_MULTICAST = 1; 333 /** 334 * Start filtering out Multicast V4 packets 335 * @return {@code true} if the operation succeeded, {@code false} otherwise 336 * 337 * Multicast filtering rules work as follows: 338 * 339 * The driver can filter multicast (v4 and/or v6) and broadcast packets when in 340 * a power optimized mode (typically when screen goes off). 341 * 342 * In order to prevent the driver from filtering the multicast/broadcast packets, we have to 343 * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective 344 * 345 * DRIVER RXFILTER-ADD Num 346 * where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6 347 * 348 * and DRIVER RXFILTER-START 349 * In order to stop the usage of these rules, we do 350 * 351 * DRIVER RXFILTER-STOP 352 * DRIVER RXFILTER-REMOVE Num 353 * where Num is as described for RXFILTER-ADD 354 * 355 * The SETSUSPENDOPT driver command overrides the filtering rules 356 */ startFilteringMulticastV4Packets()357 public boolean startFilteringMulticastV4Packets() { 358 return mSupplicantStaIfaceHal.stopRxFilter() 359 && mSupplicantStaIfaceHal.removeRxFilter( 360 RX_FILTER_TYPE_V4_MULTICAST) 361 && mSupplicantStaIfaceHal.startRxFilter(); 362 } 363 364 /** 365 * Stop filtering out Multicast V4 packets. 366 * @return {@code true} if the operation succeeded, {@code false} otherwise 367 */ stopFilteringMulticastV4Packets()368 public boolean stopFilteringMulticastV4Packets() { 369 return mSupplicantStaIfaceHal.stopRxFilter() 370 && mSupplicantStaIfaceHal.addRxFilter( 371 RX_FILTER_TYPE_V4_MULTICAST) 372 && mSupplicantStaIfaceHal.startRxFilter(); 373 } 374 375 /** 376 * Start filtering out Multicast V6 packets 377 * @return {@code true} if the operation succeeded, {@code false} otherwise 378 */ startFilteringMulticastV6Packets()379 public boolean startFilteringMulticastV6Packets() { 380 return mSupplicantStaIfaceHal.stopRxFilter() 381 && mSupplicantStaIfaceHal.removeRxFilter( 382 RX_FILTER_TYPE_V6_MULTICAST) 383 && mSupplicantStaIfaceHal.startRxFilter(); 384 } 385 386 /** 387 * Stop filtering out Multicast V6 packets. 388 * @return {@code true} if the operation succeeded, {@code false} otherwise 389 */ stopFilteringMulticastV6Packets()390 public boolean stopFilteringMulticastV6Packets() { 391 return mSupplicantStaIfaceHal.stopRxFilter() 392 && mSupplicantStaIfaceHal.addRxFilter( 393 RX_FILTER_TYPE_V6_MULTICAST) 394 && mSupplicantStaIfaceHal.startRxFilter(); 395 } 396 397 public static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0; 398 public static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED = 1; 399 public static final int BLUETOOTH_COEXISTENCE_MODE_SENSE = 2; 400 /** 401 * Sets the bluetooth coexistence mode. 402 * 403 * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED}, 404 * {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or 405 * {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}. 406 * @return Whether the mode was successfully set. 407 */ setBluetoothCoexistenceMode(int mode)408 public boolean setBluetoothCoexistenceMode(int mode) { 409 return mSupplicantStaIfaceHal.setBtCoexistenceMode(mode); 410 } 411 412 /** 413 * Enable or disable Bluetooth coexistence scan mode. When this mode is on, 414 * some of the low-level scan parameters used by the driver are changed to 415 * reduce interference with A2DP streaming. 416 * 417 * @param setCoexScanMode whether to enable or disable this mode 418 * @return {@code true} if the command succeeded, {@code false} otherwise. 419 */ setBluetoothCoexistenceScanMode(boolean setCoexScanMode)420 public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) { 421 return mSupplicantStaIfaceHal.setBtCoexistenceScanModeEnabled(setCoexScanMode); 422 } 423 424 /** 425 * Enable or disable suspend mode optimizations. 426 * 427 * @param enabled true to enable, false otherwise. 428 * @return true if request is sent successfully, false otherwise. 429 */ setSuspendOptimizations(boolean enabled)430 public boolean setSuspendOptimizations(boolean enabled) { 431 return mSupplicantStaIfaceHal.setSuspendModeEnabled(enabled); 432 } 433 434 /** 435 * Set country code. 436 * 437 * @param countryCode 2 byte ASCII string. For ex: US, CA. 438 * @return true if request is sent successfully, false otherwise. 439 */ setCountryCode(String countryCode)440 public boolean setCountryCode(String countryCode) { 441 return mSupplicantStaIfaceHal.setCountryCode(countryCode); 442 } 443 444 /** 445 * Initiate TDLS discover and setup or teardown with the specified peer. 446 * 447 * @param macAddr MAC Address of the peer. 448 * @param enable true to start discovery and setup, false to teardown. 449 */ startTdls(String macAddr, boolean enable)450 public void startTdls(String macAddr, boolean enable) { 451 if (enable) { 452 mSupplicantStaIfaceHal.initiateTdlsDiscover(macAddr); 453 mSupplicantStaIfaceHal.initiateTdlsSetup(macAddr); 454 } else { 455 mSupplicantStaIfaceHal.initiateTdlsTeardown(macAddr); 456 } 457 } 458 459 /** 460 * Start WPS pin display operation with the specified peer. 461 * 462 * @param bssid BSSID of the peer. 463 * @return true if request is sent successfully, false otherwise. 464 */ startWpsPbc(String bssid)465 public boolean startWpsPbc(String bssid) { 466 return mSupplicantStaIfaceHal.startWpsPbc(bssid); 467 } 468 469 /** 470 * Start WPS pin keypad operation with the specified pin. 471 * 472 * @param pin Pin to be used. 473 * @return true if request is sent successfully, false otherwise. 474 */ startWpsPinKeypad(String pin)475 public boolean startWpsPinKeypad(String pin) { 476 return mSupplicantStaIfaceHal.startWpsPinKeypad(pin); 477 } 478 479 /** 480 * Start WPS pin display operation with the specified peer. 481 * 482 * @param bssid BSSID of the peer. 483 * @return new pin generated on success, null otherwise. 484 */ startWpsPinDisplay(String bssid)485 public String startWpsPinDisplay(String bssid) { 486 return mSupplicantStaIfaceHal.startWpsPinDisplay(bssid); 487 } 488 489 /** 490 * Sets whether to use external sim for SIM/USIM processing. 491 * 492 * @param external true to enable, false otherwise. 493 * @return true if request is sent successfully, false otherwise. 494 */ setExternalSim(boolean external)495 public boolean setExternalSim(boolean external) { 496 return mSupplicantStaIfaceHal.setExternalSim(external); 497 } 498 499 /** 500 * Sim auth response types. 501 */ 502 public static final String SIM_AUTH_RESP_TYPE_GSM_AUTH = "GSM-AUTH"; 503 public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTH = "UMTS-AUTH"; 504 public static final String SIM_AUTH_RESP_TYPE_UMTS_AUTS = "UMTS-AUTS"; 505 506 /** 507 * Send the sim auth response for the currently configured network. 508 * 509 * @param type |GSM-AUTH|, |UMTS-AUTH| or |UMTS-AUTS|. 510 * @param response Response params. 511 * @return true if succeeds, false otherwise. 512 */ simAuthResponse(int id, String type, String response)513 public boolean simAuthResponse(int id, String type, String response) { 514 if (SIM_AUTH_RESP_TYPE_GSM_AUTH.equals(type)) { 515 return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthResponse(response); 516 } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTH.equals(type)) { 517 return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthResponse(response); 518 } else if (SIM_AUTH_RESP_TYPE_UMTS_AUTS.equals(type)) { 519 return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAutsResponse(response); 520 } else { 521 return false; 522 } 523 } 524 525 /** 526 * Send the eap sim gsm auth failure for the currently configured network. 527 * 528 * @return true if succeeds, false otherwise. 529 */ simAuthFailedResponse(int id)530 public boolean simAuthFailedResponse(int id) { 531 return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimGsmAuthFailure(); 532 } 533 534 /** 535 * Send the eap sim umts auth failure for the currently configured network. 536 * 537 * @return true if succeeds, false otherwise. 538 */ umtsAuthFailedResponse(int id)539 public boolean umtsAuthFailedResponse(int id) { 540 return mSupplicantStaIfaceHal.sendCurrentNetworkEapSimUmtsAuthFailure(); 541 } 542 543 /** 544 * Send the eap identity response for the currently configured network. 545 * 546 * @param response String to send. 547 * @return true if succeeds, false otherwise. 548 */ simIdentityResponse(int id, String response)549 public boolean simIdentityResponse(int id, String response) { 550 return mSupplicantStaIfaceHal.sendCurrentNetworkEapIdentityResponse(response); 551 } 552 553 /** 554 * This get anonymous identity from supplicant and returns it as a string. 555 * 556 * @return anonymous identity string if succeeds, null otherwise. 557 */ getEapAnonymousIdentity()558 public String getEapAnonymousIdentity() { 559 return mSupplicantStaIfaceHal.getCurrentNetworkEapAnonymousIdentity(); 560 } 561 562 /** 563 * Start WPS pin registrar operation with the specified peer and pin. 564 * 565 * @param bssid BSSID of the peer. 566 * @param pin Pin to be used. 567 * @return true if request is sent successfully, false otherwise. 568 */ startWpsRegistrar(String bssid, String pin)569 public boolean startWpsRegistrar(String bssid, String pin) { 570 return mSupplicantStaIfaceHal.startWpsRegistrar(bssid, pin); 571 } 572 573 /** 574 * Cancels any ongoing WPS requests. 575 * 576 * @return true if request is sent successfully, false otherwise. 577 */ cancelWps()578 public boolean cancelWps() { 579 return mSupplicantStaIfaceHal.cancelWps(); 580 } 581 582 /** 583 * Set WPS device name. 584 * 585 * @param name String to be set. 586 * @return true if request is sent successfully, false otherwise. 587 */ setDeviceName(String name)588 public boolean setDeviceName(String name) { 589 return mSupplicantStaIfaceHal.setWpsDeviceName(name); 590 } 591 592 /** 593 * Set WPS device type. 594 * 595 * @param type Type specified as a string. Used format: <categ>-<OUI>-<subcateg> 596 * @return true if request is sent successfully, false otherwise. 597 */ setDeviceType(String type)598 public boolean setDeviceType(String type) { 599 return mSupplicantStaIfaceHal.setWpsDeviceType(type); 600 } 601 602 /** 603 * Set WPS config methods 604 * 605 * @param cfg List of config methods. 606 * @return true if request is sent successfully, false otherwise. 607 */ setConfigMethods(String cfg)608 public boolean setConfigMethods(String cfg) { 609 return mSupplicantStaIfaceHal.setWpsConfigMethods(cfg); 610 } 611 612 /** 613 * Set WPS manufacturer. 614 * 615 * @param value String to be set. 616 * @return true if request is sent successfully, false otherwise. 617 */ setManufacturer(String value)618 public boolean setManufacturer(String value) { 619 return mSupplicantStaIfaceHal.setWpsManufacturer(value); 620 } 621 622 /** 623 * Set WPS model name. 624 * 625 * @param value String to be set. 626 * @return true if request is sent successfully, false otherwise. 627 */ setModelName(String value)628 public boolean setModelName(String value) { 629 return mSupplicantStaIfaceHal.setWpsModelName(value); 630 } 631 632 /** 633 * Set WPS model number. 634 * 635 * @param value String to be set. 636 * @return true if request is sent successfully, false otherwise. 637 */ setModelNumber(String value)638 public boolean setModelNumber(String value) { 639 return mSupplicantStaIfaceHal.setWpsModelNumber(value); 640 } 641 642 /** 643 * Set WPS serial number. 644 * 645 * @param value String to be set. 646 * @return true if request is sent successfully, false otherwise. 647 */ setSerialNumber(String value)648 public boolean setSerialNumber(String value) { 649 return mSupplicantStaIfaceHal.setWpsSerialNumber(value); 650 } 651 652 /** 653 * Enable or disable power save mode. 654 * 655 * @param enabled true to enable, false to disable. 656 */ setPowerSave(boolean enabled)657 public void setPowerSave(boolean enabled) { 658 mSupplicantStaIfaceHal.setPowerSave(enabled); 659 } 660 661 /** 662 * Set concurrency priority between P2P & STA operations. 663 * 664 * @param isStaHigherPriority Set to true to prefer STA over P2P during concurrency operations, 665 * false otherwise. 666 * @return true if request is sent successfully, false otherwise. 667 */ setConcurrencyPriority(boolean isStaHigherPriority)668 public boolean setConcurrencyPriority(boolean isStaHigherPriority) { 669 return mSupplicantStaIfaceHal.setConcurrencyPriority(isStaHigherPriority); 670 } 671 672 /** 673 * Enable/Disable auto reconnect functionality in wpa_supplicant. 674 * 675 * @param enable true to enable auto reconnecting, false to disable. 676 * @return true if request is sent successfully, false otherwise. 677 */ enableStaAutoReconnect(boolean enable)678 public boolean enableStaAutoReconnect(boolean enable) { 679 return mSupplicantStaIfaceHal.enableAutoReconnect(enable); 680 } 681 682 /** 683 * Migrate all the configured networks from wpa_supplicant. 684 * 685 * @param configs Map of configuration key to configuration objects corresponding to all 686 * the networks. 687 * @param networkExtras Map of extra configuration parameters stored in wpa_supplicant.conf 688 * @return Max priority of all the configs. 689 */ migrateNetworksFromSupplicant(Map<String, WifiConfiguration> configs, SparseArray<Map<String, String>> networkExtras)690 public boolean migrateNetworksFromSupplicant(Map<String, WifiConfiguration> configs, 691 SparseArray<Map<String, String>> networkExtras) { 692 return mSupplicantStaIfaceHal.loadNetworks(configs, networkExtras); 693 } 694 695 /** 696 * Add the provided network configuration to wpa_supplicant and initiate connection to it. 697 * This method does the following: 698 * 1. Abort any ongoing scan to unblock the connection request. 699 * 2. Remove any existing network in wpa_supplicant(This implicitly triggers disconnect). 700 * 3. Add a new network to wpa_supplicant. 701 * 4. Save the provided configuration to wpa_supplicant. 702 * 5. Select the new network in wpa_supplicant. 703 * 6. Triggers reconnect command to wpa_supplicant. 704 * 705 * @param configuration WifiConfiguration parameters for the provided network. 706 * @return {@code true} if it succeeds, {@code false} otherwise 707 */ connectToNetwork(WifiConfiguration configuration)708 public boolean connectToNetwork(WifiConfiguration configuration) { 709 // Abort ongoing scan before connect() to unblock connection request. 710 mWificondControl.abortScan(); 711 return mSupplicantStaIfaceHal.connectToNetwork(configuration); 712 } 713 714 /** 715 * Initiates roaming to the already configured network in wpa_supplicant. If the network 716 * configuration provided does not match the already configured network, then this triggers 717 * a new connection attempt (instead of roam). 718 * 1. Abort any ongoing scan to unblock the roam request. 719 * 2. First check if we're attempting to connect to the same network as we currently have 720 * configured. 721 * 3. Set the new bssid for the network in wpa_supplicant. 722 * 4. Triggers reassociate command to wpa_supplicant. 723 * 724 * @param configuration WifiConfiguration parameters for the provided network. 725 * @return {@code true} if it succeeds, {@code false} otherwise 726 */ roamToNetwork(WifiConfiguration configuration)727 public boolean roamToNetwork(WifiConfiguration configuration) { 728 // Abort ongoing scan before connect() to unblock roaming request. 729 mWificondControl.abortScan(); 730 return mSupplicantStaIfaceHal.roamToNetwork(configuration); 731 } 732 733 /** 734 * Get the framework network ID corresponding to the provided supplicant network ID for the 735 * network configured in wpa_supplicant. 736 * 737 * @param supplicantNetworkId network ID in wpa_supplicant for the network. 738 * @return Corresponding framework network ID if found, -1 if network not found. 739 */ getFrameworkNetworkId(int supplicantNetworkId)740 public int getFrameworkNetworkId(int supplicantNetworkId) { 741 return supplicantNetworkId; 742 } 743 744 /** 745 * Remove all the networks. 746 * 747 * @return {@code true} if it succeeds, {@code false} otherwise 748 */ removeAllNetworks()749 public boolean removeAllNetworks() { 750 return mSupplicantStaIfaceHal.removeAllNetworks(); 751 } 752 753 /** 754 * Set the BSSID for the currently configured network in wpa_supplicant. 755 * 756 * @return true if successful, false otherwise. 757 */ setConfiguredNetworkBSSID(String bssid)758 public boolean setConfiguredNetworkBSSID(String bssid) { 759 return mSupplicantStaIfaceHal.setCurrentNetworkBssid(bssid); 760 } 761 762 /** 763 * Initiate ANQP query. 764 * 765 * @param bssid BSSID of the AP to be queried 766 * @param anqpIds Set of anqp IDs. 767 * @param hs20Subtypes Set of HS20 subtypes. 768 * @return true on success, false otherwise. 769 */ requestAnqp(String bssid, Set<Integer> anqpIds, Set<Integer> hs20Subtypes)770 public boolean requestAnqp(String bssid, Set<Integer> anqpIds, Set<Integer> hs20Subtypes) { 771 if (bssid == null || ((anqpIds == null || anqpIds.isEmpty()) 772 && (hs20Subtypes == null || hs20Subtypes.isEmpty()))) { 773 Log.e(mTAG, "Invalid arguments for ANQP request."); 774 return false; 775 } 776 ArrayList<Short> anqpIdList = new ArrayList<>(); 777 for (Integer anqpId : anqpIds) { 778 anqpIdList.add(anqpId.shortValue()); 779 } 780 ArrayList<Integer> hs20SubtypeList = new ArrayList<>(); 781 hs20SubtypeList.addAll(hs20Subtypes); 782 return mSupplicantStaIfaceHal.initiateAnqpQuery(bssid, anqpIdList, hs20SubtypeList); 783 } 784 785 /** 786 * Request a passpoint icon file |filename| from the specified AP |bssid|. 787 * @param bssid BSSID of the AP 788 * @param fileName name of the icon file 789 * @return true if request is sent successfully, false otherwise 790 */ requestIcon(String bssid, String fileName)791 public boolean requestIcon(String bssid, String fileName) { 792 if (bssid == null || fileName == null) { 793 Log.e(mTAG, "Invalid arguments for Icon request."); 794 return false; 795 } 796 return mSupplicantStaIfaceHal.initiateHs20IconQuery(bssid, fileName); 797 } 798 799 /** 800 * Get the currently configured network's WPS NFC token. 801 * 802 * @return Hex string corresponding to the WPS NFC token. 803 */ getCurrentNetworkWpsNfcConfigurationToken()804 public String getCurrentNetworkWpsNfcConfigurationToken() { 805 return mSupplicantStaIfaceHal.getCurrentNetworkWpsNfcConfigurationToken(); 806 } 807 808 /** Remove the request |networkId| from supplicant if it's the current network, 809 * if the current configured network matches |networkId|. 810 * 811 * @param networkId network id of the network to be removed from supplicant. 812 */ removeNetworkIfCurrent(int networkId)813 public void removeNetworkIfCurrent(int networkId) { 814 mSupplicantStaIfaceHal.removeNetworkIfCurrent(networkId); 815 } 816 817 /******************************************************** 818 * Vendor HAL operations 819 ********************************************************/ 820 /** 821 * Callback to notify vendor HAL death. 822 */ 823 public interface VendorHalDeathEventHandler { 824 /** 825 * Invoked when the vendor HAL dies. 826 */ onDeath()827 void onDeath(); 828 } 829 830 /** 831 * Initializes the vendor HAL. This is just used to initialize the {@link HalDeviceManager}. 832 */ initializeVendorHal(VendorHalDeathEventHandler handler)833 public boolean initializeVendorHal(VendorHalDeathEventHandler handler) { 834 return mWifiVendorHal.initialize(handler); 835 } 836 837 /** 838 * Bring up the Vendor HAL and configure for STA mode or AP mode, if vendor HAL is supported. 839 * 840 * @param isStaMode true to start HAL in STA mode, false to start in AP mode. 841 * @return false if the HAL start fails, true if successful or if vendor HAL not supported. 842 */ startHalIfNecessary(boolean isStaMode)843 private boolean startHalIfNecessary(boolean isStaMode) { 844 if (!mWifiVendorHal.isVendorHalSupported()) { 845 Log.i(mTAG, "Vendor HAL not supported, Ignore start..."); 846 return true; 847 } 848 return mWifiVendorHal.startVendorHal(isStaMode); 849 } 850 851 /** 852 * Stops the HAL, if vendor HAL is supported. 853 */ stopHalIfNecessary()854 private void stopHalIfNecessary() { 855 if (!mWifiVendorHal.isVendorHalSupported()) { 856 Log.i(mTAG, "Vendor HAL not supported, Ignore stop..."); 857 return; 858 } 859 mWifiVendorHal.stopVendorHal(); 860 } 861 862 /** 863 * Tests whether the HAL is running or not 864 */ isHalStarted()865 public boolean isHalStarted() { 866 return mWifiVendorHal.isHalStarted(); 867 } 868 869 // TODO: Change variable names to camel style. 870 public static class ScanCapabilities { 871 public int max_scan_cache_size; 872 public int max_scan_buckets; 873 public int max_ap_cache_per_scan; 874 public int max_rssi_sample_size; 875 public int max_scan_reporting_threshold; 876 } 877 878 /** 879 * Gets the scan capabilities 880 * 881 * @param capabilities object to be filled in 882 * @return true for success. false for failure 883 */ getBgScanCapabilities(ScanCapabilities capabilities)884 public boolean getBgScanCapabilities(ScanCapabilities capabilities) { 885 return mWifiVendorHal.getBgScanCapabilities(capabilities); 886 } 887 888 public static class ChannelSettings { 889 public int frequency; 890 public int dwell_time_ms; 891 public boolean passive; 892 } 893 894 public static class BucketSettings { 895 public int bucket; 896 public int band; 897 public int period_ms; 898 public int max_period_ms; 899 public int step_count; 900 public int report_events; 901 public int num_channels; 902 public ChannelSettings[] channels; 903 } 904 905 /** 906 * Network parameters for hidden networks to be scanned for. 907 */ 908 public static class HiddenNetwork { 909 public String ssid; 910 911 @Override equals(Object otherObj)912 public boolean equals(Object otherObj) { 913 if (this == otherObj) { 914 return true; 915 } else if (otherObj == null || getClass() != otherObj.getClass()) { 916 return false; 917 } 918 HiddenNetwork other = (HiddenNetwork) otherObj; 919 return Objects.equals(ssid, other.ssid); 920 } 921 922 @Override hashCode()923 public int hashCode() { 924 return (ssid == null ? 0 : ssid.hashCode()); 925 } 926 } 927 928 public static class ScanSettings { 929 public int base_period_ms; 930 public int max_ap_per_scan; 931 public int report_threshold_percent; 932 public int report_threshold_num_scans; 933 public int num_buckets; 934 /* Not used for bg scans. Only works for single scans. */ 935 public HiddenNetwork[] hiddenNetworks; 936 public BucketSettings[] buckets; 937 } 938 939 /** 940 * Network parameters to start PNO scan. 941 */ 942 public static class PnoNetwork { 943 public String ssid; 944 public byte flags; 945 public byte auth_bit_field; 946 947 @Override equals(Object otherObj)948 public boolean equals(Object otherObj) { 949 if (this == otherObj) { 950 return true; 951 } else if (otherObj == null || getClass() != otherObj.getClass()) { 952 return false; 953 } 954 PnoNetwork other = (PnoNetwork) otherObj; 955 return ((Objects.equals(ssid, other.ssid)) && (flags == other.flags) 956 && (auth_bit_field == other.auth_bit_field)); 957 } 958 959 @Override hashCode()960 public int hashCode() { 961 int result = (ssid == null ? 0 : ssid.hashCode()); 962 result ^= ((int) flags * 31) + ((int) auth_bit_field << 8); 963 return result; 964 } 965 } 966 967 /** 968 * Parameters to start PNO scan. This holds the list of networks which are going to used for 969 * PNO scan. 970 */ 971 public static class PnoSettings { 972 public int min5GHzRssi; 973 public int min24GHzRssi; 974 public int initialScoreMax; 975 public int currentConnectionBonus; 976 public int sameNetworkBonus; 977 public int secureBonus; 978 public int band5GHzBonus; 979 public int periodInMs; 980 public boolean isConnected; 981 public PnoNetwork[] networkList; 982 } 983 984 public static interface ScanEventHandler { 985 /** 986 * Called for each AP as it is found with the entire contents of the beacon/probe response. 987 * Only called when WifiScanner.REPORT_EVENT_FULL_SCAN_RESULT is specified. 988 */ onFullScanResult(ScanResult fullScanResult, int bucketsScanned)989 void onFullScanResult(ScanResult fullScanResult, int bucketsScanned); 990 /** 991 * Callback on an event during a gscan scan. 992 * See WifiNative.WIFI_SCAN_* for possible values. 993 */ onScanStatus(int event)994 void onScanStatus(int event); 995 /** 996 * Called with the current cached scan results when gscan is paused. 997 */ onScanPaused(WifiScanner.ScanData[] data)998 void onScanPaused(WifiScanner.ScanData[] data); 999 /** 1000 * Called with the current cached scan results when gscan is resumed. 1001 */ onScanRestarted()1002 void onScanRestarted(); 1003 } 1004 1005 /** 1006 * Handler to notify the occurrence of various events during PNO scan. 1007 */ 1008 public interface PnoEventHandler { 1009 /** 1010 * Callback to notify when one of the shortlisted networks is found during PNO scan. 1011 * @param results List of Scan results received. 1012 */ onPnoNetworkFound(ScanResult[] results)1013 void onPnoNetworkFound(ScanResult[] results); 1014 1015 /** 1016 * Callback to notify when the PNO scan schedule fails. 1017 */ onPnoScanFailed()1018 void onPnoScanFailed(); 1019 } 1020 1021 public static final int WIFI_SCAN_RESULTS_AVAILABLE = 0; 1022 public static final int WIFI_SCAN_THRESHOLD_NUM_SCANS = 1; 1023 public static final int WIFI_SCAN_THRESHOLD_PERCENT = 2; 1024 public static final int WIFI_SCAN_FAILED = 3; 1025 1026 /** 1027 * Starts a background scan. 1028 * Any ongoing scan will be stopped first 1029 * 1030 * @param settings to control the scan 1031 * @param eventHandler to call with the results 1032 * @return true for success 1033 */ startBgScan(ScanSettings settings, ScanEventHandler eventHandler)1034 public boolean startBgScan(ScanSettings settings, ScanEventHandler eventHandler) { 1035 return mWifiVendorHal.startBgScan(settings, eventHandler); 1036 } 1037 1038 /** 1039 * Stops any ongoing backgound scan 1040 */ stopBgScan()1041 public void stopBgScan() { 1042 mWifiVendorHal.stopBgScan(); 1043 } 1044 1045 /** 1046 * Pauses an ongoing backgound scan 1047 */ pauseBgScan()1048 public void pauseBgScan() { 1049 mWifiVendorHal.pauseBgScan(); 1050 } 1051 1052 /** 1053 * Restarts a paused scan 1054 */ restartBgScan()1055 public void restartBgScan() { 1056 mWifiVendorHal.restartBgScan(); 1057 } 1058 1059 /** 1060 * Gets the latest scan results received. 1061 */ getBgScanResults()1062 public WifiScanner.ScanData[] getBgScanResults() { 1063 return mWifiVendorHal.getBgScanResults(); 1064 } 1065 getWifiLinkLayerStats(String iface)1066 public WifiLinkLayerStats getWifiLinkLayerStats(String iface) { 1067 return mWifiVendorHal.getWifiLinkLayerStats(); 1068 } 1069 1070 /** 1071 * Get the supported features 1072 * 1073 * @return bitmask defined by WifiManager.WIFI_FEATURE_* 1074 */ getSupportedFeatureSet()1075 public int getSupportedFeatureSet() { 1076 return mWifiVendorHal.getSupportedFeatureSet(); 1077 } 1078 1079 public static interface RttEventHandler { onRttResults(RttManager.RttResult[] result)1080 void onRttResults(RttManager.RttResult[] result); 1081 } 1082 1083 /** 1084 * Starts a new rtt request 1085 * 1086 * @param params RTT request params. Refer to {@link RttManager#RttParams}. 1087 * @param handler Callback to be invoked to notify any results. 1088 * @return true if the request was successful, false otherwise. 1089 */ requestRtt( RttManager.RttParams[] params, RttEventHandler handler)1090 public boolean requestRtt( 1091 RttManager.RttParams[] params, RttEventHandler handler) { 1092 return mWifiVendorHal.requestRtt(params, handler); 1093 } 1094 1095 /** 1096 * Cancels an outstanding rtt request 1097 * 1098 * @param params RTT request params. Refer to {@link RttManager#RttParams} 1099 * @return true if there was an outstanding request and it was successfully cancelled 1100 */ cancelRtt(RttManager.RttParams[] params)1101 public boolean cancelRtt(RttManager.RttParams[] params) { 1102 return mWifiVendorHal.cancelRtt(params); 1103 } 1104 1105 /** 1106 * Enable RTT responder role on the device. Returns {@link ResponderConfig} if the responder 1107 * role is successfully enabled, {@code null} otherwise. 1108 * 1109 * @param timeoutSeconds timeout to use for the responder. 1110 */ 1111 @Nullable enableRttResponder(int timeoutSeconds)1112 public ResponderConfig enableRttResponder(int timeoutSeconds) { 1113 return mWifiVendorHal.enableRttResponder(timeoutSeconds); 1114 } 1115 1116 /** 1117 * Disable RTT responder role. Returns {@code true} if responder role is successfully disabled, 1118 * {@code false} otherwise. 1119 */ disableRttResponder()1120 public boolean disableRttResponder() { 1121 return mWifiVendorHal.disableRttResponder(); 1122 } 1123 1124 /** 1125 * Set the MAC OUI during scanning. 1126 * An OUI {Organizationally Unique Identifier} is a 24-bit number that 1127 * uniquely identifies a vendor or manufacturer. 1128 * 1129 * @param oui OUI to set. 1130 * @return true for success 1131 */ setScanningMacOui(byte[] oui)1132 public boolean setScanningMacOui(byte[] oui) { 1133 return mWifiVendorHal.setScanningMacOui(oui); 1134 } 1135 1136 /** 1137 * Query the list of valid frequencies for the provided band. 1138 * The result depends on the on the country code that has been set. 1139 * 1140 * @param band as specified by one of the WifiScanner.WIFI_BAND_* constants. 1141 * @return frequencies vector of valid frequencies (MHz), or null for error. 1142 * @throws IllegalArgumentException if band is not recognized. 1143 */ getChannelsForBand(int band)1144 public int [] getChannelsForBand(int band) { 1145 return mWifiVendorHal.getChannelsForBand(band); 1146 } 1147 1148 /** 1149 * Indicates whether getChannelsForBand is supported. 1150 * 1151 * @return true if it is. 1152 */ isGetChannelsForBandSupported()1153 public boolean isGetChannelsForBandSupported() { 1154 return mWifiVendorHal.isGetChannelsForBandSupported(); 1155 } 1156 1157 /** 1158 * RTT (Round Trip Time) measurement capabilities of the device. 1159 */ getRttCapabilities()1160 public RttManager.RttCapabilities getRttCapabilities() { 1161 return mWifiVendorHal.getRttCapabilities(); 1162 } 1163 1164 /** 1165 * Get the APF (Android Packet Filter) capabilities of the device 1166 */ getApfCapabilities()1167 public ApfCapabilities getApfCapabilities() { 1168 return mWifiVendorHal.getApfCapabilities(); 1169 } 1170 1171 /** 1172 * Installs an APF program on this iface, replacing any existing program. 1173 * 1174 * @param filter is the android packet filter program 1175 * @return true for success 1176 */ installPacketFilter(byte[] filter)1177 public boolean installPacketFilter(byte[] filter) { 1178 return mWifiVendorHal.installPacketFilter(filter); 1179 } 1180 1181 /** 1182 * Set country code for this AP iface. 1183 * 1184 * @param countryCode - two-letter country code (as ISO 3166) 1185 * @return true for success 1186 */ setCountryCodeHal(String countryCode)1187 public boolean setCountryCodeHal(String countryCode) { 1188 return mWifiVendorHal.setCountryCodeHal(countryCode); 1189 } 1190 1191 //--------------------------------------------------------------------------------- 1192 /* Wifi Logger commands/events */ 1193 public static interface WifiLoggerEventHandler { onRingBufferData(RingBufferStatus status, byte[] buffer)1194 void onRingBufferData(RingBufferStatus status, byte[] buffer); onWifiAlert(int errorCode, byte[] buffer)1195 void onWifiAlert(int errorCode, byte[] buffer); 1196 } 1197 1198 /** 1199 * Registers the logger callback and enables alerts. 1200 * Ring buffer data collection is only triggered when |startLoggingRingBuffer| is invoked. 1201 * 1202 * @param handler Callback to be invoked. 1203 * @return true on success, false otherwise. 1204 */ setLoggingEventHandler(WifiLoggerEventHandler handler)1205 public boolean setLoggingEventHandler(WifiLoggerEventHandler handler) { 1206 return mWifiVendorHal.setLoggingEventHandler(handler); 1207 } 1208 1209 /** 1210 * Control debug data collection 1211 * 1212 * @param verboseLevel 0 to 3, inclusive. 0 stops logging. 1213 * @param flags Ignored. 1214 * @param maxInterval Maximum interval between reports; ignore if 0. 1215 * @param minDataSize Minimum data size in buffer for report; ignore if 0. 1216 * @param ringName Name of the ring for which data collection is to start. 1217 * @return true for success, false otherwise. 1218 */ startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval, int minDataSize, String ringName)1219 public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxInterval, 1220 int minDataSize, String ringName){ 1221 return mWifiVendorHal.startLoggingRingBuffer( 1222 verboseLevel, flags, maxInterval, minDataSize, ringName); 1223 } 1224 1225 /** 1226 * Logger features exposed. 1227 * This is a no-op now, will always return -1. 1228 * 1229 * @return true on success, false otherwise. 1230 */ getSupportedLoggerFeatureSet()1231 public int getSupportedLoggerFeatureSet() { 1232 return mWifiVendorHal.getSupportedLoggerFeatureSet(); 1233 } 1234 1235 /** 1236 * Stops all logging and resets the logger callback. 1237 * This stops both the alerts and ring buffer data collection. 1238 * @return true on success, false otherwise. 1239 */ resetLogHandler()1240 public boolean resetLogHandler() { 1241 return mWifiVendorHal.resetLogHandler(); 1242 } 1243 1244 /** 1245 * Vendor-provided wifi driver version string 1246 * 1247 * @return String returned from the HAL. 1248 */ getDriverVersion()1249 public String getDriverVersion() { 1250 return mWifiVendorHal.getDriverVersion(); 1251 } 1252 1253 /** 1254 * Vendor-provided wifi firmware version string 1255 * 1256 * @return String returned from the HAL. 1257 */ getFirmwareVersion()1258 public String getFirmwareVersion() { 1259 return mWifiVendorHal.getFirmwareVersion(); 1260 } 1261 1262 public static class RingBufferStatus{ 1263 String name; 1264 int flag; 1265 int ringBufferId; 1266 int ringBufferByteSize; 1267 int verboseLevel; 1268 int writtenBytes; 1269 int readBytes; 1270 int writtenRecords; 1271 1272 // Bit masks for interpreting |flag| 1273 public static final int HAS_BINARY_ENTRIES = (1 << 0); 1274 public static final int HAS_ASCII_ENTRIES = (1 << 1); 1275 public static final int HAS_PER_PACKET_ENTRIES = (1 << 2); 1276 1277 @Override toString()1278 public String toString() { 1279 return "name: " + name + " flag: " + flag + " ringBufferId: " + ringBufferId + 1280 " ringBufferByteSize: " +ringBufferByteSize + " verboseLevel: " +verboseLevel + 1281 " writtenBytes: " + writtenBytes + " readBytes: " + readBytes + 1282 " writtenRecords: " + writtenRecords; 1283 } 1284 } 1285 1286 /** 1287 * API to get the status of all ring buffers supported by driver 1288 */ getRingBufferStatus()1289 public RingBufferStatus[] getRingBufferStatus() { 1290 return mWifiVendorHal.getRingBufferStatus(); 1291 } 1292 1293 /** 1294 * Indicates to driver that all the data has to be uploaded urgently 1295 * 1296 * @param ringName Name of the ring buffer requested. 1297 * @return true on success, false otherwise. 1298 */ getRingBufferData(String ringName)1299 public boolean getRingBufferData(String ringName) { 1300 return mWifiVendorHal.getRingBufferData(ringName); 1301 } 1302 1303 /** 1304 * Request vendor debug info from the firmware 1305 * 1306 * @return Raw data obtained from the HAL. 1307 */ getFwMemoryDump()1308 public byte[] getFwMemoryDump() { 1309 return mWifiVendorHal.getFwMemoryDump(); 1310 } 1311 1312 /** 1313 * Request vendor debug info from the driver 1314 * 1315 * @return Raw data obtained from the HAL. 1316 */ getDriverStateDump()1317 public byte[] getDriverStateDump() { 1318 return mWifiVendorHal.getDriverStateDump(); 1319 } 1320 1321 //--------------------------------------------------------------------------------- 1322 /* Packet fate API */ 1323 1324 @Immutable 1325 abstract static class FateReport { 1326 final static int USEC_PER_MSEC = 1000; 1327 // The driver timestamp is a 32-bit counter, in microseconds. This field holds the 1328 // maximal value of a driver timestamp in milliseconds. 1329 final static int MAX_DRIVER_TIMESTAMP_MSEC = (int) (0xffffffffL / 1000); 1330 final static SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss.SSS"); 1331 1332 final byte mFate; 1333 final long mDriverTimestampUSec; 1334 final byte mFrameType; 1335 final byte[] mFrameBytes; 1336 final long mEstimatedWallclockMSec; 1337 FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes)1338 FateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) { 1339 mFate = fate; 1340 mDriverTimestampUSec = driverTimestampUSec; 1341 mEstimatedWallclockMSec = 1342 convertDriverTimestampUSecToWallclockMSec(mDriverTimestampUSec); 1343 mFrameType = frameType; 1344 mFrameBytes = frameBytes; 1345 } 1346 toTableRowString()1347 public String toTableRowString() { 1348 StringWriter sw = new StringWriter(); 1349 PrintWriter pw = new PrintWriter(sw); 1350 FrameParser parser = new FrameParser(mFrameType, mFrameBytes); 1351 dateFormatter.setTimeZone(TimeZone.getDefault()); 1352 pw.format("%-15s %12s %-9s %-32s %-12s %-23s %s\n", 1353 mDriverTimestampUSec, 1354 dateFormatter.format(new Date(mEstimatedWallclockMSec)), 1355 directionToString(), fateToString(), parser.mMostSpecificProtocolString, 1356 parser.mTypeString, parser.mResultString); 1357 return sw.toString(); 1358 } 1359 toVerboseStringWithPiiAllowed()1360 public String toVerboseStringWithPiiAllowed() { 1361 StringWriter sw = new StringWriter(); 1362 PrintWriter pw = new PrintWriter(sw); 1363 FrameParser parser = new FrameParser(mFrameType, mFrameBytes); 1364 pw.format("Frame direction: %s\n", directionToString()); 1365 pw.format("Frame timestamp: %d\n", mDriverTimestampUSec); 1366 pw.format("Frame fate: %s\n", fateToString()); 1367 pw.format("Frame type: %s\n", frameTypeToString(mFrameType)); 1368 pw.format("Frame protocol: %s\n", parser.mMostSpecificProtocolString); 1369 pw.format("Frame protocol type: %s\n", parser.mTypeString); 1370 pw.format("Frame length: %d\n", mFrameBytes.length); 1371 pw.append("Frame bytes"); 1372 pw.append(HexDump.dumpHexString(mFrameBytes)); // potentially contains PII 1373 pw.append("\n"); 1374 return sw.toString(); 1375 } 1376 1377 /* Returns a header to match the output of toTableRowString(). */ getTableHeader()1378 public static String getTableHeader() { 1379 StringWriter sw = new StringWriter(); 1380 PrintWriter pw = new PrintWriter(sw); 1381 pw.format("\n%-15s %-12s %-9s %-32s %-12s %-23s %s\n", 1382 "Time usec", "Walltime", "Direction", "Fate", "Protocol", "Type", "Result"); 1383 pw.format("%-15s %-12s %-9s %-32s %-12s %-23s %s\n", 1384 "---------", "--------", "---------", "----", "--------", "----", "------"); 1385 return sw.toString(); 1386 } 1387 directionToString()1388 protected abstract String directionToString(); 1389 fateToString()1390 protected abstract String fateToString(); 1391 frameTypeToString(byte frameType)1392 private static String frameTypeToString(byte frameType) { 1393 switch (frameType) { 1394 case WifiLoggerHal.FRAME_TYPE_UNKNOWN: 1395 return "unknown"; 1396 case WifiLoggerHal.FRAME_TYPE_ETHERNET_II: 1397 return "data"; 1398 case WifiLoggerHal.FRAME_TYPE_80211_MGMT: 1399 return "802.11 management"; 1400 default: 1401 return Byte.toString(frameType); 1402 } 1403 } 1404 1405 /** 1406 * Converts a driver timestamp to a wallclock time, based on the current 1407 * BOOTTIME to wallclock mapping. The driver timestamp is a 32-bit counter of 1408 * microseconds, with the same base as BOOTTIME. 1409 */ convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec)1410 private static long convertDriverTimestampUSecToWallclockMSec(long driverTimestampUSec) { 1411 final long wallclockMillisNow = System.currentTimeMillis(); 1412 final long boottimeMillisNow = SystemClock.elapsedRealtime(); 1413 final long driverTimestampMillis = driverTimestampUSec / USEC_PER_MSEC; 1414 1415 long boottimeTimestampMillis = boottimeMillisNow % MAX_DRIVER_TIMESTAMP_MSEC; 1416 if (boottimeTimestampMillis < driverTimestampMillis) { 1417 // The 32-bit microsecond count has wrapped between the time that the driver 1418 // recorded the packet, and the call to this function. Adjust the BOOTTIME 1419 // timestamp, to compensate. 1420 // 1421 // Note that overflow is not a concern here, since the result is less than 1422 // 2 * MAX_DRIVER_TIMESTAMP_MSEC. (Given the modulus operation above, 1423 // boottimeTimestampMillis must be less than MAX_DRIVER_TIMESTAMP_MSEC.) And, since 1424 // MAX_DRIVER_TIMESTAMP_MSEC is an int, 2 * MAX_DRIVER_TIMESTAMP_MSEC must fit 1425 // within a long. 1426 boottimeTimestampMillis += MAX_DRIVER_TIMESTAMP_MSEC; 1427 } 1428 1429 final long millisSincePacketTimestamp = boottimeTimestampMillis - driverTimestampMillis; 1430 return wallclockMillisNow - millisSincePacketTimestamp; 1431 } 1432 } 1433 1434 /** 1435 * Represents the fate information for one outbound packet. 1436 */ 1437 @Immutable 1438 public static final class TxFateReport extends FateReport { TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes)1439 TxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) { 1440 super(fate, driverTimestampUSec, frameType, frameBytes); 1441 } 1442 1443 @Override directionToString()1444 protected String directionToString() { 1445 return "TX"; 1446 } 1447 1448 @Override fateToString()1449 protected String fateToString() { 1450 switch (mFate) { 1451 case WifiLoggerHal.TX_PKT_FATE_ACKED: 1452 return "acked"; 1453 case WifiLoggerHal.TX_PKT_FATE_SENT: 1454 return "sent"; 1455 case WifiLoggerHal.TX_PKT_FATE_FW_QUEUED: 1456 return "firmware queued"; 1457 case WifiLoggerHal.TX_PKT_FATE_FW_DROP_INVALID: 1458 return "firmware dropped (invalid frame)"; 1459 case WifiLoggerHal.TX_PKT_FATE_FW_DROP_NOBUFS: 1460 return "firmware dropped (no bufs)"; 1461 case WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER: 1462 return "firmware dropped (other)"; 1463 case WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED: 1464 return "driver queued"; 1465 case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_INVALID: 1466 return "driver dropped (invalid frame)"; 1467 case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_NOBUFS: 1468 return "driver dropped (no bufs)"; 1469 case WifiLoggerHal.TX_PKT_FATE_DRV_DROP_OTHER: 1470 return "driver dropped (other)"; 1471 default: 1472 return Byte.toString(mFate); 1473 } 1474 } 1475 } 1476 1477 /** 1478 * Represents the fate information for one inbound packet. 1479 */ 1480 @Immutable 1481 public static final class RxFateReport extends FateReport { RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes)1482 RxFateReport(byte fate, long driverTimestampUSec, byte frameType, byte[] frameBytes) { 1483 super(fate, driverTimestampUSec, frameType, frameBytes); 1484 } 1485 1486 @Override directionToString()1487 protected String directionToString() { 1488 return "RX"; 1489 } 1490 1491 @Override fateToString()1492 protected String fateToString() { 1493 switch (mFate) { 1494 case WifiLoggerHal.RX_PKT_FATE_SUCCESS: 1495 return "success"; 1496 case WifiLoggerHal.RX_PKT_FATE_FW_QUEUED: 1497 return "firmware queued"; 1498 case WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER: 1499 return "firmware dropped (filter)"; 1500 case WifiLoggerHal.RX_PKT_FATE_FW_DROP_INVALID: 1501 return "firmware dropped (invalid frame)"; 1502 case WifiLoggerHal.RX_PKT_FATE_FW_DROP_NOBUFS: 1503 return "firmware dropped (no bufs)"; 1504 case WifiLoggerHal.RX_PKT_FATE_FW_DROP_OTHER: 1505 return "firmware dropped (other)"; 1506 case WifiLoggerHal.RX_PKT_FATE_DRV_QUEUED: 1507 return "driver queued"; 1508 case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_FILTER: 1509 return "driver dropped (filter)"; 1510 case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_INVALID: 1511 return "driver dropped (invalid frame)"; 1512 case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_NOBUFS: 1513 return "driver dropped (no bufs)"; 1514 case WifiLoggerHal.RX_PKT_FATE_DRV_DROP_OTHER: 1515 return "driver dropped (other)"; 1516 default: 1517 return Byte.toString(mFate); 1518 } 1519 } 1520 } 1521 1522 /** 1523 * Ask the HAL to enable packet fate monitoring. Fails unless HAL is started. 1524 * 1525 * @return true for success, false otherwise. 1526 */ startPktFateMonitoring()1527 public boolean startPktFateMonitoring() { 1528 return mWifiVendorHal.startPktFateMonitoring(); 1529 } 1530 1531 /** 1532 * Fetch the most recent TX packet fates from the HAL. Fails unless HAL is started. 1533 * 1534 * @return true for success, false otherwise. 1535 */ getTxPktFates(TxFateReport[] reportBufs)1536 public boolean getTxPktFates(TxFateReport[] reportBufs) { 1537 return mWifiVendorHal.getTxPktFates(reportBufs); 1538 } 1539 1540 /** 1541 * Fetch the most recent RX packet fates from the HAL. Fails unless HAL is started. 1542 */ getRxPktFates(RxFateReport[] reportBufs)1543 public boolean getRxPktFates(RxFateReport[] reportBufs) { 1544 return mWifiVendorHal.getRxPktFates(reportBufs); 1545 } 1546 1547 /** 1548 * Start sending the specified keep alive packets periodically. 1549 * 1550 * @param slot Integer used to identify each request. 1551 * @param keepAlivePacket Raw packet contents to send. 1552 * @param period Period to use for sending these packets. 1553 * @return 0 for success, -1 for error 1554 */ startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket, int period)1555 public int startSendingOffloadedPacket(int slot, KeepalivePacketData keepAlivePacket, 1556 int period) { 1557 String[] macAddrStr = getMacAddress().split(":"); 1558 byte[] srcMac = new byte[6]; 1559 for (int i = 0; i < 6; i++) { 1560 Integer hexVal = Integer.parseInt(macAddrStr[i], 16); 1561 srcMac[i] = hexVal.byteValue(); 1562 } 1563 return mWifiVendorHal.startSendingOffloadedPacket( 1564 slot, srcMac, keepAlivePacket, period); 1565 } 1566 1567 /** 1568 * Stop sending the specified keep alive packets. 1569 * 1570 * @param slot id - same as startSendingOffloadedPacket call. 1571 * @return 0 for success, -1 for error 1572 */ stopSendingOffloadedPacket(int slot)1573 public int stopSendingOffloadedPacket(int slot) { 1574 return mWifiVendorHal.stopSendingOffloadedPacket(slot); 1575 } 1576 1577 public static interface WifiRssiEventHandler { onRssiThresholdBreached(byte curRssi)1578 void onRssiThresholdBreached(byte curRssi); 1579 } 1580 1581 /** 1582 * Start RSSI monitoring on the currently connected access point. 1583 * 1584 * @param maxRssi Maximum RSSI threshold. 1585 * @param minRssi Minimum RSSI threshold. 1586 * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi 1587 * @return 0 for success, -1 for failure 1588 */ startRssiMonitoring(byte maxRssi, byte minRssi, WifiRssiEventHandler rssiEventHandler)1589 public int startRssiMonitoring(byte maxRssi, byte minRssi, 1590 WifiRssiEventHandler rssiEventHandler) { 1591 return mWifiVendorHal.startRssiMonitoring(maxRssi, minRssi, rssiEventHandler); 1592 } 1593 stopRssiMonitoring()1594 public int stopRssiMonitoring() { 1595 return mWifiVendorHal.stopRssiMonitoring(); 1596 } 1597 1598 /** 1599 * Fetch the host wakeup reasons stats from wlan driver. 1600 * 1601 * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver. 1602 */ getWlanWakeReasonCount()1603 public WifiWakeReasonAndCounts getWlanWakeReasonCount() { 1604 return mWifiVendorHal.getWlanWakeReasonCount(); 1605 } 1606 1607 /** 1608 * Enable/Disable Neighbour discovery offload functionality in the firmware. 1609 * 1610 * @param enabled true to enable, false to disable. 1611 * @return true for success, false otherwise. 1612 */ configureNeighborDiscoveryOffload(boolean enabled)1613 public boolean configureNeighborDiscoveryOffload(boolean enabled) { 1614 return mWifiVendorHal.configureNeighborDiscoveryOffload(enabled); 1615 } 1616 1617 // Firmware roaming control. 1618 1619 /** 1620 * Class to retrieve firmware roaming capability parameters. 1621 */ 1622 public static class RoamingCapabilities { 1623 public int maxBlacklistSize; 1624 public int maxWhitelistSize; 1625 } 1626 1627 /** 1628 * Query the firmware roaming capabilities. 1629 * @return true for success, false otherwise. 1630 */ getRoamingCapabilities(RoamingCapabilities capabilities)1631 public boolean getRoamingCapabilities(RoamingCapabilities capabilities) { 1632 return mWifiVendorHal.getRoamingCapabilities(capabilities); 1633 } 1634 1635 /** 1636 * Macros for controlling firmware roaming. 1637 */ 1638 public static final int DISABLE_FIRMWARE_ROAMING = 0; 1639 public static final int ENABLE_FIRMWARE_ROAMING = 1; 1640 1641 /** 1642 * Enable/disable firmware roaming. 1643 * 1644 * @return error code returned from HAL. 1645 */ enableFirmwareRoaming(int state)1646 public int enableFirmwareRoaming(int state) { 1647 return mWifiVendorHal.enableFirmwareRoaming(state); 1648 } 1649 1650 /** 1651 * Class for specifying the roaming configurations. 1652 */ 1653 public static class RoamingConfig { 1654 public ArrayList<String> blacklistBssids; 1655 public ArrayList<String> whitelistSsids; 1656 } 1657 1658 /** 1659 * Set firmware roaming configurations. 1660 */ configureRoaming(RoamingConfig config)1661 public boolean configureRoaming(RoamingConfig config) { 1662 Log.d(mTAG, "configureRoaming "); 1663 return mWifiVendorHal.configureRoaming(config); 1664 } 1665 1666 /** 1667 * Reset firmware roaming configuration. 1668 */ resetRoamingConfiguration()1669 public boolean resetRoamingConfiguration() { 1670 // Pass in an empty RoamingConfig object which translates to zero size 1671 // blacklist and whitelist to reset the firmware roaming configuration. 1672 return mWifiVendorHal.configureRoaming(new RoamingConfig()); 1673 } 1674 1675 /** 1676 * Tx power level scenarios that can be selected. 1677 */ 1678 public static final int TX_POWER_SCENARIO_NORMAL = 0; 1679 public static final int TX_POWER_SCENARIO_VOICE_CALL = 1; 1680 1681 /** 1682 * Select one of the pre-configured TX power level scenarios or reset it back to normal. 1683 * Primarily used for meeting SAR requirements during voice calls. 1684 * 1685 * @param scenario Should be one {@link #TX_POWER_SCENARIO_NORMAL} or 1686 * {@link #TX_POWER_SCENARIO_VOICE_CALL}. 1687 * @return true for success; false for failure or if the HAL version does not support this API. 1688 */ selectTxPowerScenario(int scenario)1689 public boolean selectTxPowerScenario(int scenario) { 1690 return mWifiVendorHal.selectTxPowerScenario(scenario); 1691 } 1692 1693 /******************************************************** 1694 * JNI operations 1695 ********************************************************/ 1696 /* Register native functions */ 1697 static { 1698 /* Native functions are defined in libwifi-service.so */ 1699 System.loadLibrary("wifi-service"); registerNatives()1700 registerNatives(); 1701 } 1702 registerNatives()1703 private static native int registerNatives(); 1704 /* kernel logging support */ readKernelLogNative()1705 private static native byte[] readKernelLogNative(); 1706 1707 /** 1708 * Fetches the latest kernel logs. 1709 */ readKernelLog()1710 public synchronized String readKernelLog() { 1711 byte[] bytes = readKernelLogNative(); 1712 if (bytes != null) { 1713 CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); 1714 try { 1715 CharBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes)); 1716 return decoded.toString(); 1717 } catch (CharacterCodingException cce) { 1718 return new String(bytes, StandardCharsets.ISO_8859_1); 1719 } 1720 } else { 1721 return "*** failed to read kernel log ***"; 1722 } 1723 } 1724 } 1725