
#define WIN32_LEAN_AND_MEAN

#include <windows.h>       /* required for all Windows applications */
#include <winsock.h>
#include <stdio.h>         /* for sprintf                           */
#include <string.h>        /* for strlen                            */

//#include        "dapdldef.h"
#define     DEF_MSS          16384
#define     NULL_ARG         (char far *)0
#define    _OK                0
#define    _ERR               1
#define    _PENDING           2
#define    _YES               0
#define    _NO                1
#define    _EXIT_ERR_1        1
#define    _EXIT_ERR_2        2
#define    _EXIT_ERR_3        3
#define    _EXIT_ERR_4        4
#define    _EXIT_ERR_5        5
#define    _EXIT_ERR_6        6
#define    _EXIT_ERR_7        7
#define    _EXIT_ERR_8        8
#define    _EXIT_ERR_9        9
#define    _EXIT_ERR_10       10
#define    _EXIT_ERR_11       11
#define    _EXIT_ERR_12       12
//---------------------------------------------------------------------------

#define NO_FLAGS_SET         0  /* Used with recv()/send()          */

DWORD WINAPI Thread1(LPVOID) ;

//---------------------------------------------------------------------------
long GetIPaddr( char *) ;
//---------------------------------------------------------------------------

int handle;
int connect_f = _ERR ;
int send_f = _ERR ;
int recv_f = _ERR ;
int recv_len = 0 ;
int err_code = _EXIT_ERR_1 ;
unsigned char   recvbuf[DEF_MSS];
unsigned char   sendbuf[DEF_MSS];

extern int wsk_ini() ;             /* ret=0: ok, else: err */
extern int wsk_connect( unsigned short local_port, char *remote_ip, unsigned short remote_port);
extern int wsk_disconnect( int handle) ;
extern int HexProcess() ;
extern int SendEndCmd() ;

//---------------------------------------------------------------------------
main( argc, argv )
int argc;
char *argv[];
{
    int     i, ret, len ;
    long    local_ip, remote_ip ;
    u_short remote_port, loop_cnt ;
    char    buf[512] ;
    char    msg[512] ;
    HANDLE  hThrd ;
    DWORD   threadid ;

    printf( "TCP Test Program 2\n" ) ;
    if ( argc <= 2 ) {
        printf ( "Usage  : TCPTEST IP_Address Port\n" ) ;
        printf ( "Example: TCPTEST 202.39.254.100 4660\n" ) ;
        printf ( "\n'*S1' for send data to DAP port 1\n") ;
        err_code = _EXIT_ERR_2 ;
        exit(err_code) ;
    }

    strcpy( buf, argv[1]) ;
    remote_port = atoi( argv[2]) ;
    printf( "Connecting to %s, Port=%ld\n", buf, remote_port) ;

    remote_ip = GetIPaddr( buf ) ;
    printf (" (%lx)\n", remote_ip ) ;

    connect_f = _PENDING ;

    if (wsk_ini()) {
        err_code = _EXIT_ERR_3 ;
        exit(err_code);
    }

    printf( "Wait to Connect ...\n") ;
    handle = wsk_connect( 0, buf, remote_port) ;
    if ( handle<0) {
        err_code = _EXIT_ERR_3 ;
        exit(err_code);
    }
    connect_f = _OK ;
    printf( "Connect OK ...\n") ;

    hThrd = CreateThread( NULL, 0, Thread1, (LPVOID)55, 0, &threadid) ;

    for ( ;;) {
        if ( connect_f == _ERR ) {
            wsk_disconnect(handle);
            err_code = _EXIT_ERR_4 ;
//          exit( err_code ) ;
            break ;
        }

        gets( buf) ;
        if ( buf[0]=='=') break ;

        len = strlen( buf) ;
        if ( buf[0]=='*' && len>3) {
            switch(buf[1]) {
            case 'S':
            case 's':
                len = 6 + HexIp( &buf[3], len-3, &msg[6]) ;
                msg[0] = len ;
                msg[1] = 0 ;
                switch(buf[2]) {
                case '0': msg[2] = 0x40 ; break ;
                case '2': msg[2] = 0x61 ; break ;
                default:  msg[2] = 0x60 ;
                }
                msg[3] = 0 ;
                msg[4] = 0 ;
                msg[5] = 0 ;
                break ;

            default:
                len = HexIp( buf, len, msg) ;
            }
        }
        else {
            len = HexIp( buf, len, msg) ;
        }

        ret = send( handle, (unsigned char *)msg, len, NO_FLAGS_SET );
        if (ret != len) {
            printf( "send error, loop=%d, len=%d, ret=%d\n", i, len, ret) ;
            connect_f=_ERR;
            break ;
        }
    }

    wsk_disconnect(handle);
}

DWORD WINAPI Thread1(LPVOID data)
{
    int     ret ;

    for (;;) {
//      printf( "data=%d\n", data) ;
        ret = recv( handle ,(unsigned char far *)recvbuf, sizeof(recvbuf),
                                                            NO_FLAGS_SET );
        if (ret <= 0) {
            printf( "receive error, ret=%d\n", ret) ;
            connect_f=_ERR;
//          return(_ERR);
        }
        else {
//          recvbuf[ret] = '\0' ;
            printf( "receive ok, count=%d, data=\n", ret) ;
            ldumps( recvbuf, ret) ;
        }
    }
}

//---------------------------------------------------------------------------
long GetIPaddr( buf )
char    *buf ;
{
    long    ip_l, ip_h ;
    int     i, len ;

    len = strlen( buf) ;
    for ( i = 0 ; i < len ; i ++ ) if ( buf[i] == '.' ) buf[i] = 0 ;
    ip_l =(long)atoi(buf) & 0xff ;
    len = strlen( buf) + 1 ;
    ip_l += (long)((atoi(&buf[len])&0xff) << 8 ) ;
    len += strlen( &buf[len] ) + 1 ;
    ip_h =(long)atoi(&buf[len]) & 0xff ;
    len += strlen( &buf[len] ) + 1 ;
    ip_h += (long)((atoi(&buf[len])&0xff) << 8 ) ;
    return ( (ip_h << 16) + ip_l ) ;
}

int wsk_ini() {             /* ret=0: ok, else: err */
    int status;             /* Status Code */
    WSADATA WSAData;
    char szTemp[80];

    if ((status = WSAStartup(MAKEWORD(1,1), &WSAData)) == 0) {
//     printf( "%s,%s\n", WSAData.szDescription, WSAData.szSystemStatus);
    }
    else {
       sprintf(szTemp, "%d is the err", status);
       printf( "%s, %s\n", szTemp, "Error");
    }
    return( status) ;
}

int wsk_connect( u_short local_port, char *remote_ip, u_short remote_port)
{
    int     sock ;
    int     portno ;
    SOCKADDR_IN dest_sin;  /* DESTination Socket INternet */

    sock = socket( AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
        printf( "socket() failed\n");
        return( -1) ;
    }

    if (local_port) {
        dest_sin.sin_family = AF_INET;
        dest_sin.sin_addr.s_addr = 0 ;
        dest_sin.sin_port = htons(local_port);  /* Convert to network ordering */
        if ( bind( sock, (PSOCKADDR)&dest_sin, sizeof( dest_sin)) != 0) {
            printf( "bind error\n") ;
            return( -1) ;
        }
    }

    memset( (char *)&dest_sin, 0, sizeof(dest_sin)) ;
    dest_sin.sin_family = AF_INET;
    dest_sin.sin_addr.s_addr = GetIPaddr( remote_ip ) ;
    dest_sin.sin_port = htons(remote_port);  /* Convert to network ordering */

//  printf( "before connect\n") ;
//  getch() ;
//  printf( "wait to connect ...\n");
    if (connect( sock, (PSOCKADDR) &dest_sin, sizeof( dest_sin)) < 0) {
        closesocket( sock );
        printf( "connect() failed\n");
        return( -1) ;
    }
//  printf( "connect() ok!\n");
//  getch() ;
    return( sock) ;
}

int wsk_disconnect( int handle)
{
    closesocket( handle);
}

