Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/nil/nildummy/nildummy.c

    r6b82009 r9cd8165  
    11/*
    22 * Copyright (c) 2009 Lukas Mejdrech
     3 * Copyright (c) 2011 Radim Vansa
     4 * Copyright (c) 2011 Jiri Svoboda
    35 * All rights reserved.
    46 *
     
    3638 */
    3739
     40#include <assert.h>
    3841#include <async.h>
    3942#include <malloc.h>
     
    5053#include <net/packet.h>
    5154#include <packet_remote.h>
    52 #include <netif_remote.h>
     55#include <packet_client.h>
     56#include <device/nic.h>
     57#include <loc.h>
    5358#include <nil_skel.h>
    5459#include "nildummy.h"
     
    6570DEVICE_MAP_IMPLEMENT(nildummy_devices, nildummy_device_t);
    6671
    67 int nil_device_state_msg_local(device_id_t device_id, sysarg_t state)
     72static void nildummy_nic_cb_conn(ipc_callid_t iid, ipc_call_t *icall,
     73    void *arg);
     74
     75static int nildummy_device_state(nildummy_device_t *device, sysarg_t state)
    6876{
    6977        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    7078        if (nildummy_globals.proto.sess)
    71                 il_device_state_msg(nildummy_globals.proto.sess, device_id,
    72                     state, nildummy_globals.proto.service);
     79                il_device_state_msg(nildummy_globals.proto.sess,
     80                    device->device_id, state, nildummy_globals.proto.service);
    7381        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    7482       
    7583        return EOK;
     84}
     85
     86static int nildummy_addr_changed(nildummy_device_t *device)
     87{
     88        return ENOTSUP;
    7689}
    7790
     
    91104       
    92105        return rc;
    93 }
    94 
    95 /** Process IPC messages from the registered device driver modules
    96  *
    97  * @param[in]     iid   Message identifier.
    98  * @param[in,out] icall Message parameters.
    99  * @param[in]     arg    Local argument.
    100  *
    101  */
    102 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    103 {
    104         packet_t *packet;
    105         int rc;
    106        
    107         while (true) {
    108                 switch (IPC_GET_IMETHOD(*icall)) {
    109                 case NET_NIL_DEVICE_STATE:
    110                         rc = nil_device_state_msg_local(IPC_GET_DEVICE(*icall),
    111                             IPC_GET_STATE(*icall));
    112                         async_answer_0(iid, (sysarg_t) rc);
    113                         break;
    114                
    115                 case NET_NIL_RECEIVED:
    116                         rc = packet_translate_remote(nildummy_globals.net_sess,
    117                             &packet, IPC_GET_PACKET(*icall));
    118                         if (rc == EOK)
    119                                 rc = nil_received_msg_local(IPC_GET_DEVICE(*icall),
    120                                     packet, 0);
    121                        
    122                         async_answer_0(iid, (sysarg_t) rc);
    123                         break;
    124                
    125                 default:
    126                         async_answer_0(iid, (sysarg_t) ENOTSUP);
    127                 }
    128                
    129                 iid = async_get_call(icall);
    130         }
    131106}
    132107
     
    148123 *
    149124 */
    150 static int nildummy_device_message(device_id_t device_id, services_t service,
    151     size_t mtu)
     125static int nildummy_device_message(nic_device_id_t device_id,
     126    service_id_t sid, size_t mtu)
    152127{
    153128        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
     
    157132            nildummy_devices_find(&nildummy_globals.devices, device_id);
    158133        if (device) {
    159                 if (device->service != service) {
    160                         printf("Device %d already exists\n", device->device_id);
    161                         fibril_rwlock_write_unlock(
    162                             &nildummy_globals.devices_lock);
     134                if (device->sid != sid) {
     135                        printf("Device %d exists, handles do not match\n",
     136                            device->device_id);
     137                        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    163138                        return EEXIST;
    164139                }
     
    170145                        device->mtu = NET_DEFAULT_MTU;
    171146               
    172                 printf("Device %d already exists:\tMTU\t= %zu\n",
    173                     device->device_id, device->mtu);
     147                printf("Device %d already exists (mtu: %zu)\n", device->device_id,
     148                    device->mtu);
    174149                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    175150               
     
    192167       
    193168        device->device_id = device_id;
    194         device->service = service;
     169        device->sid = sid;
    195170        if (mtu > 0)
    196171                device->mtu = mtu;
    197172        else
    198173                device->mtu = NET_DEFAULT_MTU;
    199 
     174       
    200175        /* Bind the device driver */
    201         device->sess = netif_bind_service(device->service, device->device_id,
    202             SERVICE_ETHERNET, nildummy_receiver);
     176        device->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid,
     177            IPC_FLAG_BLOCKING);
    203178        if (device->sess == NULL) {
    204179                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     
    207182        }
    208183       
     184        int rc = nic_callback_create(device->sess, nildummy_nic_cb_conn,
     185            device);
     186        if (rc != EOK) {
     187                async_hangup(device->sess);
     188               
     189                return ENOENT;
     190        }
     191       
    209192        /* Get hardware address */
    210         int rc = netif_get_addr_req(device->sess, device->device_id,
    211             &device->addr, &device->addr_data);
     193        rc = nic_get_address(device->sess, &device->addr);
    212194        if (rc != EOK) {
    213195                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     
    215197                return rc;
    216198        }
     199       
     200        device->addr_len = ETH_ADDR;
    217201       
    218202        /* Add to the cache */
     
    221205        if (index < 0) {
    222206                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    223                 free(device->addr);
    224                 free(device->addr_data);
    225207                free(device);
    226208                return index;
    227209        }
    228210       
    229         printf("%s: Device registered (id: %d, service: %d, mtu: %zu)\n",
    230             NAME, device->device_id, device->service, device->mtu);
     211        printf("%s: Device registered (id: %d, mtu: %zu)\n", NAME,
     212            device->device_id, device->mtu);
    231213        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    232214        return EOK;
     
    243225 *
    244226 */
    245 static int nildummy_addr_message(device_id_t device_id,
    246     measured_string_t **address)
    247 {
    248         if (!address)
     227static int nildummy_addr_message(nic_device_id_t device_id, size_t *addrlen)
     228{
     229        if (!addrlen)
    249230                return EBADMEM;
    250231       
     
    258239        }
    259240       
    260         *address = device->addr;
     241        ipc_callid_t callid;
     242        size_t max_len;
     243        if (!async_data_read_receive(&callid, &max_len)) {
     244                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
     245                return EREFUSED;
     246        }
     247       
     248        if (max_len < device->addr_len) {
     249                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
     250                async_data_read_finalize(callid, NULL, 0);
     251                return ELIMIT;
     252        }
     253       
     254        int rc = async_data_read_finalize(callid,
     255            (uint8_t *) &device->addr.address, device->addr_len);
     256        if (rc != EOK) {
     257                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
     258                return rc;
     259        }
     260       
     261        *addrlen = device->addr_len;
    261262       
    262263        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    263        
    264         return (*address) ? EOK : ENOENT;
     264        return EOK;
    265265}
    266266
     
    278278 *
    279279 */
    280 static int nildummy_packet_space_message(device_id_t device_id, size_t *addr_len,
    281     size_t *prefix, size_t *content, size_t *suffix)
     280static int nildummy_packet_space_message(nic_device_id_t device_id,
     281    size_t *addr_len, size_t *prefix, size_t *content, size_t *suffix)
    282282{
    283283        if ((!addr_len) || (!prefix) || (!content) || (!suffix))
     
    303303}
    304304
    305 int nil_received_msg_local(device_id_t device_id, packet_t *packet,
    306     services_t target)
     305int nil_received_msg_local(nic_device_id_t device_id, packet_t *packet)
    307306{
    308307        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
     
    340339        nildummy_globals.proto.sess = sess;
    341340       
    342         printf("%s: Protocol registered (service: %d)\n",
     341        printf("%s: Protocol registered (service: %#x)\n",
    343342            NAME, nildummy_globals.proto.service);
    344343       
     
    358357 *
    359358 */
    360 static int nildummy_send_message(device_id_t device_id, packet_t *packet,
     359static int nildummy_send_message(nic_device_id_t device_id, packet_t *packet,
    361360    services_t sender)
    362361{
     
    370369        }
    371370       
    372         /* Send packet queue */
    373         if (packet)
    374                 netif_send_msg(device->sess, device_id, packet,
    375                     SERVICE_NILDUMMY);
     371        packet_t *p = packet;
     372        do {
     373                nic_send_frame(device->sess, packet_get_data(p),
     374                    packet_get_data_length(p));
     375                p = pq_next(p);
     376        } while (p != NULL);
     377       
     378        pq_release_remote(nildummy_globals.net_sess, packet_get_id(packet));
    376379       
    377380        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    378381       
    379382        return EOK;
     383}
     384
     385static int nildummy_received(nildummy_device_t *device)
     386{
     387        void *data;
     388        size_t size;
     389        int rc;
     390
     391        rc = async_data_write_accept(&data, false, 0, 0, 0, &size);
     392        if (rc != EOK)
     393                return rc;
     394
     395        packet_t *packet = packet_get_1_remote(nildummy_globals.net_sess, size);
     396        if (packet == NULL)
     397                return ENOMEM;
     398
     399        void *pdata = packet_suffix(packet, size);
     400        memcpy(pdata, data, size);
     401        free(pdata);
     402
     403        return nil_received_msg_local(device->device_id, packet);
    380404}
    381405
     
    383407    ipc_call_t *answer, size_t *answer_count)
    384408{
    385         measured_string_t *address;
    386409        packet_t *packet;
    387410        size_t addrlen;
     
    404427        case NET_NIL_DEVICE:
    405428                return nildummy_device_message(IPC_GET_DEVICE(*call),
    406                     IPC_GET_SERVICE(*call), IPC_GET_MTU(*call));
     429                    IPC_GET_DEVICE_HANDLE(*call), IPC_GET_MTU(*call));
    407430       
    408431        case NET_NIL_SEND:
     
    427450       
    428451        case NET_NIL_ADDR:
    429                 rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &address);
     452        case NET_NIL_BROADCAST_ADDR:
     453                rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &addrlen);
    430454                if (rc != EOK)
    431455                        return rc;
    432                 return measured_strings_reply(address, 1);
    433        
    434         case NET_NIL_BROADCAST_ADDR:
    435                 rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &address);
    436                 if (rc != EOK)
    437                         return rc;
    438                 return measured_strings_reply(address, 1);
     456               
     457                IPC_SET_ADDR(*answer, addrlen);
     458                *answer_count = 1;
     459                return rc;
    439460        }
    440461       
    441462        return ENOTSUP;
    442463}
     464
     465static void nildummy_nic_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     466{
     467        nildummy_device_t *device = (nildummy_device_t *)arg;
     468        int rc;
     469       
     470        async_answer_0(iid, EOK);
     471       
     472        while (true) {
     473                ipc_call_t call;
     474                ipc_callid_t callid = async_get_call(&call);
     475               
     476                if (!IPC_GET_IMETHOD(call))
     477                        break;
     478               
     479                switch (IPC_GET_IMETHOD(call)) {
     480                case NIC_EV_DEVICE_STATE:
     481                        rc = nildummy_device_state(device, IPC_GET_ARG1(call));
     482                        async_answer_0(callid, (sysarg_t) rc);
     483                        break;
     484                case NIC_EV_RECEIVED:
     485                        rc = nildummy_received(device);
     486                        async_answer_0(callid, (sysarg_t) rc);
     487                        break;
     488                case NIC_EV_ADDR_CHANGED:
     489                        rc = nildummy_addr_changed(device);
     490                        async_answer_0(callid, (sysarg_t) rc);
     491                        break;
     492                default:
     493                        async_answer_0(callid, ENOTSUP);
     494                }
     495        }
     496}
     497
    443498
    444499int main(int argc, char *argv[])
Note: See TracChangeset for help on using the changeset viewer.