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.IntRange; 20 import android.annotation.NonNull; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.os.PersistableBundle; 24 25 import com.android.telephony.Rlog; 26 27 import java.util.Objects; 28 29 /** 30 * Tdscdma signal strength related information. 31 * 32 * This class provides signal strength and signal quality information for the TD-SCDMA air 33 * interface. For more information see 3gpp 25.225. 34 */ 35 public final class CellSignalStrengthTdscdma extends CellSignalStrength implements Parcelable { 36 37 private static final String LOG_TAG = "CellSignalStrengthTdscdma"; 38 private static final boolean DBG = false; 39 40 // These levels are arbitrary but carried over from SignalStrength.java for consistency. 41 private static final int TDSCDMA_RSCP_MAX = -24; 42 private static final int TDSCDMA_RSCP_GREAT = -49; 43 private static final int TDSCDMA_RSCP_GOOD = -73; 44 private static final int TDSCDMA_RSCP_MODERATE = -97; 45 private static final int TDSCDMA_RSCP_POOR = -110; 46 private static final int TDSCDMA_RSCP_MIN = -120; 47 48 49 private int mRssi; // in dBm [-113, -51], CellInfo.UNAVAILABLE 50 51 private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or 52 // CellInfo.UNAVAILABLE if unknown 53 private int mRscp; // Pilot Power in dBm [-120, -24] or CellInfo.UNAVAILABLE 54 // CellInfo.UNAVAILABLE if unknown 55 56 private int mLevel; 57 58 /** @hide */ CellSignalStrengthTdscdma()59 public CellSignalStrengthTdscdma() { 60 setDefaultValues(); 61 } 62 63 /** 64 * @param rssi in dBm [-113, -51] or UNAVAILABLE 65 * @param ber [0-7], 99 or UNAVAILABLE 66 * @param rscp in dBm [-120, -24] or UNAVAILABLE 67 * 68 * @hide 69 */ CellSignalStrengthTdscdma(int rssi, int ber, int rscp)70 public CellSignalStrengthTdscdma(int rssi, int ber, int rscp) { 71 mRssi = inRangeOrUnavailable(rssi, -113, -51); 72 mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99); 73 mRscp = inRangeOrUnavailable(rscp, -120, -24); 74 updateLevel(null, null); 75 } 76 77 /** @hide */ CellSignalStrengthTdscdma(android.hardware.radio.V1_0.TdScdmaSignalStrength tdscdma)78 public CellSignalStrengthTdscdma(android.hardware.radio.V1_0.TdScdmaSignalStrength tdscdma) { 79 // Convert from HAL values as part of construction. 80 this(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE, 81 tdscdma.rscp != CellInfo.UNAVAILABLE ? -tdscdma.rscp : tdscdma.rscp); 82 83 if (mRssi == CellInfo.UNAVAILABLE && mRscp == CellInfo.UNAVAILABLE) { 84 setDefaultValues(); 85 } 86 } 87 88 /** @hide */ CellSignalStrengthTdscdma(android.hardware.radio.V1_2.TdscdmaSignalStrength tdscdma)89 public CellSignalStrengthTdscdma(android.hardware.radio.V1_2.TdscdmaSignalStrength tdscdma) { 90 // Convert from HAL values as part of construction. 91 this(getRssiDbmFromAsu(tdscdma.signalStrength), 92 tdscdma.bitErrorRate, getRscpDbmFromAsu(tdscdma.rscp)); 93 94 if (mRssi == CellInfo.UNAVAILABLE && mRscp == CellInfo.UNAVAILABLE) { 95 setDefaultValues(); 96 } 97 } 98 99 /** @hide */ CellSignalStrengthTdscdma(CellSignalStrengthTdscdma s)100 public CellSignalStrengthTdscdma(CellSignalStrengthTdscdma s) { 101 copyFrom(s); 102 } 103 104 /** @hide */ copyFrom(CellSignalStrengthTdscdma s)105 protected void copyFrom(CellSignalStrengthTdscdma s) { 106 mRssi = s.mRssi; 107 mBitErrorRate = s.mBitErrorRate; 108 mRscp = s.mRscp; 109 mLevel = s.mLevel; 110 } 111 112 /** @hide */ 113 @Override copy()114 public CellSignalStrengthTdscdma copy() { 115 return new CellSignalStrengthTdscdma(this); 116 } 117 118 /** @hide */ 119 @Override setDefaultValues()120 public void setDefaultValues() { 121 mRssi = CellInfo.UNAVAILABLE; 122 mBitErrorRate = CellInfo.UNAVAILABLE; 123 mRscp = CellInfo.UNAVAILABLE; 124 mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 125 } 126 127 128 /** {@inheritDoc} */ 129 @Override 130 @IntRange(from = 0, to = 4) getLevel()131 public int getLevel() { 132 return mLevel; 133 } 134 135 /** @hide */ 136 @Override updateLevel(PersistableBundle cc, ServiceState ss)137 public void updateLevel(PersistableBundle cc, ServiceState ss) { 138 if (mRscp > TDSCDMA_RSCP_MAX) mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 139 else if (mRscp >= TDSCDMA_RSCP_GREAT) mLevel = SIGNAL_STRENGTH_GREAT; 140 else if (mRscp >= TDSCDMA_RSCP_GOOD) mLevel = SIGNAL_STRENGTH_GOOD; 141 else if (mRscp >= TDSCDMA_RSCP_MODERATE) mLevel = SIGNAL_STRENGTH_MODERATE; 142 else if (mRscp >= TDSCDMA_RSCP_POOR) mLevel = SIGNAL_STRENGTH_POOR; 143 else mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 144 } 145 146 /** 147 * Get the RSCP as dBm value -120..-24dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 148 */ 149 @Override getDbm()150 public int getDbm() { 151 return mRscp; 152 } 153 154 /** 155 * Get the RSCP as dBm value -120..-24dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 156 */ getRscp()157 public int getRscp() { 158 return mRscp; 159 } 160 161 /** 162 * Get the RSSI as dBm value -113..-51dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 163 * 164 * @hide 165 */ getRssi()166 public int getRssi() { 167 return mRssi; 168 } 169 170 /** 171 * Get the BER as an ASU value 0..7, 99, or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 172 * @hide 173 */ getBitErrorRate()174 public int getBitErrorRate() { 175 return mBitErrorRate; 176 } 177 178 /** 179 * Get the RSCP in ASU. 180 * 181 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 182 * 183 * @return RSCP in ASU 0..96, 255, or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 184 */ 185 @Override getAsuLevel()186 public int getAsuLevel() { 187 if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp); 188 // For historical reasons, if RSCP is unavailable, this API will very incorrectly return 189 // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+ 190 if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi); 191 return getAsuFromRscpDbm(CellInfo.UNAVAILABLE); 192 } 193 194 @Override hashCode()195 public int hashCode() { 196 return Objects.hash(mRssi, mBitErrorRate, mRscp, mLevel); 197 } 198 199 private static final CellSignalStrengthTdscdma sInvalid = new CellSignalStrengthTdscdma(); 200 201 /** @hide */ 202 @Override isValid()203 public boolean isValid() { 204 return !this.equals(sInvalid); 205 } 206 207 @Override equals(Object o)208 public boolean equals(Object o) { 209 if (!(o instanceof CellSignalStrengthTdscdma)) return false; 210 CellSignalStrengthTdscdma s = (CellSignalStrengthTdscdma) o; 211 212 return mRssi == s.mRssi 213 && mBitErrorRate == s.mBitErrorRate 214 && mRscp == s.mRscp 215 && mLevel == s.mLevel; 216 } 217 218 /** 219 * @return string representation. 220 */ 221 @Override toString()222 public String toString() { 223 return "CellSignalStrengthTdscdma:" 224 + " rssi=" + mRssi 225 + " ber=" + mBitErrorRate 226 + " rscp=" + mRscp 227 + " level=" + mLevel; 228 } 229 230 /** Implement the Parcelable interface */ 231 @Override writeToParcel(Parcel dest, int flags)232 public void writeToParcel(Parcel dest, int flags) { 233 if (DBG) log("writeToParcel(Parcel, int): " + toString()); 234 dest.writeInt(mRssi); 235 dest.writeInt(mBitErrorRate); 236 dest.writeInt(mRscp); 237 dest.writeInt(mLevel); 238 } 239 240 /** 241 * Construct a SignalStrength object from the given parcel 242 * where the token is already been processed. 243 */ CellSignalStrengthTdscdma(Parcel in)244 private CellSignalStrengthTdscdma(Parcel in) { 245 mRssi = in.readInt(); 246 mBitErrorRate = in.readInt(); 247 mRscp = in.readInt(); 248 mLevel = in.readInt(); 249 if (DBG) log("CellSignalStrengthTdscdma(Parcel): " + toString()); 250 } 251 252 /** Implement the Parcelable interface */ 253 @Override describeContents()254 public int describeContents() { 255 return 0; 256 } 257 258 /** Implement the Parcelable interface */ 259 @SuppressWarnings("hiding") 260 @NonNull 261 public static final Parcelable.Creator<CellSignalStrengthTdscdma> CREATOR = 262 new Parcelable.Creator<CellSignalStrengthTdscdma>() { 263 @Override 264 public @NonNull CellSignalStrengthTdscdma createFromParcel(Parcel in) { 265 return new CellSignalStrengthTdscdma(in); 266 } 267 268 @Override 269 public @NonNull CellSignalStrengthTdscdma[] newArray(int size) { 270 return new CellSignalStrengthTdscdma[size]; 271 } 272 }; 273 274 /** 275 * log 276 */ log(String s)277 private static void log(String s) { 278 Rlog.w(LOG_TAG, s); 279 } 280 } 281