Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/iplink_srv.c

    r4802dd7 r417a2ba1  
    3434 * @brief IP link server stub
    3535 */
     36
    3637#include <errno.h>
    3738#include <ipc/iplink.h>
    3839#include <stdlib.h>
    3940#include <sys/types.h>
    40 
     41#include <inet/addr.h>
    4142#include <inet/iplink_srv.h>
    4243
     
    4445    ipc_call_t *call)
    4546{
    46         int rc;
    4747        size_t mtu;
    48 
    49         rc = srv->ops->get_mtu(srv, &mtu);
     48        int rc = srv->ops->get_mtu(srv, &mtu);
    5049        async_answer_1(callid, rc, mtu);
    5150}
    5251
    53 static 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 
     52static void iplink_get_mac48_srv(iplink_srv_t *srv, ipc_callid_t iid,
     53    ipc_call_t *icall)
     54{
     55        addr48_t mac;
     56        int rc = srv->ops->get_mac48(srv, &mac);
     57        if (rc != EOK) {
     58                async_answer_0(iid, rc);
     59                return;
     60        }
     61       
     62        ipc_callid_t callid;
     63        size_t size;
     64        if (!async_data_read_receive(&callid, &size)) {
     65                async_answer_0(callid, EREFUSED);
     66                async_answer_0(iid, EREFUSED);
     67                return;
     68        }
     69       
     70        if (size != sizeof(addr48_t)) {
     71                async_answer_0(callid, EINVAL);
     72                async_answer_0(iid, EINVAL);
     73                return;
     74        }
     75       
     76        rc = async_data_read_finalize(callid, &mac, size);
     77        if (rc != EOK)
     78                async_answer_0(callid, rc);
     79       
     80        async_answer_0(iid, (sysarg_t) rc);
     81}
     82
     83static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t iid,
     84    ipc_call_t *icall)
     85{
     86        ipc_callid_t callid;
     87        size_t size;
     88        if (!async_data_write_receive(&callid, &size)) {
     89                async_answer_0(callid, EREFUSED);
     90                async_answer_0(iid, EREFUSED);
     91                return;
     92        }
     93       
     94        if (size != sizeof(inet_addr_t)) {
     95                async_answer_0(callid, EINVAL);
     96                async_answer_0(iid, EINVAL);
     97                return;
     98        }
     99       
     100        inet_addr_t addr;
     101        int rc = async_data_write_finalize(callid, &addr, size);
     102        if (rc != EOK) {
     103                async_answer_0(callid, (sysarg_t) rc);
     104                async_answer_0(iid, (sysarg_t) rc);
     105        }
     106       
    61107        rc = srv->ops->addr_add(srv, &addr);
    62         async_answer_0(callid, rc);
    63 }
    64 
    65 static 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 
     108        async_answer_0(iid, (sysarg_t) rc);
     109}
     110
     111static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t iid,
     112    ipc_call_t *icall)
     113{
     114        ipc_callid_t callid;
     115        size_t size;
     116        if (!async_data_write_receive(&callid, &size)) {
     117                async_answer_0(callid, EREFUSED);
     118                async_answer_0(iid, EREFUSED);
     119                return;
     120        }
     121       
     122        if (size != sizeof(inet_addr_t)) {
     123                async_answer_0(callid, EINVAL);
     124                async_answer_0(iid, EINVAL);
     125                return;
     126        }
     127       
     128        inet_addr_t addr;
     129        int rc = async_data_write_finalize(callid, &addr, size);
     130        if (rc != EOK) {
     131                async_answer_0(callid, (sysarg_t) rc);
     132                async_answer_0(iid, (sysarg_t) rc);
     133        }
     134       
    73135        rc = srv->ops->addr_remove(srv, &addr);
    74         async_answer_0(callid, rc);
    75 }
    76 
    77 static 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 
     136        async_answer_0(iid, (sysarg_t) rc);
     137}
     138
     139static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t iid,
     140    ipc_call_t *icall)
     141{
     142        iplink_sdu_t sdu;
     143       
     144        sdu.src = IPC_GET_ARG1(*icall);
     145        sdu.dest = IPC_GET_ARG2(*icall);
     146       
     147        int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     148            &sdu.size);
     149        if (rc != EOK) {
     150                async_answer_0(iid, rc);
     151                return;
     152        }
     153       
    92154        rc = srv->ops->send(srv, &sdu);
    93155        free(sdu.data);
    94         async_answer_0(callid, rc);
     156        async_answer_0(iid, rc);
     157}
     158
     159static void iplink_send6_srv(iplink_srv_t *srv, ipc_callid_t iid,
     160    ipc_call_t *icall)
     161{
     162        iplink_sdu6_t sdu;
     163       
     164        ipc_callid_t callid;
     165        size_t size;
     166        if (!async_data_write_receive(&callid, &size)) {
     167                async_answer_0(callid, EREFUSED);
     168                async_answer_0(iid, EREFUSED);
     169                return;
     170        }
     171       
     172        if (size != sizeof(addr48_t)) {
     173                async_answer_0(callid, EINVAL);
     174                async_answer_0(iid, EINVAL);
     175                return;
     176        }
     177       
     178        int rc = async_data_write_finalize(callid, &sdu.dest, size);
     179        if (rc != EOK) {
     180                async_answer_0(callid, (sysarg_t) rc);
     181                async_answer_0(iid, (sysarg_t) rc);
     182        }
     183       
     184        rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     185            &sdu.size);
     186        if (rc != EOK) {
     187                async_answer_0(iid, rc);
     188                return;
     189        }
     190       
     191        rc = srv->ops->send6(srv, &sdu);
     192        free(sdu.data);
     193        async_answer_0(iid, rc);
    95194}
    96195
     
    106205int iplink_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    107206{
    108         iplink_srv_t *srv = (iplink_srv_t *)arg;
     207        iplink_srv_t *srv = (iplink_srv_t *) arg;
    109208        int rc;
    110 
     209       
    111210        fibril_mutex_lock(&srv->lock);
    112211        if (srv->connected) {
     
    115214                return EBUSY;
    116215        }
    117 
     216       
    118217        srv->connected = true;
    119218        fibril_mutex_unlock(&srv->lock);
    120 
     219       
    121220        /* Accept the connection */
    122221        async_answer_0(iid, EOK);
    123 
     222       
    124223        async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
    125224        if (sess == NULL)
    126225                return ENOMEM;
    127 
     226       
    128227        srv->client_sess = sess;
    129 
     228       
    130229        rc = srv->ops->open(srv);
    131230        if (rc != EOK)
    132231                return rc;
    133 
     232       
    134233        while (true) {
    135234                ipc_call_t call;
    136235                ipc_callid_t callid = async_get_call(&call);
    137236                sysarg_t method = IPC_GET_IMETHOD(call);
    138 
     237               
    139238                if (!method) {
    140239                        /* The other side has hung up */
    141                         fibril_mutex_lock(&srv->lock);
     240                        fibril_mutex_lock(&srv->lock);
    142241                        srv->connected = false;
    143                         fibril_mutex_unlock(&srv->lock);
     242                        fibril_mutex_unlock(&srv->lock);
    144243                        async_answer_0(callid, EOK);
    145244                        break;
    146245                }
    147 
     246               
    148247                switch (method) {
    149248                case IPLINK_GET_MTU:
    150249                        iplink_get_mtu_srv(srv, callid, &call);
    151250                        break;
     251                case IPLINK_GET_MAC48:
     252                        iplink_get_mac48_srv(srv, callid, &call);
     253                        break;
    152254                case IPLINK_SEND:
    153255                        iplink_send_srv(srv, callid, &call);
     256                        break;
     257                case IPLINK_SEND6:
     258                        iplink_send6_srv(srv, callid, &call);
    154259                        break;
    155260                case IPLINK_ADDR_ADD:
     
    163268                }
    164269        }
    165 
     270       
    166271        return srv->ops->close(srv);
    167272}
    168273
    169 int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu)
     274/* XXX Version should be part of @a sdu */
     275int iplink_ev_recv(iplink_srv_t *srv, iplink_recv_sdu_t *sdu, ip_ver_t ver)
    170276{
    171277        if (srv->client_sess == NULL)
    172278                return EIO;
    173 
     279       
    174280        async_exch_t *exch = async_exchange_begin(srv->client_sess);
    175 
     281       
    176282        ipc_call_t answer;
    177         aid_t req = async_send_2(exch, IPLINK_EV_RECV, sdu->lsrc.ipv4,
    178             sdu->ldest.ipv4, &answer);
     283        aid_t req = async_send_1(exch, IPLINK_EV_RECV, (sysarg_t)ver,
     284            &answer);
     285       
    179286        int rc = async_data_write_start(exch, sdu->data, sdu->size);
    180287        async_exchange_end(exch);
    181 
     288       
    182289        if (rc != EOK) {
    183290                async_forget(req);
    184291                return rc;
    185292        }
    186 
     293       
    187294        sysarg_t retval;
    188295        async_wait_for(req, &retval);
    189296        if (retval != EOK)
    190297                return retval;
    191 
     298       
    192299        return EOK;
    193300}
Note: See TracChangeset for help on using the changeset viewer.