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