blob: f31fafe36508bc660b46bb70e3de4b47583a847e [file] [log] [blame]
Pengquan Mengf922b8e2018-10-29 17:59:26 -07001/*
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
17package android.telephony;
18
Shuo Qianc1f935e2019-11-23 19:09:36 -080019import android.annotation.IntDef;
Nathan Harold78cf8ac2019-04-08 19:21:02 -070020import android.annotation.IntRange;
Pengquan Mengf922b8e2018-10-29 17:59:26 -070021import android.os.Parcel;
22import android.os.Parcelable;
Nathan Haroldf23153f2018-11-19 18:09:40 -080023import android.os.PersistableBundle;
Pengquan Mengf922b8e2018-10-29 17:59:26 -070024
Shuo Qianc1f935e2019-11-23 19:09:36 -080025import java.lang.annotation.Retention;
26import java.lang.annotation.RetentionPolicy;
27import java.util.Arrays;
Pengquan Mengf922b8e2018-10-29 17:59:26 -070028import java.util.Objects;
29
30/**
31 * 5G NR signal strength related information.
32 */
33public final class CellSignalStrengthNr extends CellSignalStrength implements Parcelable {
34 /**
35 * The value is used to indicate that the asu level is unknown.
36 * Reference: 3GPP TS 27.007 section 8.69.
37 * @hide
38 */
39 public static final int UNKNOWN_ASU_LEVEL = 99;
40
41 private static final String TAG = "CellSignalStrengthNr";
42
Shuo Qianc1f935e2019-11-23 19:09:36 -080043 // Lifted from Default carrier configs and max range of SSRSRP
44 // Boundaries: [-140 dB, -44 dB]
45 private int[] mSsRsrpThresholds = new int[] {
46 -125, /* SIGNAL_STRENGTH_POOR */
47 -115, /* SIGNAL_STRENGTH_MODERATE */
48 -105, /* SIGNAL_STRENGTH_GOOD */
49 -95, /* SIGNAL_STRENGTH_GREAT */
50 };
51
52 // Lifted from Default carrier configs and max range of SSRSRQ
53 // Boundaries: [-20 dB, -3 dB]
54 private int[] mSsRsrqThresholds = new int[] {
55 -14, /* SIGNAL_STRENGTH_POOR */
56 -12, /* SIGNAL_STRENGTH_MODERATE */
57 -10, /* SIGNAL_STRENGTH_GOOD */
58 -8 /* SIGNAL_STRENGTH_GREAT */
59 };
60
61 // Lifted from Default carrier configs and max range of SSSINR
62 // Boundaries: [-23 dB, 40 dB]
63 private int[] mSsSinrThresholds = new int[] {
64 -8, /* SIGNAL_STRENGTH_POOR */
65 0, /* SIGNAL_STRENGTH_MODERATE */
66 8, /* SIGNAL_STRENGTH_GOOD */
67 16 /* SIGNAL_STRENGTH_GREAT */
68 };
69
Pengquan Mengf922b8e2018-10-29 17:59:26 -070070 /**
Shuo Qianc1f935e2019-11-23 19:09:36 -080071 * Indicates SSRSRP is considered for {@link #getLevel()} and reporting from modem.
72 *
73 * @hide
Pengquan Mengf922b8e2018-10-29 17:59:26 -070074 */
Shuo Qianc1f935e2019-11-23 19:09:36 -080075 public static final int USE_SSRSRP = 1 << 0;
76 /**
77 * Indicates SSRSRQ is considered for {@link #getLevel()} and reporting from modem.
78 *
79 * @hide
80 */
81 public static final int USE_SSRSRQ = 1 << 1;
82 /**
83 * Indicates SSSINR is considered for {@link #getLevel()} and reporting from modem.
84 *
85 * @hide
86 */
87 public static final int USE_SSSINR = 1 << 2;
88
89 /**
90 * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP),
91 * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference
92 * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the
93 * parameter whose value is smallest is used to indicate the signal bar.
94 *
95 * @hide
96 */
97 @IntDef(flag = true, prefix = { "USE_" }, value = {
98 USE_SSRSRP,
99 USE_SSRSRQ,
100 USE_SSSINR
101 })
102 @Retention(RetentionPolicy.SOURCE)
103 public @interface SignalLevelAndReportCriteriaSource {}
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700104
105 private int mCsiRsrp;
106 private int mCsiRsrq;
107 private int mCsiSinr;
108 private int mSsRsrp;
109 private int mSsRsrq;
110 private int mSsSinr;
Nathan Haroldf23153f2018-11-19 18:09:40 -0800111 private int mLevel;
112
Shuo Qianc1f935e2019-11-23 19:09:36 -0800113 /**
114 * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP),
115 * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference
116 * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the
117 * parameter whose value is smallest is used to indicate the signal bar.
118 *
119 * SSRSRP = 1 << 0,
120 * SSRSRQ = 1 << 1,
121 * SSSINR = 1 << 2,
122 *
123 * For example, if both SSRSRP and SSSINR are used, the value of key is 5 (1 << 0 | 1 << 2).
124 * If the key is invalid or not configured, a default value (SSRSRP = 1 << 0) will apply.
125 */
126 private int mParametersUseForLevel;
127
Nathan Haroldf23153f2018-11-19 18:09:40 -0800128 /** @hide */
129 public CellSignalStrengthNr() {
130 setDefaultValues();
131 }
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700132
133 /**
134 * @param csiRsrp CSI reference signal received power.
135 * @param csiRsrq CSI reference signal received quality.
136 * @param csiSinr CSI signal-to-noise and interference ratio.
137 * @param ssRsrp SS reference signal received power.
138 * @param ssRsrq SS reference signal received quality.
139 * @param ssSinr SS signal-to-noise and interference ratio.
140 * @hide
141 */
142 public CellSignalStrengthNr(
143 int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) {
Nathan Haroldf23153f2018-11-19 18:09:40 -0800144 mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44);
145 mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
146 mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
147 mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
148 mSsRsrq = inRangeOrUnavailable(ssRsrq, -20, -3);
149 mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
150 updateLevel(null, null);
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700151 }
152
153 /**
Pengquan Meng45fcd302019-01-31 16:29:43 -0800154 * @hide
155 * @param ss signal strength from modem.
156 */
157 public CellSignalStrengthNr(android.hardware.radio.V1_4.NrSignalStrength ss) {
158 this(ss.csiRsrp, ss.csiRsrq, ss.csiSinr, ss.ssRsrp, ss.ssRsrq, ss.ssSinr);
159 }
160
161 /**
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700162 * Reference: 3GPP TS 38.215.
163 * Range: -140 dBm to -44 dBm.
164 * @return SS reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported
165 * value.
166 */
167 public int getSsRsrp() {
168 return mSsRsrp;
169 }
170
171 /**
172 * Reference: 3GPP TS 38.215.
173 * Range: -20 dB to -3 dB.
174 * @return SS reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported
175 * value.
176 */
177 public int getSsRsrq() {
178 return mSsRsrq;
179 }
180
181 /**
182 * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1
183 * Range: -23 dB to 40 dB
184 * @return SS signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means
185 * unreported value.
186 */
187 public int getSsSinr() {
188 return mSsSinr;
189 }
190
191 /**
192 * Reference: 3GPP TS 38.215.
193 * Range: -140 dBm to -44 dBm.
194 * @return CSI reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported
195 * value.
196 */
197 public int getCsiRsrp() {
198 return mCsiRsrp;
199 }
200
201 /**
202 * Reference: 3GPP TS 38.215.
203 * Range: -20 dB to -3 dB.
204 * @return CSI reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported
205 * value.
206 */
207 public int getCsiRsrq() {
208 return mCsiRsrq;
209 }
210
211 /**
212 * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1
213 * Range: -23 dB to 23 dB
214 * @return CSI signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means
215 * unreported value.
216 */
217 public int getCsiSinr() {
218 return mCsiSinr;
219 }
220
221 @Override
222 public int describeContents() {
223 return 0;
224 }
225
226 /** @hide */
227 @Override
228 public void writeToParcel(Parcel dest, int flags) {
229 dest.writeInt(mCsiRsrp);
230 dest.writeInt(mCsiRsrq);
231 dest.writeInt(mCsiSinr);
232 dest.writeInt(mSsRsrp);
233 dest.writeInt(mSsRsrq);
234 dest.writeInt(mSsSinr);
Nathan Haroldf23153f2018-11-19 18:09:40 -0800235 dest.writeInt(mLevel);
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700236 }
237
238 private CellSignalStrengthNr(Parcel in) {
239 mCsiRsrp = in.readInt();
240 mCsiRsrq = in.readInt();
241 mCsiSinr = in.readInt();
242 mSsRsrp = in.readInt();
243 mSsRsrq = in.readInt();
244 mSsSinr = in.readInt();
Nathan Haroldf23153f2018-11-19 18:09:40 -0800245 mLevel = in.readInt();
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700246 }
247
248 /** @hide */
249 @Override
250 public void setDefaultValues() {
251 mCsiRsrp = CellInfo.UNAVAILABLE;
252 mCsiRsrq = CellInfo.UNAVAILABLE;
253 mCsiSinr = CellInfo.UNAVAILABLE;
254 mSsRsrp = CellInfo.UNAVAILABLE;
255 mSsRsrq = CellInfo.UNAVAILABLE;
256 mSsSinr = CellInfo.UNAVAILABLE;
Nathan Haroldf23153f2018-11-19 18:09:40 -0800257 mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Shuo Qianc1f935e2019-11-23 19:09:36 -0800258 mParametersUseForLevel = USE_SSRSRP;
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700259 }
260
Nathan Harold78cf8ac2019-04-08 19:21:02 -0700261 /** {@inheritDoc} */
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700262 @Override
Nathan Harold78cf8ac2019-04-08 19:21:02 -0700263 @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700264 public int getLevel() {
Nathan Haroldf23153f2018-11-19 18:09:40 -0800265 return mLevel;
266 }
267
Shuo Qianc1f935e2019-11-23 19:09:36 -0800268 /**
269 * Checks if the given parameter type is considered to use for {@link #getLevel()}.
270 *
271 * Note: if multiple parameter types are considered, the smaller level for one of the
272 * parameters would be returned by {@link #getLevel()}
273 *
274 * @param parameterType bitwise OR of {@link #USE_SSRSRP}, {@link #USE_SSRSRQ},
275 * {@link #USE_SSSINR}
276 * @return {@code true} if the level is calculated based on the given parameter type;
277 * {@code false} otherwise.
278 *
279 */
280 private boolean isLevelForParameter(@SignalLevelAndReportCriteriaSource int parameterType) {
281 return (parameterType & mParametersUseForLevel) == parameterType;
282 }
283
Nathan Haroldf23153f2018-11-19 18:09:40 -0800284 /** @hide */
285 @Override
286 public void updateLevel(PersistableBundle cc, ServiceState ss) {
Shuo Qianc1f935e2019-11-23 19:09:36 -0800287 if (cc == null) {
288 mParametersUseForLevel = USE_SSRSRP;
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700289 } else {
Shuo Qianc1f935e2019-11-23 19:09:36 -0800290 mParametersUseForLevel = cc.getInt(
291 CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, USE_SSRSRP);
292 Rlog.i(TAG, "Using SSRSRP for Level.");
293 mSsRsrpThresholds = cc.getIntArray(
294 CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY);
295 Rlog.i(TAG, "Applying 5G NR SSRSRP Thresholds: " + Arrays.toString(mSsRsrpThresholds));
296 mSsRsrqThresholds = cc.getIntArray(
297 CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY);
298 Rlog.i(TAG, "Applying 5G NR SSRSRQ Thresholds: " + Arrays.toString(mSsRsrqThresholds));
299 mSsSinrThresholds = cc.getIntArray(
300 CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY);
301 Rlog.i(TAG, "Applying 5G NR SSSINR Thresholds: " + Arrays.toString(mSsSinrThresholds));
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700302 }
Shuo Qianc1f935e2019-11-23 19:09:36 -0800303 int ssRsrpLevel = SignalStrength.INVALID;
304 int ssRsrqLevel = SignalStrength.INVALID;
305 int ssSinrLevel = SignalStrength.INVALID;
306 if (isLevelForParameter(USE_SSRSRP)) {
307 ssRsrpLevel = updateLevelWithMeasure(mSsRsrp, mSsRsrpThresholds);
308 Rlog.i(TAG, "Updated 5G NR SSRSRP Level: " + ssRsrpLevel);
309 }
310 if (isLevelForParameter(USE_SSRSRQ)) {
311 ssRsrqLevel = updateLevelWithMeasure(mSsRsrq, mSsRsrqThresholds);
312 Rlog.i(TAG, "Updated 5G NR SSRSRQ Level: " + ssRsrqLevel);
313 }
314 if (isLevelForParameter(USE_SSSINR)) {
315 ssSinrLevel = updateLevelWithMeasure(mSsSinr, mSsSinrThresholds);
316 Rlog.i(TAG, "Updated 5G NR SSSINR Level: " + ssSinrLevel);
317 }
318 // Apply the smaller value among three levels of three measures.
319 mLevel = Math.min(Math.min(ssRsrpLevel, ssRsrqLevel), ssSinrLevel);
320 }
321
322 /**
323 * Update level with corresponding measure and thresholds.
324 *
325 * @param measure corresponding signal measure
326 * @param thresholds corresponding signal thresholds
327 * @return level of the signal strength
328 */
329 private int updateLevelWithMeasure(int measure, int[] thresholds) {
330 int level;
331 if (measure == CellInfo.UNAVAILABLE) {
332 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
333 } else if (measure > thresholds[3]) {
334 level = SIGNAL_STRENGTH_GREAT;
335 } else if (measure > thresholds[2]) {
336 level = SIGNAL_STRENGTH_GOOD;
337 } else if (measure > thresholds[1]) {
338 level = SIGNAL_STRENGTH_MODERATE;
339 } else if (measure > thresholds[0]) {
340 level = SIGNAL_STRENGTH_POOR;
341 } else {
342 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
343 }
344 return level;
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700345 }
346
347 /**
Nathan Haroldf23153f2018-11-19 18:09:40 -0800348 * Get the RSRP in ASU.
349 *
350 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
351 *
Nathan Harold1f107352019-10-22 14:50:53 -0700352 * @return RSRP in ASU 0..97, 255, or UNAVAILABLE
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700353 */
354 @Override
355 public int getAsuLevel() {
356 int asuLevel;
357 int nrDbm = getDbm();
358 if (nrDbm == CellInfo.UNAVAILABLE) {
359 asuLevel = UNKNOWN_ASU_LEVEL;
360 } else if (nrDbm <= -140) {
361 asuLevel = 0;
362 } else if (nrDbm >= -43) {
363 asuLevel = 97;
364 } else {
365 asuLevel = nrDbm + 140;
366 }
367 return asuLevel;
368 }
369
Nathan Harold78cf8ac2019-04-08 19:21:02 -0700370 /**
Nathan Harold1f107352019-10-22 14:50:53 -0700371 * Get the SS-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}.
Nathan Harold78cf8ac2019-04-08 19:21:02 -0700372 */
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700373 @Override
374 public int getDbm() {
Nathan Harold1f107352019-10-22 14:50:53 -0700375 return mSsRsrp;
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700376 }
377
378 /** @hide */
Nathan Haroldf23153f2018-11-19 18:09:40 -0800379 public CellSignalStrengthNr(CellSignalStrengthNr s) {
380 mCsiRsrp = s.mCsiRsrp;
381 mCsiRsrq = s.mCsiRsrq;
382 mCsiSinr = s.mCsiSinr;
383 mSsRsrp = s.mSsRsrp;
384 mSsRsrq = s.mSsRsrq;
385 mSsSinr = s.mSsSinr;
386 mLevel = s.mLevel;
Shuo Qianc1f935e2019-11-23 19:09:36 -0800387 mParametersUseForLevel = s.mParametersUseForLevel;
Nathan Haroldf23153f2018-11-19 18:09:40 -0800388 }
389
390 /** @hide */
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700391 @Override
Nathan Haroldf23153f2018-11-19 18:09:40 -0800392 public CellSignalStrengthNr copy() {
393 return new CellSignalStrengthNr(this);
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700394 }
395
396 @Override
397 public int hashCode() {
Nathan Haroldf23153f2018-11-19 18:09:40 -0800398 return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr, mLevel);
399 }
400
401 private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr();
402
403 /** @hide */
404 @Override
405 public boolean isValid() {
406 return !this.equals(sInvalid);
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700407 }
408
409 @Override
410 public boolean equals(Object obj) {
411 if (obj instanceof CellSignalStrengthNr) {
412 CellSignalStrengthNr o = (CellSignalStrengthNr) obj;
413 return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr
Nathan Haroldf23153f2018-11-19 18:09:40 -0800414 && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr
415 && mLevel == o.mLevel;
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700416 }
417 return false;
418 }
419
420 @Override
421 public String toString() {
422 return new StringBuilder()
423 .append(TAG + ":{")
424 .append(" csiRsrp = " + mCsiRsrp)
425 .append(" csiRsrq = " + mCsiRsrq)
426 .append(" csiSinr = " + mCsiSinr)
427 .append(" ssRsrp = " + mSsRsrp)
428 .append(" ssRsrq = " + mSsRsrq)
429 .append(" ssSinr = " + mSsSinr)
Nathan Haroldf23153f2018-11-19 18:09:40 -0800430 .append(" level = " + mLevel)
Shuo Qianc1f935e2019-11-23 19:09:36 -0800431 .append(" parametersUseForLevel = " + mParametersUseForLevel)
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700432 .append(" }")
433 .toString();
434 }
435
436 /** Implement the Parcelable interface */
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700437 public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthNr> CREATOR =
Pengquan Mengf922b8e2018-10-29 17:59:26 -0700438 new Parcelable.Creator<CellSignalStrengthNr>() {
439 @Override
440 public CellSignalStrengthNr createFromParcel(Parcel in) {
441 return new CellSignalStrengthNr(in);
442 }
443
444 @Override
445 public CellSignalStrengthNr[] newArray(int size) {
446 return new CellSignalStrengthNr[size];
447 }
448 };
449}