1 /*
2  * Copyright (C) 2018 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 <lk/compiler.h>
20 #include <stddef.h>
21 #include <stdint.h>
22 
23 #include <trusty_ipc.h>
24 
25 __BEGIN_CDECLS
26 
27 /**
28  * DOC: TIPC helper library
29  *
30  * This library is a collection of frequently used routines
31  * and code patterns related to working with Trusty IPC.
32  */
33 
34 /**
35  * tipc_connect() - connect to specified TIPC service
36  * @handle_p: - pointer to location to store channel handle
37  * @port: - IPC port name to connect to
38  *
39  * Initiate a synchronous connection to specified port.
40  * If port does not exist, wait until it is created.
41  *
42  * Return: on success, 0 is returned and channel handle is
43  * stored at location pointed by @ph. A negative error code
44  * is returned otherwise.
45  */
46 int tipc_connect(handle_t* handle_p, const char* port);
47 
48 /**
49  * tipc_send1() - send a message from a single buffer
50  * @chan: handle of the channel to send message over
51  * @buf: pointer to the buffer containing message to send
52  * @len: length of the message pointed by @buf parameter
53  *
54  * Return: the total number of bytes sent on success, a negative
55  * error code otherwise.
56  */
57 int tipc_send1(handle_t chan, const void* buf, size_t len);
58 
59 /**
60  * tipc_recv1() - receive message into single buffer
61  * @chan: handle of the channel to receive message from
62  * @min_sz: minimum size of the message expected
63  * @buf: pointer to the buffer to place received message
64  * @buf_sz: size of the buffer pointed by @buf to receive message
65  *
66  * The received message has to contain at least @min_sz bytes and
67  * fully fit into provided buffer
68  *
69  * Return: the number of bytes stored into buffer pointed by @buf
70  * parameter on success, a negative error code otherwise
71  */
72 int tipc_recv1(handle_t chan, size_t min_sz, void* buf, size_t buf_sz);
73 
74 /**
75  * tipc_send2() - send a message consisting of two segments
76  * @chan: handle of the channel to send message over
77  * @hdr: pointer to buffer containing message header
78  * @hdr_len: size of the header pointed by @hdr parameter
79  * @payload: pointer to buffer containing payload
80  * @payload_len: size of payload pointed by @payload parameter
81  *
82  * This routine sends a message consisting of two segments, a header
83  * and a payload, which are concatenated together to make a single
84  * message.
85  *
86  * Return: the total number of bytes sent on success, a negative
87  *         error code otherwise.
88  */
89 int tipc_send2(handle_t chan,
90                const void* hdr,
91                size_t hdr_len,
92                const void* payload,
93                size_t payload_len);
94 
95 /**
96  * tipc_recv2() - receive message and split it into two segments
97  * @chan: handle of the channel to receive message from
98  * @min_sz: minimum size of the message expected
99  * @buf1: pointer to buffer to store first segment of the message
100  * @buf1_sz: size of the buffer pointed by @buf1 parameter
101  * @buf2: pointer to buffer to store second segment of the message
102  * @buf2_sz: size of the buffer pointed by @buf2 parameter
103  *
104  * This function receives a single massage from specified channel and splits
105  * it into two separate buffers, The received message has to contain at least
106  * @min_sz bytes and should fully fit into provided buffers.
107  *
108  * Return: the total number of bytes stored into provided buffers on success,
109  *         a negative error code otherwise.
110  */
111 int tipc_recv2(handle_t chan,
112                size_t min_sz,
113                void* buf1,
114                size_t buf1_sz,
115                void* buf2,
116                size_t buf2_sz);
117 
118 /**
119  * tipc_recv_hdr_payload() - receive message and split it into two segments
120  * @chan: handle of the channel to receive message from
121  * @hdr: pointer to buffer to store mandatory message header
122  * @hdr_sz: size of the message header
123  * @payload: pointer to buffer to store optional payload
124  * @payload_sz: size of the buffer pointed by @payload parameter
125  *
126  * Not: This is a wrapper on top of tipc_recv2 where min_sz set to hdr_sz
127  *
128  * Return: the total number of bytes stored into provided buffers on success,
129  *         a negative error code otherwise.
130  */
tipc_recv_hdr_payload(handle_t chan,void * hdr,size_t hdr_sz,void * payload,size_t payload_sz)131 static inline int tipc_recv_hdr_payload(handle_t chan,
132                                         void* hdr,
133                                         size_t hdr_sz,
134                                         void* payload,
135                                         size_t payload_sz) {
136     return tipc_recv2(chan, hdr_sz, hdr, hdr_sz, payload, payload_sz);
137 }
138 
139 /**
140  * tipc_handle_port_errors() - helper to handle unexpected port events
141  * @ev: pointer to event to handle
142  *
143  * This routine is intended to be called as a part of port event handler
144  * to check for unexpected conditions that normally should never
145  * happen for a valid port handle. The implementation calls an
146  * abort if any of these conditions are encountered.
147  *
148  * Return: none.
149  */
150 void tipc_handle_port_errors(const struct uevent* ev);
151 
152 /**
153  * tipc_handle_chan_errors() - helper to handle unexpected channel events
154  * @ev: pointer to event to handle
155  *
156  * This routine is intended to be called as a part of channel event handler
157  * to check for unexpected conditions. These conditions should never
158  * happen for a valid channel handle. The implementation might call an
159  * abort if any of these conditions are encountered.
160  *
161  * Return: none.
162  */
163 void tipc_handle_chan_errors(const struct uevent* ev);
164 
165 /**
166  * typedef event_handler_proc_t - pointer to event handler routine
167  * @ev: pointer to event to handle
168  * @priv: handle/context specific argument
169  *
170  * Return: none
171  */
172 typedef void (*event_handler_proc_t)(const struct uevent* ev, void* priv);
173 
174 /**
175  * struct tipc_event_handler - defines event handler for particular handle
176  * @proc: pointer to @event_handler_proc_t function to call to handle event
177  * @priv: value to pass as @priv parameter for event_handler_proc_t function
178  *        pointed by @proc parameters
179  */
180 struct tipc_event_handler {
181     event_handler_proc_t proc;
182     void* priv;
183 };
184 
185 /*
186  * struct tipc_hset - opaque structure representing handle set
187  */
188 struct tipc_hset;
189 
190 /**
191  *  tipc_hset_create() - allocate and initialize new handle set
192  *
193  *  Return: a pointer to &struct tipc_hset on success, PTR_ERR otherwise.
194  */
195 struct tipc_hset* tipc_hset_create(void);
196 
197 /**
198  * tipc_hset_add_entry() - add new existing handle to handle set
199  * @hset:        pointer to valid &struct tipc_hset
200  * @handle:      handle to add to handle set specified by @hset parameter
201  * @evt_mask:    set of events allowed to be handled for @handle
202  * @evt_handler: pointer to initialized &struct tipc_event_handler (must not
203  *               be NULL) that will be used to handle events associated with
204  *               handle specified by @handle parameter and allowed by
205  *               @evt_mask parameter.
206  *
207  * Return: 0 on success, a negative error code otherwise
208  */
209 int tipc_hset_add_entry(struct tipc_hset* hset,
210                         handle_t handle,
211                         uint32_t evt_mask,
212                         struct tipc_event_handler* evt_handler);
213 
214 /**
215  * tipc_hset_mod_entry() - modify parameters of an existing entry in handle set
216  * @hset:        pointer to valid &struct tipc_hset
217  * @handle:      handle to modify an entry for. It must be previously added by
218  *               calling tipc_hset_add_handle() function.
219  * @evt_mask:    set of events allowed to be handled for @handle
220  * @evt_handler: pointer to initialized &struct tipc_event_handler (must not
221  *               be NULL) that will be used to handle events associated with
222  *               handle specified by @handle parameter and allowed by
223  *               @evt_mask parameter.
224  *
225  * Return: 0 on success, a negative error code otherwise
226  */
227 int tipc_hset_mod_entry(struct tipc_hset* hset,
228                         handle_t handle,
229                         uint32_t evt_mask,
230                         struct tipc_event_handler* evt_handler);
231 
232 /**
233  * tipc_hset_remove_entry() - remove specified handle from handle set
234  * @hset: pointer to &struct tipc_hset to remove handle from
235  * @handle: handle to remove from handle set specified by @hset parameter
236  *
237  * Return: 0 on success, a negative error code otherwise
238  */
239 int tipc_hset_remove_entry(struct tipc_hset* hset, handle_t handle);
240 
241 /**
242  * tipc_handle_event() - wait on handle set and handle single event
243  * @hset: pointer to valid &struct tipc_hset set to get events from
244  * @timeout: a max amount of time to wait for event before returning to caller
245  *
246  * Note: It is expected that this routine is called repeatedly from event loop
247  * to handle events. The handle set specified as @hset parameter has to be
248  * populated with tipc_hset_add_handle() function.
249  *
250  * Return: 0 if an event has been retrieved and handled, ERR_TIMED_OUT if
251  * specified by @timeout parameter time has elapsed without getting new event,
252  * negative error code otherwise.
253  */
254 int tipc_handle_event(struct tipc_hset* hset, uint32_t timeout);
255 
256 /**
257  * tipc_run_event_loop() - run standard event loop
258  * @hset: handle set to retrieve and handle events from
259  *
260  * This routine does not return under normal conditions.
261  *
262  * Return: negative error code if an error is encountered.
263  */
264 int tipc_run_event_loop(struct tipc_hset* hset);
265 
266 __END_CDECLS
267