• 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_APP_H_
18 #define CHPP_APP_H_
19 
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include "chpp/condition_variable.h"
25 #include "chpp/macros.h"
26 #include "chpp/transport.h"
27 #include "chre_api/chre/common.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 /************************************************
34  *  Public Definitions
35  ***********************************************/
36 
37 /**
38  * Allocates a variable-length response message of a specific type.
39  *
40  * @param requestHeader request header, as per chppAllocResponse().
41  * @param type Type of response which includes an arrayed member.
42  * @param count number of items in the array of arrayField.
43  * @param arrayField The arrayed member field.
44  *
45  * @return Pointer to allocated memory.
46  */
47 #define chppAllocResponseTypedArray(requestHeader, type, count, arrayField) \
48   (type *)chppAllocResponse(                                                \
49       requestHeader,                                                        \
50       sizeof(type) + (count)*sizeof_member(type, arrayField[0]))
51 
52 /**
53  * Allocates a response message of a specific type and its corresponding length.
54  *
55  * @param requestHeader request header, as per chppAllocResponse().
56  * @param type Type of response.
57  *
58  * @return Pointer to allocated memory.
59  */
60 #define chppAllocResponseFixed(requestHeader, type) \
61   (type *)chppAllocResponse(requestHeader, sizeof(type))
62 
63 /**
64  * Maximum number of services that can be registered by CHPP (not including
65  * predefined services), if not defined by the build system.
66  */
67 #ifndef CHPP_MAX_REGISTERED_SERVICES
68 #define CHPP_MAX_REGISTERED_SERVICES 1
69 #endif
70 
71 /**
72  * Maximum number of clients that can be registered by CHPP (not including
73  * predefined clients), if not defined by the build system.
74  */
75 #ifndef CHPP_MAX_REGISTERED_CLIENTS
76 #define CHPP_MAX_REGISTERED_CLIENTS 1
77 #endif
78 
79 /**
80  * Maximum number of services that can be discovered by CHPP (not including
81  * predefined services), if not defined by the build system.
82  */
83 #ifndef CHPP_MAX_DISCOVERED_SERVICES
84 #define CHPP_MAX_DISCOVERED_SERVICES \
85   MAX(CHPP_MAX_REGISTERED_SERVICES, CHPP_MAX_REGISTERED_CLIENTS)
86 #endif
87 
88 #define CHPP_REQUEST_TIMEOUT_INFINITE CHPP_TIME_MAX
89 
90 #if defined(CHPP_REQUEST_TIMEOUT_DEFAULT) && \
91     defined(CHPP_CLIENT_REQUEST_TIMEOUT_DEFAULT)
92 // Build systems should prefer to only set CHPP_REQUEST_TIMEOUT_DEFAULT
93 #error Can not set both CHPP_REQUEST_TIMEOUT_DEFAULT and CHPP_CLIENT_REQUEST_TIMEOUT_DEFAULT
94 #endif
95 
96 // For backwards compatibility with vendor build systems
97 #ifdef CHPP_CLIENT_REQUEST_TIMEOUT_DEFAULT
98 #define CHPP_REQUEST_TIMEOUT_DEFAULT CHPP_CLIENT_REQUEST_TIMEOUT_DEFAULT
99 #undef CHPP_CLIENT_REQUEST_TIMEOUT_DEFAULT
100 #endif
101 
102 // If not customized in the build, we default to CHRE expectations
103 #ifndef CHPP_REQUEST_TIMEOUT_DEFAULT
104 #define CHPP_REQUEST_TIMEOUT_DEFAULT CHRE_ASYNC_RESULT_TIMEOUT_NS
105 #endif
106 
107 /**
108  * Default value for reserved fields.
109  */
110 #define CHPP_RESERVED 0
111 
112 /**
113  * Client index number when there is no matching client
114  */
115 #define CHPP_CLIENT_INDEX_NONE 0xff
116 
117 /**
118  * App layer command at initialization.
119  */
120 #define CHPP_APP_COMMAND_NONE 0
121 
122 /**
123  * Type of endpoint (either client or service)
124  */
125 enum ChppEndpointType {
126   CHPP_ENDPOINT_CLIENT = 0,
127   CHPP_ENDPOINT_SERVICE = 1,
128 };
129 
130 /**
131  * Handle Numbers in ChppAppHeader
132  */
133 enum ChppHandleNumber {
134   //! Handleless communication
135   CHPP_HANDLE_NONE = 0x00,
136 
137   //! Loopback Service
138   CHPP_HANDLE_LOOPBACK = 0x01,
139 
140   //! Time Service
141   CHPP_HANDLE_TIMESYNC = 0x02,
142 
143   //! Discovery Service
144   CHPP_HANDLE_DISCOVERY = 0x0F,
145 
146   //! Negotiated Services (starting from this offset)
147   CHPP_HANDLE_NEGOTIATED_RANGE_START = 0x10,
148 };
149 
150 /**
151  * Message Types as used in ChppAppHeader
152  */
153 #define CHPP_APP_MASK_MESSAGE_TYPE LEAST_SIGNIFICANT_NIBBLE
154 #define CHPP_APP_GET_MESSAGE_TYPE(value) \
155   ((enum ChppMessageType)(               \
156       (value)&CHPP_APP_MASK_MESSAGE_TYPE))  // TODO: Consider checking if this
157                                             // maps into a valid enum
158 enum ChppMessageType {
159   //! Request from client. Needs response from service.
160   CHPP_MESSAGE_TYPE_CLIENT_REQUEST = 0,
161 
162   //! Response from service (with the same Command and Transaction ID as the
163   //! client request).
164   CHPP_MESSAGE_TYPE_SERVICE_RESPONSE = 1,
165 
166   //! Notification from client. Service shall not respond.
167   CHPP_MESSAGE_TYPE_CLIENT_NOTIFICATION = 2,
168 
169   //! Notification from service. Client shall not respond.
170   CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION = 3,
171 
172   //! Request from service. Needs response from client.
173   CHPP_MESSAGE_TYPE_SERVICE_REQUEST = 4,
174 
175   //! Response from client (with the same Command and Transaction ID as the
176   //! service request).
177   CHPP_MESSAGE_TYPE_CLIENT_RESPONSE = 5,
178 };
179 
180 /**
181  * Error codes used by the app layer / clients / services.
182  */
183 enum ChppAppErrorCode {
184   //! Success (no error)
185   CHPP_APP_ERROR_NONE = 0,
186   //! Invalid command
187   CHPP_APP_ERROR_INVALID_COMMAND = 1,
188   //! Invalid argument(s)
189   CHPP_APP_ERROR_INVALID_ARG = 2,
190   //! Busy
191   CHPP_APP_ERROR_BUSY = 3,
192   //! Out of memory
193   CHPP_APP_ERROR_OOM = 4,
194   //! Feature not supported
195   CHPP_APP_ERROR_UNSUPPORTED = 5,
196   //! Timeout
197   CHPP_APP_ERROR_TIMEOUT = 6,
198   //! Functionality disabled (e.g. per user configuration)
199   CHPP_APP_ERROR_DISABLED = 7,
200   //! Rate limit exceeded (try again later)
201   CHPP_APP_ERROR_RATELIMITED = 8,
202   //! Function in use / blocked by another entity (e.g. the AP)
203   CHPP_APP_ERROR_BLOCKED = 9,
204   //! Invalid length
205   CHPP_APP_ERROR_INVALID_LENGTH = 10,
206   //! CHPP Not Ready
207   CHPP_APP_ERROR_NOT_READY = 11,
208   //! Error outside of CHPP (e.g. PAL API)
209   CHPP_APP_ERROR_BEYOND_CHPP = 12,
210   //! Response not matching a pending request
211   CHPP_APP_ERROR_UNEXPECTED_RESPONSE = 13,
212   //! Conversion failed
213   CHPP_APP_ERROR_CONVERSION_FAILED = 14,
214   //! Unspecified failure
215   CHPP_APP_ERROR_UNSPECIFIED = 255
216 };
217 
218 /**
219  * Open status for clients / services.
220  */
221 enum ChppOpenState {
222   CHPP_OPEN_STATE_CLOSED = 0,           // Closed
223   CHPP_OPEN_STATE_OPENING = 1,          // Enables the open request to pass
224   CHPP_OPEN_STATE_WAITING_TO_OPEN = 2,  // Waiting for open response
225   CHPP_OPEN_STATE_OPENED = 3,           // Opened
226 };
227 
228 /**
229  * CHPP Application Layer header
230  */
231 CHPP_PACKED_START
232 struct ChppAppHeader {
233   //! Service Handle
234   uint8_t handle;
235 
236   //! Most significant nibble (MSN): Reserved
237   //! Least significant nibble (LSN): Message Type from enum ChppMessageType
238   uint8_t type;
239 
240   //! Transaction ID
241   uint8_t transaction;
242 
243   //! Error if any, from enum ChppAppErrorCode
244   uint8_t error;
245 
246   //! Command
247   uint16_t command;
248 
249 } CHPP_PACKED_ATTR;
250 CHPP_PACKED_END
251 
252 /**
253  * Function type that dispatches incoming datagrams for any client or service.
254  *
255  * The buffer is freed shortly after the function returns.
256  * User code must make a copy for later processing if needed.
257  */
258 typedef enum ChppAppErrorCode(ChppDispatchFunction)(void *context, uint8_t *buf,
259                                                     size_t len);
260 
261 /**
262  * Function type that initializes a client and assigns it its handle number
263  */
264 typedef bool(ChppClientInitFunction)(void *context, uint8_t handle,
265                                      struct ChppVersion serviceVersion);
266 
267 /**
268  * Function type that deinitializes a client.
269  */
270 typedef void(ChppClientDeinitFunction)(void *context);
271 
272 /**
273  * Function type that dispatches a reset notification to any client or service
274  */
275 typedef void(ChppNotifierFunction)(void *context);
276 
277 /**
278  * Function type that processes a timeout for any client or service
279  */
280 typedef void(ChppTimeoutFunction)(void *context);
281 
282 /**
283  * Length of a service UUID and its human-readable printed form in bytes
284  */
285 #define CHPP_SERVICE_UUID_LEN 16
286 #define CHPP_SERVICE_UUID_STRING_LEN (16 * 2 + 4 + 1)
287 
288 /**
289  * Length of a version number, in bytes (major + minor + revision), per CHPP
290  * spec.
291  */
292 #define CHPP_SERVICE_VERSION_LEN (1 + 1 + 2)
293 
294 /**
295  * Maximum length of a human-readable service name, per CHPP spec.
296  * (15 ASCII characters + null)
297  */
298 #define CHPP_SERVICE_NAME_MAX_LEN (15 + 1)
299 
300 /**
301  * Support for sync response.
302  *
303  * @see chppClientSendTimestampedRequestAndWaitTimeout.
304  */
305 struct ChppSyncResponse {
306   struct ChppMutex mutex;
307   struct ChppConditionVariable condVar;
308   bool ready;
309 };
310 
311 /**
312  * CHPP definition of a service descriptor as sent over the wire.
313  */
314 CHPP_PACKED_START
315 struct ChppServiceDescriptor {
316   //! UUID of the service.
317   //! Must be generated according to RFC 4122, UUID version 4 (random).
318   uint8_t uuid[CHPP_SERVICE_UUID_LEN];
319 
320   //! Human-readable name of the service for debugging.
321   char name[CHPP_SERVICE_NAME_MAX_LEN];
322 
323   //! Version of the service.
324   struct ChppVersion version;
325 } CHPP_PACKED_ATTR;
326 CHPP_PACKED_END
327 
328 /**
329  * CHPP definition of a service as supported on a server.
330  */
331 struct ChppService {
332   //! Service Descriptor as sent over the wire.
333   struct ChppServiceDescriptor descriptor;
334 
335   //! Notifies the service if CHPP is reset.
336   ChppNotifierFunction *resetNotifierFunctionPtr;
337 
338   //! Dispatches incoming client requests.
339   //! When an error is returned by the dispatch function it is logged and an
340   //! error response is automatically sent to the remote endpoint.
341   ChppDispatchFunction *requestDispatchFunctionPtr;
342 
343   //! Dispatches incoming client notifications.
344   //! Errors returned by the dispatch function are logged.
345   ChppDispatchFunction *notificationDispatchFunctionPtr;
346 
347   //! Dispatches incoming client responses.
348   //! Errors returned by the dispatch function are logged.
349   ChppDispatchFunction *responseDispatchFunctionPtr;
350 
351   //! Processes a timeout for the client.
352   ChppTimeoutFunction *timeoutFunctionPtr;
353 
354   //! Number of outgoing requests supported by this service.
355   //! ChppAppHeader.command must be in the range [0, outReqCount - 1]
356   //! ChppEndpointState.outReqStates must contains that many elements.
357   uint16_t outReqCount;
358 
359   //! Minimum valid length of datagrams for the service:
360   //! - client requests
361   //! - client notifications
362   //! - client responses
363   size_t minLength;
364 };
365 
366 /**
367  * CHPP definition of a client descriptor.
368  */
369 struct ChppClientDescriptor {
370   //! UUID of the client.
371   //! Must be generated according to RFC 4122, UUID version 4 (random).
372   uint8_t uuid[CHPP_SERVICE_UUID_LEN];
373 
374   //! Version of the client.
375   struct ChppVersion version;
376 };
377 
378 /**
379  * CHPP definition of a client.
380  */
381 struct ChppClient {
382   //! Client descriptor.
383   struct ChppClientDescriptor descriptor;
384 
385   //! Notifies the client if CHPP is reset.
386   ChppNotifierFunction *resetNotifierFunctionPtr;
387 
388   //! Notifies the client if CHPP is matched to a service.
389   ChppNotifierFunction *matchNotifierFunctionPtr;
390 
391   //! Dispatches incoming service responses.
392   //! Service responses are only dispatched to clients that have been opened or
393   //! are in the process of being (re)opened. @see ChppOpenState.
394   //! Errors returned by the dispatch function are logged.
395   ChppDispatchFunction *responseDispatchFunctionPtr;
396 
397   //! Dispatches incoming service notifications.
398   //! Service notifications are only dispatched to clients that have been
399   //! opened. @see ChppOpenState
400   //! Errors returned by the dispatch function are logged.
401   ChppDispatchFunction *notificationDispatchFunctionPtr;
402 
403   //! Dispatches incoming service requests.
404   //! When an error is returned by the dispatch function it is logged and an
405   //! error response is automatically sent to the remote endpoint.
406   ChppDispatchFunction *requestDispatchFunctionPtr;
407 
408   //! Initializes the client (after it is matched with a service at discovery)
409   //! and assigns it its handle number.
410   ChppClientInitFunction *initFunctionPtr;
411 
412   //! Deinitializes the client.
413   ChppClientDeinitFunction *deinitFunctionPtr;
414 
415   //! Processes a timeout for the client.
416   ChppTimeoutFunction *timeoutFunctionPtr;
417 
418   //! Number of outgoing requests supported by this client.
419   //! ChppAppHeader.command must be in the range [0, outReqCount - 1]
420   //! ChppEndpointState.outReqStates must contains that many elements.
421   uint16_t outReqCount;
422 
423   //! Minimum valid length of datagrams for the service:
424   //! - service responses
425   //! - service notifications
426   //! - service requests
427   size_t minLength;
428 };
429 
430 /**
431  * Request status for clients.
432  */
433 enum ChppRequestState {
434   CHPP_REQUEST_STATE_NONE = 0,              //!< No request sent ever
435   CHPP_REQUEST_STATE_REQUEST_SENT = 1,      //!< Sent, waiting for a response
436   CHPP_REQUEST_STATE_RESPONSE_RCV = 2,      //!< Sent and response received
437   CHPP_REQUEST_STATE_RESPONSE_TIMEOUT = 3,  //!< Timeout. Responded as need be
438 };
439 
440 /**
441  * State of each outgoing request and their response.
442  *
443  * There must be as many ChppOutgoingRequestState in the client or service state
444  * (ChppEndpointState) as the number of commands they support.
445  */
446 struct ChppOutgoingRequestState {
447   uint64_t requestTimeNs;  // Time of the last request
448   // When requestState is CHPP_REQUEST_STATE_REQUEST_SENT,
449   // indicates the timeout time for the request.
450   // When requestState is CHPP_REQUEST_STATE_RESPONSE_RCV,
451   // indicates when the response was received.
452   uint64_t responseTimeNs;
453   uint8_t requestState;  // From enum ChppRequestState
454   uint8_t transaction;   // Transaction ID for the last request/response
455 };
456 
457 /**
458  * State of each incoming request and their response.
459  *
460  * There must be as many ChppIncomingRequestState in the client or service state
461  * as the number of commands supported by the other side (corresponding service
462  * for a client and corresponding client for a service).
463  *
464  * Contrary to ChppOutgoingRequestState those are not part of
465  * CChppEndpointState. They must be stored to and retrieved from the context
466  * passed to chppRegisterClient / chppRegisterService.
467  *
468  * Note: while ChppIncomingRequestState and ChppOutgoingRequestState have the
469  * same layout, we want the types to be distinct to be enforced at compile time.
470  * Using a typedef would make both types equivalent.
471  *
472  * @see ChppOutgoingRequestState for field details.
473  */
474 struct ChppIncomingRequestState {
475   uint64_t requestTimeNs;
476   uint64_t responseTimeNs;
477   uint8_t requestState;
478   uint8_t transaction;
479 };
480 
481 /**
482  * Enabled clients and services.
483  */
484 struct ChppClientServiceSet {
485   bool wifiService : 1;
486   bool gnssService : 1;
487   bool wwanService : 1;
488   bool wifiClient : 1;
489   bool gnssClient : 1;
490   bool wwanClient : 1;
491   bool loopbackClient : 1;
492   bool vendorClients : 1;
493   bool vendorServices : 1;
494 };
495 
496 struct ChppLoopbackClientState;
497 struct ChppTimesyncClientState;
498 
499 /**
500  * CHPP state of a client or a service.
501  *
502  * This is the CHPP internal client/service state.
503  * Their private state is store in the context field.
504  */
505 struct ChppEndpointState {
506   struct ChppAppState *appContext;  // Pointer to app layer context
507 
508   // State for the outgoing requests.
509   // It must accommodate Chpp{Client,Service}.outReqCount elements.
510   // It also tracks corresponding incoming responses.
511   // NULL when outReqCount = 0.
512   struct ChppOutgoingRequestState *outReqStates;
513 
514   void *context;  //!< Private state of the endpoint.
515 
516   struct ChppSyncResponse syncResponse;
517 
518   uint8_t index;        //!< Index (in ChppAppState lists).
519   uint8_t handle;       //!< Handle used to match client and service.
520   uint8_t transaction;  //!< Next Transaction ID to be used.
521 
522   uint8_t openState;  //!< see enum ChppOpenState
523 
524   bool pseudoOpen : 1;       //!< Client to be opened upon a reset
525   bool initialized : 1;      //!< Client is initialized
526   bool everInitialized : 1;  //!< Client sync primitives initialized
527 
528   uint64_t nextTimerTimeoutNs;  //!< The next timer timeout in nanoseconds.
529 };
530 
531 struct ChppAppState {
532   struct ChppTransportState *transportContext;  // Pointing to transport context
533 
534   const struct chrePalSystemApi *systemApi;  // Pointing to the PAL system APIs
535 
536   uint8_t registeredServiceCount;  // Number of services currently registered
537 
538   const struct ChppService *registeredServices[CHPP_MAX_REGISTERED_SERVICES];
539 
540   struct ChppEndpointState
541       *registeredServiceStates[CHPP_MAX_REGISTERED_SERVICES];
542 
543   uint8_t registeredClientCount;  // Number of clients currently registered
544 
545   const struct ChppClient *registeredClients[CHPP_MAX_REGISTERED_CLIENTS];
546 
547   struct ChppEndpointState *registeredClientStates[CHPP_MAX_REGISTERED_CLIENTS];
548 
549   // When the first outstanding request sent from the client timeouts.
550   uint64_t nextClientRequestTimeoutNs;
551   // When the first outstanding request sent from the service timeouts.
552   uint64_t nextServiceRequestTimeoutNs;
553 
554   uint8_t
555       clientIndexOfServiceIndex[CHPP_MAX_DISCOVERED_SERVICES];  // Lookup table
556 
557   struct ChppClientServiceSet clientServiceSet;  // Enabled client/services
558 
559   // Pointers to the contexts of basic clients, which are allocated if and when
560   // they are initialized
561   struct ChppLoopbackClientState *loopbackClientContext;
562   struct ChppTimesyncClientState *timesyncClientContext;
563 
564   // For discovery clients
565   bool isDiscoveryClientEverInitialized;
566   bool isDiscoveryClientInitialized;
567   bool isDiscoveryComplete;
568 
569   // The number of clients that matched a service during discovery.
570   uint8_t matchedClientCount;
571 
572   // The number of services that were found during discovery.
573   uint8_t discoveredServiceCount;
574 
575   struct ChppMutex discoveryMutex;
576   struct ChppConditionVariable discoveryCv;
577 };
578 
579 #define CHPP_SERVICE_INDEX_OF_HANDLE(handle) \
580   ((handle)-CHPP_HANDLE_NEGOTIATED_RANGE_START)
581 
582 #define CHPP_SERVICE_HANDLE_OF_INDEX(index) \
583   ((index) + CHPP_HANDLE_NEGOTIATED_RANGE_START)
584 
585 /************************************************
586  *  Public functions
587  ***********************************************/
588 
589 /**
590  * Initializes the CHPP app layer state stored in the parameter appContext.
591  * It is necessary to initialize state for each app layer instance on
592  * every platform.
593  *
594  * @param appContext Maintains status for each app layer instance.
595  * @param transportContext The transport layer status struct associated with
596  * this app layer instance.
597  */
598 void chppAppInit(struct ChppAppState *appContext,
599                  struct ChppTransportState *transportContext);
600 
601 /**
602  * Same as chppAppInit(), but specifies the client/service endpoints to be
603  * enabled.
604  *
605  * @param appContext Maintains status for each app layer instance.
606  * @param transportContext The transport layer status struct associated with
607  * this app layer instance.
608  * @param clientServiceSet Bitmap specifying the client/service endpoints to be
609  * enabled.
610  */
611 void chppAppInitWithClientServiceSet(
612     struct ChppAppState *appContext,
613     struct ChppTransportState *transportContext,
614     struct ChppClientServiceSet clientServiceSet);
615 
616 /**
617  * Deinitializes the CHPP app layer for e.g. clean shutdown.
618  *
619  * @param appContext A non-null pointer to ChppAppState initialized previously
620  * in chppAppInit().
621  */
622 void chppAppDeinit(struct ChppAppState *appContext);
623 
624 /**
625  * Processes an Rx Datagram from the transport layer.
626  *
627  * @param context Maintains status for each app layer instance.
628  * @param buf Input data. Cannot be null.
629  * @param len Length of input data in bytes.
630  */
631 void chppAppProcessRxDatagram(struct ChppAppState *context, uint8_t *buf,
632                               size_t len);
633 
634 /**
635  * Used by the transport layer to notify the app layer of a reset during
636  * operation. This function is called after the transport layer has sent a reset
637  * or reset-ack packet.
638  * In turn, this function notifies clients and services to allow them to reset
639  * or recover state as necessary.
640  *
641  * @param context Maintains status for each app layer instance.
642  */
643 void chppAppProcessReset(struct ChppAppState *context);
644 
645 /**
646  * Processes a timeout event. This method is called by the transport layer when
647  * a timeout has occurred, based on the next timer timeout specified through
648  * chppAppGetNextTimerTimeoutNs().
649  *
650  * @param context Maintains status for each app layer instance.
651  * @param currentTimeNs The current time to check the timeout against, used as
652  * an argument to save processing overhead to call chppGetCurrentTimeNs().
653  */
654 void chppAppProcessTimeout(struct ChppAppState *context,
655                            uint64_t currentTimeNs);
656 
657 /**
658  * Convert UUID to a human-readable, null-terminated string.
659  *
660  * @param uuid Input UUID
661  * @param strOut Output null-terminated string
662  */
663 void chppUuidToStr(const uint8_t uuid[CHPP_SERVICE_UUID_LEN],
664                    char strOut[CHPP_SERVICE_UUID_STRING_LEN]);
665 
666 /**
667  * Maps a CHPP app layer error to a CHRE error.
668  *
669  * @param chppError CHPP app layer error (from enum ChppAppErrorCode).
670  *
671  * @return CHRE error (from enum chreError).
672  */
673 uint8_t chppAppErrorToChreError(uint8_t error);
674 
675 /**
676  * Handles logging and error conversion when an app layer response is too short.
677  *
678  * @param buf Input data. Cannot be null.
679  * @param len Length of input data in bytes.
680  * @param responseName Name of the request/response to be logged.
681  *
682  * @return CHRE error (from enum chreError).
683  */
684 uint8_t chppAppShortResponseErrorHandler(uint8_t *buf, size_t len,
685                                          const char *responseName);
686 
687 /**
688  * Allocates a notification of a specified length.
689  *
690  * This function is internal. Instead use either
691  * - chppAllocClientNotification
692  * - or chppAllocServiceNotification
693  *
694  * The caller must initialize at least the handle and command fields of the
695  * ChppAppHeader.
696  *
697  * @param type CHPP_MESSAGE_TYPE_CLIENT_NOTIFICATION or
698  *        CHPP_MESSAGE_TYPE_SERVICE_NOTIFICATION.
699  * @param len Length of the notification (including header) in bytes. Note
700  *        that the specified length must be at least equal to the length of the
701  *        app layer header.
702  *
703  * @return Pointer to allocated memory.
704  */
705 struct ChppAppHeader *chppAllocNotification(uint8_t type, size_t len);
706 
707 /**
708  * Allocates a request message.
709  *
710  * This function is internal. Instead use either:
711  * - chppAllocClientRequest
712  * - or chppAllocServiceRequest
713  *
714  * @param type CHPP_MESSAGE_TYPE_CLIENT_REQUEST or
715  *        CHPP_MESSAGE_TYPE_SERVICE_REQUEST.
716  * @param endpointState State of the endpoint.
717  * @param len Length of the response message (including header) in bytes. Note
718  *        that the specified length must be at least equal to the length of the
719  *        app layer header.
720  *
721  * @return Pointer to allocated memory.
722  */
723 struct ChppAppHeader *chppAllocRequest(uint8_t type,
724                                        struct ChppEndpointState *endpointState,
725                                        size_t len);
726 
727 /**
728  * Allocates a response message of a specified length, populating the (app
729  * layer) response header according to the provided request (app layer) header.
730  *
731  * This function can be used to allocate either client or service response.
732  *
733  * @param requestHeader request header.
734  * @param len Length of the response message (including header) in bytes. Note
735  *        that the specified length must be at least equal to the length of the
736  *        app layer header.
737  *
738  * @return Pointer to allocated memory.
739  */
740 struct ChppAppHeader *chppAllocResponse(
741     const struct ChppAppHeader *requestHeader, size_t len);
742 
743 /**
744  * This function shall be called for all incoming requests in order to
745  * A) Timestamp them, and
746  * B) Save their Transaction ID
747  *
748  * This function prints an error message if a duplicate request is received
749  * while outstanding request is still pending without a response.
750  *
751  * @param inReqState State of the request/response.
752  * @param requestHeader Request header.
753  */
754 void chppTimestampIncomingRequest(struct ChppIncomingRequestState *inReqState,
755                                   const struct ChppAppHeader *requestHeader);
756 
757 /**
758  * This function shall be called for all outgoing requests in order to
759  * A) Timestamp them, and
760  * B) Save their Transaction ID
761  *
762  * This function prints an error message if a duplicate request is sent
763  * while outstanding request is still pending without a response.
764  *
765  * @param appState App layer state.
766  * @param outReqState state of the request/response.
767  * @param requestHeader Client request header.
768  * @param timeoutNs The timeout.
769  */
770 void chppTimestampOutgoingRequest(struct ChppAppState *appState,
771                                   struct ChppOutgoingRequestState *outReqState,
772                                   const struct ChppAppHeader *requestHeader,
773                                   uint64_t timeoutNs);
774 
775 /**
776  * This function shall be called for incoming responses to a request in
777  * order to
778  * A) Verify the correct transaction ID
779  * B) Timestamp them, and
780  * C) Mark them as fulfilled
781  *
782  * This function prints an error message if a response is received without an
783  * outstanding request.
784  *
785  * @param appState App layer state.
786  * @param outReqState state of the request/response.
787  * @param requestHeader Request header.
788  *
789  * @return false if there is an error. true otherwise.
790  */
791 bool chppTimestampIncomingResponse(struct ChppAppState *appState,
792                                    struct ChppOutgoingRequestState *outReqState,
793                                    const struct ChppAppHeader *responseHeader);
794 
795 /**
796  * This function shall be called for the outgoing response to a request in order
797  * to:
798  * A) Timestamp them, and
799  * B) Mark them as fulfilled part of the request/response's
800  *    ChppOutgoingRequestState struct.
801  *
802  * For most responses, it is expected that chppSendTimestampedResponseOrFail()
803  * shall be used to both timestamp and send the response in one shot.
804  *
805  * @param inReqState State of the request/response.
806  * @return The last response time (CHPP_TIME_NONE for the first response).
807  */
808 uint64_t chppTimestampOutgoingResponse(
809     struct ChppIncomingRequestState *inReqState);
810 
811 /**
812  * Timestamps a response using chppTimestampOutgoingResponse() and enqueues it
813  * using chppEnqueueTxDatagramOrFail().
814  *
815  * Refer to their respective documentation for details.
816  *
817  * This function logs an error message if a response is attempted without an
818  * outstanding request.
819  *
820  * @param appState App layer state.
821  * @param inReqState State of the request/response.
822  * @param buf Datagram payload allocated through chppMalloc. Cannot be null.
823  * @param len Datagram length in bytes.
824  *
825  * @return whether the datagram was successfully enqueued. false means that the
826  *         queue was full and the payload discarded.
827  */
828 bool chppSendTimestampedResponseOrFail(
829     struct ChppAppState *appState, struct ChppIncomingRequestState *inReqState,
830     void *buf, size_t len);
831 
832 /**
833  * Timestamps and enqueues a request.
834  *
835  * This function is internal. User either:
836  * - chppClientSendTimestampedRequestOrFail
837  * - or chppServiceSendTimestampedRequestOrFail
838  *
839  * Note that the ownership of buf is taken from the caller when this method is
840  * invoked.
841  *
842  * @param endpointState state of the endpoint.
843  * @param outReqState state of the request/response.
844  * @param buf Datagram payload allocated through chppMalloc. Cannot be null.
845  * @param len Datagram length in bytes.
846  * @param timeoutNs Time in nanoseconds before a timeout response is generated.
847  *        Zero means no timeout response.
848  *
849  * @return True informs the sender that the datagram was successfully enqueued.
850  *         False informs the sender that the queue was full and the payload
851  *         discarded.
852  */
853 bool chppSendTimestampedRequestOrFail(
854     struct ChppEndpointState *endpointState,
855     struct ChppOutgoingRequestState *outReqState, void *buf, size_t len,
856     uint64_t timeoutNs);
857 
858 /**
859  * Wait for a response to be received.
860  *
861  * @param syncResponse sync primitives.
862  * @param outReqState state of the request/response.
863  * @param timeoutNs Time in nanoseconds before a timeout response is generated.
864  */
865 bool chppWaitForResponseWithTimeout(
866     struct ChppSyncResponse *syncResponse,
867     struct ChppOutgoingRequestState *outReqState, uint64_t timeoutNs);
868 
869 /**
870  * Returns the state of a registered endpoint.
871  *
872  * @param appState State of the app layer.
873  * @param index Index of the client or service.
874  * @param type Type of the endpoint to return.
875  * @return state of the client or service.
876  */
877 struct ChppEndpointState *getRegisteredEndpointState(
878     struct ChppAppState *appState, uint8_t index, enum ChppEndpointType type);
879 
880 /**
881  * Returns the number of possible outgoing requests.
882  *
883  * @param appState State of the app layer.
884  * @param index Index of the client or service.
885  * @param type Type of the endpoint to return.
886  * @return The number of possible outgoing requests.
887  */
888 uint16_t getRegisteredEndpointOutReqCount(struct ChppAppState *appState,
889                                           uint8_t index,
890                                           enum ChppEndpointType type);
891 
892 /**
893  * Returns the number of registered endpoints of the given type.
894  *
895  * @param appState State of the app layer.
896  * @param type Type of the endpoint to return.
897  * @return The number of endpoints.
898  */
899 uint8_t getRegisteredEndpointCount(struct ChppAppState *appState,
900                                    enum ChppEndpointType type);
901 
902 /**
903  * Recalculates the next upcoming request timeout.
904  *
905  * The timeout is updated in the app layer state.
906  *
907  * @param appState State of the app layer.
908  * @param type Type of the endpoint.
909  */
910 void chppRecalculateNextTimeout(struct ChppAppState *appState,
911                                 enum ChppEndpointType type);
912 
913 /**
914  * Returns a pointer to the next request timeout for the given endpoint type.
915  *
916  * @param appState State of the app layer.
917  * @param type Type of the endpoint.
918  * @return Pointer to the timeout in nanoseconds.
919  */
920 uint64_t *getNextRequestTimeoutNs(struct ChppAppState *appState,
921                                   enum ChppEndpointType type);
922 
923 /**
924  * Closes any remaining open requests by simulating a timeout.
925  *
926  * This function is used when an endpoint is reset.
927  *
928  * @param endpointState State of the endpoint.
929  * @param type The type of the endpoint.
930  * @param clearOnly If true, indicates that a timeout response shouldn't be
931  *        sent. This must only be set if the requests are being cleared as
932  *        part of the closing.
933  */
934 void chppCloseOpenRequests(struct ChppEndpointState *endpointState,
935                            enum ChppEndpointType type, bool clearOnly);
936 
937 /**
938  * Schedules a timer for the given endpoint.
939  *
940  * @param endpointState State of the endpoint.
941  * @param timeoutNs The timeout in nanoseconds.
942  * @return True if the timer was scheduled successfully.
943  */
944 bool chppAppRequestTimerTimeout(struct ChppEndpointState *endpointState,
945                                 uint64_t timeoutNs);
946 
947 /**
948  *  Cancels a timer for the given endpoint.
949  *
950  * @param endpointState State of the endpoint.
951  */
952 void chppAppCancelTimerTimeout(struct ChppEndpointState *endpointState);
953 
954 /**
955  * Returns the next timer timeout for endpoints.
956  *
957  * @param appState State of the app layer.
958  * @return The next timer timeout in nanoseconds.
959  */
960 uint64_t chppAppGetNextTimerTimeoutNs(struct ChppAppState *appState);
961 
962 #ifdef __cplusplus
963 }
964 #endif
965 
966 #endif  // CHPP_APP_H_
967