ScanResult.java revision 894651bab56bfcfa2ecb35dfac262f2590ff483d
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.net.wifi.passpoint.WifiPasspointInfo;
20import android.net.wifi.passpoint.WifiPasspointManager;
21import android.os.Parcelable;
22import android.os.Parcel;
23
24/**
25 * Describes information about a detected access point. In addition
26 * to the attributes described here, the supplicant keeps track of
27 * {@code quality}, {@code noise}, and {@code maxbitrate} attributes,
28 * but does not currently report them to external clients.
29 */
30public class ScanResult implements Parcelable {
31    /**
32     * The network name.
33     */
34    public String SSID;
35
36    /**
37     * Ascii encoded SSID. This will replace SSID when we deprecate it. @hide
38     */
39    public WifiSsid wifiSsid;
40
41    /**
42     * The address of the access point.
43     */
44    public String BSSID;
45    /**
46     * Describes the authentication, key management, and encryption schemes
47     * supported by the access point.
48     */
49    public String capabilities;
50    /**
51     * The detected signal level in dBm.
52     */
53    public int level;
54    /**
55     * The frequency in MHz of the channel over which the client is communicating
56     * with the access point.
57     */
58    public int frequency;
59
60    /**
61     * Time Synchronization Function (tsf) timestamp in microseconds when
62     * this result was last seen.
63     */
64    public long timestamp;
65
66    /**
67     * Timestamp representing date when this result was last seen, in milliseconds from 1970
68     * {@hide}
69     */
70    public long seen;
71
72    /**
73     * @hide
74     * Update RSSI of the scan result
75     * @param previousRSSI
76     * @param previousSeen
77     * @param maxAge
78     */
79    public void averageRssi(int previousRssi, long previousSeen, int maxAge) {
80
81        if (seen == 0) {
82            seen = System.currentTimeMillis();
83        }
84        long age = seen - previousSeen;
85
86        if (previousSeen > 0 && age > 0 && age < maxAge/2) {
87            // Average the RSSI with previously seen instances of this scan result
88            double alpha = 0.5 - (double) age / (double) maxAge;
89            level = (int) ((double) level * (1 - alpha) + (double) previousRssi * alpha);
90        }
91    }
92
93    /** @hide */
94    public static final int ENABLED                                          = 0;
95    /** @hide */
96    public static final int AUTO_ROAM_DISABLED                               = 16;
97    /** @hide */
98    public static final int AUTO_JOIN_DISABLED                               = 32;
99    /** @hide */
100    public static final int AUTHENTICATION_ERROR                              = 128;
101
102    /**
103     * Status: indicating join status
104     * @hide
105     */
106    public int status;
107
108    /**
109     * Status: indicating the scan result is not a result
110     * that is part of user's saved configurations
111     * @hide
112     */
113    public boolean untrusted;
114
115    /**
116     * Number of time we connected to it
117     * @hide
118     */
119    public int numConnection;
120
121    /**
122     * Number of time autojoin used it
123     * @hide
124     */
125    public int numUsage;
126
127    /**
128     * The approximate distance to the AP in centimeter, if available.  Else
129     * {@link UNSPECIFIED}.
130     * {@hide}
131     */
132    public int distanceCm;
133
134    /**
135     * The standard deviation of the distance to the AP, if available.
136     * Else {@link UNSPECIFIED}.
137     * {@hide}
138     */
139    public int distanceSdCm;
140
141    /**
142     * Passpoint ANQP information. This is not fetched automatically.
143     * Use {@link WifiPasspointManager#requestAnqpInfo} to request ANQP info.
144     */
145    public WifiPasspointInfo passpoint;
146
147    /**
148     * {@hide}
149     */
150    public final static int UNSPECIFIED = -1;
151    /**
152     * @hide
153     */
154    public boolean is24GHz() {
155        return ScanResult.is24GHz(frequency);
156    }
157
158    /**
159     * @hide
160     * TODO: makes real freq boundaries
161     */
162    public static boolean is24GHz(int freq) {
163        return freq > 2400 && freq < 2500;
164    }
165
166    /**
167     * @hide
168     */
169    public boolean is5GHz() {
170        return ScanResult.is5GHz(frequency);
171    }
172
173    /**
174     * @hide
175     * TODO: makes real freq boundaries
176     */
177    public static boolean is5GHz(int freq) {
178        return freq > 4900 && freq < 5900;
179    }
180
181    /** information element from beacon
182     * @hide
183     */
184    public static class InformationElement {
185        public int id;
186        public byte[] bytes;
187
188        public InformationElement() {
189        }
190
191        public InformationElement(InformationElement rhs) {
192            this.id = rhs.id;
193            this.bytes = rhs.bytes.clone();
194        }
195    }
196
197    /** information elements found in the beacon
198     * @hide
199     */
200    public InformationElement informationElements[];
201
202    /** {@hide} */
203    public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
204            long tsf) {
205        this.wifiSsid = wifiSsid;
206        this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
207        this.BSSID = BSSID;
208        this.capabilities = caps;
209        this.level = level;
210        this.frequency = frequency;
211        this.timestamp = tsf;
212        this.distanceCm = UNSPECIFIED;
213        this.distanceSdCm = UNSPECIFIED;
214    }
215
216    /** {@hide} */
217    public ScanResult(WifiSsid wifiSsid, String BSSID, String caps, int level, int frequency,
218            long tsf, int distCm, int distSdCm) {
219        this.wifiSsid = wifiSsid;
220        this.SSID = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
221        this.BSSID = BSSID;
222        this.capabilities = caps;
223        this.level = level;
224        this.frequency = frequency;
225        this.timestamp = tsf;
226        this.distanceCm = distCm;
227        this.distanceSdCm = distSdCm;
228    }
229
230    /** copy constructor {@hide} */
231    public ScanResult(ScanResult source) {
232        if (source != null) {
233            wifiSsid = source.wifiSsid;
234            SSID = source.SSID;
235            BSSID = source.BSSID;
236            capabilities = source.capabilities;
237            level = source.level;
238            frequency = source.frequency;
239            timestamp = source.timestamp;
240            distanceCm = source.distanceCm;
241            distanceSdCm = source.distanceSdCm;
242            seen = source.seen;
243            passpoint = source.passpoint;
244            status = source.status;
245            untrusted = source.untrusted;
246            numConnection = source.numConnection;
247            numUsage = source.numUsage;
248        }
249    }
250
251    /** empty scan result
252     *
253     * {@hide}
254     * */
255    public ScanResult() {
256    }
257
258    @Override
259    public String toString() {
260        StringBuffer sb = new StringBuffer();
261        String none = "<none>";
262
263        sb.append("SSID: ").
264            append(wifiSsid == null ? WifiSsid.NONE : wifiSsid).
265            append(", BSSID: ").
266            append(BSSID == null ? none : BSSID).
267            append(", capabilities: ").
268            append(capabilities == null ? none : capabilities).
269            append(", level: ").
270            append(level).
271            append(", frequency: ").
272            append(frequency).
273            append(", timestamp: ").
274            append(timestamp);
275
276        sb.append(", distance: ").append((distanceCm != UNSPECIFIED ? distanceCm : "?")).
277                append("(cm)");
278        sb.append(", distanceSd: ").append((distanceSdCm != UNSPECIFIED ? distanceSdCm : "?")).
279                append("(cm)");
280
281        sb.append(", passpoint: ").append(passpoint != null ? "yes" : "no");
282        if (status != 0) {
283            sb.append(", status: ").append(status);
284        }
285        return sb.toString();
286    }
287
288    /** Implement the Parcelable interface {@hide} */
289    public int describeContents() {
290        return 0;
291    }
292
293    /** Implement the Parcelable interface {@hide} */
294    public void writeToParcel(Parcel dest, int flags) {
295        if (wifiSsid != null) {
296            dest.writeInt(1);
297            wifiSsid.writeToParcel(dest, flags);
298        } else {
299            dest.writeInt(0);
300        }
301        dest.writeString(BSSID);
302        dest.writeString(capabilities);
303        dest.writeInt(level);
304        dest.writeInt(frequency);
305        dest.writeLong(timestamp);
306        dest.writeInt(distanceCm);
307        dest.writeInt(distanceSdCm);
308        dest.writeLong(seen);
309        dest.writeInt(status);
310        dest.writeInt(untrusted ? 1 : 0);
311        dest.writeInt(numConnection);
312        dest.writeInt(numUsage);
313        if (passpoint != null) {
314            dest.writeInt(1);
315            passpoint.writeToParcel(dest, flags);
316        } else {
317            dest.writeInt(0);
318        }
319        if (informationElements != null) {
320            dest.writeInt(informationElements.length);
321            for (int i = 0; i < informationElements.length; i++) {
322                dest.writeInt(informationElements[i].id);
323                dest.writeInt(informationElements[i].bytes.length);
324                dest.writeByteArray(informationElements[i].bytes);
325            }
326        } else {
327            dest.writeInt(0);
328        }
329    }
330
331    /** Implement the Parcelable interface {@hide} */
332    public static final Creator<ScanResult> CREATOR =
333        new Creator<ScanResult>() {
334            public ScanResult createFromParcel(Parcel in) {
335                WifiSsid wifiSsid = null;
336                if (in.readInt() == 1) {
337                    wifiSsid = WifiSsid.CREATOR.createFromParcel(in);
338                }
339                ScanResult sr = new ScanResult(
340                    wifiSsid,
341                    in.readString(),
342                    in.readString(),
343                    in.readInt(),
344                    in.readInt(),
345                    in.readLong(),
346                    in.readInt(),
347                    in.readInt()
348                );
349                sr.seen = in.readLong();
350                sr.status = in.readInt();
351                sr.untrusted = in.readInt() != 0;
352                sr.numConnection = in.readInt();
353                sr.numUsage = in.readInt();
354                if (in.readInt() == 1) {
355                    sr.passpoint = WifiPasspointInfo.CREATOR.createFromParcel(in);
356                }
357                int n = in.readInt();
358                if (n != 0) {
359                    sr.informationElements = new InformationElement[n];
360                    for (int i = 0; i < n; i++) {
361                        sr.informationElements[i] = new InformationElement();
362                        sr.informationElements[i].id = in.readInt();
363                        int len = in.readInt();
364                        sr.informationElements[i].bytes = new byte[len];
365                        in.readByteArray(sr.informationElements[i].bytes);
366                    }
367                }
368                return sr;
369            }
370
371            public ScanResult[] newArray(int size) {
372                return new ScanResult[size];
373            }
374        };
375}
376