// Netwatch - watch a protocol in action
//   acts as an intermediary between two programs
//   eg.  TELNET -> netwatch -> TELNETD  to see the TELNET protocol in action
//
// NETWATCH  destserver  portnum
// eg. NETWATCH sunserv  25   (25 is SMTP)
// then telnet to your eRTOS machine to watch the protocol
// Copies output to DUMP.DAT in current directory

#include <stdio.h>
#include <tcp.h>
#include <rtos.h>
#include <stdlib.h>

void dumpdata( char *msg, char *data, int len )
{
    FILE *f;
    int i;

    f = fopen( "dump.dat", "a+t" );
    cprintf( "%s %c", msg, (data != NULL) ? ':' : ' ');
    if ( f != NULL )
        fprintf( f, "%s %c" , msg, (data != NULL ) ? ':' : ' ');
    for ( i = 0 ; i < len ; ++i ) {
        cprintf("%c",data[i] );
        if ( data != NULL )
            fprintf(f,"%c", data[i] );
    }
    cprintf("\r\n");
    if (data != NULL ) {
        fprintf(f,"\n");
        fclose( f );
    }
}

int main( int argc, char **argv )
{
    char *server;
    DWORD serv;
    int port;
    int active = 0;
    tcp_Socket *s, *t;
    int closed;
    int i,j;
    char buf[ 128 ];

    kdebug = 1;
    rt_init(100);
    sock_init();            /* initialize network */

    // process arguments
    if ( argc < 3 )
        rt_halt("NETWATCH  server   protocol");

    server = argv[1];
    serv = resolve( server );
    if ( serv == 0 )
        rt_halt("could not resolve server");

    port = atoi( argv[2] );

    s = kcalloc( sizeof( tcp_Socket ), 1 );
    t = kcalloc( sizeof( tcp_Socket ), 1 );

    // ready for action

    do {
        if ( active ) {
            cprintf("Freeing session ...\r\n");
            sock_abort( s );
            sock_abort( t );
        }


        cprintf("Listenning on port %u and relaying to %s\r\n", port, server);

        // start listenning
        active = 0;
        tcp_listen( s, port, 0L, 0, NULL, 0 );

        while ( !sock_established( s )) {
            rt_yield();
            tcp_tick( s );
        }

        // got something
        active = 1;
        cprintf("client connection arrived");

        if ( ! tcp_open( t, 0, serv, port, NULL ) ) {
            cprintf("unable to connect to server");
            continue;
        }
        while ( !sock_established( t )) {
            tcp_tick( NULL );
            rt_yield();
        }

        cprintf("connected to server: %s\r\n", server );

        // process all the data from either side
        closed = 0;
        do {
            rt_yield();     // so we can break out

            // look for closures
            if ( !tcp_tick( s )) {
                if (( closed & 1 ) == 0 ) {
                    cprintf("client broke connection\r\n");
                    closed |= 1;
                    sock_close( t );
                }
            }
            if ( !tcp_tick( t )) {
                if (( closed & 2 ) == 0 ) {
                    cprintf("server broke connection\r\n");
                    closed |= 2;
                    sock_close( s );
                }
            }
            // have both parties quit?
            if ( closed == 3 ) break;

            if ( sock_dataready( s )) {
                i = sock_fastread( s, buf, sizeof( buf ));
                dumpdata("client ", buf, i );
                sock_write( t, buf, i );
            }

            if ( sock_dataready( t )) {
                i = sock_fastread( t, buf, sizeof( buf ));
                dumpdata("server ", buf, i );
                sock_write( s, buf, i );
            }
        } while ( 1 );
    } while ( 1 );
}


