xref: /aosp_15_r20/system/chre/chpp/clients/gnss.c (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker  *
4*84e33947SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker  *
8*84e33947SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker  *
10*84e33947SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker  * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker  */
16*84e33947SAndroid Build Coastguard Worker 
17*84e33947SAndroid Build Coastguard Worker #include "chpp/clients/gnss.h"
18*84e33947SAndroid Build Coastguard Worker 
19*84e33947SAndroid Build Coastguard Worker #include <inttypes.h>
20*84e33947SAndroid Build Coastguard Worker #include <stdbool.h>
21*84e33947SAndroid Build Coastguard Worker #include <stddef.h>
22*84e33947SAndroid Build Coastguard Worker #include <stdint.h>
23*84e33947SAndroid Build Coastguard Worker #include <string.h>
24*84e33947SAndroid Build Coastguard Worker 
25*84e33947SAndroid Build Coastguard Worker #include "chpp/app.h"
26*84e33947SAndroid Build Coastguard Worker #include "chpp/clients.h"
27*84e33947SAndroid Build Coastguard Worker #include "chpp/clients/discovery.h"
28*84e33947SAndroid Build Coastguard Worker #include "chpp/common/gnss.h"
29*84e33947SAndroid Build Coastguard Worker #include "chpp/common/gnss_types.h"
30*84e33947SAndroid Build Coastguard Worker #include "chpp/common/standard_uuids.h"
31*84e33947SAndroid Build Coastguard Worker #include "chpp/log.h"
32*84e33947SAndroid Build Coastguard Worker #include "chpp/macros.h"
33*84e33947SAndroid Build Coastguard Worker #include "chpp/memory.h"
34*84e33947SAndroid Build Coastguard Worker #include "chre/pal/gnss.h"
35*84e33947SAndroid Build Coastguard Worker #include "chre_api/chre/gnss.h"
36*84e33947SAndroid Build Coastguard Worker 
37*84e33947SAndroid Build Coastguard Worker #ifndef CHPP_GNSS_DISCOVERY_TIMEOUT_MS
38*84e33947SAndroid Build Coastguard Worker #define CHPP_GNSS_DISCOVERY_TIMEOUT_MS CHPP_DISCOVERY_DEFAULT_TIMEOUT_MS
39*84e33947SAndroid Build Coastguard Worker #endif
40*84e33947SAndroid Build Coastguard Worker 
41*84e33947SAndroid Build Coastguard Worker /************************************************
42*84e33947SAndroid Build Coastguard Worker  *  Prototypes
43*84e33947SAndroid Build Coastguard Worker  ***********************************************/
44*84e33947SAndroid Build Coastguard Worker 
45*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppDispatchGnssResponse(void *clientContext,
46*84e33947SAndroid Build Coastguard Worker                                                       uint8_t *buf, size_t len);
47*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppDispatchGnssNotification(void *clientContext,
48*84e33947SAndroid Build Coastguard Worker                                                           uint8_t *buf,
49*84e33947SAndroid Build Coastguard Worker                                                           size_t len);
50*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientInit(void *clientContext, uint8_t handle,
51*84e33947SAndroid Build Coastguard Worker                                struct ChppVersion serviceVersion);
52*84e33947SAndroid Build Coastguard Worker static void chppGnssClientDeinit(void *clientContext);
53*84e33947SAndroid Build Coastguard Worker static void chppGnssClientNotifyReset(void *clientContext);
54*84e33947SAndroid Build Coastguard Worker static void chppGnssClientNotifyMatch(void *clientContext);
55*84e33947SAndroid Build Coastguard Worker 
56*84e33947SAndroid Build Coastguard Worker /************************************************
57*84e33947SAndroid Build Coastguard Worker  *  Private Definitions
58*84e33947SAndroid Build Coastguard Worker  ***********************************************/
59*84e33947SAndroid Build Coastguard Worker 
60*84e33947SAndroid Build Coastguard Worker /**
61*84e33947SAndroid Build Coastguard Worker  * Structure to maintain state for the GNSS client and its Request/Response
62*84e33947SAndroid Build Coastguard Worker  * (RR) functionality.
63*84e33947SAndroid Build Coastguard Worker  */
64*84e33947SAndroid Build Coastguard Worker struct ChppGnssClientState {
65*84e33947SAndroid Build Coastguard Worker   struct ChppEndpointState client;   // CHPP client state
66*84e33947SAndroid Build Coastguard Worker   const struct chrePalGnssApi *api;  // GNSS PAL API
67*84e33947SAndroid Build Coastguard Worker 
68*84e33947SAndroid Build Coastguard Worker   struct ChppOutgoingRequestState
69*84e33947SAndroid Build Coastguard Worker       outReqStates[CHPP_GNSS_CLIENT_REQUEST_MAX + 1];
70*84e33947SAndroid Build Coastguard Worker 
71*84e33947SAndroid Build Coastguard Worker   uint32_t capabilities;           // Cached GetCapabilities result
72*84e33947SAndroid Build Coastguard Worker   bool requestStateResyncPending;  // requestStateResync() is waiting to be
73*84e33947SAndroid Build Coastguard Worker                                    // processed
74*84e33947SAndroid Build Coastguard Worker   bool capabilitiesValid;  // Flag to indicate if the capabilities result
75*84e33947SAndroid Build Coastguard Worker                            // is valid
76*84e33947SAndroid Build Coastguard Worker };
77*84e33947SAndroid Build Coastguard Worker 
78*84e33947SAndroid Build Coastguard Worker // Note: This global definition of gGnssClientContext supports only one
79*84e33947SAndroid Build Coastguard Worker // instance of the CHPP GNSS client at a time.
80*84e33947SAndroid Build Coastguard Worker struct ChppGnssClientState gGnssClientContext;
81*84e33947SAndroid Build Coastguard Worker static const struct chrePalSystemApi *gSystemApi;
82*84e33947SAndroid Build Coastguard Worker static const struct chrePalGnssCallbacks *gCallbacks;
83*84e33947SAndroid Build Coastguard Worker 
84*84e33947SAndroid Build Coastguard Worker /**
85*84e33947SAndroid Build Coastguard Worker  * Configuration parameters for this client
86*84e33947SAndroid Build Coastguard Worker  */
87*84e33947SAndroid Build Coastguard Worker static const struct ChppClient kGnssClientConfig = {
88*84e33947SAndroid Build Coastguard Worker     .descriptor.uuid = CHPP_UUID_GNSS_STANDARD,
89*84e33947SAndroid Build Coastguard Worker 
90*84e33947SAndroid Build Coastguard Worker     // Version
91*84e33947SAndroid Build Coastguard Worker     .descriptor.version.major = 1,
92*84e33947SAndroid Build Coastguard Worker     .descriptor.version.minor = 0,
93*84e33947SAndroid Build Coastguard Worker     .descriptor.version.patch = 0,
94*84e33947SAndroid Build Coastguard Worker 
95*84e33947SAndroid Build Coastguard Worker     // Notifies client if CHPP is reset
96*84e33947SAndroid Build Coastguard Worker     .resetNotifierFunctionPtr = &chppGnssClientNotifyReset,
97*84e33947SAndroid Build Coastguard Worker 
98*84e33947SAndroid Build Coastguard Worker     // Notifies client if they are matched to a service
99*84e33947SAndroid Build Coastguard Worker     .matchNotifierFunctionPtr = &chppGnssClientNotifyMatch,
100*84e33947SAndroid Build Coastguard Worker 
101*84e33947SAndroid Build Coastguard Worker     // Service response dispatch function pointer
102*84e33947SAndroid Build Coastguard Worker     .responseDispatchFunctionPtr = &chppDispatchGnssResponse,
103*84e33947SAndroid Build Coastguard Worker 
104*84e33947SAndroid Build Coastguard Worker     // Service notification dispatch function pointer
105*84e33947SAndroid Build Coastguard Worker     .notificationDispatchFunctionPtr = &chppDispatchGnssNotification,
106*84e33947SAndroid Build Coastguard Worker 
107*84e33947SAndroid Build Coastguard Worker     // Service response dispatch function pointer
108*84e33947SAndroid Build Coastguard Worker     .initFunctionPtr = &chppGnssClientInit,
109*84e33947SAndroid Build Coastguard Worker 
110*84e33947SAndroid Build Coastguard Worker     // Service notification dispatch function pointer
111*84e33947SAndroid Build Coastguard Worker     .deinitFunctionPtr = &chppGnssClientDeinit,
112*84e33947SAndroid Build Coastguard Worker 
113*84e33947SAndroid Build Coastguard Worker     // Number of request-response states in the outReqStates array.
114*84e33947SAndroid Build Coastguard Worker     .outReqCount = ARRAY_SIZE(gGnssClientContext.outReqStates),
115*84e33947SAndroid Build Coastguard Worker 
116*84e33947SAndroid Build Coastguard Worker     // Min length is the entire header
117*84e33947SAndroid Build Coastguard Worker     .minLength = sizeof(struct ChppAppHeader),
118*84e33947SAndroid Build Coastguard Worker };
119*84e33947SAndroid Build Coastguard Worker 
120*84e33947SAndroid Build Coastguard Worker /************************************************
121*84e33947SAndroid Build Coastguard Worker  *  Prototypes
122*84e33947SAndroid Build Coastguard Worker  ***********************************************/
123*84e33947SAndroid Build Coastguard Worker 
124*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientOpen(const struct chrePalSystemApi *systemApi,
125*84e33947SAndroid Build Coastguard Worker                                const struct chrePalGnssCallbacks *callbacks);
126*84e33947SAndroid Build Coastguard Worker static void chppGnssClientClose(void);
127*84e33947SAndroid Build Coastguard Worker static uint32_t chppGnssClientGetCapabilities(void);
128*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientControlLocationSession(bool enable,
129*84e33947SAndroid Build Coastguard Worker                                                  uint32_t minIntervalMs,
130*84e33947SAndroid Build Coastguard Worker                                                  uint32_t minTimeToNextFixMs);
131*84e33947SAndroid Build Coastguard Worker static void chppGnssClientReleaseLocationEvent(
132*84e33947SAndroid Build Coastguard Worker     struct chreGnssLocationEvent *event);
133*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientControlMeasurementSession(bool enable,
134*84e33947SAndroid Build Coastguard Worker                                                     uint32_t minIntervalMs);
135*84e33947SAndroid Build Coastguard Worker static void chppGnssClientReleaseMeasurementDataEvent(
136*84e33947SAndroid Build Coastguard Worker     struct chreGnssDataEvent *event);
137*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientConfigurePassiveLocationListener(bool enable);
138*84e33947SAndroid Build Coastguard Worker 
139*84e33947SAndroid Build Coastguard Worker static void chppGnssCloseResult(struct ChppGnssClientState *clientContext,
140*84e33947SAndroid Build Coastguard Worker                                 uint8_t *buf, size_t len);
141*84e33947SAndroid Build Coastguard Worker static void chppGnssGetCapabilitiesResult(
142*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len);
143*84e33947SAndroid Build Coastguard Worker static void chppGnssControlLocationSessionResult(
144*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len);
145*84e33947SAndroid Build Coastguard Worker static void chppGnssControlMeasurementSessionResult(
146*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len);
147*84e33947SAndroid Build Coastguard Worker static void chppGnssConfigurePassiveLocationListenerResult(
148*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len);
149*84e33947SAndroid Build Coastguard Worker 
150*84e33947SAndroid Build Coastguard Worker static void chppGnssStateResyncNotification(
151*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len);
152*84e33947SAndroid Build Coastguard Worker static void chppGnssLocationResultNotification(
153*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len);
154*84e33947SAndroid Build Coastguard Worker static void chppGnssMeasurementResultNotification(
155*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len);
156*84e33947SAndroid Build Coastguard Worker 
157*84e33947SAndroid Build Coastguard Worker /************************************************
158*84e33947SAndroid Build Coastguard Worker  *  Private Functions
159*84e33947SAndroid Build Coastguard Worker  ***********************************************/
160*84e33947SAndroid Build Coastguard Worker 
161*84e33947SAndroid Build Coastguard Worker /**
162*84e33947SAndroid Build Coastguard Worker  * Dispatches a service response from the transport layer that is determined to
163*84e33947SAndroid Build Coastguard Worker  * be for the GNSS client.
164*84e33947SAndroid Build Coastguard Worker  *
165*84e33947SAndroid Build Coastguard Worker  * This function is called from the app layer using its function pointer given
166*84e33947SAndroid Build Coastguard Worker  * during client registration.
167*84e33947SAndroid Build Coastguard Worker  *
168*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
169*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
170*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
171*84e33947SAndroid Build Coastguard Worker  *
172*84e33947SAndroid Build Coastguard Worker  * @return Indicates the result of this function call.
173*84e33947SAndroid Build Coastguard Worker  */
chppDispatchGnssResponse(void * clientContext,uint8_t * buf,size_t len)174*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppDispatchGnssResponse(void *clientContext,
175*84e33947SAndroid Build Coastguard Worker                                                       uint8_t *buf,
176*84e33947SAndroid Build Coastguard Worker                                                       size_t len) {
177*84e33947SAndroid Build Coastguard Worker   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
178*84e33947SAndroid Build Coastguard Worker   struct ChppGnssClientState *gnssClientContext =
179*84e33947SAndroid Build Coastguard Worker       (struct ChppGnssClientState *)clientContext;
180*84e33947SAndroid Build Coastguard Worker   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
181*84e33947SAndroid Build Coastguard Worker 
182*84e33947SAndroid Build Coastguard Worker   if (rxHeader->command > CHPP_GNSS_CLIENT_REQUEST_MAX) {
183*84e33947SAndroid Build Coastguard Worker     error = CHPP_APP_ERROR_INVALID_COMMAND;
184*84e33947SAndroid Build Coastguard Worker 
185*84e33947SAndroid Build Coastguard Worker   } else if (!chppTimestampIncomingResponse(
186*84e33947SAndroid Build Coastguard Worker                  gnssClientContext->client.appContext,
187*84e33947SAndroid Build Coastguard Worker                  &gnssClientContext->outReqStates[rxHeader->command],
188*84e33947SAndroid Build Coastguard Worker                  rxHeader)) {
189*84e33947SAndroid Build Coastguard Worker     error = CHPP_APP_ERROR_UNEXPECTED_RESPONSE;
190*84e33947SAndroid Build Coastguard Worker 
191*84e33947SAndroid Build Coastguard Worker   } else {
192*84e33947SAndroid Build Coastguard Worker     switch (rxHeader->command) {
193*84e33947SAndroid Build Coastguard Worker       case CHPP_GNSS_OPEN: {
194*84e33947SAndroid Build Coastguard Worker         chppClientProcessOpenResponse(&gnssClientContext->client, buf, len);
195*84e33947SAndroid Build Coastguard Worker         if (rxHeader->error == CHPP_APP_ERROR_NONE &&
196*84e33947SAndroid Build Coastguard Worker             gnssClientContext->requestStateResyncPending) {
197*84e33947SAndroid Build Coastguard Worker           gCallbacks->requestStateResync();
198*84e33947SAndroid Build Coastguard Worker           gnssClientContext->requestStateResyncPending = false;
199*84e33947SAndroid Build Coastguard Worker         }
200*84e33947SAndroid Build Coastguard Worker         break;
201*84e33947SAndroid Build Coastguard Worker       }
202*84e33947SAndroid Build Coastguard Worker 
203*84e33947SAndroid Build Coastguard Worker       case CHPP_GNSS_CLOSE: {
204*84e33947SAndroid Build Coastguard Worker         chppGnssCloseResult(gnssClientContext, buf, len);
205*84e33947SAndroid Build Coastguard Worker         break;
206*84e33947SAndroid Build Coastguard Worker       }
207*84e33947SAndroid Build Coastguard Worker 
208*84e33947SAndroid Build Coastguard Worker       case CHPP_GNSS_GET_CAPABILITIES: {
209*84e33947SAndroid Build Coastguard Worker         chppGnssGetCapabilitiesResult(gnssClientContext, buf, len);
210*84e33947SAndroid Build Coastguard Worker         break;
211*84e33947SAndroid Build Coastguard Worker       }
212*84e33947SAndroid Build Coastguard Worker 
213*84e33947SAndroid Build Coastguard Worker       case CHPP_GNSS_CONTROL_LOCATION_SESSION: {
214*84e33947SAndroid Build Coastguard Worker         chppGnssControlLocationSessionResult(gnssClientContext, buf, len);
215*84e33947SAndroid Build Coastguard Worker         break;
216*84e33947SAndroid Build Coastguard Worker       }
217*84e33947SAndroid Build Coastguard Worker 
218*84e33947SAndroid Build Coastguard Worker       case CHPP_GNSS_CONTROL_MEASUREMENT_SESSION: {
219*84e33947SAndroid Build Coastguard Worker         chppGnssControlMeasurementSessionResult(gnssClientContext, buf, len);
220*84e33947SAndroid Build Coastguard Worker         break;
221*84e33947SAndroid Build Coastguard Worker       }
222*84e33947SAndroid Build Coastguard Worker 
223*84e33947SAndroid Build Coastguard Worker       case CHPP_GNSS_CONFIGURE_PASSIVE_LOCATION_LISTENER: {
224*84e33947SAndroid Build Coastguard Worker         chppGnssConfigurePassiveLocationListenerResult(gnssClientContext, buf,
225*84e33947SAndroid Build Coastguard Worker                                                        len);
226*84e33947SAndroid Build Coastguard Worker         break;
227*84e33947SAndroid Build Coastguard Worker       }
228*84e33947SAndroid Build Coastguard Worker 
229*84e33947SAndroid Build Coastguard Worker       default: {
230*84e33947SAndroid Build Coastguard Worker         error = CHPP_APP_ERROR_INVALID_COMMAND;
231*84e33947SAndroid Build Coastguard Worker         break;
232*84e33947SAndroid Build Coastguard Worker       }
233*84e33947SAndroid Build Coastguard Worker     }
234*84e33947SAndroid Build Coastguard Worker   }
235*84e33947SAndroid Build Coastguard Worker 
236*84e33947SAndroid Build Coastguard Worker   return error;
237*84e33947SAndroid Build Coastguard Worker }
238*84e33947SAndroid Build Coastguard Worker 
239*84e33947SAndroid Build Coastguard Worker /**
240*84e33947SAndroid Build Coastguard Worker  * Dispatches a service notification from the transport layer that is determined
241*84e33947SAndroid Build Coastguard Worker  * to be for the GNSS client.
242*84e33947SAndroid Build Coastguard Worker  *
243*84e33947SAndroid Build Coastguard Worker  * This function is called from the app layer using its function pointer given
244*84e33947SAndroid Build Coastguard Worker  * during client registration.
245*84e33947SAndroid Build Coastguard Worker  *
246*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
247*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
248*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
249*84e33947SAndroid Build Coastguard Worker  *
250*84e33947SAndroid Build Coastguard Worker  * @return Indicates the result of this function call.
251*84e33947SAndroid Build Coastguard Worker  */
chppDispatchGnssNotification(void * clientContext,uint8_t * buf,size_t len)252*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppDispatchGnssNotification(void *clientContext,
253*84e33947SAndroid Build Coastguard Worker                                                           uint8_t *buf,
254*84e33947SAndroid Build Coastguard Worker                                                           size_t len) {
255*84e33947SAndroid Build Coastguard Worker   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
256*84e33947SAndroid Build Coastguard Worker   struct ChppGnssClientState *gnssClientContext =
257*84e33947SAndroid Build Coastguard Worker       (struct ChppGnssClientState *)clientContext;
258*84e33947SAndroid Build Coastguard Worker   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
259*84e33947SAndroid Build Coastguard Worker 
260*84e33947SAndroid Build Coastguard Worker   switch (rxHeader->command) {
261*84e33947SAndroid Build Coastguard Worker     case CHPP_GNSS_REQUEST_STATE_RESYNC_NOTIFICATION: {
262*84e33947SAndroid Build Coastguard Worker       chppGnssStateResyncNotification(gnssClientContext, buf, len);
263*84e33947SAndroid Build Coastguard Worker       break;
264*84e33947SAndroid Build Coastguard Worker     }
265*84e33947SAndroid Build Coastguard Worker 
266*84e33947SAndroid Build Coastguard Worker     case CHPP_GNSS_LOCATION_RESULT_NOTIFICATION: {
267*84e33947SAndroid Build Coastguard Worker       chppGnssLocationResultNotification(gnssClientContext, buf, len);
268*84e33947SAndroid Build Coastguard Worker       break;
269*84e33947SAndroid Build Coastguard Worker     }
270*84e33947SAndroid Build Coastguard Worker 
271*84e33947SAndroid Build Coastguard Worker     case CHPP_GNSS_MEASUREMENT_RESULT_NOTIFICATION: {
272*84e33947SAndroid Build Coastguard Worker       chppGnssMeasurementResultNotification(gnssClientContext, buf, len);
273*84e33947SAndroid Build Coastguard Worker       break;
274*84e33947SAndroid Build Coastguard Worker     }
275*84e33947SAndroid Build Coastguard Worker 
276*84e33947SAndroid Build Coastguard Worker     default: {
277*84e33947SAndroid Build Coastguard Worker       error = CHPP_APP_ERROR_INVALID_COMMAND;
278*84e33947SAndroid Build Coastguard Worker       break;
279*84e33947SAndroid Build Coastguard Worker     }
280*84e33947SAndroid Build Coastguard Worker   }
281*84e33947SAndroid Build Coastguard Worker 
282*84e33947SAndroid Build Coastguard Worker   return error;
283*84e33947SAndroid Build Coastguard Worker }
284*84e33947SAndroid Build Coastguard Worker 
285*84e33947SAndroid Build Coastguard Worker /**
286*84e33947SAndroid Build Coastguard Worker  * Initializes the client and provides its handle number and the version of the
287*84e33947SAndroid Build Coastguard Worker  * matched service when/if it the client is matched with a service during
288*84e33947SAndroid Build Coastguard Worker  * discovery.
289*84e33947SAndroid Build Coastguard Worker  *
290*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
291*84e33947SAndroid Build Coastguard Worker  * @param handle Handle number for this client.
292*84e33947SAndroid Build Coastguard Worker  * @param serviceVersion Version of the matched service.
293*84e33947SAndroid Build Coastguard Worker  *
294*84e33947SAndroid Build Coastguard Worker  * @return True if client is compatible and successfully initialized.
295*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientInit(void * clientContext,uint8_t handle,struct ChppVersion serviceVersion)296*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientInit(void *clientContext, uint8_t handle,
297*84e33947SAndroid Build Coastguard Worker                                struct ChppVersion serviceVersion) {
298*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(serviceVersion);
299*84e33947SAndroid Build Coastguard Worker 
300*84e33947SAndroid Build Coastguard Worker   struct ChppGnssClientState *gnssClientContext =
301*84e33947SAndroid Build Coastguard Worker       (struct ChppGnssClientState *)clientContext;
302*84e33947SAndroid Build Coastguard Worker   chppClientInit(&gnssClientContext->client, handle);
303*84e33947SAndroid Build Coastguard Worker 
304*84e33947SAndroid Build Coastguard Worker   return true;
305*84e33947SAndroid Build Coastguard Worker }
306*84e33947SAndroid Build Coastguard Worker 
307*84e33947SAndroid Build Coastguard Worker /**
308*84e33947SAndroid Build Coastguard Worker  * Deinitializes the client.
309*84e33947SAndroid Build Coastguard Worker  *
310*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
311*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientDeinit(void * clientContext)312*84e33947SAndroid Build Coastguard Worker static void chppGnssClientDeinit(void *clientContext) {
313*84e33947SAndroid Build Coastguard Worker   struct ChppGnssClientState *gnssClientContext =
314*84e33947SAndroid Build Coastguard Worker       (struct ChppGnssClientState *)clientContext;
315*84e33947SAndroid Build Coastguard Worker   chppClientDeinit(&gnssClientContext->client);
316*84e33947SAndroid Build Coastguard Worker }
317*84e33947SAndroid Build Coastguard Worker 
318*84e33947SAndroid Build Coastguard Worker /**
319*84e33947SAndroid Build Coastguard Worker  * Notifies the client of an incoming reset.
320*84e33947SAndroid Build Coastguard Worker  *
321*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
322*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientNotifyReset(void * clientContext)323*84e33947SAndroid Build Coastguard Worker static void chppGnssClientNotifyReset(void *clientContext) {
324*84e33947SAndroid Build Coastguard Worker   struct ChppGnssClientState *gnssClientContext =
325*84e33947SAndroid Build Coastguard Worker       (struct ChppGnssClientState *)clientContext;
326*84e33947SAndroid Build Coastguard Worker 
327*84e33947SAndroid Build Coastguard Worker   chppClientCloseOpenRequests(&gnssClientContext->client, &kGnssClientConfig,
328*84e33947SAndroid Build Coastguard Worker                               false /* clearOnly */);
329*84e33947SAndroid Build Coastguard Worker 
330*84e33947SAndroid Build Coastguard Worker   CHPP_LOGD("GNSS client reopening from state=%" PRIu8,
331*84e33947SAndroid Build Coastguard Worker             gnssClientContext->client.openState);
332*84e33947SAndroid Build Coastguard Worker   gnssClientContext->requestStateResyncPending = true;
333*84e33947SAndroid Build Coastguard Worker   chppClientSendOpenRequest(&gGnssClientContext.client,
334*84e33947SAndroid Build Coastguard Worker                             &gGnssClientContext.outReqStates[CHPP_GNSS_OPEN],
335*84e33947SAndroid Build Coastguard Worker                             CHPP_GNSS_OPEN,
336*84e33947SAndroid Build Coastguard Worker                             /*blocking=*/false);
337*84e33947SAndroid Build Coastguard Worker }
338*84e33947SAndroid Build Coastguard Worker 
339*84e33947SAndroid Build Coastguard Worker /**
340*84e33947SAndroid Build Coastguard Worker  * Notifies the client of being matched to a service.
341*84e33947SAndroid Build Coastguard Worker  *
342*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
343*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientNotifyMatch(void * clientContext)344*84e33947SAndroid Build Coastguard Worker static void chppGnssClientNotifyMatch(void *clientContext) {
345*84e33947SAndroid Build Coastguard Worker   struct ChppGnssClientState *gnssClientContext =
346*84e33947SAndroid Build Coastguard Worker       (struct ChppGnssClientState *)clientContext;
347*84e33947SAndroid Build Coastguard Worker 
348*84e33947SAndroid Build Coastguard Worker   if (gnssClientContext->client.pseudoOpen) {
349*84e33947SAndroid Build Coastguard Worker     CHPP_LOGD("Pseudo-open GNSS client opening");
350*84e33947SAndroid Build Coastguard Worker     chppClientSendOpenRequest(&gGnssClientContext.client,
351*84e33947SAndroid Build Coastguard Worker                               &gGnssClientContext.outReqStates[CHPP_GNSS_OPEN],
352*84e33947SAndroid Build Coastguard Worker                               CHPP_GNSS_OPEN,
353*84e33947SAndroid Build Coastguard Worker                               /*blocking=*/false);
354*84e33947SAndroid Build Coastguard Worker   }
355*84e33947SAndroid Build Coastguard Worker }
356*84e33947SAndroid Build Coastguard Worker 
357*84e33947SAndroid Build Coastguard Worker /**
358*84e33947SAndroid Build Coastguard Worker  * Handles the service response for the close client request.
359*84e33947SAndroid Build Coastguard Worker  *
360*84e33947SAndroid Build Coastguard Worker  * This function is called from chppDispatchGnssResponse().
361*84e33947SAndroid Build Coastguard Worker  *
362*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
363*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
364*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
365*84e33947SAndroid Build Coastguard Worker  */
chppGnssCloseResult(struct ChppGnssClientState * clientContext,uint8_t * buf,size_t len)366*84e33947SAndroid Build Coastguard Worker static void chppGnssCloseResult(struct ChppGnssClientState *clientContext,
367*84e33947SAndroid Build Coastguard Worker                                 uint8_t *buf, size_t len) {
368*84e33947SAndroid Build Coastguard Worker   // TODO
369*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(clientContext);
370*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(buf);
371*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(len);
372*84e33947SAndroid Build Coastguard Worker }
373*84e33947SAndroid Build Coastguard Worker 
374*84e33947SAndroid Build Coastguard Worker /**
375*84e33947SAndroid Build Coastguard Worker  * Handles the service response for the get capabilities client request.
376*84e33947SAndroid Build Coastguard Worker  *
377*84e33947SAndroid Build Coastguard Worker  * This function is called from chppDispatchGnssResponse().
378*84e33947SAndroid Build Coastguard Worker  *
379*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
380*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
381*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
382*84e33947SAndroid Build Coastguard Worker  */
chppGnssGetCapabilitiesResult(struct ChppGnssClientState * clientContext,uint8_t * buf,size_t len)383*84e33947SAndroid Build Coastguard Worker static void chppGnssGetCapabilitiesResult(
384*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len) {
385*84e33947SAndroid Build Coastguard Worker   if (len < sizeof(struct ChppGnssGetCapabilitiesResponse)) {
386*84e33947SAndroid Build Coastguard Worker     CHPP_LOGE("Bad GNSS capabilities len=%" PRIuSIZE, len);
387*84e33947SAndroid Build Coastguard Worker 
388*84e33947SAndroid Build Coastguard Worker   } else {
389*84e33947SAndroid Build Coastguard Worker     struct ChppGnssGetCapabilitiesParameters *result =
390*84e33947SAndroid Build Coastguard Worker         &((struct ChppGnssGetCapabilitiesResponse *)buf)->params;
391*84e33947SAndroid Build Coastguard Worker 
392*84e33947SAndroid Build Coastguard Worker     CHPP_LOGD("chppGnssGetCapabilitiesResult received capabilities=0x%" PRIx32,
393*84e33947SAndroid Build Coastguard Worker               result->capabilities);
394*84e33947SAndroid Build Coastguard Worker 
395*84e33947SAndroid Build Coastguard Worker     CHPP_ASSERT((result->capabilities & CHPP_GNSS_DEFAULT_CAPABILITIES) ==
396*84e33947SAndroid Build Coastguard Worker                 CHPP_GNSS_DEFAULT_CAPABILITIES);
397*84e33947SAndroid Build Coastguard Worker     if (result->capabilities != CHPP_GNSS_DEFAULT_CAPABILITIES) {
398*84e33947SAndroid Build Coastguard Worker       CHPP_LOGE("GNSS capabilities 0x%" PRIx32 " != 0x%" PRIx32,
399*84e33947SAndroid Build Coastguard Worker                 result->capabilities, (uint32_t)CHPP_GNSS_DEFAULT_CAPABILITIES);
400*84e33947SAndroid Build Coastguard Worker     }
401*84e33947SAndroid Build Coastguard Worker 
402*84e33947SAndroid Build Coastguard Worker     clientContext->capabilitiesValid = true;
403*84e33947SAndroid Build Coastguard Worker     clientContext->capabilities = result->capabilities;
404*84e33947SAndroid Build Coastguard Worker   }
405*84e33947SAndroid Build Coastguard Worker }
406*84e33947SAndroid Build Coastguard Worker 
407*84e33947SAndroid Build Coastguard Worker /**
408*84e33947SAndroid Build Coastguard Worker  * Handles the service response for the Control Location Session client request.
409*84e33947SAndroid Build Coastguard Worker  *
410*84e33947SAndroid Build Coastguard Worker  * This function is called from chppDispatchGnssResponse().
411*84e33947SAndroid Build Coastguard Worker  *
412*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
413*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
414*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
415*84e33947SAndroid Build Coastguard Worker  */
chppGnssControlLocationSessionResult(struct ChppGnssClientState * clientContext,uint8_t * buf,size_t len)416*84e33947SAndroid Build Coastguard Worker static void chppGnssControlLocationSessionResult(
417*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len) {
418*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(clientContext);
419*84e33947SAndroid Build Coastguard Worker 
420*84e33947SAndroid Build Coastguard Worker   if (len < sizeof(struct ChppGnssControlLocationSessionResponse)) {
421*84e33947SAndroid Build Coastguard Worker     // Short response length indicates an error
422*84e33947SAndroid Build Coastguard Worker     gCallbacks->locationStatusChangeCallback(
423*84e33947SAndroid Build Coastguard Worker         false, chppAppShortResponseErrorHandler(buf, len, "ControlLocation"));
424*84e33947SAndroid Build Coastguard Worker 
425*84e33947SAndroid Build Coastguard Worker   } else {
426*84e33947SAndroid Build Coastguard Worker     struct ChppGnssControlLocationSessionResponse *result =
427*84e33947SAndroid Build Coastguard Worker         (struct ChppGnssControlLocationSessionResponse *)buf;
428*84e33947SAndroid Build Coastguard Worker 
429*84e33947SAndroid Build Coastguard Worker     CHPP_LOGD(
430*84e33947SAndroid Build Coastguard Worker         "chppGnssControlLocationSessionResult received enable=%d, "
431*84e33947SAndroid Build Coastguard Worker         "errorCode=%" PRIu8,
432*84e33947SAndroid Build Coastguard Worker         result->enabled, result->errorCode);
433*84e33947SAndroid Build Coastguard Worker 
434*84e33947SAndroid Build Coastguard Worker     gCallbacks->locationStatusChangeCallback(result->enabled,
435*84e33947SAndroid Build Coastguard Worker                                              result->errorCode);
436*84e33947SAndroid Build Coastguard Worker   }
437*84e33947SAndroid Build Coastguard Worker }
438*84e33947SAndroid Build Coastguard Worker 
439*84e33947SAndroid Build Coastguard Worker /**
440*84e33947SAndroid Build Coastguard Worker  * Handles the service response for the Control Measurement Session client
441*84e33947SAndroid Build Coastguard Worker  * request.
442*84e33947SAndroid Build Coastguard Worker  *
443*84e33947SAndroid Build Coastguard Worker  * This function is called from chppDispatchGnssResponse().
444*84e33947SAndroid Build Coastguard Worker  *
445*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
446*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
447*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
448*84e33947SAndroid Build Coastguard Worker  */
chppGnssControlMeasurementSessionResult(struct ChppGnssClientState * clientContext,uint8_t * buf,size_t len)449*84e33947SAndroid Build Coastguard Worker static void chppGnssControlMeasurementSessionResult(
450*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len) {
451*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(clientContext);
452*84e33947SAndroid Build Coastguard Worker 
453*84e33947SAndroid Build Coastguard Worker   if (len < sizeof(struct ChppGnssControlMeasurementSessionResponse)) {
454*84e33947SAndroid Build Coastguard Worker     // Short response length indicates an error
455*84e33947SAndroid Build Coastguard Worker     gCallbacks->measurementStatusChangeCallback(
456*84e33947SAndroid Build Coastguard Worker         false, chppAppShortResponseErrorHandler(buf, len, "Measurement"));
457*84e33947SAndroid Build Coastguard Worker 
458*84e33947SAndroid Build Coastguard Worker   } else {
459*84e33947SAndroid Build Coastguard Worker     struct ChppGnssControlMeasurementSessionResponse *result =
460*84e33947SAndroid Build Coastguard Worker         (struct ChppGnssControlMeasurementSessionResponse *)buf;
461*84e33947SAndroid Build Coastguard Worker 
462*84e33947SAndroid Build Coastguard Worker     CHPP_LOGD(
463*84e33947SAndroid Build Coastguard Worker         "chppGnssControlMeasurementSessionResult received enable=%d, "
464*84e33947SAndroid Build Coastguard Worker         "errorCode=%" PRIu8,
465*84e33947SAndroid Build Coastguard Worker         result->enabled, result->errorCode);
466*84e33947SAndroid Build Coastguard Worker 
467*84e33947SAndroid Build Coastguard Worker     gCallbacks->measurementStatusChangeCallback(result->enabled,
468*84e33947SAndroid Build Coastguard Worker                                                 result->errorCode);
469*84e33947SAndroid Build Coastguard Worker   }
470*84e33947SAndroid Build Coastguard Worker }
471*84e33947SAndroid Build Coastguard Worker 
472*84e33947SAndroid Build Coastguard Worker /**
473*84e33947SAndroid Build Coastguard Worker  * Handles the service response for the Configure Passive Location Listener
474*84e33947SAndroid Build Coastguard Worker  * client request.
475*84e33947SAndroid Build Coastguard Worker  *
476*84e33947SAndroid Build Coastguard Worker  * This function is called from chppDispatchGnssResponse().
477*84e33947SAndroid Build Coastguard Worker  *
478*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
479*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
480*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
481*84e33947SAndroid Build Coastguard Worker  */
chppGnssConfigurePassiveLocationListenerResult(struct ChppGnssClientState * clientContext,uint8_t * buf,size_t len)482*84e33947SAndroid Build Coastguard Worker static void chppGnssConfigurePassiveLocationListenerResult(
483*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len) {
484*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(clientContext);
485*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(len);
486*84e33947SAndroid Build Coastguard Worker 
487*84e33947SAndroid Build Coastguard Worker   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
488*84e33947SAndroid Build Coastguard Worker 
489*84e33947SAndroid Build Coastguard Worker   if (rxHeader->error != CHPP_APP_ERROR_NONE) {
490*84e33947SAndroid Build Coastguard Worker     CHPP_DEBUG_ASSERT_LOG(false, "Passive scan failed at service");
491*84e33947SAndroid Build Coastguard Worker 
492*84e33947SAndroid Build Coastguard Worker   } else {
493*84e33947SAndroid Build Coastguard Worker     CHPP_LOGD(
494*84e33947SAndroid Build Coastguard Worker         "WiFi ConfigurePassiveLocationListener request accepted at service");
495*84e33947SAndroid Build Coastguard Worker   }
496*84e33947SAndroid Build Coastguard Worker }
497*84e33947SAndroid Build Coastguard Worker 
498*84e33947SAndroid Build Coastguard Worker /**
499*84e33947SAndroid Build Coastguard Worker  * Handles the State Resync service notification.
500*84e33947SAndroid Build Coastguard Worker  *
501*84e33947SAndroid Build Coastguard Worker  * This function is called from chppDispatchGnssNotification().
502*84e33947SAndroid Build Coastguard Worker  *
503*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
504*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
505*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
506*84e33947SAndroid Build Coastguard Worker  */
chppGnssStateResyncNotification(struct ChppGnssClientState * clientContext,uint8_t * buf,size_t len)507*84e33947SAndroid Build Coastguard Worker static void chppGnssStateResyncNotification(
508*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len) {
509*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(buf);
510*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(len);
511*84e33947SAndroid Build Coastguard Worker   if (clientContext->client.openState == CHPP_OPEN_STATE_WAITING_TO_OPEN) {
512*84e33947SAndroid Build Coastguard Worker     // If the GNSS client is waiting for the open to proceed, the CHRE handler
513*84e33947SAndroid Build Coastguard Worker     // for requestStateResync() may fail, so we set a flag to process it later
514*84e33947SAndroid Build Coastguard Worker     // when the open has succeeded.
515*84e33947SAndroid Build Coastguard Worker     clientContext->requestStateResyncPending = true;
516*84e33947SAndroid Build Coastguard Worker   } else {
517*84e33947SAndroid Build Coastguard Worker     gCallbacks->requestStateResync();
518*84e33947SAndroid Build Coastguard Worker     clientContext->requestStateResyncPending = false;
519*84e33947SAndroid Build Coastguard Worker   }
520*84e33947SAndroid Build Coastguard Worker }
521*84e33947SAndroid Build Coastguard Worker 
522*84e33947SAndroid Build Coastguard Worker /**
523*84e33947SAndroid Build Coastguard Worker  * Handles the Location Result service notification.
524*84e33947SAndroid Build Coastguard Worker  *
525*84e33947SAndroid Build Coastguard Worker  * This function is called from chppDispatchGnssNotification().
526*84e33947SAndroid Build Coastguard Worker  *
527*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
528*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
529*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
530*84e33947SAndroid Build Coastguard Worker  */
chppGnssLocationResultNotification(struct ChppGnssClientState * clientContext,uint8_t * buf,size_t len)531*84e33947SAndroid Build Coastguard Worker static void chppGnssLocationResultNotification(
532*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len) {
533*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(clientContext);
534*84e33947SAndroid Build Coastguard Worker   CHPP_LOGD("chppGnssLocationResultNotification received data len=%" PRIuSIZE,
535*84e33947SAndroid Build Coastguard Worker             len);
536*84e33947SAndroid Build Coastguard Worker 
537*84e33947SAndroid Build Coastguard Worker   buf += sizeof(struct ChppAppHeader);
538*84e33947SAndroid Build Coastguard Worker   len -= sizeof(struct ChppAppHeader);
539*84e33947SAndroid Build Coastguard Worker 
540*84e33947SAndroid Build Coastguard Worker   struct chreGnssLocationEvent *chre =
541*84e33947SAndroid Build Coastguard Worker       chppGnssLocationEventToChre((struct ChppGnssLocationEvent *)buf, len);
542*84e33947SAndroid Build Coastguard Worker 
543*84e33947SAndroid Build Coastguard Worker   if (chre == NULL) {
544*84e33947SAndroid Build Coastguard Worker     CHPP_LOGE("Location result conversion failed: len=%" PRIuSIZE, len);
545*84e33947SAndroid Build Coastguard Worker   } else {
546*84e33947SAndroid Build Coastguard Worker     gCallbacks->locationEventCallback(chre);
547*84e33947SAndroid Build Coastguard Worker   }
548*84e33947SAndroid Build Coastguard Worker }
549*84e33947SAndroid Build Coastguard Worker 
550*84e33947SAndroid Build Coastguard Worker /**
551*84e33947SAndroid Build Coastguard Worker  * Handles the Measurement Result service notification.
552*84e33947SAndroid Build Coastguard Worker  *
553*84e33947SAndroid Build Coastguard Worker  * This function is called from chppDispatchGnssNotification().
554*84e33947SAndroid Build Coastguard Worker  *
555*84e33947SAndroid Build Coastguard Worker  * @param clientContext Maintains status for each client instance.
556*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
557*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
558*84e33947SAndroid Build Coastguard Worker  */
chppGnssMeasurementResultNotification(struct ChppGnssClientState * clientContext,uint8_t * buf,size_t len)559*84e33947SAndroid Build Coastguard Worker static void chppGnssMeasurementResultNotification(
560*84e33947SAndroid Build Coastguard Worker     struct ChppGnssClientState *clientContext, uint8_t *buf, size_t len) {
561*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(clientContext);
562*84e33947SAndroid Build Coastguard Worker   CHPP_LOGD(
563*84e33947SAndroid Build Coastguard Worker       "chppGnssMeasurementResultNotification received data len=%" PRIuSIZE,
564*84e33947SAndroid Build Coastguard Worker       len);
565*84e33947SAndroid Build Coastguard Worker 
566*84e33947SAndroid Build Coastguard Worker   buf += sizeof(struct ChppAppHeader);
567*84e33947SAndroid Build Coastguard Worker   len -= sizeof(struct ChppAppHeader);
568*84e33947SAndroid Build Coastguard Worker 
569*84e33947SAndroid Build Coastguard Worker   struct chreGnssDataEvent *chre =
570*84e33947SAndroid Build Coastguard Worker       chppGnssDataEventToChre((struct ChppGnssDataEvent *)buf, len);
571*84e33947SAndroid Build Coastguard Worker 
572*84e33947SAndroid Build Coastguard Worker   if (chre == NULL) {
573*84e33947SAndroid Build Coastguard Worker     CHPP_LOGE("Measurement result conversion failed len=%" PRIuSIZE, len);
574*84e33947SAndroid Build Coastguard Worker   } else {
575*84e33947SAndroid Build Coastguard Worker     gCallbacks->measurementEventCallback(chre);
576*84e33947SAndroid Build Coastguard Worker   }
577*84e33947SAndroid Build Coastguard Worker }
578*84e33947SAndroid Build Coastguard Worker 
579*84e33947SAndroid Build Coastguard Worker /**
580*84e33947SAndroid Build Coastguard Worker  * Initializes the GNSS client upon an open request from CHRE and responds
581*84e33947SAndroid Build Coastguard Worker  * with the result.
582*84e33947SAndroid Build Coastguard Worker  *
583*84e33947SAndroid Build Coastguard Worker  * @param systemApi CHRE system function pointers.
584*84e33947SAndroid Build Coastguard Worker  * @param callbacks CHRE entry points.
585*84e33947SAndroid Build Coastguard Worker  *
586*84e33947SAndroid Build Coastguard Worker  * @return True if successful. False otherwise.
587*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientOpen(const struct chrePalSystemApi * systemApi,const struct chrePalGnssCallbacks * callbacks)588*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientOpen(const struct chrePalSystemApi *systemApi,
589*84e33947SAndroid Build Coastguard Worker                                const struct chrePalGnssCallbacks *callbacks) {
590*84e33947SAndroid Build Coastguard Worker   CHPP_DEBUG_NOT_NULL(systemApi);
591*84e33947SAndroid Build Coastguard Worker   CHPP_DEBUG_NOT_NULL(callbacks);
592*84e33947SAndroid Build Coastguard Worker 
593*84e33947SAndroid Build Coastguard Worker   bool result = false;
594*84e33947SAndroid Build Coastguard Worker   gSystemApi = systemApi;
595*84e33947SAndroid Build Coastguard Worker   gCallbacks = callbacks;
596*84e33947SAndroid Build Coastguard Worker 
597*84e33947SAndroid Build Coastguard Worker   CHPP_LOGD("GNSS client opening");
598*84e33947SAndroid Build Coastguard Worker   if (gGnssClientContext.client.appContext == NULL) {
599*84e33947SAndroid Build Coastguard Worker     CHPP_LOGE("GNSS client app is null");
600*84e33947SAndroid Build Coastguard Worker   } else {
601*84e33947SAndroid Build Coastguard Worker     if (chppWaitForDiscoveryComplete(gGnssClientContext.client.appContext,
602*84e33947SAndroid Build Coastguard Worker                                      CHPP_GNSS_DISCOVERY_TIMEOUT_MS)) {
603*84e33947SAndroid Build Coastguard Worker       result = chppClientSendOpenRequest(
604*84e33947SAndroid Build Coastguard Worker           &gGnssClientContext.client,
605*84e33947SAndroid Build Coastguard Worker           &gGnssClientContext.outReqStates[CHPP_GNSS_OPEN], CHPP_GNSS_OPEN,
606*84e33947SAndroid Build Coastguard Worker           /*blocking=*/true);
607*84e33947SAndroid Build Coastguard Worker     }
608*84e33947SAndroid Build Coastguard Worker 
609*84e33947SAndroid Build Coastguard Worker     // Since CHPP_GNSS_DEFAULT_CAPABILITIES is mandatory, we can always
610*84e33947SAndroid Build Coastguard Worker     // pseudo-open and return true. Otherwise, these should have been gated.
611*84e33947SAndroid Build Coastguard Worker     chppClientPseudoOpen(&gGnssClientContext.client);
612*84e33947SAndroid Build Coastguard Worker     result = true;
613*84e33947SAndroid Build Coastguard Worker   }
614*84e33947SAndroid Build Coastguard Worker 
615*84e33947SAndroid Build Coastguard Worker   return result;
616*84e33947SAndroid Build Coastguard Worker }
617*84e33947SAndroid Build Coastguard Worker 
618*84e33947SAndroid Build Coastguard Worker /**
619*84e33947SAndroid Build Coastguard Worker  * Deinitializes the GNSS client.
620*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientClose(void)621*84e33947SAndroid Build Coastguard Worker static void chppGnssClientClose(void) {
622*84e33947SAndroid Build Coastguard Worker   // Remote
623*84e33947SAndroid Build Coastguard Worker   struct ChppAppHeader *request = chppAllocClientRequestCommand(
624*84e33947SAndroid Build Coastguard Worker       &gGnssClientContext.client, CHPP_GNSS_CLOSE);
625*84e33947SAndroid Build Coastguard Worker 
626*84e33947SAndroid Build Coastguard Worker   if (request == NULL) {
627*84e33947SAndroid Build Coastguard Worker     CHPP_LOG_OOM();
628*84e33947SAndroid Build Coastguard Worker   } else if (chppClientSendTimestampedRequestAndWait(
629*84e33947SAndroid Build Coastguard Worker                  &gGnssClientContext.client,
630*84e33947SAndroid Build Coastguard Worker                  &gGnssClientContext.outReqStates[CHPP_GNSS_CLOSE], request,
631*84e33947SAndroid Build Coastguard Worker                  sizeof(*request))) {
632*84e33947SAndroid Build Coastguard Worker     gGnssClientContext.client.openState = CHPP_OPEN_STATE_CLOSED;
633*84e33947SAndroid Build Coastguard Worker     gGnssClientContext.capabilities = CHRE_GNSS_CAPABILITIES_NONE;
634*84e33947SAndroid Build Coastguard Worker     gGnssClientContext.capabilitiesValid = false;
635*84e33947SAndroid Build Coastguard Worker     chppClientCloseOpenRequests(&gGnssClientContext.client, &kGnssClientConfig,
636*84e33947SAndroid Build Coastguard Worker                                 true /* clearOnly */);
637*84e33947SAndroid Build Coastguard Worker   }
638*84e33947SAndroid Build Coastguard Worker }
639*84e33947SAndroid Build Coastguard Worker 
640*84e33947SAndroid Build Coastguard Worker /**
641*84e33947SAndroid Build Coastguard Worker  * Retrieves a set of flags indicating the GNSS features supported by the
642*84e33947SAndroid Build Coastguard Worker  * current implementation.
643*84e33947SAndroid Build Coastguard Worker  *
644*84e33947SAndroid Build Coastguard Worker  * @return Capabilities flags.
645*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientGetCapabilities(void)646*84e33947SAndroid Build Coastguard Worker static uint32_t chppGnssClientGetCapabilities(void) {
647*84e33947SAndroid Build Coastguard Worker   uint32_t capabilities = CHPP_GNSS_DEFAULT_CAPABILITIES;
648*84e33947SAndroid Build Coastguard Worker 
649*84e33947SAndroid Build Coastguard Worker   if (gGnssClientContext.capabilitiesValid) {
650*84e33947SAndroid Build Coastguard Worker     // Result already cached
651*84e33947SAndroid Build Coastguard Worker     capabilities = gGnssClientContext.capabilities;
652*84e33947SAndroid Build Coastguard Worker 
653*84e33947SAndroid Build Coastguard Worker   } else {
654*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *request = chppAllocClientRequestCommand(
655*84e33947SAndroid Build Coastguard Worker         &gGnssClientContext.client, CHPP_GNSS_GET_CAPABILITIES);
656*84e33947SAndroid Build Coastguard Worker 
657*84e33947SAndroid Build Coastguard Worker     if (request == NULL) {
658*84e33947SAndroid Build Coastguard Worker       CHPP_LOG_OOM();
659*84e33947SAndroid Build Coastguard Worker     } else {
660*84e33947SAndroid Build Coastguard Worker       if (chppClientSendTimestampedRequestAndWait(
661*84e33947SAndroid Build Coastguard Worker               &gGnssClientContext.client,
662*84e33947SAndroid Build Coastguard Worker               &gGnssClientContext.outReqStates[CHPP_GNSS_GET_CAPABILITIES],
663*84e33947SAndroid Build Coastguard Worker               request, sizeof(*request))) {
664*84e33947SAndroid Build Coastguard Worker         // Success. gGnssClientContext.capabilities is now populated
665*84e33947SAndroid Build Coastguard Worker         if (gGnssClientContext.capabilitiesValid) {
666*84e33947SAndroid Build Coastguard Worker           capabilities = gGnssClientContext.capabilities;
667*84e33947SAndroid Build Coastguard Worker         }
668*84e33947SAndroid Build Coastguard Worker       }
669*84e33947SAndroid Build Coastguard Worker     }
670*84e33947SAndroid Build Coastguard Worker   }
671*84e33947SAndroid Build Coastguard Worker 
672*84e33947SAndroid Build Coastguard Worker   return capabilities;
673*84e33947SAndroid Build Coastguard Worker }
674*84e33947SAndroid Build Coastguard Worker 
675*84e33947SAndroid Build Coastguard Worker /**
676*84e33947SAndroid Build Coastguard Worker  * Start/stop/modify the GNSS location session used for clients of the CHRE
677*84e33947SAndroid Build Coastguard Worker  * API.
678*84e33947SAndroid Build Coastguard Worker  *
679*84e33947SAndroid Build Coastguard Worker  * @param enable true to start/modify the session, false to stop the
680*84e33947SAndroid Build Coastguard Worker  *        session. If false, other parameters are ignored.
681*84e33947SAndroid Build Coastguard Worker  * @param minIntervalMs See chreGnssLocationSessionStartAsync()
682*84e33947SAndroid Build Coastguard Worker  * @param minTimeToNextFixMs See chreGnssLocationSessionStartAsync()
683*84e33947SAndroid Build Coastguard Worker  *
684*84e33947SAndroid Build Coastguard Worker  * @return True indicates the request was sent off to the service.
685*84e33947SAndroid Build Coastguard Worker  */
686*84e33947SAndroid Build Coastguard Worker 
chppGnssClientControlLocationSession(bool enable,uint32_t minIntervalMs,uint32_t minTimeToNextFixMs)687*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientControlLocationSession(bool enable,
688*84e33947SAndroid Build Coastguard Worker                                                  uint32_t minIntervalMs,
689*84e33947SAndroid Build Coastguard Worker                                                  uint32_t minTimeToNextFixMs) {
690*84e33947SAndroid Build Coastguard Worker   bool result = false;
691*84e33947SAndroid Build Coastguard Worker 
692*84e33947SAndroid Build Coastguard Worker   struct ChppGnssControlLocationSessionRequest *request =
693*84e33947SAndroid Build Coastguard Worker       chppAllocClientRequestFixed(&gGnssClientContext.client,
694*84e33947SAndroid Build Coastguard Worker                                   struct ChppGnssControlLocationSessionRequest);
695*84e33947SAndroid Build Coastguard Worker 
696*84e33947SAndroid Build Coastguard Worker   if (request == NULL) {
697*84e33947SAndroid Build Coastguard Worker     CHPP_LOG_OOM();
698*84e33947SAndroid Build Coastguard Worker   } else {
699*84e33947SAndroid Build Coastguard Worker     request->header.command = CHPP_GNSS_CONTROL_LOCATION_SESSION;
700*84e33947SAndroid Build Coastguard Worker     request->params.enable = enable;
701*84e33947SAndroid Build Coastguard Worker     request->params.minIntervalMs = minIntervalMs;
702*84e33947SAndroid Build Coastguard Worker     request->params.minTimeToNextFixMs = minTimeToNextFixMs;
703*84e33947SAndroid Build Coastguard Worker 
704*84e33947SAndroid Build Coastguard Worker     result = chppClientSendTimestampedRequestOrFail(
705*84e33947SAndroid Build Coastguard Worker         &gGnssClientContext.client,
706*84e33947SAndroid Build Coastguard Worker         &gGnssClientContext.outReqStates[CHPP_GNSS_CONTROL_LOCATION_SESSION],
707*84e33947SAndroid Build Coastguard Worker         request, sizeof(*request), CHRE_GNSS_ASYNC_RESULT_TIMEOUT_NS);
708*84e33947SAndroid Build Coastguard Worker   }
709*84e33947SAndroid Build Coastguard Worker 
710*84e33947SAndroid Build Coastguard Worker   return result;
711*84e33947SAndroid Build Coastguard Worker }
712*84e33947SAndroid Build Coastguard Worker 
713*84e33947SAndroid Build Coastguard Worker /**
714*84e33947SAndroid Build Coastguard Worker  * Releases the memory held for the location event callback.
715*84e33947SAndroid Build Coastguard Worker  *
716*84e33947SAndroid Build Coastguard Worker  * @param event Location event to be released.
717*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientReleaseLocationEvent(struct chreGnssLocationEvent * event)718*84e33947SAndroid Build Coastguard Worker static void chppGnssClientReleaseLocationEvent(
719*84e33947SAndroid Build Coastguard Worker     struct chreGnssLocationEvent *event) {
720*84e33947SAndroid Build Coastguard Worker   CHPP_FREE_AND_NULLIFY(event);
721*84e33947SAndroid Build Coastguard Worker }
722*84e33947SAndroid Build Coastguard Worker 
723*84e33947SAndroid Build Coastguard Worker /**
724*84e33947SAndroid Build Coastguard Worker  * Start/stop/modify the raw GNSS measurement session used for clients of the
725*84e33947SAndroid Build Coastguard Worker  * CHRE API.
726*84e33947SAndroid Build Coastguard Worker  *
727*84e33947SAndroid Build Coastguard Worker  * @param enable true to start/modify the session, false to stop the
728*84e33947SAndroid Build Coastguard Worker  *        session. If false, other parameters are ignored.
729*84e33947SAndroid Build Coastguard Worker  * @param minIntervalMs See chreGnssMeasurementSessionStartAsync()
730*84e33947SAndroid Build Coastguard Worker  *
731*84e33947SAndroid Build Coastguard Worker  * @return True indicates the request was sent off to the service.
732*84e33947SAndroid Build Coastguard Worker  */
733*84e33947SAndroid Build Coastguard Worker 
chppGnssClientControlMeasurementSession(bool enable,uint32_t minIntervalMs)734*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientControlMeasurementSession(bool enable,
735*84e33947SAndroid Build Coastguard Worker                                                     uint32_t minIntervalMs) {
736*84e33947SAndroid Build Coastguard Worker   bool result = false;
737*84e33947SAndroid Build Coastguard Worker 
738*84e33947SAndroid Build Coastguard Worker   struct ChppGnssControlMeasurementSessionRequest *request =
739*84e33947SAndroid Build Coastguard Worker       chppAllocClientRequestFixed(
740*84e33947SAndroid Build Coastguard Worker           &gGnssClientContext.client,
741*84e33947SAndroid Build Coastguard Worker           struct ChppGnssControlMeasurementSessionRequest);
742*84e33947SAndroid Build Coastguard Worker 
743*84e33947SAndroid Build Coastguard Worker   if (request == NULL) {
744*84e33947SAndroid Build Coastguard Worker     CHPP_LOG_OOM();
745*84e33947SAndroid Build Coastguard Worker   } else {
746*84e33947SAndroid Build Coastguard Worker     request->header.command = CHPP_GNSS_CONTROL_MEASUREMENT_SESSION;
747*84e33947SAndroid Build Coastguard Worker     request->params.enable = enable;
748*84e33947SAndroid Build Coastguard Worker     request->params.minIntervalMs = minIntervalMs;
749*84e33947SAndroid Build Coastguard Worker 
750*84e33947SAndroid Build Coastguard Worker     result = chppClientSendTimestampedRequestOrFail(
751*84e33947SAndroid Build Coastguard Worker         &gGnssClientContext.client,
752*84e33947SAndroid Build Coastguard Worker         &gGnssClientContext.outReqStates[CHPP_GNSS_CONTROL_MEASUREMENT_SESSION],
753*84e33947SAndroid Build Coastguard Worker         request, sizeof(*request), CHRE_GNSS_ASYNC_RESULT_TIMEOUT_NS);
754*84e33947SAndroid Build Coastguard Worker   }
755*84e33947SAndroid Build Coastguard Worker 
756*84e33947SAndroid Build Coastguard Worker   return result;
757*84e33947SAndroid Build Coastguard Worker }
758*84e33947SAndroid Build Coastguard Worker 
759*84e33947SAndroid Build Coastguard Worker /**
760*84e33947SAndroid Build Coastguard Worker  * Releases the memory held for the measurement event callback.
761*84e33947SAndroid Build Coastguard Worker  *
762*84e33947SAndroid Build Coastguard Worker  * @param event Measurement event to be released.
763*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientReleaseMeasurementDataEvent(struct chreGnssDataEvent * event)764*84e33947SAndroid Build Coastguard Worker static void chppGnssClientReleaseMeasurementDataEvent(
765*84e33947SAndroid Build Coastguard Worker     struct chreGnssDataEvent *event) {
766*84e33947SAndroid Build Coastguard Worker   if (event->measurement_count > 0) {
767*84e33947SAndroid Build Coastguard Worker     void *measurements = CHPP_CONST_CAST_POINTER(event->measurements);
768*84e33947SAndroid Build Coastguard Worker     CHPP_FREE_AND_NULLIFY(measurements);
769*84e33947SAndroid Build Coastguard Worker   }
770*84e33947SAndroid Build Coastguard Worker 
771*84e33947SAndroid Build Coastguard Worker   CHPP_FREE_AND_NULLIFY(event);
772*84e33947SAndroid Build Coastguard Worker }
773*84e33947SAndroid Build Coastguard Worker 
774*84e33947SAndroid Build Coastguard Worker /**
775*84e33947SAndroid Build Coastguard Worker  * Starts/stops opportunistic delivery of location fixes.
776*84e33947SAndroid Build Coastguard Worker  *
777*84e33947SAndroid Build Coastguard Worker  * @param enable true to turn the passive location listener on, false to
778*84e33947SAndroid Build Coastguard Worker  *        turn it off.
779*84e33947SAndroid Build Coastguard Worker  *
780*84e33947SAndroid Build Coastguard Worker  * @return True indicates the request was sent off to the service.
781*84e33947SAndroid Build Coastguard Worker  */
chppGnssClientConfigurePassiveLocationListener(bool enable)782*84e33947SAndroid Build Coastguard Worker static bool chppGnssClientConfigurePassiveLocationListener(bool enable) {
783*84e33947SAndroid Build Coastguard Worker   bool result = false;
784*84e33947SAndroid Build Coastguard Worker 
785*84e33947SAndroid Build Coastguard Worker   struct ChppGnssConfigurePassiveLocationListenerRequest *request =
786*84e33947SAndroid Build Coastguard Worker       chppAllocClientRequestFixed(
787*84e33947SAndroid Build Coastguard Worker           &gGnssClientContext.client,
788*84e33947SAndroid Build Coastguard Worker           struct ChppGnssConfigurePassiveLocationListenerRequest);
789*84e33947SAndroid Build Coastguard Worker 
790*84e33947SAndroid Build Coastguard Worker   if (request == NULL) {
791*84e33947SAndroid Build Coastguard Worker     CHPP_LOG_OOM();
792*84e33947SAndroid Build Coastguard Worker   } else {
793*84e33947SAndroid Build Coastguard Worker     request->header.command = CHPP_GNSS_CONFIGURE_PASSIVE_LOCATION_LISTENER;
794*84e33947SAndroid Build Coastguard Worker     request->params.enable = enable;
795*84e33947SAndroid Build Coastguard Worker 
796*84e33947SAndroid Build Coastguard Worker     result = chppClientSendTimestampedRequestOrFail(
797*84e33947SAndroid Build Coastguard Worker         &gGnssClientContext.client,
798*84e33947SAndroid Build Coastguard Worker         &gGnssClientContext
799*84e33947SAndroid Build Coastguard Worker              .outReqStates[CHPP_GNSS_CONFIGURE_PASSIVE_LOCATION_LISTENER],
800*84e33947SAndroid Build Coastguard Worker         request, sizeof(*request), CHPP_REQUEST_TIMEOUT_DEFAULT);
801*84e33947SAndroid Build Coastguard Worker   }
802*84e33947SAndroid Build Coastguard Worker 
803*84e33947SAndroid Build Coastguard Worker   return result;
804*84e33947SAndroid Build Coastguard Worker }
805*84e33947SAndroid Build Coastguard Worker 
806*84e33947SAndroid Build Coastguard Worker /************************************************
807*84e33947SAndroid Build Coastguard Worker  *  Public Functions
808*84e33947SAndroid Build Coastguard Worker  ***********************************************/
809*84e33947SAndroid Build Coastguard Worker 
chppRegisterGnssClient(struct ChppAppState * appContext)810*84e33947SAndroid Build Coastguard Worker void chppRegisterGnssClient(struct ChppAppState *appContext) {
811*84e33947SAndroid Build Coastguard Worker   memset(&gGnssClientContext, 0, sizeof(gGnssClientContext));
812*84e33947SAndroid Build Coastguard Worker   chppRegisterClient(appContext, (void *)&gGnssClientContext,
813*84e33947SAndroid Build Coastguard Worker                      &gGnssClientContext.client,
814*84e33947SAndroid Build Coastguard Worker                      gGnssClientContext.outReqStates, &kGnssClientConfig);
815*84e33947SAndroid Build Coastguard Worker }
816*84e33947SAndroid Build Coastguard Worker 
chppDeregisterGnssClient(struct ChppAppState * appContext)817*84e33947SAndroid Build Coastguard Worker void chppDeregisterGnssClient(struct ChppAppState *appContext) {
818*84e33947SAndroid Build Coastguard Worker   // TODO
819*84e33947SAndroid Build Coastguard Worker 
820*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(appContext);
821*84e33947SAndroid Build Coastguard Worker }
822*84e33947SAndroid Build Coastguard Worker 
getChppGnssClientState(void)823*84e33947SAndroid Build Coastguard Worker struct ChppEndpointState *getChppGnssClientState(void) {
824*84e33947SAndroid Build Coastguard Worker   return &gGnssClientContext.client;
825*84e33947SAndroid Build Coastguard Worker }
826*84e33947SAndroid Build Coastguard Worker 
827*84e33947SAndroid Build Coastguard Worker #ifdef CHPP_CLIENT_ENABLED_GNSS
828*84e33947SAndroid Build Coastguard Worker 
829*84e33947SAndroid Build Coastguard Worker #ifdef CHPP_CLIENT_ENABLED_CHRE_GNSS
chrePalGnssGetApi(uint32_t requestedApiVersion)830*84e33947SAndroid Build Coastguard Worker const struct chrePalGnssApi *chrePalGnssGetApi(uint32_t requestedApiVersion) {
831*84e33947SAndroid Build Coastguard Worker #else
832*84e33947SAndroid Build Coastguard Worker const struct chrePalGnssApi *chppPalGnssGetApi(uint32_t requestedApiVersion) {
833*84e33947SAndroid Build Coastguard Worker #endif
834*84e33947SAndroid Build Coastguard Worker 
835*84e33947SAndroid Build Coastguard Worker   static const struct chrePalGnssApi api = {
836*84e33947SAndroid Build Coastguard Worker       .moduleVersion = CHPP_PAL_GNSS_API_VERSION,
837*84e33947SAndroid Build Coastguard Worker       .open = chppGnssClientOpen,
838*84e33947SAndroid Build Coastguard Worker       .close = chppGnssClientClose,
839*84e33947SAndroid Build Coastguard Worker       .getCapabilities = chppGnssClientGetCapabilities,
840*84e33947SAndroid Build Coastguard Worker       .controlLocationSession = chppGnssClientControlLocationSession,
841*84e33947SAndroid Build Coastguard Worker       .releaseLocationEvent = chppGnssClientReleaseLocationEvent,
842*84e33947SAndroid Build Coastguard Worker       .controlMeasurementSession = chppGnssClientControlMeasurementSession,
843*84e33947SAndroid Build Coastguard Worker       .releaseMeasurementDataEvent = chppGnssClientReleaseMeasurementDataEvent,
844*84e33947SAndroid Build Coastguard Worker       .configurePassiveLocationListener =
845*84e33947SAndroid Build Coastguard Worker           chppGnssClientConfigurePassiveLocationListener,
846*84e33947SAndroid Build Coastguard Worker   };
847*84e33947SAndroid Build Coastguard Worker 
848*84e33947SAndroid Build Coastguard Worker   CHPP_STATIC_ASSERT(
849*84e33947SAndroid Build Coastguard Worker       CHRE_PAL_GNSS_API_CURRENT_VERSION == CHPP_PAL_GNSS_API_VERSION,
850*84e33947SAndroid Build Coastguard Worker       "A newer CHRE PAL API version is available. Please update.");
851*84e33947SAndroid Build Coastguard Worker 
852*84e33947SAndroid Build Coastguard Worker   if (!CHRE_PAL_VERSIONS_ARE_COMPATIBLE(api.moduleVersion,
853*84e33947SAndroid Build Coastguard Worker                                         requestedApiVersion)) {
854*84e33947SAndroid Build Coastguard Worker     return NULL;
855*84e33947SAndroid Build Coastguard Worker   } else {
856*84e33947SAndroid Build Coastguard Worker     return &api;
857*84e33947SAndroid Build Coastguard Worker   }
858*84e33947SAndroid Build Coastguard Worker }
859*84e33947SAndroid Build Coastguard Worker 
860*84e33947SAndroid Build Coastguard Worker #endif
861