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