// Socket.cpp
//

#include <stdafx.h>
#include "ModeSet.h"

#define connectPort	1283

SOCKET      tcpSocket = 0;
SLPACKET    *pkt = NULL;

BOOL sendPacket( char *pkt, size_t size )
  {
    int length = 0;
    size_t sent   = 0;
    int tosend;

    while( size  !=  sent )
      {
	tosend	= size - sent;
	length	= send( tcpSocket, (const char *)(pkt + sent), tosend, 0 );
	if( length  <  0 )
	  {
	    printf( "\nError sending..\n");
	    return FALSE;
	  }
	sent += length;
      }
	    return TRUE;
  }


BOOL SendPacket( SLPACKET *pkt, char *ModeName )
{
    int	total  = 0;
    int length = 0;
    int sent   = 0;

    memset( pkt,0,BUFFER_SIZE);

    total = sizeof( pkt->header ) + strlen( ModeName ) + 1;
    pkt->header.token = SLT_MODESETQUERY;
    pkt->header.length = htonl( total);

    if( *ModeName )
	strcpy( pkt->body.modesetquery.modesetquery, ModeName );

    while( total != sent)
    {
	    length = send( tcpSocket, (const char *)(pkt + sent), total-sent,0);

        if( length < 0)
	        return FALSE;
       
        sent += length;
    }

    return TRUE;
}


BOOL RecvPacket( SLPACKET *pkt )
{
    int	    length=0,total=0;
    char    *p;
    char    msgBuffer[5];
    int     NOP = TRUE;

    while( NOP )
    {
        NOP = FALSE;
        length = recv( tcpSocket, (char *)pkt, 4, 0);
        total = ntohl( pkt->header.length) - sizeof pkt->header.length;
        p = (char *)&pkt->header.token;
    
        while ( total > 0)
        {
	    length = recv( tcpSocket, p, total, 0);
	    if ( length  <=  0 )
	        continue;
	    total	-= length;
	    p += length;
        }
    
        memmove( msgBuffer, &(pkt->header.token), 4);
        msgBuffer[4]=0;

        if( (pkt->header.token == SLT_DATA) && (pkt->body.data.type == SLD_NOP) )
            NOP = TRUE;
    }


    if( pkt->header.token == SLT_ERRREPORT )
        return FALSE;
    else
        return TRUE;
}

short connectUnit( LPCTSTR IPAddress )
{

    int		status=0;
    // int		gotHost	= FALSE;

    struct hostent     *phe;
    struct sockaddr_in  remote_sin;
    fd_set write_mask;
    struct timeval wait;
    int    nRet;
    int    nonBlocking = 1;
    int    Blocking = 0;

    WSADATA	WSAData;

    if( tcpSocket == 0 )
    {
        status  = WSAStartup( MAKEWORD( 2,0 ), &WSAData );
    
        if ( status )	    return 0;
    }
    

    //  Create socket 
    tcpSocket	= socket( AF_INET, SOCK_STREAM, 0 );
    
    if( tcpSocket == -1 )
        return 0;

    // Create the write_mask for select, 
    // BJ, I tried to create the write_mask just before the select statement, 
    // but it did not seem to work.

    FD_ZERO( &write_mask );
    FD_SET( tcpSocket, &write_mask );


#ifdef REQD
    //  Set Socket Options

    status  = setsockopt( tcpSocket, IPPROTO_TCP,TCP_NODELAY,
    		  (char *)&opt, optlen );
    if ( status == -1 )
        return 0;

    opt	    = 4096;
    status  = setsockopt( tcpSocket, SOL_SOCKET, SO_SNDBUF, (char *)&opt,optlen);

    if ( status == -1)
        return 0;

#endif

    phe	= gethostbyname( IPAddress );

    if ( !phe )
    {
	    closesocket( tcpSocket );
        return 0;
    }
        
    memcpy((void *)&(remote_sin.sin_addr), phe->h_addr, phe->h_length );

    // talk to user provided port value 

    remote_sin.sin_port	    = htons( connectPort );
    remote_sin.sin_family =  AF_INET;

    nRet = ioctlsocket(tcpSocket, FIONBIO, (u_long *) &nonBlocking);

    if( nRet == SOCKET_ERROR)
    {
 	        closesocket( tcpSocket );
	        return 0;                                       
    }


    // connect 
    status  = connect( tcpSocket, 
                       (struct sockaddr *)&remote_sin,
	                   sizeof remote_sin );

    nRet = 0;

    wait.tv_sec = 0;                    // connect Timeout
    wait.tv_usec = 500000;

    nRet = select( 0, NULL, &write_mask, NULL, &wait );
    if ( nRet  ==  SOCKET_ERROR || nRet == 0)
    {
	        closesocket( tcpSocket );
	        return 0;                                       
    }


    nRet = ioctlsocket(tcpSocket, FIONBIO, (u_long *) &Blocking);

    if ( !pkt )
        pkt	= ( SLPACKET* ) new char[ BUFFER_SIZE ];

    return TRUE;
}



BOOL disconnectUnit( void )
{
    if( tcpSocket )
        closesocket( tcpSocket );

    if( pkt )
    {
        delete( pkt );
        pkt = NULL;
    }
    return TRUE;
}



