/*******************************************
 *   Copyright (C) 2008 by Mauro Rodrigues *
 *******************************************/
#include <string>

#include "rs232.h"
#include "SerialPort.h"

static int h=0;

int SerialPort::initcom(void)
{
	struct termios ComParams, newParams;
	int ret;
	char *device = COM_DEVICE, temp[50];
	bzero( &newParams, sizeof(newParams)); //seting all structure values to zero
	if(createRSlog() == -1)
		cout << "INITCOM: Could not create log file for Serial Comm.\n";

	rslog("INITCOM: Opening rs232 Comm port.\n");
	h = open( device, O_RDWR );//|  O_NOCTTY    //*| O_NDELAY  O_NONBLOCK |  /*O_NONBLOCK*/
	cout << h << endl;
	if(h <= 0 )
	{
		perror("open:");
		sprintf(temp, "INITCOM: Failed on opening COM. Error nr. %d %s\n", errno, strerror(errno));
		rslog(temp);
		return (-1);
	}
	ret=tcgetattr(h, &ComParams); // get serial communication parameters
	
	if( ret < 0 ) 
		rslog("INITCOM: tcgetattr failed while retrieving serial communications parameters\n:");

	/*
	* 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 ) 
		rslog("INITCOM: tcsetattr failed while setting serial communication parameters\n");

	rslog("rs232 Comm port successfuly opened!\n");
	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){
		rslog("RESETCOM: Error while flushing port\n");
		return -1;
	}

	rslog("RESETCOM: Comm port reset successful!\n");
	return 1;
}


int SerialPort::killcom()
{
	if(h <= 0){
		rslog("KILLCOM: port is not open \n");
		return -1;		
	}
	else{
		close(h);
		rslog("KILLCOM: Comm port close!\n");
		return 1; 
	}
	if(closeRSlog() == -1)
		cout << "KILLCOM: Unable to safely close log file!\n";
}	

int SerialPort::writecom(unsigned char msg)
{
	signed int w;	
	char temp[50];

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

	if ((w=write(h, &msg, sizeof(char))) < 0){
		sprintf(temp, "WRITECOM: write port error nr.%d %s\n", errno, strerror(errno));
		rslog(temp);
	}
	
	return 1;
}


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

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

