📄 protocol.cpp
字号:
// 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 + -