1/* 2 * Copyright (C) 2012 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 19import android.os.Parcel; 20import android.os.Parcelable; 21import android.telephony.Rlog; 22 23/** 24 * GSM signal strength related information. 25 */ 26public final class CellSignalStrengthGsm extends CellSignalStrength implements Parcelable { 27 28 private static final String LOG_TAG = "CellSignalStrengthGsm"; 29 private static final boolean DBG = false; 30 31 private static final int GSM_SIGNAL_STRENGTH_GREAT = 12; 32 private static final int GSM_SIGNAL_STRENGTH_GOOD = 8; 33 private static final int GSM_SIGNAL_STRENGTH_MODERATE = 5; 34 35 private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 36 private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 37 private int mTimingAdvance; 38 39 /** 40 * Empty constructor 41 * 42 * @hide 43 */ 44 public CellSignalStrengthGsm() { 45 setDefaultValues(); 46 } 47 48 /** 49 * Constructor 50 * 51 * @hide 52 */ 53 public CellSignalStrengthGsm(int ss, int ber) { 54 initialize(ss, ber); 55 } 56 57 /** 58 * Copy constructors 59 * 60 * @param s Source SignalStrength 61 * 62 * @hide 63 */ 64 public CellSignalStrengthGsm(CellSignalStrengthGsm s) { 65 copyFrom(s); 66 } 67 68 /** 69 * Initialize all the values 70 * 71 * @param ss SignalStrength as ASU value 72 * @param ber is Bit Error Rate 73 * 74 * @hide 75 */ 76 public void initialize(int ss, int ber) { 77 mSignalStrength = ss; 78 mBitErrorRate = ber; 79 mTimingAdvance = Integer.MAX_VALUE; 80 } 81 82 /** 83 * Initialize all the values 84 * 85 * @param ss SignalStrength as ASU value 86 * @param ber is Bit Error Rate 87 * @param ta timing advance 88 * 89 * @hide 90 */ 91 public void initialize(int ss, int ber, int ta) { 92 mSignalStrength = ss; 93 mBitErrorRate = ber; 94 mTimingAdvance = ta; 95 } 96 97 /** 98 * @hide 99 */ 100 protected void copyFrom(CellSignalStrengthGsm s) { 101 mSignalStrength = s.mSignalStrength; 102 mBitErrorRate = s.mBitErrorRate; 103 mTimingAdvance = s.mTimingAdvance; 104 } 105 106 /** 107 * @hide 108 */ 109 @Override 110 public CellSignalStrengthGsm copy() { 111 return new CellSignalStrengthGsm(this); 112 } 113 114 /** @hide */ 115 @Override 116 public void setDefaultValues() { 117 mSignalStrength = Integer.MAX_VALUE; 118 mBitErrorRate = Integer.MAX_VALUE; 119 mTimingAdvance = Integer.MAX_VALUE; 120 } 121 122 /** 123 * Get signal level as an int from 0..4 124 */ 125 @Override 126 public int getLevel() { 127 int level; 128 129 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 130 // asu = 0 (-113dB or less) is very weak 131 // signal, its better to show 0 bars to the user in such cases. 132 // asu = 99 is a special case, where the signal strength is unknown. 133 int asu = mSignalStrength; 134 if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 135 else if (asu >= GSM_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT; 136 else if (asu >= GSM_SIGNAL_STRENGTH_GOOD) level = SIGNAL_STRENGTH_GOOD; 137 else if (asu >= GSM_SIGNAL_STRENGTH_MODERATE) level = SIGNAL_STRENGTH_MODERATE; 138 else level = SIGNAL_STRENGTH_POOR; 139 if (DBG) log("getLevel=" + level); 140 return level; 141 } 142 143 /** 144 * Get the GSM timing advance between 0..219 symbols (normally 0..63). 145 * Integer.MAX_VALUE is reported when there is no RR connection. 146 * Refer to 3GPP 45.010 Sec 5.8 147 * @return the current GSM timing advance, if available. 148 */ 149 public int getTimingAdvance() { 150 return mTimingAdvance; 151 } 152 153 /** 154 * Get the signal strength as dBm 155 */ 156 @Override 157 public int getDbm() { 158 int dBm; 159 160 int level = mSignalStrength; 161 int asu = (level == 99 ? Integer.MAX_VALUE : level); 162 if (asu != Integer.MAX_VALUE) { 163 dBm = -113 + (2 * asu); 164 } else { 165 dBm = Integer.MAX_VALUE; 166 } 167 if (DBG) log("getDbm=" + dBm); 168 return dBm; 169 } 170 171 /** 172 * Get the signal level as an asu value between 0..31, 99 is unknown 173 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 174 */ 175 @Override 176 public int getAsuLevel() { 177 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 178 // asu = 0 (-113dB or less) is very weak 179 // signal, its better to show 0 bars to the user in such cases. 180 // asu = 99 is a special case, where the signal strength is unknown. 181 int level = mSignalStrength; 182 if (DBG) log("getAsuLevel=" + level); 183 return level; 184 } 185 186 @Override 187 public int hashCode() { 188 int primeNum = 31; 189 return (mSignalStrength * primeNum) + (mBitErrorRate * primeNum); 190 } 191 192 @Override 193 public boolean equals (Object o) { 194 CellSignalStrengthGsm s; 195 196 try { 197 s = (CellSignalStrengthGsm) o; 198 } catch (ClassCastException ex) { 199 return false; 200 } 201 202 if (o == null) { 203 return false; 204 } 205 206 return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate && 207 s.mTimingAdvance == mTimingAdvance; 208 } 209 210 /** 211 * @return string representation. 212 */ 213 @Override 214 public String toString() { 215 return "CellSignalStrengthGsm:" 216 + " ss=" + mSignalStrength 217 + " ber=" + mBitErrorRate 218 + " mTa=" + mTimingAdvance; 219 } 220 221 /** Implement the Parcelable interface */ 222 @Override 223 public void writeToParcel(Parcel dest, int flags) { 224 if (DBG) log("writeToParcel(Parcel, int): " + toString()); 225 dest.writeInt(mSignalStrength); 226 dest.writeInt(mBitErrorRate); 227 dest.writeInt(mTimingAdvance); 228 } 229 230 /** 231 * Construct a SignalStrength object from the given parcel 232 * where the token is already been processed. 233 */ 234 private CellSignalStrengthGsm(Parcel in) { 235 mSignalStrength = in.readInt(); 236 mBitErrorRate = in.readInt(); 237 mTimingAdvance = in.readInt(); 238 if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString()); 239 } 240 241 /** Implement the Parcelable interface */ 242 @Override 243 public int describeContents() { 244 return 0; 245 } 246 247 /** Implement the Parcelable interface */ 248 @SuppressWarnings("hiding") 249 public static final Parcelable.Creator<CellSignalStrengthGsm> CREATOR = 250 new Parcelable.Creator<CellSignalStrengthGsm>() { 251 @Override 252 public CellSignalStrengthGsm createFromParcel(Parcel in) { 253 return new CellSignalStrengthGsm(in); 254 } 255 256 @Override 257 public CellSignalStrengthGsm[] newArray(int size) { 258 return new CellSignalStrengthGsm[size]; 259 } 260 }; 261 262 /** 263 * log 264 */ 265 private static void log(String s) { 266 Rlog.w(LOG_TAG, s); 267 } 268} 269