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