blob: a0e853e2e9c1c2a95235e3be1c573c05d612119c [file] [log] [blame]
Julian Hall2dcd69c2020-11-23 18:05:04 +01001/*
julhal01c3f4e9a2020-12-15 13:39:01 +00002 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
Julian Hall2dcd69c2020-11-23 18:05:04 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef SERVICE_PROVIDER_H
8#define SERVICE_PROVIDER_H
9
julhal01c3f4e9a2020-12-15 13:39:01 +000010#include <rpc/common/endpoint/rpc_interface.h>
Julian Hall2dcd69c2020-11-23 18:05:04 +010011#include <stddef.h>
12#include <stdint.h>
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18/** \brief Service handler
19 *
20 * Defines a mapping between an opcode and a handler function. A complete
21 * service interface is defined by an array of service request handlers.
22 */
23struct service_handler {
24 uint32_t opcode;
25 rpc_status_t (*invoke)(void *context, struct call_req* req);
26};
27
28static inline int service_handler_invoke(const struct service_handler *handler,
29 void *context, struct call_req* req)
30{
31 return handler->invoke(context, req);
32}
33
34static inline uint32_t service_handler_get_opcode(const struct service_handler *handler)
35{
36 return handler->opcode;
37}
38
39/** \brief Service provider
40 *
41 * A generalised service provider that acts as an rpc call endpoint. It receives call
42 * requests and delegates them to the approprate handle provided by a concrete service
julhal01c3f4e9a2020-12-15 13:39:01 +000043 * provider. To support service specialization and proxying, unhandled requests may
44 * optionally be passed to a delegate rpc_interface to form a chain of responsibility.
Julian Hall2dcd69c2020-11-23 18:05:04 +010045 */
46struct service_provider {
julhal01c3f4e9a2020-12-15 13:39:01 +000047 struct rpc_interface iface;
48 const struct service_handler *handlers;
49 size_t num_handlers;
Julian Hall65ff9052021-07-27 09:08:32 +010050 uint32_t opcode_range_lo;
51 uint32_t opcode_range_hi;
julhal01c3f4e9a2020-12-15 13:39:01 +000052 struct rpc_interface *successor;
Julian Hall2dcd69c2020-11-23 18:05:04 +010053};
54
julhal01c3f4e9a2020-12-15 13:39:01 +000055static inline struct rpc_interface *service_provider_get_rpc_interface(struct service_provider *sp)
Julian Hall2dcd69c2020-11-23 18:05:04 +010056{
julhal01c3f4e9a2020-12-15 13:39:01 +000057 return &sp->iface;
Julian Hall2dcd69c2020-11-23 18:05:04 +010058}
59
60void service_provider_init(struct service_provider *sp, void *context,
julhal01c3f4e9a2020-12-15 13:39:01 +000061 const struct service_handler *handlers,
62 size_t num_handlers);
Julian Hall2dcd69c2020-11-23 18:05:04 +010063
Julian Hall13e76952021-07-13 12:17:09 +010064/*
65 * Extend the core set of operations provided by a service provider by
66 * adding a sub provider that will add a capability. This facility
67 * allows a deployment to customize the set of operations
68 * supported to meet requirements by only extending the core service
69 * provider if needed.
70 */
71void service_provider_extend(struct service_provider *context,
72 struct service_provider *sub_provider);
73
74/*
75 * Link a successor to this service provider to extend the chain of responsibility
76 * to allow call handling to be delegated to different components. Used to support
77 * modular configuration of service capabilities.
78 */
julhal01c3f4e9a2020-12-15 13:39:01 +000079static inline void service_provider_link_successor(struct service_provider *sp,
80 struct rpc_interface *successor)
Julian Hall2dcd69c2020-11-23 18:05:04 +010081{
julhal01c3f4e9a2020-12-15 13:39:01 +000082 sp->successor = successor;
Julian Hall2dcd69c2020-11-23 18:05:04 +010083}
84
85#ifdef __cplusplus
86}
87#endif
88
89#endif /* SERVICE_PROVIDER_H */