RttManager.java revision 7f61051949875edf4bfbf29b00ad6f2ede61d6cb
1package android.net.wifi; 2 3import android.annotation.SystemApi; 4import android.content.Context; 5import android.os.Bundle; 6import android.os.Handler; 7import android.os.HandlerThread; 8import android.os.Looper; 9import android.os.Message; 10import android.os.Messenger; 11import android.os.Parcel; 12import android.os.Parcelable; 13import android.os.RemoteException; 14import android.util.Log; 15import android.util.SparseArray; 16 17import com.android.internal.util.AsyncChannel; 18import com.android.internal.util.Protocol; 19 20import java.util.concurrent.CountDownLatch; 21 22/** @hide */ 23@SystemApi 24public class RttManager { 25 26 private static final boolean DBG = true; 27 private static final String TAG = "RttManager"; 28 29 /** @deprecated It is Not supported anymore. */ 30 @Deprecated 31 public static final int RTT_TYPE_UNSPECIFIED = 0; 32 33 public static final int RTT_TYPE_ONE_SIDED = 1; 34 public static final int RTT_TYPE_TWO_SIDED = 2; 35 36 /** @deprecated It is not supported anymore. */ 37 @Deprecated 38 public static final int RTT_TYPE_11_V = 2; 39 40 /** @deprecated It is not supported anymore. */ 41 @Deprecated 42 public static final int RTT_TYPE_11_MC = 4; 43 44 /** @deprecated It is not supported anymore. */ 45 @Deprecated 46 public static final int RTT_PEER_TYPE_UNSPECIFIED = 0; 47 48 public static final int RTT_PEER_TYPE_AP = 1; 49 public static final int RTT_PEER_TYPE_STA = 2; /* requires NAN */ 50 public static final int RTT_PEER_P2P_GO = 3; 51 public static final int RTT_PEER_P2P_CLIENT = 4; 52 public static final int RTT_PEER_NAN = 5; 53 54 /** 55 * @deprecated It is not supported anymore. 56 * Use {@link android.net.wifi.RttManager#RTT_BW_20_SUPPORT} API. 57 */ 58 @Deprecated 59 public static final int RTT_CHANNEL_WIDTH_20 = 0; 60 61 /** 62 * @deprecated It is not supported anymore. 63 * Use {@link android.net.wifi.RttManager#RTT_BW_40_SUPPORT} API. 64 */ 65 @Deprecated 66 public static final int RTT_CHANNEL_WIDTH_40 = 1; 67 68 /** 69 * @deprecated It is not supported anymore. 70 * Use {@link android.net.wifi.RttManager#RTT_BW_80_SUPPORT} API. 71 */ 72 @Deprecated 73 public static final int RTT_CHANNEL_WIDTH_80 = 2; 74 75 /**@deprecated It is not supported anymore. 76 * Use {@link android.net.wifi.RttManager#RTT_BW_160_SUPPORT} API. 77 */ 78 @Deprecated 79 public static final int RTT_CHANNEL_WIDTH_160 = 3; 80 81 /**@deprecated not supported anymore*/ 82 @Deprecated 83 public static final int RTT_CHANNEL_WIDTH_80P80 = 4; 84 85 /**@deprecated It is not supported anymore. 86 * Use {@link android.net.wifi.RttManager#RTT_BW_5_SUPPORT} API. 87 */ 88 @Deprecated 89 public static final int RTT_CHANNEL_WIDTH_5 = 5; 90 91 /**@deprecated It is not supported anymore. 92 * Use {@link android.net.wifi.RttManager#RTT_BW_10_SUPPORT} API. 93 */ 94 @Deprecated 95 public static final int RTT_CHANNEL_WIDTH_10 = 6; 96 97 /** @deprecated channel info must be specified. */ 98 @Deprecated 99 public static final int RTT_CHANNEL_WIDTH_UNSPECIFIED = -1; 100 101 public static final int RTT_STATUS_SUCCESS = 0; 102 /** General failure*/ 103 public static final int RTT_STATUS_FAILURE = 1; 104 /** Destination does not respond to RTT request*/ 105 public static final int RTT_STATUS_FAIL_NO_RSP = 2; 106 /** RTT request is rejected by the destination. Double side RTT only*/ 107 public static final int RTT_STATUS_FAIL_REJECTED = 3; 108 /** */ 109 public static final int RTT_STATUS_FAIL_NOT_SCHEDULED_YET = 4; 110 /** Timing measurement timeout*/ 111 public static final int RTT_STATUS_FAIL_TM_TIMEOUT = 5; 112 /** Destination is on a different channel from the RTT Request*/ 113 public static final int RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL = 6; 114 /** This type of Ranging is not support by Hardware*/ 115 public static final int RTT_STATUS_FAIL_NO_CAPABILITY = 7; 116 /** Request abort fro uncertain reason*/ 117 public static final int RTT_STATUS_ABORTED = 8; 118 /** The T1-T4 or TOD/TOA Timestamp is illegal*/ 119 public static final int RTT_STATUS_FAIL_INVALID_TS = 9; 120 /** 11mc protocol level failed, eg, unrecognized FTMR/FTM frame*/ 121 public static final int RTT_STATUS_FAIL_PROTOCOL = 10; 122 /** Request can not be scheduled by hardware*/ 123 public static final int RTT_STATUS_FAIL_SCHEDULE = 11; 124 /** destination is busy now, you can try after a specified time from destination*/ 125 public static final int RTT_STATUS_FAIL_BUSY_TRY_LATER = 12; 126 /** Bad Request argument*/ 127 public static final int RTT_STATUS_INVALID_REQ = 13; 128 /** Wifi is not enabled*/ 129 public static final int RTT_STATUS_NO_WIFI = 14; 130 /** Responder overrides param info, cannot range with new params 2-side RTT only*/ 131 public static final int RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE = 15; 132 133 public static final int REASON_UNSPECIFIED = -1; 134 public static final int REASON_NOT_AVAILABLE = -2; 135 public static final int REASON_INVALID_LISTENER = -3; 136 public static final int REASON_INVALID_REQUEST = -4; 137 138 public static final String DESCRIPTION_KEY = "android.net.wifi.RttManager.Description"; 139 140 /** 141 * RTT BW supported bit mask, used as RTT param bandWidth too 142 */ 143 public static final int RTT_BW_5_SUPPORT = 0x01; 144 public static final int RTT_BW_10_SUPPORT = 0x02; 145 public static final int RTT_BW_20_SUPPORT = 0x04; 146 public static final int RTT_BW_40_SUPPORT = 0x08; 147 public static final int RTT_BW_80_SUPPORT = 0x10; 148 public static final int RTT_BW_160_SUPPORT = 0x20; 149 150 /** 151 * RTT Preamble Support bit mask 152 */ 153 public static final int PREAMBLE_LEGACY = 0x01; 154 public static final int PREAMBLE_HT = 0x02; 155 public static final int PREAMBLE_VHT = 0x04; 156 157 /** @deprecated Use the new {@link android.net.wifi.RttManager.RttCapabilities} API */ 158 @Deprecated 159 public class Capabilities { 160 public int supportedType; 161 public int supportedPeerType; 162 } 163 164 /** @deprecated Use the new {@link android.net.wifi.RttManager#getRttCapabilities()} API.*/ 165 @Deprecated 166 public Capabilities getCapabilities() { 167 return new Capabilities(); 168 } 169 170 /** 171 * This class describe the RTT capability of the Hardware 172 */ 173 public static class RttCapabilities implements Parcelable { 174 /** @deprecated It is not supported*/ 175 @Deprecated 176 public boolean supportedType; 177 /** @deprecated It is not supported*/ 178 @Deprecated 179 public boolean supportedPeerType; 180 //1-sided rtt measurement is supported 181 public boolean oneSidedRttSupported; 182 //11mc 2-sided rtt measurement is supported 183 public boolean twoSided11McRttSupported; 184 //location configuration information supported 185 public boolean lciSupported; 186 //location civic records supported 187 public boolean lcrSupported; 188 //preamble supported, see bit mask definition above 189 public int preambleSupported; 190 //RTT bandwidth supported 191 public int bwSupported; 192 193 @Override 194 public String toString() { 195 StringBuffer sb = new StringBuffer(); 196 sb.append("oneSidedRtt "). 197 append(oneSidedRttSupported ? "is Supported. " : "is not supported. "). 198 append("twoSided11McRtt "). 199 append(twoSided11McRttSupported ? "is Supported. " : "is not supported. "). 200 append("lci "). 201 append(lciSupported ? "is Supported. " : "is not supported. "). 202 append("lcr "). 203 append(lcrSupported ? "is Supported. " : "is not supported. "); 204 205 if ((preambleSupported & PREAMBLE_LEGACY) != 0) { 206 sb.append("Legacy "); 207 } 208 209 if ((preambleSupported & PREAMBLE_HT) != 0) { 210 sb.append("HT "); 211 } 212 213 if ((preambleSupported & PREAMBLE_VHT) != 0) { 214 sb.append("VHT "); 215 } 216 217 sb.append("is supported. \n"); 218 219 if ((bwSupported & RTT_BW_5_SUPPORT) != 0) { 220 sb.append("5 MHz "); 221 } 222 223 if ((bwSupported & RTT_BW_10_SUPPORT) != 0) { 224 sb.append("10 MHz "); 225 } 226 227 if ((bwSupported & RTT_BW_20_SUPPORT) != 0) { 228 sb.append("20 MHz "); 229 } 230 231 if ((bwSupported & RTT_BW_40_SUPPORT) != 0) { 232 sb.append("40 MHz "); 233 } 234 235 if ((bwSupported & RTT_BW_80_SUPPORT) != 0) { 236 sb.append("80 MHz "); 237 } 238 239 if ((bwSupported & RTT_BW_160_SUPPORT) != 0) { 240 sb.append("160 MHz "); 241 } 242 243 sb.append("is supported."); 244 245 return sb.toString(); 246 } 247 /** Implement the Parcelable interface {@hide} */ 248 @Override 249 public int describeContents() { 250 return 0; 251 } 252 253 /** Implement the Parcelable interface {@hide} */ 254 @Override 255 public void writeToParcel(Parcel dest, int flags) { 256 dest.writeInt(oneSidedRttSupported ? 1 : 0); 257 dest.writeInt(twoSided11McRttSupported ? 1 : 0); 258 dest.writeInt(lciSupported ? 1 : 0); 259 dest.writeInt(lcrSupported ? 1 : 0); 260 dest.writeInt(preambleSupported); 261 dest.writeInt(bwSupported); 262 263 } 264 265 /** Implement the Parcelable interface {@hide} */ 266 public static final Creator<RttCapabilities> CREATOR = 267 new Creator<RttCapabilities>() { 268 public RttCapabilities createFromParcel(Parcel in) { 269 RttCapabilities capabilities = new RttCapabilities(); 270 capabilities.oneSidedRttSupported = in.readInt() == 1 ? true : false; 271 capabilities.twoSided11McRttSupported = in.readInt() == 1 ? true : false; 272 capabilities.lciSupported = in.readInt() == 1 ? true : false; 273 capabilities.lcrSupported = in.readInt() == 1 ? true : false; 274 capabilities.preambleSupported = in.readInt(); 275 capabilities.bwSupported = in.readInt(); 276 return capabilities; 277 } 278 /** Implement the Parcelable interface {@hide} */ 279 @Override 280 public RttCapabilities[] newArray(int size) { 281 return new RttCapabilities[size]; 282 } 283 }; 284 } 285 286 public RttCapabilities getRttCapabilities() { 287 synchronized (sCapabilitiesLock) { 288 if (mRttCapabilities == null) { 289 try { 290 mRttCapabilities = mService.getRttCapabilities(); 291 } catch (RemoteException e) { 292 Log.e(TAG, "Can not get RTT Capabilities"); 293 } 294 } 295 return mRttCapabilities; 296 } 297 } 298 299 /** specifies parameters for RTT request */ 300 public static class RttParams { 301 /** 302 * type of destination device being ranged 303 * currently only support RTT_PEER_TYPE_AP 304 * Range:RTT_PEER_TYPE_xxxx Default value:RTT_PEER_TYPE_AP 305 */ 306 public int deviceType; 307 308 /** 309 * type of RTT measurement method. Need check scan result and RttCapabilities first 310 * Range: RTT_TYPE_ONE_SIDED or RTT_TYPE_TWO_SIDED 311 * Default value: RTT_TYPE_ONE_SIDED 312 */ 313 public int requestType; 314 315 /** 316 * mac address of the device being ranged 317 * Default value: null 318 */ 319 public String bssid; 320 321 /** 322 * The primary control channel over which the client is 323 * communicating with the AP.Same as ScanResult.frequency 324 * Default value: 0 325 */ 326 public int frequency; 327 328 /** 329 * channel width of the destination AP. Same as ScanResult.channelWidth 330 * Default value: 0 331 */ 332 public int channelWidth; 333 334 /** 335 * Not used if the AP bandwidth is 20 MHz 336 * If the AP use 40, 80 or 160 MHz, this is the center frequency 337 * if the AP use 80 + 80 MHz, this is the center frequency of the first segment 338 * same as ScanResult.centerFreq0 339 * Default value: 0 340 */ 341 public int centerFreq0; 342 343 /** 344 * Only used if the AP bandwidth is 80 + 80 MHz 345 * if the AP use 80 + 80 MHz, this is the center frequency of the second segment 346 * same as ScanResult.centerFreq1 347 * Default value: 0 348 */ 349 public int centerFreq1; 350 351 /** 352 * number of samples to be taken 353 * @deprecated Use the new {@link android.net.wifi.RttManager.RttParams#numSamplesPerBurst} 354 */ 355 @Deprecated 356 public int num_samples; 357 358 /** 359 * number of retries if a sample fails 360 * @deprecated 361 * Use {@link android.net.wifi.RttManager.RttParams#numRetriesPerMeasurementFrame} API. 362 */ 363 @Deprecated 364 public int num_retries; 365 366 /** Number of burst in exp , 2^x. 0 means single shot measurement, range 0-15 367 * Currently only single shot is supported 368 * Default value: 0 369 */ 370 public int numberBurst; 371 372 /** 373 * valid only if numberBurst > 1, interval between burst(100ms). 374 * Range : 0-31, 0--means no specific 375 * Default value: 0 376 */ 377 public int interval; 378 379 /** 380 * number of samples to be taken in one burst 381 * Range: 1-31 382 * Default value: 8 383 */ 384 public int numSamplesPerBurst; 385 386 /** number of retries for each measurement frame if a sample fails 387 * Only used by single side RTT, 388 * Range 0 - 3 Default value: 0 389 */ 390 public int numRetriesPerMeasurementFrame; 391 392 /** 393 * number of retries for FTMR frame (control frame) if it fails. 394 * Only used by 80211MC double side RTT 395 * Range: 0-3 Default Value : 0 396 */ 397 public int numRetriesPerFTMR; 398 399 /** 400 * Request LCI information, only available when choose double side RTT measurement 401 * need check RttCapabilties first. 402 * Default value: false 403 * */ 404 public boolean LCIRequest; 405 406 /** 407 * Request LCR information, only available when choose double side RTT measurement 408 * need check RttCapabilties first. 409 * Default value: false 410 * */ 411 public boolean LCRRequest; 412 413 /** 414 * Timeout for each burst, (250 * 2^x) us, 415 * Range 1-11 and 15. 15 means no control Default value: 15 416 * */ 417 public int burstTimeout; 418 419 /** preamble used for RTT measurement 420 * Range: PREAMBLE_LEGACY, PREAMBLE_HT, PREAMBLE_VHT 421 * Default value: PREAMBLE_HT 422 */ 423 public int preamble; 424 425 /** bandWidth used for RTT measurement.User need verify the highest BW the destination 426 * support (from scan result etc) before set this value. Wider channels result usually give 427 * better accuracy. However, the frame loss can increase too. 428 * should be one of RTT_BW_5_SUPPORT to RTT_BW_160_SUPPORT. However, need check 429 * RttCapabilities firstto verify HW support this bandwidth. 430 * Default value:RTT_BW_20_SUPPORT 431 */ 432 public int bandwidth; 433 434 public RttParams() { 435 //provide initial value for RttParams 436 deviceType = RTT_PEER_TYPE_AP; 437 requestType = RTT_TYPE_ONE_SIDED; 438 numberBurst = 0; 439 numSamplesPerBurst = 8; 440 numRetriesPerMeasurementFrame = 0; 441 numRetriesPerFTMR = 0; 442 burstTimeout = 15; 443 preamble = PREAMBLE_HT; 444 bandwidth = RTT_BW_20_SUPPORT; 445 } 446 } 447 448 /** pseudo-private class used to parcel arguments */ 449 public static class ParcelableRttParams implements Parcelable { 450 451 public RttParams mParams[]; 452 453 ParcelableRttParams(RttParams[] params) { 454 mParams = params; 455 } 456 457 /** Implement the Parcelable interface {@hide} */ 458 public int describeContents() { 459 return 0; 460 } 461 462 /** Implement the Parcelable interface {@hide} */ 463 public void writeToParcel(Parcel dest, int flags) { 464 if (mParams != null) { 465 dest.writeInt(mParams.length); 466 467 for (RttParams params : mParams) { 468 dest.writeInt(params.deviceType); 469 dest.writeInt(params.requestType); 470 dest.writeString(params.bssid); 471 dest.writeInt(params.channelWidth); 472 dest.writeInt(params.frequency); 473 dest.writeInt(params.centerFreq0); 474 dest.writeInt(params.centerFreq1); 475 dest.writeInt(params.numberBurst); 476 dest.writeInt(params.interval); 477 dest.writeInt(params.numSamplesPerBurst); 478 dest.writeInt(params.numRetriesPerMeasurementFrame); 479 dest.writeInt(params.numRetriesPerFTMR); 480 dest.writeInt(params.LCIRequest ? 1 : 0); 481 dest.writeInt(params.LCRRequest ? 1 : 0); 482 dest.writeInt(params.burstTimeout); 483 dest.writeInt(params.preamble); 484 dest.writeInt(params.bandwidth); 485 } 486 } else { 487 dest.writeInt(0); 488 } 489 } 490 491 /** Implement the Parcelable interface {@hide} */ 492 public static final Creator<ParcelableRttParams> CREATOR = 493 new Creator<ParcelableRttParams>() { 494 public ParcelableRttParams createFromParcel(Parcel in) { 495 496 int num = in.readInt(); 497 498 if (num == 0) { 499 return new ParcelableRttParams(null); 500 } 501 502 RttParams params[] = new RttParams[num]; 503 for (int i = 0; i < num; i++) { 504 params[i] = new RttParams(); 505 params[i].deviceType = in.readInt(); 506 params[i].requestType = in.readInt(); 507 params[i].bssid = in.readString(); 508 params[i].channelWidth = in.readInt(); 509 params[i].frequency = in.readInt(); 510 params[i].centerFreq0 = in.readInt(); 511 params[i].centerFreq1 = in.readInt(); 512 params[i].numberBurst = in.readInt(); 513 params[i].interval = in.readInt(); 514 params[i].numSamplesPerBurst = in.readInt(); 515 params[i].numRetriesPerMeasurementFrame = in.readInt(); 516 params[i].numRetriesPerFTMR = in.readInt(); 517 params[i].LCIRequest = in.readInt() == 1 ? true : false; 518 params[i].LCRRequest = in.readInt() == 1 ? true : false; 519 params[i].burstTimeout = in.readInt(); 520 params[i].preamble = in.readInt(); 521 params[i].bandwidth = in.readInt(); 522 } 523 524 ParcelableRttParams parcelableParams = new ParcelableRttParams(params); 525 return parcelableParams; 526 } 527 528 public ParcelableRttParams[] newArray(int size) { 529 return new ParcelableRttParams[size]; 530 } 531 }; 532 } 533 534 public static class WifiInformationElement { 535 /** Information Element ID 0xFF means element is invalid. */ 536 public byte id; 537 public byte[] data; 538 } 539 /** specifies RTT results */ 540 public static class RttResult { 541 /** mac address of the device being ranged. */ 542 public String bssid; 543 544 /** # of burst for this measurement. */ 545 public int burstNumber; 546 547 /** total number of measurement frames attempted in this measurement. */ 548 public int measurementFrameNumber; 549 550 /** total successful number of measurement frames in this measurement. */ 551 public int successMeasurementFrameNumber; 552 553 /** 554 * Maximum number of frames per burst supported by peer. Two side RTT only 555 * Valid only if less than request 556 */ 557 public int frameNumberPerBurstPeer; 558 559 /** status of the request */ 560 public int status; 561 562 /** 563 * type of the request used 564 * @deprecated Use {@link android.net.wifi.RttManager.RttResult#measurementType} 565 */ 566 @Deprecated 567 public int requestType; 568 569 /** RTT measurement method type used, should be one of RTT_TYPE_ONE_SIDED or 570 * RTT_TYPE_TWO_SIDED. 571 */ 572 public int measurementType; 573 574 /** 575 * only valid when status == RTT_STATUS_FAIL_BUSY_TRY_LATER 576 * please retry RTT measurement after this duration since peer indicate busy at ths moment 577 * Unit S Range:1-31 578 */ 579 public int retryAfterDuration; 580 581 /** timestamp of completion, in microsecond since boot. */ 582 public long ts; 583 584 /** average RSSI observed, unit of 0.5 dB. */ 585 public int rssi; 586 587 /** 588 * RSSI spread (i.e. max - min) 589 * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rssiSpread} API. 590 */ 591 @Deprecated 592 public int rssi_spread; 593 594 /**RSSI spread (i.e. max - min), unit of 0.5 dB. */ 595 public int rssiSpread; 596 597 /** 598 * average transmit rate 599 * @deprecated Use {@link android.net.wifi.RttManager.RttResult#txRate} API. 600 */ 601 @Deprecated 602 public int tx_rate; 603 604 /** average transmit rate. Unit (100kbps). */ 605 public int txRate; 606 607 /** average receiving rate Unit (100kbps). */ 608 public int rxRate; 609 610 /** 611 * average round trip time in nano second 612 * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rtt} API. 613 */ 614 @Deprecated 615 public long rtt_ns; 616 617 /** average round trip time in 0.1 nano second. */ 618 public long rtt; 619 620 /** 621 * standard deviation observed in round trip time 622 * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rttStandardDeviation} API. 623 */ 624 @Deprecated 625 public long rtt_sd_ns; 626 627 /** standard deviation of RTT in 0.1 ns. */ 628 public long rttStandardDeviation; 629 630 /** 631 * spread (i.e. max - min) round trip time 632 * @deprecated Use {@link android.net.wifi.RttManager.RttResult#rttSpread} API. 633 */ 634 @Deprecated 635 public long rtt_spread_ns; 636 637 /** spread (i.e. max - min) RTT in 0.1 ns. */ 638 public long rttSpread; 639 640 /** 641 * average distance in centimeter, computed based on rtt_ns 642 * @deprecated use {@link android.net.wifi.RttManager.RttResult#distance} API. 643 */ 644 @Deprecated 645 public int distance_cm; 646 647 /** average distance in cm, computed based on rtt. */ 648 public int distance; 649 650 /** 651 * standard deviation observed in distance 652 * @deprecated 653 * Use {@link .android.net.wifi.RttManager.RttResult#distanceStandardDeviation} API. 654 */ 655 @Deprecated 656 public int distance_sd_cm; 657 658 /** standard deviation observed in distance in cm. */ 659 public int distanceStandardDeviation; 660 661 /** 662 * spread (i.e. max - min) distance 663 * @deprecate Use {@link android.net.wifi.RttManager.RttResult#distanceSpread} API. 664 */ 665 @Deprecated 666 public int distance_spread_cm; 667 668 /** spread (i.e. max - min) distance in cm. */ 669 public int distanceSpread; 670 671 /** the duration of this measurement burst, unit ms. */ 672 public int burstDuration; 673 674 /** Burst number supported by peer after negotiation, 2side RTT only*/ 675 public int negotiatedBurstNum; 676 677 /** LCI information Element, only available for double side RTT. */ 678 public WifiInformationElement LCI; 679 680 /** LCR information Element, only available to double side RTT. */ 681 public WifiInformationElement LCR; 682 } 683 684 685 /** pseudo-private class used to parcel results. */ 686 public static class ParcelableRttResults implements Parcelable { 687 688 public RttResult mResults[]; 689 690 public ParcelableRttResults(RttResult[] results) { 691 mResults = results; 692 } 693 694 /** Implement the Parcelable interface {@hide} */ 695 public int describeContents() { 696 return 0; 697 } 698 699 /** Implement the Parcelable interface {@hide} */ 700 public void writeToParcel(Parcel dest, int flags) { 701 if (mResults != null) { 702 dest.writeInt(mResults.length); 703 for (RttResult result : mResults) { 704 dest.writeString(result.bssid); 705 dest.writeInt(result.burstNumber); 706 dest.writeInt(result.measurementFrameNumber); 707 dest.writeInt(result.successMeasurementFrameNumber); 708 dest.writeInt(result.frameNumberPerBurstPeer); 709 dest.writeInt(result.status); 710 dest.writeInt(result.measurementType); 711 dest.writeInt(result.retryAfterDuration); 712 dest.writeLong(result.ts); 713 dest.writeInt(result.rssi); 714 dest.writeInt(result.rssiSpread); 715 dest.writeInt(result.txRate); 716 dest.writeLong(result.rtt); 717 dest.writeLong(result.rttStandardDeviation); 718 dest.writeLong(result.rttSpread); 719 dest.writeInt(result.distance); 720 dest.writeInt(result.distanceStandardDeviation); 721 dest.writeInt(result.distanceSpread); 722 dest.writeInt(result.burstDuration); 723 dest.writeInt(result.negotiatedBurstNum); 724 dest.writeByte(result.LCI.id); 725 if (result.LCI.id != (byte) 0xFF) { 726 dest.writeByte((byte)result.LCI.data.length); 727 dest.writeByteArray(result.LCI.data); 728 } 729 dest.writeByte(result.LCR.id); 730 if (result.LCR.id != (byte) 0xFF) { 731 dest.writeInt((byte) result.LCR.data.length); 732 dest.writeByte(result.LCR.id); 733 } 734 } 735 } else { 736 dest.writeInt(0); 737 } 738 } 739 740 /** Implement the Parcelable interface {@hide} */ 741 public static final Creator<ParcelableRttResults> CREATOR = 742 new Creator<ParcelableRttResults>() { 743 public ParcelableRttResults createFromParcel(Parcel in) { 744 745 int num = in.readInt(); 746 747 if (num == 0) { 748 return new ParcelableRttResults(null); 749 } 750 751 RttResult results[] = new RttResult[num]; 752 for (int i = 0; i < num; i++) { 753 results[i] = new RttResult(); 754 results[i].bssid = in.readString(); 755 results[i].burstNumber = in.readInt(); 756 results[i].measurementFrameNumber = in.readInt(); 757 results[i].successMeasurementFrameNumber = in.readInt(); 758 results[i].frameNumberPerBurstPeer = in.readInt(); 759 results[i].status = in.readInt(); 760 results[i].measurementType = in.readInt(); 761 results[i].retryAfterDuration = in.readInt(); 762 results[i].ts = in.readLong(); 763 results[i].rssi = in.readInt(); 764 results[i].rssiSpread = in.readInt(); 765 results[i].txRate = in.readInt(); 766 results[i].rtt = in.readLong(); 767 results[i].rttStandardDeviation = in.readLong(); 768 results[i].rttSpread = in.readLong(); 769 results[i].distance = in.readInt(); 770 results[i].distanceStandardDeviation = in.readInt(); 771 results[i].distanceSpread = in.readInt(); 772 results[i].burstDuration = in.readInt(); 773 results[i].negotiatedBurstNum = in.readInt(); 774 results[i].LCI = new WifiInformationElement(); 775 results[i].LCI.id = in.readByte(); 776 if (results[i].LCI.id != (byte) 0xFF) { 777 byte length = in.readByte(); 778 results[i].LCI.data = new byte[length]; 779 in.readByteArray(results[i].LCI.data); 780 } 781 results[i].LCR = new WifiInformationElement(); 782 results[i].LCR.id = in.readByte(); 783 if (results[i].LCR.id != (byte) 0xFF) { 784 byte length = in.readByte(); 785 results[i].LCR.data = new byte[length]; 786 in.readByteArray(results[i].LCR.data); 787 } 788 } 789 790 ParcelableRttResults parcelableResults = new ParcelableRttResults(results); 791 return parcelableResults; 792 } 793 794 public ParcelableRttResults[] newArray(int size) { 795 return new ParcelableRttResults[size]; 796 } 797 }; 798 } 799 800 801 public static interface RttListener { 802 public void onSuccess(RttResult[] results); 803 public void onFailure(int reason, String description); 804 public void onAborted(); 805 } 806 807 private boolean rttParamSanity(RttParams params, int index) { 808 if (mRttCapabilities == null) { 809 if(getRttCapabilities() == null) { 810 Log.e(TAG, "Can not get RTT capabilities"); 811 throw new IllegalStateException("RTT chip is not working"); 812 } 813 } 814 815 if (params.deviceType != RTT_PEER_TYPE_AP) { 816 return false; 817 } else if (params.requestType != RTT_TYPE_ONE_SIDED && params.requestType != 818 RTT_TYPE_TWO_SIDED) { 819 Log.e(TAG, "Request " + index + ": Illegal Request Type: " + params.requestType); 820 return false; 821 } else if (params.requestType == RTT_TYPE_ONE_SIDED && 822 !mRttCapabilities.oneSidedRttSupported) { 823 Log.e(TAG, "Request " + index + ": One side RTT is not supported"); 824 return false; 825 } else if (params.requestType == RTT_TYPE_TWO_SIDED && 826 !mRttCapabilities.twoSided11McRttSupported) { 827 Log.e(TAG, "Request " + index + ": two side RTT is not supported"); 828 return false; 829 } else if(params.bssid == null || params.bssid.isEmpty()) { 830 Log.e(TAG,"No BSSID is input"); 831 } else if ( params.numberBurst != 0 ) { 832 Log.e(TAG, "Request " + index + ": Illegal number of burst: " + params.numberBurst); 833 return false; 834 } else if (params.numSamplesPerBurst <= 0 || params.numSamplesPerBurst > 31) { 835 Log.e(TAG, "Request " + index + ": Illegal sample number per burst: " + 836 params.numSamplesPerBurst); 837 return false; 838 } else if (params.numRetriesPerMeasurementFrame < 0 || 839 params.numRetriesPerMeasurementFrame > 3) { 840 Log.e(TAG, "Request " + index + ": Illegal measurement frame retry number:" + 841 params.numRetriesPerMeasurementFrame); 842 return false; 843 } else if(params.numRetriesPerFTMR < 0 || 844 params.numRetriesPerFTMR > 3) { 845 Log.e(TAG, "Request " + index + ": Illegal FTMR frame retry number:" + 846 params.numRetriesPerFTMR); 847 return false; 848 } else if (params.LCIRequest && !mRttCapabilities.lciSupported) { 849 Log.e(TAG, "Request " + index + ": LCI is not supported"); 850 return false; 851 } else if (params.LCRRequest && !mRttCapabilities.lcrSupported) { 852 Log.e(TAG, "Request " + index + ": LCR is not supported"); 853 return false; 854 } else if (params.burstTimeout < 1 || 855 (params.burstTimeout > 11 && params.burstTimeout != 15)){ 856 Log.e(TAG, "Request " + index + ": Illegal burst timeout: " + params.burstTimeout); 857 return false; 858 } else if ((params.preamble & mRttCapabilities.preambleSupported) == 0) { 859 Log.e(TAG, "Request " + index + ": Do not support this preamble: " + params.preamble); 860 return false; 861 } else if ((params.bandwidth & mRttCapabilities.bwSupported) == 0) { 862 Log.e(TAG, "Request " + index + ": Do not support this bandwidth: " + params.bandwidth); 863 return false; 864 } 865 866 return true; 867 } 868 869 /** 870 * Request to start an RTT ranging 871 * 872 * @param params -- RTT request Parameters 873 * @param listener -- Call back to inform RTT result 874 * @exception throw IllegalArgumentException when params are illegal 875 * throw IllegalStateException when RttCapabilities do not exist 876 */ 877 878 public void startRanging(RttParams[] params, RttListener listener) { 879 int index = 0; 880 for(RttParams rttParam : params) { 881 if (!rttParamSanity(rttParam, index)) { 882 throw new IllegalArgumentException("RTT Request Parameter Illegal"); 883 } 884 index++; 885 } 886 887 validateChannel(); 888 ParcelableRttParams parcelableParams = new ParcelableRttParams(params); 889 sAsyncChannel.sendMessage(CMD_OP_START_RANGING, 890 0, putListener(listener), parcelableParams); 891 } 892 893 public void stopRanging(RttListener listener) { 894 validateChannel(); 895 sAsyncChannel.sendMessage(CMD_OP_STOP_RANGING, 0, removeListener(listener)); 896 } 897 898 /* private methods */ 899 public static final int BASE = Protocol.BASE_WIFI_RTT_MANAGER; 900 901 public static final int CMD_OP_START_RANGING = BASE + 0; 902 public static final int CMD_OP_STOP_RANGING = BASE + 1; 903 public static final int CMD_OP_FAILED = BASE + 2; 904 public static final int CMD_OP_SUCCEEDED = BASE + 3; 905 public static final int CMD_OP_ABORTED = BASE + 4; 906 907 private Context mContext; 908 private IRttManager mService; 909 private RttCapabilities mRttCapabilities; 910 911 private static final int INVALID_KEY = 0; 912 private static int sListenerKey = 1; 913 914 private static final SparseArray sListenerMap = new SparseArray(); 915 private static final Object sListenerMapLock = new Object(); 916 private static final Object sCapabilitiesLock = new Object(); 917 918 private static AsyncChannel sAsyncChannel; 919 private static CountDownLatch sConnected; 920 921 private static final Object sThreadRefLock = new Object(); 922 private static int sThreadRefCount; 923 private static HandlerThread sHandlerThread; 924 925 /** 926 * Create a new WifiScanner instance. 927 * Applications will almost always want to use 928 * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve 929 * the standard {@link android.content.Context#WIFI_RTT_SERVICE Context.WIFI_RTT_SERVICE}. 930 * @param context the application context 931 * @param service the Binder interface 932 * @hide 933 */ 934 935 public RttManager(Context context, IRttManager service) { 936 mContext = context; 937 mService = service; 938 init(); 939 } 940 941 private void init() { 942 synchronized (sThreadRefLock) { 943 if (++sThreadRefCount == 1) { 944 Messenger messenger = null; 945 try { 946 Log.d(TAG, "Get the messenger from " + mService); 947 messenger = mService.getMessenger(); 948 } catch (RemoteException e) { 949 /* do nothing */ 950 } catch (SecurityException e) { 951 /* do nothing */ 952 } 953 954 if (messenger == null) { 955 sAsyncChannel = null; 956 return; 957 } 958 959 sHandlerThread = new HandlerThread("WifiScanner"); 960 sAsyncChannel = new AsyncChannel(); 961 sConnected = new CountDownLatch(1); 962 963 sHandlerThread.start(); 964 Handler handler = new ServiceHandler(sHandlerThread.getLooper()); 965 sAsyncChannel.connect(mContext, handler, messenger); 966 try { 967 sConnected.await(); 968 } catch (InterruptedException e) { 969 Log.e(TAG, "interrupted wait at init"); 970 } 971 } 972 } 973 } 974 975 private void validateChannel() { 976 if (sAsyncChannel == null) throw new IllegalStateException( 977 "No permission to access and change wifi or a bad initialization"); 978 } 979 980 private static int putListener(Object listener) { 981 if (listener == null) return INVALID_KEY; 982 int key; 983 synchronized (sListenerMapLock) { 984 do { 985 key = sListenerKey++; 986 } while (key == INVALID_KEY); 987 sListenerMap.put(key, listener); 988 } 989 return key; 990 } 991 992 private static Object getListener(int key) { 993 if (key == INVALID_KEY) return null; 994 synchronized (sListenerMapLock) { 995 Object listener = sListenerMap.get(key); 996 return listener; 997 } 998 } 999 1000 private static int getListenerKey(Object listener) { 1001 if (listener == null) return INVALID_KEY; 1002 synchronized (sListenerMapLock) { 1003 int index = sListenerMap.indexOfValue(listener); 1004 if (index == -1) { 1005 return INVALID_KEY; 1006 } else { 1007 return sListenerMap.keyAt(index); 1008 } 1009 } 1010 } 1011 1012 private static Object removeListener(int key) { 1013 if (key == INVALID_KEY) return null; 1014 synchronized (sListenerMapLock) { 1015 Object listener = sListenerMap.get(key); 1016 sListenerMap.remove(key); 1017 return listener; 1018 } 1019 } 1020 1021 private static int removeListener(Object listener) { 1022 int key = getListenerKey(listener); 1023 if (key == INVALID_KEY) return key; 1024 synchronized (sListenerMapLock) { 1025 sListenerMap.remove(key); 1026 return key; 1027 } 1028 } 1029 1030 private static class ServiceHandler extends Handler { 1031 ServiceHandler(Looper looper) { 1032 super(looper); 1033 } 1034 @Override 1035 public void handleMessage(Message msg) { 1036 switch (msg.what) { 1037 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 1038 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 1039 sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); 1040 } else { 1041 Log.e(TAG, "Failed to set up channel connection"); 1042 // This will cause all further async API calls on the WifiManager 1043 // to fail and throw an exception 1044 sAsyncChannel = null; 1045 } 1046 sConnected.countDown(); 1047 return; 1048 case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: 1049 return; 1050 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: 1051 Log.e(TAG, "Channel connection lost"); 1052 // This will cause all further async API calls on the WifiManager 1053 // to fail and throw an exception 1054 sAsyncChannel = null; 1055 getLooper().quit(); 1056 return; 1057 } 1058 1059 Object listener = getListener(msg.arg2); 1060 if (listener == null) { 1061 if (DBG) Log.d(TAG, "invalid listener key = " + msg.arg2); 1062 return; 1063 } else { 1064 if (DBG) Log.d(TAG, "listener key = " + msg.arg2); 1065 } 1066 1067 switch (msg.what) { 1068 /* ActionListeners grouped together */ 1069 case CMD_OP_SUCCEEDED : 1070 reportSuccess(listener, msg); 1071 removeListener(msg.arg2); 1072 break; 1073 case CMD_OP_FAILED : 1074 reportFailure(listener, msg); 1075 removeListener(msg.arg2); 1076 break; 1077 case CMD_OP_ABORTED : 1078 ((RttListener) listener).onAborted(); 1079 removeListener(msg.arg2); 1080 break; 1081 default: 1082 if (DBG) Log.d(TAG, "Ignoring message " + msg.what); 1083 return; 1084 } 1085 } 1086 1087 void reportSuccess(Object listener, Message msg) { 1088 RttListener rttListener = (RttListener) listener; 1089 ParcelableRttResults parcelableResults = (ParcelableRttResults) msg.obj; 1090 ((RttListener) listener).onSuccess(parcelableResults.mResults); 1091 } 1092 1093 void reportFailure(Object listener, Message msg) { 1094 RttListener rttListener = (RttListener) listener; 1095 Bundle bundle = (Bundle) msg.obj; 1096 ((RttListener) listener).onFailure(msg.arg1, bundle.getString(DESCRIPTION_KEY)); 1097 } 1098 } 1099 1100} 1101 1102