1199 lines
27 KiB
C++
1199 lines
27 KiB
C++
// SComPort.cpp: implementation of the CSComPort class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "SComPort.h"
|
|
|
|
#include "GeoMative.h"
|
|
#include "FileOperTools.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
OVERLAPPED rOverLaped = {0};
|
|
OVERLAPPED wOverLaped = {0};
|
|
|
|
OVERLAPPED rZModemOverLaped = {0};
|
|
|
|
extern CGeoMativeApp theApp;
|
|
extern SYSTEMTIME g_sysCurTime;
|
|
extern int g_iTransMode;
|
|
extern void TransDelay(int iTransMode, int iDS0, int iDS1, HWND hWnd = NULL);
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
CSComPort::CSComPort()
|
|
{
|
|
m_szComName = _T("");
|
|
|
|
// memset(&m_CriticalSection, 0 ,sizeof(CRITICAL_SECTION));
|
|
|
|
memset(&m_dcbBlock, 0, sizeof(DCB));
|
|
m_hCom = NULL;
|
|
|
|
memset(m_aWriteBuffer, 0, WRITEBUFFER_SIZE);
|
|
m_iWriteSize = 0;
|
|
|
|
memset(m_aReadBuffer, 0, READBUFFER_SIZE);
|
|
m_iReadSize = 0;
|
|
|
|
m_dwBLThreadID = 0;
|
|
m_hBLThread = NULL;
|
|
|
|
m_hOwnerWnd = NULL;
|
|
m_lCommID = 0;
|
|
|
|
m_bIsDetBreakFun = FALSE;
|
|
m_bIsScanBreak = TRUE;
|
|
|
|
m_dwFactdata = 0;
|
|
m_Log = fopen("LOG\\commLog.txt","ab+");
|
|
|
|
}
|
|
|
|
|
|
CSComPort::CSComPort(HWND hOwnerWnd, long lCommID)
|
|
{
|
|
m_szComName = _T("");
|
|
|
|
memset(&m_dcbBlock, 0, sizeof(DCB));
|
|
m_hCom = NULL;
|
|
|
|
memset(m_aWriteBuffer, 0, WRITEBUFFER_SIZE);
|
|
m_iWriteSize = 0;
|
|
|
|
memset(m_aReadBuffer, 0, READBUFFER_SIZE);
|
|
m_iReadSize = 0;
|
|
|
|
m_dwBLThreadID = 0;
|
|
m_hBLThread = NULL;
|
|
|
|
m_hOwnerWnd = hOwnerWnd;
|
|
m_lCommID = lCommID;
|
|
|
|
m_bIsScanBreak = TRUE;
|
|
|
|
m_dwFactdata = 0;
|
|
m_Log = fopen("LOG\\commLog.txt","ab+");
|
|
|
|
}
|
|
|
|
CSComPort::~CSComPort()
|
|
{
|
|
fclose(m_Log);
|
|
CloseComm();
|
|
}
|
|
|
|
BOOL CSComPort::FindComName(CStringArray *pStringArray)
|
|
{
|
|
HKEY hKey = NULL;
|
|
long lRes = 0;
|
|
char aPortName[256] = {0};
|
|
char aComName[256] = {0};
|
|
DWORD dwIndex = 0;
|
|
DWORD dwSize = 0;
|
|
DWORD dwType = REG_SZ;
|
|
|
|
if (NULL != pStringArray)
|
|
{
|
|
pStringArray->RemoveAll();
|
|
|
|
lRes = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Hardware\\DeviceMap\\SerialComm"), NULL, KEY_READ, &hKey);
|
|
if ( ERROR_SUCCESS == lRes )
|
|
{
|
|
dwSize = sizeof(aPortName);
|
|
|
|
while (::RegEnumValue(hKey, dwIndex, aPortName, &dwSize, NULL, &dwType, (LPBYTE)aComName, &dwSize) == ERROR_MORE_DATA)
|
|
{
|
|
pStringArray->Add(aComName);
|
|
|
|
dwSize = sizeof(aPortName);
|
|
dwIndex++;
|
|
}
|
|
::RegCloseKey(hKey);
|
|
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CSComPort::OpenComm(CString szComName)
|
|
{
|
|
unsigned long uParam = 0;
|
|
|
|
if (NULL == m_hCom)
|
|
{
|
|
m_szComName = _T("");
|
|
|
|
memset(&m_dcbBlock, 0, sizeof(DCB));
|
|
m_hCom = NULL;
|
|
|
|
memset(m_aWriteBuffer, 0, WRITEBUFFER_SIZE);
|
|
m_iWriteSize = 0;
|
|
|
|
memset(m_aReadBuffer, 0, READBUFFER_SIZE);
|
|
m_iReadSize = 0;
|
|
|
|
m_bIsDetBreakFun = FALSE;
|
|
|
|
if (4 == szComName.GetLength())
|
|
{
|
|
m_szComName = szComName;
|
|
}
|
|
else if (szComName.GetLength() > 4)
|
|
{
|
|
m_szComName = _T("\\\\.\\") + szComName;
|
|
}
|
|
|
|
|
|
this->m_hCom = CreateFile(m_szComName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
if (INVALID_HANDLE_VALUE == this->m_hCom)
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle(m_hCom);
|
|
m_hCom = NULL;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
SetupComm(this->m_hCom, READBUFFER_SIZE, WRITEBUFFER_SIZE);
|
|
|
|
memset(&m_dcbBlock, 0, sizeof(DCB));
|
|
GetCommState(this->m_hCom, &m_dcbBlock);
|
|
|
|
m_dcbBlock.BaudRate = CBR_115200;
|
|
m_dcbBlock.fBinary = TRUE;
|
|
m_dcbBlock.fParity = FALSE;
|
|
m_dcbBlock.ByteSize = 8;
|
|
m_dcbBlock.Parity = NOPARITY;
|
|
m_dcbBlock.StopBits = ONESTOPBIT;
|
|
|
|
if (!SetCommState(this->m_hCom, &m_dcbBlock))
|
|
{
|
|
CloseHandle(m_hCom);
|
|
m_hCom = NULL;
|
|
|
|
// AfxMessageBox(_T("Setup State is failed!"));
|
|
TRACE(_T("Setup State is failed!\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
if (!SetCommMask(this->m_hCom, EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY))
|
|
{
|
|
CloseHandle(m_hCom);
|
|
m_hCom = NULL;
|
|
// AfxMessageBox(_T("Setup mask is failed"));
|
|
TRACE(_T("Setup mask is failed\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
/*waston_0429
|
|
if (TRUE == m_bIsScanBreak)
|
|
{
|
|
// TRACE("OK1\n");
|
|
m_bIsDetBreakFun = FALSE;
|
|
m_dwBLThreadID = 0;
|
|
uParam = (unsigned long)this;
|
|
m_hBLThread = NULL;
|
|
m_hBLThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SComPortDetectBreakThreadFun, (void *)uParam, 0, &m_dwBLThreadID);
|
|
if (INVALID_HANDLE_VALUE == m_hBLThread)
|
|
{
|
|
CloseHandle(m_hBLThread);
|
|
CloseHandle(m_hCom);
|
|
m_hCom = NULL;
|
|
|
|
// AfxMessageBox("To create thread fail!");
|
|
TRACE(_T("To create scan break line thread fail!"));
|
|
return FALSE;
|
|
}
|
|
CloseHandle(m_hBLThread);
|
|
// TRACE("OK2\n");
|
|
}
|
|
*/
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
UINT CSComPort::SComPortDetectBreakThreadFun(LPVOID pParam)
|
|
{
|
|
CSComPort* pSComPort = (CSComPort*)pParam;
|
|
|
|
HANDLE hCom = NULL;
|
|
DWORD dwError = 0;
|
|
|
|
while (!(pSComPort->m_bIsDetBreakFun))
|
|
{
|
|
hCom = NULL;
|
|
hCom = CreateFile(pSComPort->m_szComName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
if (INVALID_HANDLE_VALUE == hCom)
|
|
{
|
|
dwError = GetLastError();
|
|
if (ERROR_FILE_NOT_FOUND == dwError)
|
|
{
|
|
pSComPort->m_bIsDetBreakFun = TRUE;
|
|
pSComPort->CloseComm();
|
|
::SendMessage(pSComPort->m_hOwnerWnd, WM_BREAKLINE, 0, pSComPort->m_lCommID);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CloseHandle(hCom);
|
|
hCom = NULL;
|
|
}
|
|
Sleep(50);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CSComPort::SetOwnerWnd(HWND hOwnerWnd)
|
|
{
|
|
this->m_hOwnerWnd = hOwnerWnd;
|
|
}
|
|
|
|
void CSComPort::SetCommID(long lCommID)
|
|
{
|
|
m_lCommID = lCommID;
|
|
}
|
|
|
|
void CSComPort::CloseComm()
|
|
{
|
|
m_bIsDetBreakFun = TRUE;
|
|
Sleep(50);
|
|
|
|
memset(m_aWriteBuffer, 0, WRITEBUFFER_SIZE);
|
|
m_iWriteSize = 0;
|
|
|
|
memset(m_aReadBuffer, 0, READBUFFER_SIZE);
|
|
m_iReadSize = 0;
|
|
|
|
if (NULL != m_hCom)
|
|
{
|
|
PurgeComm(m_hCom, PURGE_TXCLEAR | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_RXABORT);
|
|
CloseHandle(m_hCom);
|
|
m_hCom = NULL;
|
|
}
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
/*
|
|
关于对GetOverlappedResult的注解
|
|
第一个参数hFile其实不是用来完成IO的,而是用来同步的,其地位和第二个参数的某成员hEvent相同!
|
|
其内部代码如下:
|
|
hObject = lpOverlapped->hEvent ? lpOverlapped->hEvent : hFile; //here is the fucking trap
|
|
WaitStatus = WaitForSingleObject(hObject, INFINITE);
|
|
|
|
如上述代码所示,如果lpOverlapped->hEvent为空,则拿hFile作为同步的object,若lpOverlapped->hEvent不为空,那
|
|
么可怜的hFile根本一点用都没有!
|
|
If the hEvent member of the OVERLAPPED structure is NULL, the system uses the state of the hFile handle to signal
|
|
when the operation has been completed. Use of file, named pipe, or communications-device handles for this purpose is discouraged.
|
|
It is safer to use an event object because of the confusion that can occur when multiple simultaneous
|
|
overlapped operations are performed on the same file, named pipe, or communications device. In this situation,
|
|
there is no way to know which operation caused the object's state to be signaled.
|
|
*/
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
BOOL CSComPort::ReceiveDataDirectly(char *pDataBuff, int* iDataSize)
|
|
{
|
|
if (NULL == m_hCom)
|
|
{
|
|
return FALSE;
|
|
}
|
|
DWORD dwMaxBytesRead=1024;
|
|
DWORD dwNeedReadBytes = 0;
|
|
DWORD dwReadedBytes = 0;
|
|
BOOL bReadStatus;
|
|
DWORD dwErrorFlags = 0;
|
|
COMSTAT ComStat;
|
|
DWORD res = 0;
|
|
OVERLAPPED tOverLaped= {0};
|
|
memset(&ComStat, 0, sizeof(ComStat));
|
|
CString strLog = _T("");
|
|
|
|
if (TRUE != ClearCommError(m_hCom,&dwErrorFlags,&ComStat))
|
|
{
|
|
strLog.Format(_T("ClearCommError Error, errorno = %d, res = %d, InQue = %d"), GetLastError(), dwErrorFlags, ComStat.cbInQue);
|
|
PrintLogLast(strLog);
|
|
}
|
|
|
|
if (0 == ComStat.cbInQue)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
dwNeedReadBytes=min(dwMaxBytesRead,(DWORD)ComStat.cbInQue);
|
|
bReadStatus=ReadFile(m_hCom, pDataBuff, dwNeedReadBytes, &dwReadedBytes,&tOverLaped);
|
|
BOOL bResult = false;
|
|
if(!bReadStatus) //如果ReadFile函数返回FALSE
|
|
{
|
|
if(GetLastError()==ERROR_IO_PENDING)
|
|
{
|
|
//GetOverlappedResult查询异步操作是否完成,直到异步操作完成或者出错的情况下返回
|
|
if (GetOverlappedResult(m_hCom, &tOverLaped, &dwReadedBytes, TRUE))
|
|
{
|
|
if (dwReadedBytes != dwNeedReadBytes)
|
|
{
|
|
strLog.Empty();
|
|
strLog.Format(_T("[%d](ERROR)CSComPort::ReceiveBytes is not equal to NeedReadBytes,readbytes = %d,needreadybytes = %d!"),__LINE__,
|
|
dwReadedBytes, dwNeedReadBytes);
|
|
PrintLogLast(strLog);
|
|
}
|
|
*iDataSize = dwReadedBytes;
|
|
bResult = TRUE;
|
|
}
|
|
else
|
|
{
|
|
//log
|
|
strLog.Empty();
|
|
strLog.Format("[%d](ERROR)CSComPort::GetOverlappedResult failed,error = %d,,readbytes = %d,needreadybytes = %d!",
|
|
__LINE__, GetLastError(), dwReadedBytes, dwNeedReadBytes);
|
|
PrintLogLast(strLog);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
strLog.Empty();
|
|
strLog.Format("[%d](ERROR)CSComPort::the Result of ReadFile is error, errorid = %d",__LINE__, GetLastError());
|
|
PrintLogLast(strLog);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (dwReadedBytes != dwNeedReadBytes)
|
|
{
|
|
strLog.Empty();
|
|
strLog.Format(_T("[%d](ERROR)CSComPort::ReceiveBytes is not equal to NeedReadBytes in readfile,readbytes = %d,needreadybytes = %d!"),__LINE__,
|
|
dwReadedBytes, dwNeedReadBytes);
|
|
PrintLogLast(strLog);
|
|
}
|
|
*iDataSize = dwReadedBytes;
|
|
bResult = TRUE;
|
|
}
|
|
|
|
//打印日志
|
|
strLog.Empty();
|
|
strLog.AppendFormat(_T("CSComPort::ReceiveDataDirectly "));
|
|
for (int i = 0; i < *iDataSize; i++)
|
|
{
|
|
strLog.AppendFormat(_T("%02x "), (byte)pDataBuff[i]);
|
|
}
|
|
strLog.AppendFormat(_T("\n"));
|
|
CFileOperTools::GetInstance()->WriteComLog(strLog);
|
|
OutputDebugString(strLog);
|
|
|
|
// CString strRcv = pDataBuff;
|
|
// strLog.Empty();
|
|
// strLog.Format(_T("[%d]CSComPort::recvdata result is %d, recvbytes = %d, buf = %s"),__LINE__, bResult, dwReadedBytes, strRcv);
|
|
// PrintLogLast(strRcv);
|
|
|
|
return bResult;
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
/* DWORD dwRes = 0;
|
|
DWORD dwCurReadSize = 0;
|
|
COMSTAT comStat = {0};
|
|
OVERLAPPED Overlapped = {0};
|
|
OVERLAPPED tOverLaped= {0};
|
|
char aReadBuffer[READBUFFER_SIZE] = {0};
|
|
DWORD dwReadSize = 0;
|
|
DWORD dwEvtMask ,dwResult,dwByteNumber;
|
|
|
|
|
|
|
|
if (NULL != m_hCom)
|
|
{
|
|
|
|
// COMSTAT rst;
|
|
// DWORD res ;
|
|
// DWORD factdata;
|
|
// res = 0;
|
|
// factdata = 0;
|
|
// memset(&rst, 0, sizeof(rst));
|
|
// Sleep(200);
|
|
// // openLog();
|
|
//
|
|
// CString szLog = _T("");
|
|
// DWORD dwNeedRead = 100;
|
|
//
|
|
// if (TRUE != ClearCommError(m_hCom,&res,&rst))
|
|
// {
|
|
//
|
|
// // PrintLogLast("111");
|
|
// }
|
|
// else
|
|
// dwNeedRead = rst.cbInQue;
|
|
// CString strTest = _T("");
|
|
// strTest.Format(_T("cbInqueue = %d !"),dwNeedRead);
|
|
// AfxMessageBox(strTest);
|
|
|
|
|
|
|
|
tOverLaped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
WaitCommEvent(m_hCom, &dwEvtMask, &tOverLaped);//将事件和串口的动态联系起来
|
|
dwResult = WaitForSingleObject(tOverLaped.hEvent, COMM_TIMEOUT);
|
|
|
|
if (WAIT_OBJECT_0 == dwResult)
|
|
{
|
|
dwByteNumber = 0;
|
|
if (GetOverlappedResult(m_hCom, &tOverLaped, &dwByteNumber, TRUE))
|
|
{
|
|
CloseHandle(tOverLaped.hEvent);
|
|
|
|
if (dwByteNumber > 0)
|
|
{
|
|
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
ClearCommError(m_hCom, &dwRes, &comStat);
|
|
|
|
if (0 == comStat.cbInQue)
|
|
{
|
|
CloseHandle(Overlapped.hEvent);
|
|
return TRUE;
|
|
}
|
|
|
|
memset(m_aReadBuffer, 0, READBUFFER_SIZE);
|
|
memset(aReadBuffer, 0, READBUFFER_SIZE);
|
|
m_iReadSize = 0;
|
|
|
|
if (comStat.cbInQue >= READBUFFER_SIZE)
|
|
{
|
|
dwReadSize = READBUFFER_SIZE;
|
|
}
|
|
else
|
|
{
|
|
dwReadSize = comStat.cbInQue;
|
|
}
|
|
|
|
if (!ReadFile(m_hCom, aReadBuffer, dwReadSize, &dwCurReadSize, &Overlapped))
|
|
{
|
|
if (ERROR_IO_PENDING == GetLastError())
|
|
{
|
|
dwRes = WaitForSingleObject(Overlapped.hEvent, COMM_TIMEOUT);
|
|
if ((WAIT_FAILED == dwRes) || (WAIT_TIMEOUT == dwRes))
|
|
{
|
|
CloseHandle(Overlapped.hEvent);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
CloseHandle(Overlapped.hEvent);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// AfxMessageBox(pSComPort->m_aReadBuffer);
|
|
m_iReadSize = dwCurReadSize;
|
|
|
|
if (dwReadSize == dwCurReadSize)
|
|
{
|
|
memcpy(m_aReadBuffer, aReadBuffer, (UINT)dwCurReadSize);
|
|
memcpy(pDataBuff, m_aReadBuffer, (UINT)dwCurReadSize);
|
|
*iDataSize = m_iReadSize;
|
|
|
|
memset(m_aReadBuffer, 0, (UINT)dwCurReadSize);
|
|
m_iReadSize = 0;
|
|
|
|
CloseHandle(Overlapped.hEvent);
|
|
return TRUE;
|
|
}
|
|
|
|
CloseHandle(Overlapped.hEvent);
|
|
}
|
|
}
|
|
}
|
|
SetLastError(ERROR_TIMEOUT);
|
|
CloseHandle(tOverLaped.hEvent);
|
|
}
|
|
|
|
|
|
return FALSE;
|
|
*/
|
|
//////////////////////////////////////////////////////////////////////////
|
|
}
|
|
|
|
BOOL CSComPort::SendDataDirectly(char *pDataBuff, int iDataSize)
|
|
{
|
|
unsigned long uCurWriteSize = 0;
|
|
DWORD dwRes = 0;
|
|
OVERLAPPED Overlapped = {0};
|
|
|
|
if (NULL == m_hCom)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (NULL == pDataBuff)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
memset(&Overlapped, 0, sizeof(OVERLAPPED));
|
|
memset(m_aWriteBuffer, 0, WRITEBUFFER_SIZE);
|
|
|
|
m_iWriteSize = iDataSize;
|
|
memcpy(m_aWriteBuffer, pDataBuff, iDataSize);
|
|
|
|
//打印日志
|
|
CString strLog;
|
|
strLog.AppendFormat(_T("CSComPort::SendDataDirectly"));
|
|
for (int i = 0; i < iDataSize; i++)
|
|
{
|
|
strLog.AppendFormat(_T("%02x "), (byte)pDataBuff[i]);
|
|
}
|
|
strLog.AppendFormat("\n");
|
|
CFileOperTools::GetInstance()->WriteComLog(strLog);
|
|
//OutputDebugString(strLog);
|
|
|
|
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
if (!WriteFile(m_hCom, m_aWriteBuffer, m_iWriteSize, &uCurWriteSize, (LPOVERLAPPED)&Overlapped))
|
|
{
|
|
dwRes = WaitForSingleObject(Overlapped.hEvent, 500);
|
|
|
|
CloseHandle(Overlapped.hEvent);
|
|
|
|
if (WAIT_OBJECT_0 != dwRes)
|
|
{
|
|
// PurgeComm(m_hCom, PURGE_TXCLEAR);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void CSComPort::SetScanBreakSign(BOOL bIsScanBreak)
|
|
{
|
|
m_bIsScanBreak = bIsScanBreak;
|
|
}
|
|
|
|
|
|
void CSComPort::ClearCommSendBuff()
|
|
{
|
|
PurgeComm(m_hCom, PURGE_TXCLEAR | PURGE_TXABORT);
|
|
memset(m_aWriteBuffer, 0, WRITEBUFFER_SIZE);
|
|
}
|
|
|
|
void CSComPort::ClearCommReceiveBuff()
|
|
{
|
|
PurgeComm(m_hCom, PURGE_RXCLEAR | PURGE_RXABORT);
|
|
memset(m_aReadBuffer, 0, READBUFFER_SIZE);
|
|
}
|
|
|
|
/*
|
|
BOOL CSComPort::ZmodemReceiveDataDirectly(char *pDataBuff, int *iDataSize)
|
|
{
|
|
|
|
#define READBUFFER_SIZE 8192
|
|
DWORD m_iReadSize = 0;
|
|
// char m_aReadBuffer[READBUFFER_SIZE];
|
|
|
|
DWORD dwRes = 0;
|
|
DWORD dwCurReadSize = 0;
|
|
COMSTAT comStat = {0};
|
|
OVERLAPPED Overlapped = {0};
|
|
OVERLAPPED tOverLaped= {0};
|
|
char aReadBuffer[READBUFFER_SIZE] = {0};
|
|
DWORD dwReadSize = 0;
|
|
DWORD dwEvtMask ,dwResult,dwByteNumber;
|
|
|
|
|
|
if (NULL != m_hCom)
|
|
{
|
|
tOverLaped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
WaitCommEvent(m_hCom, &dwEvtMask, &tOverLaped);//将事件和串口的动态联系起来
|
|
dwResult = WaitForSingleObject(tOverLaped.hEvent, 200);
|
|
|
|
if (WAIT_OBJECT_0 == dwResult)
|
|
{
|
|
dwByteNumber = 0;
|
|
if (GetOverlappedResult(m_hCom, &tOverLaped, &dwByteNumber, TRUE))
|
|
{
|
|
if (dwByteNumber > 0)
|
|
{
|
|
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
ClearCommError(m_hCom, &dwRes, &comStat);
|
|
|
|
if (0 == comStat.cbInQue)
|
|
{
|
|
CloseHandle(Overlapped.hEvent);
|
|
return TRUE;
|
|
}
|
|
|
|
memset(aReadBuffer, 0, READBUFFER_SIZE);
|
|
m_iReadSize = 0;
|
|
|
|
if (comStat.cbInQue >= READBUFFER_SIZE)
|
|
{
|
|
dwReadSize = READBUFFER_SIZE;
|
|
}
|
|
else
|
|
{
|
|
dwReadSize = comStat.cbInQue;
|
|
}
|
|
|
|
if (!ReadFile(m_hCom, aReadBuffer, dwReadSize, &dwCurReadSize, &Overlapped))
|
|
{
|
|
if (ERROR_IO_PENDING == GetLastError())
|
|
{
|
|
dwRes = WaitForSingleObject(Overlapped.hEvent, 200);
|
|
PurgeComm(m_hCom, PURGE_RXCLEAR);
|
|
|
|
if (WAIT_FAILED == dwRes)
|
|
{
|
|
CloseHandle(Overlapped.hEvent);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CloseHandle(Overlapped.hEvent);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// AfxMessageBox(pSComPort->m_aReadBuffer);
|
|
// PurgeComm(m_hCom, PURGE_RXCLEAR);
|
|
m_iReadSize = dwCurReadSize;
|
|
|
|
if (dwReadSize == dwCurReadSize)
|
|
{
|
|
memcpy(aReadBuffer, aReadBuffer, (UINT)dwCurReadSize);
|
|
memcpy(pDataBuff, aReadBuffer, (UINT)dwCurReadSize);
|
|
*iDataSize = m_iReadSize;
|
|
|
|
memset(aReadBuffer, 0, (UINT)dwCurReadSize);
|
|
m_iReadSize = 0;
|
|
|
|
CloseHandle(Overlapped.hEvent);
|
|
return TRUE;
|
|
}
|
|
|
|
CloseHandle(Overlapped.hEvent);
|
|
|
|
}
|
|
|
|
}
|
|
CloseHandle(tOverLaped.hEvent);
|
|
}
|
|
|
|
|
|
}
|
|
return FALSE;
|
|
}
|
|
*/
|
|
|
|
/*
|
|
BOOL CSComPort::ZmodemSendDataDirectly(char *pDataBuff, int iDataSize)
|
|
{
|
|
if(WriteFile(m_hCom, pDataBuff, iDataSize, &m_dwFactdata, &wOverLaped) == TRUE)
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
*/
|
|
|
|
|
|
BOOL CSComPort::ZmodemSendDataDirectly(char *pDataBuff, int iDataSize)
|
|
{
|
|
OVERLAPPED wZModemOverLaped = {0};
|
|
|
|
char cReadLog[2048];
|
|
memset(cReadLog, 0, 2048);
|
|
DWORD factdata;
|
|
factdata = 0;
|
|
DWORD res;
|
|
wZModemOverLaped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
|
|
|
PurgeComm(m_hCom, PURGE_TXCLEAR);
|
|
|
|
if (WriteFile(m_hCom, pDataBuff, iDataSize, &factdata, &wZModemOverLaped))
|
|
{
|
|
// PurgeComm(m_hCom, PURGE_TXCLEAR);
|
|
CloseHandle(wZModemOverLaped.hEvent);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (GetLastError() == ERROR_IO_PENDING)
|
|
{
|
|
int nTimeOut = 0;
|
|
BOOL bStop = TRUE;
|
|
while(bStop)
|
|
{
|
|
res = WaitForSingleObject(wZModemOverLaped.hEvent,100);
|
|
switch (res)
|
|
{
|
|
case WAIT_OBJECT_0:
|
|
GetOverlappedResult(m_hCom, &wZModemOverLaped, &factdata, TRUE);
|
|
bStop = FALSE;
|
|
break;
|
|
case WAIT_TIMEOUT :
|
|
if (nTimeOut++ == 5)
|
|
{
|
|
bStop = FALSE;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// PurgeComm(m_hCom, PURGE_TXCLEAR);
|
|
CloseHandle(wZModemOverLaped.hEvent);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CSComPort::ZmodemReceiveDataDirectly(char *pDataBuff, int *iDataSize)
|
|
{
|
|
COMSTAT rst;
|
|
DWORD res ;
|
|
DWORD factdata;
|
|
res = 0;
|
|
factdata = 0;
|
|
memset(&rst, 0, sizeof(rst));
|
|
|
|
// openLog();
|
|
|
|
CString szLog = _T("");
|
|
DWORD dwNeedRead = 100;
|
|
|
|
if (TRUE != ClearCommError(m_hCom,&res,&rst))
|
|
{
|
|
szLog.Format(_T("ClearCommError Error, errorno = %d, res = %d, InQue = %d"), GetLastError(), res, rst.cbInQue);
|
|
PrintLogLast(szLog);
|
|
}
|
|
else
|
|
dwNeedRead = rst.cbInQue;
|
|
|
|
|
|
rZModemOverLaped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
|
|
|
// szLog.Format("begin--------------------------");
|
|
// PrintLogLast(szLog);
|
|
|
|
if (ReadFile(m_hCom, pDataBuff, dwNeedRead, &factdata, &rZModemOverLaped))
|
|
{
|
|
*iDataSize = factdata;
|
|
|
|
// if (0 == factdata)
|
|
// {
|
|
// //log
|
|
// szLog.Format("ReadFile = TRUE,rst.cbInQue = %d, factdata = %d",rst.cbInQue,factdata);
|
|
// PrintLogLast(szLog);
|
|
// //log
|
|
//
|
|
// }
|
|
|
|
|
|
PurgeComm(m_hCom, PURGE_RXCLEAR);
|
|
CloseHandle(rZModemOverLaped.hEvent);
|
|
|
|
// szLog.Format("end-----------------------------\r\n");
|
|
// PrintLogLast(szLog);
|
|
// closeLog();
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
if (dwError == ERROR_IO_PENDING)
|
|
{
|
|
int nTimeOut = 0;
|
|
BOOL bStop = TRUE;
|
|
|
|
//log
|
|
szLog.Format("ReadFile = FALSE,GetLastError = ERROR_IO_PENDING");
|
|
PrintLogLast(szLog);
|
|
//log
|
|
|
|
while(bStop)
|
|
{
|
|
res = WaitForSingleObject(rZModemOverLaped.hEvent,100);
|
|
switch (res)
|
|
{
|
|
case WAIT_OBJECT_0:
|
|
if (GetOverlappedResult(m_hCom, &rZModemOverLaped, &factdata, TRUE))
|
|
{
|
|
*iDataSize = factdata;
|
|
bStop = FALSE;
|
|
|
|
//log
|
|
szLog.Format("WaitForSingleObject = WAIT_OBJECT_0,GetOverlappedResult = TRUE, factdata = %d",factdata);
|
|
PrintLogLast(szLog);
|
|
//log
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
//log
|
|
szLog.Format("WaitForSingleObject = WAIT_OBJECT_0,GetOverlappedResult = FALSE, factdata = %d",factdata);
|
|
PrintLogLast(szLog);
|
|
//log
|
|
break;
|
|
}
|
|
case WAIT_TIMEOUT :
|
|
if (nTimeOut++ == 5)
|
|
{
|
|
bStop = FALSE;
|
|
}
|
|
//log
|
|
szLog.Format("WaitForSingleObject = WAIT_TIMEOUT,nTimeOut = %d",nTimeOut);
|
|
PrintLogLast(szLog);
|
|
//log
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//log
|
|
TCHAR szBuf[128];
|
|
LPVOID lpMsgBuf;
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
dwError,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPTSTR) &lpMsgBuf,
|
|
0, NULL );
|
|
wsprintf(szBuf,
|
|
_T("出错码:%d: %s"),
|
|
dwError, lpMsgBuf);
|
|
// AfxMessageBox(szBuf);
|
|
LocalFree(lpMsgBuf);
|
|
|
|
szLog.Format("ReadFile = FALSE,GetLastError = %d, desc: %s",GetLastError(),szBuf);
|
|
PrintLogLast(szLog);
|
|
//log
|
|
}
|
|
}
|
|
|
|
PurgeComm(m_hCom, PURGE_RXCLEAR);
|
|
CloseHandle(rZModemOverLaped.hEvent);
|
|
|
|
szLog.Format("end-----------------------------");
|
|
PrintLogLast(szLog);
|
|
|
|
// closeLog();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CSComPort::DetectLine()
|
|
{
|
|
unsigned long uParam = 0;
|
|
|
|
try
|
|
{
|
|
if (TRUE == m_bIsScanBreak)
|
|
{
|
|
// TRACE("OK1\n");
|
|
m_bIsDetBreakFun = FALSE;
|
|
m_dwBLThreadID = 0;
|
|
uParam = (unsigned long)this;
|
|
m_hBLThread = NULL;
|
|
m_hBLThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SComPortDetectBreakThreadFun, (void *)uParam, 0, &m_dwBLThreadID);
|
|
if (INVALID_HANDLE_VALUE == m_hBLThread)
|
|
{
|
|
CloseHandle(m_hBLThread);
|
|
CloseHandle(m_hCom);
|
|
m_hCom = NULL;
|
|
|
|
// AfxMessageBox("To create thread fail!");
|
|
TRACE(_T("To create scan break line thread fail!"));
|
|
return FALSE;
|
|
}
|
|
CloseHandle(m_hBLThread);
|
|
// TRACE("OK2\n");
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
void CSComPort::PrintLogLast(CString& strLog)
|
|
{
|
|
if (NULL == m_Log)
|
|
{
|
|
if (LANG_ZHCN == g_iUILanguage)
|
|
AfxMessageBox(_T("无法写入device_log,日志文件点为空"));
|
|
else
|
|
MessageBoxEx(NULL, _T("Can't write device_log, log File point is NULL"), _T("LOG_ERROR"), MB_OK, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
|
|
return;
|
|
}
|
|
CString strOutPut = _T("");
|
|
strOutPut.Format(_T("%04d-%02d-%02d %02d:%02d:%02d.%03d %s \r\n"),g_sysCurTime.wYear, g_sysCurTime.wMonth, g_sysCurTime.wDay,
|
|
g_sysCurTime.wHour, g_sysCurTime.wMinute, g_sysCurTime.wSecond, g_sysCurTime.wMilliseconds, strLog.GetBuffer(0));
|
|
fwrite(strOutPut.GetBuffer(0), 1, strOutPut.GetLength(), m_Log);
|
|
fflush(m_Log);
|
|
}
|
|
|
|
void CSComPort::openLog()
|
|
{
|
|
m_Log = fopen("log\\commLog.txt","ab+");
|
|
}
|
|
|
|
void CSComPort::closeLog()
|
|
{
|
|
fclose(m_Log);
|
|
}
|
|
|
|
|
|
|
|
//执行传给设备的指令: strOrder: 传给设备的指令 strSign:收到的结果, pStrResult:希望等待到的字符串,nRepeatCnt:重发指令的次数
|
|
BOOL CSComPort::ExecuteOrder(CString strOrder, CString strSign, CString *pStrResult, int nRepeatCnt)
|
|
{
|
|
for (int i = 0; i < nRepeatCnt; i++)
|
|
{
|
|
if (ExecuteSignleOrder(strOrder, strSign, pStrResult))
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
//执行单次设备指令: f_szOrder: 传给设备的指令 f_szResult:收到的结果,f_szSign:希望等待到的字符串
|
|
BOOL CSComPort::ExecuteSignleOrder(CString f_szOrder, CString f_szSign, CString *f_szResult)
|
|
{
|
|
//log
|
|
CString szlog = _T("");
|
|
DWORD dwBegin = GetTickCount();
|
|
|
|
//log
|
|
CString szOrder = _T("");
|
|
CString szResBuff = _T("");
|
|
|
|
int iPollingTime = (int)VAL_ZERO;
|
|
int iResSize = (int)VAL_ZERO;
|
|
char aResBuff[2048] = {0};
|
|
|
|
TransDelay(g_iTransMode, 10, 50, NULL);
|
|
|
|
//清空串口缓冲区
|
|
ClearCommSendBuff();
|
|
ClearCommReceiveBuff();
|
|
|
|
//判断设备是否等待就绪
|
|
szOrder.Empty();
|
|
szResBuff.Empty();
|
|
iResSize = (int)VAL_ZERO;
|
|
iPollingTime = (int)VAL_ZERO;
|
|
memset(aResBuff, 0, sizeof(aResBuff));
|
|
|
|
szOrder.Format(_T("\r\n"));
|
|
SendDataDirectly(szOrder.GetBuffer(szOrder.GetLength()), szOrder.GetLength());
|
|
|
|
//log
|
|
szlog.Empty();
|
|
szlog.Format("[%d] send %s, cost_ticks = %d",__LINE__,szOrder.GetBuffer(0), GetTickCount() - dwBegin);
|
|
PrintLogLast(szlog);
|
|
//log
|
|
|
|
while ((szResBuff.Find(">") == -1) && (iPollingTime < 100))
|
|
{
|
|
Sleep(3);
|
|
while (ReceiveDataDirectly(aResBuff, &iResSize) == TRUE)
|
|
{
|
|
szResBuff.Insert(szResBuff.GetLength(), aResBuff);
|
|
|
|
iResSize = (int)VAL_ZERO;
|
|
memset(aResBuff, 0, sizeof(aResBuff));
|
|
}
|
|
|
|
iPollingTime++;
|
|
if (iPollingTime % 25 == 0)//设备没有响应,准备重发,每循环25次就重发
|
|
{
|
|
szOrder.Format(_T("\r\n"));
|
|
SendDataDirectly(szOrder.GetBuffer(szOrder.GetLength()), szOrder.GetLength());
|
|
}
|
|
}
|
|
|
|
//log
|
|
szlog.Empty();
|
|
szlog.Format("[%d] recv %s, cost_ticks = %d",__LINE__,szResBuff.GetBuffer(0), GetTickCount() - dwBegin);
|
|
PrintLogLast(szlog);
|
|
//log
|
|
|
|
|
|
//设备没有响应
|
|
if (iPollingTime == 100 )
|
|
{
|
|
szlog.Empty();
|
|
if (szResBuff.IsEmpty())
|
|
{
|
|
szlog.Format("[%d] recv start_respose_cmd timeout",__LINE__);
|
|
PrintLogLast(szlog);
|
|
}
|
|
else
|
|
{
|
|
szlog.Format("[%d] recv wrong cmd_responses signal, cmd = %s",__LINE__,szResBuff.GetBuffer(0));
|
|
PrintLogLast(szlog);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
//设备准备局就绪,准备发送指令
|
|
ClearCommSendBuff();
|
|
ClearCommReceiveBuff();
|
|
|
|
//初始化值
|
|
szOrder.Empty();
|
|
szResBuff.Empty();
|
|
iResSize = (int)VAL_ZERO;
|
|
iPollingTime = (int)VAL_ZERO;
|
|
memset(aResBuff, 0, sizeof(aResBuff));
|
|
|
|
//发送指令
|
|
SendDataDirectly(f_szOrder.GetBuffer(f_szOrder.GetLength()), f_szOrder.GetLength());
|
|
|
|
//log
|
|
szlog.Empty();
|
|
szlog.Format("[%d] send %s, cost_ticks = %d",__LINE__,f_szOrder.GetBuffer(0), GetTickCount() - dwBegin);
|
|
PrintLogLast(szlog);
|
|
//log
|
|
|
|
while ((szResBuff.Find(f_szSign) == -1) && (iPollingTime < 100))
|
|
{
|
|
Sleep(3);
|
|
while (ReceiveDataDirectly(aResBuff, &iResSize) == TRUE)
|
|
{
|
|
szResBuff.Insert(szResBuff.GetLength(), aResBuff);
|
|
|
|
iResSize = (int)VAL_ZERO;
|
|
memset(aResBuff, 0, sizeof(aResBuff));
|
|
}
|
|
iPollingTime++;
|
|
}
|
|
|
|
|
|
|
|
if (iPollingTime == 100 )
|
|
{
|
|
//log
|
|
szlog.Empty();
|
|
szlog.Format("[%d] recv wrong cmd_responses_signal, cmd = %s",__LINE__,szResBuff.GetBuffer(0));
|
|
PrintLogLast(szlog);
|
|
//log
|
|
return FALSE;
|
|
}
|
|
f_szResult->Format("%s", szResBuff.GetBuffer(0));
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CSComPort::ExecuteNoResOrder(CString f_szOrder)
|
|
{
|
|
//log
|
|
CString szlog = _T("");
|
|
DWORD dwBegin = GetTickCount();
|
|
|
|
//log
|
|
CString szOrder = _T("");
|
|
CString szResBuff = _T("");
|
|
|
|
int iPollingTime = (int)VAL_ZERO;
|
|
int iResSize = (int)VAL_ZERO;
|
|
char aResBuff[2048] = {0};
|
|
|
|
TransDelay(g_iTransMode, 10, 50, NULL);
|
|
|
|
//清空串口缓冲区
|
|
ClearCommSendBuff();
|
|
ClearCommReceiveBuff();
|
|
|
|
//判断设备是否等待就绪
|
|
szOrder.Empty();
|
|
szResBuff.Empty();
|
|
iResSize = (int)VAL_ZERO;
|
|
iPollingTime = (int)VAL_ZERO;
|
|
memset(aResBuff, 0, sizeof(aResBuff));
|
|
|
|
szOrder.Format(_T("\r\n"));
|
|
SendDataDirectly(szOrder.GetBuffer(szOrder.GetLength()), szOrder.GetLength());
|
|
|
|
//log
|
|
szlog.Empty();
|
|
szlog.Format("[%d] send %s, cost_ticks = %d",__LINE__,szOrder.GetBuffer(0), GetTickCount() - dwBegin);
|
|
PrintLogLast(szlog);
|
|
//log
|
|
|
|
while ((szResBuff.Find(">") == -1) && (iPollingTime < 200))
|
|
{
|
|
Sleep(5);
|
|
while (ReceiveDataDirectly(aResBuff, &iResSize) == TRUE)
|
|
{
|
|
szResBuff.Insert(szResBuff.GetLength(), aResBuff);
|
|
|
|
iResSize = (int)VAL_ZERO;
|
|
memset(aResBuff, 0, sizeof(aResBuff));
|
|
}
|
|
|
|
iPollingTime++;
|
|
if (iPollingTime % 25 == 0)//设备没有响应,准备重发,每循环25次就重发
|
|
{
|
|
szOrder.Format(_T("\r\n"));
|
|
SendDataDirectly(szOrder.GetBuffer(szOrder.GetLength()), szOrder.GetLength());
|
|
}
|
|
}
|
|
|
|
//log
|
|
szlog.Empty();
|
|
szlog.Format("[%d] recv %s, cost_ticks = %d",__LINE__,szResBuff.GetBuffer(0), GetTickCount() - dwBegin);
|
|
PrintLogLast(szlog);
|
|
//log
|
|
|
|
|
|
//设备没有响应
|
|
if (iPollingTime == 200 )
|
|
{
|
|
szlog.Empty();
|
|
if (szResBuff.IsEmpty())
|
|
{
|
|
szlog.Format("[%d] recv start_respose_cmd timeout",__LINE__);
|
|
PrintLogLast(szlog);
|
|
}
|
|
else
|
|
{
|
|
szlog.Format("[%d] recv wrong cmd_responses signal, cmd = %s",__LINE__,szResBuff.GetBuffer(0));
|
|
PrintLogLast(szlog);
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
//设备准备局就绪,准备发送指令
|
|
ClearCommSendBuff();
|
|
ClearCommReceiveBuff();
|
|
|
|
//发送指令
|
|
SendDataDirectly(f_szOrder.GetBuffer(f_szOrder.GetLength()), f_szOrder.GetLength());
|
|
|
|
//log
|
|
szlog.Empty();
|
|
szlog.Format("[%d] send %s, cost_ticks = %d",__LINE__,f_szOrder.GetBuffer(0), GetTickCount() - dwBegin);
|
|
PrintLogLast(szlog);
|
|
|
|
return TRUE;
|
|
} |