233 lines
6.1 KiB
C++
233 lines
6.1 KiB
C++
#ifndef _COMMCTRL_COMMCONTROL_HPP_
|
|
#define _COMMCTRL_COMMCONTROL_HPP_
|
|
#ifndef _COMMON_WINDOWS_HPP_
|
|
#include <common/windows.hpp>
|
|
#endif
|
|
#ifndef _COMMON_OPENFILE_HPP_
|
|
#include <common/openfile.hpp>
|
|
#endif
|
|
#ifndef _COMMON_BLOCK_HPP_
|
|
#include <common/block.hpp>
|
|
#endif
|
|
#ifndef _COMMON_STRING_HPP_
|
|
#include <common/string.hpp>
|
|
#endif
|
|
#ifndef _COMMON_GLOBALDATA_HPP_
|
|
#include <common/gdata.hpp>
|
|
#endif
|
|
#ifndef _COMMCTRL_DEVICECONTROLBLOCK_HPP_
|
|
#include <commctrl/dcb.hpp>
|
|
#endif
|
|
#ifndef _COMMCTRL_COMMSTATUS_HPP_
|
|
#include <commctrl/commstat.hpp>
|
|
#endif
|
|
#ifndef _THREAD_EVENT_HPP_
|
|
#include <thread/event.hpp>
|
|
#endif
|
|
|
|
class CommControl
|
|
{
|
|
public:
|
|
enum {TimeOut=5000};
|
|
enum Port{PortCOM1,PortCOM2,PortCOM3,PortCOM4};
|
|
enum EventMask{EventBreak=EV_BREAK,EventCts=EV_CTS,EventDsr=EV_DSR,EventErr=EV_ERR,EventRing=EV_RING,
|
|
EventRlsd=EV_RLSD,EventRxChar=EV_RXCHAR,EventRxFlag=EV_RXFLAG,EventTxEmpty=EV_TXEMPTY,
|
|
EventAll=EV_BREAK|EV_CTS|EV_DSR|EV_ERR|EV_RING|EV_RLSD|EV_RXCHAR|EV_RXFLAG|EV_TXEMPTY};
|
|
CommControl(void);
|
|
virtual ~CommControl();
|
|
bool open(Port commPort,BOOL overlappedIO=false);
|
|
void close();
|
|
bool getDeviceControlBlock(DeviceControlBlock &deviceControlBlock)const;
|
|
bool setDeviceControlBlock(const DeviceControlBlock &deviceControlBlock)const;
|
|
bool setDeviceControlBlock(String strControlBlock)const; // (ie) "baud=1200 parity=N data=8 stop=1"
|
|
DWORD readLine(String &strLine);
|
|
DWORD writeLine(const String &strLine)const;
|
|
DWORD read(void *pBuffer,int length,DWORD timeout=0L);
|
|
DWORD write(BYTE *pBuffer,int length)const;
|
|
DWORD write(GlobalData<BYTE> &sndBuffer);
|
|
DWORD enumerateDevices(Block<Port> &deviceList);
|
|
DWORD enumerateDevices(Block<String> &deviceList);
|
|
bool clearError(void)const;
|
|
bool clearError(CommStatus &commStatus)const;
|
|
bool clearBreak(void)const;
|
|
bool clearReceiveQueue(void);
|
|
bool readFully(GlobalData<BYTE> &dataBytes);
|
|
bool readFully(BYTE *pBuffer,DWORD byteCount);
|
|
bool setBreak(void)const;
|
|
bool waitEvent(DWORD &eventMask,DWORD timeout);
|
|
bool waitEvent(DWORD timeout=TimeOut);
|
|
bool waitForBreak(DWORD timeout=TimeOut);
|
|
bool waitForData(DWORD timeout=TimeOut);
|
|
bool waitForTransmit(DWORD timeout=TimeOut);
|
|
bool setEventMask(DWORD eventMask)const;
|
|
bool hasData(void);
|
|
bool isOkay(void)const;
|
|
static void portToString(CommControl::Port port,String &strPort);
|
|
static CommControl::Port stringToPort(const String &strPort);
|
|
static void showBytes(GlobalData<BYTE> rcvBytes);
|
|
static void showBytes(BYTE *pBuffer,DWORD byteCount);
|
|
private:
|
|
CommControl(const CommControl &someCommControl);
|
|
CommControl &operator=(const CommControl &someCommControl);
|
|
void showError(DWORD errorMask)const;
|
|
|
|
FileHandle mCommDevice;
|
|
Block<String> mStrPorts;
|
|
CommStatus mCommStatus;
|
|
Event mIOEvent;
|
|
Overlapped mOverlapped;
|
|
static String msCOM1;
|
|
static String msCOM2;
|
|
static String msCOM3;
|
|
static String msCOM4;
|
|
};
|
|
|
|
inline
|
|
CommControl::CommControl(void)
|
|
{
|
|
mOverlapped.event((HANDLE)mIOEvent);
|
|
mStrPorts.insert(&String("\\.\\COM1"));
|
|
mStrPorts.insert(&String("\\.\\COM2"));
|
|
mStrPorts.insert(&String("\\.\\COM3"));
|
|
mStrPorts.insert(&String("\\.\\COM4"));
|
|
}
|
|
|
|
inline
|
|
CommControl::CommControl(const CommControl &someCommControl)
|
|
{ // private implementation
|
|
*this=someCommControl;
|
|
}
|
|
|
|
inline
|
|
CommControl::~CommControl()
|
|
{
|
|
close();
|
|
}
|
|
|
|
inline
|
|
CommControl &CommControl::operator=(const CommControl &/*someCommControl*/)
|
|
{ // private implementation
|
|
return *this;
|
|
}
|
|
|
|
inline
|
|
bool CommControl::open(Port commPort,BOOL overlappedIO)
|
|
{
|
|
close();
|
|
mCommDevice.open(mStrPorts[commPort],FileHandle::ReadWrite,FileHandle::ShareNone,FileHandle::Open,(overlappedIO?FileHandle::FlagOverlapped:FileHandle::Normal));
|
|
return isOkay();
|
|
}
|
|
|
|
inline
|
|
void CommControl::close(void)
|
|
{
|
|
if(!isOkay())return;
|
|
mCommDevice.close();
|
|
}
|
|
|
|
inline
|
|
DWORD CommControl::readLine(String &strLine)
|
|
{
|
|
strLine.reserve(1024);
|
|
if(!isOkay())return FALSE;
|
|
clearError(mCommStatus);
|
|
if(!mCommStatus.bytesInReceiveQueue())return FALSE;
|
|
return mCommDevice.getLine(strLine);
|
|
}
|
|
|
|
inline
|
|
DWORD CommControl::writeLine(const String &strLine)const
|
|
{
|
|
if(!isOkay()||strLine.isNull())return FALSE;
|
|
return mCommDevice.writeLine(strLine);
|
|
}
|
|
|
|
inline
|
|
DWORD CommControl::write(GlobalData<BYTE> &sndBuffer)
|
|
{
|
|
if(!isOkay()||!sndBuffer.size())return 0;
|
|
return write(&sndBuffer[0],sndBuffer.size());
|
|
}
|
|
|
|
inline
|
|
DWORD CommControl::write(BYTE *pBuffer,int length)const
|
|
{
|
|
if(!isOkay()||!pBuffer||!length)return 0;
|
|
return mCommDevice.write(pBuffer,length);
|
|
}
|
|
|
|
inline
|
|
bool CommControl::setBreak(void)const
|
|
{
|
|
if(!isOkay())return false;
|
|
return ::SetCommBreak((HANDLE)mCommDevice);
|
|
}
|
|
|
|
inline
|
|
bool CommControl::clearBreak(void)const
|
|
{
|
|
if(!isOkay())return false;
|
|
return ::ClearCommBreak((HANDLE)mCommDevice);
|
|
}
|
|
|
|
inline
|
|
bool CommControl::getDeviceControlBlock(DeviceControlBlock &deviceControlBlock)const
|
|
{
|
|
if(!isOkay())return false;
|
|
return ::GetCommState((HANDLE)mCommDevice,&((DeviceControlBlock&)deviceControlBlock).getDCB());
|
|
}
|
|
|
|
inline
|
|
bool CommControl::setDeviceControlBlock(const DeviceControlBlock &deviceControlBlock)const
|
|
{
|
|
if(!isOkay())return false;
|
|
return ::SetCommState((HANDLE)mCommDevice,&((DeviceControlBlock&)deviceControlBlock).getDCB());
|
|
}
|
|
|
|
inline
|
|
bool CommControl::setDeviceControlBlock(String strControlBlock)const // (ie) "baud=1200 parity=N data=8 stop=1"
|
|
{
|
|
DeviceControlBlock deviceControlBlock;
|
|
if(!::BuildCommDCB(strControlBlock.str(),&((DeviceControlBlock&)deviceControlBlock).getDCB()))return false;
|
|
return ::SetCommState((HANDLE)mCommDevice,&((DeviceControlBlock&)deviceControlBlock).getDCB());
|
|
}
|
|
|
|
inline
|
|
bool CommControl::setEventMask(DWORD eventMask)const
|
|
{
|
|
if(!isOkay())return false;
|
|
return ::SetCommMask((HANDLE)mCommDevice,eventMask);
|
|
}
|
|
|
|
inline
|
|
bool CommControl::waitEvent(DWORD timeout)
|
|
{
|
|
DWORD eventMask;
|
|
return waitEvent(eventMask,timeout);
|
|
}
|
|
|
|
inline
|
|
bool CommControl::waitForBreak(DWORD timeout)
|
|
{
|
|
if(!isOkay())return false;
|
|
setEventMask(EventBreak);
|
|
return waitEvent(timeout);
|
|
}
|
|
|
|
inline
|
|
bool CommControl::waitForData(DWORD timeout)
|
|
{
|
|
if(!isOkay())return false;
|
|
setEventMask(EventRxChar);
|
|
return waitEvent(timeout);
|
|
}
|
|
|
|
inline
|
|
bool CommControl::waitForTransmit(DWORD timeout)
|
|
{
|
|
if(!isOkay())return false;
|
|
setEventMask(EventTxEmpty);
|
|
return waitEvent(timeout);
|
|
}
|
|
#endif
|