blob: fe2dfe72556317e345a91db357672a900b5d2437 [file] [log] [blame] [edit]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef CHPP_CLIENTS_H_
#define CHPP_CLIENTS_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "chpp/app.h"
#include "chpp/condition_variable.h"
#include "chpp/macros.h"
#include "chpp/mutex.h"
#ifdef __cplusplus
extern "C" {
#endif
/************************************************
* Public Definitions
***********************************************/
/**
* Allocates a client request message of a specific type and its corresponding
* length.
*
* @param clientState State of the client.
* @param type Type of response.
*
* @return Pointer to allocated memory
*/
#define chppAllocClientRequestFixed(clientState, type) \
(type *)chppAllocClientRequest(clientState, sizeof(type))
/**
* Allocates a variable-length client request message of a specific type.
*
* @param clientState State of the client.
* @param type Type of response which includes an arrayed member.
* @param count number of items in the array of arrayField.
* @param arrayField The arrayed member field.
*
* @return Pointer to allocated memory
*/
#define chppAllocClientRequestTypedArray(clientState, type, count, arrayField) \
(type *)chppAllocClientRequest( \
clientState, sizeof(type) + (count)*sizeof_member(type, arrayField[0]))
/**
* Allocates a variable-length notification of a specific type.
*
* @param type Type of notification which includes an arrayed member.
* @param count number of items in the array of arrayField.
* @param arrayField The arrayed member field.
*
* @return Pointer to allocated memory
*/
#define chppAllocClientNotificationTypedArray(type, count, arrayField) \
(type *)chppAllocClientNotification( \
sizeof(type) + (count)*sizeof_member(type, arrayField[0]))
/**
* Allocates a notification of a specific type and its corresponding length.
*
* @param type Type of notification.
*
* @return Pointer to allocated memory
*/
#define chppAllocClientNotificationFixed(type) \
(type *)chppAllocClientNotification(sizeof(type))
#ifdef CHPP_CLIENT_ENABLED_CHRE_WWAN
#define CHPP_CLIENT_ENABLED_WWAN
#endif
#ifdef CHPP_CLIENT_ENABLED_CHRE_WIFI
#define CHPP_CLIENT_ENABLED_WIFI
#endif
#ifdef CHPP_CLIENT_ENABLED_CHRE_GNSS
#define CHPP_CLIENT_ENABLED_GNSS
#endif
#if defined(CHPP_CLIENT_ENABLED_LOOPBACK) || \
defined(CHPP_CLIENT_ENABLED_TIMESYNC) || \
defined(CHPP_CLIENT_ENABLED_DISCOVERY) || \
defined(CHPP_CLIENT_ENABLED_WWAN) || defined(CHPP_CLIENT_ENABLED_WIFI) || \
defined(CHPP_CLIENT_ENABLED_GNSS)
#define CHPP_CLIENT_ENABLED
#endif
// Default timeout for discovery completion.
#ifndef CHPP_DISCOVERY_DEFAULT_TIMEOUT_MS
#define CHPP_DISCOVERY_DEFAULT_TIMEOUT_MS UINT64_C(10000) // 10s
#endif
/************************************************
* Public functions
***********************************************/
/**
* Registers common clients with the CHPP app layer. These clients are enabled
* by CHPP_CLIENT_ENABLED_xxxx definitions. This function is automatically
* called by chppAppInit().
*
* @param context State of the app layer.
*/
void chppRegisterCommonClients(struct ChppAppState *context);
/**
* Deregisters common clients with the CHPP app layer. These clients are enabled
* by CHPP_CLIENT_ENABLED_xxxx definitions. This function is automatically
* called by chppAppDeinit().
*
* @param context State of the app layer.
*/
void chppDeregisterCommonClients(struct ChppAppState *context);
/**
* Registers a new client on CHPP.
*
* This function is to be called by the platform initialization code for every
* non-common client available on a server (if any), i.e. except those that are
* registered through chppRegisterCommonClients().
*
* Registered clients are matched with discovered services during discovery.
* When a match succeeds, the client's initialization function (pointer) is
* called, assigning them their handle number.
*
* outReqStates must point to an array of ChppOutgoingRequestState with
* ChppEndpointState.outReqCount elements. It must be NULL when the client
* does not send requests (ChppEndpointState.outReqCount = 0).
*
* inReqStates must point to an array of ChppIncomingRequestState with
* as many elements as the corresponding service can send. It must be NULL when
* the service does not send requests (ChppEndpointState.outReqCount = 0).
*
* Note that the maximum number of clients that can be registered on a platform
* can specified as CHPP_MAX_REGISTERED_CLIENTS by the initialization code.
* Otherwise, a default value will be used.
*
* @param appContext State of the app layer.
* @param clientContext State of the client instance.
* @param clientState State of the client.
* @param outReqStates List of outgoing request states.
* @param newClient The client to be registered on this platform.
*/
void chppRegisterClient(struct ChppAppState *appContext, void *clientContext,
struct ChppEndpointState *clientState,
struct ChppOutgoingRequestState *outReqStates,
const struct ChppClient *newClient);
/**
* Initializes basic CHPP clients.
*
* @param context State of the app layer.
*/
void chppInitBasicClients(struct ChppAppState *context);
/**
* Initializes a client. This function must be called when a client is matched
* with a service during discovery to provides its handle number.
*
* @param clientState State of the client.
* @param handle Handle number for this client.
*/
void chppClientInit(struct ChppEndpointState *clientState, uint8_t handle);
/**
* Deinitializes a client.
*
* @param clientState State of the client.
*/
void chppClientDeinit(struct ChppEndpointState *clientState);
/**
* Deinitializes basic clients.
*
* @param context State of the app layer.
*/
void chppDeinitBasicClients(struct ChppAppState *context);
/**
* Deinitializes all matched clients.
*
* @param context State of the app layer.
*/
void chppDeinitMatchedClients(struct ChppAppState *context);
/**
* Allocates a client request message of a specified length.
*
* It populates the request header, including the transaction number which is
* then incremented.
*
* For most use cases, the chppAllocClientRequestFixed() or
* chppAllocClientRequestTypedArray() macros shall be preferred.
*
* @param clientState State of the client.
* @param len Length of the response message (including header) in bytes. Note
* that the specified length must be at least equal to the length of the
* app layer header.
*
* @return Pointer to allocated memory
*/
struct ChppAppHeader *chppAllocClientRequest(
struct ChppEndpointState *clientState, size_t len);
/**
* Allocates a specific client request command without any additional payload.
*
* @param clientState State of the client.
* @param command Type of response.
*
* @return Pointer to allocated memory
*/
struct ChppAppHeader *chppAllocClientRequestCommand(
struct ChppEndpointState *clientState, uint16_t command);
/**
* Timestamps and enqueues a request.
*
* Note that the ownership of buf is taken from the caller when this method is
* invoked.
*
* @param clientState State of the client sending the request.
* @param outReqState State of the request/response
* @param buf Datagram payload allocated through chppMalloc. Cannot be null.
* @param len Datagram length in bytes.
* @param timeoutNs Time in nanoseconds before a timeout response is generated.
* Zero means no timeout response.
*
* @return True informs the sender that the datagram was successfully enqueued.
* False informs the sender that the queue was full and the payload
* discarded.
*/
bool chppClientSendTimestampedRequestOrFail(
struct ChppEndpointState *clientState,
struct ChppOutgoingRequestState *outReqState, void *buf, size_t len,
uint64_t timeoutNs);
/**
* Similar to chppClientSendTimestampedRequestOrFail() but blocks execution
* until a response is received. Used for synchronous requests.
*
* In order to use this function, clientState->responseNotifier must have been
* initialized using chppNotifierInit() upon initialization of the client.
*
* @param clientState State of the client sending the request.
* @param outReqState State of the request/response.
* @param buf Datagram payload allocated through chppMalloc. Cannot be null.
* @param len Datagram length in bytes.
*
* @return True informs the sender that the datagram was successfully enqueued.
* False informs the sender that the payload was discarded because
* either the queue was full, or the request timed out.
*/
bool chppClientSendTimestampedRequestAndWait(
struct ChppEndpointState *clientState,
struct ChppOutgoingRequestState *outReqState, void *buf, size_t len);
/**
* Same as chppClientSendTimestampedRequestAndWait() but with a specified
* timeout.
*
* @param clientState State of the client sending the request.
* @param outReqState State of the request/response.
* @param buf Datagram payload allocated through chppMalloc. Cannot be null.
* @param len Datagram length in bytes.
*
* @return True informs the sender that the datagram was successfully enqueued.
* False informs the sender that the payload was discarded because
* either the queue was full, or the request timed out.
*/
bool chppClientSendTimestampedRequestAndWaitTimeout(
struct ChppEndpointState *clientState,
struct ChppOutgoingRequestState *outReqState, void *buf, size_t len,
uint64_t timeoutNs);
/**
* Marks a closed client as pseudo-open, so that it would be opened upon a
* reset.
*
* @param clientState State of the client.
*/
void chppClientPseudoOpen(struct ChppEndpointState *clientState);
/**
* Sends a client request for the open command in a blocking or non-blocking
* manner.
* A non-blocking open is used to for reopening a service after a reset or for
* opening a pseudo-open service.
*
* @param clientState State of the client.
* @param openReqState State of the request/response for the open command.
* @param openCommand Open command to be sent.
* @param blocking Indicates a blocking (vs. non-blocking) open request.
*
* @return Indicates success or failure.
*/
bool chppClientSendOpenRequest(struct ChppEndpointState *clientState,
struct ChppOutgoingRequestState *openReqState,
uint16_t openCommand, bool blocking);
/**
* Processes a service response for the open command.
*
* @param clientState State of the client.
*/
void chppClientProcessOpenResponse(struct ChppEndpointState *clientState,
uint8_t *buf, size_t len);
/**
* Closes any remaining open requests by simulating a timeout.
* This function is used when a client is reset.
*
* @param clientState State of the client.
* @param client The client for which to clear out open requests.
* @param clearOnly If true, indicates that a timeout response shouldn't be
* sent. This must only be set if the requests are being cleared as part
* of the client closing.
*/
void chppClientCloseOpenRequests(struct ChppEndpointState *clientState,
const struct ChppClient *client,
bool clearOnly);
/**
* Allocates a client notification of a specified length.
*
* It is expected that for most use cases, the
* chppAllocClientNotificationFixed() or
* chppAllocClientNotificationTypedArray() macros shall be used rather than
* calling this function directly.
*
* The caller must initialize at least the handle and command fields of the
* ChppAppHeader.
*
* @param len Length of the notification (including header) in bytes. Note
* that the specified length must be at least equal to the length of the
* app layer header.
*
* @return Pointer to allocated memory.
*/
struct ChppAppHeader *chppAllocClientNotification(size_t len);
#ifdef __cplusplus
}
#endif
#endif // CHPP_CLIENTS_H_