|
@@ -0,0 +1,992 @@
|
|
|
|
+///////////////////////////////// Includes ////////////////////////////////////
|
|
|
|
+#include "stdafx.h"
|
|
|
|
+#include "serialport.h"
|
|
|
|
+#ifndef _WINERROR
|
|
|
|
+#pragma message("To avoid this message, please put WinError.h in your pre compiled header")
|
|
|
|
+#include <WinError.h>
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+///////////////////////////////// Defines /////////////////////////////////////
|
|
|
|
+#ifdef _DEBUG
|
|
|
|
+#define new DEBUG_NEW
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+//////////////////////////////// Implementation ///////////////////////////////
|
|
|
|
+CSerialException::CSerialException(DWORD dwError) : m_dwError(dwError)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+BOOL CSerialException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError, PUINT pnHelpContext /* = 0 */)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
|
|
|
|
+
|
|
|
|
+ if(pnHelpContext != NULL)
|
|
|
|
+ *pnHelpContext = 0;
|
|
|
|
+
|
|
|
|
+ // What will be the return value from this function(assume the worst)
|
|
|
|
+ BOOL bSuccess = FALSE;
|
|
|
|
+
|
|
|
|
+ LPTSTR lpBuffer;
|
|
|
|
+ DWORD dwReturn = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
|
+ NULL,
|
|
|
|
+ m_dwError,
|
|
|
|
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
|
|
|
|
+ reinterpret_cast<LPTSTR>(&lpBuffer),
|
|
|
|
+ 0,
|
|
|
|
+ NULL
|
|
|
|
+ );
|
|
|
|
+ if(dwReturn == 0)
|
|
|
|
+ {
|
|
|
|
+ *lpszError = _T('\0');
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ bSuccess = TRUE;
|
|
|
|
+ Checked::tcsncpy_s(lpszError, nMaxError, lpBuffer, _TRUNCATE);
|
|
|
|
+ LocalFree(lpBuffer);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return bSuccess;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+CString CSerialException::GetErrorMessage()
|
|
|
|
+{
|
|
|
|
+ CString strVal;
|
|
|
|
+ LPTSTR pstrError = strVal.GetBuffer(ERR_BUFFER);
|
|
|
|
+
|
|
|
|
+ GetErrorMessage(pstrError, ERR_BUFFER, NULL);
|
|
|
|
+ strVal.ReleaseBuffer();
|
|
|
|
+
|
|
|
|
+ return strVal;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+IMPLEMENT_DYNAMIC(CSerialException, CException)
|
|
|
|
+
|
|
|
|
+#ifdef _DEBUG
|
|
|
|
+void CSerialException::Dump(CDumpContext &dc) const
|
|
|
|
+{
|
|
|
|
+ CObject::Dump(dc);
|
|
|
|
+ dc << _T("m_dwError = ") << m_dwError << _T("\n");
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+CSerialPort::CSerialPort() : m_hComm(INVALID_HANDLE_VALUE), m_hEvent(NULL)
|
|
|
|
+{
|
|
|
|
+ m_hKernel32 = GetModuleHandle(_T("KERNEL32.DLL"));
|
|
|
|
+ if(m_hKernel32)
|
|
|
|
+ m_lpfnCancelIO = reinterpret_cast<LPCANCELIO>(GetProcAddress(m_hKernel32, "CancelIo"));
|
|
|
|
+ else
|
|
|
|
+ m_lpfnCancelIO = NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+CSerialPort::~CSerialPort()
|
|
|
|
+{
|
|
|
|
+ Close();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::ThrowSerialException(DWORD dwError /* = 0 */)
|
|
|
|
+{
|
|
|
|
+ if(dwError == 0)
|
|
|
|
+ dwError = GetLastError();
|
|
|
|
+
|
|
|
|
+ CSerialException* pException = new CSerialException(dwError);
|
|
|
|
+
|
|
|
|
+ TRACE(_T("Warning: throwing CSerialException for error %d\n"), dwError);
|
|
|
|
+ THROW(pException);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#ifdef _DEBUG
|
|
|
|
+void CSerialPort::Dump(CDumpContext &dc) const
|
|
|
|
+{
|
|
|
|
+ dc << _T("m_hComm = ") << m_hComm << _T("\n");
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+void CSerialPort::Open(LPCTSTR pszPort, /* COM1 */
|
|
|
|
+ DWORD dwBaud /* = 9600 */,
|
|
|
|
+ Parity parity /* = NoParity */,
|
|
|
|
+ BYTE dataBits /* = 8 */,
|
|
|
|
+ StopBits stopBits /* = OneStopBit */,
|
|
|
|
+ FlowControl flowCtl /* = NoFlowControl */,
|
|
|
|
+ BOOL bOverlapped /* = 0 */)
|
|
|
|
+{
|
|
|
|
+ Close(); // In case we are already open
|
|
|
|
+ // Call CreateFile to open the comms port
|
|
|
|
+ TCHAR szPort[16] = {0};
|
|
|
|
+ _stprintf_s(szPort, _T("\\\\.\\%s"), pszPort);
|
|
|
|
+ m_hComm = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, bOverlapped ? FILE_FLAG_OVERLAPPED : 0, NULL);
|
|
|
|
+ if(m_hComm == INVALID_HANDLE_VALUE)
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //LOG4C((LOG_WARN,"%s打开失败,GetLastError=%ld", szPort, dwLastError));
|
|
|
|
+ //Global::WriteReportLog(1, "Serial port error", "Open Serial Port Fail, GetLastError=%ld !", dwLastError);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Create the event we need for later synchronisation use
|
|
|
|
+ m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
+ if(m_hEvent == NULL)
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //LOG4C((LOG_WARN,"CreateEvent失败,GetLastError=%ld", szPort, dwLastError));
|
|
|
|
+ //Global::WriteReportLog(1, "Serial port error", "CreateEvent Fail, GetLastError=%ld !", dwLastError);
|
|
|
|
+ Close();
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ( !SetupComm(m_hComm,10240,2048) )
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ CloseHandle(m_hComm);
|
|
|
|
+ CloseHandle(m_hEvent);
|
|
|
|
+// Global::WriteReportLog(1, "Serial port error", "SetupComm Fail, GetLastError=%ld !", dwLastError);
|
|
|
|
+ Close();
|
|
|
|
+ return ;
|
|
|
|
+ }
|
|
|
|
+ // Get the current state prior to changing it
|
|
|
|
+ DCB dcb;
|
|
|
|
+ dcb.DCBlength = sizeof(DCB);
|
|
|
|
+ GetState(dcb);
|
|
|
|
+
|
|
|
|
+ // Setup the baud rate
|
|
|
|
+ dcb.BaudRate = dwBaud;
|
|
|
|
+
|
|
|
|
+ // Setup the Parity
|
|
|
|
+ switch(parity)
|
|
|
|
+ {
|
|
|
|
+ case NoParity:
|
|
|
|
+ dcb.Parity = NOPARITY;
|
|
|
|
+ break;
|
|
|
|
+ case OddParity:
|
|
|
|
+ dcb.Parity = ODDPARITY;
|
|
|
|
+ break;
|
|
|
|
+ case EvenParity:
|
|
|
|
+ dcb.Parity = EVENPARITY;
|
|
|
|
+ break;
|
|
|
|
+ case MarkParity:
|
|
|
|
+ dcb.Parity = MARKPARITY;
|
|
|
|
+ break;
|
|
|
|
+ case SpaceParity:
|
|
|
|
+ dcb.Parity = SPACEPARITY;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ ASSERT(FALSE);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Setup the data bits
|
|
|
|
+ dcb.ByteSize = dataBits;
|
|
|
|
+
|
|
|
|
+ // Setup the stop bits
|
|
|
|
+ switch(stopBits)
|
|
|
|
+ {
|
|
|
|
+ case OneStopBit:
|
|
|
|
+ dcb.StopBits = ONESTOPBIT;
|
|
|
|
+ break;
|
|
|
|
+ case OnePointFiveStopBits:
|
|
|
|
+ dcb.StopBits = ONE5STOPBITS;
|
|
|
|
+ break;
|
|
|
|
+ case TwoStopBits:
|
|
|
|
+ dcb.StopBits = TWOSTOPBITS;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ ASSERT(FALSE);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Setup the flow control
|
|
|
|
+ dcb.fDsrSensitivity = FALSE;
|
|
|
|
+ switch(flowCtl)
|
|
|
|
+ {
|
|
|
|
+ case NoFlowControl:
|
|
|
|
+ dcb.fOutxCtsFlow = FALSE;
|
|
|
|
+ dcb.fOutxDsrFlow = FALSE;
|
|
|
|
+ dcb.fOutX = FALSE;
|
|
|
|
+ dcb.fInX = FALSE;
|
|
|
|
+ break;
|
|
|
|
+ case CtsRtsFlowControl:
|
|
|
|
+ dcb.fOutxCtsFlow = TRUE;
|
|
|
|
+ dcb.fOutxDsrFlow = FALSE;
|
|
|
|
+ dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
|
|
|
+ dcb.fOutX = FALSE;
|
|
|
|
+ dcb.fInX = FALSE;
|
|
|
|
+ break;
|
|
|
|
+ case CtsDtrFlowControl:
|
|
|
|
+ dcb.fOutxCtsFlow = TRUE;
|
|
|
|
+ dcb.fOutxDsrFlow = FALSE;
|
|
|
|
+ dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
|
|
|
|
+ dcb.fOutX = FALSE;
|
|
|
|
+ dcb.fInX = FALSE;
|
|
|
|
+ break;
|
|
|
|
+ case DsrRtsFlowControl:
|
|
|
|
+ dcb.fOutxCtsFlow = FALSE;
|
|
|
|
+ dcb.fOutxDsrFlow = TRUE;
|
|
|
|
+ dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
|
|
|
|
+ dcb.fOutX = FALSE;
|
|
|
|
+ dcb.fInX = FALSE;
|
|
|
|
+ break;
|
|
|
|
+ case DsrDtrFlowControl:
|
|
|
|
+ dcb.fOutxCtsFlow = FALSE;
|
|
|
|
+ dcb.fOutxDsrFlow = TRUE;
|
|
|
|
+ dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
|
|
|
|
+ dcb.fOutX = FALSE;
|
|
|
|
+ dcb.fInX = FALSE;
|
|
|
|
+ break;
|
|
|
|
+ case XonXoffFlowControl:
|
|
|
|
+ dcb.fOutxCtsFlow = FALSE;
|
|
|
|
+ dcb.fOutxDsrFlow = FALSE;
|
|
|
|
+ dcb.fOutX = TRUE;
|
|
|
|
+ dcb.fInX = TRUE;
|
|
|
|
+ dcb.XonChar = 0x11;
|
|
|
|
+ dcb.XoffChar = 0x13;
|
|
|
|
+ dcb.XoffLim = 100;
|
|
|
|
+ dcb.XonLim = 100;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ ASSERT(FALSE);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //Now that we have all the settings in place, make the changes
|
|
|
|
+ SetState(dcb);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Open(int nPort,
|
|
|
|
+ DWORD dwBaud /* = 9600 */,
|
|
|
|
+ Parity parity /* = NoParity */,
|
|
|
|
+ BYTE dataBits /* = 8 */,
|
|
|
|
+ StopBits stopBits /* = OneStopBit */,
|
|
|
|
+ FlowControl flowCtl /* = NoFlowControl */,
|
|
|
|
+ BOOL bOverlapped /* = 0 */)
|
|
|
|
+{
|
|
|
|
+ //Form the string version of the port number
|
|
|
|
+ CString strPort;
|
|
|
|
+ strPort.Format(_T("\\\\.\\COM%d"), nPort);
|
|
|
|
+
|
|
|
|
+ //Then delegate the work to the other version of Open
|
|
|
|
+ Open(strPort, dwBaud, parity, dataBits, stopBits, flowCtl, bOverlapped);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Close()
|
|
|
|
+{
|
|
|
|
+ if(IsOpen())
|
|
|
|
+ {
|
|
|
|
+ // Close down the comms port
|
|
|
|
+ BOOL bSuccess = CloseHandle(m_hComm);
|
|
|
|
+ m_hComm = INVALID_HANDLE_VALUE;
|
|
|
|
+ if(!bSuccess)
|
|
|
|
+ TRACE(_T("CSerialPort::Close, Failed to close up the comms port, Error:%d\n"), GetLastError());
|
|
|
|
+// LOG4C((LOG_WARN,"关闭串口失败,GetLastError=%ld", GetLastError()));
|
|
|
|
+
|
|
|
|
+ // Free the event object we are using
|
|
|
|
+ if(m_hEvent)
|
|
|
|
+ {
|
|
|
|
+ CloseHandle(m_hEvent);
|
|
|
|
+ m_hEvent = NULL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Attach(HANDLE hComm)
|
|
|
|
+{
|
|
|
|
+ Close();
|
|
|
|
+
|
|
|
|
+ //Validate our parameters, now that the port has been closed
|
|
|
|
+ ASSERT(m_hComm == INVALID_HANDLE_VALUE);
|
|
|
|
+ ASSERT(m_hEvent == NULL);
|
|
|
|
+
|
|
|
|
+ m_hComm = hComm;
|
|
|
|
+
|
|
|
|
+ //Create the event we need for later synchronisation use
|
|
|
|
+ m_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
+ if (m_hEvent == NULL)
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ Close();
|
|
|
|
+ //TRACE(_T("CSerialPort::Attach, Failed in call to CreateEvent in Attach, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"CreateEvent失败,GetLastError=%ld", GetLastError()));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+HANDLE CSerialPort::Detach()
|
|
|
|
+{
|
|
|
|
+ // What will be the return value from this function
|
|
|
|
+ HANDLE hVal = m_hComm;
|
|
|
|
+
|
|
|
|
+ m_hComm = INVALID_HANDLE_VALUE;
|
|
|
|
+
|
|
|
|
+ if(m_hEvent)
|
|
|
|
+ {
|
|
|
|
+ CloseHandle(m_hEvent);
|
|
|
|
+ m_hEvent = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return hVal;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+DWORD CSerialPort::Read(void *lpBuf, DWORD dwCount)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (lpBuf == NULL || !::AfxIsValidAddress(lpBuf, dwCount, FALSE))
|
|
|
|
+ {
|
|
|
|
+// LOG4C((LOG_WARN, "Read的缓存地址无效!"))
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ DWORD dwErrorFlags = 0;
|
|
|
|
+ COMSTAT ComStat;
|
|
|
|
+ ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
|
|
|
|
+
|
|
|
|
+#if 1
|
|
|
|
+ // 使用ClearCommError来读取缓存区接受到的字节时,
|
|
|
|
+ // 可能受系统线程调试或硬件延时, cbInQue为空,
|
|
|
|
+ // 这里要用while延时获取;
|
|
|
|
+ DWORD dwTick = GetTickCount();
|
|
|
|
+ DWORD dwLastLen = 0;
|
|
|
|
+ //while (ComStat.cbInQue == 0)
|
|
|
|
+ while(1)
|
|
|
|
+ {// cbInQue表示输入缓冲区的字节数;
|
|
|
|
+ Sleep(150);
|
|
|
|
+ if (GetTickCount() - dwTick > 5000)
|
|
|
|
+ break;
|
|
|
|
+ ClearCommError(m_hComm, &dwErrorFlags, &ComStat);
|
|
|
|
+ if ( ComStat.cbInQue != 0 && dwLastLen == ComStat.cbInQue )
|
|
|
|
+ break;
|
|
|
|
+ dwLastLen = ComStat.cbInQue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ComStat.cbInQue == 0)
|
|
|
|
+ {
|
|
|
|
+ // 串口无数据返回;
|
|
|
|
+// LOG4C((LOG_ERROR, "1.5秒超时已过,读串口失败,缓存区无数据"));
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ DWORD dwBytesRead = 0;
|
|
|
|
+ if(!ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, NULL))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"ReadFile失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return dwBytesRead;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Read(void *lpBuf, DWORD dwCount, OVERLAPPED &overlapped, DWORD *pBytesRead /* = 0 */)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ DWORD dwBytesRead = 0;
|
|
|
|
+ BOOL bSuccess = ReadFile(m_hComm, lpBuf, dwCount, &dwBytesRead, &overlapped);
|
|
|
|
+ if(!bSuccess)
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::Read, Failed in call to ReadFile, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"ReadFile失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if(pBytesRead)
|
|
|
|
+ *pBytesRead = dwBytesRead;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+DWORD CSerialPort::Write(const void *lpBuf, DWORD dwCount)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ DWORD dwBytesWritten = 0;
|
|
|
|
+ // 写前,清空缓存区;
|
|
|
|
+ PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
|
|
|
|
+ if(!WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, NULL))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"WriteFile失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return dwBytesWritten;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Write(const void *lpBuf, DWORD dwCount, OVERLAPPED &overlapped, DWORD *pBytesWritten /* = 0 */)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ DWORD dwBytesWritten = 0;
|
|
|
|
+ // 写前,清空缓存区;
|
|
|
|
+ PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
|
|
|
|
+ BOOL bSuccess = WriteFile(m_hComm, lpBuf, dwCount, &dwBytesWritten, &overlapped);
|
|
|
|
+ if(!bSuccess)
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::Write, Failed in call to WriteFile, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"WriteFile失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if(pBytesWritten)
|
|
|
|
+ *pBytesWritten = dwBytesWritten;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetOverlappedResult(OVERLAPPED &overlapped, DWORD &dwBytesTransferred, BOOL bWait)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if(!::GetOverlappedResult(m_hComm, &overlapped, &dwBytesTransferred, bWait))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetOverlappedResult, Failed in call to GetOverlappedResult, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"GetOverlappedResult失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ AFXASSUME(lpOverlapped);
|
|
|
|
+
|
|
|
|
+ // Convert back to the C++ world
|
|
|
|
+ CSerialPort* pSerialPort = static_cast<CSerialPort*>(lpOverlapped->hEvent);
|
|
|
|
+ AFXASSUME(pSerialPort);
|
|
|
|
+
|
|
|
|
+ // Call the C++ function
|
|
|
|
+ pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::OnCompletion(DWORD /* dwErrorCode */, DWORD /* dwCount */, LPOVERLAPPED lpOverlapped)
|
|
|
|
+{
|
|
|
|
+ // Just free the memory which was previously allocated for the OVERLAPPED structure
|
|
|
|
+ delete lpOverlapped;
|
|
|
|
+
|
|
|
|
+ // Your derived classes can do something useful in OnCompletion, but don't forget to
|
|
|
|
+ // call CSerialPort::OnCompletion to ensure the memory is freed
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::CancelIO()
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if(m_lpfnCancelIO == NULL)
|
|
|
|
+ {
|
|
|
|
+ //TRACE(_T("CSerialPort::CancelIO, CancelIO function is not supported on this OS, You need to be running at least NT 4 or Win 98 to use this function\n"));
|
|
|
|
+// LOG4C((LOG_WARN,"CancelIO失败,m_lpfnCancelIO函数指针空"));
|
|
|
|
+ //ThrowSerialException(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(!m_lpfnCancelIO(m_hComm))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("Failed in call to CancelIO, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"CancelIO失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+DWORD CSerialPort::BytesWaiting()
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ // Check to see how many characters are unread
|
|
|
|
+ COMSTAT stat;
|
|
|
|
+ GetStatus(stat);
|
|
|
|
+ return stat.cbInQue;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+BOOL CSerialPort::DataWaiting(DWORD dwTimeout)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ // Setup to wait fo incoming data
|
|
|
|
+ DWORD dwOldMask;
|
|
|
|
+ GetMask(dwOldMask);
|
|
|
|
+ SetMask(EV_RXCHAR);
|
|
|
|
+
|
|
|
|
+ // Setup the overlapped structure
|
|
|
|
+ OVERLAPPED overlapped;
|
|
|
|
+ overlapped.hEvent = m_hEvent;
|
|
|
|
+
|
|
|
|
+ // Assume the worst
|
|
|
|
+ BOOL bSuccess = FALSE;
|
|
|
|
+
|
|
|
|
+ DWORD dwEvent;
|
|
|
|
+ bSuccess = WaitEvent(dwEvent, overlapped);
|
|
|
|
+ if(!bSuccess)
|
|
|
|
+ {
|
|
|
|
+ if(WaitForSingleObject(overlapped.hEvent, dwTimeout) == WAIT_OBJECT_0)
|
|
|
|
+ {
|
|
|
|
+ DWORD dwBytesTransferred;
|
|
|
|
+ GetOverlappedResult(overlapped, dwBytesTransferred, FALSE);
|
|
|
|
+ bSuccess = TRUE;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Reset the event mask
|
|
|
|
+ SetMask(dwOldMask);
|
|
|
|
+
|
|
|
|
+ return bSuccess;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::WriteEx(const void *lpBuf, DWORD dwCount)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ OVERLAPPED* pOverlapped = new OVERLAPPED;
|
|
|
|
+ memset(pOverlapped, 0, sizeof(OVERLAPPED));
|
|
|
|
+ pOverlapped->hEvent = static_cast<HANDLE>(this);
|
|
|
|
+ if(!WriteFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ delete pOverlapped;
|
|
|
|
+ //TRACE(_T("CSerialPort::WriteEx, Failed in call to WriteFileEx, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"WriteEx失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::ReadEx(void *lpBuf, DWORD dwCount)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ OVERLAPPED* pOverlapped = new OVERLAPPED;
|
|
|
|
+ memset(pOverlapped, 0, sizeof(OVERLAPPED));
|
|
|
|
+ pOverlapped->hEvent = static_cast<HANDLE>(this);
|
|
|
|
+ if(!ReadFileEx(m_hComm, lpBuf, dwCount, pOverlapped, _OnCompletion))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ delete pOverlapped;
|
|
|
|
+ //TRACE(_T("CSerialPort::ReadEx, Failed in call to ReadFileEx, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"ReadEx失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::TransmitChar(char cChar)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if(!TransmitCommChar(m_hComm, cChar))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::TransmitChar, Failed in call to TransmitCommChar, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"TransmitCommChar失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetConfig(COMMCONFIG &config)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ DWORD dwSize = sizeof(COMMCONFIG);
|
|
|
|
+ if(!GetCommConfig(m_hComm, &config, &dwSize))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetConfig, Failed in call to GetCommConfig, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"GetCommConfig失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetConfig(COMMCONFIG &config)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ DWORD dwSize = sizeof(COMMCONFIG);
|
|
|
|
+ if(!SetCommConfig(m_hComm, &config, dwSize))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::SetConfig, Failed in call to SetCommConfig, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"SetCommConfig失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetBreak()
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if(!SetCommBreak(m_hComm))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::SetBreak, Failed in call to SetCommBreak, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"SetCommBreak失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::ClearBreak()
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if(!ClearCommBreak(m_hComm))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::ClearBreak, Failed in call to ClearCommBreak, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"ClearCommBreak失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::ClearError(DWORD &dwErrors)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if(!ClearCommError(m_hComm, &dwErrors, NULL))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::ClearError, Failed in call to ClearCommError, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"ClearCommError失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetDefaultConfig(int nPort, COMMCONFIG &config)
|
|
|
|
+{
|
|
|
|
+ // Create the device name as a string
|
|
|
|
+ CString strPort;
|
|
|
|
+ strPort.Format(_T("COM%d"), nPort);
|
|
|
|
+
|
|
|
|
+ DWORD dwSize = sizeof(COMMCONFIG);
|
|
|
|
+ if(!GetDefaultCommConfig(strPort, &config, &dwSize))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetDefaultConfig, Failed in call to GetDefaultCommConfig, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"GetDefaultCommConfig失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetDefaultConfig(int nPort, COMMCONFIG &config)
|
|
|
|
+{
|
|
|
|
+ // Create the device name as a string
|
|
|
|
+ CString strPort;
|
|
|
|
+ strPort.Format(_T("COM%d"), nPort);
|
|
|
|
+
|
|
|
|
+ DWORD dwSize = sizeof(COMMCONFIG);
|
|
|
|
+ if(!SetDefaultCommConfig(strPort, &config, dwSize))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::SetDefaultConfig, Failed in call to SetDefaultCommConfig, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"SetDefaultConfig失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetStatus(COMSTAT &stat)
|
|
|
|
+{
|
|
|
|
+ // Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ DWORD dwErrors;
|
|
|
|
+ if (!ClearCommError(m_hComm, &dwErrors, &stat))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetStatus, Failed in call to ClearCommError, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"ClearCommError失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetState(DCB &dcb)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!GetCommState(m_hComm, &dcb))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetState, Failed in call to GetCommState, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"GetCommState失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetState(DCB &dcb)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!SetCommState(m_hComm, &dcb))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::SetState, Failed in call to SetCommState, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"SetState失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Escape(DWORD dwFunc)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!EscapeCommFunction(m_hComm, dwFunc))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::Escape, Failed in call to EscapeCommFunction, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"Escape失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::ClearDTR()
|
|
|
|
+{
|
|
|
|
+ Escape(CLRDTR);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::ClearRTS()
|
|
|
|
+{
|
|
|
|
+ Escape(CLRRTS);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetDTR()
|
|
|
|
+{
|
|
|
|
+ Escape(SETDTR);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetRTS()
|
|
|
|
+{
|
|
|
|
+ Escape(SETRTS);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetXOFF()
|
|
|
|
+{
|
|
|
|
+ Escape(SETXOFF);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetXON()
|
|
|
|
+{
|
|
|
|
+ Escape(SETXON);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetProperties(COMMPROP& properties)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!GetCommProperties(m_hComm, &properties))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetProperties, Failed in call to GetCommProperties, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"GetProperties失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetModemStatus(DWORD& dwModemStatus)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!GetCommModemStatus(m_hComm, &dwModemStatus))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetModemStatus, Failed in call to GetCommModemStatus, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"GetModemStatus失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetMask(DWORD dwMask)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!SetCommMask(m_hComm, dwMask))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::SetMask, Failed in call to SetCommMask, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"SetMask失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetMask(DWORD& dwMask)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!GetCommMask(m_hComm, &dwMask))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetMask, Failed in call to GetCommMask, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"GetMask失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Flush()
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!FlushFileBuffers(m_hComm))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::Flush, Failed in call to FlushFileBuffers, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"Flush失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Purge(DWORD dwFlags)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!PurgeComm(m_hComm, dwFlags))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::Purge, Failed in call to PurgeComm, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"Purge失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::TerminateOutstandingWrites()
|
|
|
|
+{
|
|
|
|
+ Purge(PURGE_TXABORT);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::TerminateOutstandingReads()
|
|
|
|
+{
|
|
|
|
+ Purge(PURGE_RXABORT);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::ClearWriteBuffer()
|
|
|
|
+{
|
|
|
|
+ Purge(PURGE_TXCLEAR);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::ClearReadBuffer()
|
|
|
|
+{
|
|
|
|
+ Purge(PURGE_RXCLEAR);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Setup(DWORD dwInQueue, DWORD dwOutQueue)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!SetupComm(m_hComm, dwInQueue, dwOutQueue))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::Setup, Failed in call to SetupComm, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"Setup失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::SetTimeouts(COMMTIMEOUTS& timeouts)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!SetCommTimeouts(m_hComm, &timeouts))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::SetTimeouts, Failed in call to SetCommTimeouts, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"SetTimeouts失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::GetTimeouts(COMMTIMEOUTS& timeouts)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!GetCommTimeouts(m_hComm, &timeouts))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::GetTimeouts, Failed in call to GetCommTimeouts, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"GetTimeouts失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Set0Timeout()
|
|
|
|
+{
|
|
|
|
+ COMMTIMEOUTS Timeouts;
|
|
|
|
+ memset(&Timeouts, 0, sizeof(Timeouts));
|
|
|
|
+ Timeouts.ReadIntervalTimeout = MAXDWORD;
|
|
|
|
+ SetTimeouts(Timeouts);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Set0WriteTimeout()
|
|
|
|
+{
|
|
|
|
+ COMMTIMEOUTS Timeouts;
|
|
|
|
+ GetTimeouts(Timeouts);
|
|
|
|
+ Timeouts.WriteTotalTimeoutMultiplier = 0;
|
|
|
|
+ Timeouts.WriteTotalTimeoutConstant = 0;
|
|
|
|
+ SetTimeouts(Timeouts);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::Set0ReadTimeout()
|
|
|
|
+{
|
|
|
|
+ COMMTIMEOUTS Timeouts;
|
|
|
|
+ GetTimeouts(Timeouts);
|
|
|
|
+ Timeouts.ReadIntervalTimeout = MAXDWORD;
|
|
|
|
+ Timeouts.ReadTotalTimeoutMultiplier = 0;
|
|
|
|
+ Timeouts.ReadTotalTimeoutConstant = 0;
|
|
|
|
+ SetTimeouts(Timeouts);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void CSerialPort::WaitEvent(DWORD& dwMask)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+
|
|
|
|
+ if (!WaitCommEvent(m_hComm, &dwMask, NULL))
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::WaitEvent, Failed in call to WaitCommEvent, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"WaitEvent失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+BOOL CSerialPort::WaitEvent(DWORD& dwMask, OVERLAPPED& overlapped)
|
|
|
|
+{
|
|
|
|
+ //Validate our parameters
|
|
|
|
+ ASSERT(IsOpen());
|
|
|
|
+ ASSERT(overlapped.hEvent);
|
|
|
|
+
|
|
|
|
+ BOOL bSuccess = WaitCommEvent(m_hComm, &dwMask, &overlapped);
|
|
|
|
+ if (!bSuccess)
|
|
|
|
+ {
|
|
|
|
+ DWORD dwLastError = GetLastError();
|
|
|
|
+ //TRACE(_T("CSerialPort::WaitEvent, Failed in call to WaitCommEvent, Error:%d\n"), dwLastError);
|
|
|
|
+// LOG4C((LOG_WARN,"WaitEvent失败,GetLastError=%ld", dwLastError));
|
|
|
|
+ //ThrowSerialException(dwLastError);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return bSuccess;
|
|
|
|
+}
|