• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.annotation.IntRange;
20 import android.annotation.UnsupportedAppUsage;
21 import android.os.Build;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.os.PersistableBundle;
25 import android.telephony.Rlog;
26 
27 import java.util.Objects;
28 
29 /**
30  * GSM signal strength related information.
31  */
32 public final class CellSignalStrengthGsm extends CellSignalStrength implements Parcelable {
33 
34     private static final String LOG_TAG = "CellSignalStrengthGsm";
35     private static final boolean DBG = false;
36 
37     private static final int GSM_RSSI_MAX = -51;
38     private static final int GSM_RSSI_GREAT = -89;
39     private static final int GSM_RSSI_GOOD = -97;
40     private static final int GSM_RSSI_MODERATE = -103;
41     private static final int GSM_RSSI_POOR = -107;
42     private static final int GSM_RSSI_MIN = -113;
43 
44     private static final int[] sRssiThresholds = new int[] {
45             GSM_RSSI_POOR, GSM_RSSI_MODERATE, GSM_RSSI_GOOD, GSM_RSSI_GREAT};
46 
47     private int mRssi; // in dBm [-113, -51] or UNAVAILABLE
48     @UnsupportedAppUsage
49     private int mBitErrorRate; // bit error rate (0-7, 99) TS 27.007 8.5 or UNAVAILABLE
50     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
51     private int mTimingAdvance; // range from 0-219 or CellInfo.UNAVAILABLE if unknown
52     private int mLevel;
53 
54     /** @hide */
55     @UnsupportedAppUsage
CellSignalStrengthGsm()56     public CellSignalStrengthGsm() {
57         setDefaultValues();
58     }
59 
60     /** @hide */
CellSignalStrengthGsm(int rssi, int ber, int ta)61     public CellSignalStrengthGsm(int rssi, int ber, int ta) {
62         mRssi = inRangeOrUnavailable(rssi, GSM_RSSI_MIN, GSM_RSSI_MAX);
63         mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99);
64         mTimingAdvance = inRangeOrUnavailable(ta, 0, 219);
65         updateLevel(null, null);
66     }
67 
68     /** @hide */
CellSignalStrengthGsm(android.hardware.radio.V1_0.GsmSignalStrength gsm)69     public CellSignalStrengthGsm(android.hardware.radio.V1_0.GsmSignalStrength gsm) {
70         // Convert from HAL values as part of construction.
71         this(getRssiDbmFromAsu(gsm.signalStrength), gsm.bitErrorRate, gsm.timingAdvance);
72 
73         if (mRssi == CellInfo.UNAVAILABLE) {
74             setDefaultValues();
75         }
76     }
77 
78     /** @hide */
CellSignalStrengthGsm(CellSignalStrengthGsm s)79     public CellSignalStrengthGsm(CellSignalStrengthGsm s) {
80         copyFrom(s);
81     }
82 
83     /** @hide */
copyFrom(CellSignalStrengthGsm s)84     protected void copyFrom(CellSignalStrengthGsm s) {
85         mRssi = s.mRssi;
86         mBitErrorRate = s.mBitErrorRate;
87         mTimingAdvance = s.mTimingAdvance;
88         mLevel = s.mLevel;
89     }
90 
91     /** @hide */
92     @Override
copy()93     public CellSignalStrengthGsm copy() {
94         return new CellSignalStrengthGsm(this);
95     }
96 
97     /** @hide */
98     @Override
setDefaultValues()99     public void setDefaultValues() {
100         mRssi = CellInfo.UNAVAILABLE;
101         mBitErrorRate = CellInfo.UNAVAILABLE;
102         mTimingAdvance = CellInfo.UNAVAILABLE;
103         mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
104     }
105 
106     /** {@inheritDoc} */
107     @Override
108     @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
getLevel()109     public int getLevel() {
110         return mLevel;
111     }
112 
113     /** @hide */
114     @Override
updateLevel(PersistableBundle cc, ServiceState ss)115     public void updateLevel(PersistableBundle cc, ServiceState ss) {
116         int[] rssiThresholds;
117         if (cc == null) {
118             rssiThresholds = sRssiThresholds;
119         } else {
120             rssiThresholds = cc.getIntArray(CarrierConfigManager.KEY_GSM_RSSI_THRESHOLDS_INT_ARRAY);
121             if (rssiThresholds == null || rssiThresholds.length != NUM_SIGNAL_STRENGTH_THRESHOLDS) {
122                 rssiThresholds = sRssiThresholds;
123             }
124         }
125         int level = NUM_SIGNAL_STRENGTH_THRESHOLDS;
126         if (mRssi < GSM_RSSI_MIN || mRssi > GSM_RSSI_MAX) {
127             mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
128             return;
129         }
130         while (level > 0 && mRssi < rssiThresholds[level - 1]) level--;
131         mLevel = level;
132     }
133 
134     /**
135      * Get the GSM timing advance between 0..219 symbols (normally 0..63).
136      * <p>{@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} is reported when there is no RR
137      * connection. Refer to 3GPP 45.010 Sec 5.8.
138      *
139      * @return the current GSM timing advance, if available.
140      */
getTimingAdvance()141     public int getTimingAdvance() {
142         return mTimingAdvance;
143     }
144 
145     /**
146      * Get the signal strength as dBm
147      */
148     @Override
getDbm()149     public int getDbm() {
150         return mRssi;
151     }
152 
153     /**
154      * Get the RSSI in ASU.
155      *
156      * Asu is calculated based on 3GPP RSSI. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
157      *
158      * @return RSSI in ASU 0..31, 99, or UNAVAILABLE
159      */
160     @Override
getAsuLevel()161     public int getAsuLevel() {
162         return getAsuFromRssiDbm(mRssi);
163     }
164 
165     /**
166      * Return the Received Signal Strength Indicator
167      *
168      * @return the RSSI in dBm (-113, -51) or
169      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}.
170      * @hide
171      */
getRssi()172     public int getRssi() {
173         return mRssi;
174     }
175 
176     /**
177      * Return the Bit Error Rate
178      *
179      * @return the bit error rate (0-7, 99) as defined in TS 27.007 8.5 or
180      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}.
181      */
getBitErrorRate()182     public int getBitErrorRate() {
183         return mBitErrorRate;
184     }
185 
186     @Override
hashCode()187     public int hashCode() {
188         return Objects.hash(mRssi, mBitErrorRate, mTimingAdvance);
189     }
190 
191     private static final CellSignalStrengthGsm sInvalid = new CellSignalStrengthGsm();
192 
193     /** @hide */
194     @Override
isValid()195     public boolean isValid() {
196         return !this.equals(sInvalid);
197     }
198 
199     @Override
equals(Object o)200     public boolean equals(Object o) {
201         if (!(o instanceof CellSignalStrengthGsm)) return false;
202         CellSignalStrengthGsm s = (CellSignalStrengthGsm) o;
203 
204         return mRssi == s.mRssi
205                 && mBitErrorRate == s.mBitErrorRate
206                 && mTimingAdvance == s.mTimingAdvance
207                 && mLevel == s.mLevel;
208     }
209 
210     /**
211      * @return string representation.
212      */
213     @Override
toString()214     public String toString() {
215         return "CellSignalStrengthGsm:"
216                 + " rssi=" + mRssi
217                 + " ber=" + mBitErrorRate
218                 + " mTa=" + mTimingAdvance
219                 + " mLevel=" + mLevel;
220     }
221 
222     /** Implement the Parcelable interface */
223     @Override
writeToParcel(Parcel dest, int flags)224     public void writeToParcel(Parcel dest, int flags) {
225         if (DBG) log("writeToParcel(Parcel, int): " + toString());
226         dest.writeInt(mRssi);
227         dest.writeInt(mBitErrorRate);
228         dest.writeInt(mTimingAdvance);
229         dest.writeInt(mLevel);
230     }
231 
232     /**
233      * Construct a SignalStrength object from the given parcel
234      * where the token is already been processed.
235      */
CellSignalStrengthGsm(Parcel in)236     private CellSignalStrengthGsm(Parcel in) {
237         mRssi = in.readInt();
238         mBitErrorRate = in.readInt();
239         mTimingAdvance = in.readInt();
240         mLevel = in.readInt();
241         if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString());
242     }
243 
244     /** Implement the Parcelable interface */
245     @Override
describeContents()246     public int describeContents() {
247         return 0;
248     }
249 
250     /** Implement the Parcelable interface */
251     @SuppressWarnings("hiding")
252     public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthGsm> CREATOR =
253             new Parcelable.Creator<CellSignalStrengthGsm>() {
254         @Override
255         public CellSignalStrengthGsm createFromParcel(Parcel in) {
256             return new CellSignalStrengthGsm(in);
257         }
258 
259         @Override
260         public CellSignalStrengthGsm[] newArray(int size) {
261             return new CellSignalStrengthGsm[size];
262         }
263     };
264 
265     /**
266      * log
267      */
log(String s)268     private static void log(String s) {
269         Rlog.w(LOG_TAG, s);
270     }
271 }
272