#include "StdAfx.h"
#include "_error.h"
#include "puerto_com.h"
//************************************************************************************************************
Cpuerto_com::Cpuerto_com(C_error *err/*=NULL*/  )
{
	if (err)
	{
		borra_error=FALSE;
		er=err;
	}
	else
	{
		borra_error=TRUE;
		er=new C_error();
	}
	hport=INVALID_HANDLE_VALUE;
}
//************************************************************************************************************
Cpuerto_com::~Cpuerto_com(void)
{
	if (er&&borra_error)
		delete er;
}
//************************************************************************************************************
BOOL Cpuerto_com::inicia( Puerto_com_conf* conf )
{
	DCB		m_dcb;
	COMMTIMEOUTS m_CommTimeouts;
	//creamos-------------------------------------------
	hport=CreateFile(conf->com, 
		GENERIC_READ | GENERIC_WRITE,
		0, // exclusive access
		NULL, // no security
		OPEN_EXISTING,
		0, // no overlapped I/O
		NULL); // null template

	if (hport == INVALID_HANDLE_VALUE)
	{
		er->pon_win(MODULO_CPUERTO_COM);
		return FALSE;
	}
	//configuramos sizes-------------------------------
	if(!SetupComm(hport, 128, 128))
	{
		er->pon_win(MODULO_CPUERTO_COM);
		goto salir;
	}
	//configuramos-------------------------------------
	if(!GetCommState(hport, &m_dcb))
	{
		er->pon_win(MODULO_CPUERTO_COM);
		goto salir;
	}
	m_dcb.BaudRate = conf->baud;
	m_dcb.ByteSize = conf->nb; 
	m_dcb.Parity = conf->paridad;
	m_dcb.StopBits = conf->b_parada; 
/*	m_dcb.fRtsControl*/
	if(!SetCommState(hport, &m_dcb))
	{
		er->pon_win(MODULO_CPUERTO_COM);
		goto salir;
	}
	//configuracion de timeours------------------------
	if(!GetCommTimeouts(hport, &m_CommTimeouts))
	{
		er->pon_win(MODULO_CPUERTO_COM);
		goto salir;
	}
	//valores por defecto------------------------------
	m_CommTimeouts.ReadIntervalTimeout = 50;
	m_CommTimeouts.ReadTotalTimeoutConstant = 50;
	m_CommTimeouts.ReadTotalTimeoutMultiplier = 10;
	m_CommTimeouts.WriteTotalTimeoutConstant = 50;
	m_CommTimeouts.WriteTotalTimeoutMultiplier = 10;
	if(!SetCommTimeouts(hport, &m_CommTimeouts))
	{
		er->pon_win(MODULO_CPUERTO_COM);
		goto salir;
	}
	return TRUE;

salir:
	termina();
	return FALSE;
}
//************************************************************************************************************
void Cpuerto_com::termina()
{
	if (hport!=INVALID_HANDLE_VALUE)
		CloseHandle(hport);
	hport=INVALID_HANDLE_VALUE;
}
//************************************************************************************************************
BOOL Cpuerto_com::escribe( BYTE* b,int nb )
{
	DWORD	iBytesWritten; 
	DWORD	dwError=0;
	int i=0;
	COMSTAT cst;
	int v=0;
	while(TRUE)
	{
		if(!WriteFile(hport, &b[i], nb-i, &iBytesWritten, NULL))
		{
			er->pon_win(MODULO_CPUERTO_COM);
			ClearCommError(hport,&dwError,&cst);
			return FALSE;
		}
		i+=iBytesWritten;
		if(i>=nb)
			break;
		if(!iBytesWritten)
		{
			v++;
			if(v>10)
			{
				er->pon(MODULO_CPUERTO_COM,"Demasiado tiempo en espera para escribir datos",-1);
				return FALSE;
			}
			Sleep(1);
		}
	}
	
/*
	if (!rs || iBytesWritten == 0)
	{
		papp->wgeolog(LOG_POCO, "modem", "Error al pedir el tamaņo: deseados=%ld,"
			"Escritos=%d, Error=%d",num_bytes,iBytesWritten, dwError);
		return(-1);
	}*/
	return TRUE;
}
//************************************************************************************************************
int Cpuerto_com::lee( int nb )
{
	BOOL	rs;
	DWORD	iBytesRead=-1,dw;
	COMSTAT cst;
	if (nb>1023)
		nb=1023;
	memset(buf,0,1024);
	rs = ReadFile(hport, (LPSTR) buf, nb, &iBytesRead, NULL);
	if (!rs)
	{
		er->pon_win(MODULO_CPUERTO_COM);
		ClearCommError(hport,&dw,&cst);
	}
	return iBytesRead;
}
//************************************************************************************************************
int Cpuerto_com::lee( int nb, int ms, int veces)
{
	BOOL	rs;
	DWORD	iBytesRead=-1,dw;
	COMSTAT cst;
	int i=0, rep=0;
	if (nb>1023)
		nb=1023;
	memset(buf,0,1024);
	while(TRUE)
	{
		rs = ReadFile(hport, (LPSTR) &buf[i], nb-i, &iBytesRead, NULL);
		if(!rs)
			break;
		i+=iBytesRead;
		if(i>=nb)
			break;
		if(iBytesRead<=0)
		{
			rep++;
			if (rep>veces)
			{
				er->pon(MODULO_CPUERTO_COM,"Demasiado tiempo en espera para leer datos",-1);
				break;
			}
		}
		else
			rep=0;
		Sleep(ms);

	}
	//rs = ReadFile(hport, (LPSTR) buf, nb, &iBytesRead, NULL);
	if (!rs)
	{
		er->pon_win(MODULO_CPUERTO_COM);
		ClearCommError(hport,&dw,&cst);
	}
	return i;
}
//************************************************************************************************************

int Cpuerto_com::escribeylee( BYTE* b,int nb, int time_sleep )
{
	if(!escribe(b,nb))
		return -1;
	Sleep(time_sleep);
	if(lee(nb)<0)
		return -1;
	return lee();
}
//************************************************************************************************************

