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