source: mainline/uspace/lib/c/generic/iplink_srv.c@ b5cf742a

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

cstyle (no change in functionality)

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