• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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.IntDef;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
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.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.Objects;
34 import java.util.stream.Collectors;
35 
36 /**
37  * 5G NR signal strength related information.
38  */
39 public final class CellSignalStrengthNr extends CellSignalStrength implements Parcelable {
40     /**
41      * The value is used to indicate that the asu level is unknown.
42      * Reference: 3GPP TS 27.007 section 8.69.
43      * @hide
44      */
45     public static final int UNKNOWN_ASU_LEVEL = 99;
46 
47     private static final boolean VDBG = false;
48 
49     private static final String TAG = "CellSignalStrengthNr";
50 
51     // Lifted from Default carrier configs and max range of SSRSRP
52     // Boundaries: [-156 dB, -31 dB]
53     private int[] mSsRsrpThresholds = new int[] {
54             -110, /* SIGNAL_STRENGTH_POOR */
55             -90, /* SIGNAL_STRENGTH_MODERATE */
56             -80, /* SIGNAL_STRENGTH_GOOD */
57             -65,  /* SIGNAL_STRENGTH_GREAT */
58     };
59 
60     // Lifted from Default carrier configs and max range of SSRSRQ
61     // Boundaries: [-43 dB, 20 dB]
62     private int[] mSsRsrqThresholds = new int[] {
63             -31, /* SIGNAL_STRENGTH_POOR */
64             -19, /* SIGNAL_STRENGTH_MODERATE */
65             -7, /* SIGNAL_STRENGTH_GOOD */
66             6  /* SIGNAL_STRENGTH_GREAT */
67     };
68 
69     // Lifted from Default carrier configs and max range of SSSINR
70     // Boundaries: [-23 dB, 40 dB]
71     private int[] mSsSinrThresholds = new int[] {
72             -5, /* SIGNAL_STRENGTH_POOR */
73             5, /* SIGNAL_STRENGTH_MODERATE */
74             15, /* SIGNAL_STRENGTH_GOOD */
75             30  /* SIGNAL_STRENGTH_GREAT */
76     };
77 
78     /**
79      * Indicates SSRSRP is considered for {@link #getLevel()} and reporting from modem.
80      *
81      * @hide
82      */
83     public static final int USE_SSRSRP = 1 << 0;
84     /**
85      * Indicates SSRSRQ is considered for {@link #getLevel()} and reporting from modem.
86      *
87      * @hide
88      */
89     public static final int USE_SSRSRQ = 1 << 1;
90     /**
91      * Indicates SSSINR is considered for {@link #getLevel()} and reporting from modem.
92      *
93      * @hide
94      */
95     public static final int USE_SSSINR = 1 << 2;
96 
97     /**
98      * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP),
99      * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference
100      * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the
101      * parameter whose value is smallest is used to indicate the signal bar.
102      *
103      * @hide
104      */
105     @IntDef(flag = true, prefix = { "USE_" }, value = {
106         USE_SSRSRP,
107         USE_SSRSRQ,
108         USE_SSSINR
109     })
110     @Retention(RetentionPolicy.SOURCE)
111     public @interface SignalLevelAndReportCriteriaSource {}
112 
113     private int mCsiRsrp;
114     private int mCsiRsrq;
115     private int mCsiSinr;
116     /**
117      * CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
118      * The definition of CQI in each table is different.
119      *
120      * Reference: 3GPP TS 138.214 section 5.2.2.1.
121      *
122      * Range [1, 3].
123      */
124     private int mCsiCqiTableIndex;
125     /**
126      * CSI channel quality indicators (CQI) for all subbands.
127      *
128      * If the CQI report is for the entire wideband, a single CQI index is provided.
129      * If the CQI report is for all subbands, one CQI index is provided for each subband,
130      * in ascending order of subband index.
131      * If CQI is not available, the CQI report is empty.
132      *
133      * Reference: 3GPP TS 138.214 section 5.2.2.1.
134      *
135      * Range [0, 15] for each CQI.
136      */
137     private List<Integer> mCsiCqiReport;
138     private int mSsRsrp;
139     private int mSsRsrq;
140     private int mSsSinr;
141     private int mLevel;
142 
143     /**
144      * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP),
145      * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference
146      * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the
147      * parameter whose value is smallest is used to indicate the signal bar.
148      *
149      *  SSRSRP = 1 << 0,
150      *  SSRSRQ = 1 << 1,
151      *  SSSINR = 1 << 2,
152      *
153      * For example, if both SSRSRP and SSSINR are used, the value of key is 5 (1 << 0 | 1 << 2).
154      * If the key is invalid or not configured, a default value (SSRSRP = 1 << 0) will apply.
155      */
156     private int mParametersUseForLevel;
157 
158     /** @hide */
CellSignalStrengthNr()159     public CellSignalStrengthNr() {
160         setDefaultValues();
161     }
162 
163     /**
164      * @param csiRsrp CSI reference signal received power.
165      * @param csiRsrq CSI reference signal received quality.
166      * @param csiSinr CSI signal-to-noise and interference ratio.
167      * @param csiCqiTableIndex CSI CSI channel quality indicator (CQI) table index.
168      * @param csiCqiReport CSI channel quality indicators (CQI) for all subbands.
169      * @param ssRsrp SS reference signal received power.
170      * @param ssRsrq SS reference signal received quality.
171      * @param ssSinr SS signal-to-noise and interference ratio.
172      * @hide
173      */
CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex, List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr)174     public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex,
175             List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr) {
176         mCsiRsrp = inRangeOrUnavailable(csiRsrp, -156, -31);
177         mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
178         mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
179         mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3);
180         mCsiCqiReport = csiCqiReport.stream()
181                 .map(cqi -> inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15))
182                 .collect(Collectors.toList());
183         mSsRsrp = inRangeOrUnavailable(ssRsrp, -156, -31);
184         mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
185         mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
186         updateLevel(null, null);
187     }
188 
189     /**
190      * @param csiRsrp CSI reference signal received power.
191      * @param csiRsrq CSI reference signal received quality.
192      * @param csiSinr CSI signal-to-noise and interference ratio.
193      * @param ssRsrp SS reference signal received power.
194      * @param ssRsrq SS reference signal received quality.
195      * @param ssSinr SS signal-to-noise and interference ratio.
196      * @hide
197      */
CellSignalStrengthNr( int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr)198     public CellSignalStrengthNr(
199             int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) {
200         this(csiRsrp, csiRsrq, csiSinr, CellInfo.UNAVAILABLE, Collections.emptyList(),
201                 ssRsrp, ssRsrq, ssSinr);
202     }
203 
204     /**
205      * Flip sign cell strength value when taking in the value from hal
206      * @param val cell strength value
207      * @return flipped value
208      * @hide
209      */
flip(int val)210     public static int flip(int val) {
211         return val != CellInfo.UNAVAILABLE ? -val : val;
212     }
213 
214     /**
215      * Reference: 3GPP TS 38.133 10.1.6.1.
216      * Range: -156 dBm to -31 dBm.
217      * @return SS reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported
218      * value.
219      */
getSsRsrp()220     public int getSsRsrp() {
221         return mSsRsrp;
222     }
223 
224     /**
225      * Reference: 3GPP TS 38.215; 3GPP TS 38.133 section 10
226      * Range: -43 dB to 20 dB.
227      * @return SS reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported
228      * value.
229      */
getSsRsrq()230     public int getSsRsrq() {
231         return mSsRsrq;
232     }
233 
234     /**
235      * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1
236      * Range: -23 dB to 40 dB
237      * @return SS signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means
238      * unreported value.
239      */
getSsSinr()240     public int getSsSinr() {
241         return mSsSinr;
242     }
243 
244     /**
245      * Reference: 3GPP TS 38.133 10.1.6.1.
246      * Range: -156 dBm to -31 dBm.
247      * @return CSI reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported
248      * value.
249      */
getCsiRsrp()250     public int getCsiRsrp() {
251         return mCsiRsrp;
252     }
253 
254     /**
255      * Reference: 3GPP TS 38.215.
256      * Range: -20 dB to -3 dB.
257      * @return CSI reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported
258      * value.
259      */
getCsiRsrq()260     public int getCsiRsrq() {
261         return mCsiRsrq;
262     }
263 
264     /**
265      * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1
266      * Range: -23 dB to 23 dB
267      * @return CSI signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means
268      * unreported value.
269      */
getCsiSinr()270     public int getCsiSinr() {
271         return mCsiSinr;
272     }
273 
274     /**
275      * Return CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
276      * The definition of CQI in each table is different.
277      *
278      * Reference: 3GPP TS 138.214 section 5.2.2.1.
279      *
280      * @return the CQI table index if available or
281      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
282      */
283     @IntRange(from = 1, to = 3)
getCsiCqiTableIndex()284     public int getCsiCqiTableIndex() {
285         return mCsiCqiTableIndex;
286     }
287     /**
288      * Return a list of CSI channel quality indicators (CQI) for all subbands.
289      *
290      * If the CQI report is for the entire wideband, a single CQI index is provided.
291      * If the CQI report is for all subbands, one CQI index is provided for each subband,
292      * in ascending order of subband index.
293      * If CQI is not available, the CQI report is empty.
294      *
295      * Reference: 3GPP TS 138.214 section 5.2.2.1.
296      *
297      * @return the CQIs for all subbands if available or empty list if unavailable.
298      */
299     @NonNull
300     @IntRange(from = 0, to = 15)
getCsiCqiReport()301     public List<Integer> getCsiCqiReport() {
302         return mCsiCqiReport;
303     }
304 
305     @Override
describeContents()306     public int describeContents() {
307         return 0;
308     }
309 
310     /** @hide */
311     @Override
writeToParcel(Parcel dest, int flags)312     public void writeToParcel(Parcel dest, int flags) {
313         dest.writeInt(mCsiRsrp);
314         dest.writeInt(mCsiRsrq);
315         dest.writeInt(mCsiSinr);
316         dest.writeInt(mCsiCqiTableIndex);
317         dest.writeList(mCsiCqiReport);
318         dest.writeInt(mSsRsrp);
319         dest.writeInt(mSsRsrq);
320         dest.writeInt(mSsSinr);
321         dest.writeInt(mLevel);
322     }
323 
CellSignalStrengthNr(Parcel in)324     private CellSignalStrengthNr(Parcel in) {
325         mCsiRsrp = in.readInt();
326         mCsiRsrq = in.readInt();
327         mCsiSinr = in.readInt();
328         mCsiCqiTableIndex = in.readInt();
329         mCsiCqiReport = in.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class);
330         mSsRsrp = in.readInt();
331         mSsRsrq = in.readInt();
332         mSsSinr = in.readInt();
333         mLevel = in.readInt();
334     }
335 
336     /** @hide */
337     @Override
setDefaultValues()338     public void setDefaultValues() {
339         mCsiRsrp = CellInfo.UNAVAILABLE;
340         mCsiRsrq = CellInfo.UNAVAILABLE;
341         mCsiSinr = CellInfo.UNAVAILABLE;
342         mCsiCqiTableIndex = CellInfo.UNAVAILABLE;
343         mCsiCqiReport = Collections.emptyList();
344         mSsRsrp = CellInfo.UNAVAILABLE;
345         mSsRsrq = CellInfo.UNAVAILABLE;
346         mSsSinr = CellInfo.UNAVAILABLE;
347         mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
348         mParametersUseForLevel = USE_SSRSRP;
349     }
350 
351     /** {@inheritDoc} */
352     @Override
353     @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
getLevel()354     public int getLevel() {
355         return mLevel;
356     }
357 
358     /**
359      * Checks if the given parameter type is considered to use for {@link #getLevel()}.
360      *
361      * Note: if multiple parameter types are considered, the smaller level for one of the
362      * parameters would be returned by {@link #getLevel()}
363      *
364      * @param parameterType bitwise OR of {@link #USE_SSRSRP}, {@link #USE_SSRSRQ},
365      *         {@link #USE_SSSINR}
366      * @return {@code true} if the level is calculated based on the given parameter type;
367      *      {@code false} otherwise.
368      *
369      */
isLevelForParameter(@ignalLevelAndReportCriteriaSource int parameterType)370     private boolean isLevelForParameter(@SignalLevelAndReportCriteriaSource int parameterType) {
371         return (parameterType & mParametersUseForLevel) == parameterType;
372     }
373 
374     /** @hide */
375     @Override
updateLevel(PersistableBundle cc, ServiceState ss)376     public void updateLevel(PersistableBundle cc, ServiceState ss) {
377         if (cc == null) {
378             mParametersUseForLevel = USE_SSRSRP;
379         } else {
380             mParametersUseForLevel = cc.getInt(
381                     CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, USE_SSRSRP);
382             mSsRsrpThresholds = cc.getIntArray(
383                     CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY);
384             if (VDBG) {
385                 Rlog.i(TAG, "Applying 5G NR SSRSRP Thresholds: "
386                         + Arrays.toString(mSsRsrpThresholds));
387             }
388             mSsRsrqThresholds = cc.getIntArray(
389                     CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY);
390             if (VDBG) {
391                 Rlog.i(TAG, "Applying 5G NR SSRSRQ Thresholds: "
392                         + Arrays.toString(mSsRsrqThresholds));
393             }
394             mSsSinrThresholds = cc.getIntArray(
395                     CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY);
396             if (VDBG) {
397                 Rlog.i(TAG, "Applying 5G NR SSSINR Thresholds: "
398                         + Arrays.toString(mSsSinrThresholds));
399             }
400         }
401         int ssRsrpLevel = SignalStrength.INVALID;
402         int ssRsrqLevel = SignalStrength.INVALID;
403         int ssSinrLevel = SignalStrength.INVALID;
404         if (isLevelForParameter(USE_SSRSRP)) {
405             int rsrpBoost = 0;
406             if (ss != null) {
407                 rsrpBoost = ss.getArfcnRsrpBoost();
408             }
409             ssRsrpLevel = updateLevelWithMeasure(mSsRsrp + rsrpBoost, mSsRsrpThresholds);
410             if (VDBG) {
411                 Rlog.i(TAG, "Updated 5G NR SSRSRP Level: " + ssRsrpLevel);
412             }
413         }
414         if (isLevelForParameter(USE_SSRSRQ)) {
415             ssRsrqLevel = updateLevelWithMeasure(mSsRsrq, mSsRsrqThresholds);
416             if (VDBG) {
417                 Rlog.i(TAG, "Updated 5G NR SSRSRQ Level: " + ssRsrqLevel);
418             }
419         }
420         if (isLevelForParameter(USE_SSSINR)) {
421             ssSinrLevel = updateLevelWithMeasure(mSsSinr, mSsSinrThresholds);
422             if (VDBG) {
423                 Rlog.i(TAG, "Updated 5G NR SSSINR Level: " + ssSinrLevel);
424             }
425         }
426         // Apply the smaller value among three levels of three measures.
427         mLevel = Math.min(Math.min(ssRsrpLevel, ssRsrqLevel), ssSinrLevel);
428     }
429 
430     /**
431      * Update level with corresponding measure and thresholds.
432      *
433      * @param measure corresponding signal measure
434      * @param thresholds corresponding signal thresholds
435      * @return level of the signal strength
436      */
updateLevelWithMeasure(int measure, int[] thresholds)437     private int updateLevelWithMeasure(int measure, int[] thresholds) {
438         int level;
439         if (measure == CellInfo.UNAVAILABLE) {
440             level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
441         } else if (measure >= thresholds[3]) {
442             level = SIGNAL_STRENGTH_GREAT;
443         } else if (measure >= thresholds[2]) {
444             level = SIGNAL_STRENGTH_GOOD;
445         } else if (measure >= thresholds[1]) {
446             level = SIGNAL_STRENGTH_MODERATE;
447         }  else if (measure >= thresholds[0]) {
448             level = SIGNAL_STRENGTH_POOR;
449         } else {
450             level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
451         }
452         return level;
453     }
454 
455     /**
456      * Get the RSRP in ASU.
457      *
458      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
459      *
460      * @return RSRP in ASU 0..97, 255, or UNAVAILABLE
461      */
462     @Override
getAsuLevel()463     public int getAsuLevel() {
464         int asuLevel;
465         int nrDbm = getDbm();
466         if (nrDbm == CellInfo.UNAVAILABLE) {
467             asuLevel = UNKNOWN_ASU_LEVEL;
468         } else if (nrDbm <= -140) {
469             asuLevel = 0;
470         } else if (nrDbm >= -43) {
471             asuLevel = 97;
472         } else {
473             asuLevel = nrDbm + 140;
474         }
475         return asuLevel;
476     }
477 
478     /**
479      * Get the SS-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}.
480      */
481     @Override
getDbm()482     public int getDbm() {
483         return mSsRsrp;
484     }
485 
486     /** @hide */
CellSignalStrengthNr(CellSignalStrengthNr s)487     public CellSignalStrengthNr(CellSignalStrengthNr s) {
488         mCsiRsrp = s.mCsiRsrp;
489         mCsiRsrq = s.mCsiRsrq;
490         mCsiSinr = s.mCsiSinr;
491         mCsiCqiTableIndex = s.mCsiCqiTableIndex;
492         mCsiCqiReport = s.mCsiCqiReport;
493         mSsRsrp = s.mSsRsrp;
494         mSsRsrq = s.mSsRsrq;
495         mSsSinr = s.mSsSinr;
496         mLevel = s.mLevel;
497         mParametersUseForLevel = s.mParametersUseForLevel;
498     }
499 
500     /** @hide */
501     @Override
copy()502     public CellSignalStrengthNr copy() {
503         return new CellSignalStrengthNr(this);
504     }
505 
506     @Override
hashCode()507     public int hashCode() {
508         return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mCsiCqiTableIndex,
509                 mCsiCqiReport, mSsRsrp, mSsRsrq, mSsSinr, mLevel);
510     }
511 
512     private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr();
513 
514     /** @hide */
515     @Override
isValid()516     public boolean isValid() {
517         return !this.equals(sInvalid);
518     }
519 
520     @Override
equals(Object obj)521     public boolean equals(Object obj) {
522         if (obj instanceof CellSignalStrengthNr) {
523             CellSignalStrengthNr o = (CellSignalStrengthNr) obj;
524             return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr
525                     && mCsiCqiTableIndex == o.mCsiCqiTableIndex
526                     && mCsiCqiReport.equals(o.mCsiCqiReport)
527                     && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr
528                     && mLevel == o.mLevel;
529         }
530         return false;
531     }
532 
533     @Override
toString()534     public String toString() {
535         return new StringBuilder()
536                 .append(TAG + ":{")
537                 .append(" csiRsrp = " + mCsiRsrp)
538                 .append(" csiRsrq = " + mCsiRsrq)
539                 .append(" csiCqiTableIndex = " + mCsiCqiTableIndex)
540                 .append(" csiCqiReport = " + mCsiCqiReport)
541                 .append(" ssRsrp = " + mSsRsrp)
542                 .append(" ssRsrq = " + mSsRsrq)
543                 .append(" ssSinr = " + mSsSinr)
544                 .append(" level = " + mLevel)
545                 .append(" parametersUseForLevel = " + mParametersUseForLevel)
546                 .append(" }")
547                 .toString();
548     }
549 
550     /** Implement the Parcelable interface */
551     public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthNr> CREATOR =
552             new Parcelable.Creator<CellSignalStrengthNr>() {
553         @Override
554         public CellSignalStrengthNr createFromParcel(Parcel in) {
555             return new CellSignalStrengthNr(in);
556         }
557 
558         @Override
559         public CellSignalStrengthNr[] newArray(int size) {
560             return new CellSignalStrengthNr[size];
561         }
562     };
563 }
564