Ignore:
File:
1 edited

Legend:

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

    r46d4d9f r514ee46  
    4242#include <byteorder.h>
    4343#include <str.h>
    44 #include <errno.h>
     44#include <err.h>
    4545
    4646#include <ipc/ipc.h>
     
    6666#include "eth_header.h"
    6767
    68 /** The module name. */
     68/** The module name.
     69 */
    6970#define NAME  "eth"
    7071
    71 /** Reserved packet prefix length. */
    72 #define ETH_PREFIX \
    73         (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + \
    74         sizeof(eth_header_snap_t))
    75 
    76 /** Reserved packet suffix length. */
    77 #define ETH_SUFFIX \
    78         sizeof(eth_fcs_t)
    79 
    80 /** Maximum packet content length. */
     72/** Reserved packet prefix length.
     73 */
     74#define ETH_PREFIX              (sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t))
     75
     76/** Reserved packet suffix length.
     77 */
     78#define ETH_SUFFIX              sizeof(eth_fcs_t)
     79
     80/** Maximum packet content length.
     81 */
    8182#define ETH_MAX_CONTENT 1500u
    8283
    83 /** Minimum packet content length. */
     84/** Minimum packet content length.
     85 */
    8486#define ETH_MIN_CONTENT 46u
    8587
    86 /** Maximum tagged packet content length. */
    87 #define ETH_MAX_TAGGED_CONTENT(flags) \
    88         (ETH_MAX_CONTENT - \
    89         ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \
    90         sizeof(eth_header_lsap_t) : 0) - \
    91         (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
    92 
    93 /** Minimum tagged packet content length. */
    94 #define ETH_MIN_TAGGED_CONTENT(flags) \
    95         (ETH_MIN_CONTENT - \
    96         ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? \
    97         sizeof(eth_header_lsap_t) : 0) - \
    98         (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
    99 
    100 /** Dummy flag shift value. */
     88/** Maximum tagged packet content length.
     89 */
     90#define ETH_MAX_TAGGED_CONTENT(flags)   (ETH_MAX_CONTENT - ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? sizeof(eth_header_lsap_t) : 0) - (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
     91
     92/** Minimum tagged packet content length.
     93 */
     94#define ETH_MIN_TAGGED_CONTENT(flags)   (ETH_MIN_CONTENT - ((IS_8023_2_LSAP(flags) || IS_8023_2_SNAP(flags)) ? sizeof(eth_header_lsap_t) : 0) - (IS_8023_2_SNAP(flags) ? sizeof(eth_header_snap_t) : 0))
     95
     96/** Dummy flag shift value.
     97 */
    10198#define ETH_DUMMY_SHIFT 0
    10299
    103 /** Mode flag shift value. */
     100/** Mode flag shift value.
     101 */
    104102#define ETH_MODE_SHIFT  1
    105103
    106104/** Dummy device flag.
    107  * Preamble and FCS are mandatory part of the packets.
    108  */
    109 #define ETH_DUMMY               (1 << ETH_DUMMY_SHIFT)
     105 *  Preamble and FCS are mandatory part of the packets.
     106 */
     107#define ETH_DUMMY                               (1 << ETH_DUMMY_SHIFT)
    110108
    111109/** Returns the dummy flag.
    112  * @see ETH_DUMMY
    113  */
    114 #define IS_DUMMY(flags)         ((flags) & ETH_DUMMY)
     110 *  @see ETH_DUMMY
     111 */
     112#define IS_DUMMY(flags)         ((flags) &ETH_DUMMY)
    115113
    116114/** Device mode flags.
    117  * @see ETH_DIX
    118  * @see ETH_8023_2_LSAP
    119  * @see ETH_8023_2_SNAP
    120  */
    121 #define ETH_MODE_MASK           (3 << ETH_MODE_SHIFT)
    122 
    123 /** DIX Ethernet mode flag. */
    124 #define ETH_DIX                 (1 << ETH_MODE_SHIFT)
     115 *  @see ETH_DIX
     116 *  @see ETH_8023_2_LSAP
     117 *  @see ETH_8023_2_SNAP
     118 */
     119#define ETH_MODE_MASK                   (3 << ETH_MODE_SHIFT)
     120
     121/** DIX Ethernet mode flag.
     122 */
     123#define ETH_DIX                                 (1 << ETH_MODE_SHIFT)
    125124
    126125/** Returns whether the DIX Ethernet mode flag is set.
    127  *
    128  * @param[in] flags     The ethernet flags.
    129  * @see ETH_DIX
    130  */
    131 #define IS_DIX(flags)           (((flags) & ETH_MODE_MASK) == ETH_DIX)
    132 
    133 /** 802.3 + 802.2 + LSAP mode flag. */
    134 #define ETH_8023_2_LSAP         (2 << ETH_MODE_SHIFT)
     126 *  @param[in] flags The ethernet flags.
     127 *  @see ETH_DIX
     128 */
     129#define IS_DIX(flags)                   (((flags) &ETH_MODE_MASK) == ETH_DIX)
     130
     131/** 802.3 + 802.2 + LSAP mode flag.
     132 */
     133#define ETH_8023_2_LSAP                 (2 << ETH_MODE_SHIFT)
    135134
    136135/** Returns whether the 802.3 + 802.2 + LSAP mode flag is set.
    137  *
    138  * @param[in] flags     The ethernet flags.
    139  * @see ETH_8023_2_LSAP
    140  */
    141 #define IS_8023_2_LSAP(flags)   (((flags) & ETH_MODE_MASK) == ETH_8023_2_LSAP)
    142 
    143 /** 802.3 + 802.2 + LSAP + SNAP mode flag. */
    144 #define ETH_8023_2_SNAP         (3 << ETH_MODE_SHIFT)
     136 *  @param[in] flags The ethernet flags.
     137 *  @see ETH_8023_2_LSAP
     138 */
     139#define IS_8023_2_LSAP(flags)   (((flags) &ETH_MODE_MASK) == ETH_8023_2_LSAP)
     140
     141/** 802.3 + 802.2 + LSAP + SNAP mode flag.
     142 */
     143#define ETH_8023_2_SNAP                 (3 << ETH_MODE_SHIFT)
    145144
    146145/** Returns whether the 802.3 + 802.2 + LSAP + SNAP mode flag is set.
    147  *
    148  * @param[in] flags     The ethernet flags.
    149  * @see ETH_8023_2_SNAP
    150  */
    151 #define IS_8023_2_SNAP(flags)   (((flags) & ETH_MODE_MASK) == ETH_8023_2_SNAP)
     146 *  @param[in] flags The ethernet flags.
     147 *  @see ETH_8023_2_SNAP
     148 */
     149#define IS_8023_2_SNAP(flags)   (((flags) &ETH_MODE_MASK) == ETH_8023_2_SNAP)
    152150
    153151/** Type definition of the ethernet address type.
    154  * @see eth_addr_type
    155  */
    156 typedef enum eth_addr_type eth_addr_type_t;
    157 
    158 /** Ethernet address type. */
    159 enum eth_addr_type {
    160         /** Local address. */
     152 *  @see eth_addr_type
     153 */
     154typedef enum eth_addr_type      eth_addr_type_t;
     155
     156/** Type definition of the ethernet address type pointer.
     157 *  @see eth_addr_type
     158 */
     159typedef eth_addr_type_t *       eth_addr_type_ref;
     160
     161/** Ethernet address type.
     162 */
     163enum eth_addr_type{
     164        /** Local address.
     165         */
    161166        ETH_LOCAL_ADDR,
    162         /** Broadcast address. */
     167        /** Broadcast address.
     168         */
    163169        ETH_BROADCAST_ADDR
    164170};
    165171
    166 /** Ethernet module global data. */
    167 eth_globals_t eth_globals;
    168 
    169 DEVICE_MAP_IMPLEMENT(eth_devices, eth_device_t);
    170 INT_MAP_IMPLEMENT(eth_protos, eth_proto_t);
    171 
    172 int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state)
    173 {
     172/** Ethernet module global data.
     173 */
     174eth_globals_t   eth_globals;
     175
     176/** @name Message processing functions
     177 */
     178/*@{*/
     179
     180/** Processes IPC messages from the registered device driver modules in an infinite loop.
     181 *  @param[in] iid The message identifier.
     182 *  @param[in,out] icall The message parameters.
     183 */
     184void eth_receiver(ipc_callid_t iid, ipc_call_t * icall);
     185
     186/** Registers new device or updates the MTU of an existing one.
     187 *  Determines the device local hardware address.
     188 *  @param[in] device_id The new device identifier.
     189 *  @param[in] service The device driver service.
     190 *  @param[in] mtu The device maximum transmission unit.
     191 *  @returns EOK on success.
     192 *  @returns EEXIST if the device with the different service exists.
     193 *  @returns ENOMEM if there is not enough memory left.
     194 *  @returns Other error codes as defined for the net_get_device_conf_req() function.
     195 *  @returns Other error codes as defined for the netif_bind_service() function.
     196 *  @returns Other error codes as defined for the netif_get_addr_req() function.
     197 */
     198int eth_device_message(device_id_t device_id, services_t service, size_t mtu);
     199
     200/** Registers receiving module service.
     201 *  Passes received packets for this service.
     202 *  @param[in] service The module service.
     203 *  @param[in] phone The service phone.
     204 *  @returns EOK on success.
     205 *  @returns ENOENT if the service is not known.
     206 *  @returns ENOMEM if there is not enough memory left.
     207 */
     208int eth_register_message(services_t service, int phone);
     209
     210/** Returns the device packet dimensions for sending.
     211 *  @param[in] device_id The device identifier.
     212 *  @param[out] addr_len The minimum reserved address length.
     213 *  @param[out] prefix The minimum reserved prefix size.
     214 *  @param[out] content The maximum content size.
     215 *  @param[out] suffix The minimum reserved suffix size.
     216 *  @returns EOK on success.
     217 *  @returns EBADMEM if either one of the parameters is NULL.
     218 *  @returns ENOENT if there is no such device.
     219 */
     220int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix);
     221
     222/** Returns the device hardware address.
     223 *  @param[in] device_id The device identifier.
     224 *  @param[in] type Type of the desired address.
     225 *  @param[out] address The device hardware address.
     226 *  @returns EOK on success.
     227 *  @returns EBADMEM if the address parameter is NULL.
     228 *  @returns ENOENT if there no such device.
     229 */
     230int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address);
     231
     232/** Sends the packet queue.
     233 *  Sends only packet successfully processed by the eth_prepare_packet() function.
     234 *  @param[in] device_id The device identifier.
     235 *  @param[in] packet The packet queue.
     236 *  @param[in] sender The sending module service.
     237 *  @returns EOK on success.
     238 *  @returns ENOENT if there no such device.
     239 *  @returns EINVAL if the service parameter is not known.
     240 */
     241int eth_send_message(device_id_t device_id, packet_t packet, services_t sender);
     242
     243/*@}*/
     244
     245/** Processes the received packet and chooses the target registered module.
     246 *  @param[in] flags The device flags.
     247 *  @param[in] packet The packet.
     248 *  @returns The target registered module.
     249 *  @returns NULL if the packet is not long enough.
     250 *  @returns NULL if the packet is too long.
     251 *  @returns NULL if the raw ethernet protocol is used.
     252 *  @returns NULL if the dummy device FCS checksum is invalid.
     253 *  @returns NULL if the packet address length is not big enough.
     254 */
     255eth_proto_ref eth_process_packet(int flags, packet_t packet);
     256
     257/** Prepares the packet for sending.
     258 *  @param[in] flags The device flags.
     259 *  @param[in] packet The packet.
     260 *  @param[in] src_addr The source hardware address.
     261 *  @param[in] ethertype The ethernet protocol type.
     262 *  @param[in] mtu The device maximum transmission unit.
     263 *  @returns EOK on success.
     264 *  @returns EINVAL if the packet addresses length is not long enough.
     265 *  @returns EINVAL if the packet is bigger than the device MTU.
     266 *  @returns ENOMEM if there is not enough memory in the packet.
     267 */
     268int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu);
     269
     270DEVICE_MAP_IMPLEMENT(eth_devices, eth_device_t)
     271
     272INT_MAP_IMPLEMENT(eth_protos, eth_proto_t)
     273
     274int nil_device_state_msg_local(int nil_phone, device_id_t device_id, int state){
    174275        int index;
    175         eth_proto_t *proto;
     276        eth_proto_ref proto;
    176277
    177278        fibril_rwlock_read_lock(&eth_globals.protos_lock);
    178         for (index = eth_protos_count(&eth_globals.protos) - 1; index >= 0;
    179             index--) {
     279        for(index = eth_protos_count(&eth_globals.protos) - 1; index >= 0; -- index){
    180280                proto = eth_protos_get_index(&eth_globals.protos, index);
    181                 if (proto && proto->phone) {
    182                         il_device_state_msg(proto->phone, device_id, state,
    183                             proto->service);
     281                if(proto && proto->phone){
     282                        il_device_state_msg(proto->phone, device_id, state, proto->service);
    184283                }
    185284        }
    186285        fibril_rwlock_read_unlock(&eth_globals.protos_lock);
    187        
    188286        return EOK;
    189287}
    190288
    191 int nil_initialize(int net_phone)
    192 {
    193         int rc;
     289int nil_initialize(int net_phone){
     290        ERROR_DECLARE;
    194291
    195292        fibril_rwlock_initialize(&eth_globals.devices_lock);
    196293        fibril_rwlock_initialize(&eth_globals.protos_lock);
    197        
    198294        fibril_rwlock_write_lock(&eth_globals.devices_lock);
    199295        fibril_rwlock_write_lock(&eth_globals.protos_lock);
    200296        eth_globals.net_phone = net_phone;
    201 
    202         eth_globals.broadcast_addr =
    203             measured_string_create_bulk("\xFF\xFF\xFF\xFF\xFF\xFF",
    204             CONVERT_SIZE(uint8_t, char, ETH_ADDR));
    205         if (!eth_globals.broadcast_addr) {
    206                 rc = ENOMEM;
    207                 goto out;
    208         }
    209 
    210         rc = eth_devices_initialize(&eth_globals.devices);
    211         if (rc != EOK) {
    212                 free(eth_globals.broadcast_addr);
    213                 goto out;
    214         }
    215 
    216         rc = eth_protos_initialize(&eth_globals.protos);
    217         if (rc != EOK) {
    218                 free(eth_globals.broadcast_addr);
     297        eth_globals.broadcast_addr = measured_string_create_bulk("\xFF\xFF\xFF\xFF\xFF\xFF", CONVERT_SIZE(uint8_t, char, ETH_ADDR));
     298        if(! eth_globals.broadcast_addr){
     299                return ENOMEM;
     300        }
     301        ERROR_PROPAGATE(eth_devices_initialize(&eth_globals.devices));
     302        if(ERROR_OCCURRED(eth_protos_initialize(&eth_globals.protos))){
    219303                eth_devices_destroy(&eth_globals.devices);
    220         }
    221 out:
     304                return ERROR_CODE;
     305        }
    222306        fibril_rwlock_write_unlock(&eth_globals.protos_lock);
    223307        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    224        
    225         return rc;
    226 }
    227 
    228 /** Processes IPC messages from the registered device driver modules in an
    229  * infinite loop.
    230  *
    231  * @param[in] iid       The message identifier.
    232  * @param[in,out] icall The message parameters.
    233  */
    234 static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall)
    235 {
    236         packet_t *packet;
    237         int rc;
    238 
    239         while (true) {
    240                 switch (IPC_GET_METHOD(*icall)) {
    241                 case NET_NIL_DEVICE_STATE:
    242                         nil_device_state_msg_local(0, IPC_GET_DEVICE(icall),
    243                             IPC_GET_STATE(icall));
    244                         ipc_answer_0(iid, EOK);
    245                         break;
    246                 case NET_NIL_RECEIVED:
    247                         rc = packet_translate_remote(eth_globals.net_phone,
    248                             &packet, IPC_GET_PACKET(icall));
    249                         if (rc == EOK) {
    250                                 rc = nil_received_msg_local(0,
    251                                     IPC_GET_DEVICE(icall), packet, 0);
    252                         }
    253                         ipc_answer_0(iid, (ipcarg_t) rc);
    254                         break;
    255                 default:
    256                         ipc_answer_0(iid, (ipcarg_t) ENOTSUP);
    257                 }
    258                
    259                 iid = async_get_call(icall);
    260         }
    261 }
    262 
    263 /** Registers new device or updates the MTU of an existing one.
    264  *
    265  * Determines the device local hardware address.
    266  *
    267  * @param[in] device_id The new device identifier.
    268  * @param[in] service   The device driver service.
    269  * @param[in] mtu       The device maximum transmission unit.
    270  * @return              EOK on success.
    271  * @return              EEXIST if the device with the different service exists.
    272  * @return              ENOMEM if there is not enough memory left.
    273  * @return              Other error codes as defined for the
    274  *                      net_get_device_conf_req() function.
    275  * @return              Other error codes as defined for the
    276  *                      netif_bind_service() function.
    277  * @return              Other error codes as defined for the
    278  *                      netif_get_addr_req() function.
    279  */
    280 static int eth_device_message(device_id_t device_id, services_t service,
    281     size_t mtu)
    282 {
    283         eth_device_t *device;
     308        return EOK;
     309}
     310
     311int eth_device_message(device_id_t device_id, services_t service, size_t mtu){
     312        ERROR_DECLARE;
     313
     314        eth_device_ref device;
    284315        int index;
    285         measured_string_t names[2] = {
    286                 {
    287                         (char *) "ETH_MODE",
    288                         8
    289                 },
    290                 {
    291                         (char *) "ETH_DUMMY",
    292                         9
    293                 }
    294         };
    295         measured_string_t *configuration;
     316        measured_string_t names[2] = {{str_dup("ETH_MODE"), 8}, {str_dup("ETH_DUMMY"), 9}};
     317        measured_string_ref configuration;
    296318        size_t count = sizeof(names) / sizeof(measured_string_t);
    297         char *data;
    298         eth_proto_t *proto;
    299         int rc;
     319        char * data;
     320        eth_proto_ref proto;
    300321
    301322        fibril_rwlock_write_lock(&eth_globals.devices_lock);
    302         /* An existing device? */
     323        // an existing device?
    303324        device = eth_devices_find(&eth_globals.devices, device_id);
    304         if (device) {
    305                 if (device->service != service) {
     325        if(device){
     326                if(device->service != service){
    306327                        printf("Device %d already exists\n", device->device_id);
    307328                        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    308329                        return EEXIST;
    309                 }
    310                
    311                 /* Update mtu */
    312                 if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags)))
     330                }else{
     331                        // update mtu
     332                        if((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))){
     333                                device->mtu = mtu;
     334                        }else{
     335                                 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
     336                        }
     337                        printf("Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu);
     338                        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     339                        // notify all upper layer modules
     340                        fibril_rwlock_read_lock(&eth_globals.protos_lock);
     341                        for(index = 0; index < eth_protos_count(&eth_globals.protos); ++ index){
     342                                proto = eth_protos_get_index(&eth_globals.protos, index);
     343                                if (proto->phone){
     344                                        il_mtu_changed_msg(proto->phone, device->device_id, device->mtu, proto->service);
     345                                }
     346                        }
     347                        fibril_rwlock_read_unlock(&eth_globals.protos_lock);
     348                        return EOK;
     349                }
     350        }else{
     351                // create a new device
     352                device = (eth_device_ref) malloc(sizeof(eth_device_t));
     353                if(! device){
     354                        return ENOMEM;
     355                }
     356                device->device_id = device_id;
     357                device->service = service;
     358                device->flags = 0;
     359                if((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags))){
    313360                        device->mtu = mtu;
    314                 else
    315                         device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
    316                
    317                 printf("Device %d already exists:\tMTU\t= %d\n",
    318                     device->device_id, device->mtu);
    319                 fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    320                
    321                 /* Notify all upper layer modules */
    322                 fibril_rwlock_read_lock(&eth_globals.protos_lock);
    323                 for (index = 0; index < eth_protos_count(&eth_globals.protos);
    324                     index++) {
    325                         proto = eth_protos_get_index(&eth_globals.protos,
    326                             index);
    327                         if (proto->phone) {
    328                                 il_mtu_changed_msg(proto->phone,
    329                                     device->device_id, device->mtu,
    330                                     proto->service);
     361                }else{
     362                         device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
     363                }
     364                configuration = &names[0];
     365                if(ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone, device->device_id, &configuration, count, &data))){
     366                        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     367                        free(device);
     368                        return ERROR_CODE;
     369                }
     370                if(configuration){
     371                        if(! str_lcmp(configuration[0].value, "DIX", configuration[0].length)){
     372                                device->flags |= ETH_DIX;
     373                        }else if(! str_lcmp(configuration[0].value, "8023_2_LSAP", configuration[0].length)){
     374                                device->flags |= ETH_8023_2_LSAP;
     375                        }else device->flags |= ETH_8023_2_SNAP;
     376                        if((configuration[1].value) && (configuration[1].value[0] == 'y')){
     377                                device->flags |= ETH_DUMMY;
    331378                        }
    332                 }
    333 
    334                 fibril_rwlock_read_unlock(&eth_globals.protos_lock);
    335                 return EOK;
    336         }
    337        
    338         /* Create a new device */
    339         device = (eth_device_t *) malloc(sizeof(eth_device_t));
    340         if (!device)
    341                 return ENOMEM;
    342 
    343         device->device_id = device_id;
    344         device->service = service;
    345         device->flags = 0;
    346         if ((mtu > 0) && (mtu <= ETH_MAX_TAGGED_CONTENT(device->flags)))
    347                 device->mtu = mtu;
    348         else
    349                 device->mtu = ETH_MAX_TAGGED_CONTENT(device->flags);
    350 
    351         configuration = &names[0];
    352         rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id,
    353             &configuration, count, &data);
    354         if (rc != EOK) {
    355                 fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    356                 free(device);
    357                 return rc;
    358         }
    359 
    360         if (configuration) {
    361                 if (!str_lcmp(configuration[0].value, "DIX",
    362                     configuration[0].length)) {
    363                         device->flags |= ETH_DIX;
    364                 } else if(!str_lcmp(configuration[0].value, "8023_2_LSAP",
    365                     configuration[0].length)) {
    366                         device->flags |= ETH_8023_2_LSAP;
    367                 } else {
     379                        net_free_settings(configuration, data);
     380                }else{
    368381                        device->flags |= ETH_8023_2_SNAP;
    369382                }
    370                
    371                 if (configuration[1].value &&
    372                     (configuration[1].value[0] == 'y')) {
    373                         device->flags |= ETH_DUMMY;
    374                 }
    375                 net_free_settings(configuration, data);
    376         } else {
    377                 device->flags |= ETH_8023_2_SNAP;
    378         }
    379        
    380         /* Bind the device driver */
    381         device->phone = netif_bind_service(device->service, device->device_id,
    382             SERVICE_ETHERNET, eth_receiver);
    383         if (device->phone < 0) {
    384                 fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    385                 free(device);
    386                 return device->phone;
    387         }
    388        
    389         /* Get hardware address */
    390         rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
    391             &device->addr_data);
    392         if (rc != EOK) {
    393                 fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    394                 free(device);
    395                 return rc;
    396         }
    397        
    398         /* Add to the cache */
    399         index = eth_devices_add(&eth_globals.devices, device->device_id,
    400             device);
    401         if (index < 0) {
    402                 fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    403                 free(device->addr);
    404                 free(device->addr_data);
    405                 free(device);
    406                 return index;
    407         }
    408        
    409         printf("%s: Device registered (id: %d, service: %d: mtu: %d, "
    410             "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n",
    411             NAME, device->device_id, device->service, device->mtu,
    412             device->addr_data[0], device->addr_data[1],
    413             device->addr_data[2], device->addr_data[3],
    414             device->addr_data[4], device->addr_data[5], device->flags);
    415 
     383                // bind the device driver
     384                device->phone = netif_bind_service(device->service, device->device_id, SERVICE_ETHERNET, eth_receiver);
     385                if(device->phone < 0){
     386                        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     387                        free(device);
     388                        return device->phone;
     389                }
     390                // get hardware address
     391                if(ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, &device->addr, &device->addr_data))){
     392                        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     393                        free(device);
     394                        return ERROR_CODE;
     395                }
     396                // add to the cache
     397                index = eth_devices_add(&eth_globals.devices, device->device_id, device);
     398                if(index < 0){
     399                        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
     400                        free(device->addr);
     401                        free(device->addr_data);
     402                        free(device);
     403                        return index;
     404                }
     405                printf("%s: Device registered (id: %d, service: %d: mtu: %d, "
     406                    "mac: %x:%x:%x:%x:%x:%x, flags: 0x%x)\n",
     407                    NAME, device->device_id, device->service, device->mtu,
     408                    device->addr_data[0], device->addr_data[1],
     409                    device->addr_data[2], device->addr_data[3],
     410                    device->addr_data[4], device->addr_data[5], device->flags);
     411        }
    416412        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    417413        return EOK;
    418414}
    419415
    420 /** Processes the received packet and chooses the target registered module.
    421  *
    422  * @param[in] flags     The device flags.
    423  * @param[in] packet    The packet.
    424  * @return              The target registered module.
    425  * @return              NULL if the packet is not long enough.
    426  * @return              NULL if the packet is too long.
    427  * @return              NULL if the raw ethernet protocol is used.
    428  * @return              NULL if the dummy device FCS checksum is invalid.
    429  * @return              NULL if the packet address length is not big enough.
    430  */
    431 static eth_proto_t *eth_process_packet(int flags, packet_t *packet)
    432 {
    433         eth_header_snap_t *header;
     416eth_proto_ref eth_process_packet(int flags, packet_t packet){
     417        ERROR_DECLARE;
     418
     419        eth_header_snap_ref header;
    434420        size_t length;
    435421        eth_type_t type;
    436422        size_t prefix;
    437423        size_t suffix;
    438         eth_fcs_t *fcs;
    439         uint8_t *data;
    440         int rc;
     424        eth_fcs_ref fcs;
     425        uint8_t * data;
    441426
    442427        length = packet_get_data_length(packet);
    443        
    444         if (IS_DUMMY(flags))
     428        if(IS_DUMMY(flags)){
    445429                packet_trim(packet, sizeof(eth_preamble_t), 0);
    446         if (length < sizeof(eth_header_t) + ETH_MIN_CONTENT +
    447             (IS_DUMMY(flags) ? ETH_SUFFIX : 0))
    448                 return NULL;
    449        
     430        }
     431        if(length < sizeof(eth_header_t) + ETH_MIN_CONTENT + (IS_DUMMY(flags) ? ETH_SUFFIX : 0)) return NULL;
    450432        data = packet_get_data(packet);
    451         header = (eth_header_snap_t *) data;
     433        header = (eth_header_snap_ref) data;
    452434        type = ntohs(header->header.ethertype);
    453        
    454         if (type >= ETH_MIN_PROTO) {
    455                 /* DIX Ethernet */
     435        if(type >= ETH_MIN_PROTO){
     436                // DIX Ethernet
    456437                prefix = sizeof(eth_header_t);
    457438                suffix = 0;
    458                 fcs = (eth_fcs_t *) data + length - sizeof(eth_fcs_t);
     439                fcs = (eth_fcs_ref) data + length - sizeof(eth_fcs_t);
    459440                length -= sizeof(eth_fcs_t);
    460         } else if(type <= ETH_MAX_CONTENT) {
    461                 /* Translate "LSAP" values */
    462                 if ((header->lsap.dsap == ETH_LSAP_GLSAP) &&
    463                     (header->lsap.ssap == ETH_LSAP_GLSAP)) {
    464                         /* Raw packet -- discard */
     441        }else if(type <= ETH_MAX_CONTENT){
     442                // translate "LSAP" values
     443                if((header->lsap.dsap == ETH_LSAP_GLSAP) && (header->lsap.ssap == ETH_LSAP_GLSAP)){
     444                        // raw packet
     445                        // discard
    465446                        return NULL;
    466                 } else if((header->lsap.dsap == ETH_LSAP_SNAP) &&
    467                     (header->lsap.ssap == ETH_LSAP_SNAP)) {
    468                         /*
    469                          * IEEE 802.3 + 802.2 + LSAP + SNAP
    470                          * organization code not supported
    471                          */
     447                }else if((header->lsap.dsap == ETH_LSAP_SNAP) && (header->lsap.ssap == ETH_LSAP_SNAP)){
     448                        // IEEE 802.3 + 802.2 + LSAP + SNAP
     449                        // organization code not supported
    472450                        type = ntohs(header->snap.ethertype);
    473                         prefix = sizeof(eth_header_t) +
    474                             sizeof(eth_header_lsap_t) +
    475                             sizeof(eth_header_snap_t);
    476                 } else {
    477                         /* IEEE 802.3 + 802.2 LSAP */
     451                        prefix = sizeof(eth_header_t) + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t);
     452                }else{
     453                        // IEEE 802.3 + 802.2 LSAP
    478454                        type = lsap_map(header->lsap.dsap);
    479                         prefix = sizeof(eth_header_t) +
    480                             sizeof(eth_header_lsap_t);
    481                 }
    482 
    483                 suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0U;
    484                 fcs = (eth_fcs_t *) data + prefix + type + suffix;
     455                        prefix = sizeof(eth_header_t) + sizeof(eth_header_lsap_t);
     456                }
     457                suffix = (type < ETH_MIN_CONTENT) ? ETH_MIN_CONTENT - type : 0u;
     458                fcs = (eth_fcs_ref) data + prefix + type + suffix;
    485459                suffix += length - prefix - type;
    486460                length = prefix + type + suffix;
    487         } else {
    488                 /* Invalid length/type, should not occur */
     461        }else{
     462                // invalid length/type, should not occurr
    489463                return NULL;
    490464        }
    491        
    492         if (IS_DUMMY(flags)) {
    493                 if (~compute_crc32(~0U, data, length * 8) != ntohl(*fcs))
     465        if(IS_DUMMY(flags)){
     466                if((~ compute_crc32(~ 0u, data, length * 8)) != ntohl(*fcs)){
    494467                        return NULL;
     468                }
    495469                suffix += sizeof(eth_fcs_t);
    496470        }
    497        
    498         rc = packet_set_addr(packet, header->header.source_address,
    499             header->header.destination_address, ETH_ADDR);
    500         if (rc != EOK)
     471        if(ERROR_OCCURRED(packet_set_addr(packet, header->header.source_address, header->header.destination_address, ETH_ADDR))
     472                || ERROR_OCCURRED(packet_trim(packet, prefix, suffix))){
    501473                return NULL;
    502 
    503         rc = packet_trim(packet, prefix, suffix);
    504         if (rc != EOK)
    505                 return NULL;
    506        
     474        }
    507475        return eth_protos_find(&eth_globals.protos, type);
    508476}
    509477
    510 int nil_received_msg_local(int nil_phone, device_id_t device_id,
    511     packet_t *packet, services_t target)
    512 {
    513         eth_proto_t *proto;
    514         packet_t *next;
    515         eth_device_t *device;
     478int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
     479        eth_proto_ref proto;
     480        packet_t next;
     481        eth_device_ref device;
    516482        int flags;
    517483
    518484        fibril_rwlock_read_lock(&eth_globals.devices_lock);
    519485        device = eth_devices_find(&eth_globals.devices, device_id);
    520         if (!device) {
     486        if(! device){
    521487                fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    522488                return ENOENT;
    523489        }
    524 
    525490        flags = device->flags;
    526491        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    527        
    528492        fibril_rwlock_read_lock(&eth_globals.protos_lock);
    529         do {
     493        do{
    530494                next = pq_detach(packet);
    531495                proto = eth_process_packet(flags, packet);
    532                 if (proto) {
    533                         il_received_msg(proto->phone, device_id, packet,
    534                             proto->service);
    535                 } else {
     496                if(proto){
     497                        il_received_msg(proto->phone, device_id, packet, proto->service);
     498                }else{
    536499                        // drop invalid/unknown
    537                         pq_release_remote(eth_globals.net_phone,
    538                             packet_get_id(packet));
     500                        pq_release_remote(eth_globals.net_phone, packet_get_id(packet));
    539501                }
    540502                packet = next;
    541         } while(packet);
    542 
     503        }while(packet);
    543504        fibril_rwlock_read_unlock(&eth_globals.protos_lock);
    544505        return EOK;
    545506}
    546507
    547 /** Returns the device packet dimensions for sending.
    548  *
    549  * @param[in] device_id The device identifier.
    550  * @param[out] addr_len The minimum reserved address length.
    551  * @param[out] prefix   The minimum reserved prefix size.
    552  * @param[out] content  The maximum content size.
    553  * @param[out] suffix   The minimum reserved suffix size.
    554  * @return              EOK on success.
    555  * @return              EBADMEM if either one of the parameters is NULL.
    556  * @return              ENOENT if there is no such device.
    557  */
    558 static int eth_packet_space_message(device_id_t device_id, size_t *addr_len,
    559     size_t *prefix, size_t *content, size_t *suffix)
    560 {
    561         eth_device_t *device;
    562 
    563         if (!addr_len || !prefix || !content || !suffix)
     508int eth_packet_space_message(device_id_t device_id, size_t * addr_len, size_t * prefix, size_t * content, size_t * suffix){
     509        eth_device_ref device;
     510
     511        if(!(addr_len && prefix && content && suffix)){
    564512                return EBADMEM;
    565        
     513        }
    566514        fibril_rwlock_read_lock(&eth_globals.devices_lock);
    567515        device = eth_devices_find(&eth_globals.devices, device_id);
    568         if (!device) {
     516        if(! device){
    569517                fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    570518                return ENOENT;
    571519        }
    572 
    573520        *content = device->mtu;
    574521        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    575        
    576522        *addr_len = ETH_ADDR;
    577523        *prefix = ETH_PREFIX;
    578524        *suffix = ETH_MIN_CONTENT + ETH_SUFFIX;
    579 
    580525        return EOK;
    581526}
    582527
    583 /** Returns the device hardware address.
    584  *
    585  * @param[in] device_id The device identifier.
    586  * @param[in] type      Type of the desired address.
    587  * @param[out] address  The device hardware address.
    588  * @return              EOK on success.
    589  * @return              EBADMEM if the address parameter is NULL.
    590  * @return              ENOENT if there no such device.
    591  */
    592 static int eth_addr_message(device_id_t device_id, eth_addr_type_t type,
    593     measured_string_t **address)
    594 {
    595         eth_device_t *device;
    596 
    597         if (!address)
     528int eth_addr_message(device_id_t device_id, eth_addr_type_t type, measured_string_ref * address){
     529        eth_device_ref device;
     530
     531        if(! address){
    598532                return EBADMEM;
    599 
    600         if (type == ETH_BROADCAST_ADDR) {
     533        }
     534        if(type == ETH_BROADCAST_ADDR){
    601535                *address = eth_globals.broadcast_addr;
    602         } else {
     536        }else{
    603537                fibril_rwlock_read_lock(&eth_globals.devices_lock);
    604538                device = eth_devices_find(&eth_globals.devices, device_id);
    605                 if (!device) {
     539                if(! device){
    606540                        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    607541                        return ENOENT;
     
    610544                fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    611545        }
    612        
    613546        return (*address) ? EOK : ENOENT;
    614547}
    615548
    616 /** Registers receiving module service.
    617  *
    618  * Passes received packets for this service.
    619  *
    620  * @param[in] service   The module service.
    621  * @param[in] phone     The service phone.
    622  * @return              EOK on success.
    623  * @return              ENOENT if the service is not known.
    624  * @return              ENOMEM if there is not enough memory left.
    625  */
    626 static int eth_register_message(services_t service, int phone)
    627 {
    628         eth_proto_t *proto;
     549int eth_register_message(services_t service, int phone){
     550        eth_proto_ref proto;
    629551        int protocol;
    630552        int index;
    631553
    632554        protocol = protocol_map(SERVICE_ETHERNET, service);
    633         if (!protocol)
     555        if(! protocol){
    634556                return ENOENT;
    635 
     557        }
    636558        fibril_rwlock_write_lock(&eth_globals.protos_lock);
    637559        proto = eth_protos_find(&eth_globals.protos, protocol);
    638         if (proto) {
     560        if(proto){
    639561                proto->phone = phone;
    640562                fibril_rwlock_write_unlock(&eth_globals.protos_lock);
    641563                return EOK;
    642         } else {
    643                 proto = (eth_proto_t *) malloc(sizeof(eth_proto_t));
    644                 if (!proto) {
     564        }else{
     565                proto = (eth_proto_ref) malloc(sizeof(eth_proto_t));
     566                if(! proto){
    645567                        fibril_rwlock_write_unlock(&eth_globals.protos_lock);
    646568                        return ENOMEM;
    647569                }
    648 
    649570                proto->service = service;
    650571                proto->protocol = protocol;
    651572                proto->phone = phone;
    652 
    653573                index = eth_protos_add(&eth_globals.protos, protocol, proto);
    654                 if (index < 0) {
     574                if(index < 0){
    655575                        fibril_rwlock_write_unlock(&eth_globals.protos_lock);
    656576                        free(proto);
     
    659579        }
    660580       
    661         printf("%s: Protocol registered (protocol: %d, service: %d, phone: "
    662             "%d)\n", NAME, proto->protocol, proto->service, proto->phone);
     581        printf("%s: Protocol registered (protocol: %d, service: %d, phone: %d)\n",
     582            NAME, proto->protocol, proto->service, proto->phone);
    663583       
    664584        fibril_rwlock_write_unlock(&eth_globals.protos_lock);
     
    666586}
    667587
    668 /** Prepares the packet for sending.
    669  *
    670  * @param[in] flags     The device flags.
    671  * @param[in] packet    The packet.
    672  * @param[in] src_addr  The source hardware address.
    673  * @param[in] ethertype The ethernet protocol type.
    674  * @param[in] mtu       The device maximum transmission unit.
    675  * @return              EOK on success.
    676  * @return              EINVAL if the packet addresses length is not long
    677  *                      enough.
    678  * @return              EINVAL if the packet is bigger than the device MTU.
    679  * @return              ENOMEM if there is not enough memory in the packet.
    680  */
    681 static int
    682 eth_prepare_packet(int flags, packet_t *packet, uint8_t *src_addr, int ethertype,
    683     size_t mtu)
    684 {
    685         eth_header_snap_t *header;
    686         eth_header_lsap_t *header_lsap;
    687         eth_header_t *header_dix;
    688         eth_fcs_t *fcs;
    689         uint8_t *src;
    690         uint8_t *dest;
     588int eth_prepare_packet(int flags, packet_t packet, uint8_t * src_addr, int ethertype, size_t mtu){
     589        eth_header_snap_ref header;
     590        eth_header_lsap_ref header_lsap;
     591        eth_header_ref header_dix;
     592        eth_fcs_ref fcs;
     593        uint8_t * src;
     594        uint8_t * dest;
    691595        size_t length;
    692596        int i;
    693         void *padding;
    694         eth_preamble_t *preamble;
     597        void * padding;
     598        eth_preamble_ref preamble;
    695599
    696600        i = packet_get_addr(packet, &src, &dest);
    697         if (i < 0)
     601        if(i < 0){
    698602                return i;
    699         if (i != ETH_ADDR)
     603        }
     604        if(i != ETH_ADDR){
    700605                return EINVAL;
    701 
     606        }
    702607        length = packet_get_data_length(packet);
    703         if (length > mtu)
     608        if(length > mtu){
    704609                return EINVAL;
    705        
    706         if (length < ETH_MIN_TAGGED_CONTENT(flags)) {
    707                 padding = packet_suffix(packet,
    708                     ETH_MIN_TAGGED_CONTENT(flags) - length);
    709                 if (!padding)
     610        }
     611        if(length < ETH_MIN_TAGGED_CONTENT(flags)){
     612                padding = packet_suffix(packet, ETH_MIN_TAGGED_CONTENT(flags) - length);
     613                if(! padding){
    710614                        return ENOMEM;
    711 
     615                }
    712616                bzero(padding, ETH_MIN_TAGGED_CONTENT(flags) - length);
    713617        }
    714        
    715         if (IS_DIX(flags)) {
     618        if(IS_DIX(flags)){
    716619                header_dix = PACKET_PREFIX(packet, eth_header_t);
    717                 if (!header_dix)
     620                if(! header_dix){
    718621                        return ENOMEM;
    719                
     622                }
    720623                header_dix->ethertype = (uint16_t) ethertype;
    721624                memcpy(header_dix->source_address, src_addr, ETH_ADDR);
    722625                memcpy(header_dix->destination_address, dest, ETH_ADDR);
    723626                src = &header_dix->destination_address[0];
    724         } else if(IS_8023_2_LSAP(flags)) {
     627        }else if(IS_8023_2_LSAP(flags)){
    725628                header_lsap = PACKET_PREFIX(packet, eth_header_lsap_t);
    726                 if (!header_lsap)
     629                if(! header_lsap){
    727630                        return ENOMEM;
    728                
    729                 header_lsap->header.ethertype = htons(length +
    730                     sizeof(eth_header_lsap_t));
     631                }
     632                header_lsap->header.ethertype = htons(length + sizeof(eth_header_lsap_t));
    731633                header_lsap->lsap.dsap = lsap_unmap(ntohs(ethertype));
    732634                header_lsap->lsap.ssap = header_lsap->lsap.dsap;
     
    735637                memcpy(header_lsap->header.destination_address, dest, ETH_ADDR);
    736638                src = &header_lsap->header.destination_address[0];
    737         } else if(IS_8023_2_SNAP(flags)) {
     639        }else if(IS_8023_2_SNAP(flags)){
    738640                header = PACKET_PREFIX(packet, eth_header_snap_t);
    739                 if (!header)
     641                if(! header){
    740642                        return ENOMEM;
    741                
    742                 header->header.ethertype = htons(length +
    743                     sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t));
     643                }
     644                header->header.ethertype = htons(length + sizeof(eth_header_lsap_t) + sizeof(eth_header_snap_t));
    744645                header->lsap.dsap = (uint16_t) ETH_LSAP_SNAP;
    745646                header->lsap.ssap = header->lsap.dsap;
    746647                header->lsap.ctrl = IEEE_8023_2_UI;
    747                
    748                 for (i = 0; i < 3; ++ i)
     648                for(i = 0; i < 3; ++ i){
    749649                        header->snap.protocol[i] = 0;
    750                
     650                }
    751651                header->snap.ethertype = (uint16_t) ethertype;
    752652                memcpy(header->header.source_address, src_addr, ETH_ADDR);
     
    754654                src = &header->header.destination_address[0];
    755655        }
    756        
    757         if (IS_DUMMY(flags)) {
     656        if(IS_DUMMY(flags)){
    758657                preamble = PACKET_PREFIX(packet, eth_preamble_t);
    759                 if (!preamble)
     658                if(! preamble){
    760659                        return ENOMEM;
    761                
    762                 for (i = 0; i < 7; ++ i)
     660                }
     661                for(i = 0; i < 7; ++ i){
    763662                        preamble->preamble[i] = ETH_PREAMBLE;
    764                
     663                }
    765664                preamble->sfd = ETH_SFD;
    766                
    767665                fcs = PACKET_SUFFIX(packet, eth_fcs_t);
    768                 if (!fcs)
     666                if(! fcs){
    769667                        return ENOMEM;
    770 
    771                 *fcs = htonl(~compute_crc32(~0U, src, length * 8));
    772         }
    773        
     668                }
     669                *fcs = htonl(~ compute_crc32(~ 0u, src, length * 8));
     670        }
    774671        return EOK;
    775672}
    776673
    777 /** Sends the packet queue.
    778  *
    779  * Sends only packet successfully processed by the eth_prepare_packet()
    780  * function.
    781  *
    782  * @param[in] device_id The device identifier.
    783  * @param[in] packet    The packet queue.
    784  * @param[in] sender    The sending module service.
    785  * @return              EOK on success.
    786  * @return              ENOENT if there no such device.
    787  * @return              EINVAL if the service parameter is not known.
    788  */
    789 static int eth_send_message(device_id_t device_id, packet_t *packet,
    790     services_t sender)
    791 {
    792         eth_device_t *device;
    793         packet_t *next;
    794         packet_t *tmp;
     674int eth_send_message(device_id_t device_id, packet_t packet, services_t sender){
     675        ERROR_DECLARE;
     676
     677        eth_device_ref device;
     678        packet_t next;
     679        packet_t tmp;
    795680        int ethertype;
    796         int rc;
    797681
    798682        ethertype = htons(protocol_map(SERVICE_ETHERNET, sender));
    799         if (!ethertype) {
     683        if(! ethertype){
    800684                pq_release_remote(eth_globals.net_phone, packet_get_id(packet));
    801685                return EINVAL;
    802686        }
    803        
    804687        fibril_rwlock_read_lock(&eth_globals.devices_lock);
    805688        device = eth_devices_find(&eth_globals.devices, device_id);
    806         if (!device) {
     689        if(! device){
    807690                fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    808691                return ENOENT;
    809692        }
    810        
    811         /* Process packet queue */
     693        // process packet queue
    812694        next = packet;
    813         do {
    814                 rc = eth_prepare_packet(device->flags, next,
    815                     (uint8_t *) device->addr->value, ethertype, device->mtu);
    816                 if (rc != EOK) {
    817                         /* Release invalid packet */
     695        do{
     696                if(ERROR_OCCURRED(eth_prepare_packet(device->flags, next, (uint8_t *) device->addr->value, ethertype, device->mtu))){
     697                        // release invalid packet
    818698                        tmp = pq_detach(next);
    819                         if (next == packet)
     699                        if(next == packet){
    820700                                packet = tmp;
    821                         pq_release_remote(eth_globals.net_phone,
    822                             packet_get_id(next));
     701                        }
     702                        pq_release_remote(eth_globals.net_phone, packet_get_id(next));
    823703                        next = tmp;
    824                 } else {
     704                }else{
    825705                        next = pq_next(next);
    826706                }
    827         } while(next);
    828        
    829         /* Send packet queue */
    830         if (packet) {
    831                 netif_send_msg(device->phone, device_id, packet,
    832                     SERVICE_ETHERNET);
    833         }
    834 
     707        }while(next);
     708        // send packet queue
     709        if(packet){
     710                netif_send_msg(device->phone, device_id, packet, SERVICE_ETHERNET);
     711        }
    835712        fibril_rwlock_read_unlock(&eth_globals.devices_lock);
    836713        return EOK;
    837714}
    838715
    839 int nil_message_standalone(const char *name, ipc_callid_t callid,
    840     ipc_call_t *call, ipc_call_t *answer, int *answer_count)
     716int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
     717    ipc_call_t *answer, int *answer_count)
    841718{
    842         measured_string_t *address;
    843         packet_t *packet;
     719        ERROR_DECLARE;
     720       
     721        measured_string_ref address;
     722        packet_t packet;
    844723        size_t addrlen;
    845724        size_t prefix;
    846725        size_t suffix;
    847726        size_t content;
    848         int rc;
    849727       
    850728        *answer_count = 0;
    851729        switch (IPC_GET_METHOD(*call)) {
    852         case IPC_M_PHONE_HUNGUP:
    853                 return EOK;
    854        
    855         case NET_NIL_DEVICE:
    856                 return eth_device_message(IPC_GET_DEVICE(call),
    857                     IPC_GET_SERVICE(call), IPC_GET_MTU(call));
    858         case NET_NIL_SEND:
    859                 rc = packet_translate_remote(eth_globals.net_phone, &packet,
    860                     IPC_GET_PACKET(call));
    861                 if (rc != EOK)
    862                         return rc;
    863                 return eth_send_message(IPC_GET_DEVICE(call), packet,
    864                     IPC_GET_SERVICE(call));
    865         case NET_NIL_PACKET_SPACE:
    866                 rc = eth_packet_space_message(IPC_GET_DEVICE(call), &addrlen,
    867                     &prefix, &content, &suffix);
    868                 if (rc != EOK)
    869                         return rc;
    870                 IPC_SET_ADDR(answer, addrlen);
    871                 IPC_SET_PREFIX(answer, prefix);
    872                 IPC_SET_CONTENT(answer, content);
    873                 IPC_SET_SUFFIX(answer, suffix);
    874                 *answer_count = 4;
    875                 return EOK;
    876         case NET_NIL_ADDR:
    877                 rc = eth_addr_message(IPC_GET_DEVICE(call), ETH_LOCAL_ADDR,
    878                     &address);
    879                 if (rc != EOK)
    880                         return rc;
    881                 return measured_strings_reply(address, 1);
    882         case NET_NIL_BROADCAST_ADDR:
    883                 rc = eth_addr_message(IPC_GET_DEVICE(call), ETH_BROADCAST_ADDR,
    884                     &address);
    885                 if (rc != EOK)
     730                case IPC_M_PHONE_HUNGUP:
    886731                        return EOK;
    887                 return measured_strings_reply(address, 1);
    888         case IPC_M_CONNECT_TO_ME:
    889                 return eth_register_message(NIL_GET_PROTO(call),
    890                     IPC_GET_PHONE(call));
     732                case NET_NIL_DEVICE:
     733                        return eth_device_message(IPC_GET_DEVICE(call),
     734                            IPC_GET_SERVICE(call), IPC_GET_MTU(call));
     735                case NET_NIL_SEND:
     736                        ERROR_PROPAGATE(packet_translate_remote(eth_globals.net_phone, &packet,
     737                            IPC_GET_PACKET(call)));
     738                        return eth_send_message(IPC_GET_DEVICE(call), packet,
     739                            IPC_GET_SERVICE(call));
     740                case NET_NIL_PACKET_SPACE:
     741                        ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call),
     742                            &addrlen, &prefix, &content, &suffix));
     743                        IPC_SET_ADDR(answer, addrlen);
     744                        IPC_SET_PREFIX(answer, prefix);
     745                        IPC_SET_CONTENT(answer, content);
     746                        IPC_SET_SUFFIX(answer, suffix);
     747                        *answer_count = 4;
     748                        return EOK;
     749                case NET_NIL_ADDR:
     750                        ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call),
     751                            ETH_LOCAL_ADDR, &address));
     752                        return measured_strings_reply(address, 1);
     753                case NET_NIL_BROADCAST_ADDR:
     754                        ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call),
     755                            ETH_BROADCAST_ADDR, &address));
     756                        return measured_strings_reply(address, 1);
     757                case IPC_M_CONNECT_TO_ME:
     758                        return eth_register_message(NIL_GET_PROTO(call),
     759                            IPC_GET_PHONE(call));
    891760        }
    892761       
     
    894763}
    895764
     765void eth_receiver(ipc_callid_t iid, ipc_call_t * icall){
     766        ERROR_DECLARE;
     767
     768        packet_t packet;
     769
     770        while(true){
     771//              printf("message %d - %d\n", IPC_GET_METHOD(*icall), NET_NIL_FIRST);
     772                switch(IPC_GET_METHOD(*icall)){
     773                        case NET_NIL_DEVICE_STATE:
     774                                nil_device_state_msg_local(0, IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
     775                                ipc_answer_0(iid, EOK);
     776                                break;
     777                        case NET_NIL_RECEIVED:
     778                                if(! ERROR_OCCURRED(packet_translate_remote(eth_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){
     779                                        ERROR_CODE = nil_received_msg_local(0, IPC_GET_DEVICE(icall), packet, 0);
     780                                }
     781                                ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
     782                                break;
     783                        default:
     784                                ipc_answer_0(iid, (ipcarg_t) ENOTSUP);
     785                }
     786                iid = async_get_call(icall);
     787        }
     788}
     789
    896790/** Default thread for new connections.
    897791 *
    898  * @param[in] iid       The initial message identifier.
    899  * @param[in] icall     The initial message call structure.
     792 * @param[in] iid The initial message identifier.
     793 * @param[in] icall The initial message call structure.
     794 *
    900795 */
    901796static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    907802        ipc_answer_0(iid, EOK);
    908803       
    909         while (true) {
     804        while(true) {
    910805                ipc_call_t answer;
    911806                int answer_count;
     
    919814               
    920815                /* Process the message */
    921                 int res = nil_module_message_standalone(NAME, callid, &call,
    922                     &answer, &answer_count);
     816                int res = nil_module_message_standalone(NAME, callid, &call, &answer,
     817                    &answer_count);
    923818               
    924                 /*
    925                  * End if told to either by the message or the processing
    926                  * result.
    927                  */
    928                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
    929                     (res == EHANGUP))
     819                /* End if said to either by the message or the processing result */
     820                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
    930821                        return;
    931822               
     
    937828int main(int argc, char *argv[])
    938829{
    939         int rc;
     830        ERROR_DECLARE;
    940831       
    941832        /* Start the module */
    942         rc = nil_module_start_standalone(nil_client_connection);
    943         return rc;
     833        if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection)))
     834                return ERROR_CODE;
     835       
     836        return EOK;
    944837}
    945838
Note: See TracChangeset for help on using the changeset viewer.