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

📄 protocol.cpp

📁 电信机房MDF、电源柜监控源码,主要用在通信机房配线设备监控、电源柜监控
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Protocol.cpp: implementation of the CProtocol class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Protocol.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//##ModelId=44B6F88401B8
CProtocol::CProtocol()
{

}

//##ModelId=44B6F88401B9
CProtocol::~CProtocol()
{

}
//********* 解释数据包 ***********
//*     通讯版本暂时不做判断。   *
//********************************
//##ModelId=44B6F88401A9
int CProtocol::Explain(UCHAR *buf , UINT len ,sCommPack* InPack , CString& strError , CString& strTip)
{
	UINT unCount ;
	char* ptBuf ;

	try
	{
		ptBuf =(char*)buf ;
		strError.Empty() ;

		if( len < 18 ) //无效数据 0x06 错误 非法数据
		{
			strError = "  非法数据格式,长度低于18 " ;
			return  6 ;
		}

		memset(InPack, 0, sizeof(InPack)) ;//初始化通讯包

		//协议包结构
		InPack->SOI = *ptBuf++ ;

		StringToBytes(ptBuf,&(InPack->VER),2) ;//获取通讯版本
		ptBuf += 2 ;
		StringToBytes(ptBuf,&(InPack->ADR),2) ;//获取通讯地址
		ptBuf += 2 ;
		StringToBytes(ptBuf,&(InPack->CID1),2) ;//获取监测模块类型
		ptBuf += 2 ;
		StringToBytes(ptBuf,&(InPack->CID2),2) ;//获取通讯命令
		ptBuf += 2 ;

		if( FindCmd(InPack->CID2,strTip ) != 0 ) //查询CID2是否正确命令。
		{
			strError = "  无效命令 CID2 出错" ;
			return 4 ;
		}
		StringToBytes(ptBuf,InPack->LENGTH,4);//获取内容长度LENGTH
		ptBuf += 4 ;
		
		if(!CheckLCHKSUM((UCHAR*)InPack->LENGTH, sizeof(InPack->LENGTH)))//LCHKSUM校验错误0x03错误
		{
			strError = "  LCHKSUM 校验和错误" ;
			return 3 ;
		}

		//获得INFO数据的ASCII字符长度
		unCount = InPack->LENGTH[0] & 0X0F ;//屏蔽高4位的校验码,取低4位
		unCount = ( unCount << 8 ) | InPack->LENGTH[1] ;//高字节4位+低字节8位
		
		if( unCount+18 > len )//LENID与实际INFO内容不符 0x05 错误
		{
			strError = "  非法数据 INFO 长度与LENGTH指定的长度不符" ;
			return 5 ;
		}
		
		StringToBytes(ptBuf,InPack->INFO,unCount);//获取 INFO 内容

		ptBuf += unCount ;			//指针后移

		StringToBytes(ptBuf,InPack->CHKSUM,4) ; //获取CHKSUM码

		ptBuf += 4 ;

		InPack->EOI = *ptBuf ; 
		//CHKSUM校验错误为 0x02 
		if(!CheckCHKSUM( buf+1 , len - 6 , (UCHAR*)InPack->CHKSUM , sizeof(InPack->CHKSUM)))
		{
			strError = "  CHKSUM 校验和错误" ;
			return 2 ;
		}

		return 0 ;
	}
	catch(_com_error e)
	{
		strError = "异常:校验时发生未知异常" ;
		TRACE0(strError) ;
		return 6 ;
	}

}




//********* 解释数据包 **************
//*     数据包展开,分析转换数据格式*
//***********************************
int CProtocol::Explain(CInfoFrame &frame)
{
	UINT unCount;
	int len;
	char *ptBuf,*buf;
	//sCommPack* InPack;
	CString  strTip,strError;
	UCHAR cBuf;
	len = frame.nRLen;
	buf = new char[frame.nRLen];

	try
	{
		memset(buf,0,frame.nRLen);
		memcpy(buf,frame.ucBuf,frame.nRLen);
		ptBuf = (char *)buf;
		strError.Empty() ;
		if( len < 18 ) //无效数据 0x06 错误 非法数据
		{
			strError = "  非法数据格式,长度低于18 " ;
			return  6 ;
		}
		//InPack = &(frame.InPack);

  		//memset(InPack, 0, sizeof(InPack)) ;//初始化通讯包
		//协议包结构
		
		frame.InPack.SOI = *ptBuf++ ;
		StringToBytes(ptBuf,&cBuf,2) ;		//获取通讯版本
		frame.InPack.VER = cBuf;
		ptBuf += 2 ;
		StringToBytes(ptBuf,&cBuf,2) ;		//获取通讯地址
		frame.InPack.ADR = cBuf;
		ptBuf += 2 ;
		StringToBytes(ptBuf,&cBuf,2) ;		//获取监测模块类型
		frame.InPack.CID1 = cBuf;
		ptBuf += 2 ;
		StringToBytes(ptBuf,&cBuf ,2) ;		//获取通讯命令
		frame.InPack.CID2 = cBuf;
		ptBuf += 2 ;
		if( FindCmd(frame.InPack.CID2,strTip ) != 0 ) //查询CID2是否正确命令。
		{
			strError = "  无效命令 CID2 出错" ;
			return 4 ;
		}
		StringToBytes(ptBuf,frame.InPack.LENGTH,4);//获取内容长度LENGTH
		ptBuf += 4 ;
		
		if(!CheckLCHKSUM((UCHAR*)frame.InPack.LENGTH, sizeof(frame.InPack.LENGTH)))//LCHKSUM校验错误0x03错误
		{
			strError = "  LCHKSUM 校验和错误" ;
			return 3 ;
		}

		//获得INFO数据的ASCII字符长度
		unCount = frame.InPack.LENGTH[0] & 0X0F ;				//屏蔽高4位的校验码,取低4位
		unCount = ( unCount << 8 ) |frame.InPack.LENGTH[1] ;	//高字节4位+低字节8位
		
		if( !(unCount+18 == len + 1  || unCount+18 == len) )	//LENID与实际INFO内容不符 0x05 错误
		{
			strError = "  非法数据 INFO 长度与LENGTH指定的长度不符" ;
			return 5 ;
		}
		
		StringToBytes(ptBuf,frame.InPack.INFO,unCount);			//获取 INFO 内容
		frame.InPack.DataLen =  unCount / 2;

		ptBuf += unCount ;										//指针后移
		StringToBytes(ptBuf,frame.InPack.CHKSUM,4) ;			//获取CHKSUM码
		ptBuf += 4 ;

		frame.InPack.EOI = *ptBuf ; 

		return 0 ;
	}
	catch(_com_error e)
	{
		strError = "异常:校验时发生未知异常" ;
		TRACE0(strError) ;
		return 6 ;
	}

}
//将ASCII码的十六进制,转换为整型 ********
//##ModelId=44B6F88401A6
DWORD CProtocol::StringToHex(UCHAR *cBuf , UINT len)
{
	UINT i,j,iStep ;
	DWORD iSum;
	CString strTip ;

	try
	{
		for( i = len , iSum=0 ,iStep = 1 ; i > 0 ; i-- )
		{
			for(j=i-1 ; j >0  ; j-- )
				iStep *= 16 ;

			iSum += ASCIIToHex(cBuf) * iStep ;

			cBuf++ ;
			iStep = 1 ;

		}
	}
	catch(_com_error e)
	{
		strTip.Format( "异常:StringToHex 检验和产生异常:%s ",(LPCSTR)e.Description() ) ;
		TRACE0(strTip) ;
		return FALSE ;
	}
	return iSum ;
}
//判断数据包内容校验和 ***********
//##ModelId=44B6F8840199
BOOL CProtocol::CheckCHKSUM(UCHAR *pPack , DWORD len , UCHAR* buf , UINT unLen ) 
{
	CString strTip ;
	DWORD dwCheck , dwSum ;
	dwCheck = 0 ;

	try
	{

		dwCheck = *buf++ << 8 ;
		dwCheck |= *buf ;

		dwSum = GetCHKSUM( pPack , len ) ;

		if( dwSum == dwCheck ) 

			return TRUE ;
		else
			return FALSE ;
	}
	catch(_com_error e)
	{
		strTip.Format( "异常:CHKSUM 检验和产生异常:%s ",(LPCSTR)e.Description() ) ;
		TRACE0(strTip) ;
		return FALSE ;
	}
}
//判断长度校验和*********
//##ModelId=44B6F8840196
BOOL CProtocol::CheckLCHKSUM(UCHAR *buf, DWORD len)
{
	//-问题-
	CString strTip ;
	DWORD i ;
	UCHAR ucSum , ucCheck;
	try
	{

		ucCheck = *buf >> 4  ;		//取出长度检验码

		ucSum = *buf & 0X0F ;		//获取LCHKSUM
		//求长度校验和
		for( i=0 ; i < len - 1 ; i++ )
		{
			buf++ ;
			ucSum += *buf >> 4 ;
			ucSum += *buf & 0X0F ;
		}							

		ucSum = ~ucSum + 1 ;		//取反加1
		ucSum &= 0X0F ;

		if( ucCheck == ucSum )
			return TRUE ;
		else
			return FALSE ;
	}
	catch(_com_error e)
	{
		strTip.Format( "异常:LCHKSUM 检验和产生异常:%s ",(LPCSTR)e.Description() ) ;
		TRACE0(strTip) ;
		return FALSE ;
	}

}
//获得LCHAKSUM*****
//##ModelId=44B6F884018A
UCHAR CProtocol::GetLCHKSUM(UCHAR *buf , DWORD len)
{
	DWORD	i ;
	UCHAR	ucSum ;
	CString strTip ;

	try
	{
		for(i = 0 , ucSum = 0 ; i < len ; i++)
		{
			ucSum += ASCIIToHex(buf++) ;
		}

		ucSum = ucSum % 16 ;						//模16取余数
		ucSum = ~ucSum + 1 ;						//取反加1
		ucSum &= 0X0F ;								//只取低四位

		return HexToASCII(&ucSum) ;
	}
	catch(_com_error e)
	{
		strTip.Format( "异常:CHKSUM 检验和产生异常:%s ",(LPCSTR)e.Description() ) ;
		TRACE0(strTip) ;
		return 0 ;
	}

}
//获得CHKSUM*********
//##ModelId=44B6F8840187
DWORD CProtocol::GetCHKSUM(UCHAR *buf, DWORD len)
{
	DWORD i,iSum ;
	CString strTip ;
	try
	{
		for( i=0 , iSum = 0 ; i < len ; i++ )
			iSum += *buf++ ;

		iSum = iSum % 65536 ;						//模65536取余数
		iSum = ~iSum + 1 ;							//取反加1
		iSum &= 0XFFFF ;							//只取低四字节

		return iSum ;
	}
	catch(_com_error e)
	{
		strTip.Format( "获得 CHKSUM 检验和产生异常(GetCHKSUM):%s ",(LPCSTR)e.Description() ) ;
		TRACE0(strTip) ;
		return 0 ;
	}
}

int CProtocol::Build( CArray<sUnit,sUnit>& lpArray, UCHAR ucCmd)
{
	CString strTip,sBuf;
	sUnit* m_unit;

	for(int i =0;i < lpArray.GetSize();i++)
	{
		m_unit = &lpArray.GetAt(i);
		sBuf = Build(m_unit->strIDAddr ,m_unit->strType,ucCmd);
		if (sBuf.GetLength() > 0)
		{
			m_unit->iCmd = ucCmd;
			m_unit->strSend = sBuf;
		}
	}
	
	return 0 ;
	
}

//组建协议包
int CProtocol::Build( sUnit *m_unit, UCHAR ucCmd)
{
	CString strTip,sBuf;
		
	sBuf = Build(m_unit->strIDAddr ,m_unit->strType,ucCmd);
	if (sBuf.GetAllocLength() >0 )
	{
		m_unit->strSend = sBuf;
		m_unit->iCmd = ucCmd;
		return 0;
	}else
		return -1 ;
	
}

//CHKSUM 转为 string ******
//##ModelId=44B6F8840179
CString CProtocol::CHKSUMToString(DWORD dwSum)
{
	UINT i ;
	UCHAR	ucTemp ;
	CString strTemp ;

	strTemp.Empty() ;

	for(i=0 ; i < 4 ; i++)
	{
		ucTemp = (UCHAR)(0X0F & dwSum) ;
		ucTemp = HexToASCII(&ucTemp);

		strTemp.Insert(0,ucTemp) ;

		dwSum >>= 4 ;
	}

	return strTemp ;

}
//单个ASCII码转为二进制。*******
//##ModelId=44B6F8840177
UCHAR CProtocol::ASCIIToHex(UCHAR *buf)
{

	UCHAR ucSum ;

	if( *buf >= '0' && *buf <= '9' )
	{
		ucSum = (*buf - 0x30) ;
	}
	else if( *buf >= 'A' && *buf <= 'Z' )
	{
		ucSum = *buf - 0x37 ;
	}
	else if( *buf >= 'a' && *buf <= 'z' )
	{
		ucSum = *buf - 0x57 ;
	}

	return ucSum ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -