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     /**
159      * Timing advance value for a one way trip from cell to device in microseconds.
160      * Approximate distance is calculated using 300m/us * timingAdvance.
161      *
162      * Reference: 3GPP TS 36.213 section 4.2.3.
163      *
164      * Range: [0, 1282]
165      */
166     private int mTimingAdvance;
167 
168     /** @hide */
CellSignalStrengthNr()169     public CellSignalStrengthNr() {
170         setDefaultValues();
171     }
172 
173     /**
174      * @param csiRsrp CSI reference signal received power.
175      * @param csiRsrq CSI reference signal received quality.
176      * @param csiSinr CSI signal-to-noise and interference ratio.
177      * @param csiCqiTableIndex CSI CSI channel quality indicator (CQI) table index.
178      * @param csiCqiReport CSI channel quality indicators (CQI) for all subbands.
179      * @param ssRsrp SS reference signal received power.
180      * @param ssRsrq SS reference signal received quality.
181      * @param ssSinr SS signal-to-noise and interference ratio.
182      * @param timingAdvance Timing advance.
183      * @hide
184      */
CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex, List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr, int timingAdvance)185     public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex,
186             List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr, int timingAdvance) {
187         mCsiRsrp = inRangeOrUnavailable(csiRsrp, -156, -31);
188         mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
189         mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
190         mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3);
191         mCsiCqiReport = csiCqiReport.stream()
192                 .map(cqi -> inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15))
193                 .collect(Collectors.toList());
194         mSsRsrp = inRangeOrUnavailable(ssRsrp, -156, -31);
195         mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20);
196         mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
197         mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
198         updateLevel(null, null);
199     }
200 
201     /**
202      * @param csiRsrp CSI reference signal received power.
203      * @param csiRsrq CSI reference signal received quality.
204      * @param csiSinr CSI signal-to-noise and interference ratio.
205      * @param ssRsrp SS reference signal received power.
206      * @param ssRsrq SS reference signal received quality.
207      * @param ssSinr SS signal-to-noise and interference ratio.
208      * @hide
209      */
CellSignalStrengthNr( int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr)210     public CellSignalStrengthNr(
211             int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) {
212         this(csiRsrp, csiRsrq, csiSinr, CellInfo.UNAVAILABLE, Collections.emptyList(),
213                 ssRsrp, ssRsrq, ssSinr, CellInfo.UNAVAILABLE);
214     }
215 
216     /**
217      * Flip sign cell strength value when taking in the value from hal
218      * @param val cell strength value
219      * @return flipped value
220      * @hide
221      */
flip(int val)222     public static int flip(int val) {
223         return val != CellInfo.UNAVAILABLE ? -val : val;
224     }
225 
226     /**
227      * Reference: 3GPP TS 38.133 10.1.6.1.
228      * Range: -156 dBm to -31 dBm.
229      * @return SS reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported
230      * value.
231      */
getSsRsrp()232     public int getSsRsrp() {
233         return mSsRsrp;
234     }
235 
236     /**
237      * Reference: 3GPP TS 38.215; 3GPP TS 38.133 section 10
238      * Range: -43 dB to 20 dB.
239      * @return SS reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported
240      * value.
241      */
getSsRsrq()242     public int getSsRsrq() {
243         return mSsRsrq;
244     }
245 
246     /**
247      * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1
248      * Range: -23 dB to 40 dB
249      * @return SS signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means
250      * unreported value.
251      */
getSsSinr()252     public int getSsSinr() {
253         return mSsSinr;
254     }
255 
256     /**
257      * Reference: 3GPP TS 38.133 10.1.6.1.
258      * Range: -156 dBm to -31 dBm.
259      * @return CSI reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported
260      * value.
261      */
getCsiRsrp()262     public int getCsiRsrp() {
263         return mCsiRsrp;
264     }
265 
266     /**
267      * Reference: 3GPP TS 38.215.
268      * Range: -20 dB to -3 dB.
269      * @return CSI reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported
270      * value.
271      */
getCsiRsrq()272     public int getCsiRsrq() {
273         return mCsiRsrq;
274     }
275 
276     /**
277      * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1
278      * Range: -23 dB to 23 dB
279      * @return CSI signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means
280      * unreported value.
281      */
getCsiSinr()282     public int getCsiSinr() {
283         return mCsiSinr;
284     }
285 
286     /**
287      * Return CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
288      * The definition of CQI in each table is different.
289      *
290      * Reference: 3GPP TS 138.214 section 5.2.2.1.
291      *
292      * @return the CQI table index if available or
293      *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
294      */
295     @IntRange(from = 1, to = 3)
getCsiCqiTableIndex()296     public int getCsiCqiTableIndex() {
297         return mCsiCqiTableIndex;
298     }
299     /**
300      * Return a list of CSI channel quality indicators (CQI) for all subbands.
301      *
302      * If the CQI report is for the entire wideband, a single CQI index is provided.
303      * If the CQI report is for all subbands, one CQI index is provided for each subband,
304      * in ascending order of subband index.
305      * If CQI is not available, the CQI report is empty.
306      *
307      * Reference: 3GPP TS 138.214 section 5.2.2.1.
308      *
309      * @return the CQIs for all subbands if available or empty list if unavailable.
310      */
311     @NonNull
312     @IntRange(from = 0, to = 15)
getCsiCqiReport()313     public List<Integer> getCsiCqiReport() {
314         return mCsiCqiReport;
315     }
316 
317     /**
318      * Get the timing advance value for a one way trip from cell to device for NR in microseconds.
319      * {@link android.telephony.CellInfo#UNAVAILABLE} is reported when there is no
320      * active RRC connection.
321      *
322      * Reference: 3GPP TS 36.213 section 4.2.3.
323      * Range: 0 us to 1282 us.
324      *
325      * @return the NR timing advance if available or
326      *         {@link android.telephony.CellInfo#UNAVAILABLE} if unavailable.
327      */
328     @IntRange(from = 0, to = 1282)
getTimingAdvanceMicros()329     public int getTimingAdvanceMicros() {
330         return mTimingAdvance;
331     }
332 
333     @Override
describeContents()334     public int describeContents() {
335         return 0;
336     }
337 
338     /** @hide */
339     @Override
writeToParcel(Parcel dest, int flags)340     public void writeToParcel(Parcel dest, int flags) {
341         dest.writeInt(mCsiRsrp);
342         dest.writeInt(mCsiRsrq);
343         dest.writeInt(mCsiSinr);
344         dest.writeInt(mCsiCqiTableIndex);
345         dest.writeList(mCsiCqiReport);
346         dest.writeInt(mSsRsrp);
347         dest.writeInt(mSsRsrq);
348         dest.writeInt(mSsSinr);
349         dest.writeInt(mLevel);
350         dest.writeInt(mTimingAdvance);
351     }
352 
CellSignalStrengthNr(Parcel in)353     private CellSignalStrengthNr(Parcel in) {
354         mCsiRsrp = in.readInt();
355         mCsiRsrq = in.readInt();
356         mCsiSinr = in.readInt();
357         mCsiCqiTableIndex = in.readInt();
358         mCsiCqiReport = in.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class);
359         mSsRsrp = in.readInt();
360         mSsRsrq = in.readInt();
361         mSsSinr = in.readInt();
362         mLevel = in.readInt();
363         mTimingAdvance = in.readInt();
364     }
365 
366     /** @hide */
367     @Override
setDefaultValues()368     public void setDefaultValues() {
369         mCsiRsrp = CellInfo.UNAVAILABLE;
370         mCsiRsrq = CellInfo.UNAVAILABLE;
371         mCsiSinr = CellInfo.UNAVAILABLE;
372         mCsiCqiTableIndex = CellInfo.UNAVAILABLE;
373         mCsiCqiReport = Collections.emptyList();
374         mSsRsrp = CellInfo.UNAVAILABLE;
375         mSsRsrq = CellInfo.UNAVAILABLE;
376         mSsSinr = CellInfo.UNAVAILABLE;
377         mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
378         mParametersUseForLevel = USE_SSRSRP;
379         mTimingAdvance = CellInfo.UNAVAILABLE;
380     }
381 
382     /** {@inheritDoc} */
383     @Override
384     @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
getLevel()385     public int getLevel() {
386         return mLevel;
387     }
388 
389     /**
390      * Checks if the given parameter type is considered to use for {@link #getLevel()}.
391      *
392      * Note: if multiple parameter types are considered, the smaller level for one of the
393      * parameters would be returned by {@link #getLevel()}
394      *
395      * @param parameterType bitwise OR of {@link #USE_SSRSRP}, {@link #USE_SSRSRQ},
396      *         {@link #USE_SSSINR}
397      * @return {@code true} if the level is calculated based on the given parameter type;
398      *      {@code false} otherwise.
399      *
400      */
isLevelForParameter(@ignalLevelAndReportCriteriaSource int parameterType)401     private boolean isLevelForParameter(@SignalLevelAndReportCriteriaSource int parameterType) {
402         return (parameterType & mParametersUseForLevel) == parameterType;
403     }
404 
405     /** @hide */
406     @Override
updateLevel(PersistableBundle cc, ServiceState ss)407     public void updateLevel(PersistableBundle cc, ServiceState ss) {
408         if (cc == null) {
409             mParametersUseForLevel = USE_SSRSRP;
410         } else {
411             mParametersUseForLevel = cc.getInt(
412                     CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, USE_SSRSRP);
413             mSsRsrpThresholds = cc.getIntArray(
414                     CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY);
415             if (VDBG) {
416                 Rlog.i(TAG, "Applying 5G NR SSRSRP Thresholds: "
417                         + Arrays.toString(mSsRsrpThresholds));
418             }
419             mSsRsrqThresholds = cc.getIntArray(
420                     CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY);
421             if (VDBG) {
422                 Rlog.i(TAG, "Applying 5G NR SSRSRQ Thresholds: "
423                         + Arrays.toString(mSsRsrqThresholds));
424             }
425             mSsSinrThresholds = cc.getIntArray(
426                     CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY);
427             if (VDBG) {
428                 Rlog.i(TAG, "Applying 5G NR SSSINR Thresholds: "
429                         + Arrays.toString(mSsSinrThresholds));
430             }
431         }
432         int ssRsrpLevel = SignalStrength.INVALID;
433         int ssRsrqLevel = SignalStrength.INVALID;
434         int ssSinrLevel = SignalStrength.INVALID;
435         if (isLevelForParameter(USE_SSRSRP)) {
436             int rsrpBoost = 0;
437             if (ss != null) {
438                 rsrpBoost = ss.getArfcnRsrpBoost();
439             }
440             ssRsrpLevel = updateLevelWithMeasure(mSsRsrp + rsrpBoost, mSsRsrpThresholds);
441             if (VDBG) {
442                 Rlog.i(TAG, "Updated 5G NR SSRSRP Level: " + ssRsrpLevel);
443             }
444         }
445         if (isLevelForParameter(USE_SSRSRQ)) {
446             ssRsrqLevel = updateLevelWithMeasure(mSsRsrq, mSsRsrqThresholds);
447             if (VDBG) {
448                 Rlog.i(TAG, "Updated 5G NR SSRSRQ Level: " + ssRsrqLevel);
449             }
450         }
451         if (isLevelForParameter(USE_SSSINR)) {
452             ssSinrLevel = updateLevelWithMeasure(mSsSinr, mSsSinrThresholds);
453             if (VDBG) {
454                 Rlog.i(TAG, "Updated 5G NR SSSINR Level: " + ssSinrLevel);
455             }
456         }
457         // Apply the smaller value among three levels of three measures.
458         mLevel = Math.min(Math.min(ssRsrpLevel, ssRsrqLevel), ssSinrLevel);
459     }
460 
461     /**
462      * Update level with corresponding measure and thresholds.
463      *
464      * @param measure corresponding signal measure
465      * @param thresholds corresponding signal thresholds
466      * @return level of the signal strength
467      */
updateLevelWithMeasure(int measure, int[] thresholds)468     private int updateLevelWithMeasure(int measure, int[] thresholds) {
469         int level;
470         if (measure == CellInfo.UNAVAILABLE) {
471             level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
472         } else if (measure >= thresholds[3]) {
473             level = SIGNAL_STRENGTH_GREAT;
474         } else if (measure >= thresholds[2]) {
475             level = SIGNAL_STRENGTH_GOOD;
476         } else if (measure >= thresholds[1]) {
477             level = SIGNAL_STRENGTH_MODERATE;
478         }  else if (measure >= thresholds[0]) {
479             level = SIGNAL_STRENGTH_POOR;
480         } else {
481             level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
482         }
483         return level;
484     }
485 
486     /**
487      * Get the RSRP in ASU.
488      *
489      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
490      *
491      * @return RSRP in ASU 0..97, 255, or UNAVAILABLE
492      */
493     @Override
getAsuLevel()494     public int getAsuLevel() {
495         int asuLevel;
496         int nrDbm = getDbm();
497         if (nrDbm == CellInfo.UNAVAILABLE) {
498             asuLevel = UNKNOWN_ASU_LEVEL;
499         } else if (nrDbm <= -140) {
500             asuLevel = 0;
501         } else if (nrDbm >= -43) {
502             asuLevel = 97;
503         } else {
504             asuLevel = nrDbm + 140;
505         }
506         return asuLevel;
507     }
508 
509     /**
510      * Get the SS-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}.
511      */
512     @Override
getDbm()513     public int getDbm() {
514         return mSsRsrp;
515     }
516 
517     /** @hide */
CellSignalStrengthNr(CellSignalStrengthNr s)518     public CellSignalStrengthNr(CellSignalStrengthNr s) {
519         mCsiRsrp = s.mCsiRsrp;
520         mCsiRsrq = s.mCsiRsrq;
521         mCsiSinr = s.mCsiSinr;
522         mCsiCqiTableIndex = s.mCsiCqiTableIndex;
523         mCsiCqiReport = s.mCsiCqiReport;
524         mSsRsrp = s.mSsRsrp;
525         mSsRsrq = s.mSsRsrq;
526         mSsSinr = s.mSsSinr;
527         mLevel = s.mLevel;
528         mParametersUseForLevel = s.mParametersUseForLevel;
529         mTimingAdvance = s.mTimingAdvance;
530     }
531 
532     /** @hide */
533     @Override
copy()534     public CellSignalStrengthNr copy() {
535         return new CellSignalStrengthNr(this);
536     }
537 
538     @Override
hashCode()539     public int hashCode() {
540         return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mCsiCqiTableIndex,
541                 mCsiCqiReport, mSsRsrp, mSsRsrq, mSsSinr, mLevel, mTimingAdvance);
542     }
543 
544     private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr();
545 
546     /** @hide */
547     @Override
isValid()548     public boolean isValid() {
549         return !this.equals(sInvalid);
550     }
551 
552     @Override
equals(Object obj)553     public boolean equals(Object obj) {
554         if (obj instanceof CellSignalStrengthNr) {
555             CellSignalStrengthNr o = (CellSignalStrengthNr) obj;
556             return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr
557                     && mCsiCqiTableIndex == o.mCsiCqiTableIndex
558                     && mCsiCqiReport.equals(o.mCsiCqiReport)
559                     && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr
560                     && mLevel == o.mLevel && mTimingAdvance == o.mTimingAdvance;
561         }
562         return false;
563     }
564 
565     @Override
toString()566     public String toString() {
567         return new StringBuilder()
568                 .append(TAG + ":{")
569                 .append(" csiRsrp = " + mCsiRsrp)
570                 .append(" csiRsrq = " + mCsiRsrq)
571                 .append(" csiCqiTableIndex = " + mCsiCqiTableIndex)
572                 .append(" csiCqiReport = " + mCsiCqiReport)
573                 .append(" ssRsrp = " + mSsRsrp)
574                 .append(" ssRsrq = " + mSsRsrq)
575                 .append(" ssSinr = " + mSsSinr)
576                 .append(" level = " + mLevel)
577                 .append(" parametersUseForLevel = " + mParametersUseForLevel)
578                 .append(" timingAdvance = " + mTimingAdvance)
579                 .append(" }")
580                 .toString();
581     }
582 
583     /** Implement the Parcelable interface */
584     public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthNr> CREATOR =
585             new Parcelable.Creator<CellSignalStrengthNr>() {
586         @Override
587         public CellSignalStrengthNr createFromParcel(Parcel in) {
588             return new CellSignalStrengthNr(in);
589         }
590 
591         @Override
592         public CellSignalStrengthNr[] newArray(int size) {
593             return new CellSignalStrengthNr[size];
594         }
595     };
596 }
597