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