Ignore:
Timestamp:
2010-10-26T22:45:19Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f2d2c604
Parents:
e503d3a9 (diff), 3cd95ef (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/net.

File:
1 edited

Legend:

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

    re503d3a9 re7f6389  
    5858#include "nildummy.h"
    5959
    60 /** The module name.
    61  *
    62  */
     60/** The module name. */
    6361#define NAME  "nildummy"
    6462
    65 /** Default maximum transmission unit.
    66  *
    67  */
     63/** Default maximum transmission unit. */
    6864#define NET_DEFAULT_MTU  1500
    6965
    70 /** Network interface layer module global data.
    71  *
    72  */
     66/** Network interface layer module global data. */
    7367nildummy_globals_t nildummy_globals;
    7468
     
    7872{
    7973        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    80        
    8174        if (nildummy_globals.proto.phone)
    82                 il_device_state_msg(nildummy_globals.proto.phone, device_id, state,
    83                     nildummy_globals.proto.service);
    84        
     75                il_device_state_msg(nildummy_globals.proto.phone, device_id,
     76                    state, nildummy_globals.proto.service);
    8577        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    8678       
     
    9991        nildummy_globals.net_phone = net_phone;
    10092        nildummy_globals.proto.phone = 0;
    101         ERROR_PROPAGATE(nildummy_devices_initialize(&nildummy_globals.devices));
     93        ERROR_CODE = nildummy_devices_initialize(&nildummy_globals.devices);
    10294       
    10395        fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
    10496        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    10597       
    106         return EOK;
    107 }
    108 
    109 /** Process IPC messages from the registered device driver modules in an infinite loop.
    110  *
    111  * @param[in]     iid   The message identifier.
    112  * @param[in,out] icall The message parameters.
    113  *
    114  */
    115 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t * icall){
     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 */
     107static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall)
     108{
    116109        ERROR_DECLARE;
    117110
    118111        packet_t packet;
    119112
    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);
     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);
    134133                }
     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  *
    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  */
    154 static int nildummy_device_message(device_id_t device_id, services_t service,
    155     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 * @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 */
     154static int
     155nildummy_device_message(device_id_t device_id, services_t service, size_t mtu)
    156156{
    157157        ERROR_DECLARE;
     
    161161
    162162        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
     163
    163164        // an existing device?
    164165        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    165         if(device){
    166                 if(device->service != service){
     166        if (device) {
     167                if (device->service != service) {
    167168                        printf("Device %d already exists\n", device->device_id);
    168                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
     169                        fibril_rwlock_write_unlock(
     170                            &nildummy_globals.devices_lock);
    169171                        return EEXIST;
    170                 }else{
    171                         // update mtu
    172                         if(mtu > 0){
    173                                 device->mtu = mtu;
    174                         }else{
    175                                 device->mtu = NET_DEFAULT_MTU;
    176                         }
    177                         printf("Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu);
    178                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    179                         // notify the upper layer module
    180                         fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    181                         if(nildummy_globals.proto.phone){
    182                                 il_mtu_changed_msg(nildummy_globals.proto.phone, device->device_id, device->mtu, nildummy_globals.proto.service);
    183                         }
    184                         fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
    185                         return EOK;
    186172                }
    187         }else{
    188                 // create a new device
    189                 device = (nildummy_device_ref) malloc(sizeof(nildummy_device_t));
    190                 if(! device){
    191                         return ENOMEM;
     173               
     174                // update mtu
     175                if (mtu > 0)
     176                        device->mtu = mtu;
     177                else
     178                        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);
    192190                }
    193                 device->device_id = device_id;
    194                 device->service = service;
    195                 if(mtu > 0){
    196                         device->mtu = mtu;
    197                 }else{
    198                         device->mtu = NET_DEFAULT_MTU;
    199                 }
    200                 // bind the device driver
    201                 device->phone = netif_bind_service(device->service, device->device_id, SERVICE_ETHERNET, nildummy_receiver);
    202                 if(device->phone < 0){
    203                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    204                         free(device);
    205                         return device->phone;
    206                 }
    207                 // get hardware address
    208                 if(ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, &device->addr, &device->addr_data))){
    209                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    210                         free(device);
    211                         return ERROR_CODE;
    212                 }
    213                 // add to the cache
    214                 index = nildummy_devices_add(&nildummy_globals.devices, device->device_id, device);
    215                 if(index < 0){
    216                         fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    217                         free(device->addr);
    218                         free(device->addr_data);
    219                         free(device);
    220                         return index;
    221                 }
    222                 printf("%s: Device registered (id: %d, service: %d, mtu: %d)\n",
    223                     NAME, device->device_id, device->service, device->mtu);
    224         }
     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);
    225238        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    226239        return EOK;
     
    229242/** Return the device hardware address.
    230243 *
    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  */
    239 static int nildummy_addr_message(device_id_t device_id,
    240     measured_string_ref *address)
     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 */
     251static int
     252nildummy_addr_message(device_id_t device_id, measured_string_ref *address)
    241253{
    242254        nildummy_device_ref device;
    243255
    244         if(! address){
     256        if (!address)
    245257                return EBADMEM;
    246         }
     258       
    247259        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    248260        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    249         if(! device){
     261        if (!device) {
    250262                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    251263                return ENOENT;
     
    253265        *address = device->addr;
    254266        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
     267       
    255268        return (*address) ? EOK : ENOENT;
    256269}
     
    258271/** Return the device packet dimensions for sending.
    259272 *
    260  * @param[in]  device_id The device identifier.
    261  * @param[out] addr_len  The minimum reserved address length.
    262  * @param[out] prefix    The minimum reserved prefix size.
    263  * @param[out] content   The maximum content size.
    264  * @param[out] suffix    The minimum reserved suffix size.
    265  *
    266  * @return EOK on success.
    267  * @return EBADMEM if either one of the parameters is NULL.
    268  * @return ENOENT if there is no such device.
    269  *
    270  */
    271 static int nildummy_packet_space_message(device_id_t device_id,
    272     size_t *addr_len, size_t *prefix, size_t *content, size_t *suffix)
     273 * @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 */
     283static int
     284nildummy_packet_space_message(device_id_t device_id, size_t *addr_len,
     285    size_t *prefix, size_t *content, size_t *suffix)
    273286{
    274287        nildummy_device_ref device;
    275288
    276         if(!(addr_len && prefix && content && suffix)){
     289        if (!addr_len || !prefix || !content || !suffix)
    277290                return EBADMEM;
    278         }
     291       
    279292        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    280293        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    281         if(! device){
     294        if (!device) {
    282295                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    283296                return ENOENT;
     
    285298        *content = device->mtu;
    286299        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
     300       
    287301        *addr_len = 0;
    288302        *prefix = 0;
     
    291305}
    292306
    293 int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){
     307int
     308nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet,
     309    services_t target)
     310{
    294311        packet_t next;
    295312
    296313        fibril_rwlock_read_lock(&nildummy_globals.protos_lock);
    297         if(nildummy_globals.proto.phone){
    298                 do{
     314        if (nildummy_globals.proto.phone) {
     315                do {
    299316                        next = pq_detach(packet);
    300                         il_received_msg(nildummy_globals.proto.phone, device_id, packet, nildummy_globals.proto.service);
     317                        il_received_msg(nildummy_globals.proto.phone, device_id,
     318                            packet, nildummy_globals.proto.service);
    301319                        packet = next;
    302                 }while(packet);
     320                } while(packet);
    303321        }
    304322        fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);
     323       
    305324        return EOK;
    306325}
     
    310329 * Pass received packets for this service.
    311330 *
    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  *
     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.
    319336 */
    320337static int nildummy_register_message(services_t service, int phone)
     
    333350/** Send the packet queue.
    334351 *
    335  * @param[in] device_id The device identifier.
    336  * @param[in] packet    The packet queue.
    337  * @param[in] sender    The sending module service.
    338  *
    339  * @return EOK on success.
    340  * @return ENOENT if there no such device.
    341  * @return EINVAL if the service parameter is not known.
    342  *
    343  */
    344 static int nildummy_send_message(device_id_t device_id, packet_t packet,
    345     services_t sender)
     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 */
     359static int
     360nildummy_send_message(device_id_t device_id, packet_t packet, services_t sender)
    346361{
    347362        nildummy_device_ref device;
     
    349364        fibril_rwlock_read_lock(&nildummy_globals.devices_lock);
    350365        device = nildummy_devices_find(&nildummy_globals.devices, device_id);
    351         if(! device){
     366        if (!device) {
    352367                fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    353368                return ENOENT;
    354369        }
    355370        // send packet queue
    356         if(packet){
    357                 netif_send_msg(device->phone, device_id, packet, SERVICE_NILDUMMY);
    358         }
     371        if (packet)
     372                netif_send_msg(device->phone, device_id, packet,
     373                    SERVICE_NILDUMMY);
    359374        fibril_rwlock_read_unlock(&nildummy_globals.devices_lock);
    360375        return EOK;
    361376}
    362377
    363 int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
     378int
     379nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call,
    364380    ipc_call_t *answer, int *answer_count)
    365381{
     
    375391        *answer_count = 0;
    376392        switch (IPC_GET_METHOD(*call)) {
    377                 case IPC_M_PHONE_HUNGUP:
    378                         return EOK;
    379                 case NET_NIL_DEVICE:
    380                         return nildummy_device_message(IPC_GET_DEVICE(call),
    381                             IPC_GET_SERVICE(call), IPC_GET_MTU(call));
    382                 case NET_NIL_SEND:
    383                         ERROR_PROPAGATE(packet_translate_remote(nildummy_globals.net_phone,
    384                             &packet, IPC_GET_PACKET(call)));
    385                         return nildummy_send_message(IPC_GET_DEVICE(call), packet,
    386                             IPC_GET_SERVICE(call));
    387                 case NET_NIL_PACKET_SPACE:
    388                         ERROR_PROPAGATE(nildummy_packet_space_message(IPC_GET_DEVICE(call),
    389                             &addrlen, &prefix, &content, &suffix));
    390                         IPC_SET_ADDR(answer, addrlen);
    391                         IPC_SET_PREFIX(answer, prefix);
    392                         IPC_SET_CONTENT(answer, content);
    393                         IPC_SET_SUFFIX(answer, suffix);
    394                         *answer_count = 4;
    395                         return EOK;
    396                 case NET_NIL_ADDR:
    397                         ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
    398                             &address));
    399                         return measured_strings_reply(address, 1);
    400                 case NET_NIL_BROADCAST_ADDR:
    401                         ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
    402                             &address));
    403                         return measured_strings_reply(address, 1);
    404                 case IPC_M_CONNECT_TO_ME:
    405                         return nildummy_register_message(NIL_GET_PROTO(call),
    406                             IPC_GET_PHONE(call));
     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));
    407430        }
    408431       
     
    412435/** Default thread for new connections.
    413436 *
    414  * @param[in] iid   The initial message identifier.
    415  * @param[in] icall The initial message call structure.
    416  *
     437 * @param[in] iid       The initial message identifier.
     438 * @param[in] icall     The initial message call structure.
    417439 */
    418440static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    424446        ipc_answer_0(iid, EOK);
    425447       
    426         while(true) {
     448        while (true) {
    427449                ipc_call_t answer;
    428450                int answer_count;
     
    436458               
    437459                /* Process the message */
    438                 int res = nil_module_message_standalone(NAME, callid, &call, &answer,
    439                     &answer_count);
    440                
    441                 /* End if said to either by the message or the processing result */
    442                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
     460                int res = nil_module_message_standalone(NAME, callid, &call,
     461                    &answer, &answer_count);
     462               
     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))
    443469                        return;
    444470               
     
    453479       
    454480        /* Start the module */
    455         if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection)))
    456                 return ERROR_CODE;
    457        
     481        ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection));
    458482        return EOK;
    459483}
Note: See TracChangeset for help on using the changeset viewer.