Ignore:
File:
1 edited

Legend:

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

    r514ee46 r46d4d9f  
    4141#include <stdio.h>
    4242#include <str.h>
    43 #include <err.h>
    4443#include <ipc/ipc.h>
    4544#include <ipc/net.h>
     
    5857#include "nildummy.h"
    5958
    60 /** The module name.
    61  *
    62  */
     59/** The module name. */
    6360#define NAME  "nildummy"
    6461
    65 /** Default maximum transmission unit.
    66  *
    67  */
     62/** Default maximum transmission unit. */
    6863#define NET_DEFAULT_MTU  1500
    6964
    70 /** Network interface layer module global data.
    71  *
    72  */
     65/** Network interface layer module global data. */
    7366nildummy_globals_t nildummy_globals;
    7467
     
    7871{
    7972        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    80        
    8173        if (nildummy_globals.proto.phone)
    82                 il_device_state_msg(nildummy_globals.proto.phone, device_id, state,
    83                     nildummy_globals.proto.service);
    84        
     74                il_device_state_msg(nildummy_globals.proto.phone, device_id,
     75                    state, nildummy_globals.proto.service);
    8576        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    8677       
     
    9081int nil_initialize(int net_phone)
    9182{
    92         ERROR_DECLARE;
     83        int rc;
    9384       
    9485        fibril_rwlock_initialize(&nildummy_globals.devices_lock);
     
    9990        nildummy_globals.net_phone = net_phone;
    10091        nildummy_globals.proto.phone = 0;
    101         ERROR_PROPAGATE(nildummy_devices_initialize(&nildummy_globals.devices));
     92        rc = nildummy_devices_initialize(&nildummy_globals.devices);
    10293       
    10394        fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
    10495        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    10596       
    106         return EOK;
    107 }
    108 
    109 /** Process IPC messages from the registered device driver modules in an infinite loop.
    110  *
    111  * @param[in]     iid   The message identifier.
    112  * @param[in,out] icall The message parameters.
    113  *
    114  */
    115 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t * icall){
    116         ERROR_DECLARE;
    117 
    118         packet_t packet;
    119 
    120         while(true){
    121                 switch(IPC_GET_METHOD(*icall)){
    122                         case NET_NIL_DEVICE_STATE:
    123                                 ERROR_CODE = nil_device_state_msg_local(0, IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
    124                                 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
    125                                 break;
    126                         case NET_NIL_RECEIVED:
    127                                 if(! ERROR_OCCURRED(packet_translate_remote(nildummy_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){
    128                                         ERROR_CODE = nil_received_msg_local(0, IPC_GET_DEVICE(icall), packet, 0);
    129                                 }
    130                                 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
    131                                 break;
    132                         default:
    133                                 ipc_answer_0(iid, (ipcarg_t) ENOTSUP);
     97        return rc;
     98}
     99
     100/** Process IPC messages from the registered device driver modules in an
     101 * infinite loop.
     102 *
     103 * @param[in] iid       The message identifier.
     104 * @param[in,out]       icall The message parameters.
     105 */
     106static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall)
     107{
     108        packet_t *packet;
     109        int rc;
     110
     111        while (true) {
     112                switch (IPC_GET_METHOD(*icall)) {
     113                case NET_NIL_DEVICE_STATE:
     114                        rc = nil_device_state_msg_local(0,
     115                            IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
     116                        ipc_answer_0(iid, (ipcarg_t) rc);
     117                        break;
     118               
     119                case NET_NIL_RECEIVED:
     120                        rc = packet_translate_remote(nildummy_globals.net_phone,
     121                            &packet, IPC_GET_PACKET(icall));
     122                        if (rc == EOK) {
     123                                rc = nil_received_msg_local(0,
     124                                    IPC_GET_DEVICE(icall), packet, 0);
     125                        }
     126                        ipc_answer_0(iid, (ipcarg_t) rc);
     127                        break;
     128               
     129                default:
     130                        ipc_answer_0(iid, (ipcarg_t) ENOTSUP);
    134131                }
     132               
    135133                iid = async_get_call(icall);
    136134        }
     
    141139 * Determine the device local hardware address.
    142140 *
    143  * @param[in] device_id The new device identifier.
    144  * @param[in] service   The device driver service.
    145  * @param[in] mtu       The device maximum transmission unit.
    146  *
    147  * @returns EOK on success.
    148  * @returns EEXIST if the device with the different service exists.
    149  * @returns ENOMEM if there is not enough memory left.
    150  * @returns Other error codes as defined for the netif_bind_service() function.
    151  * @returns Other error codes as defined for the netif_get_addr_req() function.
    152  *
     141 * @param[in] device_id The new device identifier.
     142 * @param[in] service   The device driver service.
     143 * @param[in] mtu       The device maximum transmission unit.
     144 * @return              EOK on success.
     145 * @return              EEXIST if the device with the different service exists.
     146 * @return              ENOMEM if there is not enough memory left.
     147 * @return              Other error codes as defined for the
     148 *                      netif_bind_service() function.
     149 * @return              Other error codes as defined for the
     150 *                      netif_get_addr_req() function.
    153151 */
    154152static int nildummy_device_message(device_id_t device_id, services_t service,
    155153    size_t mtu)
    156154{
    157         ERROR_DECLARE;
    158 
    159         nildummy_device_ref device;
     155        nildummy_device_t *device;
    160156        int index;
     157        int rc;
    161158
    162159        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
    163         // an existing device?
     160
     161        /* An existing device? */
    164162        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    165         if(device){
    166                 if(device->service != service){
     163        if (device) {
     164                if (device->service != service) {
    167165                        printf("Device %d already exists\n", device->device_id);
    168                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     166                        fibril_rwlock_write_unlock(
     167                            &nildummy_globals.devices_lock);
    169168                        return EEXIST;
    170                 }else{
    171                         // update mtu
    172                         if(mtu > 0){
    173                                 device->mtu = mtu;
    174                         }else{
    175                                 device->mtu = NET_DEFAULT_MTU;
    176                         }
    177                         printf("Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu);
    178                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    179                         // notify the upper layer module
    180                         fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    181                         if(nildummy_globals.proto.phone){
    182                                 il_mtu_changed_msg(nildummy_globals.proto.phone, device->device_id, device->mtu, nildummy_globals.proto.service);
    183                         }
    184                         fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    185                         return EOK;
    186169                }
    187         }else{
    188                 // create a new device
    189                 device = (nildummy_device_ref) malloc(sizeof(nildummy_device_t));
    190                 if(! device){
    191                         return ENOMEM;
     170               
     171                /* Update MTU */
     172                if (mtu > 0)
     173                        device->mtu = mtu;
     174                else
     175                        device->mtu = NET_DEFAULT_MTU;
     176               
     177                printf("Device %d already exists:\tMTU\t= %d\n",
     178                    device->device_id, device->mtu);
     179                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     180               
     181                /* Notify the upper layer module */
     182                fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
     183                if (nildummy_globals.proto.phone) {
     184                        il_mtu_changed_msg(nildummy_globals.proto.phone,
     185                            device->device_id, device->mtu,
     186                            nildummy_globals.proto.service);
    192187                }
    193                 device->device_id = device_id;
    194                 device->service = service;
    195                 if(mtu > 0){
    196                         device->mtu = mtu;
    197                 }else{
    198                         device->mtu = NET_DEFAULT_MTU;
    199                 }
    200                 // bind the device driver
    201                 device->phone = netif_bind_service(device->service, device->device_id, SERVICE_ETHERNET, nildummy_receiver);
    202                 if(device->phone < 0){
    203                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    204                         free(device);
    205                         return device->phone;
    206                 }
    207                 // get hardware address
    208                 if(ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, &device->addr, &device->addr_data))){
    209                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    210                         free(device);
    211                         return ERROR_CODE;
    212                 }
    213                 // add to the cache
    214                 index = nildummy_devices_add(&nildummy_globals.devices, device->device_id, device);
    215                 if(index < 0){
    216                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    217                         free(device->addr);
    218                         free(device->addr_data);
    219                         free(device);
    220                         return index;
    221                 }
    222                 printf("%s: Device registered (id: %d, service: %d, mtu: %d)\n",
    223                     NAME, device->device_id, device->service, device->mtu);
    224         }
     188                fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
     189               
     190                return EOK;
     191        }
     192       
     193        /* Create a new device */
     194        device = (nildummy_device_t *) malloc(sizeof(nildummy_device_t));
     195        if (!device)
     196                return ENOMEM;
     197       
     198        device->device_id = device_id;
     199        device->service = service;
     200        if (mtu > 0)
     201                device->mtu = mtu;
     202        else
     203                device->mtu = NET_DEFAULT_MTU;
     204
     205        /* Bind the device driver */
     206        device->phone = netif_bind_service(device->service, device->device_id,
     207            SERVICE_ETHERNET, nildummy_receiver);
     208        if (device->phone < 0) {
     209                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     210                free(device);
     211                return device->phone;
     212        }
     213       
     214        /* Get hardware address */
     215        rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
     216            &device->addr_data);
     217        if (rc != EOK) {
     218                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     219                free(device);
     220                return rc;
     221        }
     222       
     223        /* Add to the cache */
     224        index = nildummy_devices_add(&nildummy_globals.devices,
     225            device->device_id, device);
     226        if (index < 0) {
     227                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     228                free(device->addr);
     229                free(device->addr_data);
     230                free(device);
     231                return index;
     232        }
     233       
     234        printf("%s: Device registered (id: %d, service: %d, mtu: %d)\n",
     235            NAME, device->device_id, device->service, device->mtu);
    225236        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    226237        return EOK;
     
    229240/** Return the device hardware address.
    230241 *
    231  * @param[in]  device_id The device identifier.
    232  * @param[out] address   The device hardware address.
    233  *
    234  * @return EOK on success.
    235  * @return EBADMEM if the address parameter is NULL.
    236  * @return ENOENT if there no such device.
     242 * @param[in] device_id The device identifier.
     243 * @param[out] address  The device hardware address.
     244 * @return               EOK on success.
     245 * @return              EBADMEM if the address parameter is NULL.
     246 * @return              ENOENT if there no such device.
    237247 *
    238248 */
    239249static int nildummy_addr_message(device_id_t device_id,
    240     measured_string_ref *address)
    241 {
    242         nildummy_device_ref device;
    243 
    244         if(! address){
     250    measured_string_t **address)
     251{
     252        nildummy_device_t *device;
     253
     254        if (!address)
    245255                return EBADMEM;
    246         }
     256       
    247257        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    248258        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    249         if(! device){
     259        if (!device) {
    250260                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    251261                return ENOENT;
     
    253263        *address = device->addr;
    254264        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
     265       
    255266        return (*address) ? EOK : ENOENT;
    256267}
     
    258269/** Return the device packet dimensions for sending.
    259270 *
    260  * @param[in]  device_id The device identifier.
    261  * @param[out] addr_len  The minimum reserved address length.
    262  * @param[out] prefix    The minimum reserved prefix size.
    263  * @param[out] content   The maximum content size.
    264  * @param[out] suffix    The minimum reserved suffix size.
    265  *
    266  * @return EOK on success.
    267  * @return EBADMEM if either one of the parameters is NULL.
    268  * @return ENOENT if there is no such device.
    269  *
    270  */
    271 static int nildummy_packet_space_message(device_id_t device_id,
    272     size_t *addr_len, size_t *prefix, size_t *content, size_t *suffix)
    273 {
    274         nildummy_device_ref device;
    275 
    276         if(!(addr_len && prefix && content && suffix)){
     271 * @param[in] device_id The device identifier.
     272 * @param[out] addr_len The minimum reserved address length.
     273 * @param[out] prefix   The minimum reserved prefix size.
     274 * @param[out] content  The maximum content size.
     275 * @param[out] suffix   The minimum reserved suffix size.
     276 * @return              EOK on success.
     277 * @return              EBADMEM if either one of the parameters is NULL.
     278 * @return              ENOENT if there is no such device.
     279 *
     280 */
     281static int nildummy_packet_space_message(device_id_t device_id, size_t *addr_len,
     282    size_t *prefix, size_t *content, size_t *suffix)
     283{
     284        nildummy_device_t *device;
     285
     286        if (!addr_len || !prefix || !content || !suffix)
    277287                return EBADMEM;
    278         }
     288       
    279289        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    280290        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    281         if(! device){
     291        if (!device) {
    282292                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    283293                return ENOENT;
    284294        }
     295
    285296        *content = device->mtu;
    286297        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
     298       
    287299        *addr_len = 0;
    288300        *prefix = 0;
     
    291303}
    292304
    293 int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
    294         packet_t next;
     305int nil_received_msg_local(int nil_phone, device_id_t device_id,
     306    packet_t *packet, services_t target)
     307{
     308        packet_t *next;
    295309
    296310        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    297         if(nildummy_globals.proto.phone){
    298                 do{
     311        if (nildummy_globals.proto.phone) {
     312                do {
    299313                        next = pq_detach(packet);
    300                         il_received_msg(nildummy_globals.proto.phone, device_id, packet, nildummy_globals.proto.service);
     314                        il_received_msg(nildummy_globals.proto.phone, device_id,
     315                            packet, nildummy_globals.proto.service);
    301316                        packet = next;
    302                 }while(packet);
     317                } while(packet);
    303318        }
    304319        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
     320       
    305321        return EOK;
    306322}
     
    310326 * Pass received packets for this service.
    311327 *
    312  * @param[in] service The module service.
    313  * @param[in] phone   The service phone.
    314  *
    315  * @return EOK on success.
    316  * @return ENOENT if the service is not known.
    317  * @return ENOMEM if there is not enough memory left.
    318  *
     328 * @param[in] service   The module service.
     329 * @param[in] phone     The service phone.
     330 * @return              EOK on success.
     331 * @return              ENOENT if the service is not known.
     332 * @return              ENOMEM if there is not enough memory left.
    319333 */
    320334static int nildummy_register_message(services_t service, int phone)
     
    333347/** Send the packet queue.
    334348 *
    335  * @param[in] device_id The device identifier.
    336  * @param[in] packet    The packet queue.
    337  * @param[in] sender    The sending module service.
    338  *
    339  * @return EOK on success.
    340  * @return ENOENT if there no such device.
    341  * @return EINVAL if the service parameter is not known.
    342  *
    343  */
    344 static int nildummy_send_message(device_id_t device_id, packet_t packet,
     349 * @param[in] device_id The device identifier.
     350 * @param[in] packet    The packet queue.
     351 * @param[in] sender    The sending module service.
     352 * @return              EOK on success.
     353 * @return              ENOENT if there no such device.
     354 * @return              EINVAL if the service parameter is not known.
     355 */
     356static int nildummy_send_message(device_id_t device_id, packet_t *packet,
    345357    services_t sender)
    346358{
    347         nildummy_device_ref device;
     359        nildummy_device_t *device;
    348360
    349361        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    350362        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    351         if(! device){
     363        if (!device) {
    352364                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    353365                return ENOENT;
    354366        }
    355         // send packet queue
    356         if(packet){
    357                 netif_send_msg(device->phone, device_id, packet, SERVICE_NILDUMMY);
    358         }
     367
     368        /* Send packet queue */
     369        if (packet)
     370                netif_send_msg(device->phone, device_id, packet,
     371                    SERVICE_NILDUMMY);
    359372        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    360373        return EOK;
    361374}
    362375
    363 int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
    364     ipc_call_t *answer, int *answer_count)
    365 {
    366         ERROR_DECLARE;
    367        
    368         measured_string_ref address;
    369         packet_t packet;
     376int nil_message_standalone(const char *name, ipc_callid_t callid,
     377    ipc_call_t *call, ipc_call_t *answer, int *answer_count)
     378{
     379        measured_string_t *address;
     380        packet_t *packet;
    370381        size_t addrlen;
    371382        size_t prefix;
    372383        size_t suffix;
    373384        size_t content;
     385        int rc;
    374386       
    375387        *answer_count = 0;
    376388        switch (IPC_GET_METHOD(*call)) {
    377                 case IPC_M_PHONE_HUNGUP:
    378                         return EOK;
    379                 case NET_NIL_DEVICE:
    380                         return nildummy_device_message(IPC_GET_DEVICE(call),
    381                             IPC_GET_SERVICE(call), IPC_GET_MTU(call));
    382                 case NET_NIL_SEND:
    383                         ERROR_PROPAGATE(packet_translate_remote(nildummy_globals.net_phone,
    384                             &packet, IPC_GET_PACKET(call)));
    385                         return nildummy_send_message(IPC_GET_DEVICE(call), packet,
    386                             IPC_GET_SERVICE(call));
    387                 case NET_NIL_PACKET_SPACE:
    388                         ERROR_PROPAGATE(nildummy_packet_space_message(IPC_GET_DEVICE(call),
    389                             &addrlen, &prefix, &content, &suffix));
    390                         IPC_SET_ADDR(answer, addrlen);
    391                         IPC_SET_PREFIX(answer, prefix);
    392                         IPC_SET_CONTENT(answer, content);
    393                         IPC_SET_SUFFIX(answer, suffix);
    394                         *answer_count = 4;
    395                         return EOK;
    396                 case NET_NIL_ADDR:
    397                         ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
    398                             &address));
    399                         return measured_strings_reply(address, 1);
    400                 case NET_NIL_BROADCAST_ADDR:
    401                         ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
    402                             &address));
    403                         return measured_strings_reply(address, 1);
    404                 case IPC_M_CONNECT_TO_ME:
    405                         return nildummy_register_message(NIL_GET_PROTO(call),
    406                             IPC_GET_PHONE(call));
     389        case IPC_M_PHONE_HUNGUP:
     390                return EOK;
     391       
     392        case NET_NIL_DEVICE:
     393                return nildummy_device_message(IPC_GET_DEVICE(call),
     394                    IPC_GET_SERVICE(call), IPC_GET_MTU(call));
     395       
     396        case NET_NIL_SEND:
     397                rc = packet_translate_remote(nildummy_globals.net_phone,
     398                    &packet, IPC_GET_PACKET(call));
     399                if (rc != EOK)
     400                        return rc;
     401                return nildummy_send_message(IPC_GET_DEVICE(call), packet,
     402                    IPC_GET_SERVICE(call));
     403       
     404        case NET_NIL_PACKET_SPACE:
     405                rc = nildummy_packet_space_message(IPC_GET_DEVICE(call),
     406                    &addrlen, &prefix, &content, &suffix);
     407                if (rc != EOK)
     408                        return rc;
     409                IPC_SET_ADDR(answer, addrlen);
     410                IPC_SET_PREFIX(answer, prefix);
     411                IPC_SET_CONTENT(answer, content);
     412                IPC_SET_SUFFIX(answer, suffix);
     413                *answer_count = 4;
     414                return EOK;
     415       
     416        case NET_NIL_ADDR:
     417                rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address);
     418                if (rc != EOK)
     419                        return rc;
     420                return measured_strings_reply(address, 1);
     421       
     422        case NET_NIL_BROADCAST_ADDR:
     423                rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address);
     424                if (rc != EOK)
     425                        return rc;
     426                return measured_strings_reply(address, 1);
     427       
     428        case IPC_M_CONNECT_TO_ME:
     429                return nildummy_register_message(NIL_GET_PROTO(call),
     430                    IPC_GET_PHONE(call));
    407431        }
    408432       
     
    412436/** Default thread for new connections.
    413437 *
    414  * @param[in] iid   The initial message identifier.
    415  * @param[in] icall The initial message call structure.
    416  *
     438 * @param[in] iid       The initial message identifier.
     439 * @param[in] icall     The initial message call structure.
    417440 */
    418441static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    424447        ipc_answer_0(iid, EOK);
    425448       
    426         while(true) {
     449        while (true) {
    427450                ipc_call_t answer;
    428451                int answer_count;
     
    436459               
    437460                /* Process the message */
    438                 int res = nil_module_message_standalone(NAME, callid, &call, &answer,
    439                     &answer_count);
    440                
    441                 /* End if said to either by the message or the processing result */
    442                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
     461                int res = nil_module_message_standalone(NAME, callid, &call,
     462                    &answer, &answer_count);
     463               
     464                /*
     465                 * End if told to either by the message or the processing
     466                 * result.
     467                 */
     468                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     469                    (res == EHANGUP))
    443470                        return;
    444471               
     
    450477int main(int argc, char *argv[])
    451478{
    452         ERROR_DECLARE;
     479        int rc;
    453480       
    454481        /* Start the module */
    455         if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection)))
    456                 return ERROR_CODE;
    457        
    458         return EOK;
     482        rc = nil_module_start_standalone(nil_client_connection);
     483        return rc;
    459484}
    460485
Note: See TracChangeset for help on using the changeset viewer.