WifiConfiguration.java revision 5ddc65b9860b7ef39a0921bcbca3cbc50abe3a2c
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 android.net.wifi; 18 19import android.annotation.SystemApi; 20import android.content.pm.PackageManager; 21import android.net.IpConfiguration; 22import android.net.IpConfiguration.ProxySettings; 23import android.net.ProxyInfo; 24import android.net.StaticIpConfiguration; 25import android.os.Parcel; 26import android.os.Parcelable; 27import android.text.TextUtils; 28import android.util.Log; 29 30import java.util.HashMap; 31import java.util.BitSet; 32import java.util.ArrayList; 33import java.util.Collections; 34import java.util.Comparator; 35import java.util.HashSet; 36 37/** 38 * A class representing a configured Wi-Fi network, including the 39 * security configuration. 40 */ 41public class WifiConfiguration implements Parcelable { 42 private static final String TAG = "WifiConfiguration"; 43 /** {@hide} */ 44 public static final String ssidVarName = "ssid"; 45 /** {@hide} */ 46 public static final String bssidVarName = "bssid"; 47 /** {@hide} */ 48 public static final String pskVarName = "psk"; 49 /** {@hide} */ 50 public static final String[] wepKeyVarNames = { "wep_key0", "wep_key1", "wep_key2", "wep_key3" }; 51 /** {@hide} */ 52 public static final String wepTxKeyIdxVarName = "wep_tx_keyidx"; 53 /** {@hide} */ 54 public static final String priorityVarName = "priority"; 55 /** {@hide} */ 56 public static final String hiddenSSIDVarName = "scan_ssid"; 57 /** {@hide} */ 58 public static final String pmfVarName = "ieee80211w"; 59 /** {@hide} */ 60 public static final String updateIdentiferVarName = "update_identifier"; 61 /** {@hide} */ 62 public static final int INVALID_NETWORK_ID = -1; 63 64 /** 65 * Recognized key management schemes. 66 */ 67 public static class KeyMgmt { 68 private KeyMgmt() { } 69 70 /** WPA is not used; plaintext or static WEP could be used. */ 71 public static final int NONE = 0; 72 /** WPA pre-shared key (requires {@code preSharedKey} to be specified). */ 73 public static final int WPA_PSK = 1; 74 /** WPA using EAP authentication. Generally used with an external authentication server. */ 75 public static final int WPA_EAP = 2; 76 /** IEEE 802.1X using EAP authentication and (optionally) dynamically 77 * generated WEP keys. */ 78 public static final int IEEE8021X = 3; 79 80 /** WPA2 pre-shared key for use with soft access point 81 * (requires {@code preSharedKey} to be specified). 82 * @hide 83 */ 84 public static final int WPA2_PSK = 4; 85 86 public static final String varName = "key_mgmt"; 87 88 public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X", 89 "WPA2_PSK" }; 90 } 91 92 /** 93 * Recognized security protocols. 94 */ 95 public static class Protocol { 96 private Protocol() { } 97 98 /** WPA/IEEE 802.11i/D3.0 */ 99 public static final int WPA = 0; 100 /** WPA2/IEEE 802.11i */ 101 public static final int RSN = 1; 102 103 public static final String varName = "proto"; 104 105 public static final String[] strings = { "WPA", "RSN" }; 106 } 107 108 /** 109 * Recognized IEEE 802.11 authentication algorithms. 110 */ 111 public static class AuthAlgorithm { 112 private AuthAlgorithm() { } 113 114 /** Open System authentication (required for WPA/WPA2) */ 115 public static final int OPEN = 0; 116 /** Shared Key authentication (requires static WEP keys) */ 117 public static final int SHARED = 1; 118 /** LEAP/Network EAP (only used with LEAP) */ 119 public static final int LEAP = 2; 120 121 public static final String varName = "auth_alg"; 122 123 public static final String[] strings = { "OPEN", "SHARED", "LEAP" }; 124 } 125 126 /** 127 * Recognized pairwise ciphers for WPA. 128 */ 129 public static class PairwiseCipher { 130 private PairwiseCipher() { } 131 132 /** Use only Group keys (deprecated) */ 133 public static final int NONE = 0; 134 /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */ 135 public static final int TKIP = 1; 136 /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ 137 public static final int CCMP = 2; 138 139 public static final String varName = "pairwise"; 140 141 public static final String[] strings = { "NONE", "TKIP", "CCMP" }; 142 } 143 144 /** 145 * Recognized group ciphers. 146 * <pre> 147 * CCMP = AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] 148 * TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] 149 * WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key 150 * WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) 151 * </pre> 152 */ 153 public static class GroupCipher { 154 private GroupCipher() { } 155 156 /** WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11) */ 157 public static final int WEP40 = 0; 158 /** WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key */ 159 public static final int WEP104 = 1; 160 /** Temporal Key Integrity Protocol [IEEE 802.11i/D7.0] */ 161 public static final int TKIP = 2; 162 /** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */ 163 public static final int CCMP = 3; 164 165 public static final String varName = "group"; 166 167 public static final String[] strings = { "WEP40", "WEP104", "TKIP", "CCMP" }; 168 } 169 170 /** Possible status of a network configuration. */ 171 public static class Status { 172 private Status() { } 173 174 /** this is the network we are currently connected to */ 175 public static final int CURRENT = 0; 176 /** supplicant will not attempt to use this network */ 177 public static final int DISABLED = 1; 178 /** supplicant will consider this network available for association */ 179 public static final int ENABLED = 2; 180 181 public static final String[] strings = { "current", "disabled", "enabled" }; 182 } 183 184 /** @hide */ 185 public static final int DISABLED_UNKNOWN_REASON = 0; 186 /** @hide */ 187 public static final int DISABLED_DNS_FAILURE = 1; 188 /** @hide */ 189 public static final int DISABLED_DHCP_FAILURE = 2; 190 /** @hide */ 191 public static final int DISABLED_AUTH_FAILURE = 3; 192 /** @hide */ 193 public static final int DISABLED_ASSOCIATION_REJECT = 4; 194 /** @hide */ 195 public static final int DISABLED_BY_WIFI_MANAGER = 5; 196 197 /** @hide */ 198 public static final int UNKNOWN_UID = -1; 199 200 /** 201 * The ID number that the supplicant uses to identify this 202 * network configuration entry. This must be passed as an argument 203 * to most calls into the supplicant. 204 */ 205 public int networkId; 206 207 /** 208 * The current status of this network configuration entry. 209 * @see Status 210 */ 211 public int status; 212 213 /** 214 * The configuration needs to be written to networkHistory.txt 215 * @hide 216 */ 217 public boolean dirty; 218 219 /** 220 * The code referring to a reason for disabling the network 221 * Valid when {@link #status} == Status.DISABLED 222 * @hide 223 */ 224 public int disableReason; 225 226 /** 227 * The network's SSID. Can either be an ASCII string, 228 * which must be enclosed in double quotation marks 229 * (e.g., {@code "MyNetwork"}, or a string of 230 * hex digits,which are not enclosed in quotes 231 * (e.g., {@code 01a243f405}). 232 */ 233 public String SSID; 234 /** 235 * When set, this network configuration entry should only be used when 236 * associating with the AP having the specified BSSID. The value is 237 * a string in the format of an Ethernet MAC address, e.g., 238 * <code>XX:XX:XX:XX:XX:XX</code> where each <code>X</code> is a hex digit. 239 */ 240 public String BSSID; 241 242 /** 243 * The band which AP resides on 244 * 0-2G 1-5G 245 * By default, 2G is chosen 246 * @hide 247 */ 248 public int apBand = 0; 249 250 /** 251 * The channel which AP resides on,currently, US only 252 * 2G 1-11 253 * 5G 36,40,44,48,149,153,157,161,165 254 * 0 - find a random available channel according to the apBand 255 * @hide 256 */ 257 public int apChannel = 0; 258 259 /** 260 * Pre-shared key for use with WPA-PSK. 261 * <p/> 262 * When the value of this key is read, the actual key is 263 * not returned, just a "*" if the key has a value, or the null 264 * string otherwise. 265 */ 266 public String preSharedKey; 267 /** 268 * Up to four WEP keys. Either an ASCII string enclosed in double 269 * quotation marks (e.g., {@code "abcdef"} or a string 270 * of hex digits (e.g., {@code 0102030405}). 271 * <p/> 272 * When the value of one of these keys is read, the actual key is 273 * not returned, just a "*" if the key has a value, or the null 274 * string otherwise. 275 */ 276 public String[] wepKeys; 277 278 /** Default WEP key index, ranging from 0 to 3. */ 279 public int wepTxKeyIndex; 280 281 /** 282 * Priority determines the preference given to a network by {@code wpa_supplicant} 283 * when choosing an access point with which to associate. 284 */ 285 public int priority; 286 287 /** 288 * This is a network that does not broadcast its SSID, so an 289 * SSID-specific probe request must be used for scans. 290 */ 291 public boolean hiddenSSID; 292 293 /** 294 * This is a network that requries Protected Management Frames (PMF). 295 * @hide 296 */ 297 public boolean requirePMF; 298 299 /** 300 * Update identifier, for Passpoint network. 301 * @hide 302 */ 303 public String updateIdentifier; 304 305 /** 306 * The set of key management protocols supported by this configuration. 307 * See {@link KeyMgmt} for descriptions of the values. 308 * Defaults to WPA-PSK WPA-EAP. 309 */ 310 public BitSet allowedKeyManagement; 311 /** 312 * The set of security protocols supported by this configuration. 313 * See {@link Protocol} for descriptions of the values. 314 * Defaults to WPA RSN. 315 */ 316 public BitSet allowedProtocols; 317 /** 318 * The set of authentication protocols supported by this configuration. 319 * See {@link AuthAlgorithm} for descriptions of the values. 320 * Defaults to automatic selection. 321 */ 322 public BitSet allowedAuthAlgorithms; 323 /** 324 * The set of pairwise ciphers for WPA supported by this configuration. 325 * See {@link PairwiseCipher} for descriptions of the values. 326 * Defaults to CCMP TKIP. 327 */ 328 public BitSet allowedPairwiseCiphers; 329 /** 330 * The set of group ciphers supported by this configuration. 331 * See {@link GroupCipher} for descriptions of the values. 332 * Defaults to CCMP TKIP WEP104 WEP40. 333 */ 334 public BitSet allowedGroupCiphers; 335 /** 336 * The enterprise configuration details specifying the EAP method, 337 * certificates and other settings associated with the EAP. 338 */ 339 public WifiEnterpriseConfig enterpriseConfig; 340 341 /** 342 * Fully qualified domain name of a passpoint configuration 343 */ 344 public String FQDN; 345 346 /** 347 * Service provider name, for Passpoint credential. 348 */ 349 public String providerFriendlyName; 350 351 /** 352 * Roaming Consortium Id, for Passpoint credential. 353 */ 354 public HashSet<Long> roamingConsortiumIds; 355 356 /** 357 * @hide 358 */ 359 private IpConfiguration mIpConfiguration; 360 361 /** 362 * @hide 363 * dhcp server MAC address if known 364 */ 365 public String dhcpServer; 366 367 /** 368 * @hide 369 * default Gateway MAC address if known 370 */ 371 public String defaultGwMacAddress; 372 373 /** 374 * @hide 375 * last failure 376 */ 377 public String lastFailure; 378 379 /** 380 * @hide 381 * last time we connected, this configuration had validated internet access 382 */ 383 public boolean validatedInternetAccess; 384 385 /** 386 * @hide 387 * Uid of app creating the configuration 388 */ 389 @SystemApi 390 public int creatorUid; 391 392 /** 393 * @hide 394 * Uid of last app issuing a connection related command 395 */ 396 public int lastConnectUid; 397 398 /** 399 * @hide 400 * Uid of last app modifying the configuration 401 */ 402 @SystemApi 403 public int lastUpdateUid; 404 405 /** 406 * @hide 407 * Universal name for app creating the configuration 408 * see {#link {@link PackageManager#getNameForUid(int)} 409 */ 410 @SystemApi 411 public String creatorName; 412 413 /** 414 * @hide 415 * Universal name for app updating the configuration 416 * see {#link {@link PackageManager#getNameForUid(int)} 417 */ 418 @SystemApi 419 public String lastUpdateName; 420 421 /** 422 * @hide 423 * Uid used by autoJoin 424 */ 425 public String autoJoinBSSID; 426 427 /** 428 * @hide 429 * Status of user approval for connection 430 */ 431 public int userApproved = USER_UNSPECIFIED; 432 433 /** The Below RSSI thresholds are used to configure AutoJoin 434 * - GOOD/LOW/BAD thresholds are used so as to calculate link score 435 * - UNWANTED_SOFT are used by the blacklisting logic so as to handle 436 * the unwanted network message coming from CS 437 * - UNBLACKLIST thresholds are used so as to tweak the speed at which 438 * the network is unblacklisted (i.e. if 439 * it is seen with good RSSI, it is blacklisted faster) 440 * - INITIAL_AUTOJOIN_ATTEMPT, used to determine how close from 441 * the network we need to be before autojoin kicks in 442 */ 443 /** @hide **/ 444 public static int INVALID_RSSI = -127; 445 446 /** @hide **/ 447 public static int UNWANTED_BLACKLIST_SOFT_RSSI_24 = -80; 448 449 /** @hide **/ 450 public static int UNWANTED_BLACKLIST_SOFT_RSSI_5 = -70; 451 452 /** @hide **/ 453 public static int GOOD_RSSI_24 = -65; 454 455 /** @hide **/ 456 public static int LOW_RSSI_24 = -77; 457 458 /** @hide **/ 459 public static int BAD_RSSI_24 = -87; 460 461 /** @hide **/ 462 public static int GOOD_RSSI_5 = -60; 463 464 /** @hide **/ 465 public static int LOW_RSSI_5 = -72; 466 467 /** @hide **/ 468 public static int BAD_RSSI_5 = -82; 469 470 /** @hide **/ 471 public static int UNWANTED_BLACKLIST_SOFT_BUMP = 4; 472 473 /** @hide **/ 474 public static int UNWANTED_BLACKLIST_HARD_BUMP = 8; 475 476 /** @hide **/ 477 public static int UNBLACKLIST_THRESHOLD_24_SOFT = -77; 478 479 /** @hide **/ 480 public static int UNBLACKLIST_THRESHOLD_24_HARD = -68; 481 482 /** @hide **/ 483 public static int UNBLACKLIST_THRESHOLD_5_SOFT = -63; 484 485 /** @hide **/ 486 public static int UNBLACKLIST_THRESHOLD_5_HARD = -56; 487 488 /** @hide **/ 489 public static int INITIAL_AUTO_JOIN_ATTEMPT_MIN_24 = -80; 490 491 /** @hide **/ 492 public static int INITIAL_AUTO_JOIN_ATTEMPT_MIN_5 = -70; 493 494 /** @hide 495 * 5GHz band is prefered low over 2.4 if the 5GHz RSSI is higher than this threshold */ 496 public static int A_BAND_PREFERENCE_RSSI_THRESHOLD = -65; 497 498 /** @hide 499 * 5GHz band is penalized if the 5GHz RSSI is lower than this threshold **/ 500 public static int G_BAND_PREFERENCE_RSSI_THRESHOLD = -75; 501 502 /** @hide 503 * Boost given to RSSI on a home network for the purpose of calculating the score 504 * This adds stickiness to home networks, as defined by: 505 * - less than 4 known BSSIDs 506 * - PSK only 507 * - TODO: add a test to verify that all BSSIDs are behind same gateway 508 ***/ 509 public static int HOME_NETWORK_RSSI_BOOST = 5; 510 511 /** @hide 512 * RSSI boost for configuration which use autoJoinUseAggressiveJoinAttemptThreshold 513 * To be more aggressive when initially attempting to auto join 514 */ 515 public static int MAX_INITIAL_AUTO_JOIN_RSSI_BOOST = 8; 516 517 /** 518 * @hide 519 * A summary of the RSSI and Band status for that configuration 520 * This is used as a temporary value by the auto-join controller 521 */ 522 public static final class Visibility { 523 public int rssi5; // strongest 5GHz RSSI 524 public int rssi24; // strongest 2.4GHz RSSI 525 public int num5; // number of BSSIDs on 5GHz 526 public int num24; // number of BSSIDs on 2.4GHz 527 public long age5; // timestamp of the strongest 5GHz BSSID (last time it was seen) 528 public long age24; // timestamp of the strongest 2.4GHz BSSID (last time it was seen) 529 public String BSSID24; 530 public String BSSID5; 531 public int score; // Debug only, indicate last score used for autojoin/cell-handover 532 public int currentNetworkBoost; // Debug only, indicate boost applied to RSSI if current 533 public int bandPreferenceBoost; // Debug only, indicate boost applied to RSSI if current 534 public int lastChoiceBoost; // Debug only, indicate last choice applied to this configuration 535 public String lastChoiceConfig; // Debug only, indicate last choice applied to this configuration 536 537 public Visibility() { 538 rssi5 = INVALID_RSSI; 539 rssi24 = INVALID_RSSI; 540 } 541 542 public Visibility(Visibility source) { 543 rssi5 = source.rssi5; 544 rssi24 = source.rssi24; 545 age24 = source.age24; 546 age5 = source.age5; 547 num24 = source.num24; 548 num5 = source.num5; 549 BSSID5 = source.BSSID5; 550 BSSID24 = source.BSSID24; 551 } 552 553 @Override 554 public String toString() { 555 StringBuilder sbuf = new StringBuilder(); 556 sbuf.append("["); 557 if (rssi24 > INVALID_RSSI) { 558 sbuf.append(Integer.toString(rssi24)); 559 sbuf.append(","); 560 sbuf.append(Integer.toString(num24)); 561 if (BSSID24 != null) sbuf.append(",").append(BSSID24); 562 } 563 sbuf.append("; "); 564 if (rssi5 > INVALID_RSSI) { 565 sbuf.append(Integer.toString(rssi5)); 566 sbuf.append(","); 567 sbuf.append(Integer.toString(num5)); 568 if (BSSID5 != null) sbuf.append(",").append(BSSID5); 569 } 570 if (score != 0) { 571 sbuf.append("; ").append(score); 572 sbuf.append(", ").append(currentNetworkBoost); 573 sbuf.append(", ").append(bandPreferenceBoost); 574 if (lastChoiceConfig != null) { 575 sbuf.append(", ").append(lastChoiceBoost); 576 sbuf.append(", ").append(lastChoiceConfig); 577 } 578 } 579 sbuf.append("]"); 580 return sbuf.toString(); 581 } 582 } 583 584 /** @hide 585 * Cache the visibility status of this configuration. 586 * Visibility can change at any time depending on scan results availability. 587 * Owner of the WifiConfiguration is responsible to set this field based on 588 * recent scan results. 589 ***/ 590 public Visibility visibility; 591 592 /** @hide 593 * calculate and set Visibility for that configuration. 594 * 595 * age in milliseconds: we will consider only ScanResults that are more recent, 596 * i.e. younger. 597 ***/ 598 public void setVisibility(Visibility status) { 599 visibility = status; 600 } 601 602 /** @hide */ 603 public static final int AUTO_JOIN_ENABLED = 0; 604 /** 605 * if this is set, the WifiConfiguration cannot use linkages so as to bump 606 * it's relative priority. 607 * - status between and 128 indicate various level of blacklisting depending 608 * on the severity or frequency of the connection error 609 * - deleted status indicates that the user is deleting the configuration, and so 610 * although it may have been self added we will not re-self-add it, ignore it, 611 * not return it to applications, and not connect to it 612 * */ 613 614 /** @hide 615 * network was temporary disabled due to bad connection, most likely due 616 * to weak RSSI */ 617 public static final int AUTO_JOIN_TEMPORARY_DISABLED = 1; 618 /** @hide 619 * network was temporary disabled due to bad connection, which cant be attributed 620 * to weak RSSI */ 621 public static final int AUTO_JOIN_TEMPORARY_DISABLED_LINK_ERRORS = 32; 622 /** @hide */ 623 public static final int AUTO_JOIN_TEMPORARY_DISABLED_AT_SUPPLICANT = 64; 624 /** @hide */ 625 public static final int AUTO_JOIN_DISABLED_ON_AUTH_FAILURE = 128; 626 /** @hide */ 627 public static final int AUTO_JOIN_DISABLED_NO_CREDENTIALS = 160; 628 /** @hide */ 629 public static final int AUTO_JOIN_DISABLED_USER_ACTION = 161; 630 631 /** @hide */ 632 public static final int AUTO_JOIN_DELETED = 200; 633 634 // States for the userApproved field 635 /** 636 * @hide 637 * User hasn't specified if connection is okay 638 */ 639 public static final int USER_UNSPECIFIED = 0; 640 /** 641 * @hide 642 * User has approved this for connection 643 */ 644 public static final int USER_APPROVED = 1; 645 /** 646 * @hide 647 * User has banned this from connection 648 */ 649 public static final int USER_BANNED = 2; 650 /** 651 * @hide 652 * Waiting for user input 653 */ 654 public static final int USER_PENDING = 3; 655 656 /** 657 * @hide 658 */ 659 public int autoJoinStatus; 660 661 /** 662 * @hide 663 * Number of connection failures 664 */ 665 public int numConnectionFailures; 666 667 /** 668 * @hide 669 * Number of IP config failures 670 */ 671 public int numIpConfigFailures; 672 673 /** 674 * @hide 675 * Number of Auth failures 676 */ 677 public int numAuthFailures; 678 679 /** 680 * @hide 681 * Number of reports indicating no Internet Access 682 */ 683 public int numNoInternetAccessReports; 684 685 /** 686 * @hide 687 * The WiFi configuration is considered to have no internet access for purpose of autojoining 688 * if there has been a report of it having no internet access, and, it never have had 689 * internet access in the past. 690 */ 691 public boolean hasNoInternetAccess() { 692 return numNoInternetAccessReports > 0 && !validatedInternetAccess; 693 } 694 695 /** 696 * The WiFi configuration is expected not to have Internet access (e.g., a wireless printer, a 697 * Chromecast hotspot, etc.). This will be set if the user explicitly confirms a connection to 698 * this configuration and selects "don't ask again". 699 * @hide 700 */ 701 public boolean noInternetAccessExpected; 702 703 /** 704 * @hide 705 * Last time we blacklisted the configuration 706 */ 707 public long blackListTimestamp; 708 709 /** 710 * @hide 711 * Last time the system was connected to this configuration. 712 */ 713 public long lastConnected; 714 715 /** 716 * @hide 717 * Last time the system tried to connect and failed. 718 */ 719 public long lastConnectionFailure; 720 721 /** 722 * @hide 723 * Last time the system tried to roam and failed because of authentication failure or DHCP 724 * RENEW failure. 725 */ 726 public long lastRoamingFailure; 727 728 /** @hide */ 729 public static int ROAMING_FAILURE_IP_CONFIG = 1; 730 /** @hide */ 731 public static int ROAMING_FAILURE_AUTH_FAILURE = 2; 732 733 /** 734 * @hide 735 * Initial amount of time this Wifi configuration gets blacklisted for network switching 736 * because of roaming failure 737 */ 738 public long roamingFailureBlackListTimeMilli = 1000; 739 740 /** 741 * @hide 742 * Last roaming failure reason code 743 */ 744 public int lastRoamingFailureReason; 745 746 /** 747 * @hide 748 * Last time the system was disconnected to this configuration. 749 */ 750 public long lastDisconnected; 751 752 /** 753 * Set if the configuration was self added by the framework 754 * This boolean is cleared if we get a connect/save/ update or 755 * any wifiManager command that indicate the user interacted with the configuration 756 * since we will now consider that the configuration belong to him. 757 * @hide 758 */ 759 public boolean selfAdded; 760 761 /** 762 * Set if the configuration was self added by the framework 763 * This boolean is set once and never cleared. It is used 764 * so as we never loose track of who created the 765 * configuration in the first place. 766 * @hide 767 */ 768 public boolean didSelfAdd; 769 770 /** 771 * Peer WifiConfiguration this WifiConfiguration was added for 772 * @hide 773 */ 774 public String peerWifiConfiguration; 775 776 /** 777 * @hide 778 * Indicate that a WifiConfiguration is temporary and should not be saved 779 * nor considered by AutoJoin. 780 */ 781 public boolean ephemeral; 782 783 /** 784 * @hide 785 * Indicate that we didn't auto-join because rssi was too low 786 */ 787 public boolean autoJoinBailedDueToLowRssi; 788 789 /** 790 * @hide 791 * AutoJoin even though RSSI is 10dB below threshold 792 */ 793 public int autoJoinUseAggressiveJoinAttemptThreshold; 794 795 /** 796 * @hide 797 * Number of time the scorer overrode a the priority based choice, when comparing two 798 * WifiConfigurations, note that since comparing WifiConfiguration happens very often 799 * potentially at every scan, this number might become very large, even on an idle 800 * system. 801 */ 802 @SystemApi 803 public int numScorerOverride; 804 805 /** 806 * @hide 807 * Number of time the scorer overrode a the priority based choice, and the comparison 808 * triggered a network switch 809 */ 810 @SystemApi 811 public int numScorerOverrideAndSwitchedNetwork; 812 813 /** 814 * @hide 815 * Number of time we associated to this configuration. 816 */ 817 @SystemApi 818 public int numAssociation; 819 820 /** 821 * @hide 822 * Number of time user disabled WiFi while associated to this configuration with Low RSSI. 823 */ 824 public int numUserTriggeredWifiDisableLowRSSI; 825 826 /** 827 * @hide 828 * Number of time user disabled WiFi while associated to this configuration with Bad RSSI. 829 */ 830 public int numUserTriggeredWifiDisableBadRSSI; 831 832 /** 833 * @hide 834 * Number of time user disabled WiFi while associated to this configuration 835 * and RSSI was not HIGH. 836 */ 837 public int numUserTriggeredWifiDisableNotHighRSSI; 838 839 /** 840 * @hide 841 * Number of ticks associated to this configuration with Low RSSI. 842 */ 843 public int numTicksAtLowRSSI; 844 845 /** 846 * @hide 847 * Number of ticks associated to this configuration with Bad RSSI. 848 */ 849 public int numTicksAtBadRSSI; 850 851 /** 852 * @hide 853 * Number of ticks associated to this configuration 854 * and RSSI was not HIGH. 855 */ 856 public int numTicksAtNotHighRSSI; 857 /** 858 * @hide 859 * Number of time user (WifiManager) triggered association to this configuration. 860 * TODO: count this only for Wifi Settings uuid, so as to not count 3rd party apps 861 */ 862 public int numUserTriggeredJoinAttempts; 863 864 /** 865 * @hide 866 * Connect choices 867 * 868 * remember the keys identifying the known WifiConfiguration over which this configuration 869 * was preferred by user or a "WiFi Network Management app", that is, 870 * a WifiManager.CONNECT_NETWORK or SELECT_NETWORK was received while this configuration 871 * was visible to the user: 872 * configKey is : "SSID"-WEP-WPA_PSK-WPA_EAP 873 * 874 * The integer represents the configuration's RSSI at that time (useful?) 875 * 876 * The overall auto-join algorithm make use of past connect choice so as to sort configuration, 877 * the exact algorithm still fluctuating as of 5/7/2014 878 * 879 */ 880 public HashMap<String, Integer> connectChoices; 881 882 /** 883 * @hide 884 * Linked Configurations: represent the set of Wificonfigurations that are equivalent 885 * regarding roaming and auto-joining. 886 * The linked configuration may or may not have same SSID, and may or may not have same 887 * credentials. 888 * For instance, linked configurations will have same defaultGwMacAddress or same dhcp server. 889 */ 890 public HashMap<String, Integer> linkedConfigurations; 891 892 public WifiConfiguration() { 893 networkId = INVALID_NETWORK_ID; 894 SSID = null; 895 BSSID = null; 896 FQDN = null; 897 roamingConsortiumIds = new HashSet<Long>(); 898 priority = 0; 899 hiddenSSID = false; 900 disableReason = DISABLED_UNKNOWN_REASON; 901 allowedKeyManagement = new BitSet(); 902 allowedProtocols = new BitSet(); 903 allowedAuthAlgorithms = new BitSet(); 904 allowedPairwiseCiphers = new BitSet(); 905 allowedGroupCiphers = new BitSet(); 906 wepKeys = new String[4]; 907 for (int i = 0; i < wepKeys.length; i++) { 908 wepKeys[i] = null; 909 } 910 enterpriseConfig = new WifiEnterpriseConfig(); 911 autoJoinStatus = AUTO_JOIN_ENABLED; 912 selfAdded = false; 913 didSelfAdd = false; 914 ephemeral = false; 915 validatedInternetAccess = false; 916 mIpConfiguration = new IpConfiguration(); 917 lastUpdateUid = -1; 918 creatorUid = -1; 919 } 920 921 /** 922 * indicates whether the configuration is valid 923 * @return true if valid, false otherwise 924 * @hide 925 */ 926 public boolean isValid() { 927 String reason = strIsValid(); 928 if (reason != null) { 929 Log.e(TAG, "WiFi Config not valid: " + reason); 930 return false; 931 } 932 else { 933 return true; 934 } 935 } 936 937 private String strIsValid() { 938 939 if (allowedKeyManagement == null) 940 return "allowed kmgmt"; 941 942 if (allowedKeyManagement.cardinality() > 1) { 943 if (allowedKeyManagement.cardinality() != 2) { 944 return "cardinality != 2"; 945 } 946 if (!allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 947 return "not WPA_EAP"; 948 } 949 if ((!allowedKeyManagement.get(KeyMgmt.IEEE8021X)) 950 && (!allowedKeyManagement.get(KeyMgmt.WPA_PSK))) { 951 return "not PSK or 8021X"; 952 } 953 } 954 955 if (!TextUtils.isEmpty(FQDN)) { 956 /* this is passpoint configuration; it must not have an SSID */ 957 if (!TextUtils.isEmpty(SSID)) { 958 return "SSID not expected for Passpoint: '" + SSID + "'"; 959 } 960 /* this is passpoint configuration; it must have a providerFriendlyName */ 961 if (TextUtils.isEmpty(providerFriendlyName)) { 962 return "no provider friendly name"; 963 } 964 /* this is passpoint configuration; it must have enterprise config */ 965 if (enterpriseConfig == null 966 || enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.NONE ) { 967 return "no enterprise config"; 968 } 969 } 970 971 // TODO: Add more checks 972 return null; 973 } 974 975 /** 976 * Identify if this configuration represents a passpoint network 977 */ 978 public boolean isPasspoint() { 979 return !TextUtils.isEmpty(FQDN) 980 && !TextUtils.isEmpty(providerFriendlyName) 981 && enterpriseConfig != null 982 && enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE; 983 } 984 985 /** 986 * Helper function, identify if a configuration is linked 987 * @hide 988 */ 989 public boolean isLinked(WifiConfiguration config) { 990 if (config.linkedConfigurations != null && linkedConfigurations != null) { 991 if (config.linkedConfigurations.get(configKey()) != null 992 && linkedConfigurations.get(config.configKey()) != null) { 993 return true; 994 } 995 } 996 return false; 997 } 998 999 /** 1000 * Helper function, idenfity if a configuration should be treated as an enterprise network 1001 * @hide 1002 */ 1003 public boolean isEnterprise() { 1004 return allowedKeyManagement.get(KeyMgmt.WPA_EAP) || 1005 allowedKeyManagement.get(KeyMgmt.IEEE8021X); 1006 } 1007 1008 /** @hide **/ 1009 public void setAutoJoinStatus(int status) { 1010 if (status < 0) status = 0; 1011 if (status == 0) { 1012 blackListTimestamp = 0; 1013 } else if (status > autoJoinStatus) { 1014 blackListTimestamp = System.currentTimeMillis(); 1015 } 1016 if (status != autoJoinStatus) { 1017 autoJoinStatus = status; 1018 dirty = true; 1019 } 1020 } 1021 1022 @Override 1023 public String toString() { 1024 StringBuilder sbuf = new StringBuilder(); 1025 if (this.status == WifiConfiguration.Status.CURRENT) { 1026 sbuf.append("* "); 1027 } else if (this.status == WifiConfiguration.Status.DISABLED) { 1028 sbuf.append("- DSBLE "); 1029 } 1030 sbuf.append("ID: ").append(this.networkId).append(" SSID: ").append(this.SSID). 1031 append(" PROVIDER-NAME: ").append(this.providerFriendlyName). 1032 append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN). 1033 append(" PRIO: ").append(this.priority). 1034 append('\n'); 1035 if (this.numConnectionFailures > 0) { 1036 sbuf.append(" numConnectFailures ").append(this.numConnectionFailures).append("\n"); 1037 } 1038 if (this.numIpConfigFailures > 0) { 1039 sbuf.append(" numIpConfigFailures ").append(this.numIpConfigFailures).append("\n"); 1040 } 1041 if (this.numAuthFailures > 0) { 1042 sbuf.append(" numAuthFailures ").append(this.numAuthFailures).append("\n"); 1043 } 1044 if (this.autoJoinStatus > 0) { 1045 sbuf.append(" autoJoinStatus ").append(this.autoJoinStatus).append("\n"); 1046 } 1047 if (this.disableReason > 0) { 1048 sbuf.append(" disableReason ").append(this.disableReason).append("\n"); 1049 } 1050 if (this.numAssociation > 0) { 1051 sbuf.append(" numAssociation ").append(this.numAssociation).append("\n"); 1052 } 1053 if (this.numNoInternetAccessReports > 0) { 1054 sbuf.append(" numNoInternetAccessReports "); 1055 sbuf.append(this.numNoInternetAccessReports).append("\n"); 1056 } 1057 if (this.didSelfAdd) sbuf.append(" didSelfAdd"); 1058 if (this.selfAdded) sbuf.append(" selfAdded"); 1059 if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess"); 1060 if (this.ephemeral) sbuf.append(" ephemeral"); 1061 if (this.didSelfAdd || this.selfAdded || this.validatedInternetAccess || this.ephemeral) { 1062 sbuf.append("\n"); 1063 } 1064 sbuf.append(" KeyMgmt:"); 1065 for (int k = 0; k < this.allowedKeyManagement.size(); k++) { 1066 if (this.allowedKeyManagement.get(k)) { 1067 sbuf.append(" "); 1068 if (k < KeyMgmt.strings.length) { 1069 sbuf.append(KeyMgmt.strings[k]); 1070 } else { 1071 sbuf.append("??"); 1072 } 1073 } 1074 } 1075 sbuf.append(" Protocols:"); 1076 for (int p = 0; p < this.allowedProtocols.size(); p++) { 1077 if (this.allowedProtocols.get(p)) { 1078 sbuf.append(" "); 1079 if (p < Protocol.strings.length) { 1080 sbuf.append(Protocol.strings[p]); 1081 } else { 1082 sbuf.append("??"); 1083 } 1084 } 1085 } 1086 sbuf.append('\n'); 1087 sbuf.append(" AuthAlgorithms:"); 1088 for (int a = 0; a < this.allowedAuthAlgorithms.size(); a++) { 1089 if (this.allowedAuthAlgorithms.get(a)) { 1090 sbuf.append(" "); 1091 if (a < AuthAlgorithm.strings.length) { 1092 sbuf.append(AuthAlgorithm.strings[a]); 1093 } else { 1094 sbuf.append("??"); 1095 } 1096 } 1097 } 1098 sbuf.append('\n'); 1099 sbuf.append(" PairwiseCiphers:"); 1100 for (int pc = 0; pc < this.allowedPairwiseCiphers.size(); pc++) { 1101 if (this.allowedPairwiseCiphers.get(pc)) { 1102 sbuf.append(" "); 1103 if (pc < PairwiseCipher.strings.length) { 1104 sbuf.append(PairwiseCipher.strings[pc]); 1105 } else { 1106 sbuf.append("??"); 1107 } 1108 } 1109 } 1110 sbuf.append('\n'); 1111 sbuf.append(" GroupCiphers:"); 1112 for (int gc = 0; gc < this.allowedGroupCiphers.size(); gc++) { 1113 if (this.allowedGroupCiphers.get(gc)) { 1114 sbuf.append(" "); 1115 if (gc < GroupCipher.strings.length) { 1116 sbuf.append(GroupCipher.strings[gc]); 1117 } else { 1118 sbuf.append("??"); 1119 } 1120 } 1121 } 1122 sbuf.append('\n').append(" PSK: "); 1123 if (this.preSharedKey != null) { 1124 sbuf.append('*'); 1125 } 1126 sbuf.append("\nEnterprise config:\n"); 1127 sbuf.append(enterpriseConfig); 1128 1129 sbuf.append("IP config:\n"); 1130 sbuf.append(mIpConfiguration.toString()); 1131 1132 if (this.autoJoinBSSID != null) sbuf.append(" autoJoinBSSID=" + autoJoinBSSID); 1133 long now_ms = System.currentTimeMillis(); 1134 if (this.blackListTimestamp != 0) { 1135 sbuf.append('\n'); 1136 long diff = now_ms - this.blackListTimestamp; 1137 if (diff <= 0) { 1138 sbuf.append(" blackListed since <incorrect>"); 1139 } else { 1140 sbuf.append(" blackListed: ").append(Long.toString(diff/1000)).append( "sec "); 1141 } 1142 } 1143 if (creatorUid != 0) sbuf.append(" cuid=" + Integer.toString(creatorUid)); 1144 if (creatorName != null) sbuf.append(" cname=" + creatorName); 1145 if (lastUpdateUid != 0) sbuf.append(" luid=" + lastUpdateUid); 1146 if (lastUpdateName != null) sbuf.append(" lname=" + lastUpdateName); 1147 sbuf.append(" lcuid=" + lastConnectUid); 1148 sbuf.append(" userApproved=" + userApprovedAsString(userApproved)); 1149 sbuf.append(" noInternetAccessExpected=" + noInternetAccessExpected); 1150 sbuf.append(" "); 1151 1152 if (this.lastConnected != 0) { 1153 sbuf.append('\n'); 1154 long diff = now_ms - this.lastConnected; 1155 if (diff <= 0) { 1156 sbuf.append("lastConnected since <incorrect>"); 1157 } else { 1158 sbuf.append("lastConnected: ").append(Long.toString(diff/1000)).append( "sec "); 1159 } 1160 } 1161 if (this.lastConnectionFailure != 0) { 1162 sbuf.append('\n'); 1163 long diff = now_ms - this.lastConnectionFailure; 1164 if (diff <= 0) { 1165 sbuf.append("lastConnectionFailure since <incorrect> "); 1166 } else { 1167 sbuf.append("lastConnectionFailure: ").append(Long.toString(diff/1000)); 1168 sbuf.append( "sec "); 1169 } 1170 } 1171 if (this.lastRoamingFailure != 0) { 1172 sbuf.append('\n'); 1173 long diff = now_ms - this.lastRoamingFailure; 1174 if (diff <= 0) { 1175 sbuf.append("lastRoamingFailure since <incorrect> "); 1176 } else { 1177 sbuf.append("lastRoamingFailure: ").append(Long.toString(diff/1000)); 1178 sbuf.append( "sec "); 1179 } 1180 } 1181 sbuf.append("roamingFailureBlackListTimeMilli: "). 1182 append(Long.toString(this.roamingFailureBlackListTimeMilli)); 1183 sbuf.append('\n'); 1184 if (this.linkedConfigurations != null) { 1185 for(String key : this.linkedConfigurations.keySet()) { 1186 sbuf.append(" linked: ").append(key); 1187 sbuf.append('\n'); 1188 } 1189 } 1190 if (this.connectChoices != null) { 1191 for(String key : this.connectChoices.keySet()) { 1192 Integer choice = this.connectChoices.get(key); 1193 if (choice != null) { 1194 sbuf.append(" choice: ").append(key); 1195 sbuf.append(" = ").append(choice); 1196 sbuf.append('\n'); 1197 } 1198 } 1199 } 1200 sbuf.append("triggeredLow: ").append(this.numUserTriggeredWifiDisableLowRSSI); 1201 sbuf.append(" triggeredBad: ").append(this.numUserTriggeredWifiDisableBadRSSI); 1202 sbuf.append(" triggeredNotHigh: ").append(this.numUserTriggeredWifiDisableNotHighRSSI); 1203 sbuf.append('\n'); 1204 sbuf.append("ticksLow: ").append(this.numTicksAtLowRSSI); 1205 sbuf.append(" ticksBad: ").append(this.numTicksAtBadRSSI); 1206 sbuf.append(" ticksNotHigh: ").append(this.numTicksAtNotHighRSSI); 1207 sbuf.append('\n'); 1208 sbuf.append("triggeredJoin: ").append(this.numUserTriggeredJoinAttempts); 1209 sbuf.append('\n'); 1210 sbuf.append("autoJoinBailedDueToLowRssi: ").append(this.autoJoinBailedDueToLowRssi); 1211 sbuf.append('\n'); 1212 sbuf.append("autoJoinUseAggressiveJoinAttemptThreshold: "); 1213 sbuf.append(this.autoJoinUseAggressiveJoinAttemptThreshold); 1214 sbuf.append('\n'); 1215 1216 return sbuf.toString(); 1217 } 1218 1219 /** 1220 * Construct a WifiConfiguration from a scanned network 1221 * @param scannedAP the scan result used to construct the config entry 1222 * TODO: figure out whether this is a useful way to construct a new entry. 1223 * 1224 public WifiConfiguration(ScanResult scannedAP) { 1225 networkId = -1; 1226 SSID = scannedAP.SSID; 1227 BSSID = scannedAP.BSSID; 1228 } 1229 */ 1230 1231 /** {@hide} */ 1232 public String getPrintableSsid() { 1233 if (SSID == null) return ""; 1234 final int length = SSID.length(); 1235 if (length > 2 && (SSID.charAt(0) == '"') && SSID.charAt(length - 1) == '"') { 1236 return SSID.substring(1, length - 1); 1237 } 1238 1239 /** The ascii-encoded string format is P"<ascii-encoded-string>" 1240 * The decoding is implemented in the supplicant for a newly configured 1241 * network. 1242 */ 1243 if (length > 3 && (SSID.charAt(0) == 'P') && (SSID.charAt(1) == '"') && 1244 (SSID.charAt(length-1) == '"')) { 1245 WifiSsid wifiSsid = WifiSsid.createFromAsciiEncoded( 1246 SSID.substring(2, length - 1)); 1247 return wifiSsid.toString(); 1248 } 1249 return SSID; 1250 } 1251 1252 /** @hide **/ 1253 public static String userApprovedAsString(int userApproved) { 1254 switch (userApproved) { 1255 case USER_APPROVED: 1256 return "USER_APPROVED"; 1257 case USER_BANNED: 1258 return "USER_BANNED"; 1259 case USER_UNSPECIFIED: 1260 return "USER_UNSPECIFIED"; 1261 default: 1262 return "INVALID"; 1263 } 1264 } 1265 1266 /** 1267 * Get an identifier for associating credentials with this config 1268 * @param current configuration contains values for additional fields 1269 * that are not part of this configuration. Used 1270 * when a config with some fields is passed by an application. 1271 * @throws IllegalStateException if config is invalid for key id generation 1272 * @hide 1273 */ 1274 public String getKeyIdForCredentials(WifiConfiguration current) { 1275 String keyMgmt = null; 1276 1277 try { 1278 // Get current config details for fields that are not initialized 1279 if (TextUtils.isEmpty(SSID)) SSID = current.SSID; 1280 if (allowedKeyManagement.cardinality() == 0) { 1281 allowedKeyManagement = current.allowedKeyManagement; 1282 } 1283 if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 1284 keyMgmt = KeyMgmt.strings[KeyMgmt.WPA_EAP]; 1285 } 1286 if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 1287 keyMgmt += KeyMgmt.strings[KeyMgmt.IEEE8021X]; 1288 } 1289 1290 if (TextUtils.isEmpty(keyMgmt)) { 1291 throw new IllegalStateException("Not an EAP network"); 1292 } 1293 1294 return trimStringForKeyId(SSID) + "_" + keyMgmt + "_" + 1295 trimStringForKeyId(enterpriseConfig.getKeyId(current != null ? 1296 current.enterpriseConfig : null)); 1297 } catch (NullPointerException e) { 1298 throw new IllegalStateException("Invalid config details"); 1299 } 1300 } 1301 1302 private String trimStringForKeyId(String string) { 1303 // Remove quotes and spaces 1304 return string.replace("\"", "").replace(" ", ""); 1305 } 1306 1307 private static BitSet readBitSet(Parcel src) { 1308 int cardinality = src.readInt(); 1309 1310 BitSet set = new BitSet(); 1311 for (int i = 0; i < cardinality; i++) { 1312 set.set(src.readInt()); 1313 } 1314 1315 return set; 1316 } 1317 1318 private static void writeBitSet(Parcel dest, BitSet set) { 1319 int nextSetBit = -1; 1320 1321 dest.writeInt(set.cardinality()); 1322 1323 while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) { 1324 dest.writeInt(nextSetBit); 1325 } 1326 } 1327 1328 /** @hide */ 1329 public int getAuthType() { 1330 if (isValid() == false) { 1331 throw new IllegalStateException("Invalid configuration"); 1332 } 1333 if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 1334 return KeyMgmt.WPA_PSK; 1335 } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) { 1336 return KeyMgmt.WPA2_PSK; 1337 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) { 1338 return KeyMgmt.WPA_EAP; 1339 } else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 1340 return KeyMgmt.IEEE8021X; 1341 } 1342 return KeyMgmt.NONE; 1343 } 1344 1345 /* @hide 1346 * Cache the config key, this seems useful as a speed up since a lot of 1347 * lookups in the config store are done and based on this key. 1348 */ 1349 String mCachedConfigKey; 1350 1351 /** @hide 1352 * return the string used to calculate the hash in WifiConfigStore 1353 * and uniquely identify this WifiConfiguration 1354 */ 1355 public String configKey(boolean allowCached) { 1356 String key; 1357 if (allowCached && mCachedConfigKey != null) { 1358 key = mCachedConfigKey; 1359 } else if (providerFriendlyName != null) { 1360 key = FQDN + KeyMgmt.strings[KeyMgmt.WPA_EAP]; 1361 } else { 1362 if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) { 1363 key = SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK]; 1364 } else if (allowedKeyManagement.get(KeyMgmt.WPA_EAP) || 1365 allowedKeyManagement.get(KeyMgmt.IEEE8021X)) { 1366 key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP]; 1367 } else if (wepKeys[0] != null) { 1368 key = SSID + "WEP"; 1369 } else { 1370 key = SSID + KeyMgmt.strings[KeyMgmt.NONE]; 1371 } 1372 mCachedConfigKey = key; 1373 } 1374 return key; 1375 } 1376 1377 /** @hide 1378 * get configKey, force calculating the config string 1379 */ 1380 public String configKey() { 1381 return configKey(false); 1382 } 1383 1384 /** @hide 1385 * return the config key string based on a scan result 1386 */ 1387 static public String configKey(ScanResult result) { 1388 String key = "\"" + result.SSID + "\""; 1389 1390 if (result.capabilities.contains("WEP")) { 1391 key = key + "-WEP"; 1392 } 1393 1394 if (result.capabilities.contains("PSK")) { 1395 key = key + "-" + KeyMgmt.strings[KeyMgmt.WPA_PSK]; 1396 } 1397 1398 if (result.capabilities.contains("EAP")) { 1399 key = key + "-" + KeyMgmt.strings[KeyMgmt.WPA_EAP]; 1400 } 1401 1402 return key; 1403 } 1404 1405 /** @hide */ 1406 public IpConfiguration getIpConfiguration() { 1407 return mIpConfiguration; 1408 } 1409 1410 /** @hide */ 1411 public void setIpConfiguration(IpConfiguration ipConfiguration) { 1412 mIpConfiguration = ipConfiguration; 1413 } 1414 1415 /** @hide */ 1416 public StaticIpConfiguration getStaticIpConfiguration() { 1417 return mIpConfiguration.getStaticIpConfiguration(); 1418 } 1419 1420 /** @hide */ 1421 public void setStaticIpConfiguration(StaticIpConfiguration staticIpConfiguration) { 1422 mIpConfiguration.setStaticIpConfiguration(staticIpConfiguration); 1423 } 1424 1425 /** @hide */ 1426 public IpConfiguration.IpAssignment getIpAssignment() { 1427 return mIpConfiguration.ipAssignment; 1428 } 1429 1430 /** @hide */ 1431 public void setIpAssignment(IpConfiguration.IpAssignment ipAssignment) { 1432 mIpConfiguration.ipAssignment = ipAssignment; 1433 } 1434 1435 /** @hide */ 1436 public IpConfiguration.ProxySettings getProxySettings() { 1437 return mIpConfiguration.proxySettings; 1438 } 1439 1440 /** @hide */ 1441 public void setProxySettings(IpConfiguration.ProxySettings proxySettings) { 1442 mIpConfiguration.proxySettings = proxySettings; 1443 } 1444 1445 /** @hide */ 1446 public ProxyInfo getHttpProxy() { 1447 return mIpConfiguration.httpProxy; 1448 } 1449 1450 /** @hide */ 1451 public void setHttpProxy(ProxyInfo httpProxy) { 1452 mIpConfiguration.httpProxy = httpProxy; 1453 } 1454 1455 /** @hide */ 1456 public void setProxy(ProxySettings settings, ProxyInfo proxy) { 1457 mIpConfiguration.proxySettings = settings; 1458 mIpConfiguration.httpProxy = proxy; 1459 } 1460 1461 /** Implement the Parcelable interface {@hide} */ 1462 public int describeContents() { 1463 return 0; 1464 } 1465 1466 /** copy constructor {@hide} */ 1467 public WifiConfiguration(WifiConfiguration source) { 1468 if (source != null) { 1469 networkId = source.networkId; 1470 status = source.status; 1471 disableReason = source.disableReason; 1472 disableReason = source.disableReason; 1473 SSID = source.SSID; 1474 BSSID = source.BSSID; 1475 FQDN = source.FQDN; 1476 roamingConsortiumIds = new HashSet<Long>(); 1477 for (Long roamingConsortiumId : source.roamingConsortiumIds) { 1478 roamingConsortiumIds.add(roamingConsortiumId); 1479 } 1480 1481 providerFriendlyName = source.providerFriendlyName; 1482 preSharedKey = source.preSharedKey; 1483 1484 apBand = source.apBand; 1485 apChannel = source.apChannel; 1486 1487 wepKeys = new String[4]; 1488 for (int i = 0; i < wepKeys.length; i++) { 1489 wepKeys[i] = source.wepKeys[i]; 1490 } 1491 1492 wepTxKeyIndex = source.wepTxKeyIndex; 1493 priority = source.priority; 1494 hiddenSSID = source.hiddenSSID; 1495 allowedKeyManagement = (BitSet) source.allowedKeyManagement.clone(); 1496 allowedProtocols = (BitSet) source.allowedProtocols.clone(); 1497 allowedAuthAlgorithms = (BitSet) source.allowedAuthAlgorithms.clone(); 1498 allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone(); 1499 allowedGroupCiphers = (BitSet) source.allowedGroupCiphers.clone(); 1500 1501 enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig); 1502 1503 defaultGwMacAddress = source.defaultGwMacAddress; 1504 1505 mIpConfiguration = new IpConfiguration(source.mIpConfiguration); 1506 1507 if ((source.connectChoices != null) && (source.connectChoices.size() > 0)) { 1508 connectChoices = new HashMap<String, Integer>(); 1509 connectChoices.putAll(source.connectChoices); 1510 } 1511 1512 if ((source.linkedConfigurations != null) 1513 && (source.linkedConfigurations.size() > 0)) { 1514 linkedConfigurations = new HashMap<String, Integer>(); 1515 linkedConfigurations.putAll(source.linkedConfigurations); 1516 } 1517 mCachedConfigKey = null; //force null configKey 1518 autoJoinStatus = source.autoJoinStatus; 1519 selfAdded = source.selfAdded; 1520 validatedInternetAccess = source.validatedInternetAccess; 1521 ephemeral = source.ephemeral; 1522 if (source.visibility != null) { 1523 visibility = new Visibility(source.visibility); 1524 } 1525 1526 lastFailure = source.lastFailure; 1527 didSelfAdd = source.didSelfAdd; 1528 lastConnectUid = source.lastConnectUid; 1529 lastUpdateUid = source.lastUpdateUid; 1530 creatorUid = source.creatorUid; 1531 creatorName = source.creatorName; 1532 lastUpdateName = source.lastUpdateName; 1533 peerWifiConfiguration = source.peerWifiConfiguration; 1534 blackListTimestamp = source.blackListTimestamp; 1535 lastConnected = source.lastConnected; 1536 lastDisconnected = source.lastDisconnected; 1537 lastConnectionFailure = source.lastConnectionFailure; 1538 lastRoamingFailure = source.lastRoamingFailure; 1539 lastRoamingFailureReason = source.lastRoamingFailureReason; 1540 roamingFailureBlackListTimeMilli = source.roamingFailureBlackListTimeMilli; 1541 numConnectionFailures = source.numConnectionFailures; 1542 numIpConfigFailures = source.numIpConfigFailures; 1543 numAuthFailures = source.numAuthFailures; 1544 numScorerOverride = source.numScorerOverride; 1545 numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork; 1546 numAssociation = source.numAssociation; 1547 numUserTriggeredWifiDisableLowRSSI = source.numUserTriggeredWifiDisableLowRSSI; 1548 numUserTriggeredWifiDisableBadRSSI = source.numUserTriggeredWifiDisableBadRSSI; 1549 numUserTriggeredWifiDisableNotHighRSSI = source.numUserTriggeredWifiDisableNotHighRSSI; 1550 numTicksAtLowRSSI = source.numTicksAtLowRSSI; 1551 numTicksAtBadRSSI = source.numTicksAtBadRSSI; 1552 numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI; 1553 numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts; 1554 autoJoinBSSID = source.autoJoinBSSID; 1555 autoJoinUseAggressiveJoinAttemptThreshold 1556 = source.autoJoinUseAggressiveJoinAttemptThreshold; 1557 autoJoinBailedDueToLowRssi = source.autoJoinBailedDueToLowRssi; 1558 dirty = source.dirty; 1559 userApproved = source.userApproved; 1560 numNoInternetAccessReports = source.numNoInternetAccessReports; 1561 noInternetAccessExpected = source.noInternetAccessExpected; 1562 } 1563 } 1564 1565 /** {@hide} */ 1566 //public static final int NOTHING_TAG = 0; 1567 /** {@hide} */ 1568 //public static final int SCAN_CACHE_TAG = 1; 1569 1570 /** Implement the Parcelable interface {@hide} */ 1571 @Override 1572 public void writeToParcel(Parcel dest, int flags) { 1573 dest.writeInt(networkId); 1574 dest.writeInt(status); 1575 dest.writeInt(disableReason); 1576 dest.writeString(SSID); 1577 dest.writeString(BSSID); 1578 dest.writeInt(apBand); 1579 dest.writeInt(apChannel); 1580 dest.writeString(autoJoinBSSID); 1581 dest.writeString(FQDN); 1582 dest.writeString(providerFriendlyName); 1583 dest.writeInt(roamingConsortiumIds.size()); 1584 for (Long roamingConsortiumId : roamingConsortiumIds) { 1585 dest.writeLong(roamingConsortiumId); 1586 } 1587 dest.writeString(preSharedKey); 1588 for (String wepKey : wepKeys) { 1589 dest.writeString(wepKey); 1590 } 1591 dest.writeInt(wepTxKeyIndex); 1592 dest.writeInt(priority); 1593 dest.writeInt(hiddenSSID ? 1 : 0); 1594 dest.writeInt(requirePMF ? 1 : 0); 1595 dest.writeString(updateIdentifier); 1596 1597 writeBitSet(dest, allowedKeyManagement); 1598 writeBitSet(dest, allowedProtocols); 1599 writeBitSet(dest, allowedAuthAlgorithms); 1600 writeBitSet(dest, allowedPairwiseCiphers); 1601 writeBitSet(dest, allowedGroupCiphers); 1602 1603 dest.writeParcelable(enterpriseConfig, flags); 1604 1605 dest.writeParcelable(mIpConfiguration, flags); 1606 dest.writeString(dhcpServer); 1607 dest.writeString(defaultGwMacAddress); 1608 dest.writeInt(autoJoinStatus); 1609 dest.writeInt(selfAdded ? 1 : 0); 1610 dest.writeInt(didSelfAdd ? 1 : 0); 1611 dest.writeInt(validatedInternetAccess ? 1 : 0); 1612 dest.writeInt(ephemeral ? 1 : 0); 1613 dest.writeInt(creatorUid); 1614 dest.writeInt(lastConnectUid); 1615 dest.writeInt(lastUpdateUid); 1616 dest.writeString(creatorName); 1617 dest.writeString(lastUpdateName); 1618 dest.writeLong(blackListTimestamp); 1619 dest.writeLong(lastConnectionFailure); 1620 dest.writeLong(lastRoamingFailure); 1621 dest.writeInt(lastRoamingFailureReason); 1622 dest.writeLong(roamingFailureBlackListTimeMilli); 1623 dest.writeInt(numConnectionFailures); 1624 dest.writeInt(numIpConfigFailures); 1625 dest.writeInt(numAuthFailures); 1626 dest.writeInt(numScorerOverride); 1627 dest.writeInt(numScorerOverrideAndSwitchedNetwork); 1628 dest.writeInt(numAssociation); 1629 dest.writeInt(numUserTriggeredWifiDisableLowRSSI); 1630 dest.writeInt(numUserTriggeredWifiDisableBadRSSI); 1631 dest.writeInt(numUserTriggeredWifiDisableNotHighRSSI); 1632 dest.writeInt(numTicksAtLowRSSI); 1633 dest.writeInt(numTicksAtBadRSSI); 1634 dest.writeInt(numTicksAtNotHighRSSI); 1635 dest.writeInt(numUserTriggeredJoinAttempts); 1636 dest.writeInt(autoJoinUseAggressiveJoinAttemptThreshold); 1637 dest.writeInt(autoJoinBailedDueToLowRssi ? 1 : 0); 1638 dest.writeInt(userApproved); 1639 dest.writeInt(numNoInternetAccessReports); 1640 dest.writeInt(noInternetAccessExpected ? 1 : 0); 1641 } 1642 1643 /** Implement the Parcelable interface {@hide} */ 1644 public static final Creator<WifiConfiguration> CREATOR = 1645 new Creator<WifiConfiguration>() { 1646 public WifiConfiguration createFromParcel(Parcel in) { 1647 WifiConfiguration config = new WifiConfiguration(); 1648 config.networkId = in.readInt(); 1649 config.status = in.readInt(); 1650 config.disableReason = in.readInt(); 1651 config.SSID = in.readString(); 1652 config.BSSID = in.readString(); 1653 config.apBand = in.readInt(); 1654 config.apChannel = in.readInt(); 1655 config.autoJoinBSSID = in.readString(); 1656 config.FQDN = in.readString(); 1657 config.providerFriendlyName = in.readString(); 1658 int numRoamingConsortiumIds = in.readInt(); 1659 for (int i = 0; i < numRoamingConsortiumIds; i++) { 1660 config.roamingConsortiumIds.add(in.readLong()); 1661 } 1662 config.preSharedKey = in.readString(); 1663 for (int i = 0; i < config.wepKeys.length; i++) { 1664 config.wepKeys[i] = in.readString(); 1665 } 1666 config.wepTxKeyIndex = in.readInt(); 1667 config.priority = in.readInt(); 1668 config.hiddenSSID = in.readInt() != 0; 1669 config.requirePMF = in.readInt() != 0; 1670 config.updateIdentifier = in.readString(); 1671 1672 config.allowedKeyManagement = readBitSet(in); 1673 config.allowedProtocols = readBitSet(in); 1674 config.allowedAuthAlgorithms = readBitSet(in); 1675 config.allowedPairwiseCiphers = readBitSet(in); 1676 config.allowedGroupCiphers = readBitSet(in); 1677 1678 config.enterpriseConfig = in.readParcelable(null); 1679 1680 config.mIpConfiguration = in.readParcelable(null); 1681 config.dhcpServer = in.readString(); 1682 config.defaultGwMacAddress = in.readString(); 1683 config.autoJoinStatus = in.readInt(); 1684 config.selfAdded = in.readInt() != 0; 1685 config.didSelfAdd = in.readInt() != 0; 1686 config.validatedInternetAccess = in.readInt() != 0; 1687 config.ephemeral = in.readInt() != 0; 1688 config.creatorUid = in.readInt(); 1689 config.lastConnectUid = in.readInt(); 1690 config.lastUpdateUid = in.readInt(); 1691 config.creatorName = in.readString(); 1692 config.lastUpdateName = in.readString(); 1693 config.blackListTimestamp = in.readLong(); 1694 config.lastConnectionFailure = in.readLong(); 1695 config.lastRoamingFailure = in.readLong(); 1696 config.lastRoamingFailureReason = in.readInt(); 1697 config.roamingFailureBlackListTimeMilli = in.readLong(); 1698 config.numConnectionFailures = in.readInt(); 1699 config.numIpConfigFailures = in.readInt(); 1700 config.numAuthFailures = in.readInt(); 1701 config.numScorerOverride = in.readInt(); 1702 config.numScorerOverrideAndSwitchedNetwork = in.readInt(); 1703 config.numAssociation = in.readInt(); 1704 config.numUserTriggeredWifiDisableLowRSSI = in.readInt(); 1705 config.numUserTriggeredWifiDisableBadRSSI = in.readInt(); 1706 config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt(); 1707 config.numTicksAtLowRSSI = in.readInt(); 1708 config.numTicksAtBadRSSI = in.readInt(); 1709 config.numTicksAtNotHighRSSI = in.readInt(); 1710 config.numUserTriggeredJoinAttempts = in.readInt(); 1711 config.autoJoinUseAggressiveJoinAttemptThreshold = in.readInt(); 1712 config.autoJoinBailedDueToLowRssi = in.readInt() != 0; 1713 config.userApproved = in.readInt(); 1714 config.numNoInternetAccessReports = in.readInt(); 1715 config.noInternetAccessExpected = in.readInt() != 0; 1716 return config; 1717 } 1718 1719 public WifiConfiguration[] newArray(int size) { 1720 return new WifiConfiguration[size]; 1721 } 1722 }; 1723} 1724