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.Parcel;
     20 import android.os.Parcelable;
     21 import android.telephony.Rlog;
     22 
     23 import java.util.Objects;
     24 
     25 /**
     26  * GSM signal strength related information.
     27  */
     28 public final class CellSignalStrengthGsm extends CellSignalStrength implements Parcelable {
     29 
     30     private static final String LOG_TAG = "CellSignalStrengthGsm";
     31     private static final boolean DBG = false;
     32 
     33     private static final int GSM_SIGNAL_STRENGTH_GREAT = 12;
     34     private static final int GSM_SIGNAL_STRENGTH_GOOD = 8;
     35     private static final int GSM_SIGNAL_STRENGTH_MODERATE = 5;
     36 
     37     private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
     38     private int mBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
     39     private int mTimingAdvance; // range from 0-219 or Integer.MAX_VALUE if unknown
     40 
     41     /** @hide */
     42     public CellSignalStrengthGsm() {
     43         setDefaultValues();
     44     }
     45 
     46     /** @hide */
     47     public CellSignalStrengthGsm(int ss, int ber) {
     48         this(ss, ber, Integer.MAX_VALUE);
     49     }
     50 
     51     /** @hide */
     52     public CellSignalStrengthGsm(int ss, int ber, int ta) {
     53         mSignalStrength = ss;
     54         mBitErrorRate = ber;
     55         mTimingAdvance = ta;
     56     }
     57 
     58     /** @hide */
     59     public CellSignalStrengthGsm(CellSignalStrengthGsm s) {
     60         copyFrom(s);
     61     }
     62 
     63     /** @hide */
     64     protected void copyFrom(CellSignalStrengthGsm s) {
     65         mSignalStrength = s.mSignalStrength;
     66         mBitErrorRate = s.mBitErrorRate;
     67         mTimingAdvance = s.mTimingAdvance;
     68     }
     69 
     70     /** @hide */
     71     @Override
     72     public CellSignalStrengthGsm copy() {
     73         return new CellSignalStrengthGsm(this);
     74     }
     75 
     76     /** @hide */
     77     @Override
     78     public void setDefaultValues() {
     79         mSignalStrength = Integer.MAX_VALUE;
     80         mBitErrorRate = Integer.MAX_VALUE;
     81         mTimingAdvance = Integer.MAX_VALUE;
     82     }
     83 
     84     /**
     85      * Get signal level as an int from 0..4
     86      */
     87     @Override
     88     public int getLevel() {
     89         int level;
     90 
     91         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
     92         // asu = 0 (-113dB or less) is very weak
     93         // signal, its better to show 0 bars to the user in such cases.
     94         // asu = 99 is a special case, where the signal strength is unknown.
     95         int asu = mSignalStrength;
     96         if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     97         else if (asu >= GSM_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT;
     98         else if (asu >= GSM_SIGNAL_STRENGTH_GOOD)  level = SIGNAL_STRENGTH_GOOD;
     99         else if (asu >= GSM_SIGNAL_STRENGTH_MODERATE)  level = SIGNAL_STRENGTH_MODERATE;
    100         else level = SIGNAL_STRENGTH_POOR;
    101         if (DBG) log("getLevel=" + level);
    102         return level;
    103     }
    104 
    105     /**
    106      * Get the GSM timing advance between 0..219 symbols (normally 0..63).
    107      * Integer.MAX_VALUE is reported when there is no RR connection.
    108      * Refer to 3GPP 45.010 Sec 5.8
    109      * @return the current GSM timing advance, if available.
    110      */
    111     public int getTimingAdvance() {
    112         return mTimingAdvance;
    113     }
    114 
    115     /**
    116      * Get the signal strength as dBm
    117      */
    118     @Override
    119     public int getDbm() {
    120         int dBm;
    121 
    122         int level = mSignalStrength;
    123         int asu = (level == 99 ? Integer.MAX_VALUE : level);
    124         if (asu != Integer.MAX_VALUE) {
    125             dBm = -113 + (2 * asu);
    126         } else {
    127             dBm = Integer.MAX_VALUE;
    128         }
    129         if (DBG) log("getDbm=" + dBm);
    130         return dBm;
    131     }
    132 
    133     /**
    134      * Get the signal level as an asu value between 0..31, 99 is unknown
    135      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
    136      */
    137     @Override
    138     public int getAsuLevel() {
    139         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
    140         // asu = 0 (-113dB or less) is very weak
    141         // signal, its better to show 0 bars to the user in such cases.
    142         // asu = 99 is a special case, where the signal strength is unknown.
    143         int level = mSignalStrength;
    144         if (DBG) log("getAsuLevel=" + level);
    145         return level;
    146     }
    147 
    148     @Override
    149     public int hashCode() {
    150         return Objects.hash(mSignalStrength, mBitErrorRate, mTimingAdvance);
    151     }
    152 
    153     @Override
    154     public boolean equals (Object o) {
    155         CellSignalStrengthGsm s;
    156 
    157         try {
    158             s = (CellSignalStrengthGsm) o;
    159         } catch (ClassCastException ex) {
    160             return false;
    161         }
    162 
    163         if (o == null) {
    164             return false;
    165         }
    166 
    167         return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate &&
    168                         s.mTimingAdvance == mTimingAdvance;
    169     }
    170 
    171     /**
    172      * @return string representation.
    173      */
    174     @Override
    175     public String toString() {
    176         return "CellSignalStrengthGsm:"
    177                 + " ss=" + mSignalStrength
    178                 + " ber=" + mBitErrorRate
    179                 + " mTa=" + mTimingAdvance;
    180     }
    181 
    182     /** Implement the Parcelable interface */
    183     @Override
    184     public void writeToParcel(Parcel dest, int flags) {
    185         if (DBG) log("writeToParcel(Parcel, int): " + toString());
    186         dest.writeInt(mSignalStrength);
    187         dest.writeInt(mBitErrorRate);
    188         dest.writeInt(mTimingAdvance);
    189     }
    190 
    191     /**
    192      * Construct a SignalStrength object from the given parcel
    193      * where the token is already been processed.
    194      */
    195     private CellSignalStrengthGsm(Parcel in) {
    196         mSignalStrength = in.readInt();
    197         mBitErrorRate = in.readInt();
    198         mTimingAdvance = in.readInt();
    199         if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString());
    200     }
    201 
    202     /** Implement the Parcelable interface */
    203     @Override
    204     public int describeContents() {
    205         return 0;
    206     }
    207 
    208     /** Implement the Parcelable interface */
    209     @SuppressWarnings("hiding")
    210     public static final Parcelable.Creator<CellSignalStrengthGsm> CREATOR =
    211             new Parcelable.Creator<CellSignalStrengthGsm>() {
    212         @Override
    213         public CellSignalStrengthGsm createFromParcel(Parcel in) {
    214             return new CellSignalStrengthGsm(in);
    215         }
    216 
    217         @Override
    218         public CellSignalStrengthGsm[] newArray(int size) {
    219             return new CellSignalStrengthGsm[size];
    220         }
    221     };
    222 
    223     /**
    224      * log
    225      */
    226     private static void log(String s) {
    227         Rlog.w(LOG_TAG, s);
    228     }
    229 }
    230