Ignore:
File:
1 edited

Legend:

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

    r093c0a1 r514ee46  
    4141#include <stdio.h>
    4242#include <str.h>
     43#include <err.h>
    4344#include <ipc/ipc.h>
    4445#include <ipc/net.h>
     
    5758#include "nildummy.h"
    5859
    59 /** The module name. */
     60/** The module name.
     61 *
     62 */
    6063#define NAME  "nildummy"
    6164
    62 /** Default maximum transmission unit. */
     65/** Default maximum transmission unit.
     66 *
     67 */
    6368#define NET_DEFAULT_MTU  1500
    6469
    65 /** Network interface layer module global data. */
     70/** Network interface layer module global data.
     71 *
     72 */
    6673nildummy_globals_t nildummy_globals;
    6774
     
    7178{
    7279        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
     80       
    7381        if (nildummy_globals.proto.phone)
    74                 il_device_state_msg(nildummy_globals.proto.phone, device_id,
    75                     state, nildummy_globals.proto.service);
     82                il_device_state_msg(nildummy_globals.proto.phone, device_id, state,
     83                    nildummy_globals.proto.service);
     84       
    7685        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    7786       
     
    8190int nil_initialize(int net_phone)
    8291{
    83         int rc;
     92        ERROR_DECLARE;
    8493       
    8594        fibril_rwlock_initialize(&nildummy_globals.devices_lock);
     
    9099        nildummy_globals.net_phone = net_phone;
    91100        nildummy_globals.proto.phone = 0;
    92         rc = nildummy_devices_initialize(&nildummy_globals.devices);
     101        ERROR_PROPAGATE(nildummy_devices_initialize(&nildummy_globals.devices));
    93102       
    94103        fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
    95104        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    96105       
    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  */
    106 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall)
    107 {
     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){
     116        ERROR_DECLARE;
     117
    108118        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);
    131                 }
    132                
     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);
     134                }
    133135                iid = async_get_call(icall);
    134136        }
     
    139141 * Determine the device local hardware address.
    140142 *
    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  * @returns             EOK on success.
    145  * @returns             EEXIST if the device with the different service exists.
    146  * @returns             ENOMEM if there is not enough memory left.
    147  * @returns             Other error codes as defined for the
    148  *                      netif_bind_service() function.
    149  * @returns             Other error codes as defined for the
    150  *                      netif_get_addr_req() function.
    151  */
    152 static int
    153 nildummy_device_message(device_id_t device_id, services_t service, size_t mtu)
    154 {
     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)
     156{
     157        ERROR_DECLARE;
     158
    155159        nildummy_device_ref device;
    156160        int index;
    157         int rc;
    158161
    159162        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
    160 
    161163        // an existing device?
    162164        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    163         if (device) {
    164                 if (device->service != service) {
     165        if(device){
     166                if(device->service != service){
    165167                        printf("Device %d already exists\n", device->device_id);
    166                         fibril_rwlock_write_unlock(
    167                             &nildummy_globals.devices_lock);
     168                        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    168169                        return EEXIST;
    169                 }
    170                
    171                 // update mtu
    172                 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){
    173196                        device->mtu = mtu;
    174                 else
     197                }else{
    175198                        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);
    187                 }
    188                 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    189                
    190                 return EOK;
    191         }
    192        
    193         // create a new device
    194         device = (nildummy_device_ref) 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);
     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        }
    236225        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    237226        return EOK;
     
    240229/** Return the device hardware address.
    241230 *
    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.
    247  *
    248  */
    249 static int
    250 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)
    251241{
    252242        nildummy_device_ref device;
    253243
    254         if (!address)
     244        if(! address){
    255245                return EBADMEM;
    256        
     246        }
    257247        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    258248        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    259         if (!device) {
     249        if(! device){
    260250                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    261251                return ENOENT;
     
    263253        *address = device->addr;
    264254        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    265        
    266255        return (*address) ? EOK : ENOENT;
    267256}
     
    269258/** Return the device packet dimensions for sending.
    270259 *
    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  */
    281 static int
    282 nildummy_packet_space_message(device_id_t device_id, size_t *addr_len,
    283     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)
    284273{
    285274        nildummy_device_ref device;
    286275
    287         if (!addr_len || !prefix || !content || !suffix)
     276        if(!(addr_len && prefix && content && suffix)){
    288277                return EBADMEM;
    289        
     278        }
    290279        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    291280        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    292         if (!device) {
     281        if(! device){
    293282                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    294283                return ENOENT;
     
    296285        *content = device->mtu;
    297286        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    298        
    299287        *addr_len = 0;
    300288        *prefix = 0;
     
    303291}
    304292
    305 int
    306 nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet,
    307     services_t target)
    308 {
     293int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
    309294        packet_t next;
    310295
    311296        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    312         if (nildummy_globals.proto.phone) {
    313                 do {
     297        if(nildummy_globals.proto.phone){
     298                do{
    314299                        next = pq_detach(packet);
    315                         il_received_msg(nildummy_globals.proto.phone, device_id,
    316                             packet, nildummy_globals.proto.service);
     300                        il_received_msg(nildummy_globals.proto.phone, device_id, packet, nildummy_globals.proto.service);
    317301                        packet = next;
    318                 } while(packet);
     302                }while(packet);
    319303        }
    320304        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    321        
    322305        return EOK;
    323306}
     
    327310 * Pass received packets for this service.
    328311 *
    329  * @param[in] service   The module service.
    330  * @param[in] phone     The service phone.
    331  * @return              EOK on success.
    332  * @return              ENOENT if the service is not known.
    333  * @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 *
    334319 */
    335320static int nildummy_register_message(services_t service, int phone)
     
    348333/** Send the packet queue.
    349334 *
    350  * @param[in] device_id The device identifier.
    351  * @param[in] packet    The packet queue.
    352  * @param[in] sender    The sending module service.
    353  * @return              EOK on success.
    354  * @return              ENOENT if there no such device.
    355  * @return              EINVAL if the service parameter is not known.
    356  */
    357 static int
    358 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)
    359346{
    360347        nildummy_device_ref device;
     
    362349        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    363350        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    364         if (!device) {
     351        if(! device){
    365352                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    366353                return ENOENT;
    367354        }
    368355        // send packet queue
    369         if (packet)
    370                 netif_send_msg(device->phone, device_id, packet,
    371                     SERVICE_NILDUMMY);
     356        if(packet){
     357                netif_send_msg(device->phone, device_id, packet, SERVICE_NILDUMMY);
     358        }
    372359        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    373360        return EOK;
    374361}
    375362
    376 int
    377 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,
    378364    ipc_call_t *answer, int *answer_count)
    379365{
     366        ERROR_DECLARE;
     367       
    380368        measured_string_ref address;
    381369        packet_t packet;
     
    384372        size_t suffix;
    385373        size_t content;
    386         int rc;
    387374       
    388375        *answer_count = 0;
    389376        switch (IPC_GET_METHOD(*call)) {
    390         case IPC_M_PHONE_HUNGUP:
    391                 return EOK;
    392        
    393         case NET_NIL_DEVICE:
    394                 return nildummy_device_message(IPC_GET_DEVICE(call),
    395                     IPC_GET_SERVICE(call), IPC_GET_MTU(call));
    396        
    397         case NET_NIL_SEND:
    398                 rc = packet_translate_remote(nildummy_globals.net_phone,
    399                     &packet, IPC_GET_PACKET(call));
    400                 if (rc != EOK)
    401                         return rc;
    402                 return nildummy_send_message(IPC_GET_DEVICE(call), packet,
    403                     IPC_GET_SERVICE(call));
    404        
    405         case NET_NIL_PACKET_SPACE:
    406                 rc = nildummy_packet_space_message(IPC_GET_DEVICE(call),
    407                     &addrlen, &prefix, &content, &suffix);
    408                 if (rc != EOK)
    409                         return rc;
    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                 rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address);
    419                 if (rc != EOK)
    420                         return rc;
    421                 return measured_strings_reply(address, 1);
    422        
    423         case NET_NIL_BROADCAST_ADDR:
    424                 rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address);
    425                 if (rc != EOK)
    426                         return rc;
    427                 return measured_strings_reply(address, 1);
    428        
    429         case IPC_M_CONNECT_TO_ME:
    430                 return nildummy_register_message(NIL_GET_PROTO(call),
    431                     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));
    432407        }
    433408       
     
    437412/** Default thread for new connections.
    438413 *
    439  * @param[in] iid       The initial message identifier.
    440  * @param[in] icall     The initial message call structure.
     414 * @param[in] iid   The initial message identifier.
     415 * @param[in] icall The initial message call structure.
     416 *
    441417 */
    442418static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    448424        ipc_answer_0(iid, EOK);
    449425       
    450         while (true) {
     426        while(true) {
    451427                ipc_call_t answer;
    452428                int answer_count;
     
    460436               
    461437                /* Process the message */
    462                 int res = nil_module_message_standalone(NAME, callid, &call,
    463                     &answer, &answer_count);
     438                int res = nil_module_message_standalone(NAME, callid, &call, &answer,
     439                    &answer_count);
    464440               
    465                 /*
    466                  * End if told to either by the message or the processing
    467                  * result.
    468                  */
    469                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
    470                     (res == EHANGUP))
     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))
    471443                        return;
    472444               
     
    478450int main(int argc, char *argv[])
    479451{
    480         int rc;
     452        ERROR_DECLARE;
    481453       
    482454        /* Start the module */
    483         rc = nil_module_start_standalone(nil_client_connection);
    484         return rc;
     455        if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection)))
     456                return ERROR_CODE;
     457       
     458        return EOK;
    485459}
    486460
Note: See TracChangeset for help on using the changeset viewer.