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