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 
17 #ifndef _CHRE_GNSS_H_
18 #define _CHRE_GNSS_H_
19 
20 /**
21  * @file
22  * Global Navigation Satellite System (GNSS) API.
23  *
24  * These structures and definitions are based on the Android N GPS HAL.
25  * Refer to that header file (located at this path as of the time of this
26  * comment: hardware/libhardware/include/hardware/gps.h) and associated
27  * documentation for further details and explanations for these fields.
28  * References in comments like "(ref: GnssAccumulatedDeltaRangeState)" map to
29  * the relevant element in the GPS HAL where additional information can be
30  * found.
31  *
32  * In general, the parts of this API that are taken from the GPS HAL follow the
33  * naming conventions established in that interface rather than the CHRE API
34  * conventions, in order to avoid confusion and enable code re-use where
35  * applicable.
36  */
37 
38 #include <stdbool.h>
39 #include <stdint.h>
40 
41 #include <chre/common.h>
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 /**
48  * The set of flags that may be returned by chreGnssGetCapabilities()
49  * @defgroup CHRE_GNSS_CAPABILITIES
50  * @{
51  */
52 
53 //! A lack of flags indicates that GNSS is not supported in this CHRE
54 #define CHRE_GNSS_CAPABILITIES_NONE          UINT32_C(0)
55 
56 //! GNSS position fixes are supported via chreGnssPositionSessionStartAsync()
57 #define CHRE_GNSS_CAPABILITIES_LOCATION      UINT32_C(1 << 0)
58 
59 //! GNSS raw measurements are supported via
60 //! chreGnssMeasurementSessionStartAsync()
61 #define CHRE_GNSS_CAPABILITIES_MEASUREMENTS  UINT32_C(1 << 1)
62 
63 /** @} */
64 
65 /**
66  * The current version of struct chreGnssDataEvent associated with this API
67  */
68 #define CHRE_GNSS_DATA_EVENT_VERSION  UINT8_C(0)
69 
70 /**
71  * The maximum time the CHRE implementation is allowed to elapse before sending
72  * an event with the result of an asynchronous request, unless specified
73  * otherwise
74  */
75 #define CHRE_GNSS_ASYNC_RESULT_TIMEOUT_NS  (5 * CHRE_NSEC_PER_SEC_U64)
76 
77 /**
78  * Produce an event ID in the block of IDs reserved for GNSS
79  * @param offset  Index into GNSS event ID block; valid range [0,15]
80  */
81 #define CHRE_GNSS_EVENT_ID(offset)  (CHRE_EVENT_GNSS_FIRST_EVENT + (offset))
82 
83 /**
84  * nanoappHandleEvent argument: struct chreAsyncResult
85  *
86  * Communicates the asynchronous result of a request to the GNSS API, such as
87  * starting a location session via chreGnssLocationSessionStartAsync(). The
88  * requestType field in chreAsyncResult is set to a value from enum
89  * chreGnssRequestType.
90  */
91 #define CHRE_EVENT_GNSS_ASYNC_RESULT  CHRE_GNSS_EVENT_ID(0)
92 
93 /**
94  * nanoappHandleEvent argument: struct chreGnssLocationEvent
95  *
96  * Represents a location fix provided by the GNSS subsystem.
97  */
98 #define CHRE_EVENT_GNSS_LOCATION      CHRE_GNSS_EVENT_ID(1)
99 
100 /**
101  * nanoappHandleEvent argument: struct chreGnssDataEvent
102  *
103  * Represents a set of GNSS measurements with associated clock data.
104  */
105 #define CHRE_EVENT_GNSS_DATA          CHRE_GNSS_EVENT_ID(2)
106 
107 // NOTE: Do not add new events with ID > 15; only values 0-15 are reserved
108 // (see chre/event.h)
109 
110 // Flags indicating the Accumulated Delta Range's states
111 // (ref: GnssAccumulatedDeltaRangeState)
112 #define CHRE_GNSS_ADR_STATE_UNKNOWN     UINT16_C(0)
113 #define CHRE_GNSS_ADR_STATE_VALID       UINT16_C(1 << 0)
114 #define CHRE_GNSS_ADR_STATE_RESET       UINT16_C(1 << 1)
115 #define CHRE_GNSS_ADR_STATE_CYCLE_SLIP  UINT16_C(1 << 2)
116 
117 // Flags to indicate what fields in chreGnssClock are valid (ref: GnssClockFlags)
118 #define CHRE_GNSS_CLOCK_HAS_LEAP_SECOND        UINT16_C(1 << 0)
119 #define CHRE_GNSS_CLOCK_HAS_TIME_UNCERTAINTY   UINT16_C(1 << 1)
120 #define CHRE_GNSS_CLOCK_HAS_FULL_BIAS          UINT16_C(1 << 2)
121 #define CHRE_GNSS_CLOCK_HAS_BIAS               UINT16_C(1 << 3)
122 #define CHRE_GNSS_CLOCK_HAS_BIAS_UNCERTAINTY   UINT16_C(1 << 4)
123 #define CHRE_GNSS_CLOCK_HAS_DRIFT              UINT16_C(1 << 5)
124 #define CHRE_GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY  UINT16_C(1 << 6)
125 
126 // Flags to indicate which values are valid in a GpsLocation
127 // (ref: GpsLocationFlags)
128 #define CHRE_GPS_LOCATION_HAS_LAT_LONG  UINT16_C(1 << 0)
129 #define CHRE_GPS_LOCATION_HAS_ALTITUDE  UINT16_C(1 << 1)
130 #define CHRE_GPS_LOCATION_HAS_SPEED     UINT16_C(1 << 2)
131 #define CHRE_GPS_LOCATION_HAS_BEARING   UINT16_C(1 << 3)
132 #define CHRE_GPS_LOCATION_HAS_ACCURACY  UINT16_C(1 << 4)
133 
134 /**
135  * The maximum number of instances of struct chreGnssMeasurement that may be
136  * included in a single struct chreGnssDataEvent.
137  */
138 #define CHRE_GNSS_MAX_MEASUREMENT  UINT8_C(64)
139 
140 // Flags indicating the GNSS measurement state (ref: GnssMeasurementState)
141 #define CHRE_GNSS_MEASUREMENT_STATE_UNKNOWN                UINT16_C(0)
142 #define CHRE_GNSS_MEASUREMENT_STATE_CODE_LOCK              UINT16_C(1 << 0)
143 #define CHRE_GNSS_MEASUREMENT_STATE_BIT_SYNC               UINT16_C(1 << 1)
144 #define CHRE_GNSS_MEASUREMENT_STATE_SUBFRAME_SYNC          UINT16_C(1 << 2)
145 #define CHRE_GNSS_MEASUREMENT_STATE_TOW_DECODED            UINT16_C(1 << 3)
146 #define CHRE_GNSS_MEASUREMENT_STATE_MSEC_AMBIGUOUS         UINT16_C(1 << 4)
147 #define CHRE_GNSS_MEASUREMENT_STATE_SYMBOL_SYNC            UINT16_C(1 << 5)
148 #define CHRE_GNSS_MEASUREMENT_STATE_GLO_STRING_SYNC        UINT16_C(1 << 6)
149 #define CHRE_GNSS_MEASUREMENT_STATE_GLO_TOD_DECODED        UINT16_C(1 << 7)
150 #define CHRE_GNSS_MEASUREMENT_STATE_BDS_D2_BIT_SYNC        UINT16_C(1 << 8)
151 #define CHRE_GNSS_MEASUREMENT_STATE_BDS_D2_SUBFRAME_SYNC   UINT16_C(1 << 9)
152 #define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1BC_CODE_LOCK     UINT16_C(1 << 10)
153 #define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1C_2ND_CODE_LOCK  UINT16_C(1 << 11)
154 #define CHRE_GNSS_MEASUREMENT_STATE_GAL_E1B_PAGE_SYNC      UINT16_C(1 << 12)
155 #define CHRE_GNSS_MEASUREMENT_STATE_SBAS_SYNC              UINT16_C(1 << 13)
156 
157 
158 /**
159  * Indicates a type of request made in this API. Used to populate the resultType
160  * field of struct chreAsyncResult sent with CHRE_EVENT_GNSS_ASYNC_RESULT.
161  */
162 enum chreGnssRequestType {
163     CHRE_GNSS_REQUEST_TYPE_LOCATION_SESSION_START    = 1,
164     CHRE_GNSS_REQUEST_TYPE_LOCATION_SESSION_STOP     = 2,
165     CHRE_GNSS_REQUEST_TYPE_MEASUREMENT_SESSION_START = 3,
166     CHRE_GNSS_REQUEST_TYPE_MEASUREMENT_SESSION_STOP  = 4,
167 };
168 
169 /**
170  * Constellation type associated with an SV
171  */
172 enum chreGnssConstellationType {
173     CHRE_GNSS_CONSTELLATION_UNKNOWN = 0,
174     CHRE_GNSS_CONSTELLATION_GPS     = 1,
175     CHRE_GNSS_CONSTELLATION_SBAS    = 2,
176     CHRE_GNSS_CONSTELLATION_GLONASS = 3,
177     CHRE_GNSS_CONSTELLATION_QZSS    = 4,
178     CHRE_GNSS_CONSTELLATION_BEIDOU  = 5,
179     CHRE_GNSS_CONSTELLATION_GALILEO = 6,
180 };
181 
182 /**
183  * Enumeration of available values for the chreGnssMeasurement multipath indicator
184  */
185 enum chreGnssMultipathIndicator {
186     //! The indicator is not available or unknown
187     CHRE_GNSS_MULTIPATH_INDICATOR_UNKNOWN     = 0,
188     //! The measurement is indicated to be affected by multipath
189     CHRE_GNSS_MULTIPATH_INDICATOR_PRESENT     = 1,
190     //! The measurement is indicated to be not affected by multipath
191     CHRE_GNSS_MULTIPATH_INDICATOR_NOT_PRESENT = 2,
192 };
193 
194 /**
195  * Represents an estimate of the GNSS clock time (see the Android GPS HAL for
196  * more detailed information)
197  */
198 struct chreGnssClock {
199     //! The GNSS receiver hardware clock value in nanoseconds, including
200     //! uncertainty
201     int64_t time_ns;
202 
203     //! The difference between hardware clock inside GNSS receiver and the
204     //! estimated GNSS time in nanoseconds; contains bias uncertainty
205     int64_t full_bias_ns;
206 
207     //! Sub-nanosecond bias, adds to full_bias_ns
208     float bias_ns;
209 
210     //! The clock's drift in nanoseconds per second
211     float drift_nsps;
212 
213     //! 1-sigma uncertainty associated with the clock's bias in nanoseconds
214     float bias_uncertainty_ns;
215 
216     //! 1-sigma uncertainty associated with the clock's drift in nanoseconds
217     //! per second
218     float drift_uncertainty_nsps;
219 
220     //! While this number stays the same, timeNs should flow continuously
221     uint32_t hw_clock_discontinuity_count;
222 
223     //! A set of flags indicating the validity of the fields in this data
224     //! structure (see GNSS_CLOCK_HAS_*)
225     uint16_t flags;
226 
227     //! Reserved for future use; set to 0
228     uint8_t reserved[2];
229 };
230 
231 /**
232  * Represents a GNSS measurement; contains raw and computed information (see the
233  * Android GPS HAL for more detailed information)
234  */
235 struct chreGnssMeasurement {
236     //! Hardware time offset from time_ns for this measurement, in nanoseconds
237     int64_t time_offset_ns;
238 
239     //! Accumulated delta range since the last channel reset in micro-meters
240     int64_t accumulated_delta_range_um;
241 
242     //! Received GNSS satellite time at the time of measurement, in nanoseconds
243     int64_t received_sv_time_in_ns;
244 
245     //! 1-sigma uncertainty of received GNSS satellite time, in nanoseconds
246     int64_t received_sv_time_uncertainty_in_ns;
247 
248     //! Pseudorange rate at the timestamp in meters per second (uncorrected)
249     float pseudorange_rate_mps;
250 
251     //! 1-sigma uncertainty of pseudorange rate in meters per second
252     float pseudorange_rate_uncertainty_mps;
253 
254     //! 1-sigma uncertainty of the accumulated delta range in meters
255     float accumulated_delta_range_uncertainty_m;
256 
257     //! Carrier-to-noise density in dB-Hz, in the range of [0, 63]
258     float c_n0_dbhz;
259 
260     //! Signal to noise ratio (dB), power above observed noise at correlators
261     float snr_db;
262 
263     //! Satellite sync state flags (GNSS_MEASUREMENT_STATE_*) - sets modulus for
264     //! received_sv_time_in_ns
265     uint16_t state;
266 
267     //! Set of ADR state flags (GNSS_ADR_STATE_*)
268     uint16_t accumulated_delta_range_state;
269 
270     //! Satellite vehicle ID number
271     int16_t svid;
272 
273     //! Constellation of the given satellite vehicle
274     //! @see #chreGnssConstellationType
275     uint8_t constellation;
276 
277     //! @see #chreGnssMultipathIndicator
278     uint8_t multipath_indicator;
279 
280     //! Reserved for future use; set to 0
281     uint8_t reserved[4];
282 };
283 
284 /**
285  * Data structure sent with events associated with CHRE_EVENT_GNSS_DATA, enabled
286  * via chreGnssMeasurementSessionStartAsync()
287  */
288 struct chreGnssDataEvent {
289     //! Indicates the version of the structure, for compatibility purposes.
290     //! Clients do not normally need to worry about this field; the CHRE
291     //! implementation guarantees that it only sends the client the structure
292     //! version it expects.
293     uint8_t version;
294 
295     //! Number of chreGnssMeasurement entries included in this event. Must be in
296     //! the range [0, CHRE_GNSS_MAX_MEASUREMENT]
297     uint8_t measurement_count;
298 
299     //! Reserved for future use; set to 0
300     uint8_t reserved[6];
301 
302     struct chreGnssClock clock;
303 
304     //! Pointer to an array containing measurement_count measurements
305     const struct chreGnssMeasurement *measurements;
306 };
307 
308 /**
309  * Data structure sent with events of type CHRE_EVENT_GNSS_LOCATION, enabled via
310  * chreGnssLocationSessionStartAsync(). This is modeled after GpsLocation in the
311  * GPS HAL, but does not use the double data type.
312  */
313 struct chreGnssLocationEvent {
314     //! UTC timestamp for location fix in milliseconds since January 1, 1970
315     uint64_t timestamp;
316 
317     //! Fixed point latitude, degrees times 10^7 (roughly centimeter resolution)
318     int32_t latitude_deg_e7;
319 
320     //! Fixed point longitude, degrees times 10^7 (roughly centimeter
321     //! resolution)
322     int32_t longitude_deg_e7;
323 
324     //! Altitude in meters above the WGS 84 reference ellipsoid
325     float altitude;
326 
327     //! Horizontal speed in meters per second
328     float speed;
329 
330     //! Clockwise angle between north and current heading, in degrees; range
331     //! [0, 360)
332     float bearing;
333 
334     //! Expected horizontal accuracy in meters such that a circle with a radius
335     //! of length 'accuracy' from the latitude and longitude has a 68%
336     //! probability of including the true location. Use 0.0 if there is no
337     //! accuracy.
338     float accuracy;
339 
340     //! A set of flags indicating which fields in this structure are valid
341     //! @see #GpsLocationFlags
342     uint16_t flags;
343 };
344 
345 
346 /**
347  * Retrieves a set of flags indicating the GNSS features supported by the
348  * current CHRE implementation. The value returned by this function must be
349  * consistent for the entire duration of the Nanoapp's execution.
350  *
351  * The client must allow for more flags to be set in this response than it knows
352  * about, for example if the implementation supports a newer version of the API
353  * than the client was compiled against.
354  *
355  * @return A bitmask with zero or more CHRE_GNSS_CAPABILITIES_* flags set
356  *
357  * @since v1.1
358  */
359 uint32_t chreGnssGetCapabilities(void);
360 
361 /**
362  * Initiates a GNSS positioning session, or changes the requested interval of an
363  * existing session. If starting or modifying the session was successful, then
364  * the GPS engine will work on determining the device's position.
365  *
366  * This result of this request is delivered asynchronously via an event of type
367  * CHRE_EVENT_GNSS_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult}
368  * for more details.
369  *
370  * If chreGnssGetCapabilities() returns a value that does not have the
371  * CHRE_GNSS_CAPABILITIES_LOCATION flag set, then this method will return false.
372  *
373  * @param minIntervalMs The desired minimum interval between location fixes
374  *        delivered to the client via CHRE_EVENT_GNSS_LOCATION, in milliseconds.
375  *        The requesting client must allow for fixes to be delivered at shorter
376  *        or longer interval than requested. For example, adverse RF conditions
377  *        may result in fixes arriving at a longer interval, etc.
378  * @param minTimeToNextFixMs The desired minimum time to the next location fix.
379  *        If this is 0, the GNSS engine should start working on the next fix
380  *        immediately. If greater than 0, the GNSS engine should not spend
381  *        measurable power to produce a location fix until this amount of time
382  *        has elapsed.
383  * @param cookie An opaque value that will be included in the chreAsyncResult
384  *        sent in relation to this request.
385  *
386  * @return true if the request was accepted for processing, false otherwise
387  *
388  * @since v1.1
389  */
390 bool chreGnssLocationSessionStartAsync(uint32_t minIntervalMs,
391                                        uint32_t minTimeToNextFixMs,
392                                        const void *cookie);
393 
394 /**
395  * Terminates an existing GNSS positioning session. If no positioning session
396  * is active at the time of this request, it is treated as if an active session
397  * was successfully ended.
398  *
399  * This result of this request is delivered asynchronously via an event of type
400  * CHRE_EVENT_GNSS_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult}
401  * for more details.
402  *
403  * After CHRE_EVENT_GNSS_ASYNC_RESULT is delivered to the client, no more
404  * CHRE_EVENT_GNSS_LOCATION events will be delievered until a new location
405  * session is started.
406  *
407  * If chreGnssGetCapabilities() returns a value that does not have the
408  * CHRE_GNSS_CAPABILITIES_LOCATION flag set, then this method will return false.
409  *
410  * @param cookie An opaque value that will be included in the chreAsyncResult
411  *        sent in relation to this request.
412  *
413  * @return true if the request was accepted for processing, false otherwise
414  *
415  * @since v1.1
416  */
417 bool chreGnssLocationSessionStopAsync(const void *cookie);
418 
419 /**
420  * Initiates a request to receive raw GNSS measurements. A GNSS measurement
421  * session can exist independently of location sessions. In other words, a
422  * Nanoapp is able to receive measurements at its requested interval both with
423  * and without an active location session.
424  *
425  * This result of this request is delivered asynchronously via an event of type
426  * CHRE_EVENT_GNSS_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult}
427  * for more details.
428  *
429  * If chreGnssGetCapabilities() returns a value that does not have the
430  * CHRE_GNSS_CAPABILITIES_MEASUREMENTS flag set, then this method will return
431  * false.
432  *
433  * @param minIntervalMs The desired minimum interval between measurement reports
434  *        delivered via CHRE_EVENT_GNSS_DATA. When requested at 1000ms or
435  *        faster, and GNSS measurements are tracked, device should report
436  *        measurements as fast as requested, and shall report no slower than
437  *        once every 1000ms, on average.
438  * @param cookie An opaque value that will be included in the chreAsyncResult
439  *        sent in relation to this request.
440  *
441  * @return true if the request was accepted for processing, false otherwise
442  *
443  * @since v1.1
444  */
445 bool chreGnssMeasurementSessionStartAsync(uint32_t minIntervalMs,
446                                           const void *cookie);
447 
448 /**
449  * Terminates an existing raw GNSS measurement session. If no measurement
450  * session is active at the time of this request, it is treated as if an active
451  * session was successfully ended.
452  *
453  * This result of this request is delivered asynchronously via an event of type
454  * CHRE_EVENT_GNSS_ASYNC_RESULT. Refer to the note in {@link #chreAsyncResult}
455  * for more details.
456  *
457  * If chreGnssGetCapabilities() returns a value that does not have the
458  * CHRE_GNSS_CAPABILITIES_MEASUREMENTS flag set, then this method will return
459  * false.
460  *
461  * @param cookie An opaque value that will be included in the chreAsyncResult
462  *        sent in relation to this request.
463  *
464  * @return true if the request was accepted for processing, false otherwise
465  *
466  * @since v1.1
467  */
468 bool chreGnssMeasurementSessionStopAsync(const void *cookie);
469 
470 
471 #ifdef __cplusplus
472 }
473 #endif
474 
475 #endif  /* _CHRE_GNSS_H_ */
476