Ignore:
File:
1 edited

Legend:

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

    rc3b25985 r4802dd7  
    3434 * @brief IP link server stub
    3535 */
    36 
    3736#include <errno.h>
    3837#include <ipc/iplink.h>
    3938#include <stdlib.h>
    4039#include <sys/types.h>
    41 #include <inet/addr.h>
     40
    4241#include <inet/iplink_srv.h>
    4342
     
    4544    ipc_call_t *call)
    4645{
     46        int rc;
    4747        size_t mtu;
    48         int rc = srv->ops->get_mtu(srv, &mtu);
     48
     49        rc = srv->ops->get_mtu(srv, &mtu);
    4950        async_answer_1(callid, rc, mtu);
    5051}
    5152
    52 static void iplink_get_mac48_srv(iplink_srv_t *srv, ipc_callid_t iid,
    53     ipc_call_t *icall)
     53static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t callid,
     54    ipc_call_t *call)
    5455{
    55         addr48_t mac;
    56         int rc = srv->ops->get_mac48(srv, &mac);
     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);
    5787        if (rc != EOK) {
    58                 async_answer_0(iid, rc);
     88                async_answer_0(callid, rc);
    5989                return;
    6090        }
    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 }
    8291
    83 static void iplink_set_mac48_srv(iplink_srv_t *srv, ipc_callid_t iid,
    84     ipc_call_t *icall)
    85 {
    86         int rc;
    87         size_t size;
    88         addr48_t mac;
    89         ipc_callid_t callid;
    90 
    91         rc = async_data_write_receive(&callid, &size);
    92         if (rc != EOK) {
    93                 async_answer_0(callid, (sysarg_t) rc);
    94                 async_answer_0(iid, (sysarg_t) rc);
    95         }
    96 
    97         rc = srv->ops->set_mac48(srv, &mac);
    98         if (rc != EOK) {
    99                 async_answer_0(iid, rc);
    100                 return;
    101         }
    102        
    103         rc = async_data_read_finalize(callid, &mac, sizeof(addr48_t));
    104         if (rc != EOK)
    105                 async_answer_0(callid, rc);
    106        
    107         async_answer_0(iid, (sysarg_t) rc);
    108 }
    109 
    110 static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t iid,
    111     ipc_call_t *icall)
    112 {
    113         ipc_callid_t callid;
    114         size_t size;
    115         if (!async_data_write_receive(&callid, &size)) {
    116                 async_answer_0(callid, EREFUSED);
    117                 async_answer_0(iid, EREFUSED);
    118                 return;
    119         }
    120        
    121         if (size != sizeof(inet_addr_t)) {
    122                 async_answer_0(callid, EINVAL);
    123                 async_answer_0(iid, EINVAL);
    124                 return;
    125         }
    126        
    127         inet_addr_t addr;
    128         int rc = async_data_write_finalize(callid, &addr, size);
    129         if (rc != EOK) {
    130                 async_answer_0(callid, (sysarg_t) rc);
    131                 async_answer_0(iid, (sysarg_t) rc);
    132         }
    133        
    134         rc = srv->ops->addr_add(srv, &addr);
    135         async_answer_0(iid, (sysarg_t) rc);
    136 }
    137 
    138 static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t iid,
    139     ipc_call_t *icall)
    140 {
    141         ipc_callid_t callid;
    142         size_t size;
    143         if (!async_data_write_receive(&callid, &size)) {
    144                 async_answer_0(callid, EREFUSED);
    145                 async_answer_0(iid, EREFUSED);
    146                 return;
    147         }
    148        
    149         if (size != sizeof(inet_addr_t)) {
    150                 async_answer_0(callid, EINVAL);
    151                 async_answer_0(iid, EINVAL);
    152                 return;
    153         }
    154        
    155         inet_addr_t addr;
    156         int rc = async_data_write_finalize(callid, &addr, size);
    157         if (rc != EOK) {
    158                 async_answer_0(callid, (sysarg_t) rc);
    159                 async_answer_0(iid, (sysarg_t) rc);
    160         }
    161        
    162         rc = srv->ops->addr_remove(srv, &addr);
    163         async_answer_0(iid, (sysarg_t) rc);
    164 }
    165 
    166 static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t iid,
    167     ipc_call_t *icall)
    168 {
    169         iplink_sdu_t sdu;
    170        
    171         sdu.src = IPC_GET_ARG1(*icall);
    172         sdu.dest = IPC_GET_ARG2(*icall);
    173        
    174         int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
    175             &sdu.size);
    176         if (rc != EOK) {
    177                 async_answer_0(iid, rc);
    178                 return;
    179         }
    180        
    18192        rc = srv->ops->send(srv, &sdu);
    18293        free(sdu.data);
    183         async_answer_0(iid, rc);
    184 }
    185 
    186 static void iplink_send6_srv(iplink_srv_t *srv, ipc_callid_t iid,
    187     ipc_call_t *icall)
    188 {
    189         iplink_sdu6_t sdu;
    190        
    191         ipc_callid_t callid;
    192         size_t size;
    193         if (!async_data_write_receive(&callid, &size)) {
    194                 async_answer_0(callid, EREFUSED);
    195                 async_answer_0(iid, EREFUSED);
    196                 return;
    197         }
    198        
    199         if (size != sizeof(addr48_t)) {
    200                 async_answer_0(callid, EINVAL);
    201                 async_answer_0(iid, EINVAL);
    202                 return;
    203         }
    204        
    205         int rc = async_data_write_finalize(callid, &sdu.dest, size);
    206         if (rc != EOK) {
    207                 async_answer_0(callid, (sysarg_t) rc);
    208                 async_answer_0(iid, (sysarg_t) rc);
    209         }
    210        
    211         rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
    212             &sdu.size);
    213         if (rc != EOK) {
    214                 async_answer_0(iid, rc);
    215                 return;
    216         }
    217        
    218         rc = srv->ops->send6(srv, &sdu);
    219         free(sdu.data);
    220         async_answer_0(iid, rc);
     94        async_answer_0(callid, rc);
    22195}
    22296
     
    232106int iplink_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    233107{
    234         iplink_srv_t *srv = (iplink_srv_t *) arg;
     108        iplink_srv_t *srv = (iplink_srv_t *)arg;
    235109        int rc;
    236        
     110
    237111        fibril_mutex_lock(&srv->lock);
    238112        if (srv->connected) {
     
    241115                return EBUSY;
    242116        }
    243        
     117
    244118        srv->connected = true;
    245119        fibril_mutex_unlock(&srv->lock);
    246        
     120
    247121        /* Accept the connection */
    248122        async_answer_0(iid, EOK);
    249        
     123
    250124        async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
    251125        if (sess == NULL)
    252126                return ENOMEM;
    253        
     127
    254128        srv->client_sess = sess;
    255        
     129
    256130        rc = srv->ops->open(srv);
    257131        if (rc != EOK)
    258132                return rc;
    259        
     133
    260134        while (true) {
    261135                ipc_call_t call;
    262136                ipc_callid_t callid = async_get_call(&call);
    263137                sysarg_t method = IPC_GET_IMETHOD(call);
    264                
     138
    265139                if (!method) {
    266140                        /* The other side has hung up */
    267                         fibril_mutex_lock(&srv->lock);
     141                        fibril_mutex_lock(&srv->lock);
    268142                        srv->connected = false;
    269                         fibril_mutex_unlock(&srv->lock);
     143                        fibril_mutex_unlock(&srv->lock);
    270144                        async_answer_0(callid, EOK);
    271145                        break;
    272146                }
    273                
     147
    274148                switch (method) {
    275149                case IPLINK_GET_MTU:
    276150                        iplink_get_mtu_srv(srv, callid, &call);
    277151                        break;
    278                 case IPLINK_GET_MAC48:
    279                         iplink_get_mac48_srv(srv, callid, &call);
    280                         break;
    281                 case IPLINK_SET_MAC48:
    282                         iplink_set_mac48_srv(srv, callid, &call);
    283                         break;
    284152                case IPLINK_SEND:
    285153                        iplink_send_srv(srv, callid, &call);
    286                         break;
    287                 case IPLINK_SEND6:
    288                         iplink_send6_srv(srv, callid, &call);
    289154                        break;
    290155                case IPLINK_ADDR_ADD:
     
    298163                }
    299164        }
    300        
     165
    301166        return srv->ops->close(srv);
    302167}
    303168
    304 /* XXX Version should be part of @a sdu */
    305 int iplink_ev_recv(iplink_srv_t *srv, iplink_recv_sdu_t *sdu, ip_ver_t ver)
     169int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu)
    306170{
    307171        if (srv->client_sess == NULL)
    308172                return EIO;
    309        
     173
    310174        async_exch_t *exch = async_exchange_begin(srv->client_sess);
    311        
     175
    312176        ipc_call_t answer;
    313         aid_t req = async_send_1(exch, IPLINK_EV_RECV, (sysarg_t)ver,
    314             &answer);
    315        
     177        aid_t req = async_send_2(exch, IPLINK_EV_RECV, sdu->lsrc.ipv4,
     178            sdu->ldest.ipv4, &answer);
    316179        int rc = async_data_write_start(exch, sdu->data, sdu->size);
    317180        async_exchange_end(exch);
    318        
     181
    319182        if (rc != EOK) {
    320183                async_forget(req);
    321184                return rc;
    322185        }
    323        
     186
    324187        sysarg_t retval;
    325188        async_wait_for(req, &retval);
    326189        if (retval != EOK)
    327190                return retval;
    328        
    329         return EOK;
    330 }
    331191
    332 int iplink_ev_change_addr(iplink_srv_t *srv, addr48_t *addr)
    333 {
    334         if (srv->client_sess == NULL)
    335                 return EIO;
    336        
    337         async_exch_t *exch = async_exchange_begin(srv->client_sess);
    338        
    339         ipc_call_t answer;
    340         aid_t req = async_send_0(exch, IPLINK_EV_CHANGE_ADDR, &answer);
    341        
    342         int rc = async_data_write_start(exch, addr, sizeof(addr48_t));
    343         async_exchange_end(exch);
    344        
    345         if (rc != EOK) {
    346                 async_forget(req);
    347                 return rc;
    348         }
    349        
    350         sysarg_t retval;
    351         async_wait_for(req, &retval);
    352         if (retval != EOK)
    353                 return retval;
    354        
    355192        return EOK;
    356193}
Note: See TracChangeset for help on using the changeset viewer.