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
RevLine 
[f834f90d]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
[4f64a523]43static void iplink_get_mtu_srv(iplink_srv_t *srv, ipc_callid_t callid,
[f834f90d]44 ipc_call_t *call)
45{
46 size_t mtu;
[b5cf742a]47 int rc = srv->ops->get_mtu(srv, &mtu);
[f834f90d]48 async_answer_1(callid, rc, mtu);
49}
50
[962f03b]51static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t callid,
52 ipc_call_t *call)
53{
[a2e3ee6]54 int rc = srv->ops->addr_add(srv, IPC_GET_ARG1(*call));
[962f03b]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{
[a2e3ee6]61 int rc = srv->ops->addr_remove(srv, IPC_GET_ARG1(*call));
[962f03b]62 async_answer_0(callid, rc);
63}
64
[4f64a523]65static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t callid,
[f834f90d]66 ipc_call_t *call)
67{
68 iplink_srv_sdu_t sdu;
69 int rc;
[b5cf742a]70
[a2e3ee6]71 sdu.lsrc = IPC_GET_ARG1(*call);
72 sdu.ldest = IPC_GET_ARG2(*call);
[b5cf742a]73
[f834f90d]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 }
[b5cf742a]79
[4f64a523]80 rc = srv->ops->send(srv, &sdu);
[f834f90d]81 free(sdu.data);
82 async_answer_0(callid, rc);
83}
84
[4f64a523]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
[f834f90d]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;
[b5cf742a]98
[4f64a523]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 }
[b5cf742a]105
[4f64a523]106 srv->connected = true;
107 fibril_mutex_unlock(&srv->lock);
[b5cf742a]108
[f834f90d]109 /* Accept the connection */
110 async_answer_0(iid, EOK);
[b5cf742a]111
[f834f90d]112 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
113 if (sess == NULL)
114 return ENOMEM;
[b5cf742a]115
[4f64a523]116 srv->client_sess = sess;
[b5cf742a]117
[4f64a523]118 rc = srv->ops->open(srv);
[f834f90d]119 if (rc != EOK)
120 return rc;
[b5cf742a]121
[f834f90d]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);
[b5cf742a]126
[f834f90d]127 if (!method) {
128 /* The other side has hung up */
[a2e3ee6]129 fibril_mutex_lock(&srv->lock);
[4802dd7]130 srv->connected = false;
[a2e3ee6]131 fibril_mutex_unlock(&srv->lock);
[f834f90d]132 async_answer_0(callid, EOK);
133 break;
134 }
[b5cf742a]135
[f834f90d]136 switch (method) {
137 case IPLINK_GET_MTU:
[4f64a523]138 iplink_get_mtu_srv(srv, callid, &call);
[f834f90d]139 break;
140 case IPLINK_SEND:
[4f64a523]141 iplink_send_srv(srv, callid, &call);
[f834f90d]142 break;
[962f03b]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;
[f834f90d]149 default:
150 async_answer_0(callid, EINVAL);
151 }
152 }
[b5cf742a]153
[4f64a523]154 return srv->ops->close(srv);
[f834f90d]155}
156
[4f64a523]157int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu)
[f834f90d]158{
[4f64a523]159 if (srv->client_sess == NULL)
160 return EIO;
[b5cf742a]161
[4f64a523]162 async_exch_t *exch = async_exchange_begin(srv->client_sess);
[b5cf742a]163
[f834f90d]164 ipc_call_t answer;
[a2e3ee6]165 aid_t req = async_send_2(exch, IPLINK_EV_RECV, (sysarg_t) sdu->lsrc,
166 (sysarg_t) sdu->ldest, &answer);
[f834f90d]167 int rc = async_data_write_start(exch, sdu->data, sdu->size);
168 async_exchange_end(exch);
[b5cf742a]169
[f834f90d]170 if (rc != EOK) {
[50b581d]171 async_forget(req);
[f834f90d]172 return rc;
173 }
[b5cf742a]174
[f834f90d]175 sysarg_t retval;
176 async_wait_for(req, &retval);
177 if (retval != EOK)
178 return retval;
[b5cf742a]179
[f834f90d]180 return EOK;
181}
182
183/** @}
184 */
Note: See TracBrowser for help on using the repository browser.