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(CellSignalStrengthTdscdma s)78 public CellSignalStrengthTdscdma(CellSignalStrengthTdscdma s) { 79 copyFrom(s); 80 } 81 82 /** @hide */ copyFrom(CellSignalStrengthTdscdma s)83 protected void copyFrom(CellSignalStrengthTdscdma s) { 84 mRssi = s.mRssi; 85 mBitErrorRate = s.mBitErrorRate; 86 mRscp = s.mRscp; 87 mLevel = s.mLevel; 88 } 89 90 /** @hide */ 91 @Override copy()92 public CellSignalStrengthTdscdma copy() { 93 return new CellSignalStrengthTdscdma(this); 94 } 95 96 /** @hide */ 97 @Override setDefaultValues()98 public void setDefaultValues() { 99 mRssi = CellInfo.UNAVAILABLE; 100 mBitErrorRate = CellInfo.UNAVAILABLE; 101 mRscp = CellInfo.UNAVAILABLE; 102 mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 103 } 104 105 106 /** {@inheritDoc} */ 107 @Override 108 @IntRange(from = 0, to = 4) getLevel()109 public int getLevel() { 110 return mLevel; 111 } 112 113 /** @hide */ 114 @Override updateLevel(PersistableBundle cc, ServiceState ss)115 public void updateLevel(PersistableBundle cc, ServiceState ss) { 116 if (mRscp > TDSCDMA_RSCP_MAX) mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 117 else if (mRscp >= TDSCDMA_RSCP_GREAT) mLevel = SIGNAL_STRENGTH_GREAT; 118 else if (mRscp >= TDSCDMA_RSCP_GOOD) mLevel = SIGNAL_STRENGTH_GOOD; 119 else if (mRscp >= TDSCDMA_RSCP_MODERATE) mLevel = SIGNAL_STRENGTH_MODERATE; 120 else if (mRscp >= TDSCDMA_RSCP_POOR) mLevel = SIGNAL_STRENGTH_POOR; 121 else mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 122 } 123 124 /** 125 * Get the RSCP as dBm value -120..-24dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 126 */ 127 @Override getDbm()128 public int getDbm() { 129 return mRscp; 130 } 131 132 /** 133 * Get the RSCP as dBm value -120..-24dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 134 */ getRscp()135 public int getRscp() { 136 return mRscp; 137 } 138 139 /** 140 * Get the RSSI as dBm value -113..-51dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 141 * 142 * @hide 143 */ getRssi()144 public int getRssi() { 145 return mRssi; 146 } 147 148 /** 149 * Get the BER as an ASU value 0..7, 99, or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 150 * @hide 151 */ getBitErrorRate()152 public int getBitErrorRate() { 153 return mBitErrorRate; 154 } 155 156 /** 157 * Get the RSCP in ASU. 158 * 159 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 160 * 161 * @return RSCP in ASU 0..96, 255, or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 162 */ 163 @Override getAsuLevel()164 public int getAsuLevel() { 165 if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp); 166 // For historical reasons, if RSCP is unavailable, this API will very incorrectly return 167 // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+ 168 if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi); 169 return getAsuFromRscpDbm(CellInfo.UNAVAILABLE); 170 } 171 172 @Override hashCode()173 public int hashCode() { 174 return Objects.hash(mRssi, mBitErrorRate, mRscp, mLevel); 175 } 176 177 private static final CellSignalStrengthTdscdma sInvalid = new CellSignalStrengthTdscdma(); 178 179 /** @hide */ 180 @Override isValid()181 public boolean isValid() { 182 return !this.equals(sInvalid); 183 } 184 185 @Override equals(Object o)186 public boolean equals(Object o) { 187 if (!(o instanceof CellSignalStrengthTdscdma)) return false; 188 CellSignalStrengthTdscdma s = (CellSignalStrengthTdscdma) o; 189 190 return mRssi == s.mRssi 191 && mBitErrorRate == s.mBitErrorRate 192 && mRscp == s.mRscp 193 && mLevel == s.mLevel; 194 } 195 196 /** 197 * @return string representation. 198 */ 199 @Override toString()200 public String toString() { 201 return "CellSignalStrengthTdscdma:" 202 + " rssi=" + mRssi 203 + " ber=" + mBitErrorRate 204 + " rscp=" + mRscp 205 + " level=" + mLevel; 206 } 207 208 /** Implement the Parcelable interface */ 209 @Override writeToParcel(Parcel dest, int flags)210 public void writeToParcel(Parcel dest, int flags) { 211 if (DBG) log("writeToParcel(Parcel, int): " + toString()); 212 dest.writeInt(mRssi); 213 dest.writeInt(mBitErrorRate); 214 dest.writeInt(mRscp); 215 dest.writeInt(mLevel); 216 } 217 218 /** 219 * Construct a SignalStrength object from the given parcel 220 * where the token is already been processed. 221 */ CellSignalStrengthTdscdma(Parcel in)222 private CellSignalStrengthTdscdma(Parcel in) { 223 mRssi = in.readInt(); 224 mBitErrorRate = in.readInt(); 225 mRscp = in.readInt(); 226 mLevel = in.readInt(); 227 if (DBG) log("CellSignalStrengthTdscdma(Parcel): " + toString()); 228 } 229 230 /** Implement the Parcelable interface */ 231 @Override describeContents()232 public int describeContents() { 233 return 0; 234 } 235 236 /** Implement the Parcelable interface */ 237 @SuppressWarnings("hiding") 238 @NonNull 239 public static final Parcelable.Creator<CellSignalStrengthTdscdma> CREATOR = 240 new Parcelable.Creator<CellSignalStrengthTdscdma>() { 241 @Override 242 public @NonNull CellSignalStrengthTdscdma createFromParcel(Parcel in) { 243 return new CellSignalStrengthTdscdma(in); 244 } 245 246 @Override 247 public @NonNull CellSignalStrengthTdscdma[] newArray(int size) { 248 return new CellSignalStrengthTdscdma[size]; 249 } 250 }; 251 252 /** 253 * log 254 */ log(String s)255 private static void log(String s) { 256 Rlog.w(LOG_TAG, s); 257 } 258 } 259