1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.location;
18
19import android.annotation.IntDef;
20
21import java.lang.annotation.Retention;
22import java.lang.annotation.RetentionPolicy;
23
24/**
25 * This class represents the current state of the GNSS engine.
26 * This class is used in conjunction with the {@link GnssStatus.Callback}.
27 */
28public final class GnssStatus {
29    // these must match the definitions in gps.h
30
31    /** Unknown constellation type. */
32    public static final int CONSTELLATION_UNKNOWN = 0;
33    /** Constellation type constant for GPS. */
34    public static final int CONSTELLATION_GPS = 1;
35    /** Constellation type constant for SBAS. */
36    public static final int CONSTELLATION_SBAS = 2;
37    /** Constellation type constant for Glonass. */
38    public static final int CONSTELLATION_GLONASS = 3;
39    /** Constellation type constant for QZSS. */
40    public static final int CONSTELLATION_QZSS = 4;
41    /** Constellation type constant for Beidou. */
42    public static final int CONSTELLATION_BEIDOU = 5;
43    /** Constellation type constant for Galileo. */
44    public static final int CONSTELLATION_GALILEO = 6;
45
46    /** @hide */
47    public static final int GNSS_SV_FLAGS_NONE = 0;
48    /** @hide */
49    public static final int GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA = (1 << 0);
50    /** @hide */
51    public static final int GNSS_SV_FLAGS_HAS_ALMANAC_DATA = (1 << 1);
52    /** @hide */
53    public static final int GNSS_SV_FLAGS_USED_IN_FIX = (1 << 2);
54    /** @hide */
55    public static final int GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY = (1 << 3);
56
57    /** @hide */
58    public static final int SVID_SHIFT_WIDTH = 8;
59    /** @hide */
60    public static final int CONSTELLATION_TYPE_SHIFT_WIDTH = 4;
61    /** @hide */
62    public static final int CONSTELLATION_TYPE_MASK = 0xf;
63
64    /**
65     * Used for receiving notifications when GNSS events happen.
66     */
67    public static abstract class Callback {
68        /**
69         * Called when GNSS system has started.
70         */
71        public void onStarted() {}
72
73        /**
74         * Called when GNSS system has stopped.
75         */
76        public void onStopped() {}
77
78        /**
79         * Called when the GNSS system has received its first fix since starting.
80         * @param ttffMillis the time from start to first fix in milliseconds.
81         */
82        public void onFirstFix(int ttffMillis) {}
83
84        /**
85         * Called periodically to report GNSS satellite status.
86         * @param status the current status of all satellites.
87         */
88        public void onSatelliteStatusChanged(GnssStatus status) {}
89    }
90
91    /**
92     * Constellation type.
93     * @hide
94     */
95    @Retention(RetentionPolicy.SOURCE)
96    @IntDef({CONSTELLATION_UNKNOWN, CONSTELLATION_GPS, CONSTELLATION_SBAS, CONSTELLATION_GLONASS,
97            CONSTELLATION_QZSS, CONSTELLATION_BEIDOU, CONSTELLATION_GALILEO})
98    public @interface ConstellationType {}
99
100    final int[] mSvidWithFlags;
101    final float[] mCn0DbHz;
102    final float[] mElevations;
103    final float[] mAzimuths;
104    final int mSvCount;
105    final float[] mCarrierFrequencies;
106
107    GnssStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations,
108            float[] azimuths, float[] carrierFrequencies) {
109        mSvCount = svCount;
110        mSvidWithFlags = svidWithFlags;
111        mCn0DbHz = cn0s;
112        mElevations = elevations;
113        mAzimuths = azimuths;
114        mCarrierFrequencies = carrierFrequencies;
115    }
116
117    /**
118     * Gets the total number of satellites in satellite list.
119     */
120    public int getSatelliteCount() {
121        return mSvCount;
122    }
123
124    /**
125     * Retrieves the constellation type of the satellite at the specified index.
126     *
127     * @param satIndex the index of the satellite in the list.
128     */
129    @ConstellationType
130    public int getConstellationType(int satIndex) {
131        return ((mSvidWithFlags[satIndex] >> CONSTELLATION_TYPE_SHIFT_WIDTH)
132                & CONSTELLATION_TYPE_MASK);
133    }
134
135    /**
136     * Gets the identification number for the satellite at the specific index.
137     *
138     * <p>This svid is pseudo-random number for most constellations. It is FCN &amp; OSN number for
139     * Glonass.
140     *
141     * <p>The distinction is made by looking at constellation field
142     * {@link #getConstellationType(int)} Expected values are in the range of:
143     *
144     * <ul>
145     * <li>GPS: 1-32</li>
146     * <li>SBAS: 120-151, 183-192</li>
147     * <li>GLONASS: One of: OSN, or FCN+100
148     * <ul>
149     *   <li>1-24 as the orbital slot number (OSN) (preferred, if known)</li>
150     *   <li>93-106 as the frequency channel number (FCN) (-7 to +6) plus 100.
151     *   i.e. encode FCN of -7 as 93, 0 as 100, and +6 as 106</li>
152     * </ul></li>
153     * <li>QZSS: 193-200</li>
154     * <li>Galileo: 1-36</li>
155     * <li>Beidou: 1-37</li>
156     * </ul>
157     *
158     * @param satIndex the index of the satellite in the list.
159     */
160    public int getSvid(int satIndex) {
161        return mSvidWithFlags[satIndex] >> SVID_SHIFT_WIDTH;
162    }
163
164    /**
165     * Retrieves the carrier-to-noise density at the antenna of the satellite at the specified index
166     * in dB-Hz.
167     *
168     * @param satIndex the index of the satellite in the list.
169     */
170    public float getCn0DbHz(int satIndex) {
171        return mCn0DbHz[satIndex];
172    }
173
174    /**
175     * Retrieves the elevation of the satellite at the specified index.
176     *
177     * @param satIndex the index of the satellite in the list.
178     */
179    public float getElevationDegrees(int satIndex) {
180        return mElevations[satIndex];
181    }
182
183    /**
184     * Retrieves the azimuth the satellite at the specified index.
185     *
186     * @param satIndex the index of the satellite in the list.
187     */
188    public float getAzimuthDegrees(int satIndex) {
189        return mAzimuths[satIndex];
190    }
191
192    /**
193     * Reports whether the satellite at the specified index has ephemeris data.
194     *
195     * @param satIndex the index of the satellite in the list.
196     */
197    public boolean hasEphemerisData(int satIndex) {
198        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0;
199    }
200
201    /**
202     * Reports whether the satellite at the specified index has almanac data.
203     *
204     * @param satIndex the index of the satellite in the list.
205     */
206    public boolean hasAlmanacData(int satIndex) {
207        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0;
208    }
209
210    /**
211     * Reports whether the satellite at the specified index was used in the calculation of the most
212     * recent position fix.
213     *
214     * @param satIndex the index of the satellite in the list.
215     */
216    public boolean usedInFix(int satIndex) {
217        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_USED_IN_FIX) != 0;
218    }
219
220    /**
221     * Reports whether a valid {@link #getCarrierFrequencyHz(int satIndex)} is available.
222     *
223     * @param satIndex the index of the satellite in the list.
224     */
225    public boolean hasCarrierFrequencyHz(int satIndex) {
226        return (mSvidWithFlags[satIndex] & GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) != 0;
227    }
228
229    /**
230     * Gets the carrier frequency of the signal tracked.
231     *
232     * <p>For example it can be the GPS central frequency for L1 = 1575.45 MHz, or L2 = 1227.60 MHz,
233     * L5 = 1176.45 MHz, varying GLO channels, etc. If the field is not set, it is the primary
234     * common use central frequency, e.g. L1 = 1575.45 MHz for GPS.
235     *
236     * For an L1, L5 receiver tracking a satellite on L1 and L5 at the same time, two measurements
237     * will be reported for this same satellite, in one all the values related to L1 will be filled,
238     * and in the other all of the values related to L5 will be filled.
239     *
240     * <p>The value is only available if {@link #hasCarrierFrequencyHz(int satIndex)} is {@code true}.
241     *
242     * @param satIndex the index of the satellite in the list.
243     *
244     * @return the carrier frequency of the signal tracked in Hz.
245     */
246    public float getCarrierFrequencyHz(int satIndex) {
247        return mCarrierFrequencies[satIndex];
248    }
249}
250