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 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 /************************************************ 34 * Public Definitions 35 ***********************************************/ 36 37 /** 38 * Allocates a client request message of a specific type and its corresponding 39 * length. 40 * 41 * @param clientState State of the client. 42 * @param type Type of response. 43 * 44 * @return Pointer to allocated memory 45 */ 46 #define chppAllocClientRequestFixed(clientState, type) \ 47 (type *)chppAllocClientRequest(clientState, sizeof(type)) 48 49 /** 50 * Allocates a variable-length client request message of a specific type. 51 * 52 * @param clientState State of the client. 53 * @param type Type of response which includes an arrayed member. 54 * @param count number of items in the array of arrayField. 55 * @param arrayField The arrayed member field. 56 * 57 * @return Pointer to allocated memory 58 */ 59 #define chppAllocClientRequestTypedArray(clientState, type, count, arrayField) \ 60 (type *)chppAllocClientRequest( \ 61 clientState, sizeof(type) + (count)*sizeof_member(type, arrayField[0])) 62 63 /** 64 * Allocates a variable-length notification of a specific type. 65 * 66 * @param type Type of notification which includes an arrayed member. 67 * @param count number of items in the array of arrayField. 68 * @param arrayField The arrayed member field. 69 * 70 * @return Pointer to allocated memory 71 */ 72 #define chppAllocClientNotificationTypedArray(type, count, arrayField) \ 73 (type *)chppAllocClientNotification( \ 74 sizeof(type) + (count)*sizeof_member(type, arrayField[0])) 75 76 /** 77 * Allocates a notification of a specific type and its corresponding length. 78 * 79 * @param type Type of notification. 80 * 81 * @return Pointer to allocated memory 82 */ 83 #define chppAllocClientNotificationFixed(type) \ 84 (type *)chppAllocClientNotification(sizeof(type)) 85 86 #ifdef CHPP_CLIENT_ENABLED_CHRE_WWAN 87 #define CHPP_CLIENT_ENABLED_WWAN 88 #endif 89 90 #ifdef CHPP_CLIENT_ENABLED_CHRE_WIFI 91 #define CHPP_CLIENT_ENABLED_WIFI 92 #endif 93 94 #ifdef CHPP_CLIENT_ENABLED_CHRE_GNSS 95 #define CHPP_CLIENT_ENABLED_GNSS 96 #endif 97 98 #if defined(CHPP_CLIENT_ENABLED_LOOPBACK) || \ 99 defined(CHPP_CLIENT_ENABLED_TIMESYNC) || \ 100 defined(CHPP_CLIENT_ENABLED_DISCOVERY) || \ 101 defined(CHPP_CLIENT_ENABLED_WWAN) || defined(CHPP_CLIENT_ENABLED_WIFI) || \ 102 defined(CHPP_CLIENT_ENABLED_GNSS) 103 #define CHPP_CLIENT_ENABLED 104 #endif 105 106 // Default timeout for discovery completion. 107 #ifndef CHPP_DISCOVERY_DEFAULT_TIMEOUT_MS 108 #define CHPP_DISCOVERY_DEFAULT_TIMEOUT_MS UINT64_C(10000) // 10s 109 #endif 110 111 /************************************************ 112 * Public functions 113 ***********************************************/ 114 115 /** 116 * Registers common clients with the CHPP app layer. These clients are enabled 117 * by CHPP_CLIENT_ENABLED_xxxx definitions. This function is automatically 118 * called by chppAppInit(). 119 * 120 * @param context State of the app layer. 121 */ 122 void chppRegisterCommonClients(struct ChppAppState *context); 123 124 /** 125 * Deregisters common clients with the CHPP app layer. These clients are enabled 126 * by CHPP_CLIENT_ENABLED_xxxx definitions. This function is automatically 127 * called by chppAppDeinit(). 128 * 129 * @param context State of the app layer. 130 */ 131 void chppDeregisterCommonClients(struct ChppAppState *context); 132 133 /** 134 * Registers a new client on CHPP. 135 * 136 * This function is to be called by the platform initialization code for every 137 * non-common client available on a server (if any), i.e. except those that are 138 * registered through chppRegisterCommonClients(). 139 * 140 * Registered clients are matched with discovered services during discovery. 141 * When a match succeeds, the client's initialization function (pointer) is 142 * called, assigning them their handle number. 143 * 144 * outReqStates must point to an array of ChppOutgoingRequestState with 145 * ChppEndpointState.outReqCount elements. It must be NULL when the client 146 * does not send requests (ChppEndpointState.outReqCount = 0). 147 * 148 * inReqStates must point to an array of ChppIncomingRequestState with 149 * as many elements as the corresponding service can send. It must be NULL when 150 * the service does not send requests (ChppEndpointState.outReqCount = 0). 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 of the client. 159 * @param outReqStates List of outgoing request states. 160 * @param newClient The client to be registered on this platform. 161 */ 162 void chppRegisterClient(struct ChppAppState *appContext, void *clientContext, 163 struct ChppEndpointState *clientState, 164 struct ChppOutgoingRequestState *outReqStates, 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 of the client. 179 * @param handle Handle number for this client. 180 */ 181 void chppClientInit(struct ChppEndpointState *clientState, uint8_t handle); 182 183 /** 184 * Deinitializes a client. 185 * 186 * @param clientState State of the client. 187 */ 188 void chppClientDeinit(struct ChppEndpointState *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. 206 * 207 * It populates the request header, including the transaction number which is 208 * then incremented. 209 * 210 * For most use cases, the chppAllocClientRequestFixed() or 211 * chppAllocClientRequestTypedArray() macros shall be preferred. 212 * 213 * @param clientState State of the client. 214 * @param len Length of the response message (including header) in bytes. Note 215 * that the specified length must be at least equal to the length of the 216 * app layer header. 217 * 218 * @return Pointer to allocated memory 219 */ 220 struct ChppAppHeader *chppAllocClientRequest( 221 struct ChppEndpointState *clientState, size_t len); 222 223 /** 224 * Allocates a specific client request command without any additional payload. 225 * 226 * @param clientState State of the client. 227 * @param command Type of response. 228 * 229 * @return Pointer to allocated memory 230 */ 231 struct ChppAppHeader *chppAllocClientRequestCommand( 232 struct ChppEndpointState *clientState, uint16_t command); 233 234 /** 235 * Timestamps and enqueues a request. 236 * 237 * Note that the ownership of buf is taken from the caller when this method is 238 * invoked. 239 * 240 * @param clientState State of the client sending the request. 241 * @param outReqState State of the request/response 242 * @param buf Datagram payload allocated through chppMalloc. Cannot be null. 243 * @param len Datagram length in bytes. 244 * @param timeoutNs Time in nanoseconds before a timeout response is generated. 245 * Zero means no timeout response. 246 * 247 * @return True informs the sender that the datagram was successfully enqueued. 248 * False informs the sender that the queue was full and the payload 249 * discarded. 250 */ 251 bool chppClientSendTimestampedRequestOrFail( 252 struct ChppEndpointState *clientState, 253 struct ChppOutgoingRequestState *outReqState, void *buf, size_t len, 254 uint64_t timeoutNs); 255 256 /** 257 * Similar to chppClientSendTimestampedRequestOrFail() but blocks execution 258 * until a response is received. Used for synchronous requests. 259 * 260 * In order to use this function, clientState->responseNotifier must have been 261 * initialized using chppNotifierInit() upon initialization of the client. 262 * 263 * @param clientState State of the client sending the request. 264 * @param outReqState State of the request/response. 265 * @param buf Datagram payload allocated through chppMalloc. Cannot be null. 266 * @param len Datagram length in bytes. 267 * 268 * @return True informs the sender that the datagram was successfully enqueued. 269 * False informs the sender that the payload was discarded because 270 * either the queue was full, or the request timed out. 271 */ 272 bool chppClientSendTimestampedRequestAndWait( 273 struct ChppEndpointState *clientState, 274 struct ChppOutgoingRequestState *outReqState, void *buf, size_t len); 275 276 /** 277 * Same as chppClientSendTimestampedRequestAndWait() but with a specified 278 * timeout. 279 * 280 * @param clientState State of the client sending the request. 281 * @param outReqState State of the request/response. 282 * @param buf Datagram payload allocated through chppMalloc. Cannot be null. 283 * @param len Datagram length in bytes. 284 * 285 * @return True informs the sender that the datagram was successfully enqueued. 286 * False informs the sender that the payload was discarded because 287 * either the queue was full, or the request timed out. 288 */ 289 bool chppClientSendTimestampedRequestAndWaitTimeout( 290 struct ChppEndpointState *clientState, 291 struct ChppOutgoingRequestState *outReqState, void *buf, size_t len, 292 uint64_t timeoutNs); 293 294 /** 295 * Marks a closed client as pseudo-open, so that it would be opened upon a 296 * reset. 297 * 298 * @param clientState State of the client. 299 */ 300 void chppClientPseudoOpen(struct ChppEndpointState *clientState); 301 302 /** 303 * Sends a client request for the open command in a blocking or non-blocking 304 * manner. 305 * A non-blocking open is used to for reopening a service after a reset or for 306 * opening a pseudo-open service. 307 * 308 * @param clientState State of the client. 309 * @param openReqState State of the request/response for the open command. 310 * @param openCommand Open command to be sent. 311 * @param blocking Indicates a blocking (vs. non-blocking) open request. 312 * 313 * @return Indicates success or failure. 314 */ 315 bool chppClientSendOpenRequest(struct ChppEndpointState *clientState, 316 struct ChppOutgoingRequestState *openReqState, 317 uint16_t openCommand, bool blocking); 318 319 /** 320 * Processes a service response for the open command. 321 * 322 * @param clientState State of the client. 323 */ 324 void chppClientProcessOpenResponse(struct ChppEndpointState *clientState, 325 uint8_t *buf, size_t len); 326 327 /** 328 * Closes any remaining open requests by simulating a timeout. 329 330 * This function is used when a client is reset. 331 * 332 * @param clientState State of the client. 333 * @param client The client for which to clear out open requests. 334 * @param clearOnly If true, indicates that a timeout response shouldn't be 335 * sent. This must only be set if the requests are being cleared as part 336 * of the client closing. 337 */ 338 void chppClientCloseOpenRequests(struct ChppEndpointState *clientState, 339 const struct ChppClient *client, 340 bool clearOnly); 341 342 /** 343 * Allocates a client notification of a specified length. 344 * 345 * It is expected that for most use cases, the 346 * chppAllocClientNotificationFixed() or 347 * chppAllocClientNotificationTypedArray() macros shall be used rather than 348 * calling this function directly. 349 * 350 * The caller must initialize at least the handle and command fields of the 351 * ChppAppHeader. 352 * 353 * @param len Length of the notification (including header) in bytes. Note 354 * that the specified length must be at least equal to the length of the 355 * app layer header. 356 * 357 * @return Pointer to allocated memory. 358 */ 359 struct ChppAppHeader *chppAllocClientNotification(size_t len); 360 361 #ifdef __cplusplus 362 } 363 #endif 364 365 #endif // CHPP_CLIENTS_H_ 366