blob: a4f15e4cf7f96a2bc562f90ba1b31908f30a181d [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;
50 struct rpc_interface *successor;
Julian Hall2dcd69c2020-11-23 18:05:04 +010051};
52
julhal01c3f4e9a2020-12-15 13:39:01 +000053static inline struct rpc_interface *service_provider_get_rpc_interface(struct service_provider *sp)
Julian Hall2dcd69c2020-11-23 18:05:04 +010054{
julhal01c3f4e9a2020-12-15 13:39:01 +000055 return &sp->iface;
Julian Hall2dcd69c2020-11-23 18:05:04 +010056}
57
58void service_provider_init(struct service_provider *sp, void *context,
julhal01c3f4e9a2020-12-15 13:39:01 +000059 const struct service_handler *handlers,
60 size_t num_handlers);
Julian Hall2dcd69c2020-11-23 18:05:04 +010061
Julian Hall13e76952021-07-13 12:17:09 +010062/*
63 * Extend the core set of operations provided by a service provider by
64 * adding a sub provider that will add a capability. This facility
65 * allows a deployment to customize the set of operations
66 * supported to meet requirements by only extending the core service
67 * provider if needed.
68 */
69void service_provider_extend(struct service_provider *context,
70 struct service_provider *sub_provider);
71
72/*
73 * Link a successor to this service provider to extend the chain of responsibility
74 * to allow call handling to be delegated to different components. Used to support
75 * modular configuration of service capabilities.
76 */
julhal01c3f4e9a2020-12-15 13:39:01 +000077static inline void service_provider_link_successor(struct service_provider *sp,
78 struct rpc_interface *successor)
Julian Hall2dcd69c2020-11-23 18:05:04 +010079{
julhal01c3f4e9a2020-12-15 13:39:01 +000080 sp->successor = successor;
Julian Hall2dcd69c2020-11-23 18:05:04 +010081}
82
83#ifdef __cplusplus
84}
85#endif
86
87#endif /* SERVICE_PROVIDER_H */