source: mainline/uspace/lib/c/generic/iplink.c@ 74017ce

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

add standardized case fallthrough comment annotations, add actual missing breaks

GCC 7.1's attribute((fallthrough)) would be more elegant, but unfortunatelly this annotation is incompatible with previous versions of GCC (it generates an empty declaration error)

  • Property mode set to 100644
File size: 6.8 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_callid_t iid, ipc_call_t *icall, void *arg);
48
49int 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 int 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
87int 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 int 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 sysarg_t retval;
105 async_wait_for(req, &retval);
106
107 return (int) retval;
108}
109
110int 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 int 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 sysarg_t retval;
134 async_wait_for(req, &retval);
135
136 return (int) retval;
137}
138
139int 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 int 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
155int 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 int 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 sysarg_t retval;
172 async_wait_for(req, &retval);
173
174 return (int) retval;
175}
176
177int 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 int 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 sysarg_t retval;
194 async_wait_for(req, &retval);
195
196 return (int) retval;
197}
198
199
200int iplink_addr_add(iplink_t *iplink, inet_addr_t *addr)
201{
202 async_exch_t *exch = async_exchange_begin(iplink->sess);
203
204 ipc_call_t answer;
205 aid_t req = async_send_0(exch, IPLINK_ADDR_ADD, &answer);
206
207 int rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
208 async_exchange_end(exch);
209
210 if (rc != EOK) {
211 async_forget(req);
212 return rc;
213 }
214
215 sysarg_t retval;
216 async_wait_for(req, &retval);
217
218 return (int) retval;
219}
220
221int iplink_addr_remove(iplink_t *iplink, inet_addr_t *addr)
222{
223 async_exch_t *exch = async_exchange_begin(iplink->sess);
224
225 ipc_call_t answer;
226 aid_t req = async_send_0(exch, IPLINK_ADDR_REMOVE, &answer);
227
228 int rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
229 async_exchange_end(exch);
230
231 if (rc != EOK) {
232 async_forget(req);
233 return rc;
234 }
235
236 sysarg_t retval;
237 async_wait_for(req, &retval);
238
239 return (int) retval;
240}
241
242void *iplink_get_userptr(iplink_t *iplink)
243{
244 return iplink->arg;
245}
246
247static void iplink_ev_recv(iplink_t *iplink, ipc_callid_t iid,
248 ipc_call_t *icall)
249{
250 iplink_recv_sdu_t sdu;
251
252 ip_ver_t ver = IPC_GET_ARG1(*icall);
253
254 int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
255 &sdu.size);
256 if (rc != EOK) {
257 async_answer_0(iid, rc);
258 return;
259 }
260
261 rc = iplink->ev_ops->recv(iplink, &sdu, ver);
262 free(sdu.data);
263 async_answer_0(iid, rc);
264}
265
266static void iplink_ev_change_addr(iplink_t *iplink, ipc_callid_t iid,
267 ipc_call_t *icall)
268{
269 addr48_t *addr;
270 size_t size;
271
272 int rc = async_data_write_accept((void **)&addr, false,
273 sizeof(addr48_t), sizeof(addr48_t), 0, &size);
274 if (rc != EOK) {
275 async_answer_0(iid, rc);
276 return;
277 }
278
279 rc = iplink->ev_ops->change_addr(iplink, *addr);
280 free(addr);
281 async_answer_0(iid, EOK);
282}
283
284static void iplink_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
285{
286 iplink_t *iplink = (iplink_t *) arg;
287
288 while (true) {
289 ipc_call_t call;
290 ipc_callid_t callid = async_get_call(&call);
291
292 if (!IPC_GET_IMETHOD(call)) {
293 /* TODO: Handle hangup */
294 return;
295 }
296
297 switch (IPC_GET_IMETHOD(call)) {
298 case IPLINK_EV_RECV:
299 iplink_ev_recv(iplink, callid, &call);
300 break;
301 case IPLINK_EV_CHANGE_ADDR:
302 iplink_ev_change_addr(iplink, callid, &call);
303 break;
304 default:
305 async_answer_0(callid, ENOTSUP);
306 }
307 }
308}
309
310/** @}
311 */
Note: See TracBrowser for help on using the repository browser.