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_SERVICES_H_
18 #define CHPP_SERVICES_H_
19 
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #include "chpp/app.h"
25 #include "chpp/macros.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /************************************************
32  *  Public Definitions
33  ***********************************************/
34 
35 #if defined(CHPP_SERVICE_ENABLED_WWAN) || \
36     defined(CHPP_SERVICE_ENABLED_WIFI) || defined(CHPP_SERVICE_ENABLED_GNSS)
37 #define CHPP_SERVICE_ENABLED
38 #endif
39 
40 /**
41  * Uses chppAllocServiceNotification() to allocate a variable-length response
42  * message of a specific type.
43  *
44  * @param type Type of notification which includes an arrayed member.
45  * @param count number of items in the array of arrayField.
46  * @param arrayField The arrayed member field.
47  *
48  * @return Pointer to allocated memory
49  */
50 #define chppAllocServiceNotificationTypedArray(type, count, arrayField) \
51   (type *)chppAllocServiceNotification(                                 \
52       sizeof(type) + (count)*sizeof_member(type, arrayField[0]))
53 
54 /**
55  * Uses chppAllocServiceNotification() to allocate a response message of a
56  * specific type and its corresponding length.
57  *
58  * @param type Type of notification.
59  *
60  * @return Pointer to allocated memory
61  */
62 #define chppAllocServiceNotificationFixed(type) \
63   (type *)chppAllocServiceNotification(sizeof(type))
64 
65 /**
66  * Uses chppAllocServiceResponse() to allocate a variable-length response
67  * message of a specific type.
68  *
69  * @param requestHeader client request header, as per
70  * chppAllocServiceResponse().
71  * @param type Type of response which includes an arrayed member.
72  * @param count number of items in the array of arrayField.
73  * @param arrayField The arrayed member field.
74  *
75  * @return Pointer to allocated memory
76  */
77 #define chppAllocServiceResponseTypedArray(requestHeader, type, count, \
78                                            arrayField)                 \
79   (type *)chppAllocServiceResponse(                                    \
80       requestHeader,                                                   \
81       sizeof(type) + (count)*sizeof_member(type, arrayField[0]))
82 
83 /**
84  * Uses chppAllocServiceResponse() to allocate a response message of a specific
85  * type and its corresponding length.
86  *
87  * @param requestHeader client request header, as per
88  * chppAllocServiceResponse().
89  * @param type Type of response.
90  *
91  * @return Pointer to allocated memory
92  */
93 #define chppAllocServiceResponseFixed(requestHeader, type) \
94   (type *)chppAllocServiceResponse(requestHeader, sizeof(type))
95 
96 /**
97  * Maintains the basic state of a service.
98  * This is expected to be included once in the (context) status variable of each
99  * service.
100  */
101 struct ChppServiceState {
102   struct ChppAppState *appContext;  // Pointer to app layer context
103   uint8_t handle;                   // Handle number for this service
104 
105   uint8_t openState;  // As defined in enum ChppOpenState
106 };
107 
108 /************************************************
109  *  Public functions
110  ***********************************************/
111 
112 /**
113  * Registers common services with the CHPP app layer. These services are enabled
114  * by CHPP_SERVICE_ENABLED_xxxx definitions. This function is automatically
115  * called by chppAppInit().
116  *
117  * @param context Maintains status for each app layer instance.
118  */
119 void chppRegisterCommonServices(struct ChppAppState *context);
120 
121 /**
122  * Deregisters common services with the CHPP app layer. These services are
123  * enabled by CHPP_SERVICE_ENABLED_xxxx definitions. This function is
124  * automatically called by chppAppInit().
125  *
126  * @param context Maintains status for each app layer instance.
127  */
128 void chppDeregisterCommonServices(struct ChppAppState *context);
129 
130 /**
131  * Registers a new service on CHPP. This function is to be called by the
132  * platform initialization code for every non-common service available on a
133  * server (if any), i.e. except those that are registered through
134  * chppRegisterCommonServices().
135  *
136  * Note that the maximum number of services that can be registered on a platform
137  * can specified as CHPP_MAX_REGISTERED_SERVICES by the initialization code.
138  * Otherwise, a default value will be used.
139  *
140  * @param appContext Maintains status for each app layer instance.
141  * @param serviceContext Maintains status for each service instance.
142  * @param newService The service to be registered on this platform.
143  *
144  * @return Handle number of the registered service.
145  */
146 uint8_t chppRegisterService(struct ChppAppState *appContext,
147                             void *serviceContext,
148                             const struct ChppService *newService);
149 
150 /**
151  * Allocates a service notification of a specified length.
152  *
153  * It is expected that for most use cases, the
154  * chppAllocServiceNotificationFixed() or
155  * chppAllocServiceNotificationTypedArray() macros shall be used rather than
156  * calling this function directly.
157  *
158  * @param len Length of the notification (including header) in bytes. Note
159  * that the specified length must be at least equal to the lendth of the app
160  * layer header.
161  *
162  * @return Pointer to allocated memory
163  */
164 struct ChppAppHeader *chppAllocServiceNotification(size_t len);
165 
166 /**
167  * Allocates a service response message of a specified length, populating the
168  * (app layer) service response header accorging to the provided client request
169  * (app layer) header.
170  *
171  * It is expected that for most use cases, the chppAllocServiceResponseFixed()
172  * or chppAllocServiceResponseTypedArray() macros shall be used rather than
173  * calling this function directly.
174  *
175  * @param requestHeader Client request header.
176  * @param len Length of the response message (including header) in bytes. Note
177  * that the specified length must be at least equal to the lendth of the app
178  * layer header.
179  *
180  * @return Pointer to allocated memory
181  */
182 struct ChppAppHeader *chppAllocServiceResponse(
183     const struct ChppAppHeader *requestHeader, size_t len);
184 
185 /**
186  * This function shall be called for all incoming client requests in order to
187  * A) Timestamp them, and
188  * B) Save their Transaction ID
189  * as part of the request/response's ChppRequestResponseState struct.
190  *
191  * This function prints an error message if a duplicate request is received
192  * while outstanding request is still pending without a response.
193  *
194  * @param rRState Maintains the basic state for each request/response
195  * functionality of a service.
196  * @param requestHeader Client request header.
197  */
198 void chppServiceTimestampRequest(struct ChppRequestResponseState *rRState,
199                                  struct ChppAppHeader *requestHeader);
200 
201 /**
202  * This function shall be called for the final service response to a client
203  * request in order to
204  * A) Timestamp them, and
205  * B) Mark them as fulfilled
206  * part of the request/response's ChppRequestResponseState struct.
207  *
208  * This function prints an error message if a response is attempted without an
209  * outstanding request.
210  *
211  * For most responses, it is expected that chppSendTimestampedResponseOrFail()
212  * shall be used to both timestamp and send the response in one shot.
213  *
214  * @param rRState Maintains the basic state for each request/response
215  * functionality of a service.
216  */
217 void chppServiceTimestampResponse(struct ChppRequestResponseState *rRState);
218 
219 /**
220  * Timestamps a service response using chppServiceTimestampResponse() and
221  * enqueues it using chppEnqueueTxDatagramOrFail().
222  *
223  * Refer to their respective documentation for details.
224  *
225  * @param serviceState State of the service sending the response service.
226  * @param rRState Maintains the basic state for each request/response
227  * functionality of a service.
228  * @param buf Datagram payload allocated through chppMalloc. Cannot be null.
229  * @param len Datagram length in bytes.
230  *
231  * @return True informs the sender that the datagram was successfully enqueued.
232  * False informs the sender that the queue was full and the payload discarded.
233  */
234 bool chppSendTimestampedResponseOrFail(struct ChppServiceState *serviceState,
235                                        struct ChppRequestResponseState *rRState,
236                                        void *buf, size_t len);
237 
238 #ifdef __cplusplus
239 }
240 #endif
241 
242 #endif  // CHPP_SERVICES_H_
243