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

📄 dnpexplain.cpp

📁 电力和自动化通讯规约模拟软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// DnpExplain.cpp: implementation of the CDnpExplain class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "RTUSim.h"
#include "DnpExplain.h"
#include "SOERec.h"
#include "FaultRec.h"

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

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

CDnpExplain::CDnpExplain()
{
	m_bOperateTimeOut=false;
	m_soeState=false;
	m_faultState=false;
	m_timeAnch=false;
	unsigned short dnp_crc_tablet[] = {
    0x0000, 0x365e, 0x6cbc, 0x5ae2, 0xd978, 0xef26, 0xb5c4, 0x839a,
    0xff89, 0xc9d7, 0x9335, 0xa56b, 0x26f1, 0x10af, 0x4a4d, 0x7c13,
    0xb26b, 0x8435, 0xded7, 0xe889, 0x6b13, 0x5d4d, 0x07af, 0x31f1,
    0x4de2, 0x7bbc, 0x215e, 0x1700, 0x949a, 0xa2c4, 0xf826, 0xce78,
    0x29af, 0x1ff1, 0x4513, 0x734d, 0xf0d7, 0xc689, 0x9c6b, 0xaa35,
    0xd626, 0xe078, 0xba9a, 0x8cc4, 0x0f5e, 0x3900, 0x63e2, 0x55bc,
    0x9bc4, 0xad9a, 0xf778, 0xc126, 0x42bc, 0x74e2, 0x2e00, 0x185e,
    0x644d, 0x5213, 0x08f1, 0x3eaf, 0xbd35, 0x8b6b, 0xd189, 0xe7d7,
	0x535e, 0x6500, 0x3fe2, 0x09bc, 0x8a26, 0xbc78, 0xe69a, 0xd0c4,
    0xacd7, 0x9a89, 0xc06b, 0xf635, 0x75af, 0x43f1, 0x1913, 0x2f4d,
    0xe135, 0xd76b, 0x8d89, 0xbbd7, 0x384d, 0x0e13, 0x54f1, 0x62af,
    0x1ebc, 0x28e2, 0x7200, 0x445e, 0xc7c4, 0xf19a, 0xab78, 0x9d26,
    0x7af1, 0x4caf, 0x164d, 0x2013, 0xa389, 0x95d7, 0xcf35, 0xf96b,
    0x8578, 0xb326, 0xe9c4, 0xdf9a, 0x5c00, 0x6a5e, 0x30bc, 0x06e2,
    0xc89a, 0xfec4, 0xa426, 0x9278, 0x11e2, 0x27bc, 0x7d5e, 0x4b00,
    0x3713, 0x014d, 0x5baf, 0x6df1, 0xee6b, 0xd835, 0x82d7, 0xb489,
    0xa6bc, 0x90e2, 0xca00, 0xfc5e, 0x7fc4, 0x499a, 0x1378, 0x2526,
	0x5935, 0x6f6b, 0x3589, 0x03d7, 0x804d, 0xb613, 0xecf1, 0xdaaf,
    0x14d7, 0x2289, 0x786b, 0x4e35, 0xcdaf, 0xfbf1, 0xa113, 0x974d,
    0xeb5e, 0xdd00, 0x87e2, 0xb1bc, 0x3226, 0x0478, 0x5e9a, 0x68c4,
    0x8f13, 0xb94d, 0xe3af, 0xd5f1, 0x566b, 0x6035, 0x3ad7, 0x0c89,
    0x709a, 0x46c4, 0x1c26, 0x2a78, 0xa9e2, 0x9fbc, 0xc55e, 0xf300,
    0x3d78, 0x0b26, 0x51c4, 0x679a, 0xe400, 0xd25e, 0x88bc, 0xbee2,
    0xc2f1, 0xf4af, 0xae4d, 0x9813, 0x1b89, 0x2dd7, 0x7735, 0x416b,
    0xf5e2, 0xc3bc, 0x995e, 0xaf00, 0x2c9a, 0x1ac4, 0x4026, 0x7678,
    0x0a6b, 0x3c35, 0x66d7, 0x5089, 0xd313, 0xe54d, 0xbfaf, 0x89f1,
    0x4789, 0x71d7, 0x2b35, 0x1d6b, 0x9ef1, 0xa8af, 0xf24d, 0xc413,
    0xb800, 0x8e5e, 0xd4bc, 0xe2e2, 0x6178, 0x5726, 0x0dc4, 0x3b9a,
    0xdc4d, 0xea13, 0xb0f1, 0x86af, 0x0535, 0x336b, 0x6989, 0x5fd7,
    0x23c4, 0x159a, 0x4f78, 0x7926, 0xfabc, 0xcce2, 0x9600, 0xa05e,
    0x6e26, 0x5878, 0x029a, 0x34c4, 0xb75e, 0x8100, 0xdbe2, 0xedbc,
    0x91af, 0xa7f1, 0xfd13, 0xcb4d, 0x48d7, 0x7e89, 0x246b, 0x1235};
	for(int k=0;k<256;k++)
		dnp_crc_table[k]=dnp_crc_tablet[k];

}

CDnpExplain::~CDnpExplain()
{

}
BOOL CDnpExplain::SwitchSendCode(CByteArray &byteArray, int inBufLen)
{
	WORD RtuAddress,PrimartAddr;
	int address1=byteArray.GetAt(5);
	RtuAddress=address1;
	RtuAddress<<=8;
	RtuAddress+=byteArray.GetAt(4);
	if (RtuAddress!=(WORD)m_wAddr) 
	{
		return false;
	}
	int priaddress1=byteArray.GetAt(7);
	PrimartAddr=priaddress1;
	PrimartAddr<<=8;
	PrimartAddr+=byteArray.GetAt(6);
	switch(byteArray.GetAt(12))//FC code 
	{
		//read
	case 0x01:
		if(byteArray.GetAt(2)==0x0b)
		{
			//binary input without of status
			if(byteArray.GetAt(13)==0x01&&byteArray.GetAt(14)==0x01&&byteArray.GetAt(15)==0x06)
			{
				
				if(SendDigitalData(RtuAddress,PrimartAddr))
				{
					return true;
				}
				return false;
			
			}
			//analogy input
			else if(byteArray.GetAt(13)==0x1e&&byteArray.GetAt(14)==0x00&&byteArray.GetAt(15)==0x06)
			{
				if(SendAnalogyData(RtuAddress,PrimartAddr))
				{
					return true;
				}
				return false;
			}
			//count input
			else if(byteArray.GetAt(13)==0x14&&byteArray.GetAt(14)==0x00&&byteArray.GetAt(15)==0x06)
			{
				if(SendCountData(RtuAddress,PrimartAddr))
				{
					return true;
				}
			}
			//class 0 data (for all data)
			else if(byteArray.GetAt(13)==0x3c&&byteArray.GetAt(14)==0x01&&byteArray.GetAt(15)==0x06)
			{
				if(CallClass0Data(RtuAddress,PrimartAddr))
				{
					return true;
				}
			}
			//class 1 data (for fault data)
			else if(byteArray.GetAt(13)==0x3c&&byteArray.GetAt(14)==0x02&&byteArray.GetAt(15)==0x06)
			{
				if(CallClass1Data(RtuAddress,PrimartAddr))
				{
					return true;
				}
			}
			//class 2 data (for SOE data)
			else if(byteArray.GetAt(13)==0x3c&&byteArray.GetAt(14)==0x03&&byteArray.GetAt(15)==0x06)
			{
				if(CallClass2Data(RtuAddress,PrimartAddr))
				{
					return true;
				}
			}
			//class 3 data (for using)
			else if(byteArray.GetAt(13)==0x3c&&byteArray.GetAt(14)==0x04&&byteArray.GetAt(15)==0x06)
			{
				if(CallClass3Data(RtuAddress,PrimartAddr))
				{
					return true;
				}
			}
			//binary input  change with absolute data and time
			else if(byteArray.GetAt(13)==0x02&&byteArray.GetAt(14)==0x02&&byteArray.GetAt(15)==0x06)
			{
				/////////?需要添加SOE内容--从基类SOE缓冲区读取
				if(SendSoeDataWithAbsolute(RtuAddress,PrimartAddr,0x00,true))
				{
					return true;
				}
			}
			//binary input change with  relative date and time
			else if(byteArray.GetAt(13)==0x02&&byteArray.GetAt(14)==0x03&&byteArray.GetAt(15)==0x06)
			{
				if(SendSoeDataWithRelative(RtuAddress,PrimartAddr))
				{
					return true;
				}
			}
		}
		else if(byteArray.GetAt(2)==0x0e)
		{
			if((byteArray.GetAt(13)==0x01)&&(byteArray.GetAt(14)==0x01)&&(byteArray.GetAt(15)==0x06)&&(byteArray.GetAt(16)==0x1e)&&(byteArray.GetAt(17)==0x00)&&(byteArray.GetAt(18)==0x06))
			{
				if(SendBinaryAndAnalogy(RtuAddress,PrimartAddr))
				{
					return true;
				}
				
			}
			else if((byteArray.GetAt(13)==0x1e)&&(byteArray.GetAt(14)==0x00)&&(byteArray.GetAt(15)==0x06)&&(byteArray.GetAt(16)==0x14)&&(byteArray.GetAt(17)==0x00)&&(byteArray.GetAt(18)==0x06))
			{
				if(SendAnalogyAndCount(RtuAddress,PrimartAddr))
				{
					return true;
				}
			}
			else if((byteArray.GetAt(13)==0x01)&&(byteArray.GetAt(14)==0x01)&&(byteArray.GetAt(15)==0x06)&&(byteArray.GetAt(16)==0x14)&&(byteArray.GetAt(17)==0x00)&&(byteArray.GetAt(18)==0x06))
			{
				if(SendBinaryAndCount(RtuAddress,PrimartAddr))
				{
					return true;
				}
			}
		}
		else if(byteArray.GetAt(2)==0x11)
		{
			if(byteArray.GetAt(13)==0x01&&byteArray.GetAt(14)==0x01&&byteArray.GetAt(15)==0x06&&byteArray.GetAt(16)==0x1e&&byteArray.GetAt(17)==0x00&&byteArray.GetAt(18)==0x06&&byteArray.GetAt(19)==0x14&&byteArray.GetAt(20)==0x00&&byteArray.GetAt(21)==0x06)
			{
				if(CallClass0Data(RtuAddress,PrimartAddr))
				{
					return true;
				}

			}

		}
		//else data called
		break;
		//write
	case 0x02:
		//time change 
		if(byteArray.GetAt(13)==0x32&&byteArray.GetAt(14)==0x01&&byteArray.GetAt(15)==0x07)
		{
			if(TimeSynchReply(RtuAddress,PrimartAddr,byteArray))
			{
				return true;
			}

		}
		break;
		//pre-operate
	case 0x03:
		if(byteArray.GetAt(13)==0x0c&&byteArray.GetAt(14)==0x01)
		{
			if(byteArray.GetAt(18)&0x80)//trip
			{
				if(PreOperateReply(RtuAddress,PrimartAddr,byteArray.GetAt(17),true))
				{
					return true;
				}
			}
			else//close
			{
				if(PreOperateReply(RtuAddress,PrimartAddr,byteArray.GetAt(17),false))
				{
					return true;
				}
			}
		}
		break;
		//do-operate
	case 0x04:
		if(byteArray.GetAt(13)==0x0c&&byteArray.GetAt(14)==0x01)
		{
			if(byteArray.GetAt(20)&0x80)//trip
			{
				if(DoneOperateReply(RtuAddress,PrimartAddr,byteArray.GetAt(17),true))
				{
					return true;
				}
			}
			else//close
			{
				if(DoneOperateReply(RtuAddress,PrimartAddr,byteArray.GetAt(17),false))
				{
					return true;
				}
			}
		}
		break;
		//directly operate
	case 0x05:
		if(byteArray.GetAt(13)==0x0c&&byteArray.GetAt(14)==0x01)
		{
			if(byteArray.GetAt(20)&0x80)//trip
			{
				if(DirectOperateReply(RtuAddress,PrimartAddr,0x18,true))
				{
					return true;
				}
			}
			else//close
			{
				if(DirectOperateReply(RtuAddress,PrimartAddr,0x18,false))
				{
					return true;
				}
			}
		}
		break;
	case 0x0d://restart
		break;
	default:
		break;
	}
	return false;
}

void CDnpExplain::Explain()
{
	int BufNum=m_baInBuffer.GetSize();
	int crcCheckNum,remainder,m_inLen;
	CByteArray InBufTemp;
	if(m_paSOE.GetSize()>0)
	{
		m_soeState=true;
	}
	if(m_paFault.GetSize())
	{
		m_faultState=true;
	}
	if(BufNum>3&&m_baInBuffer.GetAt(0)==0x05&&m_baInBuffer.GetAt(1)==0x64)
	{
		crcCheckNum=(m_baInBuffer[2]-5)/16;//校验次数---USER DATA长度除16
		remainder=(m_baInBuffer[2]-5)%16;//余数
		if(remainder)
		{
			m_inLen=crcCheckNum*18+remainder+12;//总长度减已读取的3个
			if(m_inLen<=BufNum)
			{

				for(int i=0;i<m_inLen;i++)
				{
					InBufTemp.Add(m_baInBuffer[0]);
				//	if(i==m_inLen-1)
				//		break;
					m_baInBuffer.RemoveAt(0);
				}
				SwitchSendCode(InBufTemp,m_inLen);
			}
			else
			{
				return;
			}
		}
		else
		{
			m_inLen=crcCheckNum*18+10-3;//总长度减已读取的3个
			if(m_inLen<=BufNum)
			{
				for(int i=0;i<m_inLen;i++)
				{
					InBufTemp.Add(m_baInBuffer[i]);
					m_baInBuffer.RemoveAt(0);
				}
				SwitchSendCode(InBufTemp,m_inLen);
			}
			else
			{
				return;
			}

		}
	}
	else
	{
		if(BufNum>3)
		{
			m_baInBuffer.RemoveAll();
		}

	}
	return;



}

BOOL CDnpExplain::SendDigitalData(WORD &rtuaddress, WORD &priaddress)
{
	BYTE strLength=m_baDigital.GetSize();
	if(strLength==0)
	{
		return false;
	}
	BYTE DigitalCount=strLength*8;
	BYTE rtuaddr1,rtuaddr2,priaddr1,priaddr2;
	priaddr1=(BYTE)priaddress;
	priaddr2=priaddress>>8;
	rtuaddr1=(BYTE)rtuaddress;
	rtuaddr2=rtuaddress>>8;
	BYTE Length=15+strLength;

	m_baOutBuffer.RemoveAll();
	m_baOutBuffer.Add(0x05);
	m_baOutBuffer.Add(0x64);
	m_baOutBuffer.Add(Length);//Length
	m_baOutBuffer.Add(0x44);
	m_baOutBuffer.Add(rtuaddr1);
	m_baOutBuffer.Add(rtuaddr2);
	m_baOutBuffer.Add(priaddr1);
	m_baOutBuffer.Add(priaddr2);
	//////////////////////////////2Byte CRC reserved
	/////////////////////////////
	m_baOutBuffer.Add(0xcd);
	m_baOutBuffer.Add(0xc5);
	m_baOutBuffer.Add(0x81);
//IIN
	m_baOutBuffer.Add(0x01);//object
	m_baOutBuffer.Add(0x01);
	m_baOutBuffer.Add(0x00);
	m_baOutBuffer.Add(0x00);//Number
	m_baOutBuffer.Add(DigitalCount-1);//Number
	for(int i=0;i<m_baDigital.GetSize();i++)
	{
		m_baOutBuffer.Add(m_baDigital[i]);
	}
	HandleIInInfo();
	setSendCrc();
	SendRespons();
	return true;
}

BOOL CDnpExplain::SendAnalogyData(WORD &rtuaddress, WORD &priaddress)
{
	if(m_waAnalog.GetSize()==0)
	{
		return false;
	}
	BYTE AnalogyCount=m_waAnalog.GetSize();
	BOOL bResult = FALSE;
	BYTE rtuaddr1,rtuaddr2,priaddr1,priaddr2;
	BYTE data1,data2;
	priaddr1=(BYTE)priaddress;
	priaddr2=priaddress>>8;
	rtuaddr1=(BYTE)rtuaddress;
	rtuaddr2=rtuaddress>>8;
	BYTE Length=15+AnalogyCount*2;

	m_baOutBuffer.RemoveAll();
	m_baOutBuffer.Add(0x05);
	m_baOutBuffer.Add(0x64);
	m_baOutBuffer.Add(Length);//Length
	m_baOutBuffer.Add(0x44);
	m_baOutBuffer.Add(rtuaddr1);
	m_baOutBuffer.Add(rtuaddr2);
	m_baOutBuffer.Add(priaddr1);
	m_baOutBuffer.Add(priaddr2);
	//////////////////////////////2Byte CRC reserved
	/////////////////////////////
	m_baOutBuffer.Add(0xce);
	m_baOutBuffer.Add(0xc6);
	m_baOutBuffer.Add(0x81);
	//IIN
	m_baOutBuffer.Add(0x1e);//object
	m_baOutBuffer.Add(0x04);
	m_baOutBuffer.Add(0x00);
	m_baOutBuffer.Add(0x00);//Number
	m_baOutBuffer.Add(AnalogyCount-1);//Number
	for(int i=0;i<m_waAnalog.GetSize();i++)
	{
		data1=(BYTE)m_waAnalog[i];
		data2=m_waAnalog[i]>>8;
		m_baOutBuffer.Add(data1);
		m_baOutBuffer.Add(data2);
	}
	HandleIInInfo();
	
	setSendCrc();
	SendRespons();
	return true;
}

BOOL CDnpExplain::SendCountData(WORD &rtuaddress, WORD &priaddress)
{
	if(m_dwaCount.GetSize()==0)
	{
		return false;
	}
	BYTE CountNumber=m_dwaCount.GetSize();
	BOOL bResult = FALSE;
	BYTE rtuaddr1,rtuaddr2,priaddr1,priaddr2;
	BYTE data1,data2,data3,data4;
	priaddr1=(BYTE)priaddress;
	priaddr2=priaddress>>8;
	rtuaddr1=(BYTE)rtuaddress;
	rtuaddr2=rtuaddress>>8;
	BYTE Length=15+CountNumber*4;

	m_baOutBuffer.RemoveAll();
	m_baOutBuffer.Add(0x05);
	m_baOutBuffer.Add(0x64);
	m_baOutBuffer.Add(Length);//Length
	m_baOutBuffer.Add(0x44);
	m_baOutBuffer.Add(rtuaddr1);
	m_baOutBuffer.Add(rtuaddr2);
	m_baOutBuffer.Add(priaddr1);
	m_baOutBuffer.Add(priaddr2);
	//////////////////////////////2Byte CRC reserved
	/////////////////////////////
	m_baOutBuffer.Add(0xcf);
	m_baOutBuffer.Add(0xc7);
	m_baOutBuffer.Add(0x81);
//IIN
	m_baOutBuffer.Add(0x00);
	m_baOutBuffer.Add(0x14);//object
	m_baOutBuffer.Add(0x06);
	m_baOutBuffer.Add(0x00);
	m_baOutBuffer.Add(0x00);//Number
	m_baOutBuffer.Add(CountNumber-1);//Number
	for(int i=0;i<m_dwaCount.GetSize();i++)
	{
		DWORD dwTemp=m_dwaCount[i];
		data1=(BYTE)m_dwaCount[i];
		m_dwaCount[i]>>=8;
		data2=(BYTE)m_dwaCount[i];
		m_dwaCount[i]>>=8;
		data3=(BYTE)m_dwaCount[i];
		m_dwaCount[i]>>=8;
		data4=(BYTE)m_dwaCount[i];
		m_baOutBuffer.Add(data1);
		m_baOutBuffer.Add(data2);
		m_baOutBuffer.Add(data3);
		m_baOutBuffer.Add(data4);
	}
	HandleIInInfo();
	

⌨️ 快捷键说明

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