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