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