/***************************************************************************
 *   Copyright (C) 2007 by Daniel Baptista                                 *
 ***************************************************************************/
#include "SerialPort.h"

static int h=0; 

int SerialPort::initcom(void)
{
	struct termios ComParams, newParams;
	int ret;
	char *device = COM_DEVICE;
	bzero( &newParams, sizeof(newParams)); //seting all structure values to zero

	h = open( device, O_RDWR );//|  O_NOCTTY    //*| O_NDELAY  O_NONBLOCK |  /*O_NONBLOCK*/
	cout << h << endl;
	if(h <= 0 )
	{
		perror("open:");
		cout << "Failed on opening COM. Error nr. " << errno << " " << strerror(errno) <<"\n" << endl;
		return (-1);
	}
	ret=tcgetattr(h, &ComParams); // get serial communuication parameters
	
	if( ret < 0 ) 
		cout << "tcgetattr failed\n:" << endl;

	/*
	* Configuracao das c_flags
	*
	* B19200       : Baudrate
	* CS8          : 8 data bits
	* CLOCAL       : ligacao local, ignorar linhas de controlo
	*              : do modem
	* CREAD        : autorizar recepcao de caracteres
	* sem CRTSCTS  : sem controlo por hardware
	* B115200	:baud rate
	*/
	newParams.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
	
	/* Configuracao das c_iflags: 
   	* IGNPAR    : ignorar erros de paridade;
   	* ICRNL     : transforma "carriage return" em "newline" à entrada.
   	*/
        newParams.c_iflag = IGNPAR;
        
	/* Configuracao das c_oflags */
	newParams.c_oflag = 0;		//ONLCR;
	
	/* Configuracao das c_lflags */
	newParams.c_lflag = 0;
  	
	/* Configuracao do timeout entre caracteres recebidos */
  	newParams.c_cc[VTIME] = 0;	/* timeout em 1/10s */
  	newParams.c_cc[VMIN] = 1;	/* Espera pelos caracteres de recepcao */

	/*
   	* Limpar a linha série antes de activar a nova configuracao
   	*/
	tcflush(h, TCIFLUSH);
	ret=tcsetattr( h, TCSANOW, &newParams ); // set serial communuication parameters
	if( ret < 0 ) 
		cout << "tcsetattr failed:\n" << endl;
	
	return h;
}

int SerialPort::resetcom()
{
	int i,j;

	// Espera um pouco
	for (i=0;i<500;i++)
	{
		for(j=0;j<500;j++);
	}

	// Limpa a porta serie
	if((tcflush(h, TCIFLUSH)) < 0)
	{
		cout << "RESETCOM: Error on flush port\n" << endl;
		return -1;
	}
	return 1;
}


int SerialPort::killcom()
{
	if(h <= 0)
	{
		cout << "KILLCOM: port is not open \n" << endl;
		return -1;		
	}
	else
	{
		close(h);
		return 1; 
	}
}	

int SerialPort::writecom(unsigned char msg)
{
	signed int w;	

	if (h <= 0)
	{
		cout << "WRITECOM: port is not open \n" << endl;
		return -1;
	}

	if ((w=write(h, &msg, sizeof(char))) < 0)
	{
		cout <<"WRITECOM: write port error nr." << errno <<" "<< strerror(errno)<< "\n" << endl;
	}
	
	return 1;
}


int SerialPort::readcom(unsigned char *msg)
{
	signed int r;
	
	if (h <= 0)
	{
		cout << "READCOM: port is not open\n" << endl;
		return -1;
	}

	r = read(h, msg, sizeof(char));
	if (r < 0)
	{
		if (errno == EAGAIN)
    		{
			cout << "READCOM: Nao ha resposta da porta\n" << endl;
			return -1; // assume that command generated no response
		}
		else
		{
			cout << "READCOM: read error nr." << errno <<" "<< strerror(errno) << "\n" << endl;
			return -1;
		} 
	}

    return 1;
}

