1 /* 2 * Copyright (C) 2016 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.location; 18 19 import android.annotation.FloatRange; 20 import android.annotation.IntDef; 21 import android.annotation.IntRange; 22 import android.annotation.NonNull; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import com.android.internal.util.Preconditions; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.ArrayList; 31 import java.util.Arrays; 32 import java.util.Objects; 33 34 /** 35 * This class represents the current state of the GNSS engine and is used in conjunction with 36 * {@link GnssStatus.Callback}. 37 * 38 * @see LocationManager#registerGnssStatusCallback 39 * @see GnssStatus.Callback 40 */ 41 public final class GnssStatus implements Parcelable { 42 43 // These must match the definitions in GNSS HAL. 44 // 45 // Note: these constants are also duplicated in GnssStatusCompat.java in the androidx support 46 // library. if adding a constellation, please update that file as well. 47 48 /** Unknown constellation type. */ 49 public static final int CONSTELLATION_UNKNOWN = 0; 50 /** Constellation type constant for GPS. */ 51 public static final int CONSTELLATION_GPS = 1; 52 /** Constellation type constant for SBAS. */ 53 public static final int CONSTELLATION_SBAS = 2; 54 /** Constellation type constant for Glonass. */ 55 public static final int CONSTELLATION_GLONASS = 3; 56 /** Constellation type constant for QZSS. */ 57 public static final int CONSTELLATION_QZSS = 4; 58 /** Constellation type constant for Beidou. */ 59 public static final int CONSTELLATION_BEIDOU = 5; 60 /** Constellation type constant for Galileo. */ 61 public static final int CONSTELLATION_GALILEO = 6; 62 /** Constellation type constant for IRNSS. */ 63 public static final int CONSTELLATION_IRNSS = 7; 64 /** @hide */ 65 public static final int CONSTELLATION_COUNT = 8; 66 67 private static final int SVID_FLAGS_NONE = 0; 68 private static final int SVID_FLAGS_HAS_EPHEMERIS_DATA = (1 << 0); 69 private static final int SVID_FLAGS_HAS_ALMANAC_DATA = (1 << 1); 70 private static final int SVID_FLAGS_USED_IN_FIX = (1 << 2); 71 private static final int SVID_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3); 72 private static final int SVID_FLAGS_HAS_BASEBAND_CN0 = (1 << 4); 73 74 private static final int SVID_SHIFT_WIDTH = 12; 75 private static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 8; 76 private static final int CONSTELLATION_TYPE_MASK = 0xf; 77 78 /** 79 * Used for receiving notifications when GNSS events happen. 80 * 81 * @see LocationManager#registerGnssStatusCallback 82 */ 83 public static abstract class Callback { 84 /** 85 * Called when GNSS system has started. 86 */ onStarted()87 public void onStarted() { 88 } 89 90 /** 91 * Called when GNSS system has stopped. 92 */ onStopped()93 public void onStopped() { 94 } 95 96 /** 97 * Called when the GNSS system has received its first fix since starting. 98 * 99 * @param ttffMillis the time from start to first fix in milliseconds. 100 */ onFirstFix(int ttffMillis)101 public void onFirstFix(int ttffMillis) { 102 } 103 104 /** 105 * Called periodically to report GNSS satellite status. 106 * 107 * @param status the current status of all satellites. 108 */ onSatelliteStatusChanged(@onNull GnssStatus status)109 public void onSatelliteStatusChanged(@NonNull GnssStatus status) { 110 } 111 } 112 113 /** 114 * Constellation type. 115 * 116 * @hide 117 */ 118 @Retention(RetentionPolicy.SOURCE) 119 @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS, 120 CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO, CONSTELLATION_IRNSS}) 121 public @interface ConstellationType { 122 } 123 124 /** 125 * Create a GnssStatus that wraps the given arguments without any additional overhead. Callers 126 * are responsible for guaranteeing that the arguments are never modified after calling this 127 * method. 128 * 129 * @hide 130 */ 131 @NonNull wrap(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations, float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs)132 public static GnssStatus wrap(int svCount, int[] svidWithFlags, float[] cn0DbHzs, 133 float[] elevations, float[] azimuths, float[] carrierFrequencies, 134 float[] basebandCn0DbHzs) { 135 Preconditions.checkState(svCount >= 0); 136 Preconditions.checkState(svidWithFlags.length >= svCount); 137 Preconditions.checkState(elevations.length >= svCount); 138 Preconditions.checkState(azimuths.length >= svCount); 139 Preconditions.checkState(carrierFrequencies.length >= svCount); 140 Preconditions.checkState(basebandCn0DbHzs.length >= svCount); 141 142 return new GnssStatus(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths, 143 carrierFrequencies, basebandCn0DbHzs); 144 } 145 146 private final int mSvCount; 147 private final int[] mSvidWithFlags; 148 private final float[] mCn0DbHzs; 149 private final float[] mElevations; 150 private final float[] mAzimuths; 151 private final float[] mCarrierFrequencies; 152 private final float[] mBasebandCn0DbHzs; 153 GnssStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations, float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs)154 private GnssStatus(int svCount, int[] svidWithFlags, float[] cn0DbHzs, float[] elevations, 155 float[] azimuths, float[] carrierFrequencies, float[] basebandCn0DbHzs) { 156 mSvCount = svCount; 157 mSvidWithFlags = svidWithFlags; 158 mCn0DbHzs = cn0DbHzs; 159 mElevations = elevations; 160 mAzimuths = azimuths; 161 mCarrierFrequencies = carrierFrequencies; 162 mBasebandCn0DbHzs = basebandCn0DbHzs; 163 } 164 165 /** 166 * Gets the total number of satellites in satellite list. 167 */ 168 @IntRange(from = 0) getSatelliteCount()169 public int getSatelliteCount() { 170 return mSvCount; 171 } 172 173 /** 174 * Retrieves the constellation type of the satellite at the specified index. 175 * 176 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 177 */ 178 @ConstellationType getConstellationType(@ntRangefrom = 0) int satelliteIndex)179 public int getConstellationType(@IntRange(from = 0) int satelliteIndex) { 180 return ((mSvidWithFlags[satelliteIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH) 181 & CONSTELLATION_TYPE_MASK); 182 } 183 184 /** 185 * Gets the identification number for the satellite at the specific index. 186 * 187 * <p>This svid is pseudo-random number for most constellations. It is FCN & OSN number for 188 * Glonass. 189 * 190 * <p>The distinction is made by looking at constellation field 191 * {@link #getConstellationType(int)} Expected values are in the range of: 192 * 193 * <ul> 194 * <li>GPS: 1-32</li> 195 * <li>SBAS: 120-151, 183-192</li> 196 * <li>GLONASS: One of: OSN, or FCN+100 197 * <ul> 198 * <li>1-24 as the orbital slot number (OSN) (preferred, if known)</li> 199 * <li>93-106 as the frequency channel number (FCN) (-7 to +6) plus 100. 200 * i.e. encode FCN of -7 as 93, 0 as 100, and +6 as 106</li> 201 * </ul></li> 202 * <li>QZSS: 193-200</li> 203 * <li>Galileo: 1-36</li> 204 * <li>Beidou: 1-37</li> 205 * <li>IRNSS: 1-14</li> 206 * </ul> 207 * 208 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 209 */ 210 @IntRange(from = 1, to = 200) getSvid(@ntRangefrom = 0) int satelliteIndex)211 public int getSvid(@IntRange(from = 0) int satelliteIndex) { 212 return mSvidWithFlags[satelliteIndex] >> SVID_SHIFT_WIDTH; 213 } 214 215 /** 216 * Retrieves the carrier-to-noise density at the antenna of the satellite at the specified index 217 * in dB-Hz. 218 * 219 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 220 */ 221 @FloatRange(from = 0, to = 63) getCn0DbHz(@ntRangefrom = 0) int satelliteIndex)222 public float getCn0DbHz(@IntRange(from = 0) int satelliteIndex) { 223 return mCn0DbHzs[satelliteIndex]; 224 } 225 226 /** 227 * Retrieves the elevation of the satellite at the specified index. 228 * 229 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 230 */ 231 @FloatRange(from = -90, to = 90) getElevationDegrees(@ntRangefrom = 0) int satelliteIndex)232 public float getElevationDegrees(@IntRange(from = 0) int satelliteIndex) { 233 return mElevations[satelliteIndex]; 234 } 235 236 /** 237 * Retrieves the azimuth the satellite at the specified index. 238 * 239 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 240 */ 241 @FloatRange(from = 0, to = 360) getAzimuthDegrees(@ntRangefrom = 0) int satelliteIndex)242 public float getAzimuthDegrees(@IntRange(from = 0) int satelliteIndex) { 243 return mAzimuths[satelliteIndex]; 244 } 245 246 /** 247 * Reports whether the satellite at the specified index has ephemeris data. 248 * 249 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 250 */ hasEphemerisData(@ntRangefrom = 0) int satelliteIndex)251 public boolean hasEphemerisData(@IntRange(from = 0) int satelliteIndex) { 252 return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_EPHEMERIS_DATA) != 0; 253 } 254 255 /** 256 * Reports whether the satellite at the specified index has almanac data. 257 * 258 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 259 */ hasAlmanacData(@ntRangefrom = 0) int satelliteIndex)260 public boolean hasAlmanacData(@IntRange(from = 0) int satelliteIndex) { 261 return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_ALMANAC_DATA) != 0; 262 } 263 264 /** 265 * Reports whether the satellite at the specified index was used in the calculation of the most 266 * recent position fix. 267 * 268 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 269 */ usedInFix(@ntRangefrom = 0) int satelliteIndex)270 public boolean usedInFix(@IntRange(from = 0) int satelliteIndex) { 271 return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_USED_IN_FIX) != 0; 272 } 273 274 /** 275 * Reports whether a valid {@link #getCarrierFrequencyHz(int satelliteIndex)} is available. 276 * 277 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 278 */ hasCarrierFrequencyHz(@ntRangefrom = 0) int satelliteIndex)279 public boolean hasCarrierFrequencyHz(@IntRange(from = 0) int satelliteIndex) { 280 return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_CARRIER_FREQUENCY) != 0; 281 } 282 283 /** 284 * Gets the carrier frequency of the signal tracked. 285 * 286 * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 287 * MHz, L5 = 1176.45 MHz, varying GLO channels, etc. 288 * 289 * <p>The value is only available if {@link #hasCarrierFrequencyHz(int satelliteIndex)} is 290 * {@code true}. 291 * 292 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 293 */ 294 @FloatRange(from = 0) getCarrierFrequencyHz(@ntRangefrom = 0) int satelliteIndex)295 public float getCarrierFrequencyHz(@IntRange(from = 0) int satelliteIndex) { 296 return mCarrierFrequencies[satelliteIndex]; 297 } 298 299 /** 300 * Reports whether a valid {@link #getBasebandCn0DbHz(int satelliteIndex)} is available. 301 * 302 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 303 */ hasBasebandCn0DbHz(@ntRangefrom = 0) int satelliteIndex)304 public boolean hasBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) { 305 return (mSvidWithFlags[satelliteIndex] & SVID_FLAGS_HAS_BASEBAND_CN0) != 0; 306 } 307 308 /** 309 * Retrieves the baseband carrier-to-noise density of the satellite at the specified index in 310 * dB-Hz. 311 * 312 * @param satelliteIndex An index from zero to {@link #getSatelliteCount()} - 1 313 */ 314 @FloatRange(from = 0, to = 63) getBasebandCn0DbHz(@ntRangefrom = 0) int satelliteIndex)315 public float getBasebandCn0DbHz(@IntRange(from = 0) int satelliteIndex) { 316 return mBasebandCn0DbHzs[satelliteIndex]; 317 } 318 319 /** 320 * Returns the string representation of a constellation type. 321 * 322 * @param constellationType the constellation type. 323 * @return the string representation. 324 * @hide 325 */ 326 @NonNull constellationTypeToString(@onstellationType int constellationType)327 public static String constellationTypeToString(@ConstellationType int constellationType) { 328 switch (constellationType) { 329 case CONSTELLATION_UNKNOWN: 330 return "UNKNOWN"; 331 case CONSTELLATION_GPS: 332 return "GPS"; 333 case CONSTELLATION_SBAS: 334 return "SBAS"; 335 case CONSTELLATION_GLONASS: 336 return "GLONASS"; 337 case CONSTELLATION_QZSS: 338 return "QZSS"; 339 case CONSTELLATION_BEIDOU: 340 return "BEIDOU"; 341 case CONSTELLATION_GALILEO: 342 return "GALILEO"; 343 case CONSTELLATION_IRNSS: 344 return "IRNSS"; 345 default: 346 return Integer.toString(constellationType); 347 } 348 } 349 350 @Override equals(Object o)351 public boolean equals(Object o) { 352 if (this == o) { 353 return true; 354 } 355 if (!(o instanceof GnssStatus)) { 356 return false; 357 } 358 359 GnssStatus that = (GnssStatus) o; 360 return mSvCount == that.mSvCount 361 && Arrays.equals(mSvidWithFlags, that.mSvidWithFlags) 362 && Arrays.equals(mCn0DbHzs, that.mCn0DbHzs) 363 && Arrays.equals(mElevations, that.mElevations) 364 && Arrays.equals(mAzimuths, that.mAzimuths) 365 && Arrays.equals(mCarrierFrequencies, that.mCarrierFrequencies) 366 && Arrays.equals(mBasebandCn0DbHzs, that.mBasebandCn0DbHzs); 367 } 368 369 @Override hashCode()370 public int hashCode() { 371 int result = Objects.hash(mSvCount); 372 result = 31 * result + Arrays.hashCode(mSvidWithFlags); 373 result = 31 * result + Arrays.hashCode(mCn0DbHzs); 374 return result; 375 } 376 377 public static final @NonNull Creator<GnssStatus> CREATOR = new Creator<GnssStatus>() { 378 @Override 379 public GnssStatus createFromParcel(Parcel in) { 380 int svCount = in.readInt(); 381 int[] svidWithFlags = new int[svCount]; 382 float[] cn0DbHzs = new float[svCount]; 383 float[] elevations = new float[svCount]; 384 float[] azimuths = new float[svCount]; 385 float[] carrierFrequencies = new float[svCount]; 386 float[] basebandCn0DbHzs = new float[svCount]; 387 for (int i = 0; i < svCount; i++) { 388 svidWithFlags[i] = in.readInt(); 389 cn0DbHzs[i] = in.readFloat(); 390 elevations[i] = in.readFloat(); 391 azimuths[i] = in.readFloat(); 392 carrierFrequencies[i] = in.readFloat(); 393 basebandCn0DbHzs[i] = in.readFloat(); 394 } 395 396 return new GnssStatus(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths, 397 carrierFrequencies, basebandCn0DbHzs); 398 } 399 400 @Override 401 public GnssStatus[] newArray(int size) { 402 return new GnssStatus[size]; 403 } 404 }; 405 406 @Override describeContents()407 public int describeContents() { 408 return 0; 409 } 410 411 @Override writeToParcel(@onNull Parcel parcel, int flags)412 public void writeToParcel(@NonNull Parcel parcel, int flags) { 413 parcel.writeInt(mSvCount); 414 for (int i = 0; i < mSvCount; i++) { 415 parcel.writeInt(mSvidWithFlags[i]); 416 parcel.writeFloat(mCn0DbHzs[i]); 417 parcel.writeFloat(mElevations[i]); 418 parcel.writeFloat(mAzimuths[i]); 419 parcel.writeFloat(mCarrierFrequencies[i]); 420 parcel.writeFloat(mBasebandCn0DbHzs[i]); 421 } 422 } 423 424 /** 425 * Builder class to help create new GnssStatus instances. 426 */ 427 public static final class Builder { 428 429 private final ArrayList<GnssSvInfo> mSatellites = new ArrayList<>(); 430 431 /** 432 * Adds a new satellite to the Builder. 433 * 434 * @param constellationType one of the CONSTELLATION_* constants 435 * @param svid the space vehicle identifier 436 * @param cn0DbHz carrier-to-noise density at the antenna in dB-Hz 437 * @param elevation satellite elevation in degrees 438 * @param azimuth satellite azimuth in degrees 439 * @param hasEphemeris whether the satellite has ephemeris data 440 * @param hasAlmanac whether the satellite has almanac data 441 * @param usedInFix whether the satellite was used in the most recent location fix 442 * @param hasCarrierFrequency whether carrier frequency data is available 443 * @param carrierFrequency satellite carrier frequency in Hz 444 * @param hasBasebandCn0DbHz whether baseband carrier-to-noise density is available 445 * @param basebandCn0DbHz baseband carrier-to-noise density in dB-Hz 446 */ 447 @NonNull addSatellite(@onstellationType int constellationType, @IntRange(from = 1, to = 200) int svid, @FloatRange(from = 0, to = 63) float cn0DbHz, @FloatRange(from = -90, to = 90) float elevation, @FloatRange(from = 0, to = 360) float azimuth, boolean hasEphemeris, boolean hasAlmanac, boolean usedInFix, boolean hasCarrierFrequency, @FloatRange(from = 0) float carrierFrequency, boolean hasBasebandCn0DbHz, @FloatRange(from = 0, to = 63) float basebandCn0DbHz)448 public Builder addSatellite(@ConstellationType int constellationType, 449 @IntRange(from = 1, to = 200) int svid, 450 @FloatRange(from = 0, to = 63) float cn0DbHz, 451 @FloatRange(from = -90, to = 90) float elevation, 452 @FloatRange(from = 0, to = 360) float azimuth, 453 boolean hasEphemeris, 454 boolean hasAlmanac, 455 boolean usedInFix, 456 boolean hasCarrierFrequency, 457 @FloatRange(from = 0) float carrierFrequency, 458 boolean hasBasebandCn0DbHz, 459 @FloatRange(from = 0, to = 63) float basebandCn0DbHz) { 460 mSatellites.add(new GnssSvInfo(constellationType, svid, cn0DbHz, elevation, azimuth, 461 hasEphemeris, hasAlmanac, usedInFix, hasCarrierFrequency, carrierFrequency, 462 hasBasebandCn0DbHz, basebandCn0DbHz)); 463 return this; 464 } 465 466 /** 467 * Clears all satellites in the Builder. 468 */ 469 @NonNull clearSatellites()470 public Builder clearSatellites() { 471 mSatellites.clear(); 472 return this; 473 } 474 475 /** 476 * Builds a new GnssStatus based on the satellite information in the Builder. 477 */ 478 @NonNull build()479 public GnssStatus build() { 480 int svCount = mSatellites.size(); 481 int[] svidWithFlags = new int[svCount]; 482 float[] cn0DbHzs = new float[svCount]; 483 float[] elevations = new float[svCount]; 484 float[] azimuths = new float[svCount]; 485 float[] carrierFrequencies = new float[svCount]; 486 float[] basebandCn0DbHzs = new float[svCount]; 487 488 for (int i = 0; i < svidWithFlags.length; i++) { 489 svidWithFlags[i] = mSatellites.get(i).mSvidWithFlags; 490 } 491 for (int i = 0; i < cn0DbHzs.length; i++) { 492 cn0DbHzs[i] = mSatellites.get(i).mCn0DbHz; 493 } 494 for (int i = 0; i < elevations.length; i++) { 495 elevations[i] = mSatellites.get(i).mElevation; 496 } 497 for (int i = 0; i < azimuths.length; i++) { 498 azimuths[i] = mSatellites.get(i).mAzimuth; 499 } 500 for (int i = 0; i < carrierFrequencies.length; i++) { 501 carrierFrequencies[i] = mSatellites.get(i).mCarrierFrequency; 502 } 503 for (int i = 0; i < basebandCn0DbHzs.length; i++) { 504 basebandCn0DbHzs[i] = mSatellites.get(i).mBasebandCn0DbHz; 505 } 506 507 return new GnssStatus(svCount, svidWithFlags, cn0DbHzs, elevations, azimuths, 508 carrierFrequencies, basebandCn0DbHzs); 509 } 510 } 511 512 private static class GnssSvInfo { 513 514 private final int mSvidWithFlags; 515 private final float mCn0DbHz; 516 private final float mElevation; 517 private final float mAzimuth; 518 private final float mCarrierFrequency; 519 private final float mBasebandCn0DbHz; 520 GnssSvInfo(int constellationType, int svid, float cn0DbHz, float elevation, float azimuth, boolean hasEphemeris, boolean hasAlmanac, boolean usedInFix, boolean hasCarrierFrequency, float carrierFrequency, boolean hasBasebandCn0DbHz, float basebandCn0DbHz)521 private GnssSvInfo(int constellationType, int svid, float cn0DbHz, 522 float elevation, float azimuth, boolean hasEphemeris, boolean hasAlmanac, 523 boolean usedInFix, boolean hasCarrierFrequency, float carrierFrequency, 524 boolean hasBasebandCn0DbHz, float basebandCn0DbHz) { 525 mSvidWithFlags = (svid << SVID_SHIFT_WIDTH) 526 | ((constellationType & CONSTELLATION_TYPE_MASK) 527 << CONSTELLATION_TYPE_SHIFT_WIDTH) 528 | (hasEphemeris ? SVID_FLAGS_HAS_EPHEMERIS_DATA : SVID_FLAGS_NONE) 529 | (hasAlmanac ? SVID_FLAGS_HAS_ALMANAC_DATA : SVID_FLAGS_NONE) 530 | (usedInFix ? SVID_FLAGS_USED_IN_FIX : SVID_FLAGS_NONE) 531 | (hasCarrierFrequency ? SVID_FLAGS_HAS_CARRIER_FREQUENCY : SVID_FLAGS_NONE) 532 | (hasBasebandCn0DbHz ? SVID_FLAGS_HAS_BASEBAND_CN0 : SVID_FLAGS_NONE); 533 mCn0DbHz = cn0DbHz; 534 mElevation = elevation; 535 mAzimuth = azimuth; 536 mCarrierFrequency = hasCarrierFrequency ? carrierFrequency : 0; 537 mBasebandCn0DbHz = hasBasebandCn0DbHz ? basebandCn0DbHz : 0; 538 } 539 } 540 } 541