package CComms;
use strict;
use Inline CPP => <<'END'

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <assert.h>

#define 	true		0
#define 	false		1

class CComms
{
 private:
        int 		fp;
        char 	        *fPort;
        int 		fReturn;
        char		inbuff  [ 1024 ];
        char		outbuff [ 1024 ];
        int             BAUD;

 protected:
        struct 	termios	oldtio;
        struct	termios	newtio;

 public:
                        CComms  ( char *cp );
                        ~CComms ();
        bool		Open    ( int speed );
        void		Close   ( void );
        char 		*gets   ( void );
        bool		puts    ( char *data );
        char            getchar ( void );
        bool            putchar ( char ch );
};

CComms::CComms( char *cp )
{
    BAUD = B9600;
    fPort = cp;
}

CComms::~CComms()
{
}

bool CComms::Open ( int speed )
{
    switch ( speed )
    {
        case 2400:  BAUD = B2400;  break;
        case 4800:  BAUD = B4800;  break;
        case 9600:  BAUD = B9600;  break;
        case 19200: BAUD = B19200; break;
        case 38400: BAUD = B38400; break;
    }

    fp = open ((char *)fPort, O_RDWR ); //| O_NOCTTY | O_NONBLOCK );
    if ( fp < 0 )
    {
        return false;
    }
    
    tcgetattr ( fp, &oldtio );
    bzero ( &newtio, sizeof ( newtio ));
    
    newtio.c_cflag = BAUD | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR | IGNCR | IGNBRK;
    newtio.c_oflag = 0;
    newtio.c_lflag = 0;
    newtio.c_cc [ VTIME ] = 0;
    newtio.c_cc [ VMIN  ] = 1;
    tcflush ( fp, TCIFLUSH );
    tcsetattr ( fp, TCSANOW, &newtio );
    return ( true );
}

void CComms::Close ( void )
{
    close ( fp );
    tcsetattr ( fp, TCSANOW, &oldtio );
}

char *CComms::gets ( void )
{
    bzero ( inbuff, 1024 );
    fReturn = read ( fp, inbuff, 255 );
    if ( fReturn > 0 )
    {
        return inbuff;
    }
    else
    {
        return 0;
    }
}

bool CComms::puts ( char *data )
{
    if ( write ( fp, data, strlen ( data )) <= 0 )
    {
        return false;
    }
    return true;
}

char CComms::getchar ( void )
{
    bzero ( inbuff, 1024 );
    fReturn = read ( fp, inbuff, 1 );
    if ( fReturn > 0 )
    {
        return inbuff[0];
    }
    else
    {
        return false;
    }
}

bool CComms::putchar ( char ch )
{
    char data[1];
    data[0] = ch;
    if ( write ( fp, data, 1 ) <= 0 )
    {
        return false;
    }
    return true;
}

END
;

sub new {
  my $class = shift;
  my $self = bless {}, $class;
  return $self;
}

1;
