📄 devserver.cpp
字号:
// DevServer.cpp: implementation of the CDevServer class.
/// 设备驱动模版
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "math.h"
#include "OwnerArchive.h"
#include "DevDef.h"
#include "DevServer.h"
#include "mcgsrun.h"
#include "mcgsset.h"
#include "DevBas.h"
extern IMcgsset g_mcgsset;
extern IDataCentre g_datacentre;
#ifdef _UNICODE
#define MCGS_WCE
#else
#define MCGSSET_ESET
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDevServer::CDevServer()
{
}
CDevServer::~CDevServer()
{
}
/// 函数功能: 用于用于判断当前设备是否为有效的串口父设备。
/// 函数返回: TRUE,当前设备是有效的串口父设备,FALSE,不是有效的串口父设备。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针。
/// 备 注: 此函数时完成内嵌固有功能,不可修改。
///
inline BOOL CDevServer::mfIsCommDev(MCGS_DATA &data)
{
BOOL bReturn = TRUE;
if (data.m_ParentType != DEV_PARENT_TYPE_COMM)
{
bReturn = FALSE;
}
else
{
HANDLE hHandle = (HANDLE)data.m_pParentData;
if (hHandle == NULL || hHandle == INVALID_HANDLE_VALUE)
{
ASSERT(FALSE);
bReturn = FALSE;
}
}
return bReturn;
};
/// 函数功能: 用于用于判断当前设备是否为有效的TCP/IP父设备。
/// 函数返回: TRUE,当前设备是有效的TCP/IP父设备,FALSE,不是有效的TCP/IP父设备。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针。
/// 备 注: 此函数时完成内嵌固有功能,不可修改。
///
inline BOOL CDevServer::mfIsTcpipDev(MCGS_DATA &data)
{
BOOL bReturn = TRUE;
if (data.m_ParentType != DEV_PARENT_TYPE_TCPIP)
{
bReturn = FALSE;
}
else
{
HANDLE hHandle = (HANDLE)data.m_pParentData;
if (hHandle == NULL || hHandle == INVALID_HANDLE_VALUE)
{
ASSERT(FALSE);
bReturn = FALSE;
}
}
return bReturn;
};
/// 函数功能: 清空串口输入缓冲区。
/// 函数返回: 成功返回TRUE,失败返回FALSE。
/// 参数意义: 无。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
BOOL CDevServer::SvrClearCommInBuff(MCGS_DATA &data)
{
if (!mfIsCommDev(data))
{
return FALSE;
}
/// 清空输入缓冲区
return PurgeComm(data.m_pParentData, PURGE_RXCLEAR|PURGE_TXCLEAR);
}
/// 函数功能: 写串口函数,往串口写一个字符串,用重叠操作的方式。
/// 函数返回: 成功返回TRUE,失败返回FALSE。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针
/// byteArray 数组用来保存写到串口的数据。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
BOOL CDevServer::SvrWriteComm(MCGS_DATA &data, CByteArray& byteArray)
{
if (!mfIsCommDev(data))
{
return FALSE;
}
DWORD dwWrite = 0;
BOOL bRes = TRUE;
#ifdef MCGSSET_ESET
/// 这一段是在组态和模拟运行环境下用的代码
OVERLAPPED os;
memset(&os, 0, sizeof(OVERLAPPED));
os.Offset = 0;
os.OffsetHigh = 0;
if ((os.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
{
return FALSE;
}
BOOL bReturn = WriteFile(data.m_pParentData, byteArray.GetData(),
byteArray.GetSize(), &dwWrite, &os);
if (!bReturn)
{
if (GetLastError() != ERROR_IO_PENDING)
{
/// 写失败,且不是由于异步操作在后台进行引起的。
bRes = FALSE;
}
else
{
/// 异步操作在后台进行。
DWORD dwRes = WaitForSingleObject(os.hEvent, INFINITE);
switch(dwRes)
{
/// 重叠操作的事件信号已经被触发了。
case WAIT_OBJECT_0:
{
if (!GetOverlappedResult(data.m_pParentData, &os,
&dwWrite, FALSE))
{
bRes = FALSE;
}
else
{
/// 写操作成功。
bRes = TRUE;
}
}break;
default:
{
/// 在等待事件的过程中发生了一个错误。
bRes = FALSE;
}break;
}
}
}
CloseHandle(os.hEvent);
#endif //MCGSSET_ESET
#ifdef MCGS_WCE_EMU
/// 此段暂时不会调用到
#endif //MCGS_WCE_EMU
#ifdef MCGS_WCE
/// 这一段时运行环境下调用的代码
bRes = WriteFile(data.m_pParentData, byteArray.GetData(),
byteArray.GetSize(), &dwWrite, NULL);
#endif //MCGS_WCE
return bRes;
}
/// 函数功能: 读串口函数,从串口读一个字符串,用重叠操作的方式。
/// 函数返回: 成功返回读取的字节数,失败返回<=0。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针
/// byteArray 数组用来保存从串口读回来的数据。
/// dwDelayTime 用来保存超时值。
/// nInputFlag 读串口的结束方式
/// 0:收到ucStopChar所指定的字符马上结束。
/// 1:收到dwInputLen个字符后马上结束。
/// 2:Sleep(dwDelayTime)后接收串口所有数据,结束。
/// 3:满足0或1中的条件马上结束。如果操作的时间
/// 超过了dwDelayTime所指定的时间则无条件退出。
/// dwInputLen 要接收的长度。
/// ucStopChar 停止字符。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
int CDevServer::SvrReadComm(MCGS_DATA &data,
CByteArray& byteArray,
DWORD dwDelayTime,
int nInputFlag,
DWORD dwInputLen,
unsigned char ucStopChar)
{
byteArray.SetSize(0);
int nReturn = 0;
/// 判断结束方式
switch (nInputFlag)
{
case 0:
{
nReturn = mfReadCommUseStopChar(data, byteArray,
dwDelayTime, ucStopChar);
}break;
case 1:
{
nReturn = mfReadCommUseInputLen(data, byteArray,
dwDelayTime, dwInputLen);
}break;
case 2:
{
nReturn = mfReadCommUseSleep(data, byteArray, dwDelayTime);
}break;
case 3:
{
nReturn = mfReadCommUseCharOrLen(data, byteArray, ucStopChar,
dwDelayTime, dwInputLen);
}break;
default:
{
ASSERT(FALSE);
nReturn = -2;
}break;
}
return nReturn;
}
/// 函数功能: 操作串口函数,发送命令并接收设备回应。
/// 函数返回: 成功返回读取的字节数,失败返回<=0。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针
/// byteArrayOutIn 发送的命令和读回的数据。
/// dwDelayTime 用来保存超时值。
/// nInputFlag 读串口的结束方式
/// 0:收到ucStopChar所指定的字符马上结束。
/// 1:收到dwInputLen个字符后马上结束。
/// 2:Sleep(dwDelayTime)后接收串口所有数据,结束。
/// 3:满足0或1中的条件马上结束。如果操作的时间
/// 超过了dwDelayTime所指定的时间则无条件退出。
/// dwInputLen 要接收的长度。
/// ucStopChar 停止字符。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
int CDevServer::SvrWriteAndReadComm(MCGS_DATA &data,
CByteArray& byteArrayOutIn,
DWORD dwDelayTime,
int nInputFlag,
DWORD dwInputLen,
unsigned char ucStopChar)
{
int nReturn = 0;
if (!SvrWriteComm(data, byteArrayOutIn))
{
return -1;
}
return SvrReadComm(data, byteArrayOutIn, dwDelayTime,
nInputFlag, dwInputLen, ucStopChar);
}
/// 函数功能: 读串口函数,收到ucStopChar所指定的字符马上结束。
/// 函数返回: 成功返回读取的字节数,失败返回<=0。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针
/// byteArray 数组用来保存从串口读回来的数据。
/// dwDelayTime 用来保存超时值。如果操作的时间超过了
/// dwDelayTime所指定的时间则无条件退出。
/// ucStopChar 停止字符。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
inline int CDevServer::mfReadCommUseStopChar(MCGS_DATA &data,
CByteArray& byteArray,
DWORD dwDelayTime,
unsigned char ucStopChar)
{
/// 得到当前时间,这个变量用来判断超时
DWORD dwTimeBegin = GetTickCount();
/// 数组清0
byteArray.SetSize(0);
BOOL bContinue = TRUE;
while (bContinue)
{
CByteArray byteArInput;
if (mfReadComm(data, byteArInput))
{
// 输入缓冲有数据,则读取
for (int i = 0; i < byteArInput.GetSize(); i ++)
{
byteArray.Add(byteArInput.GetAt(i));
if (byteArInput.GetAt(i) == ucStopChar)
{
bContinue = FALSE;
break;
}
}
}
else
{
// 输入缓冲无数据,判断是否超时,超时则退出
if (mfTimeOut(dwTimeBegin, dwDelayTime))
{
break;
}
}
if (bContinue)
{
Sleep(10);
}
}
return byteArray.GetSize();
}
/// 函数功能: 读串口函数,收到dwInputLen所指定的字符数马上结束。
/// 函数返回: 成功返回读取的字节数,失败返回<=0。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针
/// byteArray 数组用来保存从串口读回来的数据。
/// dwDelayTime 用来保存超时值。如果操作的时间超过了
/// dwDelayTime所指定的时间则无条件退出。
/// dwInputLen 要接收的长度。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
inline int CDevServer::mfReadCommUseInputLen(MCGS_DATA &data,
CByteArray& byteArray,
DWORD dwDelayTime,
DWORD dwInputLen)
{
/// 得到当前时间,这个变量用来判断超时
DWORD dwTimeBegin = GetTickCount();
/// 数组清0
byteArray.SetSize(0);
BOOL bContinue = TRUE;
while (bContinue)
{
CByteArray byteArInput;
if (mfReadComm(data, byteArInput))
{
/// 输入缓冲有数据,则读取
for (int i = 0; i < byteArInput.GetSize(); i ++)
{
byteArray.Add(byteArInput.GetAt(i));
if ((DWORD)byteArray.GetSize() >= dwInputLen)
{
bContinue = FALSE;
break;
}
}
}
else
{
/// 输入缓冲无数据,判断是否超时,超时则退出
if (mfTimeOut(dwTimeBegin, dwDelayTime))
{
break;
}
}
if (bContinue)
{
Sleep(10);
}
}
return byteArray.GetSize();
}
/// 函数功能: 读串口函数,Sleep dwDelayTime指定的时间后,读取所有字符马上结束。
/// 函数返回: 成功返回读取的字节数,失败返回<=0。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针
/// byteArray 数组用来保存从串口读回来的数据。
/// dwDelayTime 用来保存超时值。如果操作的时间超过了
/// dwDelayTime所指定的时间则无条件退出。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
inline int CDevServer::mfReadCommUseSleep(MCGS_DATA &data,
CByteArray& byteArray,
DWORD dwDelayTime)
{
if (!mfIsCommDev(data))
{
return FALSE;
}
Sleep(dwDelayTime);
mfReadComm(data, byteArray);
return byteArray.GetSize();
}
/// 函数功能: 读串口函数,收到dwInputLen所指定的字符数或收到ucStopChar所指定的字符马上结束。
/// 函数返回: 成功返回读取的字节数,失败返回<=0。
/// 参数意义: data MCGS传过来的MCGS_DATA结构的指针
/// byteArray 数组用来保存从串口读回来的数据。
/// dwDelayTime 用来保存超时值。如果操作的时间超过了
/// dwDelayTime所指定的时间则无条件退出。
/// dwInputLen 要接收的长度。
/// ucStopChar 停止字符。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
inline int CDevServer::mfReadCommUseCharOrLen(MCGS_DATA &data,
CByteArray& byteArray,
unsigned char ucStopChar,
DWORD dwDelayTime,
DWORD dwInputLen)
{
// 得到当前时间,这个变量用来判断超时
DWORD dwTimeBegin = GetTickCount();
// 数组清0
byteArray.SetSize(0);
BOOL bContinue = TRUE;
while (bContinue)
{
CByteArray byteArInput;
if (mfReadComm(data, byteArInput))
{
// 输入缓冲有数据,则读取
for (int i = 0; i < byteArInput.GetSize(); i ++)
{
byteArray.Add(byteArInput.GetAt(i));
if (byteArInput.GetAt(i) == ucStopChar)
{
bContinue = FALSE;
break;
}
if ((DWORD)byteArray.GetSize() >= dwInputLen)
{
bContinue = FALSE;
break;
}
}
}
else
{
// 输入缓冲无数据,判断是否超时,超时则退出
if (mfTimeOut(dwTimeBegin, dwDelayTime))
{
break;
}
}
if (bContinue)
{
Sleep(10);
}
}
return byteArray.GetSize();
}
/// 函数功能: 判断是否超时。
/// 函数返回: 超时返回TRUE,否则返回FALSE。
/// 参数意义: dwTimeBegin 计时开始时间。
/// dwDelayTime 超时值。
/// 备 注: 此函数用于提供通用服务,建议不修改。
///
BOOL CDevServer::mfTimeOut(DWORD dwTimeBegin, DWORD dwDelayTime)
{
DWORD dwTimeNow, dwTimeSnap;
dwTimeNow = GetTickCount();
if (dwTimeNow < dwTimeBegin)
{
dwTimeSnap = 0;
dwTimeSnap = ~dwTimeSnap;
dwTimeSnap = dwTimeSnap - dwTimeBegin + dwTimeNow;
}
else
{
dwTimeSnap = dwTimeNow - dwTimeBegin;
}
if (dwTimeSnap > dwDelayTime)
{
return TRUE;
}
else
{
return FALSE;
}
}
/// 函数功能: 读串口函数,读取输入缓冲区的所有数据。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -