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