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 */
CellSignalStrengthGsm()42     public CellSignalStrengthGsm() {
43         setDefaultValues();
44     }
45 
46     /** @hide */
CellSignalStrengthGsm(int ss, int ber)47     public CellSignalStrengthGsm(int ss, int ber) {
48         this(ss, ber, Integer.MAX_VALUE);
49     }
50 
51     /** @hide */
CellSignalStrengthGsm(int ss, int ber, int ta)52     public CellSignalStrengthGsm(int ss, int ber, int ta) {
53         mSignalStrength = ss;
54         mBitErrorRate = ber;
55         mTimingAdvance = ta;
56     }
57 
58     /** @hide */
CellSignalStrengthGsm(CellSignalStrengthGsm s)59     public CellSignalStrengthGsm(CellSignalStrengthGsm s) {
60         copyFrom(s);
61     }
62 
63     /** @hide */
copyFrom(CellSignalStrengthGsm s)64     protected void copyFrom(CellSignalStrengthGsm s) {
65         mSignalStrength = s.mSignalStrength;
66         mBitErrorRate = s.mBitErrorRate;
67         mTimingAdvance = s.mTimingAdvance;
68     }
69 
70     /** @hide */
71     @Override
copy()72     public CellSignalStrengthGsm copy() {
73         return new CellSignalStrengthGsm(this);
74     }
75 
76     /** @hide */
77     @Override
setDefaultValues()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
getLevel()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      */
getTimingAdvance()111     public int getTimingAdvance() {
112         return mTimingAdvance;
113     }
114 
115     /**
116      * Get the signal strength as dBm
117      */
118     @Override
getDbm()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
getAsuLevel()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
hashCode()149     public int hashCode() {
150         return Objects.hash(mSignalStrength, mBitErrorRate, mTimingAdvance);
151     }
152 
153     @Override
equals(Object o)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
toString()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
writeToParcel(Parcel dest, int flags)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      */
CellSignalStrengthGsm(Parcel in)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
describeContents()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      */
log(String s)226     private static void log(String s) {
227         Rlog.w(LOG_TAG, s);
228     }
229 }
230