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