#include #include #include void CommControl::portToString(CommControl::Port port,String &strPort) { if(port==CommControl::PortCOM1)strPort=String(STRING_COM1); else if(port==CommControl::PortCOM2)strPort=String(STRING_COM2); else if(port==CommControl::PortCOM3)strPort=String(STRING_COM3); else strPort=String(STRING_COM4); } CommControl::Port CommControl::stringToPort(const String &strPort) { if(strPort==String(STRING_COM1))return CommControl::PortCOM1; else if(strPort==String(STRING_COM2))return CommControl::PortCOM2; else if(strPort==String(STRING_COM3))return CommControl::PortCOM3; else return CommControl::PortCOM4; } bool CommControl::readFully(GlobalData &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(bytesReadbyteCount?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 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 &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 &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 strLines; ::OutputDebugString("\n"); FormatLines::hexasciiLines(strLines,pBuffer,byteCount); for(int index=0;index rcvBytes) { showBytes(&rcvBytes[0],rcvBytes.size()); }