#include "stdafx.h"
#include "TransportSerial.h"

#include "tchar.h"

CTransportSerial::CTransportSerial()
{
	// default settings for serial transport 9600/8 bit/no parity
	//
	m_nCom		= 0x01;
	m_nSpeed	= 9600;
	m_nDataBits	= 0x08;
	m_nParity	= 0x00;	// none
	m_nStopBits	= 0x01; // 1 stop bit

	m_hDevFile	= INVALID_HANDLE_VALUE;
}

CTransportSerial::CTransportSerial(UINT nCom, UINT nSpeed, UINT nDataBits, UINT nParity, UINT nStopBits)
{
	m_nCom		= nCom;
	m_nSpeed	= nSpeed;
	m_nDataBits	= nDataBits;
	m_nParity	= nParity;	
	m_nStopBits	= nStopBits;
}

void CTransportSerial::SetOption(UINT nCom, UINT nSpeed, UINT nDataBits, UINT nParity, UINT nStopBits)
{
	m_nCom		= nCom;
	m_nSpeed	= nSpeed;
	m_nDataBits	= nDataBits;
	m_nParity	= nParity;	
	m_nStopBits	= nStopBits;
}

CTransportSerial::~CTransportSerial()
{
	if(m_hDevFile != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hDevFile);
	}
}

EERROR CTransportSerial::Open()
{
	EERROR eRet = ER_OPEN;
	TCHAR szCom[MAX_PATH];

#ifdef WINCE
	_stprintf(szCom, _T("MOC%d:"), m_nCom);
#else
	_stprintf_s(szCom, MAX_PATH, _T("\\\\.\\COM%d"), m_nCom);
#endif

	/*if((m_hDevFile = CreateFile(szCom, GENERIC_READ | GENERIC_WRITE, 0, 
						NULL, OPEN_EXISTING, 0x00, NULL)) != INVALID_HANDLE_VALUE)*/

	if((m_hDevFile = CreateFile(szCom, GENERIC_READ | GENERIC_WRITE, 0, 
				NULL, OPEN_EXISTING, 0x00, NULL)) != INVALID_HANDLE_VALUE)
	{
		eRet = ER_SET_SPEED;
		DCB stComState;
		if(GetCommState(m_hDevFile, &stComState))
		{
			stComState.BaudRate = m_nSpeed;
			stComState.ByteSize = m_nDataBits;
			stComState.Parity	= m_nParity ;
			stComState.fParity	= false;
			stComState.StopBits = m_nStopBits - 1;

			if(SetCommState(m_hDevFile, &stComState))
			{
				eRet = ER_OK;
			}
		}

		COMMTIMEOUTS stTimeOut;
		if(GetCommTimeouts(m_hDevFile, &stTimeOut))
		{
			// read timeouts will be set to 2 sec
			stTimeOut.ReadIntervalTimeout			= 100;
			stTimeOut.ReadTotalTimeoutConstant		= 100;
			stTimeOut.ReadTotalTimeoutMultiplier	= 100;
			if(SetCommTimeouts(m_hDevFile, &stTimeOut))
			{
				eRet = ER_OK;
			}
		}
	}
	return eRet;
}

EERROR CTransportSerial::Write(BYTE* pData, DWORD dwSize)
{
	EERROR eRet = ER_OPEN;
	if(m_hDevFile != INVALID_HANDLE_VALUE)
	{
		eRet = ER_INVALID_DATA;
		if(pData != NULL)
		{
			eRet = ER_WRITE;
			DWORD dwRet = -1;
			if(WriteFile(m_hDevFile, pData, dwSize, &dwRet, NULL))
			{
				eRet = dwRet != dwSize ? ER_SIZE : ER_OK;
			}
		}
	}
	return eRet;
}

EERROR CTransportSerial::Read(BYTE* pData, DWORD& dwSize)
{
	EERROR eRet = ER_OPEN;
	if(m_hDevFile != INVALID_HANDLE_VALUE)
	{
		eRet = ER_INVALID_DATA;
		if(pData != NULL)
		{
			eRet = ER_READ;
			DWORD dwRet = -1;
			if(ReadFile(m_hDevFile, pData, dwSize, &dwRet, NULL) && (dwRet > 0x00))
			{
				eRet = dwRet != dwSize ? ER_SIZE : ER_OK;
			}
		}
	}
	return eRet;
}


EERROR CTransportSerial::Close()
{
	EERROR eRet = ER_CLOSE;
	if(m_hDevFile != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hDevFile);
		m_hDevFile = INVALID_HANDLE_VALUE;
		eRet = ER_OK;
	}
	return eRet;
}