```cpp
#include "stdafx.h"
#include "COMDongle.h"
#include "TemperatureControl.h"
COMDongle::COMDongle(void)
{
iBaudRate = 38400;
iByteSize = 8;
iStopBits = 0;
iParityBit = 0;
uiTimeout = 2000;
}
COMDongle::~COMDongle(void)
{
}
bool COMDongle::Connect(const string &strReaderName)
{
strPortCOM.SetString(String2Wstring(strReaderName).c_str());
return Connect();
}
bool COMDongle::Connect(void)
{
try
{
memset(&osRead, 0, sizeof(OVERLAPPED));
if (NULL == (osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
throw "Overlapped Read init error";
}
memset(&osWrite, 0, sizeof(OVERLAPPED));
if (NULL == (osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
throw "Overlapped Write init error";
}
memset(&osWait, 0, sizeof(OVERLAPPED));
if (NULL == (osWait.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
{
throw "Overlapped Wait init error";
}
hCOM = CreateFile(strPortCOM, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hCOM)
{
throw "CreateFile error";
}
if (!SetupComm(hCOM, 4096, 4096))
{
throw "SetupComm error";
}
if (!PurgeComm(hCOM, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
{
throw "PurgeComm error";
}
COMMTIMEOUTS commTimeouts;
commTimeouts.ReadIntervalTimeout = 200;
commTimeouts.ReadTotalTimeoutMultiplier = 200;
commTimeouts.ReadTotalTimeoutConstant = 200;
commTimeouts.WriteTotalTimeoutConstant = 500;
commTimeouts.WriteTotalTimeoutMultiplier = 0;
if (!SetCommTimeouts(hCOM, &commTimeouts))
{
throw "SetCommTimeouts error";
}
DCB dcb;
if (!GetCommState(hCOM, &dcb))
{
throw "GetCommState error";
}
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = iBaudRate;
dcb.Parity = iParityBit;
dcb.ByteSize = iByteSize;
dcb.StopBits = iStopBits;
dcb.fBinary = TRUE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fOutxCtsFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fAbortOnError = FALSE;
if (!SetCommState(hCOM, &dcb))
{
throw "SetCommState error";
}
}
catch (char* ex)
{
strLastErrorMsg.SetString(String2Wstring(ex).c_str());
Disconnect();
return false;
}
return true;
}
void COMDongle::Disconnect(void)
{
if (hCOM)
{
CloseHandle(hCOM);
}
hCOM = NULL;
}
bool COMDongle::IsOpen(void)
{
if (hCOM)
{
return true;
}
else
{
return false;
}
}
string COMDongle::GetLastErrorMsg(void)
{
return Wstring2String(strLastErrorMsg.GetString());
}
bool COMDongle::Transmit(unsigned char sendData[], unsigned int uiSendLength, unsigned char receiveData[], unsigned int &uiReceiveLength)
{
return true;
}
bool COMDongle::Write(unsigned char sendData[], unsigned int uiSendLength)
{
if (!hCOM)
{
strLastErrorMsg.SetString(L"Not connected");
return false;
}
DWORD dwBytesWritten(0);
DWORD dwBytesSent(0);
DWORD dwErrorFlag(0);
COMSTAT comStat;
if (!WriteFile(hCOM, sendData, uiSendLength, &dwBytesWritten, NULL))
{
if (GetLastError() == ERROR_IO_PENDING)
{
while (!GetOverlappedResult(hCOM, &osWrite, &dwBytesWritten, TRUE))
{
if (GetLastError() == ERROR_IO_INCOMPLETE)
{
dwBytesSent += dwBytesWritten;
continue;
}
else
{
ClearCommError(hCOM, &dwErrorFlag, &comStat);
break;
}
}
dwBytesSent += dwBytesWritten;
if (dwBytesSent != uiSendLength)
{
strLastErrorMsg.SetString(L"Probable write timeout");
return false;
}
}
else
{
ClearCommError(hCOM, &dwErrorFlag, &comStat);
strLastErrorMsg.SetString(L"Write COM error");
return false;
}
}
return true;
}
bool COMDongle::Read(unsigned char receiveData[], unsigned int &uiReceiveLength)
{
if (!hCOM)
{
strLastErrorMsg.SetString(L"Not connected");
return false;
}
DWORD dwLength(uiReceiveLength);
int retryTime = uiTimeout / 500;
unsigned char cmpEnd[3] = { 0x03, 0x0D, 0x0A };
if (retryTime <= 0)
{
retryTime = 1;
}
while (retryTime--)
{
if (ReadFile(hCOM, receiveData, dwLength, &dwLength, NULL))
{
if (!memcmp(receiveData + dwLength - 3, cmpEnd, 3))
{
uiReceiveLength = dwLength;
PurgeComm(hCOM, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
return true;
}
}
}
return false;
//DWORD dwErrorFlag(0);
//COMSTAT comStat;
//DWORD dwLength;
ResetEvent(osRead.hEvent);
ClearCommError(hCOM, &dwErrorFlag, &comStat);
//dwLength = uiReceiveLength;
dwLength = min(uiReceiveLength, comStat.cbInQue);
if (dwLength > 0)
//{
// //if (!ReadFile(hCOM, receiveData, dwLength, &dwLength, &osRead))
// if (!ReadFile(hCOM, receiveData, dwLength, &dwLength, NULL))
// {
// if (ERROR_IO_PENDING == GetLastError())
// {
// while (!GetOverlappedResult(hCOM, &osRead, &dwLength, TRUE))
// {
// if (ERROR_IO_INCOMPLETE == GetLastError())
// {
// continue;
// }
// else
// {
// ClearCommError(hCOM, &dwErrorFlag, &comStat);
// strLastErrorMsg.SetString(L"Read COM error");
// return false;
// }
// }
// }
// else
// {
// dwLength = 0;
// ClearCommError(hCOM, &dwErrorFlag, &comStat);
// strLastErrorMsg.SetString(L"");
// return false;
// }
// }
//}
//PurgeComm(hCOM, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
//return true;
}