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