Listing 1: CSerialPort header file
//===================================================================
// File : SerialPort.h
// Author : Eric Woodruff, Eric@EWoodruff.us
// Updated : Mon 04/07/1997
// Note : Copyright 1996-97, Eric Woodruff, All rights reserved
// Compiler: Borland C++ 5.xx, Visual C++ 4.xx
//
// Class declaration for CSerialPort. This class is a wrapper for
// the Win32 serial communication API functions.
//
// This class can be compiled for a DLL. Use the appropriate
// #define:
// BUILD_SPCOMM_DLL defined - Build DLL
// BUILD_SPCOMM_NODLL defined - Not a DLL
// Neither defined - Assumed to be #include for app DLL
// import
//
//===================================================================
#if !defined(__SERIALPORT_H)
#define __SERIALPORT_H
// If you will never build this for use in a DLL, you can comment out
// this #if block.
#if defined(BUILD_SPCOMM_DLL)
#define _DLLCLASS __declspec(dllexport)
#elif !defined(BUILD_SPCOMM_NODLL)
#define _DLLCLASS __declspec(dllimport)
#else
#define _DLLCLASS
#endif
//===================================================================
// Serial I/O definitions
// The standard serial I/O definitions can be found in WINBASE.H
// (i.e. CBR_xxxx, PCF_xxx, EV_xxx, CE_xxx, etc).
//===================================================================
#define SEVENDATABITS 7 // No equivalents in WINBASE.H
#define EIGHTDATABITS 8
#define PCF_NOFLOWCTL 0
#define ASCII_NUL 0x00 // Some common control codes
#define ASCII_SOH 0x01
#define ASCII_STX 0x02
#define ASCII_ETX 0x03
#define ASCII_EOT 0x04
#define ASCII_ENQ 0x05
#define ASCII_ACK 0x06
#define ASCII_XON 0x11
#define ASCII_XOFF 0x13
#define ASCII_NAK 0x15
#define ASCII_CAN 0x18
#define SP_INBUFSIZE 4096 // Default to 4K input and output buffer
#define SP_OUTBUFSIZE 4096
#define SP_WRITETIMEOUT 1000 // Default to a 1 second write timeout
//===================================================================
// Serial port class definition
//===================================================================
class _DLLCLASS CSerialPort
{
protected:
HANDLE hPortId; // Handle for port I/O
HANDLE hThread; // Event watch thread handle
DWORD dwThreadId; // Event watch thread ID
DWORD dwLastError; // Last error code from GetLastError()
DWORD dwCommErrors; // Last comm error flags
// from ClearCommError()
// Overlapped I/O structures for read and write
OVERLAPPED olRead, olWrite;
DWORD dwEventMask; // Event mask for WaitCommEvent()
// Overlapped I/O structure for WaitCommEvent()
OVERLAPPED olWait;
public:
CSerialPort(const char *szPortName);
~CSerialPort();
//===============================================================
// Initialization/configuration functions
//===============================================================
BOOL SetBaudRate(int nBaudRate = CBR_19200);
BOOL SetParityDataStop(int nParity = NOPARITY,
int nDataBits = EIGHTDATABITS, int nStopBits = ONESTOPBIT);
BOOL SetFlowControl(int nFlowCtrl = PCF_DTRDSR | PCF_RTSCTS,
int nXOnLimit = 100, int nXOffLimit = 100,
char chXOnChar = ASCII_XON, char chXOffChar = ASCII_XOFF);
BOOL SetBufferSizes(int nInBufSize = SP_INBUFSIZE,
int nOutBufSize = SP_OUTBUFSIZE);
BOOL SetReadTimeouts(int nInterval = MAXDWORD,
int nMultiplier = 0, int nConstant = 0);
BOOL SetWriteTimeouts(int nMultiplier = 0,
int nConstant = SP_WRITETIMEOUT);
//===============================================================
// Thread functions
//===============================================================
BOOL StartCommThread(LPTHREAD_START_ROUTINE CommProc,
void *pvData = NULL);
DWORD StopCommThread(void);
//===============================================================
// Inline functions
//===============================================================
// Return TRUE if port is open and no error occurred on the
// last operation, FALSE if not.
inline BOOL IsValid(void);
// Return last error that occurred
inline DWORD GetLastError(void);
// Return the last set of error flags retrieved by ClearCommError
inline DWORD GetCommErrors(void);
//===============================================================
// Virtual member functions
//===============================================================
// Can be overridden to alter the data being read/written.
// Plain read and write by default
virtual int ReadCommBlock(LPSTR lpBytes, int nBytesToRead,
BOOL bExactSize = FALSE);
virtual int WriteCommBlock(LPSTR lpBytes, int nBytesToWrite);
// Can be overridden to provide custom handling of the data read
// by the comm thread. Does nothing by default.
virtual int ProcessData(char *byData, int nLength);
// Can be overridden to provide custom polled I/O
virtual BOOL WaitCommEvent(void);
virtual DWORD CheckForCommEvent(BOOL bWait = FALSE);
//===============================================================
// Win32 API wrapper functions
//
// The following are not implemented in the class as they require
// no access to the port handle or other internal data:
//
// BuildCommDCB
// BuildCommDCBAndTimeouts
// CommConfigDialog
//
//===============================================================
BOOL ClearCommBreak(void);
BOOL ClearCommError(LPCOMSTAT lpStat, LPDWORD lpdwErrors = NULL);
BOOL EscapeCommFunction(DWORD dwFunc);
BOOL GetCommConfig(LPCOMMCONFIG lpCC, LPDWORD lpdwSize);
BOOL GetCommMask(LPDWORD lpEvtMask);
BOOL GetCommModemStatus(LPDWORD lpModemStat);
BOOL GetCommProperties(LPCOMMPROP lpCommProp);
BOOL PurgeComm(DWORD fdwAction);
BOOL SetCommBreak(void);
BOOL SetCommConfig(LPCOMMCONFIG lpCC, DWORD dwSize);
BOOL SetCommMask(DWORD fdwEvtMask);
BOOL TransmitCommChar(char chTransmit);
// DeviceIoControl() call to enable/disable insertion of line
// status and modem status values in the normal data stream
BOOL LSRMST_INSERT(BYTE chEscapeChar);
//===============================================================
// Win32 API wrappers for those who prefer the direct approach to
// port configuration.
//===============================================================
BOOL GetCommState(LPDCB lpDCB);
BOOL GetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts);
BOOL SetCommState(LPDCB lpDCB);
BOOL SetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts);
BOOL SetupComm(DWORD cbInQueue, DWORD cbOutQueue);
};
// Inline function bodies
inline BOOL CSerialPort::IsValid(void)
{ return (!(hPortId == INVALID_HANDLE_VALUE || dwLastError)); }
inline DWORD CSerialPort::GetLastError(void)
{ return dwLastError; }
inline DWORD CSerialPort::GetCommErrors(void)
{ return dwCommErrors; }
#endif
// End of File