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