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