diff options
author | Julian Hall <julian.hall@arm.com> | 2021-06-25 10:15:01 +0100 |
---|---|---|
committer | Gyorgy Szing <Gyorgy.Szing@arm.com> | 2021-10-05 22:55:46 +0200 |
commit | a6b3e1cf8b42df109d6d73c1e9beb6a6c83cb631 (patch) | |
tree | 7cf5b0baee6b249bc942a7bd693cd12b4ef5a5e7 | |
parent | d03aced2891b8cffdba0517d3119958df0d3b46c (diff) | |
download | trusted-services-a6b3e1cf8b42df109d6d73c1e9beb6a6c83cb631.tar.gz |
Add RPC demux component
To support multiple co-located service providers, the rpc_demux
may be used. It presents a single input rpc_interface and
demultiplexes incoming call requests to 1..* attached outputs
using the interface_id parameter carried by the underlying
RPC.
Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I03d7423892cd07d8a8fcd445dbb7dc7e62497455
-rw-r--r-- | components/rpc/common/demux/component.cmake | 13 | ||||
-rw-r--r-- | components/rpc/common/demux/rpc_demux.c | 57 | ||||
-rw-r--r-- | components/rpc/common/demux/rpc_demux.h | 78 | ||||
-rw-r--r-- | components/rpc/common/endpoint/rpc_interface.h | 10 | ||||
-rw-r--r-- | deployments/component-test/component-test.cmake | 1 | ||||
-rw-r--r-- | protocols/rpc/common/packed-c/status.h | 3 |
6 files changed, 160 insertions, 2 deletions
diff --git a/components/rpc/common/demux/component.cmake b/components/rpc/common/demux/component.cmake new file mode 100644 index 000000000..a02eefc3e --- /dev/null +++ b/components/rpc/common/demux/component.cmake @@ -0,0 +1,13 @@ +#------------------------------------------------------------------------------- +# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +#------------------------------------------------------------------------------- +if (NOT DEFINED TGT) + message(FATAL_ERROR "mandatory parameter TGT is not defined.") +endif() + +target_sources(${TGT} PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/rpc_demux.c" + ) diff --git a/components/rpc/common/demux/rpc_demux.c b/components/rpc/common/demux/rpc_demux.c new file mode 100644 index 000000000..efcc16254 --- /dev/null +++ b/components/rpc/common/demux/rpc_demux.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <stddef.h> +#include <protocols/rpc/common/packed-c/status.h> +#include "rpc_demux.h" + +static rpc_status_t receive(struct rpc_interface *rpc_iface, struct call_req *req) +{ + rpc_status_t rpc_status = TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST; + struct rpc_demux *context = (struct rpc_demux*)rpc_iface->context; + + unsigned int iface_id = call_req_get_interface_id(req); + + if ((iface_id < RPC_DEMUX_MAX_OUTPUTS) && context->outputs[iface_id]) { + + rpc_status = rpc_interface_receive(context->outputs[iface_id], req); + } + + return rpc_status; +} + +struct rpc_interface *rpc_demux_init(struct rpc_demux *context) +{ + context->input.receive = receive; + context->input.context = context; + + for (unsigned int i = 0; i < RPC_DEMUX_MAX_OUTPUTS; ++i) { + + context->outputs[i] = NULL; + } + + return &context->input; +} + +void rpc_demux_deinit(struct rpc_demux *context) +{ + (void)context; +} + +void rpc_demux_attach(struct rpc_demux *context, + unsigned int iface_id, struct rpc_interface *output) +{ + assert(iface_id < RPC_DEMUX_MAX_OUTPUTS); + context->outputs[iface_id] = output; +} + +void rpc_demux_dettach(struct rpc_demux *context, + unsigned int iface_id) +{ + assert(iface_id < RPC_DEMUX_MAX_OUTPUTS); + context->outputs[iface_id] = NULL; +} diff --git a/components/rpc/common/demux/rpc_demux.h b/components/rpc/common/demux/rpc_demux.h new file mode 100644 index 000000000..46d7b0fb7 --- /dev/null +++ b/components/rpc/common/demux/rpc_demux.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RPC_DEMUX_H +#define RPC_DEMUX_H + +#include <rpc/common/endpoint/rpc_interface.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The default maximum number of output interfaces. May be + * overridden to meet needs of deployment if necessary. + */ +#ifndef RPC_DEMUX_MAX_OUTPUTS +#define RPC_DEMUX_MAX_OUTPUTS (8) +#endif + +/** \brief RPC demux + * + * An rpc_demux is an rpc_interface that demultiplexes incoming call requests + * to 1..* output interfaces. Use an rpc_demux when multiple service + * providers are co-located and associated with a single RPC endpoint. + */ +struct rpc_demux +{ + struct rpc_interface input; + struct rpc_interface *outputs[RPC_DEMUX_MAX_OUTPUTS]; +}; + +/** + * \brief Initialize an rpc_demux + * + * After initialization, the required number of output interfaces need + * to be attached, + * + * \param[in] context The instance to initialize + * + * \return The input rpc_interface + */ +struct rpc_interface *rpc_demux_init(struct rpc_demux *context); + +/** + * \brief Cleans up when the instance is no longer needed + * + * \param[in] context The instance to de-initialize + */ +void rpc_demux_deinit(struct rpc_demux *context); + +/** + * \brief Attach an output interface + * + * \param[in] context The rpc_demux instance + * \param[in] iface_id The interface id (small integer) + * \param[in] output The interface to attach + */ +void rpc_demux_attach(struct rpc_demux *context, + unsigned int iface_id, struct rpc_interface *output); + +/** + * \brief Dettach an output interface + * + * \param[in] context The rpc_demux instance + * \param[in] iface_id The interface id (small integer) + */ +void rpc_demux_dettach(struct rpc_demux *context, + unsigned int iface_id); + +#ifdef __cplusplus +} +#endif + +#endif /* RPC_DEMUX_H */ diff --git a/components/rpc/common/endpoint/rpc_interface.h b/components/rpc/common/endpoint/rpc_interface.h index 44e578354..ba949dedc 100644 --- a/components/rpc/common/endpoint/rpc_interface.h +++ b/components/rpc/common/endpoint/rpc_interface.h @@ -10,6 +10,7 @@ #include <stddef.h> #include <stdint.h> #include <rpc_status.h> +#include <protocols/rpc/common/packed-c/status.h> #ifdef __cplusplus extern "C" { @@ -120,7 +121,14 @@ struct rpc_interface static inline rpc_status_t rpc_interface_receive(struct rpc_interface *iface, struct call_req *req) { - return iface->receive(iface, req); + rpc_status_t rpc_status = TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST; + + if (iface) { + + rpc_status = iface->receive(iface, req); + } + + return rpc_status; } #ifdef __cplusplus diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake index dfa006825..974e4e262 100644 --- a/deployments/component-test/component-test.cmake +++ b/deployments/component-test/component-test.cmake @@ -26,6 +26,7 @@ add_components( "components/config/ramstore/test" "components/rpc/common/caller" "components/rpc/common/interface" + "components/rpc/common/demux" "components/rpc/common/test/protocol" "components/rpc/direct" "components/rpc/dummy" diff --git a/protocols/rpc/common/packed-c/status.h b/protocols/rpc/common/packed-c/status.h index 3838240df..534f0dfb1 100644 --- a/protocols/rpc/common/packed-c/status.h +++ b/protocols/rpc/common/packed-c/status.h @@ -25,7 +25,8 @@ enum TS_RPC_ERROR_NOT_READY = -7, TS_RPC_ERROR_INVALID_TRANSACTION = -8, TS_RPC_ERROR_INTERNAL = -9, - TS_RPC_ERROR_INVALID_PARAMETER = -10 + TS_RPC_ERROR_INVALID_PARAMETER = -10, + TS_RPC_ERROR_INTERFACE_DOES_NOT_EXIST = -11 }; #endif /* PROTOCOLS_RPC_COMMON_STATUS_H */ |