GnssMeasurement.java revision 818aa2c2c46addae934fb6cd42f889affc9ef747
1/*
2 * Copyright (C) 2014 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.location;
18
19import android.annotation.IntDef;
20import android.os.Parcel;
21import android.os.Parcelable;
22
23import java.lang.annotation.Retention;
24import java.lang.annotation.RetentionPolicy;
25
26/**
27 * A class representing a GPS satellite measurement, containing raw and computed information.
28 */
29public final class GnssMeasurement implements Parcelable {
30    private int mFlags;
31    private byte mPrn;
32    private double mTimeOffsetInNs;
33    private short mState;
34    private long mReceivedGpsTowInNs;
35    private long mReceivedGpsTowUncertaintyInNs;
36    private double mCn0InDbHz;
37    private double mPseudorangeRateInMetersPerSec;
38    private double mPseudorangeRateUncertaintyInMetersPerSec;
39    private short mAccumulatedDeltaRangeState;
40    private double mAccumulatedDeltaRangeInMeters;
41    private double mAccumulatedDeltaRangeUncertaintyInMeters;
42    private double mPseudorangeInMeters;
43    private double mPseudorangeUncertaintyInMeters;
44    private double mCodePhaseInChips;
45    private double mCodePhaseUncertaintyInChips;
46    private float mCarrierFrequencyInHz;
47    private long mCarrierCycles;
48    private double mCarrierPhase;
49    private double mCarrierPhaseUncertainty;
50    private byte mLossOfLock;
51    private int mBitNumber;
52    private short mTimeFromLastBitInMs;
53    private double mDopplerShiftInHz;
54    private double mDopplerShiftUncertaintyInHz;
55    private byte mMultipathIndicator;
56    private double mSnrInDb;
57    private double mElevationInDeg;
58    private double mElevationUncertaintyInDeg;
59    private double mAzimuthInDeg;
60    private double mAzimuthUncertaintyInDeg;
61    private boolean mUsedInFix;
62    private double mPseudorangeRateCarrierInMetersPerSec;
63    private double mPseudorangeRateCarrierUncertaintyInMetersPerSec;
64
65    // The following enumerations must be in sync with the values declared in gps.h
66
67    private static final int HAS_NO_FLAGS = 0;
68    private static final int HAS_SNR = (1<<0);
69    private static final int HAS_ELEVATION = (1<<1);
70    private static final int HAS_ELEVATION_UNCERTAINTY = (1<<2);
71    private static final int HAS_AZIMUTH = (1<<3);
72    private static final int HAS_AZIMUTH_UNCERTAINTY = (1<<4);
73    private static final int HAS_PSEUDORANGE = (1<<5);
74    private static final int HAS_PSEUDORANGE_UNCERTAINTY = (1<<6);
75    private static final int HAS_CODE_PHASE = (1<<7);
76    private static final int HAS_CODE_PHASE_UNCERTAINTY = (1<<8);
77    private static final int HAS_CARRIER_FREQUENCY = (1<<9);
78    private static final int HAS_CARRIER_CYCLES = (1<<10);
79    private static final int HAS_CARRIER_PHASE = (1<<11);
80    private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
81    private static final int HAS_BIT_NUMBER = (1<<13);
82    private static final int HAS_TIME_FROM_LAST_BIT = (1<<14);
83    private static final int HAS_DOPPLER_SHIFT = (1<<15);
84    private static final int HAS_DOPPLER_SHIFT_UNCERTAINTY = (1<<16);
85    private static final int HAS_USED_IN_FIX = (1<<17);
86    private static final int GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE = (1<<18);
87
88    /** The status of 'loss of lock'. */
89    @Retention(RetentionPolicy.SOURCE)
90    @IntDef({LOSS_OF_LOCK_UNKNOWN, LOSS_OF_LOCK_OK, LOSS_OF_LOCK_CYCLE_SLIP})
91    public @interface LossOfLockStatus {}
92
93    /**
94     * The indicator is not available or it is unknown.
95     */
96    public static final byte LOSS_OF_LOCK_UNKNOWN = 0;
97
98    /**
99     * The measurement does not present any indication of 'loss of lock'.
100     */
101    public static final byte LOSS_OF_LOCK_OK = 1;
102
103    /**
104     * 'Loss of lock' detected between the previous and current observation: cycle slip possible.
105     */
106    public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2;
107
108    /** The status of multipath. */
109    @Retention(RetentionPolicy.SOURCE)
110    @IntDef({MULTIPATH_INDICATOR_UNKNOWN, MULTIPATH_INDICATOR_DETECTED,
111        MULTIPATH_INDICATOR_NOT_USED})
112    public @interface MultipathIndicator {}
113
114    /**
115     * The indicator is not available or it is unknown.
116     */
117    public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0;
118
119    /**
120     * The measurement has been indicated to use multi-path.
121     */
122    public static final byte MULTIPATH_INDICATOR_DETECTED = 1;
123
124    /**
125     * The measurement has been indicated not tu use multi-path.
126     */
127    public static final byte MULTIPATH_INDICATOR_NOT_USED = 2;
128
129    /**
130     * The state of GPS receiver the measurement is invalid or unknown.
131     */
132    public static final short STATE_UNKNOWN = 0;
133
134    /**
135     * The state of the GPS receiver is ranging code lock.
136     */
137    public static final short STATE_CODE_LOCK = (1<<0);
138
139    /**
140     * The state of the GPS receiver is in bit sync.
141     */
142    public static final short STATE_BIT_SYNC = (1<<1);
143
144    /**
145     *The state of the GPS receiver is in sub-frame sync.
146     */
147    public static final short STATE_SUBFRAME_SYNC = (1<<2);
148
149    /**
150     * The state of the GPS receiver has TOW decoded.
151     */
152    public static final short STATE_TOW_DECODED = (1<<3);
153
154    /**
155     * The state of the GPS receiver contains millisecond ambiguity.
156     */
157    public static final short STATE_MSEC_AMBIGUOUS = (1<<4);
158
159    /**
160     * All the GPS receiver state flags.
161     */
162    private static final short STATE_ALL = STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC
163            | STATE_TOW_DECODED | STATE_MSEC_AMBIGUOUS;
164
165    /**
166     * The state of the 'Accumulated Delta Range' is invalid or unknown.
167     */
168    public static final short ADR_STATE_UNKNOWN = 0;
169
170    /**
171     * The state of the 'Accumulated Delta Range' is valid.
172     */
173    public static final short ADR_STATE_VALID = (1<<0);
174
175    /**
176     * The state of the 'Accumulated Delta Range' has detected a reset.
177     */
178    public static final short ADR_STATE_RESET = (1<<1);
179
180    /**
181     * The state of the 'Accumulated Delta Range' has a cycle slip detected.
182     */
183    public static final short ADR_STATE_CYCLE_SLIP = (1<<2);
184
185    /**
186     * All the 'Accumulated Delta Range' flags.
187     */
188    private static final short ADR_ALL = ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP;
189
190    // End enumerations in sync with gps.h
191
192    GnssMeasurement() {
193        initialize();
194    }
195
196    /**
197     * Sets all contents to the values stored in the provided object.
198     */
199    public void set(GnssMeasurement measurement) {
200        mFlags = measurement.mFlags;
201        mPrn = measurement.mPrn;
202        mTimeOffsetInNs = measurement.mTimeOffsetInNs;
203        mState = measurement.mState;
204        mReceivedGpsTowInNs = measurement.mReceivedGpsTowInNs;
205        mReceivedGpsTowUncertaintyInNs = measurement.mReceivedGpsTowUncertaintyInNs;
206        mCn0InDbHz = measurement.mCn0InDbHz;
207        mPseudorangeRateInMetersPerSec = measurement.mPseudorangeRateInMetersPerSec;
208        mPseudorangeRateUncertaintyInMetersPerSec =
209                measurement.mPseudorangeRateUncertaintyInMetersPerSec;
210        mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
211        mAccumulatedDeltaRangeInMeters = measurement.mAccumulatedDeltaRangeInMeters;
212        mAccumulatedDeltaRangeUncertaintyInMeters =
213                measurement.mAccumulatedDeltaRangeUncertaintyInMeters;
214        mPseudorangeInMeters = measurement.mPseudorangeInMeters;
215        mPseudorangeUncertaintyInMeters = measurement.mPseudorangeUncertaintyInMeters;
216        mCodePhaseInChips = measurement.mCodePhaseInChips;
217        mCodePhaseUncertaintyInChips = measurement.mCodePhaseUncertaintyInChips;
218        mCarrierFrequencyInHz = measurement.mCarrierFrequencyInHz;
219        mCarrierCycles = measurement.mCarrierCycles;
220        mCarrierPhase = measurement.mCarrierPhase;
221        mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
222        mLossOfLock = measurement.mLossOfLock;
223        mBitNumber = measurement.mBitNumber;
224        mTimeFromLastBitInMs = measurement.mTimeFromLastBitInMs;
225        mDopplerShiftInHz = measurement.mDopplerShiftInHz;
226        mDopplerShiftUncertaintyInHz = measurement.mDopplerShiftUncertaintyInHz;
227        mMultipathIndicator = measurement.mMultipathIndicator;
228        mSnrInDb = measurement.mSnrInDb;
229        mElevationInDeg = measurement.mElevationInDeg;
230        mElevationUncertaintyInDeg = measurement.mElevationUncertaintyInDeg;
231        mAzimuthInDeg = measurement.mAzimuthInDeg;
232        mAzimuthUncertaintyInDeg = measurement.mAzimuthUncertaintyInDeg;
233        mUsedInFix = measurement.mUsedInFix;
234        mPseudorangeRateCarrierInMetersPerSec =
235                measurement.mPseudorangeRateCarrierInMetersPerSec;
236        mPseudorangeRateCarrierUncertaintyInMetersPerSec =
237                measurement.mPseudorangeRateCarrierUncertaintyInMetersPerSec;
238    }
239
240    /**
241     * Resets all the contents to its original state.
242     */
243    public void reset() {
244        initialize();
245    }
246
247    /**
248     * Gets the Pseudo-random number (PRN).
249     * Range: [1, 32]
250     */
251    public byte getPrn() {
252        return mPrn;
253    }
254
255    /**
256     * Sets the Pseud-random number (PRN).
257     */
258    public void setPrn(byte value) {
259        mPrn = value;
260    }
261
262    /**
263     * Gets the time offset at which the measurement was taken in nanoseconds.
264     * The reference receiver's time is specified by {@link GnssClock#getTimeInNs()} and should be
265     * interpreted in the same way as indicated by {@link GnssClock#getType()}.
266     *
267     * The sign of this value is given by the following equation:
268     *      measurement time = time_ns + time_offset_ns
269     *
270     * The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
271     * accuracy.
272     */
273    public double getTimeOffsetInNs() {
274        return mTimeOffsetInNs;
275    }
276
277    /**
278     * Sets the time offset at which the measurement was taken in nanoseconds.
279     */
280    public void setTimeOffsetInNs(double value) {
281        mTimeOffsetInNs = value;
282    }
283
284    /**
285     * Gets per-satellite sync state.
286     * It represents the current sync state for the associated satellite.
287     *
288     * This value helps interpret {@link #getReceivedGpsTowInNs()}.
289     */
290    public short getState() {
291        return mState;
292    }
293
294    /**
295     * Sets the sync state.
296     */
297    public void setState(short value) {
298        mState = value;
299    }
300
301    /**
302     * Gets a string representation of the 'sync state'.
303     * For internal and logging use only.
304     */
305    private String getStateString() {
306        if (mState == STATE_UNKNOWN) {
307            return "Unknown";
308        }
309        StringBuilder builder = new StringBuilder();
310        if ((mState & STATE_CODE_LOCK) == STATE_CODE_LOCK) {
311            builder.append("CodeLock|");
312        }
313        if ((mState & STATE_BIT_SYNC) == STATE_BIT_SYNC) {
314            builder.append("BitSync|");
315        }
316        if ((mState & STATE_SUBFRAME_SYNC) == STATE_SUBFRAME_SYNC) {
317            builder.append("SubframeSync|");
318        }
319        if ((mState & STATE_TOW_DECODED) == STATE_TOW_DECODED) {
320            builder.append("TowDecoded|");
321        }
322        if ((mState & STATE_MSEC_AMBIGUOUS) == STATE_MSEC_AMBIGUOUS) {
323            builder.append("MsecAmbiguous");
324        }
325        int remainingStates = mState & ~STATE_ALL;
326        if (remainingStates > 0) {
327            builder.append("Other(");
328            builder.append(Integer.toBinaryString(remainingStates));
329            builder.append(")|");
330        }
331        builder.deleteCharAt(builder.length() - 1);
332        return builder.toString();
333    }
334
335    /**
336     * Gets the received GPS Time-of-Week at the measurement time, in nanoseconds.
337     * The value is relative to the beginning of the current GPS week.
338     *
339     * Given {@link #getState()} of the GPS receiver, the range of this field can be:
340     *      Searching           : [ 0           ]   : {@link #STATE_UNKNOWN} is set
341     *      Ranging code lock   : [ 0    1 ms   ]   : {@link #STATE_CODE_LOCK} is set
342     *      Bit sync            : [ 0   20 ms   ]   : {@link #STATE_BIT_SYNC} is set
343     *      Subframe sync       : [ 0    6 ms   ]   : {@link #STATE_SUBFRAME_SYNC} is set
344     *      TOW decoded         : [ 0    1 week ]   : {@link #STATE_TOW_DECODED} is set
345     */
346    public long getReceivedGpsTowInNs() {
347        return mReceivedGpsTowInNs;
348    }
349
350    /**
351     * Sets the received GPS time-of-week in nanoseconds.
352     */
353    public void setReceivedGpsTowInNs(long value) {
354        mReceivedGpsTowInNs = value;
355    }
356
357    /**
358     * Gets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
359     */
360    public long getReceivedGpsTowUncertaintyInNs() {
361        return mReceivedGpsTowUncertaintyInNs;
362    }
363
364    /**
365     * Sets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
366     */
367    public void setReceivedGpsTowUncertaintyInNs(long value) {
368        mReceivedGpsTowUncertaintyInNs = value;
369    }
370
371    /**
372     * Gets the Carrier-to-noise density in dB-Hz.
373     * Range: [0, 63].
374     *
375     * The value contains the measured C/N0 for the signal at the antenna input.
376     */
377    public double getCn0InDbHz() {
378        return mCn0InDbHz;
379    }
380
381    /**
382     * Sets the carrier-to-noise density in dB-Hz.
383     */
384    public void setCn0InDbHz(double value) {
385        mCn0InDbHz = value;
386    }
387
388    /**
389     * Gets the Pseudorange rate at the timestamp in m/s.
390     * The reported value includes {@link #getPseudorangeRateUncertaintyInMetersPerSec()}.
391     *
392     * The correction of a given Pseudorange Rate value includes corrections from receiver and
393     * satellite clock frequency errors.
394     * {@link #isPseudorangeRateCorrected()} identifies the type of value reported.
395     *
396     * A positive 'uncorrected' value indicates that the SV is moving away from the receiver.
397     * The sign of the 'uncorrected' Pseudorange Rate and its relation to the sign of
398     * {@link #getDopplerShiftInHz()} is given by the equation:
399     *      pseudorange rate = -k * doppler shift   (where k is a constant)
400     */
401    public double getPseudorangeRateInMetersPerSec() {
402        return mPseudorangeRateInMetersPerSec;
403    }
404
405    /**
406     * Sets the pseudorange rate at the timestamp in m/s.
407     */
408    public void setPseudorangeRateInMetersPerSec(double value) {
409        mPseudorangeRateInMetersPerSec = value;
410    }
411
412    /**
413     * See {@link #getPseudorangeRateInMetersPerSec()} for more details.
414     *
415     * @return {@code true} if {@link #getPseudorangeRateInMetersPerSec()} contains a corrected
416     *         value, {@code false} if it contains an uncorrected value.
417     */
418    public boolean isPseudorangeRateCorrected() {
419        return !isFlagSet(GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE);
420    }
421
422    /**
423     * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
424     * The uncertainty is represented as an absolute (single sided) value.
425     */
426    public double getPseudorangeRateUncertaintyInMetersPerSec() {
427        return mPseudorangeRateUncertaintyInMetersPerSec;
428    }
429
430    /**
431     * Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
432     */
433    public void setPseudorangeRateUncertaintyInMetersPerSec(double value) {
434        mPseudorangeRateUncertaintyInMetersPerSec = value;
435    }
436
437    /**
438     * Gets 'Accumulated Delta Range' state.
439     * It indicates whether {@link #getAccumulatedDeltaRangeInMeters()} is reset or there is a
440     * cycle slip (indicating 'loss of lock').
441     */
442    public short getAccumulatedDeltaRangeState() {
443        return mAccumulatedDeltaRangeState;
444    }
445
446    /**
447     * Sets the 'Accumulated Delta Range' state.
448     */
449    public void setAccumulatedDeltaRangeState(short value) {
450        mAccumulatedDeltaRangeState = value;
451    }
452
453    /**
454     * Gets a string representation of the 'Accumulated Delta Range state'.
455     * For internal and logging use only.
456     */
457    private String getAccumulatedDeltaRangeStateString() {
458        if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
459            return "Unknown";
460        }
461        StringBuilder builder = new StringBuilder();
462        if ((mAccumulatedDeltaRangeState & ADR_STATE_VALID) == ADR_STATE_VALID) {
463            builder.append("Valid|");
464        }
465        if ((mAccumulatedDeltaRangeState & ADR_STATE_RESET) == ADR_STATE_RESET) {
466            builder.append("Reset|");
467        }
468        if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
469            builder.append("CycleSlip|");
470        }
471        int remainingStates = mAccumulatedDeltaRangeState & ~ADR_ALL;
472        if (remainingStates > 0) {
473            builder.append("Other(");
474            builder.append(Integer.toBinaryString(remainingStates));
475            builder.append(")|");
476        }
477        builder.deleteCharAt(builder.length() - 1);
478        return builder.toString();
479    }
480
481    /**
482     * Gets the accumulated delta range since the last channel reset, in meters.
483     * The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyInMeters()}.
484     *
485     * The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
486     *
487     * A positive value indicates that the SV is moving away from the receiver.
488     * The sign of {@link #getAccumulatedDeltaRangeInMeters()} and its relation to the sign of
489     * {@link #getCarrierPhase()} is given by the equation:
490     *          accumulated delta range = -k * carrier phase    (where k is a constant)
491     */
492    public double getAccumulatedDeltaRangeInMeters() {
493        return mAccumulatedDeltaRangeInMeters;
494    }
495
496    /**
497     * Sets the accumulated delta range in meters.
498     */
499    public void setAccumulatedDeltaRangeInMeters(double value) {
500        mAccumulatedDeltaRangeInMeters = value;
501    }
502
503    /**
504     * Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
505     * The uncertainty is represented as an absolute (single sided) value.
506     *
507     * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
508     */
509    public double getAccumulatedDeltaRangeUncertaintyInMeters() {
510        return mAccumulatedDeltaRangeUncertaintyInMeters;
511    }
512
513    /**
514     * Sets the accumulated delta range's uncertainty (1-sigma) in meters.
515     *
516     * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
517     */
518    public void setAccumulatedDeltaRangeUncertaintyInMeters(double value) {
519        mAccumulatedDeltaRangeUncertaintyInMeters = value;
520    }
521
522    /**
523     * Returns true if {@link #getPseudorangeInMeters()} is available, false otherwise.
524     */
525    public boolean hasPseudorangeInMeters() {
526        return isFlagSet(HAS_PSEUDORANGE);
527    }
528
529    /**
530     * Gets the best derived pseudorange by the chipset, in meters.
531     * The reported pseudorange includes {@link #getPseudorangeUncertaintyInMeters()}.
532     *
533     * The value is only available if {@link #hasPseudorangeInMeters()} is true.
534     */
535    public double getPseudorangeInMeters() {
536        return mPseudorangeInMeters;
537    }
538
539    /**
540     * Sets the Pseudo-range in meters.
541     */
542    public void setPseudorangeInMeters(double value) {
543        setFlag(HAS_PSEUDORANGE);
544        mPseudorangeInMeters = value;
545    }
546
547    /**
548     * Resets the Pseudo-range in meters.
549     */
550    public void resetPseudorangeInMeters() {
551        resetFlag(HAS_PSEUDORANGE);
552        mPseudorangeInMeters = Double.NaN;
553    }
554
555    /**
556     * Returns true if {@link #getPseudorangeUncertaintyInMeters()} is available, false otherwise.
557     */
558    public boolean hasPseudorangeUncertaintyInMeters() {
559        return isFlagSet(HAS_PSEUDORANGE_UNCERTAINTY);
560    }
561
562    /**
563     * Gets the pseudorange's uncertainty (1-Sigma) in meters.
564     * The value contains the 'pseudorange' and 'clock' uncertainty in it.
565     * The uncertainty is represented as an absolute (single sided) value.
566     *
567     * The value is only available if {@link #hasPseudorangeUncertaintyInMeters()} is true.
568     */
569    public double getPseudorangeUncertaintyInMeters() {
570        return mPseudorangeUncertaintyInMeters;
571    }
572
573    /**
574     * Sets the pseudo-range's uncertainty (1-Sigma) in meters.
575     */
576    public void setPseudorangeUncertaintyInMeters(double value) {
577        setFlag(HAS_PSEUDORANGE_UNCERTAINTY);
578        mPseudorangeUncertaintyInMeters = value;
579    }
580
581    /**
582     * Resets the pseudo-range's uncertainty (1-Sigma) in meters.
583     */
584    public void resetPseudorangeUncertaintyInMeters() {
585        resetFlag(HAS_PSEUDORANGE_UNCERTAINTY);
586        mPseudorangeUncertaintyInMeters = Double.NaN;
587    }
588
589    /**
590     * Returns true if {@link #getCodePhaseInChips()} is available, false otherwise.
591     */
592    public boolean hasCodePhaseInChips() {
593        return isFlagSet(HAS_CODE_PHASE);
594    }
595
596    /**
597     * Gets the fraction of the current C/A code cycle.
598     * Range: [0, 1023]
599     * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
600     * The reported code-phase includes {@link #getCodePhaseUncertaintyInChips()}.
601     *
602     * The value is only available if {@link #hasCodePhaseInChips()} is true.
603     */
604    public double getCodePhaseInChips() {
605        return mCodePhaseInChips;
606    }
607
608    /**
609     * Sets the Code-phase in chips.
610     */
611    public void setCodePhaseInChips(double value) {
612        setFlag(HAS_CODE_PHASE);
613        mCodePhaseInChips = value;
614    }
615
616    /**
617     * Resets the Code-phase in chips.
618     */
619    public void resetCodePhaseInChips() {
620        resetFlag(HAS_CODE_PHASE);
621        mCodePhaseInChips = Double.NaN;
622    }
623
624    /**
625     * Returns true if {@link #getCodePhaseUncertaintyInChips()} is available, false otherwise.
626     */
627    public boolean hasCodePhaseUncertaintyInChips() {
628        return isFlagSet(HAS_CODE_PHASE_UNCERTAINTY);
629    }
630
631    /**
632     * Gets the code-phase's uncertainty (1-Sigma) as a fraction of chips.
633     * The uncertainty is represented as an absolute (single sided) value.
634     *
635     * The value is only available if {@link #hasCodePhaseUncertaintyInChips()} is true.
636     */
637    public double getCodePhaseUncertaintyInChips() {
638        return mCodePhaseUncertaintyInChips;
639    }
640
641    /**
642     * Sets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
643     */
644    public void setCodePhaseUncertaintyInChips(double value) {
645        setFlag(HAS_CODE_PHASE_UNCERTAINTY);
646        mCodePhaseUncertaintyInChips = value;
647    }
648
649    /**
650     * Resets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
651     */
652    public void resetCodePhaseUncertaintyInChips() {
653        resetFlag(HAS_CODE_PHASE_UNCERTAINTY);
654        mCodePhaseUncertaintyInChips = Double.NaN;
655    }
656
657    /**
658     * Returns true if {@link #getCarrierFrequencyInHz()} is available, false otherwise.
659     */
660    public boolean hasCarrierFrequencyInHz() {
661        return isFlagSet(HAS_CARRIER_FREQUENCY);
662    }
663
664    /**
665     * Gets the carrier frequency at which codes and messages are modulated, it can be L1 or L2.
666     * If the field is not set, the carrier frequency corresponds to L1.
667     *
668     * The value is only available if {@link #hasCarrierFrequencyInHz()} is true.
669     */
670    public float getCarrierFrequencyInHz() {
671        return mCarrierFrequencyInHz;
672    }
673
674    /**
675     * Sets the Carrier frequency (L1 or L2) in Hz.
676     */
677    public void setCarrierFrequencyInHz(float carrierFrequencyInHz) {
678        setFlag(HAS_CARRIER_FREQUENCY);
679        mCarrierFrequencyInHz = carrierFrequencyInHz;
680    }
681
682    /**
683     * Resets the Carrier frequency (L1 or L2) in Hz.
684     */
685    public void resetCarrierFrequencyInHz() {
686        resetFlag(HAS_CARRIER_FREQUENCY);
687        mCarrierFrequencyInHz = Float.NaN;
688    }
689
690    /**
691     * Returns true if {@link #getCarrierCycles()} is available, false otherwise.
692     */
693    public boolean hasCarrierCycles() {
694        return isFlagSet(HAS_CARRIER_CYCLES);
695    }
696
697    /**
698     * The number of full carrier cycles between the satellite and the receiver.
699     * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
700     *
701     * The value is only available if {@link #hasCarrierCycles()} is true.
702     */
703    public long getCarrierCycles() {
704        return mCarrierCycles;
705    }
706
707    /**
708     * Sets the number of full carrier cycles between the satellite and the receiver.
709     */
710    public void setCarrierCycles(long value) {
711        setFlag(HAS_CARRIER_CYCLES);
712        mCarrierCycles = value;
713    }
714
715    /**
716     * Resets the number of full carrier cycles between the satellite and the receiver.
717     */
718    public void resetCarrierCycles() {
719        resetFlag(HAS_CARRIER_CYCLES);
720        mCarrierCycles = Long.MIN_VALUE;
721    }
722
723    /**
724     * Returns true if {@link #getCarrierPhase()} is available, false otherwise.
725     */
726    public boolean hasCarrierPhase() {
727        return isFlagSet(HAS_CARRIER_PHASE);
728    }
729
730    /**
731     * Gets the RF phase detected by the receiver.
732     * Range: [0.0, 1.0].
733     * This is usually the fractional part of the complete carrier phase measurement.
734     *
735     * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
736     * The reported carrier-phase includes {@link #getCarrierPhaseUncertainty()}.
737     *
738     * The value is only available if {@link #hasCarrierPhase()} is true.
739     */
740    public double getCarrierPhase() {
741        return mCarrierPhase;
742    }
743
744    /**
745     * Sets the RF phase detected by the receiver.
746     */
747    public void setCarrierPhase(double value) {
748        setFlag(HAS_CARRIER_PHASE);
749        mCarrierPhase = value;
750    }
751
752    /**
753     * Resets the RF phase detected by the receiver.
754     */
755    public void resetCarrierPhase() {
756        resetFlag(HAS_CARRIER_PHASE);
757        mCarrierPhase = Double.NaN;
758    }
759
760    /**
761     * Returns true if {@link #getCarrierPhaseUncertainty()} is available, false otherwise.
762     */
763    public boolean hasCarrierPhaseUncertainty() {
764        return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
765    }
766
767    /**
768     * Gets the carrier-phase's uncertainty (1-Sigma).
769     * The uncertainty is represented as an absolute (single sided) value.
770     *
771     * The value is only available if {@link #hasCarrierPhaseUncertainty()} is true.
772     */
773    public double getCarrierPhaseUncertainty() {
774        return mCarrierPhaseUncertainty;
775    }
776
777    /**
778     * Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
779     */
780    public void setCarrierPhaseUncertainty(double value) {
781        setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
782        mCarrierPhaseUncertainty = value;
783    }
784
785    /**
786     * Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
787     */
788    public void resetCarrierPhaseUncertainty() {
789        resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
790        mCarrierPhaseUncertainty = Double.NaN;
791    }
792
793    /**
794     * Gets a value indicating the 'loss of lock' state of the event.
795     */
796    @LossOfLockStatus
797    public byte getLossOfLock() {
798        return mLossOfLock;
799    }
800
801    /**
802     * Sets the 'loss of lock' status.
803     */
804    public void setLossOfLock(@LossOfLockStatus byte value) {
805        mLossOfLock = value;
806    }
807
808    /**
809     * Gets a string representation of the 'loss of lock'.
810     * For internal and logging use only.
811     */
812    private String getLossOfLockString() {
813        switch (mLossOfLock) {
814            case LOSS_OF_LOCK_UNKNOWN:
815                return "Unknown";
816            case LOSS_OF_LOCK_OK:
817                return "Ok";
818            case LOSS_OF_LOCK_CYCLE_SLIP:
819                return "CycleSlip";
820            default:
821                return "<Invalid:" + mLossOfLock + ">";
822        }
823    }
824
825    /**
826     * Returns true if {@link #getBitNumber()} is available, false otherwise.
827     */
828    public boolean hasBitNumber() {
829        return isFlagSet(HAS_BIT_NUMBER);
830    }
831
832    /**
833     * Gets the number of GPS bits transmitted since Sat-Sun midnight (GPS week).
834     *
835     * The value is only available if {@link #hasBitNumber()} is true.
836     */
837    public int getBitNumber() {
838        return mBitNumber;
839    }
840
841    /**
842     * Sets the bit number within the broadcast frame.
843     */
844    public void setBitNumber(int bitNumber) {
845        setFlag(HAS_BIT_NUMBER);
846        mBitNumber = bitNumber;
847    }
848
849    /**
850     * Resets the bit number within the broadcast frame.
851     */
852    public void resetBitNumber() {
853        resetFlag(HAS_BIT_NUMBER);
854        mBitNumber = Integer.MIN_VALUE;
855    }
856
857    /**
858     * Returns true if {@link #getTimeFromLastBitInMs()} is available, false otherwise.
859     */
860    public boolean hasTimeFromLastBitInMs() {
861        return isFlagSet(HAS_TIME_FROM_LAST_BIT);
862    }
863
864    /**
865     * Gets the elapsed time since the last received bit in milliseconds.
866     * Range: [0, 20].
867     *
868     * The value is only available if {@link #hasTimeFromLastBitInMs()} is true.
869     */
870    public short getTimeFromLastBitInMs() {
871        return mTimeFromLastBitInMs;
872    }
873
874    /**
875     * Sets the elapsed time since the last received bit in milliseconds.
876     */
877    public void setTimeFromLastBitInMs(short value) {
878        setFlag(HAS_TIME_FROM_LAST_BIT);
879        mTimeFromLastBitInMs = value;
880    }
881
882    /**
883     * Resets the elapsed time since the last received bit in milliseconds.
884     */
885    public void resetTimeFromLastBitInMs() {
886        resetFlag(HAS_TIME_FROM_LAST_BIT);
887        mTimeFromLastBitInMs = Short.MIN_VALUE;
888    }
889
890    /**
891     * Returns true if {@link #getDopplerShiftInHz()} is available, false otherwise.
892     */
893    public boolean hasDopplerShiftInHz() {
894        return isFlagSet(HAS_DOPPLER_SHIFT);
895    }
896
897    /**
898     * Gets the Doppler Shift in Hz.
899     * A positive value indicates that the SV is moving toward the receiver.
900     *
901     * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
902     * The reported doppler shift includes {@link #getDopplerShiftUncertaintyInHz()}.
903     *
904     * The value is only available if {@link #hasDopplerShiftInHz()} is true.
905     */
906    public double getDopplerShiftInHz() {
907        return mDopplerShiftInHz;
908    }
909
910    /**
911     * Sets the Doppler shift in Hz.
912     */
913    public void setDopplerShiftInHz(double value) {
914        setFlag(HAS_DOPPLER_SHIFT);
915        mDopplerShiftInHz = value;
916    }
917
918    /**
919     * Resets the Doppler shift in Hz.
920     */
921    public void resetDopplerShiftInHz() {
922        resetFlag(HAS_DOPPLER_SHIFT);
923        mDopplerShiftInHz = Double.NaN;
924    }
925
926    /**
927     * Returns true if {@link #getDopplerShiftUncertaintyInHz()} is available, false otherwise.
928     */
929    public boolean hasDopplerShiftUncertaintyInHz() {
930        return isFlagSet(HAS_DOPPLER_SHIFT_UNCERTAINTY);
931    }
932
933    /**
934     * Gets the Doppler's Shift uncertainty (1-Sigma) in Hz.
935     * The uncertainty is represented as an absolute (single sided) value.
936     *
937     * The value is only available if {@link #hasDopplerShiftUncertaintyInHz()} is true.
938     */
939    public double getDopplerShiftUncertaintyInHz() {
940        return mDopplerShiftUncertaintyInHz;
941    }
942
943    /**
944     * Sets the Doppler's shift uncertainty (1-Sigma) in Hz.
945     */
946    public void setDopplerShiftUncertaintyInHz(double value) {
947        setFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
948        mDopplerShiftUncertaintyInHz = value;
949    }
950
951    /**
952     * Resets the Doppler's shift uncertainty (1-Sigma) in Hz.
953     */
954    public void resetDopplerShiftUncertaintyInHz() {
955        resetFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
956        mDopplerShiftUncertaintyInHz = Double.NaN;
957    }
958
959    /**
960     * Gets a value indicating the 'multipath' state of the event.
961     */
962    @MultipathIndicator
963    public byte getMultipathIndicator() {
964        return mMultipathIndicator;
965    }
966
967    /**
968     * Sets the 'multi-path' indicator.
969     */
970    public void setMultipathIndicator(@MultipathIndicator byte value) {
971        mMultipathIndicator = value;
972    }
973
974    /**
975     * Gets a string representation of the 'multi-path indicator'.
976     * For internal and logging use only.
977     */
978    private String getMultipathIndicatorString() {
979        switch(mMultipathIndicator) {
980            case MULTIPATH_INDICATOR_UNKNOWN:
981                return "Unknown";
982            case MULTIPATH_INDICATOR_DETECTED:
983                return "Detected";
984            case MULTIPATH_INDICATOR_NOT_USED:
985                return "NotUsed";
986            default:
987                return "<Invalid:" + mMultipathIndicator + ">";
988        }
989    }
990
991    /**
992     * Returns true if {@link #getSnrInDb()} is available, false otherwise.
993     */
994    public boolean hasSnrInDb() {
995        return isFlagSet(HAS_SNR);
996    }
997
998    /**
999     * Gets the Signal-to-Noise ratio (SNR) in dB.
1000     *
1001     * The value is only available if {@link #hasSnrInDb()} is true.
1002     */
1003    public double getSnrInDb() {
1004        return mSnrInDb;
1005    }
1006
1007    /**
1008     * Sets the Signal-to-noise ratio (SNR) in dB.
1009     */
1010    public void setSnrInDb(double snrInDb) {
1011        setFlag(HAS_SNR);
1012        mSnrInDb = snrInDb;
1013    }
1014
1015    /**
1016     * Resets the Signal-to-noise ratio (SNR) in dB.
1017     */
1018    public void resetSnrInDb() {
1019        resetFlag(HAS_SNR);
1020        mSnrInDb = Double.NaN;
1021    }
1022
1023    /**
1024     * Returns true if {@link #getElevationInDeg()} is available, false otherwise.
1025     */
1026    public boolean hasElevationInDeg() {
1027        return isFlagSet(HAS_ELEVATION);
1028    }
1029
1030    /**
1031     * Gets the Elevation in degrees.
1032     * Range: [-90, 90]
1033     * The reported elevation includes {@link #getElevationUncertaintyInDeg()}.
1034     *
1035     * The value is only available if {@link #hasElevationInDeg()} is true.
1036     */
1037    public double getElevationInDeg() {
1038        return mElevationInDeg;
1039    }
1040
1041    /**
1042     * Sets the Elevation in degrees.
1043     */
1044    public void setElevationInDeg(double elevationInDeg) {
1045        setFlag(HAS_ELEVATION);
1046        mElevationInDeg = elevationInDeg;
1047    }
1048
1049    /**
1050     * Resets the Elevation in degrees.
1051     */
1052    public void resetElevationInDeg() {
1053        resetFlag(HAS_ELEVATION);
1054        mElevationInDeg = Double.NaN;
1055    }
1056
1057    /**
1058     * Returns true if {@link #getElevationUncertaintyInDeg()} is available, false otherwise.
1059     */
1060    public boolean hasElevationUncertaintyInDeg() {
1061        return isFlagSet(HAS_ELEVATION_UNCERTAINTY);
1062    }
1063
1064    /**
1065     * Gets the elevation's uncertainty (1-Sigma) in degrees.
1066     * Range: [0, 90]
1067     *
1068     * The uncertainty is represented as an absolute (single sided) value.
1069     *
1070     * The value is only available if {@link #hasElevationUncertaintyInDeg()} is true.
1071     */
1072    public double getElevationUncertaintyInDeg() {
1073        return mElevationUncertaintyInDeg;
1074    }
1075
1076    /**
1077     * Sets the elevation's uncertainty (1-Sigma) in degrees.
1078     */
1079    public void setElevationUncertaintyInDeg(double value) {
1080        setFlag(HAS_ELEVATION_UNCERTAINTY);
1081        mElevationUncertaintyInDeg = value;
1082    }
1083
1084    /**
1085     * Resets the elevation's uncertainty (1-Sigma) in degrees.
1086     */
1087    public void resetElevationUncertaintyInDeg() {
1088        resetFlag(HAS_ELEVATION_UNCERTAINTY);
1089        mElevationUncertaintyInDeg = Double.NaN;
1090    }
1091
1092    /**
1093     * Returns true if {@link #getAzimuthInDeg()} is available, false otherwise.
1094     */
1095    public boolean hasAzimuthInDeg() {
1096        return isFlagSet(HAS_AZIMUTH);
1097    }
1098
1099    /**
1100     * Gets the azimuth in degrees.
1101     * Range: [0, 360).
1102     *
1103     * The reported azimuth includes {@link #getAzimuthUncertaintyInDeg()}.
1104     *
1105     * The value is only available if {@link #hasAzimuthInDeg()} is true.
1106     */
1107    public double getAzimuthInDeg() {
1108        return mAzimuthInDeg;
1109    }
1110
1111    /**
1112     * Sets the Azimuth in degrees.
1113     */
1114    public void setAzimuthInDeg(double value) {
1115        setFlag(HAS_AZIMUTH);
1116        mAzimuthInDeg = value;
1117    }
1118
1119    /**
1120     * Resets the Azimuth in degrees.
1121     */
1122    public void resetAzimuthInDeg() {
1123        resetFlag(HAS_AZIMUTH);
1124        mAzimuthInDeg = Double.NaN;
1125    }
1126
1127    /**
1128     * Returns true if {@link #getAzimuthUncertaintyInDeg()} is available, false otherwise.
1129     */
1130    public boolean hasAzimuthUncertaintyInDeg() {
1131        return isFlagSet(HAS_AZIMUTH_UNCERTAINTY);
1132    }
1133
1134    /**
1135     * Gets the azimuth's uncertainty (1-Sigma) in degrees.
1136     * Range: [0, 180].
1137     *
1138     * The uncertainty is represented as an absolute (single sided) value.
1139     *
1140     * The value is only available if {@link #hasAzimuthUncertaintyInDeg()} is true.
1141     */
1142    public double getAzimuthUncertaintyInDeg() {
1143        return mAzimuthUncertaintyInDeg;
1144    }
1145
1146    /**
1147     * Sets the Azimuth's uncertainty (1-Sigma) in degrees.
1148     */
1149    public void setAzimuthUncertaintyInDeg(double value) {
1150        setFlag(HAS_AZIMUTH_UNCERTAINTY);
1151        mAzimuthUncertaintyInDeg = value;
1152    }
1153
1154    /**
1155     * Resets the Azimuth's uncertainty (1-Sigma) in degrees.
1156     */
1157    public void resetAzimuthUncertaintyInDeg() {
1158        resetFlag(HAS_AZIMUTH_UNCERTAINTY);
1159        mAzimuthUncertaintyInDeg = Double.NaN;
1160    }
1161
1162    /**
1163     * Gets a flag indicating whether the GPS represented by the measurement was used for computing
1164     * the most recent fix.
1165     *
1166     * @return A non-null value if the data is available, null otherwise.
1167     */
1168    public boolean isUsedInFix() {
1169        return mUsedInFix;
1170    }
1171
1172    /**
1173     * Sets the Used-in-Fix flag.
1174     */
1175    public void setUsedInFix(boolean value) {
1176        mUsedInFix = value;
1177    }
1178
1179    /**
1180     * Gets pseudorange rate (based on carrier phase changes) at the timestamp in m/s.
1181     */
1182    public double getPseudorangeRateCarrierInMetersPerSec() {
1183        return mPseudorangeRateCarrierInMetersPerSec;
1184    }
1185
1186    /**
1187     * Sets pseudorange rate (based on carrier phase changes) at the timestamp in m/s.
1188     */
1189    public void setPseudorangeRateCarrierInMetersPerSec(double value) {
1190        mPseudorangeRateCarrierInMetersPerSec = value;
1191    }
1192
1193    /**
1194     * Gets 1-Sigma uncertainty of the pseudorange rate carrier.
1195     */
1196    public double getPseudorangeRateCarrierUncertaintyInMetersPerSec() {
1197        return mPseudorangeRateCarrierUncertaintyInMetersPerSec;
1198    }
1199
1200    /**
1201     * Sets 1-Sigma uncertainty of the pseudorange rate carrier.
1202     */
1203    public void setPseudorangeRateCarrierUncertaintyInMetersPerSec(double value) {
1204        mPseudorangeRateCarrierUncertaintyInMetersPerSec = value;
1205    }
1206
1207    public static final Creator<GnssMeasurement> CREATOR = new Creator<GnssMeasurement>() {
1208        @Override
1209        public GnssMeasurement createFromParcel(Parcel parcel) {
1210            GnssMeasurement gnssMeasurement = new GnssMeasurement();
1211
1212            gnssMeasurement.mFlags = parcel.readInt();
1213            gnssMeasurement.mPrn = parcel.readByte();
1214            gnssMeasurement.mTimeOffsetInNs = parcel.readDouble();
1215            gnssMeasurement.mState = (short) parcel.readInt();
1216            gnssMeasurement.mReceivedGpsTowInNs = parcel.readLong();
1217            gnssMeasurement.mReceivedGpsTowUncertaintyInNs = parcel.readLong();
1218            gnssMeasurement.mCn0InDbHz = parcel.readDouble();
1219            gnssMeasurement.mPseudorangeRateInMetersPerSec = parcel.readDouble();
1220            gnssMeasurement.mPseudorangeRateUncertaintyInMetersPerSec = parcel.readDouble();
1221            gnssMeasurement.mAccumulatedDeltaRangeState = (short) parcel.readInt();
1222            gnssMeasurement.mAccumulatedDeltaRangeInMeters = parcel.readDouble();
1223            gnssMeasurement.mAccumulatedDeltaRangeUncertaintyInMeters = parcel.readDouble();
1224            gnssMeasurement.mPseudorangeInMeters = parcel.readDouble();
1225            gnssMeasurement.mPseudorangeUncertaintyInMeters = parcel.readDouble();
1226            gnssMeasurement.mCodePhaseInChips = parcel.readDouble();
1227            gnssMeasurement.mCodePhaseUncertaintyInChips = parcel.readDouble();
1228            gnssMeasurement.mCarrierFrequencyInHz = parcel.readFloat();
1229            gnssMeasurement.mCarrierCycles = parcel.readLong();
1230            gnssMeasurement.mCarrierPhase = parcel.readDouble();
1231            gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
1232            gnssMeasurement.mLossOfLock = parcel.readByte();
1233            gnssMeasurement.mBitNumber = parcel.readInt();
1234            gnssMeasurement.mTimeFromLastBitInMs = (short) parcel.readInt();
1235            gnssMeasurement.mDopplerShiftInHz = parcel.readDouble();
1236            gnssMeasurement.mDopplerShiftUncertaintyInHz = parcel.readDouble();
1237            gnssMeasurement.mMultipathIndicator = parcel.readByte();
1238            gnssMeasurement.mSnrInDb = parcel.readDouble();
1239            gnssMeasurement.mElevationInDeg = parcel.readDouble();
1240            gnssMeasurement.mElevationUncertaintyInDeg = parcel.readDouble();
1241            gnssMeasurement.mAzimuthInDeg = parcel.readDouble();
1242            gnssMeasurement.mAzimuthUncertaintyInDeg = parcel.readDouble();
1243            gnssMeasurement.mUsedInFix = parcel.readInt() != 0;
1244            gnssMeasurement.mPseudorangeRateCarrierInMetersPerSec = parcel.readDouble();
1245            gnssMeasurement.mPseudorangeRateCarrierUncertaintyInMetersPerSec = parcel.readDouble();
1246
1247            return gnssMeasurement;
1248        }
1249
1250        @Override
1251        public GnssMeasurement[] newArray(int i) {
1252            return new GnssMeasurement[i];
1253        }
1254    };
1255
1256    public void writeToParcel(Parcel parcel, int flags) {
1257        parcel.writeInt(mFlags);
1258        parcel.writeByte(mPrn);
1259        parcel.writeDouble(mTimeOffsetInNs);
1260        parcel.writeInt(mState);
1261        parcel.writeLong(mReceivedGpsTowInNs);
1262        parcel.writeLong(mReceivedGpsTowUncertaintyInNs);
1263        parcel.writeDouble(mCn0InDbHz);
1264        parcel.writeDouble(mPseudorangeRateInMetersPerSec);
1265        parcel.writeDouble(mPseudorangeRateUncertaintyInMetersPerSec);
1266        parcel.writeInt(mAccumulatedDeltaRangeState);
1267        parcel.writeDouble(mAccumulatedDeltaRangeInMeters);
1268        parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyInMeters);
1269        parcel.writeDouble(mPseudorangeInMeters);
1270        parcel.writeDouble(mPseudorangeUncertaintyInMeters);
1271        parcel.writeDouble(mCodePhaseInChips);
1272        parcel.writeDouble(mCodePhaseUncertaintyInChips);
1273        parcel.writeFloat(mCarrierFrequencyInHz);
1274        parcel.writeLong(mCarrierCycles);
1275        parcel.writeDouble(mCarrierPhase);
1276        parcel.writeDouble(mCarrierPhaseUncertainty);
1277        parcel.writeByte(mLossOfLock);
1278        parcel.writeInt(mBitNumber);
1279        parcel.writeInt(mTimeFromLastBitInMs);
1280        parcel.writeDouble(mDopplerShiftInHz);
1281        parcel.writeDouble(mDopplerShiftUncertaintyInHz);
1282        parcel.writeByte(mMultipathIndicator);
1283        parcel.writeDouble(mSnrInDb);
1284        parcel.writeDouble(mElevationInDeg);
1285        parcel.writeDouble(mElevationUncertaintyInDeg);
1286        parcel.writeDouble(mAzimuthInDeg);
1287        parcel.writeDouble(mAzimuthUncertaintyInDeg);
1288        parcel.writeInt(mUsedInFix ? 1 : 0);
1289        parcel.writeDouble(mPseudorangeRateCarrierInMetersPerSec);
1290        parcel.writeDouble(mPseudorangeRateCarrierUncertaintyInMetersPerSec);
1291    }
1292
1293    @Override
1294    public int describeContents() {
1295        return 0;
1296    }
1297
1298    @Override
1299    public String toString() {
1300        final String format = "   %-29s = %s\n";
1301        final String formatWithUncertainty = "   %-29s = %-25s   %-40s = %s\n";
1302        StringBuilder builder = new StringBuilder("GnssMeasurement:\n");
1303
1304        builder.append(String.format(format, "Prn", mPrn));
1305
1306        builder.append(String.format(format, "TimeOffsetInNs", mTimeOffsetInNs));
1307
1308        builder.append(String.format(format, "State", getStateString()));
1309
1310        builder.append(String.format(
1311                formatWithUncertainty,
1312                "ReceivedGpsTowInNs",
1313                mReceivedGpsTowInNs,
1314                "ReceivedGpsTowUncertaintyInNs",
1315                mReceivedGpsTowUncertaintyInNs));
1316
1317        builder.append(String.format(format, "Cn0InDbHz", mCn0InDbHz));
1318
1319        builder.append(String.format(
1320                formatWithUncertainty,
1321                "PseudorangeRateInMetersPerSec",
1322                mPseudorangeRateInMetersPerSec,
1323                "PseudorangeRateUncertaintyInMetersPerSec",
1324                mPseudorangeRateUncertaintyInMetersPerSec));
1325        builder.append(String.format(
1326                format,
1327                "PseudorangeRateIsCorrected",
1328                isPseudorangeRateCorrected()));
1329
1330        builder.append(String.format(
1331                format,
1332                "AccumulatedDeltaRangeState",
1333                getAccumulatedDeltaRangeStateString()));
1334
1335        builder.append(String.format(
1336                formatWithUncertainty,
1337                "AccumulatedDeltaRangeInMeters",
1338                mAccumulatedDeltaRangeInMeters,
1339                "AccumulatedDeltaRangeUncertaintyInMeters",
1340                mAccumulatedDeltaRangeUncertaintyInMeters));
1341
1342        builder.append(String.format(
1343                formatWithUncertainty,
1344                "PseudorangeInMeters",
1345                hasPseudorangeInMeters() ? mPseudorangeInMeters : null,
1346                "PseudorangeUncertaintyInMeters",
1347                hasPseudorangeUncertaintyInMeters() ? mPseudorangeUncertaintyInMeters : null));
1348
1349        builder.append(String.format(
1350                formatWithUncertainty,
1351                "CodePhaseInChips",
1352                hasCodePhaseInChips() ? mCodePhaseInChips : null,
1353                "CodePhaseUncertaintyInChips",
1354                hasCodePhaseUncertaintyInChips() ? mCodePhaseUncertaintyInChips : null));
1355
1356        builder.append(String.format(
1357                format,
1358                "CarrierFrequencyInHz",
1359                hasCarrierFrequencyInHz() ? mCarrierFrequencyInHz : null));
1360
1361        builder.append(String.format(
1362                format,
1363                "CarrierCycles",
1364                hasCarrierCycles() ? mCarrierCycles : null));
1365
1366        builder.append(String.format(
1367                formatWithUncertainty,
1368                "CarrierPhase",
1369                hasCarrierPhase() ? mCarrierPhase : null,
1370                "CarrierPhaseUncertainty",
1371                hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
1372
1373        builder.append(String.format(format, "LossOfLock", getLossOfLockString()));
1374
1375        builder.append(String.format(
1376                format,
1377                "BitNumber",
1378                hasBitNumber() ? mBitNumber : null));
1379
1380        builder.append(String.format(
1381                format,
1382                "TimeFromLastBitInMs",
1383                hasTimeFromLastBitInMs() ? mTimeFromLastBitInMs : null));
1384
1385        builder.append(String.format(
1386                formatWithUncertainty,
1387                "DopplerShiftInHz",
1388                hasDopplerShiftInHz() ? mDopplerShiftInHz : null,
1389                "DopplerShiftUncertaintyInHz",
1390                hasDopplerShiftUncertaintyInHz() ? mDopplerShiftUncertaintyInHz : null));
1391
1392        builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
1393
1394        builder.append(String.format(
1395                format,
1396                "SnrInDb",
1397                hasSnrInDb() ? mSnrInDb : null));
1398
1399        builder.append(String.format(
1400                formatWithUncertainty,
1401                "ElevationInDeg",
1402                hasElevationInDeg() ? mElevationInDeg : null,
1403                "ElevationUncertaintyInDeg",
1404                hasElevationUncertaintyInDeg() ? mElevationUncertaintyInDeg : null));
1405
1406        builder.append(String.format(
1407                formatWithUncertainty,
1408                "AzimuthInDeg",
1409                hasAzimuthInDeg() ? mAzimuthInDeg : null,
1410                "AzimuthUncertaintyInDeg",
1411                hasAzimuthUncertaintyInDeg() ? mAzimuthUncertaintyInDeg : null));
1412
1413        builder.append(String.format(format, "UsedInFix", mUsedInFix));
1414
1415        builder.append(String.format(format, "PseudorangeRateCarrierInMetersPerSec",
1416                    mPseudorangeRateCarrierInMetersPerSec));
1417        builder.append(String.format(format, "PseudorangeRateCarrierUncertaintyInMetersPerSec",
1418                    mPseudorangeRateCarrierUncertaintyInMetersPerSec));
1419
1420        return builder.toString();
1421    }
1422
1423    private void initialize() {
1424        mFlags = HAS_NO_FLAGS;
1425        setPrn(Byte.MIN_VALUE);
1426        setTimeOffsetInNs(Long.MIN_VALUE);
1427        setState(STATE_UNKNOWN);
1428        setReceivedGpsTowInNs(Long.MIN_VALUE);
1429        setReceivedGpsTowUncertaintyInNs(Long.MAX_VALUE);
1430        setCn0InDbHz(Double.MIN_VALUE);
1431        setPseudorangeRateInMetersPerSec(Double.MIN_VALUE);
1432        setPseudorangeRateUncertaintyInMetersPerSec(Double.MIN_VALUE);
1433        setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
1434        setAccumulatedDeltaRangeInMeters(Double.MIN_VALUE);
1435        setAccumulatedDeltaRangeUncertaintyInMeters(Double.MIN_VALUE);
1436        resetPseudorangeInMeters();
1437        resetPseudorangeUncertaintyInMeters();
1438        resetCodePhaseInChips();
1439        resetCodePhaseUncertaintyInChips();
1440        resetCarrierFrequencyInHz();
1441        resetCarrierCycles();
1442        resetCarrierPhase();
1443        resetCarrierPhaseUncertainty();
1444        setLossOfLock(LOSS_OF_LOCK_UNKNOWN);
1445        resetBitNumber();
1446        resetTimeFromLastBitInMs();
1447        resetDopplerShiftInHz();
1448        resetDopplerShiftUncertaintyInHz();
1449        setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
1450        resetSnrInDb();
1451        resetElevationInDeg();
1452        resetElevationUncertaintyInDeg();
1453        resetAzimuthInDeg();
1454        resetAzimuthUncertaintyInDeg();
1455        setUsedInFix(false);
1456        setPseudorangeRateCarrierInMetersPerSec(Double.MIN_VALUE);
1457        setPseudorangeRateCarrierUncertaintyInMetersPerSec(Double.MIN_VALUE);
1458    }
1459
1460    private void setFlag(int flag) {
1461        mFlags |= flag;
1462    }
1463
1464    private void resetFlag(int flag) {
1465        mFlags &= ~flag;
1466    }
1467
1468    private boolean isFlagSet(int flag) {
1469        return (mFlags & flag) == flag;
1470    }
1471}
1472