• 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.Parcel;
22 import android.os.Parcelable;
23 import android.os.PersistableBundle;
24 
25 import java.util.Arrays;
26 import java.util.Objects;
27 
28 /**
29  * LTE signal strength related information.
30  */
31 public final class CellSignalStrengthLte extends CellSignalStrength implements Parcelable {
32 
33     private static final String LOG_TAG = "CellSignalStrengthLte";
34     private static final boolean DBG = false;
35 
36     /**
37      * Indicates the unknown or undetectable RSSI value in ASU.
38      *
39      * Reference: TS 27.007 8.5 - Signal quality +CSQ
40      */
41     private static final int SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN = 99;
42     /**
43      * Indicates the maximum valid RSSI value in ASU.
44      *
45      * Reference: TS 27.007 8.5 - Signal quality +CSQ
46      */
47     private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE = 31;
48     /**
49      * Indicates the minimum valid RSSI value in ASU.
50      *
51      * Reference: TS 27.007 8.5 - Signal quality +CSQ
52      */
53     private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0;
54 
55     private static final int MAX_LTE_RSRP = -44;
56     private static final int MIN_LTE_RSRP = -140;
57 
58     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
59     private int mSignalStrength; // To be removed
60     private int mRssi;
61     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
62     private int mRsrp;
63     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
64     private int mRsrq;
65     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
66     private int mRssnr;
67     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
68     private int mCqi;
69     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
70     private int mTimingAdvance;
71     private int mLevel;
72 
73     /** @hide */
74     @UnsupportedAppUsage
CellSignalStrengthLte()75     public CellSignalStrengthLte() {
76         setDefaultValues();
77     }
78 
79     /**
80      * Construct a cell signal strength
81      *
82      * @param rssi in dBm [-113,-51], UNKNOWN
83      * @param rsrp in dBm [-140,-43], UNKNOWN
84      * @param rsrq in dB [-20,-3], UNKNOWN
85      * @param rssnr in 10*dB [-200, +300], UNKNOWN
86      * @param cqi [0, 15], UNKNOWN
87      * @param timingAdvance [0, 1282], UNKNOWN
88      *
89      */
90     /** @hide */
CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi, int timingAdvance)91     public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi,
92             int timingAdvance) {
93 
94         mRssi = inRangeOrUnavailable(rssi, -113, -51);
95         mSignalStrength = mRssi;
96         mRsrp = inRangeOrUnavailable(rsrp, -140, -43);
97         mRsrq = inRangeOrUnavailable(rsrq, -20, -3);
98         mRssnr = inRangeOrUnavailable(rssnr, -200, 300);
99         mCqi = inRangeOrUnavailable(cqi, 0, 15);
100         mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
101         updateLevel(null, null);
102     }
103 
104     /** @hide */
CellSignalStrengthLte(android.hardware.radio.V1_0.LteSignalStrength lte)105     public CellSignalStrengthLte(android.hardware.radio.V1_0.LteSignalStrength lte) {
106         // Convert from HAL values as part of construction.
107         this(convertRssiAsuToDBm(lte.signalStrength),
108                 lte.rsrp != CellInfo.UNAVAILABLE ? -lte.rsrp : lte.rsrp,
109                 lte.rsrq != CellInfo.UNAVAILABLE ? -lte.rsrq : lte.rsrq,
110                 lte.rssnr, lte.cqi, lte.timingAdvance);
111     }
112 
113     /** @hide */
CellSignalStrengthLte(CellSignalStrengthLte s)114     public CellSignalStrengthLte(CellSignalStrengthLte s) {
115         copyFrom(s);
116     }
117 
118     /** @hide */
copyFrom(CellSignalStrengthLte s)119     protected void copyFrom(CellSignalStrengthLte s) {
120         mSignalStrength = s.mSignalStrength;
121         mRssi = s.mRssi;
122         mRsrp = s.mRsrp;
123         mRsrq = s.mRsrq;
124         mRssnr = s.mRssnr;
125         mCqi = s.mCqi;
126         mTimingAdvance = s.mTimingAdvance;
127         mLevel = s.mLevel;
128     }
129 
130     /** @hide */
131     @Override
copy()132     public CellSignalStrengthLte copy() {
133         return new CellSignalStrengthLte(this);
134     }
135 
136     /** @hide */
137     @Override
setDefaultValues()138     public void setDefaultValues() {
139         mSignalStrength = CellInfo.UNAVAILABLE;
140         mRssi = CellInfo.UNAVAILABLE;
141         mRsrp = CellInfo.UNAVAILABLE;
142         mRsrq = CellInfo.UNAVAILABLE;
143         mRssnr = CellInfo.UNAVAILABLE;
144         mCqi = CellInfo.UNAVAILABLE;
145         mTimingAdvance = CellInfo.UNAVAILABLE;
146         mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
147     }
148 
149     /** {@inheritDoc} */
150     @Override
151     @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
getLevel()152     public int getLevel() {
153         return mLevel;
154     }
155 
156     // Lifted from Default carrier configs and max range of RSRP
157     private static final int[] sThresholds = new int[]{-115, -105, -95, -85};
158     private static final int sRsrpBoost = 0;
159 
160     /** @hide */
161     @Override
updateLevel(PersistableBundle cc, ServiceState ss)162     public void updateLevel(PersistableBundle cc, ServiceState ss) {
163         int[] thresholds;
164         boolean rsrpOnly;
165         if (cc == null) {
166             thresholds = sThresholds;
167             rsrpOnly = false;
168         } else {
169             rsrpOnly = cc.getBoolean(
170                     CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, false);
171             thresholds = cc.getIntArray(
172                     CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
173             if (thresholds == null) thresholds = sThresholds;
174             if (DBG) log("updateLevel() carrierconfig - rsrpOnly="
175                     + rsrpOnly + ", thresholds=" + Arrays.toString(thresholds));
176         }
177 
178 
179         int rsrpBoost = 0;
180         if (ss != null) {
181             rsrpBoost = ss.getLteEarfcnRsrpBoost();
182         }
183 
184         int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
185         int rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
186         int snrIconLevel = -1;
187 
188         int rsrp = mRsrp + rsrpBoost;
189 
190         if (rsrp < MIN_LTE_RSRP || rsrp > MAX_LTE_RSRP) {
191             rsrpIconLevel = -1;
192         } else {
193             rsrpIconLevel = thresholds.length;
194             while (rsrpIconLevel > 0 && rsrp < thresholds[rsrpIconLevel - 1]) rsrpIconLevel--;
195         }
196 
197         if (rsrpOnly) {
198             if (DBG) log("updateLevel() - rsrp = " + rsrpIconLevel);
199             if (rsrpIconLevel != -1) {
200                 mLevel = rsrpIconLevel;
201                 return;
202             }
203         }
204 
205         /*
206          * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
207          * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
208          * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
209          * Icon Only
210          */
211         if (mRssnr > 300) snrIconLevel = -1;
212         else if (mRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
213         else if (mRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
214         else if (mRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
215         else if (mRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
216         else if (mRssnr >= -200)
217             snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
218 
219         if (DBG) log("updateLevel() - rsrp:" + mRsrp + " snr:" + mRssnr + " rsrpIconLevel:"
220                 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
221                 + " lteRsrpBoost:" + sRsrpBoost);
222 
223         /* Choose a measurement type to use for notification */
224         if (snrIconLevel != -1 && rsrpIconLevel != -1) {
225             /*
226              * The number of bars displayed shall be the smaller of the bars
227              * associated with LTE RSRP and the bars associated with the LTE
228              * RS_SNR
229              */
230             mLevel = (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
231             return;
232         }
233 
234         if (snrIconLevel != -1) {
235             mLevel = snrIconLevel;
236             return;
237         }
238 
239         if (rsrpIconLevel != -1) {
240             mLevel = rsrpIconLevel;
241             return;
242         }
243 
244         if (mRssi > -51) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
245         else if (mRssi >= -89) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
246         else if (mRssi >= -97) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
247         else if (mRssi >= -103) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
248         else if (mRssi >= -113) rssiIconLevel = SIGNAL_STRENGTH_POOR;
249         else rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
250         if (DBG) log("getLteLevel - rssi:" + mRssi + " rssiIconLevel:"
251                 + rssiIconLevel);
252         mLevel = rssiIconLevel;
253     }
254 
255     /**
256      * Get reference signal received quality
257      *
258      * @return the RSRQ if available or
259      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
260      */
getRsrq()261     public int getRsrq() {
262         return mRsrq;
263     }
264 
265     /**
266      * Get Received Signal Strength Indication (RSSI) in dBm
267      *
268      * The value range is [-113, -51] inclusively or {@link CellInfo#UNAVAILABLE} if unavailable.
269      *
270      * Reference: TS 27.007 8.5 Signal quality +CSQ
271      *
272      * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable.
273      */
getRssi()274     public int getRssi() {
275         return mRssi;
276     }
277 
278     /**
279      * Get reference signal signal-to-noise ratio
280      *
281      * @return the RSSNR if available or
282      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
283      */
getRssnr()284     public int getRssnr() {
285         return mRssnr;
286     }
287 
288     /**
289      * Get reference signal received power in dBm
290      *
291      * @return the RSRP of the measured cell.
292      */
getRsrp()293     public int getRsrp() {
294         return mRsrp;
295     }
296 
297     /**
298      * Get channel quality indicator
299      *
300      * @return the CQI if available or
301      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
302      */
getCqi()303     public int getCqi() {
304         return mCqi;
305     }
306 
307     /**
308      * Get signal strength in dBm
309      *
310      * @return the RSRP of the measured cell.
311      */
312     @Override
getDbm()313     public int getDbm() {
314         return mRsrp;
315     }
316 
317     /**
318      * Get the RSRP in ASU.
319      *
320      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
321      *
322      * @return RSCP in ASU 0..97, 255, or UNAVAILABLE
323      */
324     @Override
getAsuLevel()325     public int getAsuLevel() {
326         int lteAsuLevel = 99;
327         int lteDbm = mRsrp;
328         if (lteDbm == CellInfo.UNAVAILABLE) lteAsuLevel = 99;
329         else if (lteDbm <= -140) lteAsuLevel = 0;
330         else if (lteDbm >= -43) lteAsuLevel = 97;
331         else lteAsuLevel = lteDbm + 140;
332         if (DBG) log("Lte Asu level: "+lteAsuLevel);
333         return lteAsuLevel;
334     }
335 
336     /**
337      * Get the timing advance value for LTE, as a value in range of 0..1282.
338      * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} is reported when there is no
339      * active RRC connection. Refer to 3GPP 36.213 Sec 4.2.3
340      *
341      * @return the LTE timing advance if available or
342      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
343      */
getTimingAdvance()344     public int getTimingAdvance() {
345         return mTimingAdvance;
346     }
347 
348     @Override
hashCode()349     public int hashCode() {
350         return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance, mLevel);
351     }
352 
353     private static final CellSignalStrengthLte sInvalid = new CellSignalStrengthLte();
354 
355     /** @hide */
356     @Override
isValid()357     public boolean isValid() {
358         return !this.equals(sInvalid);
359     }
360 
361     @Override
equals(Object o)362     public boolean equals (Object o) {
363         CellSignalStrengthLte s;
364 
365         if (!(o instanceof CellSignalStrengthLte)) return false;
366         s = (CellSignalStrengthLte) o;
367 
368         return mRssi == s.mRssi
369                 && mRsrp == s.mRsrp
370                 && mRsrq == s.mRsrq
371                 && mRssnr == s.mRssnr
372                 && mCqi == s.mCqi
373                 && mTimingAdvance == s.mTimingAdvance
374                 && mLevel == s.mLevel;
375     }
376 
377     /**
378      * @return string representation.
379      */
380     @Override
toString()381     public String toString() {
382         return "CellSignalStrengthLte:"
383                 + " rssi=" + mRssi
384                 + " rsrp=" + mRsrp
385                 + " rsrq=" + mRsrq
386                 + " rssnr=" + mRssnr
387                 + " cqi=" + mCqi
388                 + " ta=" + mTimingAdvance
389                 + " level=" + mLevel;
390     }
391 
392     /** Implement the Parcelable interface */
393     @Override
writeToParcel(Parcel dest, int flags)394     public void writeToParcel(Parcel dest, int flags) {
395         if (DBG) log("writeToParcel(Parcel, int): " + toString());
396         dest.writeInt(mRssi);
397         // Need to multiply rsrp and rsrq by -1
398         // to ensure consistency when reading values written here
399         // unless the values are invalid
400         dest.writeInt(mRsrp);
401         dest.writeInt(mRsrq);
402         dest.writeInt(mRssnr);
403         dest.writeInt(mCqi);
404         dest.writeInt(mTimingAdvance);
405         dest.writeInt(mLevel);
406     }
407 
408     /**
409      * Construct a SignalStrength object from the given parcel
410      * where the token is already been processed.
411      */
CellSignalStrengthLte(Parcel in)412     private CellSignalStrengthLte(Parcel in) {
413         mRssi = in.readInt();
414         mSignalStrength = mRssi;
415         mRsrp = in.readInt();
416         mRsrq = in.readInt();
417         mRssnr = in.readInt();
418         mCqi = in.readInt();
419         mTimingAdvance = in.readInt();
420         mLevel = in.readInt();
421         if (DBG) log("CellSignalStrengthLte(Parcel): " + toString());
422     }
423 
424     /** Implement the Parcelable interface */
425     @Override
describeContents()426     public int describeContents() {
427         return 0;
428     }
429 
430     /** Implement the Parcelable interface */
431     @SuppressWarnings("hiding")
432     public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthLte> CREATOR =
433             new Parcelable.Creator<CellSignalStrengthLte>() {
434         @Override
435         public CellSignalStrengthLte createFromParcel(Parcel in) {
436             return new CellSignalStrengthLte(in);
437         }
438 
439         @Override
440         public CellSignalStrengthLte[] newArray(int size) {
441             return new CellSignalStrengthLte[size];
442         }
443     };
444 
445     /**
446      * log
447      */
log(String s)448     private static void log(String s) {
449         Rlog.w(LOG_TAG, s);
450     }
451 
convertRssiAsuToDBm(int rssiAsu)452     private static int convertRssiAsuToDBm(int rssiAsu) {
453         if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
454             return CellInfo.UNAVAILABLE;
455         }
456         if ((rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
457                 || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
458             Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
459             return CellInfo.UNAVAILABLE;
460         }
461         return -113 + (2 * rssiAsu);
462     }
463 }
464