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