Subversion Repositories HelenOS

Rev

Rev 3666 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

/*
 * Copyright (c) 2008 Lukas Mejdrech
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** @addtogroup net
 * @{
 */

/** @file
 */

#include <async.h>
#include <errno.h>
#include <stdio.h>
#include <task.h>
#include <ipc/ipc.h>
#include <ipc/services.h>
//#include <sys/mman.h>

#include "../modules.h"
#include "../messages.h"

#ifdef NETWORKING_module

    #include "../ip/ip.h"
    #include "../tcp/tcp.h"

#endif

#define IS_IN_INTERVAL( item, first_inclusive, last_exclusive ) ((( item ) >= ( first_inclusive )) && (( item ) < ( last_exclusive )))

#define IS_NET_MESSAGE( call )          IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_FIRST, NET_LAST )
#define IS_NET_NETWORKING_MESSAGE( call )   IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_NETWORKING_FIRST, NET_NETWORKING_LAST )
#define IS_NET_IP_MESSAGE( call )       IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_IP_FIRST, NET_IP_LAST )
#define IS_NET_ARP_MESSAGE( call )      IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_ARP_FIRST, NET_ARP_LAST )
#define IS_NET_RARP_MESSAGE( call )     IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_RARP_FIRST, NET_RARP_LAST )
#define IS_NET_UDP_MESSAGE( call )      IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_UDP_FIRST, NET_UDP_LAST )
#define IS_NET_TCP_MESSAGE( call )      IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_TCP_FIRST, NET_TCP_LAST )
#define IS_NET_SOCKET_MESSAGE( call )       IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_SOCKET_FIRST, NET_SOCKET_LAST )
#define IS_NET_ETHERNET_MESSAGE( call )     IS_IN_INTERVAL( IPC_GET_METHOD( call ), NET_ETHERNET_FIRST, NET_SOCKET_LAST )

int networking_initialize( void );
static void client_connection( ipc_callid_t iid, ipc_call_t * icall );
int main( int argc, char * argv[] );
int spawn( const char * fname );
int networking_call( ipc_callid_t callid );
int networking_message( ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3 );

int networking_call( ipc_callid_t callid ){
    return EOK;
}

int networking_message( ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3 ){
    switch( method ){
        case IPC_M_PHONE_HUNGUP:
            return EOK;
    }
    return ENOTSUP;
}

int spawn(const char *fname)
{
    const char *argv[2];
    int res;

    printf("Spawning %s\n", fname);

    argv[0] = fname;
    argv[1] = NULL;

    res = task_spawn(fname, argv);
    if( res != 0 ){
        /* Success */
        sleep(1);
    }else return EINVAL;

    return EOK;
}

/** Initializes the module.
 */
int networking_initialize( void ){
    ERROR_DECLARE;

#ifdef NETWORKING_modular
    ERROR_PROPAGATE( spawn("/sbin/ip"));
//  ERROR_PROPAGATE( spawn("/sbin/arp"));
//  ERROR_PROPAGATE( spawn("/sbin/rarp"));
//  ERROR_PROPAGATE( spawn("/sbin/icmp"));
//  ERROR_PROPAGATE( spawn("/sbin/udp"));
    ERROR_PROPAGATE( spawn("/sbin/tcp"));
//  ERROR_PROPAGATE( spawn("/sbin/socket"));
#else
#ifdef NETWORKING_module
    ipcarg_t phonehash;

    ERROR_PROPAGATE( REGISTER_ME( SERVICE_IP, & phonehash ));
    ERROR_PROPAGATE( ip_initialize());
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ARP, & phonehash ));
//  ERROR_PROPAGATE( arp_initialize());
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_RARP, & phonehash ));
//  ERROR_PROPAGATE( rarp_initialize());
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ICMP, & phonehash ));
//  ERROR_PROPAGATE( icmp_initialize());
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_UDP, & phonehash ));
//  ERROR_PROPAGATE( udp_initialize());
    ERROR_PROPAGATE( REGISTER_ME( SERVICE_TCP, & phonehash ));
    ERROR_PROPAGATE( tcp_initialize());
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_SOCKET, & phonehash ));
//  ERROR_PROPAGATE( socket_initialize());
//  ERROR_PROPAGATE( REGISTER_ME( SERVICE_ETHERNET, & phonehash ));
//  ERROR_PROPAGATE( ethernet_initialize());
#endif
#endif
    return EOK;
}

/** Default thread for new connections.
 */
static void client_connection( ipc_callid_t iid, ipc_call_t * icall ){
    ipc_callid_t callid;
    ipc_call_t call;
    ipcarg_t arg1, arg2, arg3;
    int res;

    /* Accept the connection */
    ipc_answer_0( iid, EOK );

    while( true ){
        callid = async_get_call( & call );
        arg1 = 0;
        arg2 = 0;
        arg3 = 0;
#ifdef NETWORKING_module
        if( IS_NET_IP_MESSAGE( call )){
            res = ip_call( callid );
            if( res == EOK ){
                res = ip_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
/*      }else if( IS_NET_ARP_MESSAGE( call )){
            res = arp_call( callid );
            if( res == EOK ){
                res = arp_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
*//*        }else if( IS_NET_RARP_MESSAGE( call )){
            res = rarp_call( callid );
            if( res == EOK ){
                res = rarp_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
*//*        }else if( IS_NET_ICMP_MESSAGE( call )){
            res = icmp_call( callid );
            if( res == EOK ){
                res = icmp_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
*//*        }else if( IS_NET_UDP_MESSAGE( call )){
            res = udp_call( callid );
            if( res == EOK ){
                res = udp_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
*/      }else if( IS_NET_TCP_MESSAGE( call )){
            res = tcp_call( callid );
            if( res == EOK ){
                res = tcp_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
/*      }else if( IS_NET_SOCKET_MESSAGE( call )){
            res = socket_call( callid );
            if( res == EOK ){
                res = socket_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
*//*        }else if( IS_NET_ETHERNET_MESSAGE( call )){
            res = ethernet_call( callid );
            if( res == EOK ){
                res = ethernet_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
*/      }else{
#endif
            res = networking_call( callid );
            if( res == EOK ){
                res = networking_message( IPC_GET_METHOD( call ), IPC_GET_ARG1( call ), IPC_GET_ARG2( call ), IPC_GET_ARG3( call ), & arg1, & arg2, & arg3 );
            }
#ifdef NETWORKING_module
        }
#endif
        ipc_answer_2( callid, EOK, arg1, arg2 );
    }
}

/** Starts the module.
 *  Parameters are ignored.
 */
int main( int argc, char * argv[] ){

    printf("networking : HelenOS Networking subsystem\n");

    return start_service( SERVICE_NETWORKING, NULL, NULL, client_connection, networking_initialize );
}

/** @}
 */