Initial
This commit is contained in:
213
commctrl/commctrl.cpp
Normal file
213
commctrl/commctrl.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
#include <commctrl/commctrl.hpp>
|
||||
#include <commctrl/fmtlines.hpp>
|
||||
|
||||
String CommControl::msCOM1="COM1";
|
||||
String CommControl::msCOM2="COM2";
|
||||
String CommControl::msCOM3="COM3";
|
||||
String CommControl::msCOM4="COM4";
|
||||
|
||||
void CommControl::portToString(CommControl::Port port,String &strPort)
|
||||
{
|
||||
if(port==CommControl::PortCOM1)strPort=msCOM1;
|
||||
else if(port==CommControl::PortCOM2)strPort=msCOM2;
|
||||
else if(port==CommControl::PortCOM3)strPort=msCOM3;
|
||||
else strPort=msCOM4;
|
||||
}
|
||||
|
||||
CommControl::Port CommControl::stringToPort(const String &strPort)
|
||||
{
|
||||
if(strPort==msCOM1)return CommControl::PortCOM1;
|
||||
else if(strPort==msCOM2)return CommControl::PortCOM2;
|
||||
else if(strPort==msCOM3)return CommControl::PortCOM3;
|
||||
else return CommControl::PortCOM4;
|
||||
}
|
||||
|
||||
bool CommControl::readFully(GlobalData<BYTE> &dataBytes)
|
||||
{
|
||||
CommStatus commStatus;
|
||||
DWORD bytesRead=0;
|
||||
DWORD byteCount;
|
||||
DWORD bytesToRead;
|
||||
|
||||
if(!isOkay())return false;
|
||||
clearError(commStatus);
|
||||
byteCount=dataBytes.size();
|
||||
if(!byteCount&&!commStatus.bytesInReceiveQueue())return false;
|
||||
if(!byteCount){byteCount=commStatus.bytesInReceiveQueue();dataBytes.size(byteCount);}
|
||||
return readFully(&dataBytes[0],dataBytes.size());
|
||||
}
|
||||
|
||||
bool CommControl::readFully(BYTE *pBuffer,DWORD byteCount)
|
||||
{
|
||||
CommStatus commStatus;
|
||||
DWORD bytesRead=0;
|
||||
DWORD bytesToRead;
|
||||
|
||||
if(!isOkay())return false;
|
||||
clearError(commStatus);
|
||||
if(!byteCount||!pBuffer)return false;
|
||||
while(bytesRead<byteCount)
|
||||
{
|
||||
if(commStatus.bytesInReceiveQueue())
|
||||
{
|
||||
bytesToRead=bytesRead+commStatus.bytesInReceiveQueue()>byteCount?byteCount-bytesRead:commStatus.bytesInReceiveQueue();
|
||||
read(&pBuffer[bytesRead],bytesToRead);
|
||||
bytesRead+=bytesToRead;
|
||||
}
|
||||
if(bytesRead==byteCount)break;
|
||||
::Sleep(25);
|
||||
clearError(commStatus);
|
||||
}
|
||||
showBytes(pBuffer,byteCount);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommControl::hasData(void)
|
||||
{
|
||||
CommStatus commStatus;
|
||||
clearError(commStatus);
|
||||
return commStatus.bytesInReceiveQueue()?true:false;
|
||||
}
|
||||
|
||||
bool CommControl::clearReceiveQueue(void)
|
||||
{
|
||||
GlobalData<BYTE> rcvBytes;
|
||||
CommStatus commStatus;
|
||||
|
||||
if(!isOkay())return false;
|
||||
::Sleep(1000);
|
||||
clearError(commStatus);
|
||||
if(!commStatus.bytesInReceiveQueue())return true;
|
||||
::OutputDebugString(String(String("Clearing ")+String().fromInt(commStatus.bytesInReceiveQueue())+String(" bytes from receive queue.\n")).str());
|
||||
rcvBytes.size(commStatus.bytesInReceiveQueue());
|
||||
read(&rcvBytes[0],rcvBytes.size());
|
||||
showBytes(rcvBytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CommControl::waitEvent(DWORD &eventMask,DWORD timeout)
|
||||
{
|
||||
BOOL result;
|
||||
DWORD lastError;
|
||||
|
||||
eventMask=0;
|
||||
if(!isOkay())return false;
|
||||
mIOEvent.resetEvent();
|
||||
result=::WaitCommEvent((HANDLE)mCommDevice,&eventMask,&mOverlapped.getOverlapped());
|
||||
if(result)return true;
|
||||
lastError=::GetLastError();
|
||||
if(lastError!=ERROR_IO_PENDING)return false;
|
||||
mIOEvent.waitEvent(timeout);
|
||||
if(!mCommDevice.getOverlappedResult(mOverlapped,false))return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD CommControl::enumerateDevices(Block<Port> &deviceList)
|
||||
{
|
||||
|
||||
deviceList.remove();
|
||||
if(isOkay())return 0;
|
||||
for(Port port=PortCOM1;port<=PortCOM4;((int&)port)++)
|
||||
{
|
||||
if(mCommDevice.open(mStrPorts[port]))
|
||||
{
|
||||
mCommDevice.close();
|
||||
deviceList.insert(&port);
|
||||
}
|
||||
}
|
||||
return deviceList.size();
|
||||
}
|
||||
|
||||
DWORD CommControl::enumerateDevices(Block<String> &deviceList)
|
||||
{
|
||||
deviceList.remove();
|
||||
if(isOkay())return 0;
|
||||
for(Port port=PortCOM1;port<=PortCOM4;((int&)port)++)
|
||||
{
|
||||
if(mCommDevice.open(mStrPorts[port]))
|
||||
{
|
||||
mCommDevice.close();
|
||||
if(PortCOM1==port)deviceList.insert(&String("COM1"));
|
||||
else if(PortCOM2==port)deviceList.insert(&String("COM2"));
|
||||
else if(PortCOM3==port)deviceList.insert(&String("COM3"));
|
||||
else if(PortCOM4==port)deviceList.insert(&String("COM4"));
|
||||
}
|
||||
}
|
||||
return deviceList.size();
|
||||
}
|
||||
|
||||
DWORD CommControl::read(void *pBuffer,int length,DWORD timeout)
|
||||
{
|
||||
BOOL result;
|
||||
DWORD lastError;
|
||||
|
||||
if(!isOkay())return FALSE;
|
||||
mIOEvent.resetEvent();
|
||||
result=mCommDevice.read((BYTE*)pBuffer,length,mOverlapped);
|
||||
if(result)return TRUE;
|
||||
lastError=::GetLastError();
|
||||
if(lastError!=ERROR_IO_PENDING)return FALSE;
|
||||
mIOEvent.waitEvent(TimeOut);
|
||||
if(!mCommDevice.getOverlappedResult(mOverlapped,FALSE))return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool CommControl::isOkay(void)const
|
||||
{
|
||||
return mCommDevice.isOkay();
|
||||
}
|
||||
|
||||
bool CommControl::clearError(CommStatus &commStatus)const
|
||||
{
|
||||
DWORD errorMask(0);
|
||||
bool returnCode(false);
|
||||
|
||||
if(!isOkay())return returnCode;
|
||||
returnCode=::ClearCommError((HANDLE)mCommDevice,&errorMask,&commStatus.getCOMSTAT());
|
||||
showError(errorMask);
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
bool CommControl::clearError(void)const
|
||||
{
|
||||
DWORD errorMask(0);
|
||||
bool returnCode(false);
|
||||
|
||||
if(!isOkay())return false;
|
||||
returnCode=::ClearCommError((HANDLE)mCommDevice,&errorMask,0);
|
||||
showError(errorMask);
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
void CommControl::showError(DWORD errorMask)const
|
||||
{
|
||||
if(errorMask&CE_BREAK)::OutputDebugString("The hardware detected a break condition.\n");
|
||||
if(errorMask&CE_DNS)::OutputDebugString("Windows 95 and Windows 98: A parallel device is not selected.\n");
|
||||
if(errorMask&CE_FRAME)::OutputDebugString("The hardware detected a framing error.\n");
|
||||
if(errorMask&CE_IOE)::OutputDebugString("An I/O error occurred during communications with the device.\n");
|
||||
if(errorMask&CE_MODE)::OutputDebugString("The requested mode is not supported, or the hFile parameter is invalid. If this value is specified, it is the only valid error.\n");
|
||||
if(errorMask&CE_OOP)::OutputDebugString("Windows 95 and Windows 98: A parallel device signaled that it is out of paper.\n");
|
||||
if(errorMask&CE_OVERRUN)::OutputDebugString("A character-buffer overrun has occurred. The next character is lost.\n");
|
||||
if(errorMask&CE_PTO)::OutputDebugString("Windows 95 and Windows 98: A time-out occurred on a parallel device.\n");
|
||||
if(errorMask&CE_RXOVER)::OutputDebugString("An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.\n");
|
||||
if(errorMask&CE_RXPARITY)::OutputDebugString("The hardware detected a parity error.\n");
|
||||
if(errorMask&CE_TXFULL)::OutputDebugString("The application tried to transmit a character, but the output buffer was full.\n");
|
||||
}
|
||||
|
||||
void CommControl::showBytes(BYTE *pBuffer,DWORD byteCount)
|
||||
{
|
||||
Block<String> strLines;
|
||||
|
||||
::OutputDebugString("\n");
|
||||
FormatLines::hexasciiLines(strLines,pBuffer,byteCount);
|
||||
for(int index=0;index<strLines.size();index++)
|
||||
{
|
||||
::OutputDebugString(strLines[index].str());
|
||||
::OutputDebugString("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CommControl::showBytes(GlobalData<BYTE> rcvBytes)
|
||||
{
|
||||
showBytes(&rcvBytes[0],rcvBytes.size());
|
||||
}
|
||||
Reference in New Issue
Block a user