⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devserver.cpp

📁 国家环保总局污染源在线通讯协议的简化版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// 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 + -