Home | History | Annotate | Download | only in telephony
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.telephony;
     18 
     19 import android.os.Bundle;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 import android.telephony.Rlog;
     23 import android.util.Log;
     24 import android.content.res.Resources;
     25 
     26 /**
     27  * Contains phone signal strength related information.
     28  */
     29 public class SignalStrength implements Parcelable {
     30 
     31     private static final String LOG_TAG = "SignalStrength";
     32     private static final boolean DBG = false;
     33 
     34     /** @hide */
     35     public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
     36     /** @hide */
     37     public static final int SIGNAL_STRENGTH_POOR = 1;
     38     /** @hide */
     39     public static final int SIGNAL_STRENGTH_MODERATE = 2;
     40     /** @hide */
     41     public static final int SIGNAL_STRENGTH_GOOD = 3;
     42     /** @hide */
     43     public static final int SIGNAL_STRENGTH_GREAT = 4;
     44     /** @hide */
     45     public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
     46     /** @hide */
     47     public static final String[] SIGNAL_STRENGTH_NAMES = {
     48         "none", "poor", "moderate", "good", "great"
     49     };
     50 
     51     /** @hide */
     52     //Use int max, as -1 is a valid value in signal strength
     53     public static final int INVALID = 0x7FFFFFFF;
     54 
     55     private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
     56     private int mGsmBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
     57     private int mCdmaDbm;   // This value is the RSSI value
     58     private int mCdmaEcio;  // This value is the Ec/Io
     59     private int mEvdoDbm;   // This value is the EVDO RSSI value
     60     private int mEvdoEcio;  // This value is the EVDO Ec/Io
     61     private int mEvdoSnr;   // Valid values are 0-8.  8 is the highest signal to noise ratio
     62     private int mLteSignalStrength;
     63     private int mLteRsrp;
     64     private int mLteRsrq;
     65     private int mLteRssnr;
     66     private int mLteCqi;
     67     private int mLteRsrpBoost; // offset to be reduced from the rsrp threshold while calculating
     68                                 // signal strength level
     69     private int mTdScdmaRscp;
     70 
     71     private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
     72 
     73     /**
     74      * Create a new SignalStrength from a intent notifier Bundle
     75      *
     76      * This method is used by PhoneStateIntentReceiver and maybe by
     77      * external applications.
     78      *
     79      * @param m Bundle from intent notifier
     80      * @return newly created SignalStrength
     81      *
     82      * @hide
     83      */
     84     public static SignalStrength newFromBundle(Bundle m) {
     85         SignalStrength ret;
     86         ret = new SignalStrength();
     87         ret.setFromNotifierBundle(m);
     88         return ret;
     89     }
     90 
     91     /**
     92      * Empty constructor
     93      *
     94      * @hide
     95      */
     96     public SignalStrength() {
     97         mGsmSignalStrength = 99;
     98         mGsmBitErrorRate = -1;
     99         mCdmaDbm = -1;
    100         mCdmaEcio = -1;
    101         mEvdoDbm = -1;
    102         mEvdoEcio = -1;
    103         mEvdoSnr = -1;
    104         mLteSignalStrength = 99;
    105         mLteRsrp = INVALID;
    106         mLteRsrq = INVALID;
    107         mLteRssnr = INVALID;
    108         mLteCqi = INVALID;
    109         mLteRsrpBoost = 0;
    110         mTdScdmaRscp = INVALID;
    111         isGsm = true;
    112     }
    113 
    114     /**
    115      * This constructor is used to create SignalStrength with default
    116      * values and set the isGsmFlag with the value passed in the input
    117      *
    118      * @param gsmFlag true if Gsm Phone,false if Cdma phone
    119      * @return newly created SignalStrength
    120      * @hide
    121      */
    122     public SignalStrength(boolean gsmFlag) {
    123         mGsmSignalStrength = 99;
    124         mGsmBitErrorRate = -1;
    125         mCdmaDbm = -1;
    126         mCdmaEcio = -1;
    127         mEvdoDbm = -1;
    128         mEvdoEcio = -1;
    129         mEvdoSnr = -1;
    130         mLteSignalStrength = 99;
    131         mLteRsrp = INVALID;
    132         mLteRsrq = INVALID;
    133         mLteRssnr = INVALID;
    134         mLteCqi = INVALID;
    135         mLteRsrpBoost = 0;
    136         mTdScdmaRscp = INVALID;
    137         isGsm = gsmFlag;
    138     }
    139 
    140     /**
    141      * Constructor
    142      *
    143      * @hide
    144      */
    145     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
    146             int cdmaDbm, int cdmaEcio,
    147             int evdoDbm, int evdoEcio, int evdoSnr,
    148             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
    149             int lteRsrpBoost, int tdScdmaRscp, boolean gsmFlag) {
    150         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
    151                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
    152                 lteRsrq, lteRssnr, lteCqi, lteRsrpBoost, gsmFlag);
    153         mTdScdmaRscp = tdScdmaRscp;
    154     }
    155 
    156     /**
    157      * Constructor
    158      *
    159      * @hide
    160      */
    161     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
    162             int cdmaDbm, int cdmaEcio,
    163             int evdoDbm, int evdoEcio, int evdoSnr,
    164             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
    165             int tdScdmaRscp, boolean gsmFlag) {
    166         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
    167                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
    168                 lteRsrq, lteRssnr, lteCqi, 0, gsmFlag);
    169         mTdScdmaRscp = tdScdmaRscp;
    170     }
    171 
    172     /**
    173      * Constructor
    174      *
    175      * @hide
    176      */
    177     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
    178             int cdmaDbm, int cdmaEcio,
    179             int evdoDbm, int evdoEcio, int evdoSnr,
    180             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
    181             boolean gsmFlag) {
    182         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
    183                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
    184                 lteRsrq, lteRssnr, lteCqi, 0, gsmFlag);
    185     }
    186 
    187     /**
    188      * Constructor
    189      *
    190      * @hide
    191      */
    192     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
    193             int cdmaDbm, int cdmaEcio,
    194             int evdoDbm, int evdoEcio, int evdoSnr,
    195             boolean gsmFlag) {
    196         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
    197                 evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
    198                 INVALID, INVALID, INVALID, 0, gsmFlag);
    199     }
    200 
    201     /**
    202      * Copy constructors
    203      *
    204      * @param s Source SignalStrength
    205      *
    206      * @hide
    207      */
    208     public SignalStrength(SignalStrength s) {
    209         copyFrom(s);
    210     }
    211 
    212     /**
    213      * Initialize gsm/cdma values, sets lte values to defaults.
    214      *
    215      * @param gsmSignalStrength
    216      * @param gsmBitErrorRate
    217      * @param cdmaDbm
    218      * @param cdmaEcio
    219      * @param evdoDbm
    220      * @param evdoEcio
    221      * @param evdoSnr
    222      * @param gsm
    223      *
    224      * @hide
    225      */
    226     public void initialize(int gsmSignalStrength, int gsmBitErrorRate,
    227             int cdmaDbm, int cdmaEcio,
    228             int evdoDbm, int evdoEcio, int evdoSnr,
    229             boolean gsm) {
    230         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
    231                 evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
    232                 INVALID, INVALID, INVALID, 0, gsm);
    233     }
    234 
    235     /**
    236      * Initialize all the values
    237      *
    238      * @param gsmSignalStrength
    239      * @param gsmBitErrorRate
    240      * @param cdmaDbm
    241      * @param cdmaEcio
    242      * @param evdoDbm
    243      * @param evdoEcio
    244      * @param evdoSnr
    245      * @param lteSignalStrength
    246      * @param lteRsrp
    247      * @param lteRsrq
    248      * @param lteRssnr
    249      * @param lteCqi
    250      * @param lteRsrpBoost
    251      * @param gsm
    252      *
    253      * @hide
    254      */
    255     public void initialize(int gsmSignalStrength, int gsmBitErrorRate,
    256             int cdmaDbm, int cdmaEcio,
    257             int evdoDbm, int evdoEcio, int evdoSnr,
    258             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
    259             int lteRsrpBoost, boolean gsm) {
    260         mGsmSignalStrength = gsmSignalStrength;
    261         mGsmBitErrorRate = gsmBitErrorRate;
    262         mCdmaDbm = cdmaDbm;
    263         mCdmaEcio = cdmaEcio;
    264         mEvdoDbm = evdoDbm;
    265         mEvdoEcio = evdoEcio;
    266         mEvdoSnr = evdoSnr;
    267         mLteSignalStrength = lteSignalStrength;
    268         mLteRsrp = lteRsrp;
    269         mLteRsrq = lteRsrq;
    270         mLteRssnr = lteRssnr;
    271         mLteCqi = lteCqi;
    272         mLteRsrpBoost = lteRsrpBoost;
    273         mTdScdmaRscp = INVALID;
    274         isGsm = gsm;
    275         if (DBG) log("initialize: " + toString());
    276     }
    277 
    278     /**
    279      * @hide
    280      */
    281     protected void copyFrom(SignalStrength s) {
    282         mGsmSignalStrength = s.mGsmSignalStrength;
    283         mGsmBitErrorRate = s.mGsmBitErrorRate;
    284         mCdmaDbm = s.mCdmaDbm;
    285         mCdmaEcio = s.mCdmaEcio;
    286         mEvdoDbm = s.mEvdoDbm;
    287         mEvdoEcio = s.mEvdoEcio;
    288         mEvdoSnr = s.mEvdoSnr;
    289         mLteSignalStrength = s.mLteSignalStrength;
    290         mLteRsrp = s.mLteRsrp;
    291         mLteRsrq = s.mLteRsrq;
    292         mLteRssnr = s.mLteRssnr;
    293         mLteCqi = s.mLteCqi;
    294         mLteRsrpBoost = s.mLteRsrpBoost;
    295         mTdScdmaRscp = s.mTdScdmaRscp;
    296         isGsm = s.isGsm;
    297     }
    298 
    299     /**
    300      * Construct a SignalStrength object from the given parcel.
    301      *
    302      * @hide
    303      */
    304     public SignalStrength(Parcel in) {
    305         if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
    306 
    307         mGsmSignalStrength = in.readInt();
    308         mGsmBitErrorRate = in.readInt();
    309         mCdmaDbm = in.readInt();
    310         mCdmaEcio = in.readInt();
    311         mEvdoDbm = in.readInt();
    312         mEvdoEcio = in.readInt();
    313         mEvdoSnr = in.readInt();
    314         mLteSignalStrength = in.readInt();
    315         mLteRsrp = in.readInt();
    316         mLteRsrq = in.readInt();
    317         mLteRssnr = in.readInt();
    318         mLteCqi = in.readInt();
    319         mLteRsrpBoost = in.readInt();
    320         mTdScdmaRscp = in.readInt();
    321         isGsm = (in.readInt() != 0);
    322     }
    323 
    324     /**
    325      * Make a SignalStrength object from the given parcel as passed up by
    326      * the ril which does not have isGsm. isGsm will be changed by ServiceStateTracker
    327      * so the default is a don't care.
    328      *
    329      * @hide
    330      */
    331     public static SignalStrength makeSignalStrengthFromRilParcel(Parcel in) {
    332         if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
    333 
    334         SignalStrength ss = new SignalStrength();
    335         ss.mGsmSignalStrength = in.readInt();
    336         ss.mGsmBitErrorRate = in.readInt();
    337         ss.mCdmaDbm = in.readInt();
    338         ss.mCdmaEcio = in.readInt();
    339         ss.mEvdoDbm = in.readInt();
    340         ss.mEvdoEcio = in.readInt();
    341         ss.mEvdoSnr = in.readInt();
    342         ss.mLteSignalStrength = in.readInt();
    343         ss.mLteRsrp = in.readInt();
    344         ss.mLteRsrq = in.readInt();
    345         ss.mLteRssnr = in.readInt();
    346         ss.mLteCqi = in.readInt();
    347         ss.mTdScdmaRscp = in.readInt();
    348         return ss;
    349     }
    350 
    351     /**
    352      * {@link Parcelable#writeToParcel}
    353      */
    354     public void writeToParcel(Parcel out, int flags) {
    355         out.writeInt(mGsmSignalStrength);
    356         out.writeInt(mGsmBitErrorRate);
    357         out.writeInt(mCdmaDbm);
    358         out.writeInt(mCdmaEcio);
    359         out.writeInt(mEvdoDbm);
    360         out.writeInt(mEvdoEcio);
    361         out.writeInt(mEvdoSnr);
    362         out.writeInt(mLteSignalStrength);
    363         out.writeInt(mLteRsrp);
    364         out.writeInt(mLteRsrq);
    365         out.writeInt(mLteRssnr);
    366         out.writeInt(mLteCqi);
    367         out.writeInt(mLteRsrpBoost);
    368         out.writeInt(mTdScdmaRscp);
    369         out.writeInt(isGsm ? 1 : 0);
    370     }
    371 
    372     /**
    373      * {@link Parcelable#describeContents}
    374      */
    375     public int describeContents() {
    376         return 0;
    377     }
    378 
    379     /**
    380      * {@link Parcelable.Creator}
    381      *
    382      * @hide
    383      */
    384     public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() {
    385         public SignalStrength createFromParcel(Parcel in) {
    386             return new SignalStrength(in);
    387         }
    388 
    389         public SignalStrength[] newArray(int size) {
    390             return new SignalStrength[size];
    391         }
    392     };
    393 
    394     /**
    395      * Validate the individual signal strength fields as per the range
    396      * specified in ril.h
    397      * Set to invalid any field that is not in the valid range
    398      * Cdma, evdo, lte rsrp & rsrq values are sign converted
    399      * when received from ril interface
    400      *
    401      * @return
    402      *      Valid values for all signalstrength fields
    403      * @hide
    404      */
    405     public void validateInput() {
    406         if (DBG) log("Signal before validate=" + this);
    407         // TS 27.007 8.5
    408         mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
    409         // BER no change;
    410 
    411         mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
    412         mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160;
    413 
    414         mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
    415         mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -1;
    416         mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
    417 
    418         // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
    419         mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
    420         mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID;
    421         mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
    422         mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
    423                 : SignalStrength.INVALID;
    424 
    425         mTdScdmaRscp = ((mTdScdmaRscp >= 25) && (mTdScdmaRscp <= 120))
    426                 ? -mTdScdmaRscp : SignalStrength.INVALID;
    427         // Cqi no change
    428         if (DBG) log("Signal after validate=" + this);
    429     }
    430 
    431     /**
    432      * @param true - Gsm, Lte phones
    433      *        false - Cdma phones
    434      *
    435      * Used by voice phone to set the isGsm
    436      *        flag
    437      * @hide
    438      */
    439     public void setGsm(boolean gsmFlag) {
    440         isGsm = gsmFlag;
    441     }
    442 
    443     /**
    444      * @param lteRsrpBoost - signal strength offset
    445      *
    446      * Used by phone to set the lte signal strength offset which will be
    447      * reduced from rsrp threshold while calculating signal strength level
    448      *
    449      * @hide
    450      */
    451     public void setLteRsrpBoost(int lteRsrpBoost) {
    452         mLteRsrpBoost = lteRsrpBoost;
    453     }
    454 
    455     /**
    456      * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
    457      * 27.007 8.5
    458      */
    459     public int getGsmSignalStrength() {
    460         return this.mGsmSignalStrength;
    461     }
    462 
    463     /**
    464      * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5
    465      */
    466     public int getGsmBitErrorRate() {
    467         return this.mGsmBitErrorRate;
    468     }
    469 
    470     /**
    471      * Get the CDMA RSSI value in dBm
    472      */
    473     public int getCdmaDbm() {
    474         return this.mCdmaDbm;
    475     }
    476 
    477     /**
    478      * Get the CDMA Ec/Io value in dB*10
    479      */
    480     public int getCdmaEcio() {
    481         return this.mCdmaEcio;
    482     }
    483 
    484     /**
    485      * Get the EVDO RSSI value in dBm
    486      */
    487     public int getEvdoDbm() {
    488         return this.mEvdoDbm;
    489     }
    490 
    491     /**
    492      * Get the EVDO Ec/Io value in dB*10
    493      */
    494     public int getEvdoEcio() {
    495         return this.mEvdoEcio;
    496     }
    497 
    498     /**
    499      * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
    500      */
    501     public int getEvdoSnr() {
    502         return this.mEvdoSnr;
    503     }
    504 
    505     /** @hide */
    506     public int getLteSignalStrength() {
    507         return mLteSignalStrength;
    508     }
    509 
    510     /** @hide */
    511     public int getLteRsrp() {
    512         return mLteRsrp;
    513     }
    514 
    515     /** @hide */
    516     public int getLteRsrq() {
    517         return mLteRsrq;
    518     }
    519 
    520     /** @hide */
    521     public int getLteRssnr() {
    522         return mLteRssnr;
    523     }
    524 
    525     /** @hide */
    526     public int getLteCqi() {
    527         return mLteCqi;
    528     }
    529 
    530     /** @hide */
    531     public int getLteRsrpBoost() {
    532         return mLteRsrpBoost;
    533     }
    534 
    535     /**
    536      * Retrieve an abstract level value for the overall signal strength.
    537      *
    538      * @return a single integer from 0 to 4 representing the general signal quality.
    539      *     This may take into account many different radio technology inputs.
    540      *     0 represents very poor signal strength
    541      *     while 4 represents a very strong signal strength.
    542      */
    543     public int getLevel() {
    544         int level = 0;
    545 
    546         if (isGsm) {
    547             level = getLteLevel();
    548             if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    549                 level = getTdScdmaLevel();
    550                 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    551                     level = getGsmLevel();
    552                 }
    553             }
    554         } else {
    555             int cdmaLevel = getCdmaLevel();
    556             int evdoLevel = getEvdoLevel();
    557             if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    558                 /* We don't know evdo, use cdma */
    559                 level = cdmaLevel;
    560             } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    561                 /* We don't know cdma, use evdo */
    562                 level = evdoLevel;
    563             } else {
    564                 /* We know both, use the lowest level */
    565                 level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
    566             }
    567         }
    568         if (DBG) log("getLevel=" + level);
    569         return level;
    570     }
    571 
    572     /**
    573      * Get the signal level as an asu value between 0..31, 99 is unknown
    574      *
    575      * @hide
    576      */
    577     public int getAsuLevel() {
    578         int asuLevel = 0;
    579         if (isGsm) {
    580             if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    581                 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    582                     asuLevel = getGsmAsuLevel();
    583                 } else {
    584                     asuLevel = getTdScdmaAsuLevel();
    585                 }
    586             } else {
    587                 asuLevel = getLteAsuLevel();
    588             }
    589         } else {
    590             int cdmaAsuLevel = getCdmaAsuLevel();
    591             int evdoAsuLevel = getEvdoAsuLevel();
    592             if (evdoAsuLevel == 0) {
    593                 /* We don't know evdo use, cdma */
    594                 asuLevel = cdmaAsuLevel;
    595             } else if (cdmaAsuLevel == 0) {
    596                 /* We don't know cdma use, evdo */
    597                 asuLevel = evdoAsuLevel;
    598             } else {
    599                 /* We know both, use the lowest level */
    600                 asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel;
    601             }
    602         }
    603         if (DBG) log("getAsuLevel=" + asuLevel);
    604         return asuLevel;
    605     }
    606 
    607     /**
    608      * Get the signal strength as dBm
    609      *
    610      * @hide
    611      */
    612     public int getDbm() {
    613         int dBm = INVALID;
    614 
    615         if(isGsm()) {
    616             dBm = getLteDbm();
    617             if (dBm == INVALID) {
    618                 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    619                     dBm = getGsmDbm();
    620                 } else {
    621                     dBm = getTdScdmaDbm();
    622                 }
    623             }
    624         } else {
    625             int cdmaDbm = getCdmaDbm();
    626             int evdoDbm = getEvdoDbm();
    627 
    628             return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm
    629                     : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm));
    630         }
    631         if (DBG) log("getDbm=" + dBm);
    632         return dBm;
    633     }
    634 
    635     /**
    636      * Get Gsm signal strength as dBm
    637      *
    638      * @hide
    639      */
    640     public int getGsmDbm() {
    641         int dBm;
    642 
    643         int gsmSignalStrength = getGsmSignalStrength();
    644         int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
    645         if (asu != -1) {
    646             dBm = -113 + (2 * asu);
    647         } else {
    648             dBm = -1;
    649         }
    650         if (DBG) log("getGsmDbm=" + dBm);
    651         return dBm;
    652     }
    653 
    654     /**
    655      * Get gsm as level 0..4
    656      *
    657      * @hide
    658      */
    659     public int getGsmLevel() {
    660         int level;
    661 
    662         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
    663         // asu = 0 (-113dB or less) is very weak
    664         // signal, its better to show 0 bars to the user in such cases.
    665         // asu = 99 is a special case, where the signal strength is unknown.
    666         int asu = getGsmSignalStrength();
    667         if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    668         else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
    669         else if (asu >= 8)  level = SIGNAL_STRENGTH_GOOD;
    670         else if (asu >= 5)  level = SIGNAL_STRENGTH_MODERATE;
    671         else level = SIGNAL_STRENGTH_POOR;
    672         if (DBG) log("getGsmLevel=" + level);
    673         return level;
    674     }
    675 
    676     /**
    677      * Get the gsm signal level as an asu value between 0..31, 99 is unknown
    678      *
    679      * @hide
    680      */
    681     public int getGsmAsuLevel() {
    682         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
    683         // asu = 0 (-113dB or less) is very weak
    684         // signal, its better to show 0 bars to the user in such cases.
    685         // asu = 99 is a special case, where the signal strength is unknown.
    686         int level = getGsmSignalStrength();
    687         if (DBG) log("getGsmAsuLevel=" + level);
    688         return level;
    689     }
    690 
    691     /**
    692      * Get cdma as level 0..4
    693      *
    694      * @hide
    695      */
    696     public int getCdmaLevel() {
    697         final int cdmaDbm = getCdmaDbm();
    698         final int cdmaEcio = getCdmaEcio();
    699         int levelDbm;
    700         int levelEcio;
    701 
    702         if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
    703         else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
    704         else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
    705         else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
    706         else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    707 
    708         // Ec/Io are in dB*10
    709         if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
    710         else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
    711         else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
    712         else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
    713         else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    714 
    715         int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
    716         if (DBG) log("getCdmaLevel=" + level);
    717         return level;
    718     }
    719 
    720     /**
    721      * Get the cdma signal level as an asu value between 0..31, 99 is unknown
    722      *
    723      * @hide
    724      */
    725     public int getCdmaAsuLevel() {
    726         final int cdmaDbm = getCdmaDbm();
    727         final int cdmaEcio = getCdmaEcio();
    728         int cdmaAsuLevel;
    729         int ecioAsuLevel;
    730 
    731         if (cdmaDbm >= -75) cdmaAsuLevel = 16;
    732         else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
    733         else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
    734         else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
    735         else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
    736         else cdmaAsuLevel = 99;
    737 
    738         // Ec/Io are in dB*10
    739         if (cdmaEcio >= -90) ecioAsuLevel = 16;
    740         else if (cdmaEcio >= -100) ecioAsuLevel = 8;
    741         else if (cdmaEcio >= -115) ecioAsuLevel = 4;
    742         else if (cdmaEcio >= -130) ecioAsuLevel = 2;
    743         else if (cdmaEcio >= -150) ecioAsuLevel = 1;
    744         else ecioAsuLevel = 99;
    745 
    746         int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
    747         if (DBG) log("getCdmaAsuLevel=" + level);
    748         return level;
    749     }
    750 
    751     /**
    752      * Get Evdo as level 0..4
    753      *
    754      * @hide
    755      */
    756     public int getEvdoLevel() {
    757         int evdoDbm = getEvdoDbm();
    758         int evdoSnr = getEvdoSnr();
    759         int levelEvdoDbm;
    760         int levelEvdoSnr;
    761 
    762         if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
    763         else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
    764         else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
    765         else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
    766         else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    767 
    768         if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
    769         else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
    770         else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
    771         else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
    772         else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    773 
    774         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
    775         if (DBG) log("getEvdoLevel=" + level);
    776         return level;
    777     }
    778 
    779     /**
    780      * Get the evdo signal level as an asu value between 0..31, 99 is unknown
    781      *
    782      * @hide
    783      */
    784     public int getEvdoAsuLevel() {
    785         int evdoDbm = getEvdoDbm();
    786         int evdoSnr = getEvdoSnr();
    787         int levelEvdoDbm;
    788         int levelEvdoSnr;
    789 
    790         if (evdoDbm >= -65) levelEvdoDbm = 16;
    791         else if (evdoDbm >= -75) levelEvdoDbm = 8;
    792         else if (evdoDbm >= -85) levelEvdoDbm = 4;
    793         else if (evdoDbm >= -95) levelEvdoDbm = 2;
    794         else if (evdoDbm >= -105) levelEvdoDbm = 1;
    795         else levelEvdoDbm = 99;
    796 
    797         if (evdoSnr >= 7) levelEvdoSnr = 16;
    798         else if (evdoSnr >= 6) levelEvdoSnr = 8;
    799         else if (evdoSnr >= 5) levelEvdoSnr = 4;
    800         else if (evdoSnr >= 3) levelEvdoSnr = 2;
    801         else if (evdoSnr >= 1) levelEvdoSnr = 1;
    802         else levelEvdoSnr = 99;
    803 
    804         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
    805         if (DBG) log("getEvdoAsuLevel=" + level);
    806         return level;
    807     }
    808 
    809     /**
    810      * Get LTE as dBm
    811      *
    812      * @hide
    813      */
    814     public int getLteDbm() {
    815         return mLteRsrp;
    816     }
    817 
    818     /**
    819      * Get LTE as level 0..4
    820      *
    821      * @hide
    822      */
    823     public int getLteLevel() {
    824         /*
    825          * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
    826          * signal + noise RSRP = reference signal dBm RSRQ = quality of signal
    827          * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
    828          * = -10log P1/P2 dB
    829          */
    830         int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
    831 
    832         int[] threshRsrp = Resources.getSystem().getIntArray(
    833                 com.android.internal.R.array.config_lteDbmThresholds);
    834         if (threshRsrp.length != 6) {
    835             Log.wtf(LOG_TAG, "getLteLevel - config_lteDbmThresholds has invalid num of elements."
    836                     + " Cannot evaluate RSRP signal.");
    837         } else {
    838             if (mLteRsrp > threshRsrp[5]) {
    839                 rsrpIconLevel = -1;
    840             } else if (mLteRsrp >= (threshRsrp[4] - mLteRsrpBoost)) {
    841                 rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
    842             } else if (mLteRsrp >= (threshRsrp[3] - mLteRsrpBoost)) {
    843                 rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
    844             } else if (mLteRsrp >= (threshRsrp[2] - mLteRsrpBoost)) {
    845                 rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
    846             } else if (mLteRsrp >= (threshRsrp[1] - mLteRsrpBoost)) {
    847                 rsrpIconLevel = SIGNAL_STRENGTH_POOR;
    848             } else if (mLteRsrp >= threshRsrp[0]) {
    849                 rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    850             }
    851         }
    852 
    853         /*
    854          * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
    855          * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
    856          * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
    857          * Icon Only
    858          */
    859         if (mLteRssnr > 300) snrIconLevel = -1;
    860         else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
    861         else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
    862         else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
    863         else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
    864         else if (mLteRssnr >= -200)
    865             snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    866 
    867         if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
    868                 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
    869                 + " lteRsrpBoost:" + mLteRsrpBoost);
    870 
    871         /* Choose a measurement type to use for notification */
    872         if (snrIconLevel != -1 && rsrpIconLevel != -1) {
    873             /*
    874              * The number of bars displayed shall be the smaller of the bars
    875              * associated with LTE RSRP and the bars associated with the LTE
    876              * RS_SNR
    877              */
    878             return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
    879         }
    880 
    881         if (snrIconLevel != -1) return snrIconLevel;
    882 
    883         if (rsrpIconLevel != -1) return rsrpIconLevel;
    884 
    885         /* Valid values are (0-63, 99) as defined in TS 36.331 */
    886         if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    887         else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
    888         else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
    889         else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
    890         else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
    891 
    892         if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
    893                 + rssiIconLevel);
    894         return rssiIconLevel;
    895 
    896     }
    897     /**
    898      * Get the LTE signal level as an asu value between 0..97, 99 is unknown
    899      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
    900      *
    901      * @hide
    902      */
    903     public int getLteAsuLevel() {
    904         int lteAsuLevel = 99;
    905         int lteDbm = getLteDbm();
    906         /*
    907          * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
    908          * 0   -140 dBm or less
    909          * 1   -139 dBm
    910          * 2...96  -138... -44 dBm
    911          * 97  -43 dBm or greater
    912          * 255 not known or not detectable
    913          */
    914         /*
    915          * validateInput will always give a valid range between -140 t0 -44 as
    916          * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255
    917          * and not 97 or 0
    918          */
    919         if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255;
    920         else lteAsuLevel = lteDbm + 140;
    921         if (DBG) log("Lte Asu level: "+lteAsuLevel);
    922         return lteAsuLevel;
    923     }
    924 
    925     /**
    926      * @return true if this is for GSM
    927      */
    928     public boolean isGsm() {
    929         return this.isGsm;
    930     }
    931 
    932     /**
    933      * @return get TD_SCDMA dbm
    934      *
    935      * @hide
    936      */
    937     public int getTdScdmaDbm() {
    938         return this.mTdScdmaRscp;
    939     }
    940 
    941     /**
    942      * Get TD-SCDMA as level 0..4
    943      * Range : 25 to 120
    944      * INT_MAX: 0x7FFFFFFF denotes invalid value
    945      * Reference: 3GPP TS 25.123, section 9.1.1.1
    946      *
    947      * @hide
    948      */
    949     public int getTdScdmaLevel() {
    950         final int tdScdmaDbm = getTdScdmaDbm();
    951         int level;
    952 
    953         if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
    954                 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    955         else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
    956         else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
    957         else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
    958         else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR;
    959         else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    960 
    961         if (DBG) log("getTdScdmaLevel = " + level);
    962         return level;
    963      }
    964 
    965     /**
    966      * Get the TD-SCDMA signal level as an asu value.
    967      *
    968      * @hide
    969      */
    970     public int getTdScdmaAsuLevel() {
    971         final int tdScdmaDbm = getTdScdmaDbm();
    972         int tdScdmaAsuLevel;
    973 
    974         if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
    975         else tdScdmaAsuLevel = tdScdmaDbm + 120;
    976         if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
    977         return tdScdmaAsuLevel;
    978     }
    979 
    980    /**
    981      * @return hash code
    982      */
    983     @Override
    984     public int hashCode() {
    985         int primeNum = 31;
    986         return ((mGsmSignalStrength * primeNum)
    987                 + (mGsmBitErrorRate * primeNum)
    988                 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum)
    989                 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
    990                 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
    991                 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
    992                 + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0));
    993     }
    994 
    995     /**
    996      * @return true if the signal strengths are the same
    997      */
    998     @Override
    999     public boolean equals (Object o) {
   1000         SignalStrength s;
   1001 
   1002         try {
   1003             s = (SignalStrength) o;
   1004         } catch (ClassCastException ex) {
   1005             return false;
   1006         }
   1007 
   1008         if (o == null) {
   1009             return false;
   1010         }
   1011 
   1012         return (mGsmSignalStrength == s.mGsmSignalStrength
   1013                 && mGsmBitErrorRate == s.mGsmBitErrorRate
   1014                 && mCdmaDbm == s.mCdmaDbm
   1015                 && mCdmaEcio == s.mCdmaEcio
   1016                 && mEvdoDbm == s.mEvdoDbm
   1017                 && mEvdoEcio == s.mEvdoEcio
   1018                 && mEvdoSnr == s.mEvdoSnr
   1019                 && mLteSignalStrength == s.mLteSignalStrength
   1020                 && mLteRsrp == s.mLteRsrp
   1021                 && mLteRsrq == s.mLteRsrq
   1022                 && mLteRssnr == s.mLteRssnr
   1023                 && mLteCqi == s.mLteCqi
   1024                 && mLteRsrpBoost == s.mLteRsrpBoost
   1025                 && mTdScdmaRscp == s.mTdScdmaRscp
   1026                 && isGsm == s.isGsm);
   1027     }
   1028 
   1029     /**
   1030      * @return string representation.
   1031      */
   1032     @Override
   1033     public String toString() {
   1034         return ("SignalStrength:"
   1035                 + " " + mGsmSignalStrength
   1036                 + " " + mGsmBitErrorRate
   1037                 + " " + mCdmaDbm
   1038                 + " " + mCdmaEcio
   1039                 + " " + mEvdoDbm
   1040                 + " " + mEvdoEcio
   1041                 + " " + mEvdoSnr
   1042                 + " " + mLteSignalStrength
   1043                 + " " + mLteRsrp
   1044                 + " " + mLteRsrq
   1045                 + " " + mLteRssnr
   1046                 + " " + mLteCqi
   1047                 + " " + mLteRsrpBoost
   1048                 + " " + mTdScdmaRscp
   1049                 + " " + (isGsm ? "gsm|lte" : "cdma"));
   1050     }
   1051 
   1052     /**
   1053      * Set SignalStrength based on intent notifier map
   1054      *
   1055      * @param m intent notifier map
   1056      * @hide
   1057      */
   1058     private void setFromNotifierBundle(Bundle m) {
   1059         mGsmSignalStrength = m.getInt("GsmSignalStrength");
   1060         mGsmBitErrorRate = m.getInt("GsmBitErrorRate");
   1061         mCdmaDbm = m.getInt("CdmaDbm");
   1062         mCdmaEcio = m.getInt("CdmaEcio");
   1063         mEvdoDbm = m.getInt("EvdoDbm");
   1064         mEvdoEcio = m.getInt("EvdoEcio");
   1065         mEvdoSnr = m.getInt("EvdoSnr");
   1066         mLteSignalStrength = m.getInt("LteSignalStrength");
   1067         mLteRsrp = m.getInt("LteRsrp");
   1068         mLteRsrq = m.getInt("LteRsrq");
   1069         mLteRssnr = m.getInt("LteRssnr");
   1070         mLteCqi = m.getInt("LteCqi");
   1071         mLteRsrpBoost = m.getInt("lteRsrpBoost");
   1072         mTdScdmaRscp = m.getInt("TdScdma");
   1073         isGsm = m.getBoolean("isGsm");
   1074     }
   1075 
   1076     /**
   1077      * Set intent notifier Bundle based on SignalStrength
   1078      *
   1079      * @param m intent notifier Bundle
   1080      * @hide
   1081      */
   1082     public void fillInNotifierBundle(Bundle m) {
   1083         m.putInt("GsmSignalStrength", mGsmSignalStrength);
   1084         m.putInt("GsmBitErrorRate", mGsmBitErrorRate);
   1085         m.putInt("CdmaDbm", mCdmaDbm);
   1086         m.putInt("CdmaEcio", mCdmaEcio);
   1087         m.putInt("EvdoDbm", mEvdoDbm);
   1088         m.putInt("EvdoEcio", mEvdoEcio);
   1089         m.putInt("EvdoSnr", mEvdoSnr);
   1090         m.putInt("LteSignalStrength", mLteSignalStrength);
   1091         m.putInt("LteRsrp", mLteRsrp);
   1092         m.putInt("LteRsrq", mLteRsrq);
   1093         m.putInt("LteRssnr", mLteRssnr);
   1094         m.putInt("LteCqi", mLteCqi);
   1095         m.putInt("lteRsrpBoost", mLteRsrpBoost);
   1096         m.putInt("TdScdma", mTdScdmaRscp);
   1097         m.putBoolean("isGsm", isGsm);
   1098     }
   1099 
   1100     /**
   1101      * log
   1102      */
   1103     private static void log(String s) {
   1104         Rlog.w(LOG_TAG, s);
   1105     }
   1106 }
   1107