1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.wifi; 18 19 import android.annotation.SystemApi; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 23 import java.util.ArrayList; 24 import java.util.List; 25 26 /** 27 * Describes information about a detected access point. In addition 28 * to the attributes described here, the supplicant keeps track of 29 * {@code quality}, {@code noise}, and {@code maxbitrate} attributes, 30 * but does not currently report them to external clients. 31 */ 32 public class ScanResult implements Parcelable { 33 /** 34 * The network name. 35 */ 36 public String SSID; 37 38 /** 39 * Ascii encoded SSID. This will replace SSID when we deprecate it. @hide 40 */ 41 public WifiSsid wifiSsid; 42 43 /** 44 * The address of the access point. 45 */ 46 public String BSSID; 47 48 /** 49 * The HESSID from the beacon. 50 * @hide 51 */ 52 public long hessid; 53 54 /** 55 * The ANQP Domain ID from the Hotspot 2.0 Indication element, if present. 56 * @hide 57 */ 58 public int anqpDomainId; 59 60 /* 61 * This field is equivalent to the |flags|, rather than the |capabilities| field 62 * of the per-BSS scan results returned by WPA supplicant. See the definition of 63 * |struct wpa_bss| in wpa_supplicant/bss.h for more details. 64 */ 65 /** 66 * Describes the authentication, key management, and encryption schemes 67 * supported by the access point. 68 */ 69 public String capabilities; 70 71 /** 72 * @hide 73 * No security protocol. 74 */ 75 public static final int PROTOCOL_NONE = 0; 76 /** 77 * @hide 78 * Security protocol type: WPA version 1. 79 */ 80 public static final int PROTOCOL_WPA = 1; 81 /** 82 * @hide 83 * Security protocol type: WPA version 2, also called RSN. 84 */ 85 public static final int PROTOCOL_WPA2 = 2; 86 /** 87 * @hide 88 * Security protocol type: 89 * OSU Server-only authenticated layer 2 Encryption Network. 90 * Used for Hotspot 2.0. 91 */ 92 public static final int PROTOCOL_OSEN = 3; 93 94 /** 95 * @hide 96 * No security key management scheme. 97 */ 98 public static final int KEY_MGMT_NONE = 0; 99 /** 100 * @hide 101 * Security key management scheme: PSK. 102 */ 103 public static final int KEY_MGMT_PSK = 1; 104 /** 105 * @hide 106 * Security key management scheme: EAP. 107 */ 108 public static final int KEY_MGMT_EAP = 2; 109 /** 110 * @hide 111 * Security key management scheme: FT_PSK. 112 */ 113 public static final int KEY_MGMT_FT_PSK = 3; 114 /** 115 * @hide 116 * Security key management scheme: FT_EAP. 117 */ 118 public static final int KEY_MGMT_FT_EAP = 4; 119 /** 120 * @hide 121 * Security key management scheme: PSK_SHA256 122 */ 123 public static final int KEY_MGMT_PSK_SHA256 = 5; 124 /** 125 * @hide 126 * Security key management scheme: EAP_SHA256. 127 */ 128 public static final int KEY_MGMT_EAP_SHA256 = 6; 129 /** 130 * @hide 131 * Security key management scheme: OSEN. 132 * Used for Hotspot 2.0. 133 */ 134 public static final int KEY_MGMT_OSEN = 7; 135 136 /** 137 * @hide 138 * No cipher suite. 139 */ 140 public static final int CIPHER_NONE = 0; 141 /** 142 * @hide 143 * No group addressed, only used for group data cipher. 144 */ 145 public static final int CIPHER_NO_GROUP_ADDRESSED = 1; 146 /** 147 * @hide 148 * Cipher suite: TKIP 149 */ 150 public static final int CIPHER_TKIP = 2; 151 /** 152 * @hide 153 * Cipher suite: CCMP 154 */ 155 public static final int CIPHER_CCMP = 3; 156 157 /** 158 * The detected signal level in dBm, also known as the RSSI. 159 * 160 * <p>Use {@link android.net.wifi.WifiManager#calculateSignalLevel} to convert this number into 161 * an absolute signal level which can be displayed to a user. 162 */ 163 public int level; 164 /** 165 * The primary 20 MHz frequency (in MHz) of the channel over which the client is communicating 166 * with the access point. 167 */ 168 public int frequency; 169 170 /** 171 * AP Channel bandwidth is 20 MHZ 172 */ 173 public static final int CHANNEL_WIDTH_20MHZ = 0; 174 /** 175 * AP Channel bandwidth is 40 MHZ 176 */ 177 public static final int CHANNEL_WIDTH_40MHZ = 1; 178 /** 179 * AP Channel bandwidth is 80 MHZ 180 */ 181 public static final int CHANNEL_WIDTH_80MHZ = 2; 182 /** 183 * AP Channel bandwidth is 160 MHZ 184 */ 185 public static final int CHANNEL_WIDTH_160MHZ = 3; 186 /** 187 * AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ 188 */ 189 public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 4; 190 191 /** 192 * AP Channel bandwidth; one of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ}, 193 * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ} 194 * or {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}. 195 */ 196 public int channelWidth; 197 198 /** 199 * Not used if the AP bandwidth is 20 MHz 200 * If the AP use 40, 80 or 160 MHz, this is the center frequency (in MHz) 201 * if the AP use 80 + 80 MHz, this is the center frequency of the first segment (in MHz) 202 */ 203 public int centerFreq0; 204 205 /** 206 * Only used if the AP bandwidth is 80 + 80 MHz 207 * if the AP use 80 + 80 MHz, this is the center frequency of the second segment (in MHz) 208 */ 209 public int centerFreq1; 210 211 /** 212 * @deprecated use is80211mcResponder() instead 213 * @hide 214 */ 215 public boolean is80211McRTTResponder; 216 217 /** 218 * timestamp in microseconds (since boot) when 219 * this result was last seen. 220 */ 221 public long timestamp; 222 223 /** 224 * Timestamp representing date when this result was last seen, in milliseconds from 1970 225 * {@hide} 226 */ 227 public long seen; 228 229 /** 230 * @hide 231 * Update RSSI of the scan result 232 * @param previousRssi 233 * @param previousSeen 234 * @param maxAge 235 */ averageRssi(int previousRssi, long previousSeen, int maxAge)236 public void averageRssi(int previousRssi, long previousSeen, int maxAge) { 237 238 if (seen == 0) { 239 seen = System.currentTimeMillis(); 240 } 241 long age = seen - previousSeen; 242 243 if (previousSeen > 0 && age > 0 && age < maxAge/2) { 244 // Average the RSSI with previously seen instances of this scan result 245 double alpha = 0.5 - (double) age / (double) maxAge; 246 level = (int) ((double) level * (1 - alpha) + (double) previousRssi * alpha); 247 } 248 } 249 250 /** 251 * num IP configuration failures 252 * @hide 253 */ 254 public int numIpConfigFailures; 255 256 /** 257 * @hide 258 * Last time we blacklisted the ScanResult 259 */ 260 public long blackListTimestamp; 261 262 /** 263 * Status indicating the scan result does not correspond to a user's saved configuration 264 * @hide 265 * @removed 266 */ 267 @SystemApi 268 public boolean untrusted; 269 270 /** 271 * Number of time we connected to it 272 * @hide 273 */ 274 public int numConnection; 275 276 /** 277 * Number of time autojoin used it 278 * @hide 279 */ 280 public int numUsage; 281 282 /** 283 * The approximate distance to the AP in centimeter, if available. Else 284 * {@link UNSPECIFIED}. 285 * {@hide} 286 */ 287 public int distanceCm; 288 289 /** 290 * The standard deviation of the distance to the access point, if available. 291 * Else {@link UNSPECIFIED}. 292 * {@hide} 293 */ 294 public int distanceSdCm; 295 296 /** {@hide} */ 297 public static final long FLAG_PASSPOINT_NETWORK = 0x0000000000000001; 298 299 /** {@hide} */ 300 public static final long FLAG_80211mc_RESPONDER = 0x0000000000000002; 301 302 /* 303 * These flags are specific to the ScanResult class, and are not related to the |flags| 304 * field of the per-BSS scan results from WPA supplicant. 305 */ 306 /** 307 * Defines flags; such as {@link #FLAG_PASSPOINT_NETWORK}. 308 * {@hide} 309 */ 310 public long flags; 311 312 /** 313 * sets a flag in {@link #flags} field 314 * @param flag flag to set 315 * @hide 316 */ setFlag(long flag)317 public void setFlag(long flag) { 318 flags |= flag; 319 } 320 321 /** 322 * clears a flag in {@link #flags} field 323 * @param flag flag to set 324 * @hide 325 */ clearFlag(long flag)326 public void clearFlag(long flag) { 327 flags &= ~flag; 328 } 329 is80211mcResponder()330 public boolean is80211mcResponder() { 331 return (flags & FLAG_80211mc_RESPONDER) != 0; 332 } 333 isPasspointNetwork()334 public boolean isPasspointNetwork() { 335 return (flags & FLAG_PASSPOINT_NETWORK) != 0; 336 } 337 338 /** 339 * Indicates venue name (such as 'San Francisco Airport') published by access point; only 340 * available on Passpoint network and if published by access point. 341 */ 342 public CharSequence venueName; 343 344 /** 345 * Indicates Passpoint operator name published by access point. 346 */ 347 public CharSequence operatorFriendlyName; 348 349 /** 350 * {@hide} 351 */ 352 public final static int UNSPECIFIED = -1; 353 /** 354 * @hide 355 */ is24GHz()356 public boolean is24GHz() { 357 return ScanResult.is24GHz(frequency); 358 } 359 360 /** 361 * @hide 362 * TODO: makes real freq boundaries 363 */ is24GHz(int freq)364 public static boolean is24GHz(int freq) { 365 return freq > 2400 && freq < 2500; 366 } 367 368 /** 369 * @hide 370 */ is5GHz()371 public boolean is5GHz() { 372 return ScanResult.is5GHz(frequency); 373 } 374 375 /** 376 * @hide 377 * TODO: makes real freq boundaries 378 */ is5GHz(int freq)379 public static boolean is5GHz(int freq) { 380 return freq > 4900 && freq < 5900; 381 } 382 383 /** 384 * @hide 385 * anqp lines from supplicant BSS response 386 */ 387 public List<String> anqpLines; 388 389 /** 390 * @hide 391 * storing the raw bytes of full result IEs 392 **/ 393 public byte[] bytes; 394 395 /** information elements from beacon 396 * @hide 397 */ 398 public static class InformationElement { 399 public static final int EID_SSID = 0; 400 public static final int EID_SUPPORTED_RATES = 1; 401 public static final int EID_TIM = 5; 402 public static final int EID_BSS_LOAD = 11; 403 public static final int EID_ERP = 42; 404 public static final int EID_RSN = 48; 405 public static final int EID_EXTENDED_SUPPORTED_RATES = 50; 406 public static final int EID_HT_OPERATION = 61; 407 public static final int EID_INTERWORKING = 107; 408 public static final int EID_ROAMING_CONSORTIUM = 111; 409 public static final int EID_EXTENDED_CAPS = 127; 410 public static final int EID_VHT_OPERATION = 192; 411 public static final int EID_VSA = 221; 412 413 public int id; 414 public byte[] bytes; 415 InformationElement()416 public InformationElement() { 417 } 418 InformationElement(InformationElement rhs)419 public InformationElement(InformationElement rhs) { 420 this.id = rhs.id; 421 this.bytes = rhs.bytes.clone(); 422 } 423 } 424 425 /** information elements found in the beacon 426 * @hide 427 */ 428 public InformationElement[] informationElements; 429 430 /** ANQP response elements. 431 * @hide 432 */ 433 public AnqpInformationElement[] anqpElements; 434 435 /** 436 * Flag indicating if this AP is a carrier AP. The determination is based 437 * on the AP's SSID and if AP is using EAP security. 438 * 439 * @hide 440 */ 441 public boolean isCarrierAp; 442 443 /** 444 * The EAP type {@link WifiEnterpriseConfig.Eap} associated with this AP if it is a carrier AP. 445 * 446 * @hide 447 */ 448 public int carrierApEapType; 449 450 /** 451 * The name of the carrier that's associated with this AP if it is a carrier AP. 452 * 453 * @hide 454 */ 455 public String carrierName; 456 457 /** {@hide} */ ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId, byte[] osuProviders, String caps, int level, int frequency, long tsf)458 public ScanResult(WifiSsid wifiSsid, String BSSID, long hessid, int anqpDomainId, 459 byte[] osuProviders, String caps, int level, int frequency, long tsf) { 460 this.wifiSsid = wifiSsid; 461 this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE; 462 this.BSSID = BSSID; 463 this.hessid = hessid; 464 this.anqpDomainId = anqpDomainId; 465 if (osuProviders != null) { 466 this.anqpElements = new AnqpInformationElement[1]; 467 this.anqpElements[0] = 468 new AnqpInformationElement(AnqpInformationElement.HOTSPOT20_VENDOR_ID, 469 AnqpInformationElement.HS_OSU_PROVIDERS, osuProviders); 470 } 471 this.capabilities = caps; 472 this.level = level; 473 this.frequency = frequency; 474 this.timestamp = tsf; 475 this.distanceCm = UNSPECIFIED; 476 this.distanceSdCm = UNSPECIFIED; 477 this.channelWidth = UNSPECIFIED; 478 this.centerFreq0 = UNSPECIFIED; 479 this.centerFreq1 = UNSPECIFIED; 480 this.flags = 0; 481 this.isCarrierAp = false; 482 this.carrierApEapType = UNSPECIFIED; 483 this.carrierName = null; 484 } 485 486 /** {@hide} */ ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency, long tsf, int distCm, int distSdCm)487 public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency, 488 long tsf, int distCm, int distSdCm) { 489 this.wifiSsid = wifiSsid; 490 this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE; 491 this.BSSID = BSSID; 492 this.capabilities = caps; 493 this.level = level; 494 this.frequency = frequency; 495 this.timestamp = tsf; 496 this.distanceCm = distCm; 497 this.distanceSdCm = distSdCm; 498 this.channelWidth = UNSPECIFIED; 499 this.centerFreq0 = UNSPECIFIED; 500 this.centerFreq1 = UNSPECIFIED; 501 this.flags = 0; 502 this.isCarrierAp = false; 503 this.carrierApEapType = UNSPECIFIED; 504 this.carrierName = null; 505 } 506 507 /** {@hide} */ ScanResult(String Ssid, String BSSID, long hessid, int anqpDomainId, String caps, int level, int frequency, long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1, boolean is80211McRTTResponder)508 public ScanResult(String Ssid, String BSSID, long hessid, int anqpDomainId, String caps, 509 int level, int frequency, 510 long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1, 511 boolean is80211McRTTResponder) { 512 this.SSID = Ssid; 513 this.BSSID = BSSID; 514 this.hessid = hessid; 515 this.anqpDomainId = anqpDomainId; 516 this.capabilities = caps; 517 this.level = level; 518 this.frequency = frequency; 519 this.timestamp = tsf; 520 this.distanceCm = distCm; 521 this.distanceSdCm = distSdCm; 522 this.channelWidth = channelWidth; 523 this.centerFreq0 = centerFreq0; 524 this.centerFreq1 = centerFreq1; 525 if (is80211McRTTResponder) { 526 this.flags = FLAG_80211mc_RESPONDER; 527 } else { 528 this.flags = 0; 529 } 530 this.isCarrierAp = false; 531 this.carrierApEapType = UNSPECIFIED; 532 this.carrierName = null; 533 } 534 535 /** {@hide} */ ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, long hessid, int anqpDomainId, String caps, int level, int frequency, long tsf, int distCm, int distSdCm, int channelWidth, int centerFreq0, int centerFreq1, boolean is80211McRTTResponder)536 public ScanResult(WifiSsid wifiSsid, String Ssid, String BSSID, long hessid, int anqpDomainId, 537 String caps, int level, 538 int frequency, long tsf, int distCm, int distSdCm, int channelWidth, 539 int centerFreq0, int centerFreq1, boolean is80211McRTTResponder) { 540 this(Ssid, BSSID, hessid, anqpDomainId, caps, level, frequency, tsf, distCm, 541 distSdCm, channelWidth, centerFreq0, centerFreq1, is80211McRTTResponder); 542 this.wifiSsid = wifiSsid; 543 } 544 545 /** copy constructor {@hide} */ ScanResult(ScanResult source)546 public ScanResult(ScanResult source) { 547 if (source != null) { 548 wifiSsid = source.wifiSsid; 549 SSID = source.SSID; 550 BSSID = source.BSSID; 551 hessid = source.hessid; 552 anqpDomainId = source.anqpDomainId; 553 informationElements = source.informationElements; 554 anqpElements = source.anqpElements; 555 capabilities = source.capabilities; 556 level = source.level; 557 frequency = source.frequency; 558 channelWidth = source.channelWidth; 559 centerFreq0 = source.centerFreq0; 560 centerFreq1 = source.centerFreq1; 561 timestamp = source.timestamp; 562 distanceCm = source.distanceCm; 563 distanceSdCm = source.distanceSdCm; 564 seen = source.seen; 565 untrusted = source.untrusted; 566 numConnection = source.numConnection; 567 numUsage = source.numUsage; 568 numIpConfigFailures = source.numIpConfigFailures; 569 venueName = source.venueName; 570 operatorFriendlyName = source.operatorFriendlyName; 571 flags = source.flags; 572 isCarrierAp = source.isCarrierAp; 573 carrierApEapType = source.carrierApEapType; 574 carrierName = source.carrierName; 575 } 576 } 577 578 /** empty scan result 579 * 580 * {@hide} 581 * */ ScanResult()582 public ScanResult() { 583 } 584 585 @Override toString()586 public String toString() { 587 StringBuffer sb = new StringBuffer(); 588 String none = "<none>"; 589 590 sb.append("SSID: "). 591 append(wifiSsid == null ? WifiSsid.NONE : wifiSsid). 592 append(", BSSID: "). 593 append(BSSID == null ? none : BSSID). 594 append(", capabilities: "). 595 append(capabilities == null ? none : capabilities). 596 append(", level: "). 597 append(level). 598 append(", frequency: "). 599 append(frequency). 600 append(", timestamp: "). 601 append(timestamp); 602 603 sb.append(", distance: ").append((distanceCm != UNSPECIFIED ? distanceCm : "?")). 604 append("(cm)"); 605 sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")). 606 append("(cm)"); 607 608 sb.append(", passpoint: "); 609 sb.append(((flags & FLAG_PASSPOINT_NETWORK) != 0) ? "yes" : "no"); 610 sb.append(", ChannelBandwidth: ").append(channelWidth); 611 sb.append(", centerFreq0: ").append(centerFreq0); 612 sb.append(", centerFreq1: ").append(centerFreq1); 613 sb.append(", 80211mcResponder: "); 614 sb.append(((flags & FLAG_80211mc_RESPONDER) != 0) ? "is supported" : "is not supported"); 615 sb.append(", Carrier AP: ").append(isCarrierAp ? "yes" : "no"); 616 sb.append(", Carrier AP EAP Type: ").append(carrierApEapType); 617 sb.append(", Carrier name: ").append(carrierName); 618 return sb.toString(); 619 } 620 621 /** Implement the Parcelable interface {@hide} */ describeContents()622 public int describeContents() { 623 return 0; 624 } 625 626 /** Implement the Parcelable interface {@hide} */ writeToParcel(Parcel dest, int flags)627 public void writeToParcel(Parcel dest, int flags) { 628 if (wifiSsid != null) { 629 dest.writeInt(1); 630 wifiSsid.writeToParcel(dest, flags); 631 } else { 632 dest.writeInt(0); 633 } 634 dest.writeString(SSID); 635 dest.writeString(BSSID); 636 dest.writeLong(hessid); 637 dest.writeInt(anqpDomainId); 638 dest.writeString(capabilities); 639 dest.writeInt(level); 640 dest.writeInt(frequency); 641 dest.writeLong(timestamp); 642 dest.writeInt(distanceCm); 643 dest.writeInt(distanceSdCm); 644 dest.writeInt(channelWidth); 645 dest.writeInt(centerFreq0); 646 dest.writeInt(centerFreq1); 647 dest.writeLong(seen); 648 dest.writeInt(untrusted ? 1 : 0); 649 dest.writeInt(numConnection); 650 dest.writeInt(numUsage); 651 dest.writeInt(numIpConfigFailures); 652 dest.writeString((venueName != null) ? venueName.toString() : ""); 653 dest.writeString((operatorFriendlyName != null) ? operatorFriendlyName.toString() : ""); 654 dest.writeLong(this.flags); 655 656 if (informationElements != null) { 657 dest.writeInt(informationElements.length); 658 for (int i = 0; i < informationElements.length; i++) { 659 dest.writeInt(informationElements[i].id); 660 dest.writeInt(informationElements[i].bytes.length); 661 dest.writeByteArray(informationElements[i].bytes); 662 } 663 } else { 664 dest.writeInt(0); 665 } 666 667 if (anqpLines != null) { 668 dest.writeInt(anqpLines.size()); 669 for (int i = 0; i < anqpLines.size(); i++) { 670 dest.writeString(anqpLines.get(i)); 671 } 672 } 673 else { 674 dest.writeInt(0); 675 } 676 if (anqpElements != null) { 677 dest.writeInt(anqpElements.length); 678 for (AnqpInformationElement element : anqpElements) { 679 dest.writeInt(element.getVendorId()); 680 dest.writeInt(element.getElementId()); 681 dest.writeInt(element.getPayload().length); 682 dest.writeByteArray(element.getPayload()); 683 } 684 } else { 685 dest.writeInt(0); 686 } 687 dest.writeInt(isCarrierAp ? 1 : 0); 688 dest.writeInt(carrierApEapType); 689 dest.writeString(carrierName); 690 } 691 692 /** Implement the Parcelable interface {@hide} */ 693 public static final Creator<ScanResult> CREATOR = 694 new Creator<ScanResult>() { 695 public ScanResult createFromParcel(Parcel in) { 696 WifiSsid wifiSsid = null; 697 if (in.readInt() == 1) { 698 wifiSsid = WifiSsid.CREATOR.createFromParcel(in); 699 } 700 ScanResult sr = new ScanResult( 701 wifiSsid, 702 in.readString(), /* SSID */ 703 in.readString(), /* BSSID */ 704 in.readLong(), /* HESSID */ 705 in.readInt(), /* ANQP Domain ID */ 706 in.readString(), /* capabilities */ 707 in.readInt(), /* level */ 708 in.readInt(), /* frequency */ 709 in.readLong(), /* timestamp */ 710 in.readInt(), /* distanceCm */ 711 in.readInt(), /* distanceSdCm */ 712 in.readInt(), /* channelWidth */ 713 in.readInt(), /* centerFreq0 */ 714 in.readInt(), /* centerFreq1 */ 715 false /* rtt responder, 716 fixed with flags below */ 717 ); 718 719 sr.seen = in.readLong(); 720 sr.untrusted = in.readInt() != 0; 721 sr.numConnection = in.readInt(); 722 sr.numUsage = in.readInt(); 723 sr.numIpConfigFailures = in.readInt(); 724 sr.venueName = in.readString(); 725 sr.operatorFriendlyName = in.readString(); 726 sr.flags = in.readLong(); 727 int n = in.readInt(); 728 if (n != 0) { 729 sr.informationElements = new InformationElement[n]; 730 for (int i = 0; i < n; i++) { 731 sr.informationElements[i] = new InformationElement(); 732 sr.informationElements[i].id = in.readInt(); 733 int len = in.readInt(); 734 sr.informationElements[i].bytes = new byte[len]; 735 in.readByteArray(sr.informationElements[i].bytes); 736 } 737 } 738 739 n = in.readInt(); 740 if (n != 0) { 741 sr.anqpLines = new ArrayList<String>(); 742 for (int i = 0; i < n; i++) { 743 sr.anqpLines.add(in.readString()); 744 } 745 } 746 n = in.readInt(); 747 if (n != 0) { 748 sr.anqpElements = new AnqpInformationElement[n]; 749 for (int i = 0; i < n; i++) { 750 int vendorId = in.readInt(); 751 int elementId = in.readInt(); 752 int len = in.readInt(); 753 byte[] payload = new byte[len]; 754 in.readByteArray(payload); 755 sr.anqpElements[i] = 756 new AnqpInformationElement(vendorId, elementId, payload); 757 } 758 } 759 sr.isCarrierAp = in.readInt() != 0; 760 sr.carrierApEapType = in.readInt(); 761 sr.carrierName = in.readString(); 762 return sr; 763 } 764 765 public ScanResult[] newArray(int size) { 766 return new ScanResult[size]; 767 } 768 }; 769 } 770