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