Home | History | Annotate | Download | only in wifi
      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
    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
    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
    267         public int describeContents() {
    268             return 0;
    269         }
    270 
    271         /** Implement the Parcelable interface {@hide} */
    272         @Override
    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 
    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 
    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
    487         public ParcelableRttParams(RttParams[] params) {
    488             mParams = (params == null ? new RttParams[0] : params);
    489         }
    490 
    491         /** Implement the Parcelable interface {@hide} */
    492         @Override
    493         public int describeContents() {
    494             return 0;
    495         }
    496 
    497         /** Implement the Parcelable interface {@hide} */
    498         @Override
    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 
    726         public ParcelableRttResults(RttResult[] results) {
    727             mResults = results;
    728         }
    729 
    730         /** Implement the Parcelable interface {@hide} */
    731         @Override
    732         public int describeContents() {
    733             return 0;
    734         }
    735 
    736         /** Implement the Parcelable interface {@hide} */
    737         @Override
    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 {
    844         public void onSuccess(RttResult[] results);
    845         public void onFailure(int reason, String description);
    846         public void onAborted();
    847     }
    848 
    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 
    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 
    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. */
    952         public abstract void onResponderEnabled(ResponderConfig config);
    953         /** Callback when enabling responder failed. */
    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      */
    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      */
    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
   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
   1058         public int describeContents() {
   1059             return 0;
   1060         }
   1061 
   1062         @Override
   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      */
   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 
   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 
   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.
   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 
   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 
   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 
   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 
   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 {
   1230         ServiceHandler(Looper looper) {
   1231             super(looper);
   1232         }
   1233         @Override
   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 
   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 
   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