Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tl/udp/udp.c

    r014dd57b r774e6d1a  
    3535 * @see udp.h
    3636 */
     37
     38#include "udp.h"
     39#include "udp_header.h"
     40#include "udp_module.h"
    3741
    3842#include <async.h>
     
    6569#include <socket_core.h>
    6670#include <tl_common.h>
    67 #include <tl_remote.h>
    68 #include <tl_skel.h>
    69 
    70 #include "udp.h"
    71 #include "udp_header.h"
     71#include <tl_local.h>
     72#include <tl_interface.h>
    7273
    7374/** UDP module name. */
    74 #define NAME  "udp"
     75#define NAME    "UDP protocol"
    7576
    7677/** Default UDP checksum computing. */
     
    9192/** UDP global data.  */
    9293udp_globals_t udp_globals;
     94
     95/** Initializes the UDP module.
     96 *
     97 * @param[in] client_connection The client connection processing function. The
     98 *                      module skeleton propagates its own one.
     99 * @return              EOK on success.
     100 * @return              ENOMEM if there is not enough memory left.
     101 */
     102int udp_initialize(async_client_conn_t client_connection)
     103{
     104        measured_string_t names[] = {
     105                {
     106                        (uint8_t *) "UDP_CHECKSUM_COMPUTING",
     107                        22
     108                },
     109                {
     110                        (uint8_t *) "UDP_AUTOBINDING",
     111                        15
     112                }
     113        };
     114        measured_string_t *configuration;
     115        size_t count = sizeof(names) / sizeof(measured_string_t);
     116        uint8_t *data;
     117        int rc;
     118
     119        fibril_rwlock_initialize(&udp_globals.lock);
     120        fibril_rwlock_write_lock(&udp_globals.lock);
     121
     122        udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
     123            ICMP_CONNECT_TIMEOUT);
     124       
     125        udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
     126            SERVICE_UDP, client_connection);
     127        if (udp_globals.ip_phone < 0) {
     128                fibril_rwlock_write_unlock(&udp_globals.lock);
     129                return udp_globals.ip_phone;
     130        }
     131
     132        /* Read default packet dimensions */
     133        rc = ip_packet_size_req(udp_globals.ip_phone, -1,
     134            &udp_globals.packet_dimension);
     135        if (rc != EOK) {
     136                fibril_rwlock_write_unlock(&udp_globals.lock);
     137                return rc;
     138        }
     139       
     140        rc = socket_ports_initialize(&udp_globals.sockets);
     141        if (rc != EOK) {
     142                fibril_rwlock_write_unlock(&udp_globals.lock);
     143                return rc;
     144        }
     145       
     146        rc = packet_dimensions_initialize(&udp_globals.dimensions);
     147        if (rc != EOK) {
     148                socket_ports_destroy(&udp_globals.sockets);
     149                fibril_rwlock_write_unlock(&udp_globals.lock);
     150                return rc;
     151        }
     152       
     153        udp_globals.packet_dimension.prefix += sizeof(udp_header_t);
     154        udp_globals.packet_dimension.content -= sizeof(udp_header_t);
     155        udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
     156
     157        udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
     158        udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
     159
     160        /* Get configuration */
     161        configuration = &names[0];
     162        rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
     163            &data);
     164        if (rc != EOK) {
     165                socket_ports_destroy(&udp_globals.sockets);
     166                fibril_rwlock_write_unlock(&udp_globals.lock);
     167                return rc;
     168        }
     169       
     170        if (configuration) {
     171                if (configuration[0].value)
     172                        udp_globals.checksum_computing =
     173                            (configuration[0].value[0] == 'y');
     174               
     175                if (configuration[1].value)
     176                        udp_globals.autobinding =
     177                            (configuration[1].value[0] == 'y');
     178
     179                net_free_settings(configuration, data);
     180        }
     181
     182        fibril_rwlock_write_unlock(&udp_globals.lock);
     183        return EOK;
     184}
    93185
    94186/** Releases the packet and returns the result.
     
    334426}
    335427
    336 /** Process IPC messages from the IP module
    337  *
    338  * @param[in]     iid   Message identifier.
    339  * @param[in,out] icall Message parameters.
    340  *
    341  */
    342 static void udp_receiver(ipc_callid_t iid, ipc_call_t *icall)
    343 {
    344         packet_t *packet;
    345         int rc;
    346        
    347         while (true) {
    348                 switch (IPC_GET_IMETHOD(*icall)) {
    349                 case NET_TL_RECEIVED:
    350                         rc = packet_translate_remote(udp_globals.net_phone, &packet,
    351                             IPC_GET_PACKET(*icall));
    352                         if (rc == EOK)
    353                                 rc = udp_received_msg(IPC_GET_DEVICE(*icall), packet,
    354                                     SERVICE_UDP, IPC_GET_ERROR(*icall));
    355                        
    356                         ipc_answer_0(iid, (sysarg_t) rc);
    357                         break;
    358                 default:
    359                         ipc_answer_0(iid, (sysarg_t) ENOTSUP);
    360                 }
    361                
    362                 iid = async_get_call(icall);
    363         }
    364 }
    365 
    366 /** Initialize the UDP module.
    367  *
    368  * @param[in] net_phone Network module phone.
    369  *
    370  * @return EOK on success.
    371  * @return ENOMEM if there is not enough memory left.
    372  *
    373  */
    374 int tl_initialize(int net_phone)
    375 {
    376         measured_string_t names[] = {
    377                 {
    378                         (uint8_t *) "UDP_CHECKSUM_COMPUTING",
    379                         22
    380                 },
    381                 {
    382                         (uint8_t *) "UDP_AUTOBINDING",
    383                         15
    384                 }
    385         };
    386         measured_string_t *configuration;
    387         size_t count = sizeof(names) / sizeof(measured_string_t);
    388         uint8_t *data;
    389        
    390         fibril_rwlock_initialize(&udp_globals.lock);
    391         fibril_rwlock_write_lock(&udp_globals.lock);
    392        
    393         udp_globals.net_phone = net_phone;
    394        
    395         udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
    396             ICMP_CONNECT_TIMEOUT);
    397        
    398         udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
    399             SERVICE_UDP, udp_receiver);
    400         if (udp_globals.ip_phone < 0) {
    401                 fibril_rwlock_write_unlock(&udp_globals.lock);
    402                 return udp_globals.ip_phone;
    403         }
    404        
    405         /* Read default packet dimensions */
    406         int rc = ip_packet_size_req(udp_globals.ip_phone, -1,
    407             &udp_globals.packet_dimension);
    408         if (rc != EOK) {
    409                 fibril_rwlock_write_unlock(&udp_globals.lock);
    410                 return rc;
    411         }
    412        
    413         rc = socket_ports_initialize(&udp_globals.sockets);
    414         if (rc != EOK) {
    415                 fibril_rwlock_write_unlock(&udp_globals.lock);
    416                 return rc;
    417         }
    418        
    419         rc = packet_dimensions_initialize(&udp_globals.dimensions);
    420         if (rc != EOK) {
    421                 socket_ports_destroy(&udp_globals.sockets);
    422                 fibril_rwlock_write_unlock(&udp_globals.lock);
    423                 return rc;
    424         }
    425        
    426         udp_globals.packet_dimension.prefix += sizeof(udp_header_t);
    427         udp_globals.packet_dimension.content -= sizeof(udp_header_t);
    428         udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
    429 
    430         udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    431         udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
    432 
    433         /* Get configuration */
    434         configuration = &names[0];
    435         rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
    436             &data);
    437         if (rc != EOK) {
    438                 socket_ports_destroy(&udp_globals.sockets);
    439                 fibril_rwlock_write_unlock(&udp_globals.lock);
    440                 return rc;
    441         }
    442        
    443         if (configuration) {
    444                 if (configuration[0].value)
    445                         udp_globals.checksum_computing =
    446                             (configuration[0].value[0] == 'y');
    447                
    448                 if (configuration[1].value)
    449                         udp_globals.autobinding =
    450                             (configuration[1].value[0] == 'y');
    451 
    452                 net_free_settings(configuration, data);
    453         }
    454 
    455         fibril_rwlock_write_unlock(&udp_globals.lock);
    456         return EOK;
    457 }
    458 
    459428/** Sends data from the socket to the remote address.
    460429 *
     
    891860 * @see IS_NET_UDP_MESSAGE()
    892861 */
    893 int tl_module_message(ipc_callid_t callid, ipc_call_t *call,
     862int udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
    894863    ipc_call_t *answer, size_t *answer_count)
    895864{
     865        packet_t *packet;
     866        int rc;
     867
    896868        *answer_count = 0;
    897869
    898870        switch (IPC_GET_IMETHOD(*call)) {
     871        case NET_TL_RECEIVED:
     872                rc = packet_translate_remote(udp_globals.net_phone, &packet,
     873                    IPC_GET_PACKET(*call));
     874                if (rc != EOK)
     875                        return rc;
     876                return udp_received_msg(IPC_GET_DEVICE(*call), packet,
     877                    SERVICE_UDP, IPC_GET_ERROR(*call));
    899878        case IPC_M_CONNECT_TO_ME:
    900879                return udp_process_client_messages(callid, *call);
     
    904883}
    905884
     885/** Default thread for new connections.
     886 *
     887 * @param[in] iid       The initial message identifier.
     888 * @param[in] icall     The initial message call structure.
     889 */
     890static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
     891{
     892        /*
     893         * Accept the connection
     894         *  - Answer the first IPC_M_CONNECT_ME_TO call.
     895         */
     896        ipc_answer_0(iid, EOK);
     897       
     898        while (true) {
     899                ipc_call_t answer;
     900                size_t answer_count;
     901               
     902                /* Clear the answer structure */
     903                refresh_answer(&answer, &answer_count);
     904               
     905                /* Fetch the next message */
     906                ipc_call_t call;
     907                ipc_callid_t callid = async_get_call(&call);
     908               
     909                /* Process the message */
     910                int res = tl_module_message_standalone(callid, &call, &answer,
     911                    &answer_count);
     912               
     913                /*
     914                 * End if told to either by the message or the processing
     915                 * result.
     916                 */
     917                if ((IPC_GET_IMETHOD(call) == IPC_M_PHONE_HUNGUP) ||
     918                    (res == EHANGUP))
     919                        return;
     920               
     921                /* Answer the message */
     922                answer_call(callid, res, &answer, answer_count);
     923        }
     924}
     925
     926/** Starts the module.
     927 *
     928 * @return              EOK on success.
     929 * @return              Other error codes as defined for each specific module
     930 *                      start function.
     931 */
    906932int main(int argc, char *argv[])
    907933{
     934        int rc;
     935       
    908936        /* Start the module */
    909         return tl_module_start(SERVICE_UDP);
     937        rc = tl_module_start_standalone(tl_client_connection);
     938        return rc;
    910939}
    911940
Note: See TracChangeset for help on using the changeset viewer.