blob: 508a93fb94c1c75c1e237a8f91d1dbcbd134b3ad [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
julhal01c3f4e9a2020-12-15 13:39:01 +000062static inline void service_provider_link_successor(struct service_provider *sp,
63 struct rpc_interface *successor)
Julian Hall2dcd69c2020-11-23 18:05:04 +010064{
julhal01c3f4e9a2020-12-15 13:39:01 +000065 sp->successor = successor;
Julian Hall2dcd69c2020-11-23 18:05:04 +010066}
67
68#ifdef __cplusplus
69}
70#endif
71
72#endif /* SERVICE_PROVIDER_H */