628 lines
21 KiB
Java
628 lines
21 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2012 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package android.telephony;
|
||
|
|
||
|
import android.annotation.IntRange;
|
||
|
import android.compat.annotation.UnsupportedAppUsage;
|
||
|
import android.os.Build;
|
||
|
import android.os.Parcel;
|
||
|
import android.os.Parcelable;
|
||
|
import android.os.PersistableBundle;
|
||
|
|
||
|
import com.android.telephony.Rlog;
|
||
|
|
||
|
import java.util.Arrays;
|
||
|
import java.util.Objects;
|
||
|
|
||
|
/**
|
||
|
* LTE signal strength related information.
|
||
|
*/
|
||
|
public final class CellSignalStrengthLte extends CellSignalStrength implements Parcelable {
|
||
|
|
||
|
private static final String LOG_TAG = "CellSignalStrengthLte";
|
||
|
private static final boolean DBG = false;
|
||
|
|
||
|
/**
|
||
|
* Indicates the unknown or undetectable RSSI value in ASU.
|
||
|
*
|
||
|
* Reference: TS 27.007 8.5 - Signal quality +CSQ
|
||
|
*/
|
||
|
private static final int SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN = 99;
|
||
|
/**
|
||
|
* Indicates the maximum valid RSSI value in ASU.
|
||
|
*
|
||
|
* Reference: TS 27.007 8.5 - Signal quality +CSQ
|
||
|
*/
|
||
|
private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE = 31;
|
||
|
/**
|
||
|
* Indicates the minimum valid RSSI value in ASU.
|
||
|
*
|
||
|
* Reference: TS 27.007 8.5 - Signal quality +CSQ
|
||
|
*/
|
||
|
private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0;
|
||
|
|
||
|
private static final int MAX_LTE_RSRP = -44;
|
||
|
private static final int MIN_LTE_RSRP = -140;
|
||
|
|
||
|
/**
|
||
|
* Indicates RSRP is considered for {@link #getLevel()} and reported from modem.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int USE_RSRP = 1 << 0;
|
||
|
/**
|
||
|
* Indicates RSRQ is considered for {@link #getLevel()} and reported from modem.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int USE_RSRQ = 1 << 1;
|
||
|
/**
|
||
|
* Indicates RSSNR is considered for {@link #getLevel()} and reported from modem.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public static final int USE_RSSNR = 1 << 2;
|
||
|
|
||
|
@UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
|
||
|
private int mSignalStrength; // To be removed
|
||
|
private int mRssi;
|
||
|
@UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
|
||
|
private int mRsrp;
|
||
|
@UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
|
||
|
private int mRsrq;
|
||
|
@UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
|
||
|
private int mRssnr;
|
||
|
/**
|
||
|
* CSI channel quality indicator (CQI) table index. There are multiple CQI tables.
|
||
|
* The definition of CQI in each table is different.
|
||
|
*
|
||
|
* Reference: 3GPP TS 136.213 section 7.2.3.
|
||
|
*
|
||
|
* Range [1, 6].
|
||
|
*/
|
||
|
private int mCqiTableIndex;
|
||
|
@UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
|
||
|
private int mCqi;
|
||
|
@UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
|
||
|
private int mTimingAdvance;
|
||
|
private int mLevel;
|
||
|
|
||
|
/**
|
||
|
* Bit-field integer to determine whether to use Reference Signal Received Power (RSRP),
|
||
|
* Reference Signal Received Quality (RSRQ), and/or Reference Signal Signal to Noise Ratio
|
||
|
* (RSSNR) for the number of LTE signal bars. If multiple measures are set, the parameter
|
||
|
* whose signal level value is smallest is used to indicate the signal level.
|
||
|
*
|
||
|
* RSRP = 1 << 0,
|
||
|
* RSRQ = 1 << 1,
|
||
|
* RSSNR = 1 << 2,
|
||
|
*
|
||
|
* For example, if both RSRP and RSRQ are used, the value of key is 3 (1 << 0 | 1 << 1).
|
||
|
* If the key is invalid or not configured, a default value (RSRP = 1 << 0) will apply.
|
||
|
*/
|
||
|
private int mParametersUseForLevel;
|
||
|
|
||
|
/** @hide */
|
||
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||
|
public CellSignalStrengthLte() {
|
||
|
setDefaultValues();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Construct a cell signal strength
|
||
|
*
|
||
|
* @param rssi in dBm [-113,-51], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param rsrp in dBm [-140,-43], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param rsrq in dB [-34, 3], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param rssnr in dB [-20, +30], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param cqiTableIndex [1, 6], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param cqi [0, 15], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param timingAdvance [0, 1282], {@link CellInfo#UNAVAILABLE}
|
||
|
*
|
||
|
*/
|
||
|
/** @hide */
|
||
|
public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqiTableIndex,
|
||
|
int cqi, int timingAdvance) {
|
||
|
mRssi = inRangeOrUnavailable(rssi, -113, -51);
|
||
|
mSignalStrength = mRssi;
|
||
|
mRsrp = inRangeOrUnavailable(rsrp, -140, -43);
|
||
|
mRsrq = inRangeOrUnavailable(rsrq, -34, 3);
|
||
|
mRssnr = inRangeOrUnavailable(rssnr, -20, 30);
|
||
|
mCqiTableIndex = inRangeOrUnavailable(cqiTableIndex, 1, 6);
|
||
|
mCqi = inRangeOrUnavailable(cqi, 0, 15);
|
||
|
mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
|
||
|
updateLevel(null, null);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Construct a cell signal strength
|
||
|
*
|
||
|
* @param rssi in dBm [-113,-51], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param rsrp in dBm [-140,-43], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param rsrq in dB [-34, 3], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param rssnr in dB [-20, +30], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param cqi [0, 15], {@link CellInfo#UNAVAILABLE}
|
||
|
* @param timingAdvance [0, 1282], {@link CellInfo#UNAVAILABLE}
|
||
|
*
|
||
|
*/
|
||
|
/** @hide */
|
||
|
public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi,
|
||
|
int timingAdvance) {
|
||
|
this(rssi, rsrp, rsrq, rssnr, CellInfo.UNAVAILABLE, cqi, timingAdvance);
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
public CellSignalStrengthLte(CellSignalStrengthLte s) {
|
||
|
copyFrom(s);
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
protected void copyFrom(CellSignalStrengthLte s) {
|
||
|
mSignalStrength = s.mSignalStrength;
|
||
|
mRssi = s.mRssi;
|
||
|
mRsrp = s.mRsrp;
|
||
|
mRsrq = s.mRsrq;
|
||
|
mRssnr = s.mRssnr;
|
||
|
mCqiTableIndex = s.mCqiTableIndex;
|
||
|
mCqi = s.mCqi;
|
||
|
mTimingAdvance = s.mTimingAdvance;
|
||
|
mLevel = s.mLevel;
|
||
|
mParametersUseForLevel = s.mParametersUseForLevel;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@Override
|
||
|
public CellSignalStrengthLte copy() {
|
||
|
return new CellSignalStrengthLte(this);
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@Override
|
||
|
public void setDefaultValues() {
|
||
|
mSignalStrength = CellInfo.UNAVAILABLE;
|
||
|
mRssi = CellInfo.UNAVAILABLE;
|
||
|
mRsrp = CellInfo.UNAVAILABLE;
|
||
|
mRsrq = CellInfo.UNAVAILABLE;
|
||
|
mRssnr = CellInfo.UNAVAILABLE;
|
||
|
mCqiTableIndex = CellInfo.UNAVAILABLE;
|
||
|
mCqi = CellInfo.UNAVAILABLE;
|
||
|
mTimingAdvance = CellInfo.UNAVAILABLE;
|
||
|
mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
||
|
mParametersUseForLevel = USE_RSRP;
|
||
|
}
|
||
|
|
||
|
/** {@inheritDoc} */
|
||
|
@Override
|
||
|
@IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
|
||
|
public int getLevel() {
|
||
|
return mLevel;
|
||
|
}
|
||
|
|
||
|
// Lifted from Default carrier configs and max range of RSRP
|
||
|
private static final int[] sRsrpThresholds = new int[] {
|
||
|
-115, /* SIGNAL_STRENGTH_POOR */
|
||
|
-105, /* SIGNAL_STRENGTH_MODERATE */
|
||
|
-95, /* SIGNAL_STRENGTH_GOOD */
|
||
|
-85 /* SIGNAL_STRENGTH_GREAT */
|
||
|
};
|
||
|
|
||
|
// Lifted from Default carrier configs and max range of RSRQ
|
||
|
private static final int[] sRsrqThresholds = new int[] {
|
||
|
-19, /* SIGNAL_STRENGTH_POOR */
|
||
|
-17, /* SIGNAL_STRENGTH_MODERATE */
|
||
|
-14, /* SIGNAL_STRENGTH_GOOD */
|
||
|
-12 /* SIGNAL_STRENGTH_GREAT */
|
||
|
};
|
||
|
// Lifted from Default carrier configs and max range of RSSNR
|
||
|
private static final int[] sRssnrThresholds = new int[] {
|
||
|
-3, /* SIGNAL_STRENGTH_POOR */
|
||
|
1, /* SIGNAL_STRENGTH_MODERATE */
|
||
|
5, /* SIGNAL_STRENGTH_GOOD */
|
||
|
13 /* SIGNAL_STRENGTH_GREAT */
|
||
|
};
|
||
|
private static final int sRsrpBoost = 0;
|
||
|
|
||
|
/**
|
||
|
* Checks if the given parameter type is considered to use for {@link #getLevel()}.
|
||
|
*
|
||
|
* Note: if multiple parameter types are considered, the smaller level for one of the
|
||
|
* parameters would be returned by {@link #getLevel()}
|
||
|
*
|
||
|
* @param parameterType bitwise OR of {@link #USE_RSRP}, {@link #USE_RSRQ},
|
||
|
* {@link #USE_RSSNR}
|
||
|
* @return {@code true} if the level is calculated based on the given parameter type;
|
||
|
* {@code false} otherwise.
|
||
|
*/
|
||
|
private boolean isLevelForParameter(int parameterType) {
|
||
|
return (parameterType & mParametersUseForLevel) == parameterType;
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
@Override
|
||
|
public void updateLevel(PersistableBundle cc, ServiceState ss) {
|
||
|
int[] rsrpThresholds, rsrqThresholds, rssnrThresholds;
|
||
|
boolean rsrpOnly;
|
||
|
if (cc == null) {
|
||
|
mParametersUseForLevel = USE_RSRP;
|
||
|
rsrpThresholds = sRsrpThresholds;
|
||
|
rsrqThresholds = sRsrqThresholds;
|
||
|
rssnrThresholds = sRssnrThresholds;
|
||
|
rsrpOnly = false;
|
||
|
} else {
|
||
|
if (ss != null && ss.isUsingNonTerrestrialNetwork()) {
|
||
|
if (DBG) log("updateLevel: from NTN_LTE");
|
||
|
mParametersUseForLevel = cc.getInt(
|
||
|
CarrierConfigManager.KEY_PARAMETERS_USED_FOR_NTN_LTE_SIGNAL_BAR_INT);
|
||
|
rsrpThresholds = cc.getIntArray(
|
||
|
CarrierConfigManager.KEY_NTN_LTE_RSRP_THRESHOLDS_INT_ARRAY);
|
||
|
rsrqThresholds = cc.getIntArray(
|
||
|
CarrierConfigManager.KEY_NTN_LTE_RSRQ_THRESHOLDS_INT_ARRAY);
|
||
|
rssnrThresholds = cc.getIntArray(
|
||
|
CarrierConfigManager.KEY_NTN_LTE_RSSNR_THRESHOLDS_INT_ARRAY);
|
||
|
} else {
|
||
|
mParametersUseForLevel = cc.getInt(
|
||
|
CarrierConfigManager.KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT);
|
||
|
rsrpThresholds = cc.getIntArray(
|
||
|
CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
|
||
|
rsrqThresholds = cc.getIntArray(
|
||
|
CarrierConfigManager.KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY);
|
||
|
rssnrThresholds = cc.getIntArray(
|
||
|
CarrierConfigManager.KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY);
|
||
|
}
|
||
|
if (rsrpThresholds == null) rsrpThresholds = sRsrpThresholds;
|
||
|
if (rsrqThresholds == null) rsrqThresholds = sRsrqThresholds;
|
||
|
if (rssnrThresholds == null) rssnrThresholds = sRssnrThresholds;
|
||
|
if (DBG) {
|
||
|
Rlog.i(LOG_TAG, "Using signal strength level: " + mParametersUseForLevel);
|
||
|
Rlog.i(LOG_TAG, "Applying LTE RSRP Thresholds: "
|
||
|
+ Arrays.toString(rsrpThresholds));
|
||
|
Rlog.i(LOG_TAG, "Applying LTE RSRQ Thresholds: "
|
||
|
+ Arrays.toString(rsrqThresholds));
|
||
|
Rlog.i(LOG_TAG, "Applying LTE RSSNR Thresholds: "
|
||
|
+ Arrays.toString(rssnrThresholds));
|
||
|
}
|
||
|
rsrpOnly = cc.getBoolean(
|
||
|
CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, false);
|
||
|
}
|
||
|
|
||
|
int rsrpBoost = 0;
|
||
|
if (ss != null) {
|
||
|
rsrpBoost = ss.getArfcnRsrpBoost();
|
||
|
}
|
||
|
|
||
|
int rsrp = inRangeOrUnavailable(mRsrp + rsrpBoost, MIN_LTE_RSRP, MAX_LTE_RSRP);
|
||
|
|
||
|
if (rsrpOnly) {
|
||
|
int level = updateLevelWithMeasure(rsrp, rsrpThresholds);
|
||
|
if (DBG) log("updateLevel() - rsrp = " + level);
|
||
|
if (level != SignalStrength.INVALID) {
|
||
|
mLevel = level;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int rsrpLevel = SignalStrength.INVALID;
|
||
|
int rsrqLevel = SignalStrength.INVALID;
|
||
|
int rssnrLevel = SignalStrength.INVALID;
|
||
|
|
||
|
if (isLevelForParameter(USE_RSRP)) {
|
||
|
rsrpLevel = updateLevelWithMeasure(rsrp, rsrpThresholds);
|
||
|
if (DBG) {
|
||
|
Rlog.i(LOG_TAG, "Updated 4G LTE RSRP Level: " + rsrpLevel);
|
||
|
}
|
||
|
}
|
||
|
if (isLevelForParameter(USE_RSRQ)) {
|
||
|
rsrqLevel = updateLevelWithMeasure(mRsrq, rsrqThresholds);
|
||
|
if (DBG) {
|
||
|
Rlog.i(LOG_TAG, "Updated 4G LTE RSRQ Level: " + rsrqLevel);
|
||
|
}
|
||
|
}
|
||
|
if (isLevelForParameter(USE_RSSNR)) {
|
||
|
rssnrLevel = updateLevelWithMeasure(mRssnr, rssnrThresholds);
|
||
|
if (DBG) {
|
||
|
Rlog.i(LOG_TAG, "Updated 4G LTE RSSNR Level: " + rssnrLevel);
|
||
|
}
|
||
|
}
|
||
|
// Apply the smaller value among three levels of three measures.
|
||
|
mLevel = Math.min(Math.min(rsrpLevel, rsrqLevel), rssnrLevel);
|
||
|
|
||
|
if (mLevel == SignalStrength.INVALID) {
|
||
|
int rssiLevel;
|
||
|
if (mRssi > -51) {
|
||
|
rssiLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
||
|
} else if (mRssi >= -89) {
|
||
|
rssiLevel = SIGNAL_STRENGTH_GREAT;
|
||
|
} else if (mRssi >= -97) {
|
||
|
rssiLevel = SIGNAL_STRENGTH_GOOD;
|
||
|
} else if (mRssi >= -103) {
|
||
|
rssiLevel = SIGNAL_STRENGTH_MODERATE;
|
||
|
} else if (mRssi >= -113) {
|
||
|
rssiLevel = SIGNAL_STRENGTH_POOR;
|
||
|
} else {
|
||
|
rssiLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
||
|
}
|
||
|
if (DBG) log("getLteLevel - rssi:" + mRssi + " rssiIconLevel:" + rssiLevel);
|
||
|
mLevel = rssiLevel;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update level with corresponding measure and thresholds.
|
||
|
*
|
||
|
* @param measure corresponding signal measure
|
||
|
* @param thresholds corresponding signal thresholds
|
||
|
* @return level of the signal strength
|
||
|
*/
|
||
|
private int updateLevelWithMeasure(int measure, int[] thresholds) {
|
||
|
int level;
|
||
|
if (measure == CellInfo.UNAVAILABLE) {
|
||
|
level = SignalStrength.INVALID;
|
||
|
} else if (measure >= thresholds[3]) {
|
||
|
level = SIGNAL_STRENGTH_GREAT;
|
||
|
} else if (measure >= thresholds[2]) {
|
||
|
level = SIGNAL_STRENGTH_GOOD;
|
||
|
} else if (measure >= thresholds[1]) {
|
||
|
level = SIGNAL_STRENGTH_MODERATE;
|
||
|
} else if (measure >= thresholds[0]) {
|
||
|
level = SIGNAL_STRENGTH_POOR;
|
||
|
} else {
|
||
|
level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
|
||
|
}
|
||
|
return level;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get reference signal received quality
|
||
|
*
|
||
|
* @return the RSRQ if available or
|
||
|
* {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
|
||
|
*/
|
||
|
public int getRsrq() {
|
||
|
return mRsrq;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get Received Signal Strength Indication (RSSI) in dBm
|
||
|
*
|
||
|
* The value range is [-113, -51] inclusively or {@link CellInfo#UNAVAILABLE} if unavailable.
|
||
|
*
|
||
|
* Reference: TS 27.007 8.5 Signal quality +CSQ
|
||
|
*
|
||
|
* @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable.
|
||
|
*/
|
||
|
public int getRssi() {
|
||
|
return mRssi;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get reference signal signal-to-noise ratio in dB
|
||
|
* Range: -20 dB to +30 dB.
|
||
|
*
|
||
|
* @return the RSSNR if available or
|
||
|
* {@link android.telephony.CellInfo#UNAVAILABLE} if unavailable.
|
||
|
*/
|
||
|
public int getRssnr() {
|
||
|
return mRssnr;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get reference signal received power in dBm
|
||
|
* Range: -140 dBm to -43 dBm.
|
||
|
*
|
||
|
* @return the RSRP of the measured cell or {@link CellInfo#UNAVAILABLE} if
|
||
|
* unavailable.
|
||
|
*/
|
||
|
public int getRsrp() {
|
||
|
return mRsrp;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get table index for channel quality indicator
|
||
|
*
|
||
|
* Reference: 3GPP TS 136.213 section 7.2.3.
|
||
|
*
|
||
|
* @return the CQI table index if available or
|
||
|
* {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
|
||
|
*/
|
||
|
@IntRange(from = 1, to = 6)
|
||
|
public int getCqiTableIndex() {
|
||
|
return mCqiTableIndex;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get channel quality indicator
|
||
|
*
|
||
|
* Reference: 3GPP TS 136.213 section 7.2.3.
|
||
|
*
|
||
|
* @return the CQI if available or
|
||
|
* {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
|
||
|
*/
|
||
|
@IntRange(from = 0, to = 15)
|
||
|
public int getCqi() {
|
||
|
return mCqi;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get signal strength in dBm
|
||
|
*
|
||
|
* @return the RSRP of the measured cell.
|
||
|
*/
|
||
|
@Override
|
||
|
public int getDbm() {
|
||
|
return mRsrp;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the RSRP in ASU.
|
||
|
*
|
||
|
* Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
|
||
|
*
|
||
|
* @return RSCP in ASU 0..97, 255, or UNAVAILABLE
|
||
|
*/
|
||
|
@Override
|
||
|
public int getAsuLevel() {
|
||
|
int lteAsuLevel = 99;
|
||
|
int lteDbm = mRsrp;
|
||
|
if (lteDbm == CellInfo.UNAVAILABLE) lteAsuLevel = 99;
|
||
|
else if (lteDbm <= -140) lteAsuLevel = 0;
|
||
|
else if (lteDbm >= -43) lteAsuLevel = 97;
|
||
|
else lteAsuLevel = lteDbm + 140;
|
||
|
if (DBG) log("Lte Asu level: "+lteAsuLevel);
|
||
|
return lteAsuLevel;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the timing advance value for LTE, as a value in range of 0..1282.
|
||
|
* {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} is reported when there is no
|
||
|
* active RRC connection. Refer to 3GPP 36.213 Sec 4.2.3
|
||
|
*
|
||
|
* @return the LTE timing advance if available or
|
||
|
* {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
|
||
|
*/
|
||
|
public int getTimingAdvance() {
|
||
|
return mTimingAdvance;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int hashCode() {
|
||
|
return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqiTableIndex, mCqi, mTimingAdvance,
|
||
|
mLevel);
|
||
|
}
|
||
|
|
||
|
private static final CellSignalStrengthLte sInvalid = new CellSignalStrengthLte();
|
||
|
|
||
|
/** @hide */
|
||
|
@Override
|
||
|
public boolean isValid() {
|
||
|
return !this.equals(sInvalid);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean equals (Object o) {
|
||
|
CellSignalStrengthLte s;
|
||
|
|
||
|
if (!(o instanceof CellSignalStrengthLte)) return false;
|
||
|
s = (CellSignalStrengthLte) o;
|
||
|
|
||
|
return mRssi == s.mRssi
|
||
|
&& mRsrp == s.mRsrp
|
||
|
&& mRsrq == s.mRsrq
|
||
|
&& mRssnr == s.mRssnr
|
||
|
&& mCqiTableIndex == s.mCqiTableIndex
|
||
|
&& mCqi == s.mCqi
|
||
|
&& mTimingAdvance == s.mTimingAdvance
|
||
|
&& mLevel == s.mLevel;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return string representation.
|
||
|
*/
|
||
|
@Override
|
||
|
public String toString() {
|
||
|
return "CellSignalStrengthLte:"
|
||
|
+ " rssi=" + mRssi
|
||
|
+ " rsrp=" + mRsrp
|
||
|
+ " rsrq=" + mRsrq
|
||
|
+ " rssnr=" + mRssnr
|
||
|
+ " cqiTableIndex=" + mCqiTableIndex
|
||
|
+ " cqi=" + mCqi
|
||
|
+ " ta=" + mTimingAdvance
|
||
|
+ " level=" + mLevel
|
||
|
+ " parametersUseForLevel=" + mParametersUseForLevel;
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface */
|
||
|
@Override
|
||
|
public void writeToParcel(Parcel dest, int flags) {
|
||
|
if (DBG) log("writeToParcel(Parcel, int): " + toString());
|
||
|
dest.writeInt(mRssi);
|
||
|
// Need to multiply rsrp and rsrq by -1
|
||
|
// to ensure consistency when reading values written here
|
||
|
// unless the values are invalid
|
||
|
dest.writeInt(mRsrp);
|
||
|
dest.writeInt(mRsrq);
|
||
|
dest.writeInt(mRssnr);
|
||
|
dest.writeInt(mCqiTableIndex);
|
||
|
dest.writeInt(mCqi);
|
||
|
dest.writeInt(mTimingAdvance);
|
||
|
dest.writeInt(mLevel);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Construct a SignalStrength object from the given parcel
|
||
|
* where the token is already been processed.
|
||
|
*/
|
||
|
private CellSignalStrengthLte(Parcel in) {
|
||
|
mRssi = in.readInt();
|
||
|
mSignalStrength = mRssi;
|
||
|
mRsrp = in.readInt();
|
||
|
mRsrq = in.readInt();
|
||
|
mRssnr = in.readInt();
|
||
|
mCqiTableIndex = in.readInt();
|
||
|
mCqi = in.readInt();
|
||
|
mTimingAdvance = in.readInt();
|
||
|
mLevel = in.readInt();
|
||
|
if (DBG) log("CellSignalStrengthLte(Parcel): " + toString());
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface */
|
||
|
@Override
|
||
|
public int describeContents() {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/** Implement the Parcelable interface */
|
||
|
@SuppressWarnings("hiding")
|
||
|
public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthLte> CREATOR =
|
||
|
new Parcelable.Creator<CellSignalStrengthLte>() {
|
||
|
@Override
|
||
|
public CellSignalStrengthLte createFromParcel(Parcel in) {
|
||
|
return new CellSignalStrengthLte(in);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public CellSignalStrengthLte[] newArray(int size) {
|
||
|
return new CellSignalStrengthLte[size];
|
||
|
}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* log
|
||
|
*/
|
||
|
private static void log(String s) {
|
||
|
Rlog.w(LOG_TAG, s);
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
public static int convertRssnrUnitFromTenDbToDB(int rssnr) {
|
||
|
return (int) Math.floor((float) rssnr / 10);
|
||
|
}
|
||
|
|
||
|
/** @hide */
|
||
|
public static int convertRssiAsuToDBm(int rssiAsu) {
|
||
|
if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
|
||
|
return CellInfo.UNAVAILABLE;
|
||
|
}
|
||
|
if ((rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
|
||
|
|| rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
|
||
|
Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
|
||
|
return CellInfo.UNAVAILABLE;
|
||
|
}
|
||
|
return -113 + (2 * rssiAsu);
|
||
|
}
|
||
|
}
|