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