Ignore:
File:
1 edited

Legend:

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

    r9cd8165 r6b82009  
    11/*
    22 * Copyright (c) 2009 Lukas Mejdrech
    3  * Copyright (c) 2011 Radim Vansa
    4  * Copyright (c) 2011 Jiri Svoboda
    53 * All rights reserved.
    64 *
     
    3836 */
    3937
    40 #include <assert.h>
    4138#include <async.h>
    4239#include <malloc.h>
     
    5350#include <net/packet.h>
    5451#include <packet_remote.h>
    55 #include <packet_client.h>
    56 #include <device/nic.h>
    57 #include <loc.h>
     52#include <netif_remote.h>
    5853#include <nil_skel.h>
    5954#include "nildummy.h"
     
    7065DEVICE_MAP_IMPLEMENT(nildummy_devices, nildummy_device_t);
    7166
    72 static void nildummy_nic_cb_conn(ipc_callid_t iid, ipc_call_t *icall,
    73     void *arg);
    74 
    75 static int nildummy_device_state(nildummy_device_t *device, sysarg_t state)
     67int nil_device_state_msg_local(device_id_t device_id, sysarg_t state)
    7668{
    7769        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    7870        if (nildummy_globals.proto.sess)
    79                 il_device_state_msg(nildummy_globals.proto.sess,
    80                     device->device_id, state, nildummy_globals.proto.service);
     71                il_device_state_msg(nildummy_globals.proto.sess, device_id,
     72                    state, nildummy_globals.proto.service);
    8173        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    8274       
    8375        return EOK;
    84 }
    85 
    86 static int nildummy_addr_changed(nildummy_device_t *device)
    87 {
    88         return ENOTSUP;
    8976}
    9077
     
    10491       
    10592        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 */
     102static 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        }
    106131}
    107132
     
    123148 *
    124149 */
    125 static int nildummy_device_message(nic_device_id_t device_id,
    126     service_id_t sid, size_t mtu)
     150static int nildummy_device_message(device_id_t device_id, services_t service,
     151    size_t mtu)
    127152{
    128153        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
     
    132157            nildummy_devices_find(&nildummy_globals.devices, device_id);
    133158        if (device) {
    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);
     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);
    138163                        return EEXIST;
    139164                }
     
    145170                        device->mtu = NET_DEFAULT_MTU;
    146171               
    147                 printf("Device %d already exists (mtu: %zu)\n", device->device_id,
    148                     device->mtu);
     172                printf("Device %d already exists:\tMTU\t= %zu\n",
     173                    device->device_id, device->mtu);
    149174                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    150175               
     
    167192       
    168193        device->device_id = device_id;
    169         device->sid = sid;
     194        device->service = service;
    170195        if (mtu > 0)
    171196                device->mtu = mtu;
    172197        else
    173198                device->mtu = NET_DEFAULT_MTU;
    174        
     199
    175200        /* Bind the device driver */
    176         device->sess = loc_service_connect(EXCHANGE_SERIALIZE, sid,
    177             IPC_FLAG_BLOCKING);
     201        device->sess = netif_bind_service(device->service, device->device_id,
     202            SERVICE_ETHERNET, nildummy_receiver);
    178203        if (device->sess == NULL) {
    179204                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     
    182207        }
    183208       
    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        
    192209        /* Get hardware address */
    193         rc = nic_get_address(device->sess, &device->addr);
     210        int rc = netif_get_addr_req(device->sess, device->device_id,
     211            &device->addr, &device->addr_data);
    194212        if (rc != EOK) {
    195213                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     
    197215                return rc;
    198216        }
    199        
    200         device->addr_len = ETH_ADDR;
    201217       
    202218        /* Add to the cache */
     
    205221        if (index < 0) {
    206222                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     223                free(device->addr);
     224                free(device->addr_data);
    207225                free(device);
    208226                return index;
    209227        }
    210228       
    211         printf("%s: Device registered (id: %d, mtu: %zu)\n", NAME,
    212             device->device_id, device->mtu);
     229        printf("%s: Device registered (id: %d, service: %d, mtu: %zu)\n",
     230            NAME, device->device_id, device->service, device->mtu);
    213231        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    214232        return EOK;
     
    225243 *
    226244 */
    227 static int nildummy_addr_message(nic_device_id_t device_id, size_t *addrlen)
    228 {
    229         if (!addrlen)
     245static int nildummy_addr_message(device_id_t device_id,
     246    measured_string_t **address)
     247{
     248        if (!address)
    230249                return EBADMEM;
    231250       
     
    239258        }
    240259       
    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;
     260        *address = device->addr;
    262261       
    263262        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    264         return EOK;
     263       
     264        return (*address) ? EOK : ENOENT;
    265265}
    266266
     
    278278 *
    279279 */
    280 static 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)
     280static int nildummy_packet_space_message(device_id_t device_id, size_t *addr_len,
     281    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(nic_device_id_t device_id, packet_t *packet)
     305int nil_received_msg_local(device_id_t device_id, packet_t *packet,
     306    services_t target)
    306307{
    307308        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
     
    339340        nildummy_globals.proto.sess = sess;
    340341       
    341         printf("%s: Protocol registered (service: %#x)\n",
     342        printf("%s: Protocol registered (service: %d)\n",
    342343            NAME, nildummy_globals.proto.service);
    343344       
     
    357358 *
    358359 */
    359 static int nildummy_send_message(nic_device_id_t device_id, packet_t *packet,
     360static int nildummy_send_message(device_id_t device_id, packet_t *packet,
    360361    services_t sender)
    361362{
     
    369370        }
    370371       
    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));
     372        /* Send packet queue */
     373        if (packet)
     374                netif_send_msg(device->sess, device_id, packet,
     375                    SERVICE_NILDUMMY);
    379376       
    380377        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    381378       
    382379        return EOK;
    383 }
    384 
    385 static 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);
    404380}
    405381
     
    407383    ipc_call_t *answer, size_t *answer_count)
    408384{
     385        measured_string_t *address;
    409386        packet_t *packet;
    410387        size_t addrlen;
     
    427404        case NET_NIL_DEVICE:
    428405                return nildummy_device_message(IPC_GET_DEVICE(*call),
    429                     IPC_GET_DEVICE_HANDLE(*call), IPC_GET_MTU(*call));
     406                    IPC_GET_SERVICE(*call), IPC_GET_MTU(*call));
    430407       
    431408        case NET_NIL_SEND:
     
    450427       
    451428        case NET_NIL_ADDR:
    452         case NET_NIL_BROADCAST_ADDR:
    453                 rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &addrlen);
     429                rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &address);
    454430                if (rc != EOK)
    455431                        return rc;
    456                
    457                 IPC_SET_ADDR(*answer, addrlen);
    458                 *answer_count = 1;
    459                 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);
    460439        }
    461440       
    462441        return ENOTSUP;
    463442}
    464 
    465 static 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 
    498443
    499444int main(int argc, char *argv[])
Note: See TracChangeset for help on using the changeset viewer.