source: mainline/uspace/lib/c/generic/iplink.c@ 984a9ba

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 984a9ba was 984a9ba, checked in by Martin Decky <martin@…>, 7 years ago

do not expose the call capability handler from the async framework

Keep the call capability handler encapsulated within the async framework
and do not expose it explicitly via its API. Use the pointer to
ipc_call_t as the sole object identifying an IPC call in the code that
uses the async framework.

This plugs a major leak in the abstraction and also simplifies both the
async framework (slightly) and all IPC servers.

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/**
33 * @file
34 * @brief IP link client stub
35 */
36
37#include <async.h>
38#include <assert.h>
39#include <errno.h>
40#include <inet/iplink.h>
41#include <inet/addr.h>
42#include <ipc/iplink.h>
43#include <ipc/services.h>
44#include <loc.h>
45#include <stdlib.h>
46
47static void iplink_cb_conn(ipc_call_t *icall, void *arg);
48
49errno_t iplink_open(async_sess_t *sess, iplink_ev_ops_t *ev_ops, void *arg,
50 iplink_t **riplink)
51{
52 iplink_t *iplink = calloc(1, sizeof(iplink_t));
53 if (iplink == NULL)
54 return ENOMEM;
55
56 iplink->sess = sess;
57 iplink->ev_ops = ev_ops;
58 iplink->arg = arg;
59
60 async_exch_t *exch = async_exchange_begin(sess);
61
62 port_id_t port;
63 errno_t rc = async_create_callback_port(exch, INTERFACE_IPLINK_CB, 0, 0,
64 iplink_cb_conn, iplink, &port);
65
66 async_exchange_end(exch);
67
68 if (rc != EOK)
69 goto error;
70
71 *riplink = iplink;
72 return EOK;
73
74error:
75 if (iplink != NULL)
76 free(iplink);
77
78 return rc;
79}
80
81void iplink_close(iplink_t *iplink)
82{
83 /* XXX Synchronize with iplink_cb_conn */
84 free(iplink);
85}
86
87errno_t iplink_send(iplink_t *iplink, iplink_sdu_t *sdu)
88{
89 async_exch_t *exch = async_exchange_begin(iplink->sess);
90
91 ipc_call_t answer;
92 aid_t req = async_send_2(exch, IPLINK_SEND, (sysarg_t) sdu->src,
93 (sysarg_t) sdu->dest, &answer);
94
95 errno_t rc = async_data_write_start(exch, sdu->data, sdu->size);
96
97 async_exchange_end(exch);
98
99 if (rc != EOK) {
100 async_forget(req);
101 return rc;
102 }
103
104 errno_t retval;
105 async_wait_for(req, &retval);
106
107 return retval;
108}
109
110errno_t iplink_send6(iplink_t *iplink, iplink_sdu6_t *sdu)
111{
112 async_exch_t *exch = async_exchange_begin(iplink->sess);
113
114 ipc_call_t answer;
115 aid_t req = async_send_0(exch, IPLINK_SEND6, &answer);
116
117 errno_t rc = async_data_write_start(exch, &sdu->dest, sizeof(addr48_t));
118 if (rc != EOK) {
119 async_exchange_end(exch);
120 async_forget(req);
121 return rc;
122 }
123
124 rc = async_data_write_start(exch, sdu->data, sdu->size);
125
126 async_exchange_end(exch);
127
128 if (rc != EOK) {
129 async_forget(req);
130 return rc;
131 }
132
133 errno_t retval;
134 async_wait_for(req, &retval);
135
136 return retval;
137}
138
139errno_t iplink_get_mtu(iplink_t *iplink, size_t *rmtu)
140{
141 async_exch_t *exch = async_exchange_begin(iplink->sess);
142
143 sysarg_t mtu;
144 errno_t rc = async_req_0_1(exch, IPLINK_GET_MTU, &mtu);
145
146 async_exchange_end(exch);
147
148 if (rc != EOK)
149 return rc;
150
151 *rmtu = mtu;
152 return EOK;
153}
154
155errno_t iplink_get_mac48(iplink_t *iplink, addr48_t *mac)
156{
157 async_exch_t *exch = async_exchange_begin(iplink->sess);
158
159 ipc_call_t answer;
160 aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer);
161
162 errno_t rc = async_data_read_start(exch, mac, sizeof(addr48_t));
163
164 loc_exchange_end(exch);
165
166 if (rc != EOK) {
167 async_forget(req);
168 return rc;
169 }
170
171 errno_t retval;
172 async_wait_for(req, &retval);
173
174 return retval;
175}
176
177errno_t iplink_set_mac48(iplink_t *iplink, addr48_t mac)
178{
179 async_exch_t *exch = async_exchange_begin(iplink->sess);
180
181 ipc_call_t answer;
182 aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer);
183
184 errno_t rc = async_data_read_start(exch, mac, sizeof(addr48_t));
185
186 loc_exchange_end(exch);
187
188 if (rc != EOK) {
189 async_forget(req);
190 return rc;
191 }
192
193 errno_t retval;
194 async_wait_for(req, &retval);
195
196 return retval;
197}
198
199errno_t iplink_addr_add(iplink_t *iplink, inet_addr_t *addr)
200{
201 async_exch_t *exch = async_exchange_begin(iplink->sess);
202
203 ipc_call_t answer;
204 aid_t req = async_send_0(exch, IPLINK_ADDR_ADD, &answer);
205
206 errno_t rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
207 async_exchange_end(exch);
208
209 if (rc != EOK) {
210 async_forget(req);
211 return rc;
212 }
213
214 errno_t retval;
215 async_wait_for(req, &retval);
216
217 return retval;
218}
219
220errno_t iplink_addr_remove(iplink_t *iplink, inet_addr_t *addr)
221{
222 async_exch_t *exch = async_exchange_begin(iplink->sess);
223
224 ipc_call_t answer;
225 aid_t req = async_send_0(exch, IPLINK_ADDR_REMOVE, &answer);
226
227 errno_t rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
228 async_exchange_end(exch);
229
230 if (rc != EOK) {
231 async_forget(req);
232 return rc;
233 }
234
235 errno_t retval;
236 async_wait_for(req, &retval);
237
238 return retval;
239}
240
241void *iplink_get_userptr(iplink_t *iplink)
242{
243 return iplink->arg;
244}
245
246static void iplink_ev_recv(iplink_t *iplink, ipc_call_t *icall)
247{
248 iplink_recv_sdu_t sdu;
249
250 ip_ver_t ver = IPC_GET_ARG1(*icall);
251
252 errno_t rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
253 &sdu.size);
254 if (rc != EOK) {
255 async_answer_0(icall, rc);
256 return;
257 }
258
259 rc = iplink->ev_ops->recv(iplink, &sdu, ver);
260 free(sdu.data);
261 async_answer_0(icall, rc);
262}
263
264static void iplink_ev_change_addr(iplink_t *iplink, ipc_call_t *icall)
265{
266 addr48_t *addr;
267 size_t size;
268
269 errno_t rc = async_data_write_accept((void **) &addr, false,
270 sizeof(addr48_t), sizeof(addr48_t), 0, &size);
271 if (rc != EOK) {
272 async_answer_0(icall, rc);
273 return;
274 }
275
276 rc = iplink->ev_ops->change_addr(iplink, *addr);
277 free(addr);
278 async_answer_0(icall, EOK);
279}
280
281static void iplink_cb_conn(ipc_call_t *icall, void *arg)
282{
283 iplink_t *iplink = (iplink_t *) arg;
284
285 while (true) {
286 ipc_call_t call;
287 async_get_call(&call);
288
289 if (!IPC_GET_IMETHOD(call)) {
290 /* TODO: Handle hangup */
291 return;
292 }
293
294 switch (IPC_GET_IMETHOD(call)) {
295 case IPLINK_EV_RECV:
296 iplink_ev_recv(iplink, &call);
297 break;
298 case IPLINK_EV_CHANGE_ADDR:
299 iplink_ev_change_addr(iplink, &call);
300 break;
301 default:
302 async_answer_0(&call, ENOTSUP);
303 }
304 }
305}
306
307/** @}
308 */
Note: See TracBrowser for help on using the repository browser.