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