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.compat.annotation.UnsupportedAppUsage;
21 import android.os.Build;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.os.PersistableBundle;
25 
26 import com.android.telephony.Rlog;
27 
28 import java.util.Arrays;
29 import java.util.Objects;
30 
31 /**
32  * LTE signal strength related information.
33  */
34 public final class CellSignalStrengthLte extends CellSignalStrength implements Parcelable {
35 
36     private static final String LOG_TAG = "CellSignalStrengthLte";
37     private static final boolean DBG = false;
38 
39     /**
40      * Indicates the unknown or undetectable RSSI value in ASU.
41      *
42      * Reference: TS 27.007 8.5 - Signal quality +CSQ
43      */
44     private static final int SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN = 99;
45     /**
46      * Indicates the maximum valid RSSI value in ASU.
47      *
48      * Reference: TS 27.007 8.5 - Signal quality +CSQ
49      */
50     private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE = 31;
51     /**
52      * Indicates the minimum valid RSSI value in ASU.
53      *
54      * Reference: TS 27.007 8.5 - Signal quality +CSQ
55      */
56     private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0;
57 
58     private static final int MAX_LTE_RSRP = -44;
59     private static final int MIN_LTE_RSRP = -140;
60 
61     /**
62      * Indicates RSRP is considered for {@link #getLevel()} and reported from modem.
63      *
64      * @hide
65      */
66     public static final int USE_RSRP = 1 << 0;
67     /**
68      * Indicates RSRQ is considered for {@link #getLevel()} and reported from modem.
69      *
70      * @hide
71      */
72     public static final int USE_RSRQ = 1 << 1;
73     /**
74      * Indicates RSSNR is considered for {@link #getLevel()} and reported from modem.
75      *
76      * @hide
77      */
78     public static final int USE_RSSNR = 1 << 2;
79 
80     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
81     private int mSignalStrength; // To be removed
82     private int mRssi;
83     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
84     private int mRsrp;
85     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
86     private int mRsrq;
87     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
88     private int mRssnr;
89     /**
90      * CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
91      * The definition of CQI in each table is different.
92      *
93      * Reference: 3GPP TS 136.213 section 7.2.3.
94      *
95      * Range [1, 6].
96      */
97     private int mCqiTableIndex;
98     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
99     private int mCqi;
100     @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
101     private int mTimingAdvance;
102     private int mLevel;
103 
104     /**
105      * Bit-field integer to determine whether to use Reference Signal Received Power (RSRP),
106      * Reference Signal Received Quality (RSRQ), and/or Reference Signal Signal to Noise Ratio
107      * (RSSNR) for the number of LTE signal bars. If multiple measures are set, the parameter
108      * whose signal level value is smallest is used to indicate the signal level.
109      *
110      *  RSRP = 1 << 0,
111      *  RSRQ = 1 << 1,
112      *  RSSNR = 1 << 2,
113      *
114      * For example, if both RSRP and RSRQ are used, the value of key is 3 (1 << 0 | 1 << 1).
115      * If the key is invalid or not configured, a default value (RSRP = 1 << 0) will apply.
116      */
117     private int mParametersUseForLevel;
118 
119     /** @hide */
120     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
CellSignalStrengthLte()121     public CellSignalStrengthLte() {
122         setDefaultValues();
123     }
124 
125     /**
126      * Construct a cell signal strength
127      *
128      * @param rssi in dBm [-113,-51], {@link CellInfo#UNAVAILABLE}
129      * @param rsrp in dBm [-140,-43], {@link CellInfo#UNAVAILABLE}
130      * @param rsrq in dB [-34, 3], {@link CellInfo#UNAVAILABLE}
131      * @param rssnr in dB [-20, +30], {@link CellInfo#UNAVAILABLE}
132      * @param cqiTableIndex [1, 6], {@link CellInfo#UNAVAILABLE}
133      * @param cqi [0, 15], {@link CellInfo#UNAVAILABLE}
134      * @param timingAdvance [0, 1282], {@link CellInfo#UNAVAILABLE}
135      *
136      */
137     /** @hide */
CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqiTableIndex, int cqi, int timingAdvance)138     public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqiTableIndex,
139             int cqi, int timingAdvance) {
140         mRssi = inRangeOrUnavailable(rssi, -113, -51);
141         mSignalStrength = mRssi;
142         mRsrp = inRangeOrUnavailable(rsrp, -140, -43);
143         mRsrq = inRangeOrUnavailable(rsrq, -34, 3);
144         mRssnr = inRangeOrUnavailable(rssnr, -20, 30);
145         mCqiTableIndex = inRangeOrUnavailable(cqiTableIndex, 1, 6);
146         mCqi = inRangeOrUnavailable(cqi, 0, 15);
147         mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
148         updateLevel(null, null);
149     }
150 
151     /**
152      * Construct a cell signal strength
153      *
154      * @param rssi in dBm [-113,-51], {@link CellInfo#UNAVAILABLE}
155      * @param rsrp in dBm [-140,-43], {@link CellInfo#UNAVAILABLE}
156      * @param rsrq in dB [-34, 3], {@link CellInfo#UNAVAILABLE}
157      * @param rssnr in dB [-20, +30], {@link CellInfo#UNAVAILABLE}
158      * @param cqi [0, 15], {@link CellInfo#UNAVAILABLE}
159      * @param timingAdvance [0, 1282], {@link CellInfo#UNAVAILABLE}
160      *
161      */
162     /** @hide */
CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi, int timingAdvance)163     public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi,
164             int timingAdvance) {
165         this(rssi, rsrp, rsrq, rssnr, CellInfo.UNAVAILABLE, cqi, timingAdvance);
166     }
167 
168     /** @hide */
CellSignalStrengthLte(CellSignalStrengthLte s)169     public CellSignalStrengthLte(CellSignalStrengthLte s) {
170         copyFrom(s);
171     }
172 
173     /** @hide */
copyFrom(CellSignalStrengthLte s)174     protected void copyFrom(CellSignalStrengthLte s) {
175         mSignalStrength = s.mSignalStrength;
176         mRssi = s.mRssi;
177         mRsrp = s.mRsrp;
178         mRsrq = s.mRsrq;
179         mRssnr = s.mRssnr;
180         mCqiTableIndex = s.mCqiTableIndex;
181         mCqi = s.mCqi;
182         mTimingAdvance = s.mTimingAdvance;
183         mLevel = s.mLevel;
184         mParametersUseForLevel = s.mParametersUseForLevel;
185     }
186 
187     /** @hide */
188     @Override
copy()189     public CellSignalStrengthLte copy() {
190         return new CellSignalStrengthLte(this);
191     }
192 
193     /** @hide */
194     @Override
setDefaultValues()195     public void setDefaultValues() {
196         mSignalStrength = CellInfo.UNAVAILABLE;
197         mRssi = CellInfo.UNAVAILABLE;
198         mRsrp = CellInfo.UNAVAILABLE;
199         mRsrq = CellInfo.UNAVAILABLE;
200         mRssnr = CellInfo.UNAVAILABLE;
201         mCqiTableIndex = CellInfo.UNAVAILABLE;
202         mCqi = CellInfo.UNAVAILABLE;
203         mTimingAdvance = CellInfo.UNAVAILABLE;
204         mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
205         mParametersUseForLevel = USE_RSRP;
206     }
207 
208     /** {@inheritDoc} */
209     @Override
210     @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
getLevel()211     public int getLevel() {
212         return mLevel;
213     }
214 
215     // Lifted from Default carrier configs and max range of RSRP
216     private static final int[] sRsrpThresholds = new int[] {
217             -115, /* SIGNAL_STRENGTH_POOR */
218             -105, /* SIGNAL_STRENGTH_MODERATE */
219             -95,  /* SIGNAL_STRENGTH_GOOD */
220             -85   /* SIGNAL_STRENGTH_GREAT */
221     };
222 
223     // Lifted from Default carrier configs and max range of RSRQ
224     private static final int[] sRsrqThresholds = new int[] {
225             -19, /* SIGNAL_STRENGTH_POOR */
226             -17, /* SIGNAL_STRENGTH_MODERATE */
227             -14, /* SIGNAL_STRENGTH_GOOD */
228             -12  /* SIGNAL_STRENGTH_GREAT */
229     };
230     // Lifted from Default carrier configs and max range of RSSNR
231     private static final int[] sRssnrThresholds = new int[] {
232             -3, /* SIGNAL_STRENGTH_POOR */
233             1,  /* SIGNAL_STRENGTH_MODERATE */
234             5,  /* SIGNAL_STRENGTH_GOOD */
235             13  /* SIGNAL_STRENGTH_GREAT */
236     };
237     private static final int sRsrpBoost = 0;
238 
239     /**
240      * Checks if the given parameter type is considered to use for {@link #getLevel()}.
241      *
242      * Note: if multiple parameter types are considered, the smaller level for one of the
243      * parameters would be returned by {@link #getLevel()}
244      *
245      * @param parameterType bitwise OR of {@link #USE_RSRP}, {@link #USE_RSRQ},
246      *         {@link #USE_RSSNR}
247      * @return {@code true} if the level is calculated based on the given parameter type;
248      *      {@code false} otherwise.
249      */
isLevelForParameter(int parameterType)250     private boolean isLevelForParameter(int parameterType) {
251         return (parameterType & mParametersUseForLevel) == parameterType;
252     }
253 
254     /** @hide */
255     @Override
updateLevel(PersistableBundle cc, ServiceState ss)256     public void updateLevel(PersistableBundle cc, ServiceState ss) {
257         int[] rsrpThresholds, rsrqThresholds, rssnrThresholds;
258         boolean rsrpOnly;
259         if (cc == null) {
260             mParametersUseForLevel = USE_RSRP;
261             rsrpThresholds = sRsrpThresholds;
262             rsrqThresholds = sRsrqThresholds;
263             rssnrThresholds = sRssnrThresholds;
264             rsrpOnly = false;
265         } else {
266             if (ss != null && ss.isUsingNonTerrestrialNetwork()) {
267                 if (DBG) log("updateLevel: from NTN_LTE");
268                 mParametersUseForLevel = cc.getInt(
269                         CarrierConfigManager.KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT);
270                 rsrpThresholds = cc.getIntArray(
271                         CarrierConfigManager.KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY);
272                 rsrqThresholds = cc.getIntArray(
273                         CarrierConfigManager.KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY);
274                 rssnrThresholds = cc.getIntArray(
275                         CarrierConfigManager.KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY);
276             } else {
277                 mParametersUseForLevel = cc.getInt(
278                         CarrierConfigManager.KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT);
279                 rsrpThresholds = cc.getIntArray(
280                         CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
281                 rsrqThresholds = cc.getIntArray(
282                         CarrierConfigManager.KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY);
283                 rssnrThresholds = cc.getIntArray(
284                         CarrierConfigManager.KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY);
285             }
286             if (rsrpThresholds == null) rsrpThresholds = sRsrpThresholds;
287             if (rsrqThresholds == null) rsrqThresholds = sRsrqThresholds;
288             if (rssnrThresholds == null) rssnrThresholds = sRssnrThresholds;
289             if (DBG) {
290                 Rlog.i(LOG_TAG, "Using signal strength level: " + mParametersUseForLevel);
291                 Rlog.i(LOG_TAG, "Applying LTE RSRP Thresholds: "
292                         + Arrays.toString(rsrpThresholds));
293                 Rlog.i(LOG_TAG, "Applying LTE RSRQ Thresholds: "
294                         + Arrays.toString(rsrqThresholds));
295                 Rlog.i(LOG_TAG, "Applying LTE RSSNR Thresholds: "
296                         + Arrays.toString(rssnrThresholds));
297             }
298             rsrpOnly = cc.getBoolean(
299                     CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, false);
300         }
301 
302         int rsrpBoost = 0;
303         if (ss != null) {
304             rsrpBoost = ss.getArfcnRsrpBoost();
305         }
306 
307         int rsrp = inRangeOrUnavailable(mRsrp + rsrpBoost, MIN_LTE_RSRP, MAX_LTE_RSRP);
308 
309         if (rsrpOnly) {
310             int level = updateLevelWithMeasure(rsrp, rsrpThresholds);
311             if (DBG) log("updateLevel() - rsrp = " + level);
312             if (level != SignalStrength.INVALID) {
313                 mLevel = level;
314                 return;
315             }
316         }
317 
318         int rsrpLevel = SignalStrength.INVALID;
319         int rsrqLevel = SignalStrength.INVALID;
320         int rssnrLevel = SignalStrength.INVALID;
321 
322         if (isLevelForParameter(USE_RSRP)) {
323             rsrpLevel = updateLevelWithMeasure(rsrp, rsrpThresholds);
324             if (DBG) {
325                 Rlog.i(LOG_TAG, "Updated 4G LTE RSRP Level: " + rsrpLevel);
326             }
327         }
328         if (isLevelForParameter(USE_RSRQ)) {
329             rsrqLevel = updateLevelWithMeasure(mRsrq, rsrqThresholds);
330             if (DBG) {
331                 Rlog.i(LOG_TAG, "Updated 4G LTE RSRQ Level: " + rsrqLevel);
332             }
333         }
334         if (isLevelForParameter(USE_RSSNR)) {
335             rssnrLevel = updateLevelWithMeasure(mRssnr, rssnrThresholds);
336             if (DBG) {
337                 Rlog.i(LOG_TAG, "Updated 4G LTE RSSNR Level: " + rssnrLevel);
338             }
339         }
340         // Apply the smaller value among three levels of three measures.
341         mLevel = Math.min(Math.min(rsrpLevel, rsrqLevel), rssnrLevel);
342 
343         if (mLevel == SignalStrength.INVALID) {
344             int rssiLevel;
345             if (mRssi > -51) {
346                 rssiLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
347             } else if (mRssi >= -89) {
348                 rssiLevel = SIGNAL_STRENGTH_GREAT;
349             } else if (mRssi >= -97) {
350                 rssiLevel = SIGNAL_STRENGTH_GOOD;
351             } else if (mRssi >= -103) {
352                 rssiLevel = SIGNAL_STRENGTH_MODERATE;
353             } else if (mRssi >= -113) {
354                 rssiLevel = SIGNAL_STRENGTH_POOR;
355             } else {
356                 rssiLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
357             }
358             if (DBG) log("getLteLevel - rssi:" + mRssi + " rssiIconLevel:" + rssiLevel);
359             mLevel = rssiLevel;
360         }
361     }
362 
363     /**
364      * Update level with corresponding measure and thresholds.
365      *
366      * @param measure corresponding signal measure
367      * @param thresholds corresponding signal thresholds
368      * @return level of the signal strength
369      */
updateLevelWithMeasure(int measure, int[] thresholds)370     private int updateLevelWithMeasure(int measure, int[] thresholds) {
371         int level;
372         if (measure == CellInfo.UNAVAILABLE) {
373             level = SignalStrength.INVALID;
374         } else if (measure >= thresholds[3]) {
375             level = SIGNAL_STRENGTH_GREAT;
376         } else if (measure >= thresholds[2]) {
377             level = SIGNAL_STRENGTH_GOOD;
378         } else if (measure >= thresholds[1]) {
379             level = SIGNAL_STRENGTH_MODERATE;
380         } else if (measure >= thresholds[0]) {
381             level = SIGNAL_STRENGTH_POOR;
382         } else {
383             level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
384         }
385         return level;
386     }
387 
388     /**
389      * Get reference signal received quality
390      *
391      * @return the RSRQ if available or
392      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
393      */
getRsrq()394     public int getRsrq() {
395         return mRsrq;
396     }
397 
398     /**
399      * Get Received Signal Strength Indication (RSSI) in dBm
400      *
401      * The value range is [-113, -51] inclusively or {@link CellInfo#UNAVAILABLE} if unavailable.
402      *
403      * Reference: TS 27.007 8.5 Signal quality +CSQ
404      *
405      * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable.
406      */
getRssi()407     public int getRssi() {
408         return mRssi;
409     }
410 
411     /**
412      * Get reference signal signal-to-noise ratio in dB
413      * Range: -20 dB to +30 dB.
414      *
415      * @return the RSSNR if available or
416      *         {@link android.telephony.CellInfo#UNAVAILABLE} if unavailable.
417      */
getRssnr()418     public int getRssnr() {
419         return mRssnr;
420     }
421 
422     /**
423      * Get reference signal received power in dBm
424      * Range: -140 dBm to -43 dBm.
425      *
426      * @return the RSRP of the measured cell or {@link CellInfo#UNAVAILABLE} if
427      * unavailable.
428      */
getRsrp()429     public int getRsrp() {
430         return mRsrp;
431     }
432 
433     /**
434      * Get table index for channel quality indicator
435      *
436      * Reference: 3GPP TS 136.213 section 7.2.3.
437      *
438      * @return the CQI table index if available or
439      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
440      */
441     @IntRange(from = 1, to = 6)
getCqiTableIndex()442     public int getCqiTableIndex() {
443         return mCqiTableIndex;
444     }
445 
446     /**
447      * Get channel quality indicator
448      *
449      * Reference: 3GPP TS 136.213 section 7.2.3.
450      *
451      * @return the CQI if available or
452      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
453      */
454     @IntRange(from = 0, to = 15)
getCqi()455     public int getCqi() {
456         return mCqi;
457     }
458 
459     /**
460      * Get signal strength in dBm
461      *
462      * @return the RSRP of the measured cell.
463      */
464     @Override
getDbm()465     public int getDbm() {
466         return mRsrp;
467     }
468 
469     /**
470      * Get the RSRP in ASU.
471      *
472      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
473      *
474      * @return RSCP in ASU 0..97, 255, or UNAVAILABLE
475      */
476     @Override
getAsuLevel()477     public int getAsuLevel() {
478         int lteAsuLevel = 99;
479         int lteDbm = mRsrp;
480         if (lteDbm == CellInfo.UNAVAILABLE) lteAsuLevel = 99;
481         else if (lteDbm <= -140) lteAsuLevel = 0;
482         else if (lteDbm >= -43) lteAsuLevel = 97;
483         else lteAsuLevel = lteDbm + 140;
484         if (DBG) log("Lte Asu level: "+lteAsuLevel);
485         return lteAsuLevel;
486     }
487 
488     /**
489      * Get the timing advance value for LTE, as a value in range of 0..1282.
490      * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} is reported when there is no
491      * active RRC connection. Refer to 3GPP 36.213 Sec 4.2.3
492      *
493      * @return the LTE timing advance if available or
494      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
495      */
getTimingAdvance()496     public int getTimingAdvance() {
497         return mTimingAdvance;
498     }
499 
500     @Override
hashCode()501     public int hashCode() {
502         return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqiTableIndex, mCqi, mTimingAdvance,
503                 mLevel);
504     }
505 
506     private static final CellSignalStrengthLte sInvalid = new CellSignalStrengthLte();
507 
508     /** @hide */
509     @Override
isValid()510     public boolean isValid() {
511         return !this.equals(sInvalid);
512     }
513 
514     @Override
equals(Object o)515     public boolean equals (Object o) {
516         CellSignalStrengthLte s;
517 
518         if (!(o instanceof CellSignalStrengthLte)) return false;
519         s = (CellSignalStrengthLte) o;
520 
521         return mRssi == s.mRssi
522                 && mRsrp == s.mRsrp
523                 && mRsrq == s.mRsrq
524                 && mRssnr == s.mRssnr
525                 && mCqiTableIndex == s.mCqiTableIndex
526                 && mCqi == s.mCqi
527                 && mTimingAdvance == s.mTimingAdvance
528                 && mLevel == s.mLevel;
529     }
530 
531     /**
532      * @return string representation.
533      */
534     @Override
toString()535     public String toString() {
536         return "CellSignalStrengthLte:"
537                 + " rssi=" + mRssi
538                 + " rsrp=" + mRsrp
539                 + " rsrq=" + mRsrq
540                 + " rssnr=" + mRssnr
541                 + " cqiTableIndex=" + mCqiTableIndex
542                 + " cqi=" + mCqi
543                 + " ta=" + mTimingAdvance
544                 + " level=" + mLevel
545                 + " parametersUseForLevel=" + mParametersUseForLevel;
546     }
547 
548     /** Implement the Parcelable interface */
549     @Override
writeToParcel(Parcel dest, int flags)550     public void writeToParcel(Parcel dest, int flags) {
551         if (DBG) log("writeToParcel(Parcel, int): " + toString());
552         dest.writeInt(mRssi);
553         // Need to multiply rsrp and rsrq by -1
554         // to ensure consistency when reading values written here
555         // unless the values are invalid
556         dest.writeInt(mRsrp);
557         dest.writeInt(mRsrq);
558         dest.writeInt(mRssnr);
559         dest.writeInt(mCqiTableIndex);
560         dest.writeInt(mCqi);
561         dest.writeInt(mTimingAdvance);
562         dest.writeInt(mLevel);
563     }
564 
565     /**
566      * Construct a SignalStrength object from the given parcel
567      * where the token is already been processed.
568      */
CellSignalStrengthLte(Parcel in)569     private CellSignalStrengthLte(Parcel in) {
570         mRssi = in.readInt();
571         mSignalStrength = mRssi;
572         mRsrp = in.readInt();
573         mRsrq = in.readInt();
574         mRssnr = in.readInt();
575         mCqiTableIndex = in.readInt();
576         mCqi = in.readInt();
577         mTimingAdvance = in.readInt();
578         mLevel = in.readInt();
579         if (DBG) log("CellSignalStrengthLte(Parcel): " + toString());
580     }
581 
582     /** Implement the Parcelable interface */
583     @Override
describeContents()584     public int describeContents() {
585         return 0;
586     }
587 
588     /** Implement the Parcelable interface */
589     @SuppressWarnings("hiding")
590     public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthLte> CREATOR =
591             new Parcelable.Creator<CellSignalStrengthLte>() {
592         @Override
593         public CellSignalStrengthLte createFromParcel(Parcel in) {
594             return new CellSignalStrengthLte(in);
595         }
596 
597         @Override
598         public CellSignalStrengthLte[] newArray(int size) {
599             return new CellSignalStrengthLte[size];
600         }
601     };
602 
603     /**
604      * log
605      */
log(String s)606     private static void log(String s) {
607         Rlog.w(LOG_TAG, s);
608     }
609 
610     /** @hide */
convertRssnrUnitFromTenDbToDB(int rssnr)611     public static int convertRssnrUnitFromTenDbToDB(int rssnr) {
612         return (int) Math.floor((float) rssnr / 10);
613     }
614 
615     /** @hide */
convertRssiAsuToDBm(int rssiAsu)616     public static int convertRssiAsuToDBm(int rssiAsu) {
617         if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
618             return CellInfo.UNAVAILABLE;
619         }
620         if ((rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
621                 || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
622             Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
623             return CellInfo.UNAVAILABLE;
624         }
625         return -113 + (2 * rssiAsu);
626     }
627 }
628