• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CHPP_CLIENTS_H_
18 #define CHPP_CLIENTS_H_
19 
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include "chpp/app.h"
25 #include "chpp/condition_variable.h"
26 #include "chpp/macros.h"
27 #include "chpp/mutex.h"
28 #include "chre_api/chre/common.h"
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /************************************************
35  *  Public Definitions
36  ***********************************************/
37 
38 /**
39  * Uses chppAllocClientRequest() to allocate a client request message of a
40  * specific type and its corresponding length.
41  *
42  * @param clientState State variable of the client.
43  * @param type Type of response.
44  *
45  * @return Pointer to allocated memory
46  */
47 #define chppAllocClientRequestFixed(clientState, type) \
48   (type *)chppAllocClientRequest(clientState, sizeof(type))
49 
50 /**
51  * Uses chppAllocClientRequest() to allocate a variable-length client request
52  * message of a specific type.
53  *
54  * @param clientState State variable of the client.
55  * @param type Type of response which includes an arrayed member.
56  * @param count number of items in the array of arrayField.
57  * @param arrayField The arrayed member field.
58  *
59  * @return Pointer to allocated memory
60  */
61 #define chppAllocClientRequestTypedArray(clientState, type, count, arrayField) \
62   (type *)chppAllocClientRequest(                                              \
63       clientState, sizeof(type) + (count)*sizeof_member(type, arrayField[0]))
64 
65 /**
66  * Maintains the basic state of a client.
67  * This is expected to be included once in the (context) status variable of
68  * each client.
69  */
70 struct ChppClientState {
71   struct ChppAppState *appContext;  // Pointer to app layer context
72   struct ChppRequestResponseState
73       *rRStates;        // Pointer to array of request-response states, if any
74   uint8_t index;        // Index of this client
75   uint8_t handle;       // Handle number for this client
76   uint8_t transaction;  // Next Transaction ID to be used
77 
78   uint8_t openState;         // As defined in enum ChppOpenState
79   bool pseudoOpen : 1;       // Client to be opened upon a reset
80   bool initialized : 1;      // Is initialized
81   bool everInitialized : 1;  // Synchronization primitives initialized
82 
83   bool responseReady : 1;  // For sync. request/responses
84   struct ChppMutex responseMutex;
85   struct ChppConditionVariable responseCondVar;
86 };
87 
88 #ifdef CHPP_CLIENT_ENABLED_CHRE_WWAN
89 #define CHPP_CLIENT_ENABLED_WWAN
90 #endif
91 
92 #ifdef CHPP_CLIENT_ENABLED_CHRE_WIFI
93 #define CHPP_CLIENT_ENABLED_WIFI
94 #endif
95 
96 #ifdef CHPP_CLIENT_ENABLED_CHRE_GNSS
97 #define CHPP_CLIENT_ENABLED_GNSS
98 #endif
99 
100 #if defined(CHPP_CLIENT_ENABLED_LOOPBACK) ||                                  \
101     defined(CHPP_CLIENT_ENABLED_TIMESYNC) ||                                  \
102     defined(CHPP_CLIENT_ENABLED_DISCOVERY) ||                                 \
103     defined(CHPP_CLIENT_ENABLED_WWAN) || defined(CHPP_CLIENT_ENABLED_WIFI) || \
104     defined(CHPP_CLIENT_ENABLED_GNSS)
105 #define CHPP_CLIENT_ENABLED
106 #endif
107 
108 #define CHPP_CLIENT_REQUEST_TIMEOUT_INFINITE CHPP_TIME_MAX
109 
110 #ifndef CHPP_CLIENT_REQUEST_TIMEOUT_DEFAULT
111 #define CHPP_CLIENT_REQUEST_TIMEOUT_DEFAULT CHRE_ASYNC_RESULT_TIMEOUT_NS
112 #endif
113 
114 // Default timeout for discovery completion.
115 #ifndef CHPP_DISCOVERY_DEFAULT_TIMEOUT_MS
116 #define CHPP_DISCOVERY_DEFAULT_TIMEOUT_MS UINT64_C(10000)  // 10s
117 #endif
118 
119 /************************************************
120  *  Public functions
121  ***********************************************/
122 
123 /**
124  * Registers common clients with the CHPP app layer. These clients are enabled
125  * by CHPP_CLIENT_ENABLED_xxxx definitions. This function is automatically
126  * called by chppAppInit().
127  *
128  * @param context State of the app layer.
129  */
130 void chppRegisterCommonClients(struct ChppAppState *context);
131 
132 /**
133  * Deregisters common clients with the CHPP app layer. These clients are enabled
134  * by CHPP_CLIENT_ENABLED_xxxx definitions. This function is automatically
135  * called by chppAppDeinit().
136  *
137  * @param context State of the app layer.
138  */
139 void chppDeregisterCommonClients(struct ChppAppState *context);
140 
141 /**
142  * Registers a new client on CHPP.
143  *
144  * This function is to be called by the platform initialization code for every
145  * non-common client available on a server (if any), i.e. except those that are
146  * registered through chppRegisterCommonClients().
147  *
148  * Registered clients are matched with discovered services during discovery.
149  * When a match succeeds, the client's initialization function (pointer) is
150  * called, assigning them their handle number.
151  *
152  * Note that the maximum number of clients that can be registered on a platform
153  * can specified as CHPP_MAX_REGISTERED_CLIENTS by the initialization code.
154  * Otherwise, a default value will be used.
155  *
156  * @param appContext State of the app layer.
157  * @param clientContext State of the client instance.
158  * @param clientState State variable of the client.
159  * @param rRStates Pointer to array of request-response states, if any.
160  * @param newClient The client to be registered on this platform.
161  */
162 void chppRegisterClient(struct ChppAppState *appContext, void *clientContext,
163                         struct ChppClientState *clientState,
164                         struct ChppRequestResponseState *rRStates,
165                         const struct ChppClient *newClient);
166 
167 /**
168  * Initializes basic CHPP clients.
169  *
170  * @param context State of the app layer.
171  */
172 void chppInitBasicClients(struct ChppAppState *context);
173 
174 /**
175  * Initializes a client. This function must be called when a client is matched
176  * with a service during discovery to provides its handle number.
177  *
178  * @param clientState State variable of the client.
179  * @param handle Handle number for this client.
180  */
181 void chppClientInit(struct ChppClientState *clientState, uint8_t handle);
182 
183 /**
184  * Deinitializes a client.
185  *
186  * @param clientState State variable of the client.
187  */
188 void chppClientDeinit(struct ChppClientState *clientState);
189 
190 /**
191  * Deinitializes basic clients.
192  *
193  * @param context State of the app layer.
194  */
195 void chppDeinitBasicClients(struct ChppAppState *context);
196 
197 /**
198  * Deinitializes all matched clients.
199  *
200  * @param context State of the app layer.
201  */
202 void chppDeinitMatchedClients(struct ChppAppState *context);
203 
204 /**
205  * Allocates a client request message of a specified length, populating the
206  * (app layer) client request header, including the sequence ID. The
207  * next-sequence ID stored in the client state variable is subsequently
208  * incremented.
209  *
210  * It is expected that for most use cases, the chppAllocClientRequestFixed()
211  * or chppAllocClientRequestTypedArray() macros shall be used rather than
212  * calling this function directly.
213  *
214  * @param clientState State variable of the client.
215  * @param len Length of the response message (including header) in bytes. Note
216  * that the specified length must be at least equal to the lendth of the app
217  * layer header.
218  *
219  * @return Pointer to allocated memory
220  */
221 struct ChppAppHeader *chppAllocClientRequest(
222     struct ChppClientState *clientState, size_t len);
223 
224 /**
225  * Uses chppAllocClientRequest() to allocate a specific client request command
226  * without any additional payload.
227  *
228  * @param clientState State variable of the client.
229  * @param command Type of response.
230  *
231  * @return Pointer to allocated memory
232  */
233 struct ChppAppHeader *chppAllocClientRequestCommand(
234     struct ChppClientState *clientState, uint16_t command);
235 
236 /**
237  * This function shall be called for all outgoing client requests in order to
238  * A) Timestamp them, and
239  * B) Save their Transaction ID
240  * as part of the request/response's ChppRequestResponseState struct.
241  *
242  * This function prints an error message if a duplicate request is sent
243  * while outstanding request is still pending without a response.
244  *
245  * @param clientState State of the client sending the client request.
246  * @param transactionId The transaction ID to use when loading the app.
247  * @param rRState Maintains the basic state for each request/response
248  * functionality of a client.
249  * @param requestHeader Client request header.
250  */
251 void chppClientTimestampRequest(struct ChppClientState *clientState,
252                                 struct ChppRequestResponseState *rRState,
253                                 struct ChppAppHeader *requestHeader,
254                                 uint64_t timeoutNs);
255 
256 /**
257  * This function shall be called for incoming responses to a client request in
258  * order to
259  * A) Verify the correct transaction ID
260  * B) Timestamp them, and
261  * C) Mark them as fulfilled
262  * D) TODO: check for timeout
263  *
264  * This function prints an error message if a response is received without an
265  * outstanding request.
266  *
267  * @param clientState State of the client sending the client request.
268  * @param rRState Maintains the basic state for each request/response
269  * functionality of a client.
270  * @param requestHeader Client request header.
271  *
272  * @return false if there is an error. True otherwise.
273  */
274 bool chppClientTimestampResponse(struct ChppClientState *clientState,
275                                  struct ChppRequestResponseState *rRState,
276                                  const struct ChppAppHeader *responseHeader);
277 
278 /**
279  * Timestamps a client request using chppClientTimestampResponse() and enqueues
280  * it using chppEnqueueTxDatagramOrFail().
281  *
282  * Refer to their respective documentation for details.
283  *
284  * Note that the ownership of buf is taken from the caller when this method is
285  * invoked.
286  *
287  * @param clientState State of the client sending the client request.
288  * @param rRState Maintains the basic state for each request/response
289  * functionality of a client.
290  * @param buf Datagram payload allocated through chppMalloc. Cannot be null.
291  * @param len Datagram length in bytes.
292  * @param timeoutNs Time in nanoseconds before a timeout response is generated.
293  * Zero means no timeout response.
294  *
295  * @return True informs the sender that the datagram was successfully enqueued.
296  * False informs the sender that the queue was full and the payload discarded.
297  */
298 bool chppSendTimestampedRequestOrFail(struct ChppClientState *clientState,
299                                       struct ChppRequestResponseState *rRState,
300                                       void *buf, size_t len,
301                                       uint64_t timeoutNs);
302 
303 /**
304  * Similar to chppSendTimestampedRequestOrFail() but blocks execution until a
305  * response is received. Used for synchronous requests.
306  *
307  * In order to use this function, clientState->responseNotifier must have been
308  * initialized using chppNotifierInit() upon initialization of the client.
309  *
310  * @param clientState State of the client sending the client request.
311  * @param rRState Maintains the basic state for each request/response
312  * functionality of a client.
313  * @param buf Datagram payload allocated through chppMalloc. Cannot be null.
314  * @param len Datagram length in bytes.
315  *
316  * @return True informs the sender that the datagram was successfully enqueued.
317  * False informs the sender that the payload was discarded because either the
318  * queue was full, or the request timed out.
319  */
320 bool chppSendTimestampedRequestAndWait(struct ChppClientState *clientState,
321                                        struct ChppRequestResponseState *rRState,
322                                        void *buf, size_t len);
323 
324 /**
325  * Same as chppSendTimestampedRequestAndWait() but with a specified timeout.
326  */
327 bool chppSendTimestampedRequestAndWaitTimeout(
328     struct ChppClientState *clientState,
329     struct ChppRequestResponseState *rRState, void *buf, size_t len,
330     uint64_t timeoutNs);
331 
332 /**
333  * Marks a closed client as pseudo-open, so that it would be opened upon a
334  * reset.
335  *
336  * @param clientState State variable of the client.
337  */
338 void chppClientPseudoOpen(struct ChppClientState *clientState);
339 
340 /**
341  * Sends a client request for the open command in a blocking or non-blocking
342  * manner.
343  * A non-blocking open is used to for reopening a service after a reset or for
344  * opening a pseudo-open service.
345  *
346  * @param clientState State variable of the client.
347  * @param openRRState Request/response state for the open command.
348  * @param openCommand Open command to be sent.
349  * @param blocking Indicates a blocking (vs. non-blocking) open request.
350  *
351  * @return Indicates success or failure.
352  */
353 bool chppClientSendOpenRequest(struct ChppClientState *clientState,
354                                struct ChppRequestResponseState *openRRState,
355                                uint16_t openCommand, bool blocking);
356 
357 /**
358  * Processes a service response for the open command.
359  *
360  * @param clientState State variable of the client.
361  */
362 void chppClientProcessOpenResponse(struct ChppClientState *clientState,
363                                    uint8_t *buf, size_t len);
364 
365 /**
366  * Recalculates the next upcoming client request timeout time.
367  *
368  * @param context State of the app layer.
369  */
370 void chppClientRecalculateNextTimeout(struct ChppAppState *context);
371 
372 /**
373  * Closes any remaining open requests for a given client by sending a timeout.
374  * This function is used when a client is reset.
375  *
376  * @param clientState State variable of the client.
377  * @param client The client for whech to clear out open requests.
378  * @param clearOnly If true, indicates that a timeout response shouldn't be
379  *     sent to the client. This must only be set if the requests are being
380  *     cleared as part of the client closing.
381  */
382 void chppClientCloseOpenRequests(struct ChppClientState *clientState,
383                                  const struct ChppClient *client,
384                                  bool clearOnly);
385 
386 #ifdef __cplusplus
387 }
388 #endif
389 
390 #endif  // CHPP_CLIENTS_H_
391