SignalStrength.java revision 8ab862cbd4eeeb52ab921a555b7a006e89fd2abc
1/* 2 * Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved. 3 * Copyright (C) 2009 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package android.telephony; 19 20import android.os.Bundle; 21import android.os.Parcel; 22import android.os.Parcelable; 23import android.util.Log; 24 25/** 26 * Contains phone signal strength related information. 27 */ 28public class SignalStrength implements Parcelable { 29 30 private static final String LOG_TAG = "SignalStrength"; 31 private static final boolean DBG = false; 32 33 /** @hide */ 34 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; 35 /** @hide */ 36 public static final int SIGNAL_STRENGTH_POOR = 1; 37 /** @hide */ 38 public static final int SIGNAL_STRENGTH_MODERATE = 2; 39 /** @hide */ 40 public static final int SIGNAL_STRENGTH_GOOD = 3; 41 /** @hide */ 42 public static final int SIGNAL_STRENGTH_GREAT = 4; 43 /** @hide */ 44 public static final int NUM_SIGNAL_STRENGTH_BINS = 5; 45 /** @hide */ 46 public static final String[] SIGNAL_STRENGTH_NAMES = { 47 "none", "poor", "moderate", "good", "great" 48 }; 49 50 /** @hide */ 51 //Use int max, as -1 is a valid value in signal strength 52 public static final int INVALID = 0x7FFFFFFF; 53 54 private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 55 private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 56 private int mCdmaDbm; // This value is the RSSI value 57 private int mCdmaEcio; // This value is the Ec/Io 58 private int mEvdoDbm; // This value is the EVDO RSSI value 59 private int mEvdoEcio; // This value is the EVDO Ec/Io 60 private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio 61 private int mLteSignalStrength; 62 private int mLteRsrp; 63 private int mLteRsrq; 64 private int mLteRssnr; 65 private int mLteCqi; 66 67 private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult 68 /** 69 * Create a new SignalStrength from a intent notifier Bundle 70 * 71 * This method is used by PhoneStateIntentReceiver and maybe by 72 * external applications. 73 * 74 * @param m Bundle from intent notifier 75 * @return newly created SignalStrength 76 * 77 * @hide 78 */ 79 public static SignalStrength newFromBundle(Bundle m) { 80 SignalStrength ret; 81 ret = new SignalStrength(); 82 ret.setFromNotifierBundle(m); 83 return ret; 84 } 85 86 /** 87 * Empty constructor 88 * 89 * @hide 90 */ 91 public SignalStrength() { 92 mGsmSignalStrength = 99; 93 mGsmBitErrorRate = -1; 94 mCdmaDbm = -1; 95 mCdmaEcio = -1; 96 mEvdoDbm = -1; 97 mEvdoEcio = -1; 98 mEvdoSnr = -1; 99 mLteSignalStrength = 99; 100 mLteRsrp = INVALID; 101 mLteRsrq = INVALID; 102 mLteRssnr = INVALID; 103 mLteCqi = INVALID; 104 isGsm = true; 105 } 106 107 /** 108 * This constructor is used to create SignalStrength with default 109 * values and set the isGsmFlag with the value passed in the input 110 * 111 * @param gsmFlag true if Gsm Phone,false if Cdma phone 112 * @return newly created SignalStrength 113 * @hide 114 */ 115 public SignalStrength(boolean gsmFlag) { 116 mGsmSignalStrength = 99; 117 mGsmBitErrorRate = -1; 118 mCdmaDbm = -1; 119 mCdmaEcio = -1; 120 mEvdoDbm = -1; 121 mEvdoEcio = -1; 122 mEvdoSnr = -1; 123 mLteSignalStrength = 99; 124 mLteRsrp = INVALID; 125 mLteRsrq = INVALID; 126 mLteRssnr = INVALID; 127 mLteCqi = INVALID; 128 isGsm = gsmFlag; 129 } 130 131 /** 132 * Constructor 133 * 134 * @hide 135 */ 136 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 137 int cdmaDbm, int cdmaEcio, 138 int evdoDbm, int evdoEcio, int evdoSnr, 139 int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, 140 boolean gsm) { 141 mGsmSignalStrength = gsmSignalStrength; 142 mGsmBitErrorRate = gsmBitErrorRate; 143 mCdmaDbm = cdmaDbm; 144 mCdmaEcio = cdmaEcio; 145 mEvdoDbm = evdoDbm; 146 mEvdoEcio = evdoEcio; 147 mEvdoSnr = evdoSnr; 148 mLteSignalStrength = lteSignalStrength; 149 mLteRsrp = lteRsrp; 150 mLteRsrq = lteRsrq; 151 mLteRssnr = lteRssnr; 152 mLteCqi = lteCqi; 153 isGsm = gsm; 154 } 155 156 /** 157 * Constructor 158 * 159 * @hide 160 */ 161 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 162 int cdmaDbm, int cdmaEcio, 163 int evdoDbm, int evdoEcio, int evdoSnr, 164 boolean gsm) { 165 this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, evdoDbm, evdoEcio, evdoSnr, 99, 166 INVALID, INVALID, INVALID, INVALID, gsm); 167 } 168 169 /** 170 * Copy constructors 171 * 172 * @param s Source SignalStrength 173 * 174 * @hide 175 */ 176 public SignalStrength(SignalStrength s) { 177 copyFrom(s); 178 } 179 180 /** 181 * @hide 182 */ 183 protected void copyFrom(SignalStrength s) { 184 mGsmSignalStrength = s.mGsmSignalStrength; 185 mGsmBitErrorRate = s.mGsmBitErrorRate; 186 mCdmaDbm = s.mCdmaDbm; 187 mCdmaEcio = s.mCdmaEcio; 188 mEvdoDbm = s.mEvdoDbm; 189 mEvdoEcio = s.mEvdoEcio; 190 mEvdoSnr = s.mEvdoSnr; 191 mLteSignalStrength = s.mLteSignalStrength; 192 mLteRsrp = s.mLteRsrp; 193 mLteRsrq = s.mLteRsrq; 194 mLteRssnr = s.mLteRssnr; 195 mLteCqi = s.mLteCqi; 196 isGsm = s.isGsm; 197 } 198 199 /** 200 * Construct a SignalStrength object from the given parcel. 201 * 202 * @hide 203 */ 204 public SignalStrength(Parcel in) { 205 mGsmSignalStrength = in.readInt(); 206 mGsmBitErrorRate = in.readInt(); 207 mCdmaDbm = in.readInt(); 208 mCdmaEcio = in.readInt(); 209 mEvdoDbm = in.readInt(); 210 mEvdoEcio = in.readInt(); 211 mEvdoSnr = in.readInt(); 212 mLteSignalStrength = in.readInt(); 213 mLteRsrp = in.readInt(); 214 mLteRsrq = in.readInt(); 215 mLteRssnr = in.readInt(); 216 mLteCqi = in.readInt(); 217 isGsm = (in.readInt() != 0); 218 } 219 220 /** 221 * {@link Parcelable#writeToParcel} 222 */ 223 public void writeToParcel(Parcel out, int flags) { 224 out.writeInt(mGsmSignalStrength); 225 out.writeInt(mGsmBitErrorRate); 226 out.writeInt(mCdmaDbm); 227 out.writeInt(mCdmaEcio); 228 out.writeInt(mEvdoDbm); 229 out.writeInt(mEvdoEcio); 230 out.writeInt(mEvdoSnr); 231 out.writeInt(mLteSignalStrength); 232 out.writeInt(mLteRsrp); 233 out.writeInt(mLteRsrq); 234 out.writeInt(mLteRssnr); 235 out.writeInt(mLteCqi); 236 out.writeInt(isGsm ? 1 : 0); 237 } 238 239 /** 240 * {@link Parcelable#describeContents} 241 */ 242 public int describeContents() { 243 return 0; 244 } 245 246 /** 247 * {@link Parcelable.Creator} 248 * 249 * @hide 250 */ 251 public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() { 252 public SignalStrength createFromParcel(Parcel in) { 253 return new SignalStrength(in); 254 } 255 256 public SignalStrength[] newArray(int size) { 257 return new SignalStrength[size]; 258 } 259 }; 260 261 /** 262 * Validate the individual signal strength fields as per the range 263 * specified in ril.h 264 * Set to invalid any field that is not in the valid range 265 * Cdma, evdo, lte rsrp & rsrq values are sign converted 266 * when received from ril interface 267 * 268 * @return 269 * Valid values for all signalstrength fields 270 * @hide 271 */ 272 public void validateInput() { 273 if (DBG) log("Signal before validate=" + this); 274 // TS 27.007 8.5 275 mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99; 276 // BER no change; 277 278 mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120; 279 mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160; 280 281 mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120; 282 mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -1; 283 mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1; 284 285 // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC 286 mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99; 287 mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID; 288 mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID; 289 mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr 290 : SignalStrength.INVALID; 291 // Cqi no change 292 if (DBG) log("Signal after validate=" + this); 293 } 294 295 /** 296 * @param true - Gsm, Lte phones 297 * false - Cdma phones 298 * 299 * Used by voice phone to set the isGsm 300 * flag 301 * @hide 302 */ 303 public void setGsm(boolean gsmFlag) { 304 isGsm = gsmFlag; 305 } 306 307 /** 308 * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS 309 * 27.007 8.5 310 */ 311 public int getGsmSignalStrength() { 312 return this.mGsmSignalStrength; 313 } 314 315 /** 316 * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5 317 */ 318 public int getGsmBitErrorRate() { 319 return this.mGsmBitErrorRate; 320 } 321 322 /** 323 * Get the CDMA RSSI value in dBm 324 */ 325 public int getCdmaDbm() { 326 return this.mCdmaDbm; 327 } 328 329 /** 330 * Get the CDMA Ec/Io value in dB*10 331 */ 332 public int getCdmaEcio() { 333 return this.mCdmaEcio; 334 } 335 336 /** 337 * Get the EVDO RSSI value in dBm 338 */ 339 public int getEvdoDbm() { 340 return this.mEvdoDbm; 341 } 342 343 /** 344 * Get the EVDO Ec/Io value in dB*10 345 */ 346 public int getEvdoEcio() { 347 return this.mEvdoEcio; 348 } 349 350 /** 351 * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest. 352 */ 353 public int getEvdoSnr() { 354 return this.mEvdoSnr; 355 } 356 357 /** 358 * Get signal level as an int from 0..4 359 * 360 * @hide 361 */ 362 public int getLevel() { 363 int level; 364 365 if (isGsm) { 366 level = getLteLevel(); 367 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 368 level = getGsmLevel(); 369 } 370 } else { 371 int cdmaLevel = getCdmaLevel(); 372 int evdoLevel = getEvdoLevel(); 373 if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 374 /* We don't know evdo, use cdma */ 375 level = cdmaLevel; 376 } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 377 /* We don't know cdma, use evdo */ 378 level = evdoLevel; 379 } else { 380 /* We know both, use the lowest level */ 381 level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; 382 } 383 } 384 if (DBG) log("getLevel=" + level); 385 return level; 386 } 387 388 /** 389 * Get the signal level as an asu value between 0..31, 99 is unknown 390 * 391 * @hide 392 */ 393 public int getAsuLevel() { 394 int asuLevel; 395 if (isGsm) { 396 if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 397 asuLevel = getGsmAsuLevel(); 398 } else { 399 asuLevel = getLteAsuLevel(); 400 } 401 } else { 402 int cdmaAsuLevel = getCdmaAsuLevel(); 403 int evdoAsuLevel = getEvdoAsuLevel(); 404 if (evdoAsuLevel == 0) { 405 /* We don't know evdo use, cdma */ 406 asuLevel = cdmaAsuLevel; 407 } else if (cdmaAsuLevel == 0) { 408 /* We don't know cdma use, evdo */ 409 asuLevel = evdoAsuLevel; 410 } else { 411 /* We know both, use the lowest level */ 412 asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel; 413 } 414 } 415 if (DBG) log("getAsuLevel=" + asuLevel); 416 return asuLevel; 417 } 418 419 /** 420 * Get the signal strength as dBm 421 * 422 * @hide 423 */ 424 public int getDbm() { 425 int dBm; 426 427 if(isGsm()) { 428 if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 429 dBm = getGsmDbm(); 430 } else { 431 dBm = getLteDbm(); 432 } 433 } else { 434 int cdmaDbm = getCdmaDbm(); 435 int evdoDbm = getEvdoDbm(); 436 437 return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm 438 : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm)); 439 } 440 if (DBG) log("getDbm=" + dBm); 441 return dBm; 442 } 443 444 /** 445 * Get Gsm signal strength as dBm 446 * 447 * @hide 448 */ 449 public int getGsmDbm() { 450 int dBm; 451 452 int gsmSignalStrength = getGsmSignalStrength(); 453 int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 454 if (asu != -1) { 455 dBm = -113 + (2 * asu); 456 } else { 457 dBm = -1; 458 } 459 if (DBG) log("getGsmDbm=" + dBm); 460 return dBm; 461 } 462 463 /** 464 * Get gsm as level 0..4 465 * 466 * @hide 467 */ 468 public int getGsmLevel() { 469 int level; 470 471 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 472 // asu = 0 (-113dB or less) is very weak 473 // signal, its better to show 0 bars to the user in such cases. 474 // asu = 99 is a special case, where the signal strength is unknown. 475 int asu = getGsmSignalStrength(); 476 if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 477 else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT; 478 else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD; 479 else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE; 480 else level = SIGNAL_STRENGTH_POOR; 481 if (DBG) log("getGsmLevel=" + level); 482 return level; 483 } 484 485 /** 486 * Get the gsm signal level as an asu value between 0..31, 99 is unknown 487 * 488 * @hide 489 */ 490 public int getGsmAsuLevel() { 491 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 492 // asu = 0 (-113dB or less) is very weak 493 // signal, its better to show 0 bars to the user in such cases. 494 // asu = 99 is a special case, where the signal strength is unknown. 495 int level = getGsmSignalStrength(); 496 if (DBG) log("getGsmAsuLevel=" + level); 497 return level; 498 } 499 500 /** 501 * Get cdma as level 0..4 502 * 503 * @hide 504 */ 505 public int getCdmaLevel() { 506 final int cdmaDbm = getCdmaDbm(); 507 final int cdmaEcio = getCdmaEcio(); 508 int levelDbm; 509 int levelEcio; 510 511 if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT; 512 else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD; 513 else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE; 514 else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR; 515 else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 516 517 // Ec/Io are in dB*10 518 if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT; 519 else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD; 520 else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE; 521 else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR; 522 else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 523 524 int level = (levelDbm < levelEcio) ? levelDbm : levelEcio; 525 if (DBG) log("getCdmaLevel=" + level); 526 return level; 527 } 528 529 /** 530 * Get the cdma signal level as an asu value between 0..31, 99 is unknown 531 * 532 * @hide 533 */ 534 public int getCdmaAsuLevel() { 535 final int cdmaDbm = getCdmaDbm(); 536 final int cdmaEcio = getCdmaEcio(); 537 int cdmaAsuLevel; 538 int ecioAsuLevel; 539 540 if (cdmaDbm >= -75) cdmaAsuLevel = 16; 541 else if (cdmaDbm >= -82) cdmaAsuLevel = 8; 542 else if (cdmaDbm >= -90) cdmaAsuLevel = 4; 543 else if (cdmaDbm >= -95) cdmaAsuLevel = 2; 544 else if (cdmaDbm >= -100) cdmaAsuLevel = 1; 545 else cdmaAsuLevel = 99; 546 547 // Ec/Io are in dB*10 548 if (cdmaEcio >= -90) ecioAsuLevel = 16; 549 else if (cdmaEcio >= -100) ecioAsuLevel = 8; 550 else if (cdmaEcio >= -115) ecioAsuLevel = 4; 551 else if (cdmaEcio >= -130) ecioAsuLevel = 2; 552 else if (cdmaEcio >= -150) ecioAsuLevel = 1; 553 else ecioAsuLevel = 99; 554 555 int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel; 556 if (DBG) log("getCdmaAsuLevel=" + level); 557 return level; 558 } 559 560 /** 561 * Get Evdo as level 0..4 562 * 563 * @hide 564 */ 565 public int getEvdoLevel() { 566 int evdoDbm = getEvdoDbm(); 567 int evdoSnr = getEvdoSnr(); 568 int levelEvdoDbm; 569 int levelEvdoSnr; 570 571 if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT; 572 else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD; 573 else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE; 574 else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR; 575 else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 576 577 if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT; 578 else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD; 579 else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE; 580 else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR; 581 else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 582 583 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 584 if (DBG) log("getEvdoLevel=" + level); 585 return level; 586 } 587 588 /** 589 * Get the evdo signal level as an asu value between 0..31, 99 is unknown 590 * 591 * @hide 592 */ 593 public int getEvdoAsuLevel() { 594 int evdoDbm = getEvdoDbm(); 595 int evdoSnr = getEvdoSnr(); 596 int levelEvdoDbm; 597 int levelEvdoSnr; 598 599 if (evdoDbm >= -65) levelEvdoDbm = 16; 600 else if (evdoDbm >= -75) levelEvdoDbm = 8; 601 else if (evdoDbm >= -85) levelEvdoDbm = 4; 602 else if (evdoDbm >= -95) levelEvdoDbm = 2; 603 else if (evdoDbm >= -105) levelEvdoDbm = 1; 604 else levelEvdoDbm = 99; 605 606 if (evdoSnr >= 7) levelEvdoSnr = 16; 607 else if (evdoSnr >= 6) levelEvdoSnr = 8; 608 else if (evdoSnr >= 5) levelEvdoSnr = 4; 609 else if (evdoSnr >= 3) levelEvdoSnr = 2; 610 else if (evdoSnr >= 1) levelEvdoSnr = 1; 611 else levelEvdoSnr = 99; 612 613 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 614 if (DBG) log("getEvdoAsuLevel=" + level); 615 return level; 616 } 617 618 /** 619 * Get LTE as dBm 620 * 621 * @hide 622 */ 623 public int getLteDbm() { 624 return mLteRsrp; 625 } 626 627 /** 628 * Get LTE as level 0..4 629 * 630 * @hide 631 */ 632 public int getLteLevel() { 633 /* 634 * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received 635 * signal + noise RSRP = reference signal dBm RSRQ = quality of signal 636 * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio 637 * = -10log P1/P2 dB 638 */ 639 int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1; 640 641 if (mLteRsrp > -44) rsrpIconLevel = -1; 642 else if (mLteRsrp >= -85) rsrpIconLevel = SIGNAL_STRENGTH_GREAT; 643 else if (mLteRsrp >= -95) rsrpIconLevel = SIGNAL_STRENGTH_GOOD; 644 else if (mLteRsrp >= -105) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE; 645 else if (mLteRsrp >= -115) rsrpIconLevel = SIGNAL_STRENGTH_POOR; 646 else if (mLteRsrp >= -140) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 647 648 /* 649 * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5 650 * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars 651 * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna 652 * Icon Only 653 */ 654 if (mLteRssnr > 300) snrIconLevel = -1; 655 else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT; 656 else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD; 657 else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE; 658 else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR; 659 else if (mLteRssnr >= -200) 660 snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 661 662 if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:" 663 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel); 664 665 /* Choose a measurement type to use for notification */ 666 if (snrIconLevel != -1 && rsrpIconLevel != -1) { 667 /* 668 * The number of bars displayed shall be the smaller of the bars 669 * associated with LTE RSRP and the bars associated with the LTE 670 * RS_SNR 671 */ 672 return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel); 673 } 674 675 if (snrIconLevel != -1) return snrIconLevel; 676 677 if (rsrpIconLevel != -1) return rsrpIconLevel; 678 679 /* Valid values are (0-63, 99) as defined in TS 36.331 */ 680 if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 681 else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT; 682 else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD; 683 else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE; 684 else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR; 685 if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:" 686 + rssiIconLevel); 687 return rssiIconLevel; 688 689 } 690 /** 691 * Get the LTE signal level as an asu value between 0..97, 99 is unknown 692 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 693 * 694 * @hide 695 */ 696 public int getLteAsuLevel() { 697 int lteAsuLevel = 99; 698 int lteDbm = getLteDbm(); 699 /* 700 * 3GPP 27.007 (Ver 10.3.0) Sec 8.69 701 * 0 -140 dBm or less 702 * 1 -139 dBm 703 * 2...96 -138... -44 dBm 704 * 97 -43 dBm or greater 705 * 255 not known or not detectable 706 */ 707 /* 708 * validateInput will always give a valid range between -140 t0 -44 as 709 * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255 710 * and not 97 or 0 711 */ 712 if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255; 713 else lteAsuLevel = lteDbm + 140; 714 if (DBG) log("Lte Asu level: "+lteAsuLevel); 715 return lteAsuLevel; 716 } 717 718 /** 719 * @return true if this is for GSM 720 */ 721 public boolean isGsm() { 722 return this.isGsm; 723 } 724 725 /** 726 * @return hash code 727 */ 728 @Override 729 public int hashCode() { 730 int primeNum = 31; 731 return ((mGsmSignalStrength * primeNum) 732 + (mGsmBitErrorRate * primeNum) 733 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum) 734 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum) 735 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum) 736 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum) 737 + (isGsm ? 1 : 0)); 738 } 739 740 /** 741 * @return true if the signal strengths are the same 742 */ 743 @Override 744 public boolean equals (Object o) { 745 SignalStrength s; 746 747 try { 748 s = (SignalStrength) o; 749 } catch (ClassCastException ex) { 750 return false; 751 } 752 753 if (o == null) { 754 return false; 755 } 756 757 return (mGsmSignalStrength == s.mGsmSignalStrength 758 && mGsmBitErrorRate == s.mGsmBitErrorRate 759 && mCdmaDbm == s.mCdmaDbm 760 && mCdmaEcio == s.mCdmaEcio 761 && mEvdoDbm == s.mEvdoDbm 762 && mEvdoEcio == s.mEvdoEcio 763 && mEvdoSnr == s.mEvdoSnr 764 && mLteSignalStrength == s.mLteSignalStrength 765 && mLteRsrp == s.mLteRsrp 766 && mLteRsrq == s.mLteRsrq 767 && mLteRssnr == s.mLteRssnr 768 && mLteCqi == s.mLteCqi 769 && isGsm == s.isGsm); 770 } 771 772 /** 773 * @return string representation. 774 */ 775 @Override 776 public String toString() { 777 return ("SignalStrength:" 778 + " " + mGsmSignalStrength 779 + " " + mGsmBitErrorRate 780 + " " + mCdmaDbm 781 + " " + mCdmaEcio 782 + " " + mEvdoDbm 783 + " " + mEvdoEcio 784 + " " + mEvdoSnr 785 + " " + mLteSignalStrength 786 + " " + mLteRsrp 787 + " " + mLteRsrq 788 + " " + mLteRssnr 789 + " " + mLteCqi 790 + " " + (isGsm ? "gsm|lte" : "cdma")); 791 } 792 793 /** 794 * Set SignalStrength based on intent notifier map 795 * 796 * @param m intent notifier map 797 * @hide 798 */ 799 private void setFromNotifierBundle(Bundle m) { 800 mGsmSignalStrength = m.getInt("GsmSignalStrength"); 801 mGsmBitErrorRate = m.getInt("GsmBitErrorRate"); 802 mCdmaDbm = m.getInt("CdmaDbm"); 803 mCdmaEcio = m.getInt("CdmaEcio"); 804 mEvdoDbm = m.getInt("EvdoDbm"); 805 mEvdoEcio = m.getInt("EvdoEcio"); 806 mEvdoSnr = m.getInt("EvdoSnr"); 807 mLteSignalStrength = m.getInt("LteSignalStrength"); 808 mLteRsrp = m.getInt("LteRsrp"); 809 mLteRsrq = m.getInt("LteRsrq"); 810 mLteRssnr = m.getInt("LteRssnr"); 811 mLteCqi = m.getInt("LteCqi"); 812 isGsm = m.getBoolean("isGsm"); 813 } 814 815 /** 816 * Set intent notifier Bundle based on SignalStrength 817 * 818 * @param m intent notifier Bundle 819 * @hide 820 */ 821 public void fillInNotifierBundle(Bundle m) { 822 m.putInt("GsmSignalStrength", mGsmSignalStrength); 823 m.putInt("GsmBitErrorRate", mGsmBitErrorRate); 824 m.putInt("CdmaDbm", mCdmaDbm); 825 m.putInt("CdmaEcio", mCdmaEcio); 826 m.putInt("EvdoDbm", mEvdoDbm); 827 m.putInt("EvdoEcio", mEvdoEcio); 828 m.putInt("EvdoSnr", mEvdoSnr); 829 m.putInt("LteSignalStrength", mLteSignalStrength); 830 m.putInt("LteRsrp", mLteRsrp); 831 m.putInt("LteRsrq", mLteRsrq); 832 m.putInt("LteRssnr", mLteRssnr); 833 m.putInt("LteCqi", mLteCqi); 834 m.putBoolean("isGsm", Boolean.valueOf(isGsm)); 835 } 836 837 /** 838 * log 839 */ 840 private static void log(String s) { 841 Log.w(LOG_TAG, s); 842 } 843} 844