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 17 package android.telephony; 18 19 import android.os.Bundle; 20 import android.os.Parcel; 21 import android.os.Parcelable; 22 import android.telephony.Rlog; 23 import android.util.Log; 24 import android.content.res.Resources; 25 26 /** 27 * Contains phone signal strength related information. 28 */ 29 public class SignalStrength implements Parcelable { 30 31 private static final String LOG_TAG = "SignalStrength"; 32 private static final boolean DBG = false; 33 34 /** @hide */ 35 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; 36 /** @hide */ 37 public static final int SIGNAL_STRENGTH_POOR = 1; 38 /** @hide */ 39 public static final int SIGNAL_STRENGTH_MODERATE = 2; 40 /** @hide */ 41 public static final int SIGNAL_STRENGTH_GOOD = 3; 42 /** @hide */ 43 public static final int SIGNAL_STRENGTH_GREAT = 4; 44 /** @hide */ 45 public static final int NUM_SIGNAL_STRENGTH_BINS = 5; 46 /** @hide */ 47 public static final String[] SIGNAL_STRENGTH_NAMES = { 48 "none", "poor", "moderate", "good", "great" 49 }; 50 51 /** @hide */ 52 //Use int max, as -1 is a valid value in signal strength 53 public static final int INVALID = 0x7FFFFFFF; 54 55 private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 56 private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 57 private int mCdmaDbm; // This value is the RSSI value 58 private int mCdmaEcio; // This value is the Ec/Io 59 private int mEvdoDbm; // This value is the EVDO RSSI value 60 private int mEvdoEcio; // This value is the EVDO Ec/Io 61 private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio 62 private int mLteSignalStrength; 63 private int mLteRsrp; 64 private int mLteRsrq; 65 private int mLteRssnr; 66 private int mLteCqi; 67 private int mLteRsrpBoost; // offset to be reduced from the rsrp threshold while calculating 68 // signal strength level 69 private int mTdScdmaRscp; 70 71 private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult 72 73 /** 74 * Create a new SignalStrength from a intent notifier Bundle 75 * 76 * This method is used by PhoneStateIntentReceiver and maybe by 77 * external applications. 78 * 79 * @param m Bundle from intent notifier 80 * @return newly created SignalStrength 81 * 82 * @hide 83 */ newFromBundle(Bundle m)84 public static SignalStrength newFromBundle(Bundle m) { 85 SignalStrength ret; 86 ret = new SignalStrength(); 87 ret.setFromNotifierBundle(m); 88 return ret; 89 } 90 91 /** 92 * Empty constructor 93 * 94 * @hide 95 */ SignalStrength()96 public SignalStrength() { 97 mGsmSignalStrength = 99; 98 mGsmBitErrorRate = -1; 99 mCdmaDbm = -1; 100 mCdmaEcio = -1; 101 mEvdoDbm = -1; 102 mEvdoEcio = -1; 103 mEvdoSnr = -1; 104 mLteSignalStrength = 99; 105 mLteRsrp = INVALID; 106 mLteRsrq = INVALID; 107 mLteRssnr = INVALID; 108 mLteCqi = INVALID; 109 mLteRsrpBoost = 0; 110 mTdScdmaRscp = INVALID; 111 isGsm = true; 112 } 113 114 /** 115 * This constructor is used to create SignalStrength with default 116 * values and set the isGsmFlag with the value passed in the input 117 * 118 * @param gsmFlag true if Gsm Phone,false if Cdma phone 119 * @return newly created SignalStrength 120 * @hide 121 */ SignalStrength(boolean gsmFlag)122 public SignalStrength(boolean gsmFlag) { 123 mGsmSignalStrength = 99; 124 mGsmBitErrorRate = -1; 125 mCdmaDbm = -1; 126 mCdmaEcio = -1; 127 mEvdoDbm = -1; 128 mEvdoEcio = -1; 129 mEvdoSnr = -1; 130 mLteSignalStrength = 99; 131 mLteRsrp = INVALID; 132 mLteRsrq = INVALID; 133 mLteRssnr = INVALID; 134 mLteCqi = INVALID; 135 mLteRsrpBoost = 0; 136 mTdScdmaRscp = INVALID; 137 isGsm = gsmFlag; 138 } 139 140 /** 141 * Constructor 142 * 143 * @hide 144 */ SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, int lteRsrpBoost, int tdScdmaRscp, boolean gsmFlag)145 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 146 int cdmaDbm, int cdmaEcio, 147 int evdoDbm, int evdoEcio, int evdoSnr, 148 int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, 149 int lteRsrpBoost, int tdScdmaRscp, boolean gsmFlag) { 150 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 151 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, 152 lteRsrq, lteRssnr, lteCqi, lteRsrpBoost, gsmFlag); 153 mTdScdmaRscp = tdScdmaRscp; 154 } 155 156 /** 157 * Constructor 158 * 159 * @hide 160 */ SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, int tdScdmaRscp, boolean gsmFlag)161 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 162 int cdmaDbm, int cdmaEcio, 163 int evdoDbm, int evdoEcio, int evdoSnr, 164 int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, 165 int tdScdmaRscp, boolean gsmFlag) { 166 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 167 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, 168 lteRsrq, lteRssnr, lteCqi, 0, gsmFlag); 169 mTdScdmaRscp = tdScdmaRscp; 170 } 171 172 /** 173 * Constructor 174 * 175 * @hide 176 */ SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, boolean gsmFlag)177 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 178 int cdmaDbm, int cdmaEcio, 179 int evdoDbm, int evdoEcio, int evdoSnr, 180 int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, 181 boolean gsmFlag) { 182 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 183 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, 184 lteRsrq, lteRssnr, lteCqi, 0, gsmFlag); 185 } 186 187 /** 188 * Constructor 189 * 190 * @hide 191 */ SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, boolean gsmFlag)192 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 193 int cdmaDbm, int cdmaEcio, 194 int evdoDbm, int evdoEcio, int evdoSnr, 195 boolean gsmFlag) { 196 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 197 evdoDbm, evdoEcio, evdoSnr, 99, INVALID, 198 INVALID, INVALID, INVALID, 0, gsmFlag); 199 } 200 201 /** 202 * Copy constructors 203 * 204 * @param s Source SignalStrength 205 * 206 * @hide 207 */ SignalStrength(SignalStrength s)208 public SignalStrength(SignalStrength s) { 209 copyFrom(s); 210 } 211 212 /** 213 * Initialize gsm/cdma values, sets lte values to defaults. 214 * 215 * @param gsmSignalStrength 216 * @param gsmBitErrorRate 217 * @param cdmaDbm 218 * @param cdmaEcio 219 * @param evdoDbm 220 * @param evdoEcio 221 * @param evdoSnr 222 * @param gsm 223 * 224 * @hide 225 */ initialize(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, boolean gsm)226 public void initialize(int gsmSignalStrength, int gsmBitErrorRate, 227 int cdmaDbm, int cdmaEcio, 228 int evdoDbm, int evdoEcio, int evdoSnr, 229 boolean gsm) { 230 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 231 evdoDbm, evdoEcio, evdoSnr, 99, INVALID, 232 INVALID, INVALID, INVALID, 0, gsm); 233 } 234 235 /** 236 * Initialize all the values 237 * 238 * @param gsmSignalStrength 239 * @param gsmBitErrorRate 240 * @param cdmaDbm 241 * @param cdmaEcio 242 * @param evdoDbm 243 * @param evdoEcio 244 * @param evdoSnr 245 * @param lteSignalStrength 246 * @param lteRsrp 247 * @param lteRsrq 248 * @param lteRssnr 249 * @param lteCqi 250 * @param lteRsrpBoost 251 * @param gsm 252 * 253 * @hide 254 */ initialize(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, int lteRsrpBoost, boolean gsm)255 public void initialize(int gsmSignalStrength, int gsmBitErrorRate, 256 int cdmaDbm, int cdmaEcio, 257 int evdoDbm, int evdoEcio, int evdoSnr, 258 int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, 259 int lteRsrpBoost, boolean gsm) { 260 mGsmSignalStrength = gsmSignalStrength; 261 mGsmBitErrorRate = gsmBitErrorRate; 262 mCdmaDbm = cdmaDbm; 263 mCdmaEcio = cdmaEcio; 264 mEvdoDbm = evdoDbm; 265 mEvdoEcio = evdoEcio; 266 mEvdoSnr = evdoSnr; 267 mLteSignalStrength = lteSignalStrength; 268 mLteRsrp = lteRsrp; 269 mLteRsrq = lteRsrq; 270 mLteRssnr = lteRssnr; 271 mLteCqi = lteCqi; 272 mLteRsrpBoost = lteRsrpBoost; 273 mTdScdmaRscp = INVALID; 274 isGsm = gsm; 275 if (DBG) log("initialize: " + toString()); 276 } 277 278 /** 279 * @hide 280 */ copyFrom(SignalStrength s)281 protected void copyFrom(SignalStrength s) { 282 mGsmSignalStrength = s.mGsmSignalStrength; 283 mGsmBitErrorRate = s.mGsmBitErrorRate; 284 mCdmaDbm = s.mCdmaDbm; 285 mCdmaEcio = s.mCdmaEcio; 286 mEvdoDbm = s.mEvdoDbm; 287 mEvdoEcio = s.mEvdoEcio; 288 mEvdoSnr = s.mEvdoSnr; 289 mLteSignalStrength = s.mLteSignalStrength; 290 mLteRsrp = s.mLteRsrp; 291 mLteRsrq = s.mLteRsrq; 292 mLteRssnr = s.mLteRssnr; 293 mLteCqi = s.mLteCqi; 294 mLteRsrpBoost = s.mLteRsrpBoost; 295 mTdScdmaRscp = s.mTdScdmaRscp; 296 isGsm = s.isGsm; 297 } 298 299 /** 300 * Construct a SignalStrength object from the given parcel. 301 * 302 * @hide 303 */ SignalStrength(Parcel in)304 public SignalStrength(Parcel in) { 305 if (DBG) log("Size of signalstrength parcel:" + in.dataSize()); 306 307 mGsmSignalStrength = in.readInt(); 308 mGsmBitErrorRate = in.readInt(); 309 mCdmaDbm = in.readInt(); 310 mCdmaEcio = in.readInt(); 311 mEvdoDbm = in.readInt(); 312 mEvdoEcio = in.readInt(); 313 mEvdoSnr = in.readInt(); 314 mLteSignalStrength = in.readInt(); 315 mLteRsrp = in.readInt(); 316 mLteRsrq = in.readInt(); 317 mLteRssnr = in.readInt(); 318 mLteCqi = in.readInt(); 319 mLteRsrpBoost = in.readInt(); 320 mTdScdmaRscp = in.readInt(); 321 isGsm = (in.readInt() != 0); 322 } 323 324 /** 325 * Make a SignalStrength object from the given parcel as passed up by 326 * the ril which does not have isGsm. isGsm will be changed by ServiceStateTracker 327 * so the default is a don't care. 328 * 329 * @hide 330 */ makeSignalStrengthFromRilParcel(Parcel in)331 public static SignalStrength makeSignalStrengthFromRilParcel(Parcel in) { 332 if (DBG) log("Size of signalstrength parcel:" + in.dataSize()); 333 334 SignalStrength ss = new SignalStrength(); 335 ss.mGsmSignalStrength = in.readInt(); 336 ss.mGsmBitErrorRate = in.readInt(); 337 ss.mCdmaDbm = in.readInt(); 338 ss.mCdmaEcio = in.readInt(); 339 ss.mEvdoDbm = in.readInt(); 340 ss.mEvdoEcio = in.readInt(); 341 ss.mEvdoSnr = in.readInt(); 342 ss.mLteSignalStrength = in.readInt(); 343 ss.mLteRsrp = in.readInt(); 344 ss.mLteRsrq = in.readInt(); 345 ss.mLteRssnr = in.readInt(); 346 ss.mLteCqi = in.readInt(); 347 ss.mTdScdmaRscp = in.readInt(); 348 return ss; 349 } 350 351 /** 352 * {@link Parcelable#writeToParcel} 353 */ writeToParcel(Parcel out, int flags)354 public void writeToParcel(Parcel out, int flags) { 355 out.writeInt(mGsmSignalStrength); 356 out.writeInt(mGsmBitErrorRate); 357 out.writeInt(mCdmaDbm); 358 out.writeInt(mCdmaEcio); 359 out.writeInt(mEvdoDbm); 360 out.writeInt(mEvdoEcio); 361 out.writeInt(mEvdoSnr); 362 out.writeInt(mLteSignalStrength); 363 out.writeInt(mLteRsrp); 364 out.writeInt(mLteRsrq); 365 out.writeInt(mLteRssnr); 366 out.writeInt(mLteCqi); 367 out.writeInt(mLteRsrpBoost); 368 out.writeInt(mTdScdmaRscp); 369 out.writeInt(isGsm ? 1 : 0); 370 } 371 372 /** 373 * {@link Parcelable#describeContents} 374 */ describeContents()375 public int describeContents() { 376 return 0; 377 } 378 379 /** 380 * {@link Parcelable.Creator} 381 * 382 * @hide 383 */ 384 public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() { 385 public SignalStrength createFromParcel(Parcel in) { 386 return new SignalStrength(in); 387 } 388 389 public SignalStrength[] newArray(int size) { 390 return new SignalStrength[size]; 391 } 392 }; 393 394 /** 395 * Validate the individual signal strength fields as per the range 396 * specified in ril.h 397 * Set to invalid any field that is not in the valid range 398 * Cdma, evdo, lte rsrp & rsrq values are sign converted 399 * when received from ril interface 400 * 401 * @return 402 * Valid values for all signalstrength fields 403 * @hide 404 */ validateInput()405 public void validateInput() { 406 if (DBG) log("Signal before validate=" + this); 407 // TS 27.007 8.5 408 mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99; 409 // BER no change; 410 411 mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120; 412 mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160; 413 414 mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120; 415 mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -1; 416 mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1; 417 418 // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC 419 mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99; 420 mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID; 421 mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID; 422 mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr 423 : SignalStrength.INVALID; 424 425 mTdScdmaRscp = ((mTdScdmaRscp >= 25) && (mTdScdmaRscp <= 120)) 426 ? -mTdScdmaRscp : SignalStrength.INVALID; 427 // Cqi no change 428 if (DBG) log("Signal after validate=" + this); 429 } 430 431 /** 432 * @param true - Gsm, Lte phones 433 * false - Cdma phones 434 * 435 * Used by voice phone to set the isGsm 436 * flag 437 * @hide 438 */ setGsm(boolean gsmFlag)439 public void setGsm(boolean gsmFlag) { 440 isGsm = gsmFlag; 441 } 442 443 /** 444 * @param lteRsrpBoost - signal strength offset 445 * 446 * Used by phone to set the lte signal strength offset which will be 447 * reduced from rsrp threshold while calculating signal strength level 448 * 449 * @hide 450 */ setLteRsrpBoost(int lteRsrpBoost)451 public void setLteRsrpBoost(int lteRsrpBoost) { 452 mLteRsrpBoost = lteRsrpBoost; 453 } 454 455 /** 456 * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS 457 * 27.007 8.5 458 */ getGsmSignalStrength()459 public int getGsmSignalStrength() { 460 return this.mGsmSignalStrength; 461 } 462 463 /** 464 * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5 465 */ getGsmBitErrorRate()466 public int getGsmBitErrorRate() { 467 return this.mGsmBitErrorRate; 468 } 469 470 /** 471 * Get the CDMA RSSI value in dBm 472 */ getCdmaDbm()473 public int getCdmaDbm() { 474 return this.mCdmaDbm; 475 } 476 477 /** 478 * Get the CDMA Ec/Io value in dB*10 479 */ getCdmaEcio()480 public int getCdmaEcio() { 481 return this.mCdmaEcio; 482 } 483 484 /** 485 * Get the EVDO RSSI value in dBm 486 */ getEvdoDbm()487 public int getEvdoDbm() { 488 return this.mEvdoDbm; 489 } 490 491 /** 492 * Get the EVDO Ec/Io value in dB*10 493 */ getEvdoEcio()494 public int getEvdoEcio() { 495 return this.mEvdoEcio; 496 } 497 498 /** 499 * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest. 500 */ getEvdoSnr()501 public int getEvdoSnr() { 502 return this.mEvdoSnr; 503 } 504 505 /** @hide */ getLteSignalStrength()506 public int getLteSignalStrength() { 507 return mLteSignalStrength; 508 } 509 510 /** @hide */ getLteRsrp()511 public int getLteRsrp() { 512 return mLteRsrp; 513 } 514 515 /** @hide */ getLteRsrq()516 public int getLteRsrq() { 517 return mLteRsrq; 518 } 519 520 /** @hide */ getLteRssnr()521 public int getLteRssnr() { 522 return mLteRssnr; 523 } 524 525 /** @hide */ getLteCqi()526 public int getLteCqi() { 527 return mLteCqi; 528 } 529 530 /** @hide */ getLteRsrpBoost()531 public int getLteRsrpBoost() { 532 return mLteRsrpBoost; 533 } 534 535 /** 536 * Retrieve an abstract level value for the overall signal strength. 537 * 538 * @return a single integer from 0 to 4 representing the general signal quality. 539 * This may take into account many different radio technology inputs. 540 * 0 represents very poor signal strength 541 * while 4 represents a very strong signal strength. 542 */ getLevel()543 public int getLevel() { 544 int level = 0; 545 546 if (isGsm) { 547 level = getLteLevel(); 548 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 549 level = getTdScdmaLevel(); 550 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 551 level = getGsmLevel(); 552 } 553 } 554 } else { 555 int cdmaLevel = getCdmaLevel(); 556 int evdoLevel = getEvdoLevel(); 557 if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 558 /* We don't know evdo, use cdma */ 559 level = cdmaLevel; 560 } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 561 /* We don't know cdma, use evdo */ 562 level = evdoLevel; 563 } else { 564 /* We know both, use the lowest level */ 565 level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; 566 } 567 } 568 if (DBG) log("getLevel=" + level); 569 return level; 570 } 571 572 /** 573 * Get the signal level as an asu value between 0..31, 99 is unknown 574 * 575 * @hide 576 */ 577 public int getAsuLevel() { 578 int asuLevel = 0; 579 if (isGsm) { 580 if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 581 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 582 asuLevel = getGsmAsuLevel(); 583 } else { 584 asuLevel = getTdScdmaAsuLevel(); 585 } 586 } else { 587 asuLevel = getLteAsuLevel(); 588 } 589 } else { 590 int cdmaAsuLevel = getCdmaAsuLevel(); 591 int evdoAsuLevel = getEvdoAsuLevel(); 592 if (evdoAsuLevel == 0) { 593 /* We don't know evdo use, cdma */ 594 asuLevel = cdmaAsuLevel; 595 } else if (cdmaAsuLevel == 0) { 596 /* We don't know cdma use, evdo */ 597 asuLevel = evdoAsuLevel; 598 } else { 599 /* We know both, use the lowest level */ 600 asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel; 601 } 602 } 603 if (DBG) log("getAsuLevel=" + asuLevel); 604 return asuLevel; 605 } 606 607 /** 608 * Get the signal strength as dBm 609 * 610 * @hide 611 */ 612 public int getDbm() { 613 int dBm = INVALID; 614 615 if(isGsm()) { 616 dBm = getLteDbm(); 617 if (dBm == INVALID) { 618 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 619 dBm = getGsmDbm(); 620 } else { 621 dBm = getTdScdmaDbm(); 622 } 623 } 624 } else { 625 int cdmaDbm = getCdmaDbm(); 626 int evdoDbm = getEvdoDbm(); 627 628 return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm 629 : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm)); 630 } 631 if (DBG) log("getDbm=" + dBm); 632 return dBm; 633 } 634 635 /** 636 * Get Gsm signal strength as dBm 637 * 638 * @hide 639 */ 640 public int getGsmDbm() { 641 int dBm; 642 643 int gsmSignalStrength = getGsmSignalStrength(); 644 int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 645 if (asu != -1) { 646 dBm = -113 + (2 * asu); 647 } else { 648 dBm = -1; 649 } 650 if (DBG) log("getGsmDbm=" + dBm); 651 return dBm; 652 } 653 654 /** 655 * Get gsm as level 0..4 656 * 657 * @hide 658 */ 659 public int getGsmLevel() { 660 int level; 661 662 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 663 // asu = 0 (-113dB or less) is very weak 664 // signal, its better to show 0 bars to the user in such cases. 665 // asu = 99 is a special case, where the signal strength is unknown. 666 int asu = getGsmSignalStrength(); 667 if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 668 else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT; 669 else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD; 670 else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE; 671 else level = SIGNAL_STRENGTH_POOR; 672 if (DBG) log("getGsmLevel=" + level); 673 return level; 674 } 675 676 /** 677 * Get the gsm signal level as an asu value between 0..31, 99 is unknown 678 * 679 * @hide 680 */ 681 public int getGsmAsuLevel() { 682 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 683 // asu = 0 (-113dB or less) is very weak 684 // signal, its better to show 0 bars to the user in such cases. 685 // asu = 99 is a special case, where the signal strength is unknown. 686 int level = getGsmSignalStrength(); 687 if (DBG) log("getGsmAsuLevel=" + level); 688 return level; 689 } 690 691 /** 692 * Get cdma as level 0..4 693 * 694 * @hide 695 */ 696 public int getCdmaLevel() { 697 final int cdmaDbm = getCdmaDbm(); 698 final int cdmaEcio = getCdmaEcio(); 699 int levelDbm; 700 int levelEcio; 701 702 if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT; 703 else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD; 704 else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE; 705 else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR; 706 else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 707 708 // Ec/Io are in dB*10 709 if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT; 710 else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD; 711 else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE; 712 else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR; 713 else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 714 715 int level = (levelDbm < levelEcio) ? levelDbm : levelEcio; 716 if (DBG) log("getCdmaLevel=" + level); 717 return level; 718 } 719 720 /** 721 * Get the cdma signal level as an asu value between 0..31, 99 is unknown 722 * 723 * @hide 724 */ getCdmaAsuLevel()725 public int getCdmaAsuLevel() { 726 final int cdmaDbm = getCdmaDbm(); 727 final int cdmaEcio = getCdmaEcio(); 728 int cdmaAsuLevel; 729 int ecioAsuLevel; 730 731 if (cdmaDbm >= -75) cdmaAsuLevel = 16; 732 else if (cdmaDbm >= -82) cdmaAsuLevel = 8; 733 else if (cdmaDbm >= -90) cdmaAsuLevel = 4; 734 else if (cdmaDbm >= -95) cdmaAsuLevel = 2; 735 else if (cdmaDbm >= -100) cdmaAsuLevel = 1; 736 else cdmaAsuLevel = 99; 737 738 // Ec/Io are in dB*10 739 if (cdmaEcio >= -90) ecioAsuLevel = 16; 740 else if (cdmaEcio >= -100) ecioAsuLevel = 8; 741 else if (cdmaEcio >= -115) ecioAsuLevel = 4; 742 else if (cdmaEcio >= -130) ecioAsuLevel = 2; 743 else if (cdmaEcio >= -150) ecioAsuLevel = 1; 744 else ecioAsuLevel = 99; 745 746 int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel; 747 if (DBG) log("getCdmaAsuLevel=" + level); 748 return level; 749 } 750 751 /** 752 * Get Evdo as level 0..4 753 * 754 * @hide 755 */ getEvdoLevel()756 public int getEvdoLevel() { 757 int evdoDbm = getEvdoDbm(); 758 int evdoSnr = getEvdoSnr(); 759 int levelEvdoDbm; 760 int levelEvdoSnr; 761 762 if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT; 763 else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD; 764 else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE; 765 else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR; 766 else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 767 768 if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT; 769 else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD; 770 else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE; 771 else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR; 772 else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 773 774 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 775 if (DBG) log("getEvdoLevel=" + level); 776 return level; 777 } 778 779 /** 780 * Get the evdo signal level as an asu value between 0..31, 99 is unknown 781 * 782 * @hide 783 */ getEvdoAsuLevel()784 public int getEvdoAsuLevel() { 785 int evdoDbm = getEvdoDbm(); 786 int evdoSnr = getEvdoSnr(); 787 int levelEvdoDbm; 788 int levelEvdoSnr; 789 790 if (evdoDbm >= -65) levelEvdoDbm = 16; 791 else if (evdoDbm >= -75) levelEvdoDbm = 8; 792 else if (evdoDbm >= -85) levelEvdoDbm = 4; 793 else if (evdoDbm >= -95) levelEvdoDbm = 2; 794 else if (evdoDbm >= -105) levelEvdoDbm = 1; 795 else levelEvdoDbm = 99; 796 797 if (evdoSnr >= 7) levelEvdoSnr = 16; 798 else if (evdoSnr >= 6) levelEvdoSnr = 8; 799 else if (evdoSnr >= 5) levelEvdoSnr = 4; 800 else if (evdoSnr >= 3) levelEvdoSnr = 2; 801 else if (evdoSnr >= 1) levelEvdoSnr = 1; 802 else levelEvdoSnr = 99; 803 804 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 805 if (DBG) log("getEvdoAsuLevel=" + level); 806 return level; 807 } 808 809 /** 810 * Get LTE as dBm 811 * 812 * @hide 813 */ getLteDbm()814 public int getLteDbm() { 815 return mLteRsrp; 816 } 817 818 /** 819 * Get LTE as level 0..4 820 * 821 * @hide 822 */ getLteLevel()823 public int getLteLevel() { 824 /* 825 * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received 826 * signal + noise RSRP = reference signal dBm RSRQ = quality of signal 827 * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio 828 * = -10log P1/P2 dB 829 */ 830 int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1; 831 832 int[] threshRsrp = Resources.getSystem().getIntArray( 833 com.android.internal.R.array.config_lteDbmThresholds); 834 if (threshRsrp.length != 6) { 835 Log.wtf(LOG_TAG, "getLteLevel - config_lteDbmThresholds has invalid num of elements." 836 + " Cannot evaluate RSRP signal."); 837 } else { 838 if (mLteRsrp > threshRsrp[5]) { 839 rsrpIconLevel = -1; 840 } else if (mLteRsrp >= (threshRsrp[4] - mLteRsrpBoost)) { 841 rsrpIconLevel = SIGNAL_STRENGTH_GREAT; 842 } else if (mLteRsrp >= (threshRsrp[3] - mLteRsrpBoost)) { 843 rsrpIconLevel = SIGNAL_STRENGTH_GOOD; 844 } else if (mLteRsrp >= (threshRsrp[2] - mLteRsrpBoost)) { 845 rsrpIconLevel = SIGNAL_STRENGTH_MODERATE; 846 } else if (mLteRsrp >= (threshRsrp[1] - mLteRsrpBoost)) { 847 rsrpIconLevel = SIGNAL_STRENGTH_POOR; 848 } else if (mLteRsrp >= threshRsrp[0]) { 849 rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 850 } 851 } 852 853 /* 854 * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5 855 * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars 856 * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna 857 * Icon Only 858 */ 859 if (mLteRssnr > 300) snrIconLevel = -1; 860 else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT; 861 else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD; 862 else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE; 863 else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR; 864 else if (mLteRssnr >= -200) 865 snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 866 867 if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:" 868 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel 869 + " lteRsrpBoost:" + mLteRsrpBoost); 870 871 /* Choose a measurement type to use for notification */ 872 if (snrIconLevel != -1 && rsrpIconLevel != -1) { 873 /* 874 * The number of bars displayed shall be the smaller of the bars 875 * associated with LTE RSRP and the bars associated with the LTE 876 * RS_SNR 877 */ 878 return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel); 879 } 880 881 if (snrIconLevel != -1) return snrIconLevel; 882 883 if (rsrpIconLevel != -1) return rsrpIconLevel; 884 885 /* Valid values are (0-63, 99) as defined in TS 36.331 */ 886 if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 887 else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT; 888 else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD; 889 else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE; 890 else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR; 891 892 if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:" 893 + rssiIconLevel); 894 return rssiIconLevel; 895 896 } 897 /** 898 * Get the LTE signal level as an asu value between 0..97, 99 is unknown 899 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 900 * 901 * @hide 902 */ getLteAsuLevel()903 public int getLteAsuLevel() { 904 int lteAsuLevel = 99; 905 int lteDbm = getLteDbm(); 906 /* 907 * 3GPP 27.007 (Ver 10.3.0) Sec 8.69 908 * 0 -140 dBm or less 909 * 1 -139 dBm 910 * 2...96 -138... -44 dBm 911 * 97 -43 dBm or greater 912 * 255 not known or not detectable 913 */ 914 /* 915 * validateInput will always give a valid range between -140 t0 -44 as 916 * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255 917 * and not 97 or 0 918 */ 919 if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255; 920 else lteAsuLevel = lteDbm + 140; 921 if (DBG) log("Lte Asu level: "+lteAsuLevel); 922 return lteAsuLevel; 923 } 924 925 /** 926 * @return true if this is for GSM 927 */ isGsm()928 public boolean isGsm() { 929 return this.isGsm; 930 } 931 932 /** 933 * @return get TD_SCDMA dbm 934 * 935 * @hide 936 */ getTdScdmaDbm()937 public int getTdScdmaDbm() { 938 return this.mTdScdmaRscp; 939 } 940 941 /** 942 * Get TD-SCDMA as level 0..4 943 * Range : 25 to 120 944 * INT_MAX: 0x7FFFFFFF denotes invalid value 945 * Reference: 3GPP TS 25.123, section 9.1.1.1 946 * 947 * @hide 948 */ getTdScdmaLevel()949 public int getTdScdmaLevel() { 950 final int tdScdmaDbm = getTdScdmaDbm(); 951 int level; 952 953 if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID)) 954 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 955 else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT; 956 else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD; 957 else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE; 958 else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR; 959 else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 960 961 if (DBG) log("getTdScdmaLevel = " + level); 962 return level; 963 } 964 965 /** 966 * Get the TD-SCDMA signal level as an asu value. 967 * 968 * @hide 969 */ getTdScdmaAsuLevel()970 public int getTdScdmaAsuLevel() { 971 final int tdScdmaDbm = getTdScdmaDbm(); 972 int tdScdmaAsuLevel; 973 974 if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255; 975 else tdScdmaAsuLevel = tdScdmaDbm + 120; 976 if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel); 977 return tdScdmaAsuLevel; 978 } 979 980 /** 981 * @return hash code 982 */ 983 @Override hashCode()984 public int hashCode() { 985 int primeNum = 31; 986 return ((mGsmSignalStrength * primeNum) 987 + (mGsmBitErrorRate * primeNum) 988 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum) 989 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum) 990 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum) 991 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum) 992 + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0)); 993 } 994 995 /** 996 * @return true if the signal strengths are the same 997 */ 998 @Override equals(Object o)999 public boolean equals (Object o) { 1000 SignalStrength s; 1001 1002 try { 1003 s = (SignalStrength) o; 1004 } catch (ClassCastException ex) { 1005 return false; 1006 } 1007 1008 if (o == null) { 1009 return false; 1010 } 1011 1012 return (mGsmSignalStrength == s.mGsmSignalStrength 1013 && mGsmBitErrorRate == s.mGsmBitErrorRate 1014 && mCdmaDbm == s.mCdmaDbm 1015 && mCdmaEcio == s.mCdmaEcio 1016 && mEvdoDbm == s.mEvdoDbm 1017 && mEvdoEcio == s.mEvdoEcio 1018 && mEvdoSnr == s.mEvdoSnr 1019 && mLteSignalStrength == s.mLteSignalStrength 1020 && mLteRsrp == s.mLteRsrp 1021 && mLteRsrq == s.mLteRsrq 1022 && mLteRssnr == s.mLteRssnr 1023 && mLteCqi == s.mLteCqi 1024 && mLteRsrpBoost == s.mLteRsrpBoost 1025 && mTdScdmaRscp == s.mTdScdmaRscp 1026 && isGsm == s.isGsm); 1027 } 1028 1029 /** 1030 * @return string representation. 1031 */ 1032 @Override toString()1033 public String toString() { 1034 return ("SignalStrength:" 1035 + " " + mGsmSignalStrength 1036 + " " + mGsmBitErrorRate 1037 + " " + mCdmaDbm 1038 + " " + mCdmaEcio 1039 + " " + mEvdoDbm 1040 + " " + mEvdoEcio 1041 + " " + mEvdoSnr 1042 + " " + mLteSignalStrength 1043 + " " + mLteRsrp 1044 + " " + mLteRsrq 1045 + " " + mLteRssnr 1046 + " " + mLteCqi 1047 + " " + mLteRsrpBoost 1048 + " " + mTdScdmaRscp 1049 + " " + (isGsm ? "gsm|lte" : "cdma")); 1050 } 1051 1052 /** 1053 * Set SignalStrength based on intent notifier map 1054 * 1055 * @param m intent notifier map 1056 * @hide 1057 */ setFromNotifierBundle(Bundle m)1058 private void setFromNotifierBundle(Bundle m) { 1059 mGsmSignalStrength = m.getInt("GsmSignalStrength"); 1060 mGsmBitErrorRate = m.getInt("GsmBitErrorRate"); 1061 mCdmaDbm = m.getInt("CdmaDbm"); 1062 mCdmaEcio = m.getInt("CdmaEcio"); 1063 mEvdoDbm = m.getInt("EvdoDbm"); 1064 mEvdoEcio = m.getInt("EvdoEcio"); 1065 mEvdoSnr = m.getInt("EvdoSnr"); 1066 mLteSignalStrength = m.getInt("LteSignalStrength"); 1067 mLteRsrp = m.getInt("LteRsrp"); 1068 mLteRsrq = m.getInt("LteRsrq"); 1069 mLteRssnr = m.getInt("LteRssnr"); 1070 mLteCqi = m.getInt("LteCqi"); 1071 mLteRsrpBoost = m.getInt("lteRsrpBoost"); 1072 mTdScdmaRscp = m.getInt("TdScdma"); 1073 isGsm = m.getBoolean("isGsm"); 1074 } 1075 1076 /** 1077 * Set intent notifier Bundle based on SignalStrength 1078 * 1079 * @param m intent notifier Bundle 1080 * @hide 1081 */ fillInNotifierBundle(Bundle m)1082 public void fillInNotifierBundle(Bundle m) { 1083 m.putInt("GsmSignalStrength", mGsmSignalStrength); 1084 m.putInt("GsmBitErrorRate", mGsmBitErrorRate); 1085 m.putInt("CdmaDbm", mCdmaDbm); 1086 m.putInt("CdmaEcio", mCdmaEcio); 1087 m.putInt("EvdoDbm", mEvdoDbm); 1088 m.putInt("EvdoEcio", mEvdoEcio); 1089 m.putInt("EvdoSnr", mEvdoSnr); 1090 m.putInt("LteSignalStrength", mLteSignalStrength); 1091 m.putInt("LteRsrp", mLteRsrp); 1092 m.putInt("LteRsrq", mLteRsrq); 1093 m.putInt("LteRssnr", mLteRssnr); 1094 m.putInt("LteCqi", mLteCqi); 1095 m.putInt("lteRsrpBoost", mLteRsrpBoost); 1096 m.putInt("TdScdma", mTdScdmaRscp); 1097 m.putBoolean("isGsm", isGsm); 1098 } 1099 1100 /** 1101 * log 1102 */ log(String s)1103 private static void log(String s) { 1104 Rlog.w(LOG_TAG, s); 1105 } 1106 } 1107