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 if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 537 dBm = getGsmDbm(); 538 } else { 539 dBm = getLteDbm(); 540 } 541 } else { 542 int cdmaDbm = getCdmaDbm(); 543 int evdoDbm = getEvdoDbm(); 544 545 return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm 546 : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm)); 547 } 548 if (DBG) log("getDbm=" + dBm); 549 return dBm; 550 } 551 552 /** 553 * Get Gsm signal strength as dBm 554 * 555 * @hide 556 */ 557 public int getGsmDbm() { 558 int dBm; 559 560 int gsmSignalStrength = getGsmSignalStrength(); 561 int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 562 if (asu != -1) { 563 dBm = -113 + (2 * asu); 564 } else { 565 dBm = -1; 566 } 567 if (DBG) log("getGsmDbm=" + dBm); 568 return dBm; 569 } 570 571 /** 572 * Get gsm as level 0..4 573 * 574 * @hide 575 */ 576 public int getGsmLevel() { 577 int level; 578 579 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 580 // asu = 0 (-113dB or less) is very weak 581 // signal, its better to show 0 bars to the user in such cases. 582 // asu = 99 is a special case, where the signal strength is unknown. 583 int asu = getGsmSignalStrength(); 584 if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 585 else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT; 586 else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD; 587 else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE; 588 else level = SIGNAL_STRENGTH_POOR; 589 if (DBG) log("getGsmLevel=" + level); 590 return level; 591 } 592 593 /** 594 * Get the gsm signal level as an asu value between 0..31, 99 is unknown 595 * 596 * @hide 597 */ 598 public int getGsmAsuLevel() { 599 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 600 // asu = 0 (-113dB or less) is very weak 601 // signal, its better to show 0 bars to the user in such cases. 602 // asu = 99 is a special case, where the signal strength is unknown. 603 int level = getGsmSignalStrength(); 604 if (DBG) log("getGsmAsuLevel=" + level); 605 return level; 606 } 607 608 /** 609 * Get cdma as level 0..4 610 * 611 * @hide 612 */ 613 public int getCdmaLevel() { 614 final int cdmaDbm = getCdmaDbm(); 615 final int cdmaEcio = getCdmaEcio(); 616 int levelDbm; 617 int levelEcio; 618 619 if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT; 620 else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD; 621 else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE; 622 else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR; 623 else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 624 625 // Ec/Io are in dB*10 626 if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT; 627 else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD; 628 else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE; 629 else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR; 630 else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 631 632 int level = (levelDbm < levelEcio) ? levelDbm : levelEcio; 633 if (DBG) log("getCdmaLevel=" + level); 634 return level; 635 } 636 637 /** 638 * Get the cdma signal level as an asu value between 0..31, 99 is unknown 639 * 640 * @hide 641 */ 642 public int getCdmaAsuLevel() { 643 final int cdmaDbm = getCdmaDbm(); 644 final int cdmaEcio = getCdmaEcio(); 645 int cdmaAsuLevel; 646 int ecioAsuLevel; 647 648 if (cdmaDbm >= -75) cdmaAsuLevel = 16; 649 else if (cdmaDbm >= -82) cdmaAsuLevel = 8; 650 else if (cdmaDbm >= -90) cdmaAsuLevel = 4; 651 else if (cdmaDbm >= -95) cdmaAsuLevel = 2; 652 else if (cdmaDbm >= -100) cdmaAsuLevel = 1; 653 else cdmaAsuLevel = 99; 654 655 // Ec/Io are in dB*10 656 if (cdmaEcio >= -90) ecioAsuLevel = 16; 657 else if (cdmaEcio >= -100) ecioAsuLevel = 8; 658 else if (cdmaEcio >= -115) ecioAsuLevel = 4; 659 else if (cdmaEcio >= -130) ecioAsuLevel = 2; 660 else if (cdmaEcio >= -150) ecioAsuLevel = 1; 661 else ecioAsuLevel = 99; 662 663 int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel; 664 if (DBG) log("getCdmaAsuLevel=" + level); 665 return level; 666 } 667 668 /** 669 * Get Evdo as level 0..4 670 * 671 * @hide 672 */ 673 public int getEvdoLevel() { 674 int evdoDbm = getEvdoDbm(); 675 int evdoSnr = getEvdoSnr(); 676 int levelEvdoDbm; 677 int levelEvdoSnr; 678 679 if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT; 680 else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD; 681 else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE; 682 else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR; 683 else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 684 685 if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT; 686 else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD; 687 else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE; 688 else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR; 689 else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 690 691 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 692 if (DBG) log("getEvdoLevel=" + level); 693 return level; 694 } 695 696 /** 697 * Get the evdo signal level as an asu value between 0..31, 99 is unknown 698 * 699 * @hide 700 */ 701 public int getEvdoAsuLevel() { 702 int evdoDbm = getEvdoDbm(); 703 int evdoSnr = getEvdoSnr(); 704 int levelEvdoDbm; 705 int levelEvdoSnr; 706 707 if (evdoDbm >= -65) levelEvdoDbm = 16; 708 else if (evdoDbm >= -75) levelEvdoDbm = 8; 709 else if (evdoDbm >= -85) levelEvdoDbm = 4; 710 else if (evdoDbm >= -95) levelEvdoDbm = 2; 711 else if (evdoDbm >= -105) levelEvdoDbm = 1; 712 else levelEvdoDbm = 99; 713 714 if (evdoSnr >= 7) levelEvdoSnr = 16; 715 else if (evdoSnr >= 6) levelEvdoSnr = 8; 716 else if (evdoSnr >= 5) levelEvdoSnr = 4; 717 else if (evdoSnr >= 3) levelEvdoSnr = 2; 718 else if (evdoSnr >= 1) levelEvdoSnr = 1; 719 else levelEvdoSnr = 99; 720 721 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 722 if (DBG) log("getEvdoAsuLevel=" + level); 723 return level; 724 } 725 726 /** 727 * Get LTE as dBm 728 * 729 * @hide 730 */ 731 public int getLteDbm() { 732 return mLteRsrp; 733 } 734 735 /** 736 * Get LTE as level 0..4 737 * 738 * @hide 739 */ 740 public int getLteLevel() { 741 /* 742 * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received 743 * signal + noise RSRP = reference signal dBm RSRQ = quality of signal 744 * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio 745 * = -10log P1/P2 dB 746 */ 747 int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1; 748 749 if (mLteRsrp > -44) rsrpIconLevel = -1; 750 else if (mLteRsrp >= -85) rsrpIconLevel = SIGNAL_STRENGTH_GREAT; 751 else if (mLteRsrp >= -95) rsrpIconLevel = SIGNAL_STRENGTH_GOOD; 752 else if (mLteRsrp >= -105) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE; 753 else if (mLteRsrp >= -115) rsrpIconLevel = SIGNAL_STRENGTH_POOR; 754 else if (mLteRsrp >= -140) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 755 756 /* 757 * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5 758 * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars 759 * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna 760 * Icon Only 761 */ 762 if (mLteRssnr > 300) snrIconLevel = -1; 763 else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT; 764 else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD; 765 else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE; 766 else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR; 767 else if (mLteRssnr >= -200) 768 snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 769 770 if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:" 771 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel); 772 773 /* Choose a measurement type to use for notification */ 774 if (snrIconLevel != -1 && rsrpIconLevel != -1) { 775 /* 776 * The number of bars displayed shall be the smaller of the bars 777 * associated with LTE RSRP and the bars associated with the LTE 778 * RS_SNR 779 */ 780 return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel); 781 } 782 783 if (snrIconLevel != -1) return snrIconLevel; 784 785 if (rsrpIconLevel != -1) return rsrpIconLevel; 786 787 /* Valid values are (0-63, 99) as defined in TS 36.331 */ 788 if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 789 else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT; 790 else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD; 791 else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE; 792 else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR; 793 if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:" 794 + rssiIconLevel); 795 return rssiIconLevel; 796 797 } 798 /** 799 * Get the LTE signal level as an asu value between 0..97, 99 is unknown 800 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 801 * 802 * @hide 803 */ 804 public int getLteAsuLevel() { 805 int lteAsuLevel = 99; 806 int lteDbm = getLteDbm(); 807 /* 808 * 3GPP 27.007 (Ver 10.3.0) Sec 8.69 809 * 0 -140 dBm or less 810 * 1 -139 dBm 811 * 2...96 -138... -44 dBm 812 * 97 -43 dBm or greater 813 * 255 not known or not detectable 814 */ 815 /* 816 * validateInput will always give a valid range between -140 t0 -44 as 817 * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255 818 * and not 97 or 0 819 */ 820 if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255; 821 else lteAsuLevel = lteDbm + 140; 822 if (DBG) log("Lte Asu level: "+lteAsuLevel); 823 return lteAsuLevel; 824 } 825 826 /** 827 * @return true if this is for GSM 828 */ 829 public boolean isGsm() { 830 return this.isGsm; 831 } 832 833 /** 834 * @return hash code 835 */ 836 @Override 837 public int hashCode() { 838 int primeNum = 31; 839 return ((mGsmSignalStrength * primeNum) 840 + (mGsmBitErrorRate * primeNum) 841 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum) 842 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum) 843 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum) 844 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum) 845 + (isGsm ? 1 : 0)); 846 } 847 848 /** 849 * @return true if the signal strengths are the same 850 */ 851 @Override 852 public boolean equals (Object o) { 853 SignalStrength s; 854 855 try { 856 s = (SignalStrength) o; 857 } catch (ClassCastException ex) { 858 return false; 859 } 860 861 if (o == null) { 862 return false; 863 } 864 865 return (mGsmSignalStrength == s.mGsmSignalStrength 866 && mGsmBitErrorRate == s.mGsmBitErrorRate 867 && mCdmaDbm == s.mCdmaDbm 868 && mCdmaEcio == s.mCdmaEcio 869 && mEvdoDbm == s.mEvdoDbm 870 && mEvdoEcio == s.mEvdoEcio 871 && mEvdoSnr == s.mEvdoSnr 872 && mLteSignalStrength == s.mLteSignalStrength 873 && mLteRsrp == s.mLteRsrp 874 && mLteRsrq == s.mLteRsrq 875 && mLteRssnr == s.mLteRssnr 876 && mLteCqi == s.mLteCqi 877 && isGsm == s.isGsm); 878 } 879 880 /** 881 * @return string representation. 882 */ 883 @Override 884 public String toString() { 885 return ("SignalStrength:" 886 + " " + mGsmSignalStrength 887 + " " + mGsmBitErrorRate 888 + " " + mCdmaDbm 889 + " " + mCdmaEcio 890 + " " + mEvdoDbm 891 + " " + mEvdoEcio 892 + " " + mEvdoSnr 893 + " " + mLteSignalStrength 894 + " " + mLteRsrp 895 + " " + mLteRsrq 896 + " " + mLteRssnr 897 + " " + mLteCqi 898 + " " + (isGsm ? "gsm|lte" : "cdma")); 899 } 900 901 /** 902 * Set SignalStrength based on intent notifier map 903 * 904 * @param m intent notifier map 905 * @hide 906 */ 907 private void setFromNotifierBundle(Bundle m) { 908 mGsmSignalStrength = m.getInt("GsmSignalStrength"); 909 mGsmBitErrorRate = m.getInt("GsmBitErrorRate"); 910 mCdmaDbm = m.getInt("CdmaDbm"); 911 mCdmaEcio = m.getInt("CdmaEcio"); 912 mEvdoDbm = m.getInt("EvdoDbm"); 913 mEvdoEcio = m.getInt("EvdoEcio"); 914 mEvdoSnr = m.getInt("EvdoSnr"); 915 mLteSignalStrength = m.getInt("LteSignalStrength"); 916 mLteRsrp = m.getInt("LteRsrp"); 917 mLteRsrq = m.getInt("LteRsrq"); 918 mLteRssnr = m.getInt("LteRssnr"); 919 mLteCqi = m.getInt("LteCqi"); 920 isGsm = m.getBoolean("isGsm"); 921 } 922 923 /** 924 * Set intent notifier Bundle based on SignalStrength 925 * 926 * @param m intent notifier Bundle 927 * @hide 928 */ 929 public void fillInNotifierBundle(Bundle m) { 930 m.putInt("GsmSignalStrength", mGsmSignalStrength); 931 m.putInt("GsmBitErrorRate", mGsmBitErrorRate); 932 m.putInt("CdmaDbm", mCdmaDbm); 933 m.putInt("CdmaEcio", mCdmaEcio); 934 m.putInt("EvdoDbm", mEvdoDbm); 935 m.putInt("EvdoEcio", mEvdoEcio); 936 m.putInt("EvdoSnr", mEvdoSnr); 937 m.putInt("LteSignalStrength", mLteSignalStrength); 938 m.putInt("LteRsrp", mLteRsrp); 939 m.putInt("LteRsrq", mLteRsrq); 940 m.putInt("LteRssnr", mLteRssnr); 941 m.putInt("LteCqi", mLteCqi); 942 m.putBoolean("isGsm", Boolean.valueOf(isGsm)); 943 } 944 945 /** 946 * log 947 */ 948 private static void log(String s) { 949 Rlog.w(LOG_TAG, s); 950 } 951 } 952