Ignore:
File:
1 edited

Legend:

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

    r3cd95ef r14f1db0  
    4141#include <stdio.h>
    4242#include <str.h>
    43 #include <err.h>
    4443#include <ipc/ipc.h>
    45 #include <ipc/net.h>
    4644#include <ipc/services.h>
    4745
    48 #include <net/modules.h>
    49 #include <net/device.h>
     46#include <net_err.h>
     47#include <net_messages.h>
     48#include <net_modules.h>
     49#include <net_device.h>
    5050#include <netif_interface.h>
    5151#include <nil_interface.h>
    5252#include <il_interface.h>
    5353#include <adt/measured_strings.h>
    54 #include <net/packet.h>
     54#include <packet/packet.h>
    5555#include <packet_remote.h>
    5656#include <nil_local.h>
     
    5858#include "nildummy.h"
    5959
    60 /** The module name. */
     60/** The module name.
     61 *
     62 */
    6163#define NAME  "nildummy"
    6264
    63 /** Default maximum transmission unit. */
     65/** Default maximum transmission unit.
     66 *
     67 */
    6468#define NET_DEFAULT_MTU  1500
    6569
    66 /** Network interface layer module global data. */
     70/** Network interface layer module global data.
     71 *
     72 */
    6773nildummy_globals_t nildummy_globals;
    6874
     
    7278{
    7379        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
     80       
    7481        if (nildummy_globals.proto.phone)
    75                 il_device_state_msg(nildummy_globals.proto.phone, device_id,
    76                     state, nildummy_globals.proto.service);
     82                il_device_state_msg(nildummy_globals.proto.phone, device_id, state,
     83                    nildummy_globals.proto.service);
     84       
    7785        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    7886       
     
    9199        nildummy_globals.net_phone = net_phone;
    92100        nildummy_globals.proto.phone = 0;
    93         ERROR_CODE = nildummy_devices_initialize(&nildummy_globals.devices);
     101        ERROR_PROPAGATE(nildummy_devices_initialize(&nildummy_globals.devices));
    94102       
    95103        fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
    96104        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    97105       
    98         return ERROR_CODE;
    99 }
    100 
    101 /** Process IPC messages from the registered device driver modules in an
    102  * infinite loop.
    103  *
    104  * @param[in] iid       The message identifier.
    105  * @param[in,out]       icall The message parameters.
    106  */
    107 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall)
    108 {
     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 */
     115static void nildummy_receiver(ipc_callid_t iid, ipc_call_t * icall){
    109116        ERROR_DECLARE;
    110117
    111118        packet_t packet;
    112119
    113         while (true) {
    114                 switch (IPC_GET_METHOD(*icall)) {
    115                 case NET_NIL_DEVICE_STATE:
    116                         ERROR_CODE = nil_device_state_msg_local(0,
    117                             IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
    118                         ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
    119                         break;
    120                
    121                 case NET_NIL_RECEIVED:
    122                         if (ERROR_NONE(packet_translate_remote(
    123                             nildummy_globals.net_phone, &packet,
    124                             IPC_GET_PACKET(icall)))) {
    125                                 ERROR_CODE = nil_received_msg_local(0,
    126                                     IPC_GET_DEVICE(icall), packet, 0);
    127                         }
    128                         ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
    129                         break;
    130                
    131                 default:
    132                         ipc_answer_0(iid, (ipcarg_t) ENOTSUP);
    133                 }
    134                
     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);
     134                }
    135135                iid = async_get_call(icall);
    136136        }
     
    141141 * Determine the device local hardware address.
    142142 *
    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  * @returns             EOK on success.
    147  * @returns             EEXIST if the device with the different service exists.
    148  * @returns             ENOMEM if there is not enough memory left.
    149  * @returns             Other error codes as defined for the
    150  *                      netif_bind_service() function.
    151  * @returns             Other error codes as defined for the
    152  *                      netif_get_addr_req() function.
    153  */
    154 static int
    155 nildummy_device_message(device_id_t device_id, services_t service, size_t mtu)
     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 *
     153 */
     154static int nildummy_device_message(device_id_t device_id, services_t service,
     155    size_t mtu)
    156156{
    157157        ERROR_DECLARE;
     
    161161
    162162        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
    163 
    164163        // an existing device?
    165164        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    166         if (device) {
    167                 if (device->service != service) {
     165        if(device){
     166                if(device->service != service){
    168167                        printf("Device %d already exists\n", device->device_id);
    169                         fibril_rwlock_write_unlock(
    170                             &nildummy_globals.devices_lock);
     168                        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    171169                        return EEXIST;
    172                 }
    173                
    174                 // update mtu
    175                 if (mtu > 0)
     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;
     186                }
     187        }else{
     188                // create a new device
     189                device = (nildummy_device_ref) malloc(sizeof(nildummy_device_t));
     190                if(! device){
     191                        return ENOMEM;
     192                }
     193                device->device_id = device_id;
     194                device->service = service;
     195                if(mtu > 0){
    176196                        device->mtu = mtu;
    177                 else
     197                }else{
    178198                        device->mtu = NET_DEFAULT_MTU;
    179                
    180                 printf("Device %d already exists:\tMTU\t= %d\n",
    181                     device->device_id, device->mtu);
    182                 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    183                
    184                 // notify the upper layer module
    185                 fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    186                 if (nildummy_globals.proto.phone) {
    187                         il_mtu_changed_msg(nildummy_globals.proto.phone,
    188                             device->device_id, device->mtu,
    189                             nildummy_globals.proto.service);
    190                 }
    191                 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    192                
    193                 return EOK;
    194         }
    195        
    196         // create a new device
    197         device = (nildummy_device_ref) malloc(sizeof(nildummy_device_t));
    198         if (!device)
    199                 return ENOMEM;
    200        
    201         device->device_id = device_id;
    202         device->service = service;
    203         if (mtu > 0)
    204                 device->mtu = mtu;
    205         else
    206                 device->mtu = NET_DEFAULT_MTU;
    207 
    208         // bind the device driver
    209         device->phone = netif_bind_service(device->service, device->device_id,
    210             SERVICE_ETHERNET, nildummy_receiver);
    211         if (device->phone < 0) {
    212                 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    213                 free(device);
    214                 return device->phone;
    215         }
    216        
    217         // get hardware address
    218         if (ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id,
    219             &device->addr, &device->addr_data))) {
    220                 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    221                 free(device);
    222                 return ERROR_CODE;
    223         }
    224        
    225         // add to the cache
    226         index = nildummy_devices_add(&nildummy_globals.devices,
    227             device->device_id, device);
    228         if (index < 0) {
    229                 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    230                 free(device->addr);
    231                 free(device->addr_data);
    232                 free(device);
    233                 return index;
    234         }
    235        
    236         printf("%s: Device registered (id: %d, service: %d, mtu: %d)\n",
    237             NAME, device->device_id, device->service, device->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        }
    238225        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    239226        return EOK;
     
    242229/** Return the device hardware address.
    243230 *
    244  * @param[in] device_id The device identifier.
    245  * @param[out] address  The device hardware address.
    246  * @return               EOK on success.
    247  * @return              EBADMEM if the address parameter is NULL.
    248  * @return              ENOENT if there no such device.
    249  *
    250  */
    251 static int
    252 nildummy_addr_message(device_id_t device_id, measured_string_ref *address)
     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.
     237 *
     238 */
     239static int nildummy_addr_message(device_id_t device_id,
     240    measured_string_ref *address)
    253241{
    254242        nildummy_device_ref device;
    255243
    256         if (!address)
     244        if(! address){
    257245                return EBADMEM;
    258        
     246        }
    259247        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    260248        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    261         if (!device) {
     249        if(! device){
    262250                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    263251                return ENOENT;
     
    265253        *address = device->addr;
    266254        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    267        
    268255        return (*address) ? EOK : ENOENT;
    269256}
     
    271258/** Return the device packet dimensions for sending.
    272259 *
    273  * @param[in] device_id The device identifier.
    274  * @param[out] addr_len The minimum reserved address length.
    275  * @param[out] prefix   The minimum reserved prefix size.
    276  * @param[out] content  The maximum content size.
    277  * @param[out] suffix   The minimum reserved suffix size.
    278  * @return              EOK on success.
    279  * @return              EBADMEM if either one of the parameters is NULL.
    280  * @return              ENOENT if there is no such device.
    281  *
    282  */
    283 static int
    284 nildummy_packet_space_message(device_id_t device_id, size_t *addr_len,
    285     size_t *prefix, size_t *content, size_t *suffix)
     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 */
     271static int nildummy_packet_space_message(device_id_t device_id,
     272    size_t *addr_len, size_t *prefix, size_t *content, size_t *suffix)
    286273{
    287274        nildummy_device_ref device;
    288275
    289         if (!addr_len || !prefix || !content || !suffix)
     276        if(!(addr_len && prefix && content && suffix)){
    290277                return EBADMEM;
    291        
     278        }
    292279        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    293280        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    294         if (!device) {
     281        if(! device){
    295282                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    296283                return ENOENT;
     
    298285        *content = device->mtu;
    299286        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    300        
    301287        *addr_len = 0;
    302288        *prefix = 0;
     
    305291}
    306292
    307 int
    308 nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet,
    309     services_t target)
    310 {
     293int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
    311294        packet_t next;
    312295
    313296        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    314         if (nildummy_globals.proto.phone) {
    315                 do {
     297        if(nildummy_globals.proto.phone){
     298                do{
    316299                        next = pq_detach(packet);
    317                         il_received_msg(nildummy_globals.proto.phone, device_id,
    318                             packet, nildummy_globals.proto.service);
     300                        il_received_msg(nildummy_globals.proto.phone, device_id, packet, nildummy_globals.proto.service);
    319301                        packet = next;
    320                 } while(packet);
     302                }while(packet);
    321303        }
    322304        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    323        
    324305        return EOK;
    325306}
     
    329310 * Pass received packets for this service.
    330311 *
    331  * @param[in] service   The module service.
    332  * @param[in] phone     The service phone.
    333  * @return              EOK on success.
    334  * @return              ENOENT if the service is not known.
    335  * @return              ENOMEM if there is not enough memory left.
     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 *
    336319 */
    337320static int nildummy_register_message(services_t service, int phone)
     
    350333/** Send the packet queue.
    351334 *
    352  * @param[in] device_id The device identifier.
    353  * @param[in] packet    The packet queue.
    354  * @param[in] sender    The sending module service.
    355  * @return              EOK on success.
    356  * @return              ENOENT if there no such device.
    357  * @return              EINVAL if the service parameter is not known.
    358  */
    359 static int
    360 nildummy_send_message(device_id_t device_id, packet_t packet, services_t sender)
     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 */
     344static int nildummy_send_message(device_id_t device_id, packet_t packet,
     345    services_t sender)
    361346{
    362347        nildummy_device_ref device;
     
    364349        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    365350        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    366         if (!device) {
     351        if(! device){
    367352                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    368353                return ENOENT;
    369354        }
    370355        // send packet queue
    371         if (packet)
    372                 netif_send_msg(device->phone, device_id, packet,
    373                     SERVICE_NILDUMMY);
     356        if(packet){
     357                netif_send_msg(device->phone, device_id, packet, SERVICE_NILDUMMY);
     358        }
    374359        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    375360        return EOK;
    376361}
    377362
    378 int
    379 nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
     363int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
    380364    ipc_call_t *answer, int *answer_count)
    381365{
     
    391375        *answer_count = 0;
    392376        switch (IPC_GET_METHOD(*call)) {
    393         case IPC_M_PHONE_HUNGUP:
    394                 return EOK;
    395        
    396         case NET_NIL_DEVICE:
    397                 return nildummy_device_message(IPC_GET_DEVICE(call),
    398                     IPC_GET_SERVICE(call), IPC_GET_MTU(call));
    399        
    400         case NET_NIL_SEND:
    401                 ERROR_PROPAGATE(packet_translate_remote(
    402                     nildummy_globals.net_phone, &packet, IPC_GET_PACKET(call)));
    403                 return nildummy_send_message(IPC_GET_DEVICE(call), packet,
    404                     IPC_GET_SERVICE(call));
    405        
    406         case NET_NIL_PACKET_SPACE:
    407                 ERROR_PROPAGATE(nildummy_packet_space_message(
    408                     IPC_GET_DEVICE(call), &addrlen, &prefix, &content,
    409                     &suffix));
    410                 IPC_SET_ADDR(answer, addrlen);
    411                 IPC_SET_PREFIX(answer, prefix);
    412                 IPC_SET_CONTENT(answer, content);
    413                 IPC_SET_SUFFIX(answer, suffix);
    414                 *answer_count = 4;
    415                 return EOK;
    416        
    417         case NET_NIL_ADDR:
    418                 ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
    419                     &address));
    420                 return measured_strings_reply(address, 1);
    421        
    422         case NET_NIL_BROADCAST_ADDR:
    423                 ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
    424                     &address));
    425                 return measured_strings_reply(address, 1);
    426        
    427         case IPC_M_CONNECT_TO_ME:
    428                 return nildummy_register_message(NIL_GET_PROTO(call),
    429                     IPC_GET_PHONE(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));
    430407        }
    431408       
     
    433410}
    434411
     412#ifndef CONFIG_NETIF_NIL_BUNDLE
     413
    435414/** Default thread for new connections.
    436415 *
    437  * @param[in] iid       The initial message identifier.
    438  * @param[in] icall     The initial message call structure.
     416 * @param[in] iid   The initial message identifier.
     417 * @param[in] icall The initial message call structure.
     418 *
    439419 */
    440420static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    446426        ipc_answer_0(iid, EOK);
    447427       
    448         while (true) {
     428        while(true) {
    449429                ipc_call_t answer;
    450430                int answer_count;
     
    458438               
    459439                /* Process the message */
    460                 int res = nil_module_message_standalone(NAME, callid, &call,
    461                     &answer, &answer_count);
     440                int res = nil_module_message_standalone(NAME, callid, &call, &answer,
     441                    &answer_count);
    462442               
    463                 /*
    464                  * End if told to either by the message or the processing
    465                  * result.
    466                  */
    467                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
    468                     (res == EHANGUP))
     443                /* End if said to either by the message or the processing result */
     444                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
    469445                        return;
    470446               
     
    479455       
    480456        /* Start the module */
    481         ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection));
    482         return EOK;
    483 }
     457        if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection)))
     458                return ERROR_CODE;
     459       
     460        return EOK;
     461}
     462
     463#endif /* CONFIG_NETIF_NIL_BUNDLE */
    484464
    485465/** @}
Note: See TracChangeset for help on using the changeset viewer.