1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <lib/tipc/tipc.h>
20 #include <lk/compiler.h>
21 #include <lk/list.h>
22 #include <stddef.h>
23 
24 __BEGIN_CDECLS
25 
26 /**
27  * DOC: Theory of Operation
28  *
29  * This module implements TIPC service framework that supports
30  * hosting multiple TIPC services within single applications in a
31  * unified manner. The service set is semi-static, it can be instantiated
32  * at runtime but individual services are not expected to terminate once
33  * instantiated.
34  *
35  * An individual TIPC service consists of one or more TIPC ports that external
36  * clients can connect to. All ports for the same service share the same set
37  * of user provided ops (callbacks) that framework invokes to handle requests
38  * in a uniform way.
39 
40  * Each port can be configured individually to accept connections only from
41  * predefined set of clients identified by UUIDs.
42  *
43  * Each service can be configured to accept only limited number of connection
44  * across all ports within service.
45  *
46  * It is expected that application would make the following sequence of calls:
47  *
48  *  - call tipc_hset_create function to create handle set
49  *
50  *  - allocate statically or dynamically and initialize one or more tipc_port
51  *    structures describing set of ports related to particular services
52  *
53  *  - allocate statically or dynamically and initialize tipc_srv_ops struct
54  *    containing pointers for service specific callbacks.
55  *
56  *  - call tipc_add_service to add service to service set. Multiple services
57  *  can be added to the same service set.
58  *
59  *  - call tipc_run_event_loop to run them. This routine is not expected
60  *  to return unless unrecoverable condition is encountered.
61  */
62 
63 /**
64  * struct tipc_port_acl - tipc port ACL descriptor
65  * @flags:      a combination of IPC_PORT_ALLOW_XXX_CONNECT flags that will be
66  *              directly passed to underlying port_create call.
67  * @uuid_num:   number of entries in an array pointed by @uuids field
68  * @uuids:      pointer to array of pointers to uuids of apps allowed to connect
69  * @extra_data: pointer to extra data associated with this ACL structure, which
70  *              can be used in application specific way.
71  *
72  * Note: @uuid_num parameter can be 0 to indicate that there is no filtering by
73  * UUID and  connection from any client will be accepted. In this case @uuids
74  * parameter is ignored and can be set NULL.
75  */
76 struct tipc_port_acl {
77     uint32_t flags;
78     uint32_t uuid_num;
79     const struct uuid** uuids;
80     const void* extra_data;
81 };
82 
83 /**
84  * struct tipc_port - TIPC port descriptor
85  * @name:          port name
86  * @msg_max_size:  max message size supported
87  * @msg_queue_len: max number of messages in queue
88  * @acl:           pointer to &struct tipc_port_acl specifying ACL rules
89  * @priv:          port specific private data
90  *
91  * Note: @acl is a required parameter for specifying any port even if
92  * service does not require access control.
93  */
94 struct tipc_port {
95     const char* name;
96     uint32_t msg_max_size;
97     uint32_t msg_queue_len;
98     const struct tipc_port_acl* acl;
99     const void* priv;
100 };
101 
102 /**
103  * struct tipc_srv_ops - service specific ops (callbacks)
104  * @on_connect:    is invoked when a new connection is established.
105  * @on_message:    is invoked when a new message is available
106  * @on_disconnect: is invoked when the peer terminates connection
107  * @on_channel_cleanup: is invoked to cleanup user allocated state
108  *
109  * The overall call flow is as follow:
110  *
111  * Upon receiving a connection request from client framework accepts it and
112  * validates against configured ACL rules. If connection is allowed, the
113  * framework allocates a channel tracking structure and invokes an optional
114  * @on_connect callback if specified. The user who choose to implement this
115  * callback can allocate its own tracking structure and return pointer to that
116  * through @ctx_p parameter. After that this pointer will be associated with
117  * particular channel and it will be passed to all other callbacks.
118  *
119  * Upon receiving a message directed to particular channel, a corresponding
120  * @on_message callback is invoked so this message can be handled according
121  * with application specific protocol. The @on_message call back is a
122  * mandatory in this implementation.
123  *
124  * Upon receiving a disconnect request an optional @on_disconnect callback is
125  * invoked to indicate that peer closed connection. At this point the channel
126  * is still alive but in disconnected state, it will be closed by framework
127  * after control returns from executing this callback.
128  *
129  * The @on_channel_cleanup callback is invoked by framework to give the user
130  * a chance to release channel specific resources if allocated by
131  * @on_connect callback, after the channel have been closed. This
132  * callback is mandatory if the user implements @on_connect callback and
133  * allocates per channel state.
134  *
135  * The @on_send_unblocked callback is invoked when a channel becomes unblocked
136  * for sending after an earlier %ERR_NOT_ENOUGH_BUFFER error code returned
137  * by tipc_send1() or ipc_send_msg().
138  *
139  * Note: an application implementing these callbacks MUST not close channel
140  * received as @chan parameter directly, instead it should return an error
141  * and the channel will be closed by the framework.
142  *
143  */
144 struct tipc_srv_ops {
145     int (*on_connect)(const struct tipc_port* port,
146                       handle_t chan,
147                       const struct uuid* peer,
148                       void** ctx_p);
149 
150     int (*on_message)(const struct tipc_port* port, handle_t chan, void* ctx);
151 
152     void (*on_disconnect)(const struct tipc_port* port,
153                           handle_t chan,
154                           void* ctx);
155 
156     void (*on_channel_cleanup)(void* ctx);
157 
158     int (*on_send_unblocked)(const struct tipc_port* port,
159                              handle_t chan,
160                              void* ctx);
161 };
162 
163 /**
164  * tipc_add_service() - Add new service to service set
165  * @hset:         pointer to handle set to add service to
166  * @ports:        an array of &struct tipc_port describing ports for this
167  *                service
168  * @num_ports:    number of ports in array pointed by @ports
169  * @max_chan_cnt: max number of active connections allowed for this service, 0
170  *                for no limit.
171  * @ops:          pointer to &struct tipc_srv_ops with service specific
172  *                callbacks
173  *
174  * Note: the caller retain an ownership of structures pointed by @ports
175  * parameters and should not modify these structures in any way after the
176  * service has beed instantiated. Also, the caller is responsible for keeping
177  * them alive while service is running. The same is true for handle set. In
178  * addition, the caller should not invoke any direct operations on handle set
179  * outside of API's provided by this framework.
180  *
181  * Return: 0 on success, negative error code otherwise
182  */
183 int tipc_add_service(struct tipc_hset* hset,
184                      const struct tipc_port* ports,
185                      uint32_t num_ports,
186                      uint32_t max_chan_cnt,
187                      const struct tipc_srv_ops* ops);
188 
189 __END_CDECLS
190