source: mainline/uspace/lib/c/generic/iplink_srv.c@ 1a23f6e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1a23f6e was 50b581d, checked in by Jakub Jermar <jakub@…>, 13 years ago

Replace the async_wait_for(msg, NULL) pattern in the error paths with
async_forget(msg).

  • Property mode set to 100644
File size: 4.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 server stub
35 */
36#include <errno.h>
37#include <ipc/iplink.h>
38#include <stdlib.h>
39#include <sys/types.h>
40
41#include <inet/iplink_srv.h>
42
43static void iplink_get_mtu_srv(iplink_srv_t *srv, ipc_callid_t callid,
44 ipc_call_t *call)
45{
46 int rc;
47 size_t mtu;
48
49 rc = srv->ops->get_mtu(srv, &mtu);
50 async_answer_1(callid, rc, mtu);
51}
52
53static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t callid,
54 ipc_call_t *call)
55{
56 int rc;
57 iplink_srv_addr_t addr;
58
59 addr.ipv4 = IPC_GET_ARG1(*call);
60
61 rc = srv->ops->addr_add(srv, &addr);
62 async_answer_0(callid, rc);
63}
64
65static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t callid,
66 ipc_call_t *call)
67{
68 int rc;
69 iplink_srv_addr_t addr;
70
71 addr.ipv4 = IPC_GET_ARG1(*call);
72
73 rc = srv->ops->addr_remove(srv, &addr);
74 async_answer_0(callid, rc);
75}
76
77static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t callid,
78 ipc_call_t *call)
79{
80 iplink_srv_sdu_t sdu;
81 int rc;
82
83 sdu.lsrc.ipv4 = IPC_GET_ARG1(*call);
84 sdu.ldest.ipv4 = IPC_GET_ARG2(*call);
85
86 rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
87 if (rc != EOK) {
88 async_answer_0(callid, rc);
89 return;
90 }
91
92 rc = srv->ops->send(srv, &sdu);
93 free(sdu.data);
94 async_answer_0(callid, rc);
95}
96
97void iplink_srv_init(iplink_srv_t *srv)
98{
99 fibril_mutex_initialize(&srv->lock);
100 srv->connected = false;
101 srv->ops = NULL;
102 srv->arg = NULL;
103 srv->client_sess = NULL;
104}
105
106int iplink_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
107{
108 iplink_srv_t *srv = (iplink_srv_t *)arg;
109 int rc;
110
111 fibril_mutex_lock(&srv->lock);
112 if (srv->connected) {
113 fibril_mutex_unlock(&srv->lock);
114 async_answer_0(iid, EBUSY);
115 return EBUSY;
116 }
117
118 srv->connected = true;
119 fibril_mutex_unlock(&srv->lock);
120
121 /* Accept the connection */
122 async_answer_0(iid, EOK);
123
124 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
125 if (sess == NULL)
126 return ENOMEM;
127
128 srv->client_sess = sess;
129
130 rc = srv->ops->open(srv);
131 if (rc != EOK)
132 return rc;
133
134 while (true) {
135 ipc_call_t call;
136 ipc_callid_t callid = async_get_call(&call);
137 sysarg_t method = IPC_GET_IMETHOD(call);
138
139 if (!method) {
140 /* The other side has hung up */
141 async_answer_0(callid, EOK);
142 break;
143 }
144
145 switch (method) {
146 case IPLINK_GET_MTU:
147 iplink_get_mtu_srv(srv, callid, &call);
148 break;
149 case IPLINK_SEND:
150 iplink_send_srv(srv, callid, &call);
151 break;
152 case IPLINK_ADDR_ADD:
153 iplink_addr_add_srv(srv, callid, &call);
154 break;
155 case IPLINK_ADDR_REMOVE:
156 iplink_addr_remove_srv(srv, callid, &call);
157 break;
158 default:
159 async_answer_0(callid, EINVAL);
160 }
161 }
162
163 return srv->ops->close(srv);
164}
165
166int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu)
167{
168 if (srv->client_sess == NULL)
169 return EIO;
170
171 async_exch_t *exch = async_exchange_begin(srv->client_sess);
172
173 ipc_call_t answer;
174 aid_t req = async_send_2(exch, IPLINK_EV_RECV, sdu->lsrc.ipv4,
175 sdu->ldest.ipv4, &answer);
176 int rc = async_data_write_start(exch, sdu->data, sdu->size);
177 async_exchange_end(exch);
178
179 if (rc != EOK) {
180 async_forget(req);
181 return rc;
182 }
183
184 sysarg_t retval;
185 async_wait_for(req, &retval);
186 if (retval != EOK)
187 return retval;
188
189 return EOK;
190}
191
192/** @}
193 */
Note: See TracBrowser for help on using the repository browser.