• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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