1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.telephony; 18 19import android.os.Bundle; 20import android.os.Parcel; 21import android.os.Parcelable; 22import android.util.Log; 23 24/** 25 * Contains phone signal strength related information. 26 */ 27public 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 * {@link Parcelable#writeToParcel} 278 */ 279 public void writeToParcel(Parcel out, int flags) { 280 out.writeInt(mGsmSignalStrength); 281 out.writeInt(mGsmBitErrorRate); 282 out.writeInt(mCdmaDbm); 283 out.writeInt(mCdmaEcio); 284 out.writeInt(mEvdoDbm); 285 out.writeInt(mEvdoEcio); 286 out.writeInt(mEvdoSnr); 287 out.writeInt(mLteSignalStrength); 288 out.writeInt(mLteRsrp); 289 out.writeInt(mLteRsrq); 290 out.writeInt(mLteRssnr); 291 out.writeInt(mLteCqi); 292 out.writeInt(isGsm ? 1 : 0); 293 } 294 295 /** 296 * {@link Parcelable#describeContents} 297 */ 298 public int describeContents() { 299 return 0; 300 } 301 302 /** 303 * {@link Parcelable.Creator} 304 * 305 * @hide 306 */ 307 public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() { 308 public SignalStrength createFromParcel(Parcel in) { 309 return new SignalStrength(in); 310 } 311 312 public SignalStrength[] newArray(int size) { 313 return new SignalStrength[size]; 314 } 315 }; 316 317 /** 318 * Validate the individual signal strength fields as per the range 319 * specified in ril.h 320 * Set to invalid any field that is not in the valid range 321 * Cdma, evdo, lte rsrp & rsrq values are sign converted 322 * when received from ril interface 323 * 324 * @return 325 * Valid values for all signalstrength fields 326 * @hide 327 */ 328 public void validateInput() { 329 if (DBG) log("Signal before validate=" + this); 330 // TS 27.007 8.5 331 mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99; 332 // BER no change; 333 334 mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120; 335 mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160; 336 337 mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120; 338 mEvdoEcio = (mEvdoEcio > 0) ? -mEvdoEcio : -1; 339 mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1; 340 341 // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC 342 mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99; 343 mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID; 344 mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID; 345 mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr 346 : SignalStrength.INVALID; 347 // Cqi no change 348 if (DBG) log("Signal after validate=" + this); 349 } 350 351 /** 352 * @param true - Gsm, Lte phones 353 * false - Cdma phones 354 * 355 * Used by voice phone to set the isGsm 356 * flag 357 * @hide 358 */ 359 public void setGsm(boolean gsmFlag) { 360 isGsm = gsmFlag; 361 } 362 363 /** 364 * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS 365 * 27.007 8.5 366 */ 367 public int getGsmSignalStrength() { 368 return this.mGsmSignalStrength; 369 } 370 371 /** 372 * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5 373 */ 374 public int getGsmBitErrorRate() { 375 return this.mGsmBitErrorRate; 376 } 377 378 /** 379 * Get the CDMA RSSI value in dBm 380 */ 381 public int getCdmaDbm() { 382 return this.mCdmaDbm; 383 } 384 385 /** 386 * Get the CDMA Ec/Io value in dB*10 387 */ 388 public int getCdmaEcio() { 389 return this.mCdmaEcio; 390 } 391 392 /** 393 * Get the EVDO RSSI value in dBm 394 */ 395 public int getEvdoDbm() { 396 return this.mEvdoDbm; 397 } 398 399 /** 400 * Get the EVDO Ec/Io value in dB*10 401 */ 402 public int getEvdoEcio() { 403 return this.mEvdoEcio; 404 } 405 406 /** 407 * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest. 408 */ 409 public int getEvdoSnr() { 410 return this.mEvdoSnr; 411 } 412 413 /** @hide */ 414 public int getLteSignalStrenght() { 415 return mLteSignalStrength; 416 } 417 418 /** @hide */ 419 public int getLteRsrp() { 420 return mLteRsrp; 421 } 422 423 /** @hide */ 424 public int getLteRsrq() { 425 return mLteRsrq; 426 } 427 428 /** @hide */ 429 public int getLteRssnr() { 430 return mLteRssnr; 431 } 432 433 /** @hide */ 434 public int getLteCqi() { 435 return mLteCqi; 436 } 437 438 /** 439 * Get signal level as an int from 0..4 440 * 441 * @hide 442 */ 443 public int getLevel() { 444 int level; 445 446 if (isGsm) { 447 level = getLteLevel(); 448 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 449 level = getGsmLevel(); 450 } 451 } else { 452 int cdmaLevel = getCdmaLevel(); 453 int evdoLevel = getEvdoLevel(); 454 if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 455 /* We don't know evdo, use cdma */ 456 level = cdmaLevel; 457 } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 458 /* We don't know cdma, use evdo */ 459 level = evdoLevel; 460 } else { 461 /* We know both, use the lowest level */ 462 level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; 463 } 464 } 465 if (DBG) log("getLevel=" + level); 466 return level; 467 } 468 469 /** 470 * Get the signal level as an asu value between 0..31, 99 is unknown 471 * 472 * @hide 473 */ 474 public int getAsuLevel() { 475 int asuLevel; 476 if (isGsm) { 477 if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 478 asuLevel = getGsmAsuLevel(); 479 } else { 480 asuLevel = getLteAsuLevel(); 481 } 482 } else { 483 int cdmaAsuLevel = getCdmaAsuLevel(); 484 int evdoAsuLevel = getEvdoAsuLevel(); 485 if (evdoAsuLevel == 0) { 486 /* We don't know evdo use, cdma */ 487 asuLevel = cdmaAsuLevel; 488 } else if (cdmaAsuLevel == 0) { 489 /* We don't know cdma use, evdo */ 490 asuLevel = evdoAsuLevel; 491 } else { 492 /* We know both, use the lowest level */ 493 asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel; 494 } 495 } 496 if (DBG) log("getAsuLevel=" + asuLevel); 497 return asuLevel; 498 } 499 500 /** 501 * Get the signal strength as dBm 502 * 503 * @hide 504 */ 505 public int getDbm() { 506 int dBm; 507 508 if(isGsm()) { 509 if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 510 dBm = getGsmDbm(); 511 } else { 512 dBm = getLteDbm(); 513 } 514 } else { 515 int cdmaDbm = getCdmaDbm(); 516 int evdoDbm = getEvdoDbm(); 517 518 return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm 519 : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm)); 520 } 521 if (DBG) log("getDbm=" + dBm); 522 return dBm; 523 } 524 525 /** 526 * Get Gsm signal strength as dBm 527 * 528 * @hide 529 */ 530 public int getGsmDbm() { 531 int dBm; 532 533 int gsmSignalStrength = getGsmSignalStrength(); 534 int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 535 if (asu != -1) { 536 dBm = -113 + (2 * asu); 537 } else { 538 dBm = -1; 539 } 540 if (DBG) log("getGsmDbm=" + dBm); 541 return dBm; 542 } 543 544 /** 545 * Get gsm as level 0..4 546 * 547 * @hide 548 */ 549 public int getGsmLevel() { 550 int level; 551 552 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 553 // asu = 0 (-113dB or less) is very weak 554 // signal, its better to show 0 bars to the user in such cases. 555 // asu = 99 is a special case, where the signal strength is unknown. 556 int asu = getGsmSignalStrength(); 557 if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 558 else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT; 559 else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD; 560 else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE; 561 else level = SIGNAL_STRENGTH_POOR; 562 if (DBG) log("getGsmLevel=" + level); 563 return level; 564 } 565 566 /** 567 * Get the gsm signal level as an asu value between 0..31, 99 is unknown 568 * 569 * @hide 570 */ 571 public int getGsmAsuLevel() { 572 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 573 // asu = 0 (-113dB or less) is very weak 574 // signal, its better to show 0 bars to the user in such cases. 575 // asu = 99 is a special case, where the signal strength is unknown. 576 int level = getGsmSignalStrength(); 577 if (DBG) log("getGsmAsuLevel=" + level); 578 return level; 579 } 580 581 /** 582 * Get cdma as level 0..4 583 * 584 * @hide 585 */ 586 public int getCdmaLevel() { 587 final int cdmaDbm = getCdmaDbm(); 588 final int cdmaEcio = getCdmaEcio(); 589 int levelDbm; 590 int levelEcio; 591 592 if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT; 593 else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD; 594 else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE; 595 else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR; 596 else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 597 598 // Ec/Io are in dB*10 599 if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT; 600 else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD; 601 else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE; 602 else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR; 603 else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 604 605 int level = (levelDbm < levelEcio) ? levelDbm : levelEcio; 606 if (DBG) log("getCdmaLevel=" + level); 607 return level; 608 } 609 610 /** 611 * Get the cdma signal level as an asu value between 0..31, 99 is unknown 612 * 613 * @hide 614 */ 615 public int getCdmaAsuLevel() { 616 final int cdmaDbm = getCdmaDbm(); 617 final int cdmaEcio = getCdmaEcio(); 618 int cdmaAsuLevel; 619 int ecioAsuLevel; 620 621 if (cdmaDbm >= -75) cdmaAsuLevel = 16; 622 else if (cdmaDbm >= -82) cdmaAsuLevel = 8; 623 else if (cdmaDbm >= -90) cdmaAsuLevel = 4; 624 else if (cdmaDbm >= -95) cdmaAsuLevel = 2; 625 else if (cdmaDbm >= -100) cdmaAsuLevel = 1; 626 else cdmaAsuLevel = 99; 627 628 // Ec/Io are in dB*10 629 if (cdmaEcio >= -90) ecioAsuLevel = 16; 630 else if (cdmaEcio >= -100) ecioAsuLevel = 8; 631 else if (cdmaEcio >= -115) ecioAsuLevel = 4; 632 else if (cdmaEcio >= -130) ecioAsuLevel = 2; 633 else if (cdmaEcio >= -150) ecioAsuLevel = 1; 634 else ecioAsuLevel = 99; 635 636 int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel; 637 if (DBG) log("getCdmaAsuLevel=" + level); 638 return level; 639 } 640 641 /** 642 * Get Evdo as level 0..4 643 * 644 * @hide 645 */ 646 public int getEvdoLevel() { 647 int evdoDbm = getEvdoDbm(); 648 int evdoSnr = getEvdoSnr(); 649 int levelEvdoDbm; 650 int levelEvdoSnr; 651 652 if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT; 653 else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD; 654 else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE; 655 else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR; 656 else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 657 658 if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT; 659 else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD; 660 else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE; 661 else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR; 662 else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 663 664 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 665 if (DBG) log("getEvdoLevel=" + level); 666 return level; 667 } 668 669 /** 670 * Get the evdo signal level as an asu value between 0..31, 99 is unknown 671 * 672 * @hide 673 */ 674 public int getEvdoAsuLevel() { 675 int evdoDbm = getEvdoDbm(); 676 int evdoSnr = getEvdoSnr(); 677 int levelEvdoDbm; 678 int levelEvdoSnr; 679 680 if (evdoDbm >= -65) levelEvdoDbm = 16; 681 else if (evdoDbm >= -75) levelEvdoDbm = 8; 682 else if (evdoDbm >= -85) levelEvdoDbm = 4; 683 else if (evdoDbm >= -95) levelEvdoDbm = 2; 684 else if (evdoDbm >= -105) levelEvdoDbm = 1; 685 else levelEvdoDbm = 99; 686 687 if (evdoSnr >= 7) levelEvdoSnr = 16; 688 else if (evdoSnr >= 6) levelEvdoSnr = 8; 689 else if (evdoSnr >= 5) levelEvdoSnr = 4; 690 else if (evdoSnr >= 3) levelEvdoSnr = 2; 691 else if (evdoSnr >= 1) levelEvdoSnr = 1; 692 else levelEvdoSnr = 99; 693 694 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 695 if (DBG) log("getEvdoAsuLevel=" + level); 696 return level; 697 } 698 699 /** 700 * Get LTE as dBm 701 * 702 * @hide 703 */ 704 public int getLteDbm() { 705 return mLteRsrp; 706 } 707 708 /** 709 * Get LTE as level 0..4 710 * 711 * @hide 712 */ 713 public int getLteLevel() { 714 /* 715 * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received 716 * signal + noise RSRP = reference signal dBm RSRQ = quality of signal 717 * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio 718 * = -10log P1/P2 dB 719 */ 720 int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1; 721 722 if (mLteRsrp > -44) rsrpIconLevel = -1; 723 else if (mLteRsrp >= -85) rsrpIconLevel = SIGNAL_STRENGTH_GREAT; 724 else if (mLteRsrp >= -95) rsrpIconLevel = SIGNAL_STRENGTH_GOOD; 725 else if (mLteRsrp >= -105) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE; 726 else if (mLteRsrp >= -115) rsrpIconLevel = SIGNAL_STRENGTH_POOR; 727 else if (mLteRsrp >= -140) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 728 729 /* 730 * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5 731 * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars 732 * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna 733 * Icon Only 734 */ 735 if (mLteRssnr > 300) snrIconLevel = -1; 736 else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT; 737 else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD; 738 else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE; 739 else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR; 740 else if (mLteRssnr >= -200) 741 snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 742 743 if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:" 744 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel); 745 746 /* Choose a measurement type to use for notification */ 747 if (snrIconLevel != -1 && rsrpIconLevel != -1) { 748 /* 749 * The number of bars displayed shall be the smaller of the bars 750 * associated with LTE RSRP and the bars associated with the LTE 751 * RS_SNR 752 */ 753 return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel); 754 } 755 756 if (snrIconLevel != -1) return snrIconLevel; 757 758 if (rsrpIconLevel != -1) return rsrpIconLevel; 759 760 /* Valid values are (0-63, 99) as defined in TS 36.331 */ 761 if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 762 else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT; 763 else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD; 764 else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE; 765 else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR; 766 if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:" 767 + rssiIconLevel); 768 return rssiIconLevel; 769 770 } 771 /** 772 * Get the LTE signal level as an asu value between 0..97, 99 is unknown 773 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 774 * 775 * @hide 776 */ 777 public int getLteAsuLevel() { 778 int lteAsuLevel = 99; 779 int lteDbm = getLteDbm(); 780 /* 781 * 3GPP 27.007 (Ver 10.3.0) Sec 8.69 782 * 0 -140 dBm or less 783 * 1 -139 dBm 784 * 2...96 -138... -44 dBm 785 * 97 -43 dBm or greater 786 * 255 not known or not detectable 787 */ 788 /* 789 * validateInput will always give a valid range between -140 t0 -44 as 790 * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255 791 * and not 97 or 0 792 */ 793 if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255; 794 else lteAsuLevel = lteDbm + 140; 795 if (DBG) log("Lte Asu level: "+lteAsuLevel); 796 return lteAsuLevel; 797 } 798 799 /** 800 * @return true if this is for GSM 801 */ 802 public boolean isGsm() { 803 return this.isGsm; 804 } 805 806 /** 807 * @return hash code 808 */ 809 @Override 810 public int hashCode() { 811 int primeNum = 31; 812 return ((mGsmSignalStrength * primeNum) 813 + (mGsmBitErrorRate * primeNum) 814 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum) 815 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum) 816 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum) 817 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum) 818 + (isGsm ? 1 : 0)); 819 } 820 821 /** 822 * @return true if the signal strengths are the same 823 */ 824 @Override 825 public boolean equals (Object o) { 826 SignalStrength s; 827 828 try { 829 s = (SignalStrength) o; 830 } catch (ClassCastException ex) { 831 return false; 832 } 833 834 if (o == null) { 835 return false; 836 } 837 838 return (mGsmSignalStrength == s.mGsmSignalStrength 839 && mGsmBitErrorRate == s.mGsmBitErrorRate 840 && mCdmaDbm == s.mCdmaDbm 841 && mCdmaEcio == s.mCdmaEcio 842 && mEvdoDbm == s.mEvdoDbm 843 && mEvdoEcio == s.mEvdoEcio 844 && mEvdoSnr == s.mEvdoSnr 845 && mLteSignalStrength == s.mLteSignalStrength 846 && mLteRsrp == s.mLteRsrp 847 && mLteRsrq == s.mLteRsrq 848 && mLteRssnr == s.mLteRssnr 849 && mLteCqi == s.mLteCqi 850 && isGsm == s.isGsm); 851 } 852 853 /** 854 * @return string representation. 855 */ 856 @Override 857 public String toString() { 858 return ("SignalStrength:" 859 + " " + mGsmSignalStrength 860 + " " + mGsmBitErrorRate 861 + " " + mCdmaDbm 862 + " " + mCdmaEcio 863 + " " + mEvdoDbm 864 + " " + mEvdoEcio 865 + " " + mEvdoSnr 866 + " " + mLteSignalStrength 867 + " " + mLteRsrp 868 + " " + mLteRsrq 869 + " " + mLteRssnr 870 + " " + mLteCqi 871 + " " + (isGsm ? "gsm|lte" : "cdma")); 872 } 873 874 /** 875 * Set SignalStrength based on intent notifier map 876 * 877 * @param m intent notifier map 878 * @hide 879 */ 880 private void setFromNotifierBundle(Bundle m) { 881 mGsmSignalStrength = m.getInt("GsmSignalStrength"); 882 mGsmBitErrorRate = m.getInt("GsmBitErrorRate"); 883 mCdmaDbm = m.getInt("CdmaDbm"); 884 mCdmaEcio = m.getInt("CdmaEcio"); 885 mEvdoDbm = m.getInt("EvdoDbm"); 886 mEvdoEcio = m.getInt("EvdoEcio"); 887 mEvdoSnr = m.getInt("EvdoSnr"); 888 mLteSignalStrength = m.getInt("LteSignalStrength"); 889 mLteRsrp = m.getInt("LteRsrp"); 890 mLteRsrq = m.getInt("LteRsrq"); 891 mLteRssnr = m.getInt("LteRssnr"); 892 mLteCqi = m.getInt("LteCqi"); 893 isGsm = m.getBoolean("isGsm"); 894 } 895 896 /** 897 * Set intent notifier Bundle based on SignalStrength 898 * 899 * @param m intent notifier Bundle 900 * @hide 901 */ 902 public void fillInNotifierBundle(Bundle m) { 903 m.putInt("GsmSignalStrength", mGsmSignalStrength); 904 m.putInt("GsmBitErrorRate", mGsmBitErrorRate); 905 m.putInt("CdmaDbm", mCdmaDbm); 906 m.putInt("CdmaEcio", mCdmaEcio); 907 m.putInt("EvdoDbm", mEvdoDbm); 908 m.putInt("EvdoEcio", mEvdoEcio); 909 m.putInt("EvdoSnr", mEvdoSnr); 910 m.putInt("LteSignalStrength", mLteSignalStrength); 911 m.putInt("LteRsrp", mLteRsrp); 912 m.putInt("LteRsrq", mLteRsrq); 913 m.putInt("LteRssnr", mLteRssnr); 914 m.putInt("LteCqi", mLteCqi); 915 m.putBoolean("isGsm", Boolean.valueOf(isGsm)); 916 } 917 918 /** 919 * log 920 */ 921 private static void log(String s) { 922 Log.w(LOG_TAG, s); 923 } 924} 925