📄 datacomm.cpp
字号:
// DataComm.cpp: implementation of the CDataComm class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <afxmt.h>
#include "CPacker.h"
#include <afxtempl.h>
#include "CChannel.h"
#include "CMultiplex.h"
#include "CDemultiplex.h"
#include "CByteBuffer.h"
#include "DataComm.h"
CDataComm::CDataComm(DWORD dwUserData,
pDataServiceCallBackFunc pCallBackFunc,
int nBaudRate,
int nInputBufferSize,
int nOutputBufferSize,
BOOL bDisplayError):m_InputBuffer(READ_BUFFER_SIZE)
{
m_dwUserData = dwUserData;
m_hComm=NULL;
ZeroMemory(&m_WriteOS,sizeof(OVERLAPPED));
ZeroMemory(&m_ReadOS,sizeof(OVERLAPPED));;
m_nPort=0;
m_bConnected=FALSE;
m_bDisplayError=bDisplayError;
m_nBaudRate=nBaudRate;
m_nInputBufferSize=nInputBufferSize;
m_nOutputBufferSize=nOutputBufferSize;
m_pCallBackFunc = pCallBackFunc;
m_dwThreadID=0;
m_hThread=NULL;
m_dwWriteThreadID=0;
m_hWriteThread=NULL;
m_dwReadThreadID=0;
m_hReadThread=NULL;
m_lpUserInstance=NULL;
m_uBlockSize=m_nOutputBufferSize/2;
if(m_uBlockSize>4096)
m_uBlockSize=4096;
m_uMiniBlockSize=100;
if(m_uMiniBlockSize>m_uBlockSize/2)
m_uMiniBlockSize=0;
m_hQuitEvent=NULL;
m_hWriteEvent=NULL;
m_hCTSEvent=NULL;
m_hReadEvent=NULL;
}
BOOL CDataComm::OpenComm(int nPortNumber,LPVOID lpUserInstance)
{
if(m_bConnected)return FALSE;
m_lpUserInstance=lpUserInstance;
m_nPort=nPortNumber;
if(!CreateTTYInfo())return FALSE;
m_hQuitEvent=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,TRUE,FALSE,NULL);
if(!m_hQuitEvent)return FALSE;
m_hWriteEvent=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,FALSE,TRUE,NULL);
if(!m_hWriteEvent)
{
CloseHandle(m_hQuitEvent);
m_hQuitEvent=0;
return FALSE;
}
m_hReadEvent=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,FALSE,FALSE,NULL);
if(!m_hReadEvent)
{
CloseHandle(m_hWriteEvent);
CloseHandle(m_hQuitEvent);
m_hWriteEvent=0;
m_hQuitEvent=0;
return FALSE;
}
m_hCTSEvent=CreateEvent((LPSECURITY_ATTRIBUTES)NULL,FALSE,FALSE,NULL);
if(!m_hCTSEvent)
{
CloseHandle(m_hWriteEvent);
CloseHandle(m_hQuitEvent);
CloseHandle(m_hReadEvent);
m_hWriteEvent=0;
m_hQuitEvent=0;
m_hReadEvent=0;
return FALSE;
}
if(!OpenConnection())
{
CloseHandle(m_hWriteEvent);
CloseHandle(m_hQuitEvent);
CloseHandle(m_hReadEvent);
CloseHandle(m_hCTSEvent);
m_hWriteEvent=0;
m_hQuitEvent=0;
m_hReadEvent=0;
m_hCTSEvent=0;
return FALSE;
}
return TRUE;
}
BOOL CDataComm::CreateTTYInfo()
{
m_WriteOS.Offset = 0 ;
m_WriteOS.OffsetHigh = 0 ;
m_ReadOS.Offset = 0 ;
m_ReadOS.OffsetHigh = 0 ;
// create I/O event used for overlapped reads / writes
m_ReadOS.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (m_ReadOS.hEvent == NULL)
return FALSE;
m_WriteOS.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (NULL == m_WriteOS.hEvent)
{
CloseHandle(m_ReadOS.hEvent ) ;
return FALSE;
}
return TRUE;
} // end of CreateTTYInfo()
DWORD FAR PASCAL DataCommWatchProc(CDataComm* pCommObject)
{
DWORD dwEvtMask ;
CDataComm* pComm= (CDataComm*)pCommObject;
OVERLAPPED os ;
int nLength ;
BYTE abIn[ MAXBLOCK + 1] ;
BOOL bIsFirst = TRUE;
int nTemp = 0;
//BYTE byAllData[MAXBLOCK + 1];
static int nAllDataLength = 0;
const BYTE TextDataTotalLength = 9;
const BYTE ElseDataTotalLength = 12;
const BYTE DataIsText[4] = {42, 42, 16, 187};
const BYTE DataIsCurve[4] = {42, 42, 16, 49};
const BYTE DataHeadLength = 4;
const BYTE ProgramStartHeadLength = 80;
memset( &os, 0, sizeof( OVERLAPPED ) ) ;
// create I/O event used for overlapped read
os.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (os.hEvent == NULL)
{
MessageBox( NULL, "Failed to create event for thread!", "TTY Error!",
MB_ICONEXCLAMATION | MB_OK ) ;
return ( FALSE ) ;
}
if (!SetCommMask(pComm->m_hComm, EV_RXCHAR|EV_RLSD|EV_TXEMPTY|EV_CTS))
return ( FALSE ) ;
while (pComm->m_bConnected)
{
dwEvtMask = 0 ;
WaitCommEvent(pComm->m_hComm, &dwEvtMask, NULL );
if((dwEvtMask & EV_TXEMPTY) == EV_TXEMPTY)//Now we can write
{
SetEvent(pComm->m_hWriteEvent);
}
if((dwEvtMask & EV_CTS) == EV_CTS)
{
SetEvent(pComm->m_hCTSEvent);
}
if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
::Sleep(200);//Waiting for all data
if(bIsFirst)
{
bIsFirst = FALSE;
nTemp = MAXBLOCK;
do{//Some program start information
if(nLength = (pComm->ReadCommBlock(abIn, nTemp)))
{
nTemp = ProgramStartHeadLength - nLength;
if(pComm->m_pCallBackFunc)
(*(pComm->m_pCallBackFunc))(abIn,(UINT)nLength, pComm->m_dwUserData);
}
if(nTemp)
::Sleep(100);
}while(nTemp > 0);
}
do
{
if (nLength = (pComm->ReadCommBlock(abIn, DataHeadLength)))
{
//if(nAllDataLength < MAXBLOCK)
// ::CopyMemory(byAllData + nAllDataLength, abIn, nLength);
//else
// AfxMessageBox("Some data packet lost\n");
//nAllDataLength += nLength;
if(::memcmp(DataIsText, abIn, DataHeadLength) == 0)//Is text
{
ASSERT( nLength == DataHeadLength);
nLength = pComm->ReadCommBlock(abIn + DataHeadLength, TextDataTotalLength - DataHeadLength);
ASSERT( nLength == (TextDataTotalLength - DataHeadLength));
if(pComm->m_pCallBackFunc)
(*(pComm->m_pCallBackFunc))(abIn,(UINT)TextDataTotalLength, pComm->m_dwUserData);
}
else if(::memcmp(DataIsCurve, abIn, DataHeadLength) == 0)//Is curve
{
ASSERT( nLength == DataHeadLength);
nLength = pComm->ReadCommBlock(abIn + DataHeadLength, ElseDataTotalLength - DataHeadLength);
ASSERT( nLength == (ElseDataTotalLength - DataHeadLength));
if(pComm->m_pCallBackFunc)
(*(pComm->m_pCallBackFunc))(abIn,(UINT)ElseDataTotalLength, pComm->m_dwUserData);
}
else//Is line, retangle, ellipse, brush
{
if(nLength = pComm->ReadCommBlock(abIn + DataHeadLength, MAXBLOCK - DataHeadLength))
{
if(pComm->m_pCallBackFunc)
(*(pComm->m_pCallBackFunc))(abIn,(UINT)nLength + DataHeadLength, pComm->m_dwUserData);
}
}
}
if(nLength > 0)
::Sleep(200);//Waiting for all data
}while ( nLength > 0 ) ;
//if((pComm->m_pCallBackFunc)&&(nAllDataLength > 0))
// (*(pComm->m_pCallBackFunc))(byAllData,(UINT)nAllDataLength, pComm->m_dwUserData);
//Test
/*
do
{
if (nLength = (pComm->ReadCommBlock(abIn, MAXBLOCK)))
{
if(pComm->m_pCallBackFunc)
(*(pComm->m_pCallBackFunc))(abIn,(UINT)nLength, pComm->m_dwUserData);
TRACE("%d\n\n", nLength);
for(int ij=0; ij<nLength; ij++)
TRACE("%d\t", abIn[ij]);
TRACE("\n\n");
}
if(nLength > 0)
::Sleep(100);//Waiting for all data
}while ( nLength > 0 ) ;
*/
//End test
//nAllDataLength = 0;
//::ZeroMemory(byAllData, MAXBLOCK + 1);
/*
do
{
if (nLength = (pComm->ReadCommBlock((LPSTR) abIn, MAXBLOCK )))
pComm->m_InputBuffer.AppendTail(abIn,nLength);
}
while ( nLength > 0 ) ;
*/
}
}
// get rid of event handle
CloseHandle( os.hEvent ) ;
// clear information in structure (kind of a "we're done flag")
pComm->m_dwThreadID = 0 ;
pComm->m_hThread = NULL ;
return( TRUE ) ;
} // end of CommWatchProc()
int CDataComm::ReadCommBlock(BYTE* lpszBlock, int nMaxLength )
{
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLength;
DWORD dwError;
char szError[ 10 ] ;
// only try to read number of bytes in queue
ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
if (dwLength > 0)
{
fReadStat = ReadFile(m_hComm, lpszBlock,
dwLength, &dwLength, &m_ReadOS) ;
if (!fReadStat)
{
if (GetLastError() == ERROR_IO_PENDING)
{
OutputDebugString("\n\rIO Pending");
// We have to wait for read to complete.
// This function will timeout according to the
// CommTimeOuts.ReadTotalTimeoutConstant variable
// Every time it times out, check for port errors
while(!GetOverlappedResult(m_hComm,&m_ReadOS, &dwLength, TRUE))
{
dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
// normal result if not finished
continue;
else
{
// an error occurred, try to recover
wsprintf( szError, "<CE-%u>", dwError ) ;
MessageBox(NULL,szError,"Read Error",MB_OK);
ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
if ((dwErrorFlags > 0) &&m_bDisplayError)
{
wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
MessageBox(NULL,szError,"Read Error",MB_OK);
}
break;
}
}
}
else
{
// some other error occurred
dwLength = 0 ;
ClearCommError(m_hComm, &dwErrorFlags, &ComStat ) ;
if ((dwErrorFlags > 0) &&m_bDisplayError)
{
wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
MessageBox(NULL,szError,"Read Error",MB_OK);
}
}
}
}
return ( dwLength ) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -