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

📄 protocol101.cpp

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

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

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*附:
101规约报文格式:(不同厂家对101规约中的具体定义格式不同,要针对具体的问题
       来看,对不同厂家的报文格式进行分析)
	   读CLASS1(读遥信) ->10 4a 01 4b 16 
	                    <-68H+L+L+68H+C(88 以数据响应请求帧)+地址+类型标识(01)
						+限定词(SQ=1)+传送原因(05)+公共地址+信息体地址(0x0001)
						+数据+CS+16H
	   读CLASS2(读遥测) ->10 4b 01 4c 16
	             (无SOE)<-68H+L+L+68H+C(a8)+地址+类型标识21+限定词(SQ=0)+传送原因05
				          +公共地址+信息体地址(从0x0701开始)+数据+CS+16H
			
                  (有SOE)<-68H+L+L+68H+C(a8)+地址+类型标识17+限定词(SQ=0)+传送原因03
				           +公共地址+信息体地址(0x0801开始)+数据+CS+16H
	   读电度量 ->68 09 09 68 53 01 65 01 06 01 00 00 41 02 16
				<-69 09 09 68 80 01 0f 01 25 01 01 0c 01 00 00 13 41 19 16

				//遥控合选择
				>-68 09 09 68 53 01 2e 01 06 01 01 0b 82 18 16
				<-68 09 09 68 80 01 2e 01 07 01 01 0b 82 3a 16
				//遥控合执行
				>-68 09 09 68 53 01 2e 01 06 01 01 0b 02 98 16 
				<-68 09 09 68 80 01 2e 01 07 01 01 0b 02 ba 16
						   
				//遥控分选择
				>-68 09 09 68 53 01 2e 01 06 01 01 0b 81 17 16
				<-68 09 09 68 80 01 2e 01 07 01 01 0b 81 39 16 
				//遥控分执行
				>-68 09 09 68 53 01 2e 01 06 01 01 0b 01 97 16 
				<-68 09 09 68 80 01 2e 01 07 01 01 0b 01 b9 16 
				//
*/
CProtocol101::CProtocol101()
{
	m_nOrderType = UNDEFINE_ORDER;
	//m_bSwitchState = FALSE;
	//m_bFault = FALSE;
	m_bOpenSelect = FALSE;
	m_bCloseSelect = FALSE;
	

}

CProtocol101::~CProtocol101()
{

}

void CProtocol101::Explain()
{
	if (!ExplainInData(m_baInBuffer))
	{
		return;
	};
	if (m_nOrderType != UNDEFINE_ORDER) 
	{
		Respond(m_baOutBuffer)  ;
		SendRespons();
		return;
	}
	else
		return;
	
}

BOOL CProtocol101::ExplainInData(CByteArray& bReceive)
{
	BYTE CSByte = 0x00;
	BYTE OrderByte = 0x00;
	BYTE State = 0x00;
 	int Head = 0;//Head是以0开头的.
	
	if(bReceive.GetSize()<5)//判断是否可能含有一个完整的命令
		return FALSE;
	
	for( Head = 0; !((bReceive[Head] == 0x10)||(bReceive[Head] == 0x68)); )//判断是否含有命令头0x10或0x68
	{
        Head++;
		if(Head >= bReceive.GetSize())
		{
			bReceive.RemoveAll();
			return FALSE;
		}
	}
    bReceive.RemoveAt(0,Head);

	if(bReceive[0] == 0x10)
	{
		if(bReceive.GetSize() < 5)//判断从0x10开始是否可能含有一个完整的命令
			return FALSE;
		
		if((BYTE)m_wAddr != bReceive[2])//判断所收报文目的地址是否为本FTU地址
		{
			bReceive.RemoveAt(0,5);
			return FALSE;
		}
		
		CSByte = bReceive[1]+bReceive[2];
		if(CSByte != bReceive[3])//判断校验码
		{   //校验码不对时如何清空要看实际的情况,待定
			bReceive.RemoveAt(0,5);
			return FALSE;
		}
				
		OrderByte = bReceive[1]&0x0F;//分析命令类型
		switch(OrderByte) 
		{
			case 0x00:
				m_nOrderType = LINK_RESET;
				break;
			case 0x09: 
				m_nOrderType = REQ_LINK;
				break;
			case 0x0a:
				m_nOrderType = READ_CLASS1;
				break;
			case 0x0b:
				m_nOrderType = READ_CLASS2;
				break;
			case 0x0c:
				m_nOrderType = READ_FAULT_DATA;
				break;
			default:
				m_nOrderType = UNDEFINE_ORDER;
		}
		bReceive.RemoveAt(0,5);
		
	}
	else
		if(bReceive[0] == 0x68)
		{
			if(bReceive.GetSize() < 6)//判断从0x68开始是否可能含有一个完整的命令
				return FALSE;                   //以0x68开始的报文至少有6个字节.
            
			if(bReceive.GetSize() < (bReceive[1]+6))//判断是否含有一个完整的命令
				return FALSE;
			
			if((BYTE)m_wAddr != bReceive[5])//判断所收报文目的地址是否为本FTU地址
			{
				bReceive.RemoveAt(0,(bReceive[1]+6));
				return FALSE;
			}
			
			for(int i=4; i < (bReceive[1]+4);i++)
				CSByte += bReceive[i];
			
			if( CSByte != bReceive[bReceive[1]+4])//判断校验码
			{
				bReceive.RemoveAt(0,(bReceive[1]+6));
				return FALSE;
			}
			
		    m_chTypeMark = bReceive[6];
			
			if(m_chTypeMark == 0x2e)
			{
				State = bReceive[8];
				OrderByte = bReceive[12];

				if((State == 0x06)&&(OrderByte == 0x82))
					m_nOrderType = CLOSE_SELECT;
				if((State == 0x06)&&(OrderByte == 0x02))
					m_nOrderType = CLOSE_EXECUTE;
				if((State == 0x06)&&(OrderByte == 0x81))
					m_nOrderType = OPEN_SELECT;
				if((State == 0x06)&&(OrderByte == 0x01))
					m_nOrderType = OPEN_EXECUTE;
				if((State == 0x08)&&(OrderByte == 0x02))
					m_nOrderType = CANCEL_CLOSE_SELECT;
				if((State == 0x08)&&(OrderByte == 0x01))
					m_nOrderType = CANCEL_OPEN_SELECT;

				/*if(m_bType&&m_bControl)
					m_nOrderType = CLOSE_EXECUTE;
				if((!m_bType)&&m_bControl)					
					m_nOrderType = CLOSE_SELECT;											
				if(m_bType&&(!m_bControl))
					m_nOrderType = OPEN_EXECUTE;
				if((!m_bType)&&(!m_bControl))					
					m_nOrderType = OPEN_SELECT;	*/
											
			}
			else
				if (m_chTypeMark == 0x65)
				{
					if(bReceive[12] == 0x41)
						m_nOrderType = READ_COUNT;
					else
						m_nOrderType = UNDEFINE_ORDER;

				}
			else
				if (m_chTypeMark == 0x67) 
				{
					if (bReceive[8] == 0x06) 
					{
						m_nOrderType = SYN_TIME;
						for(int n=0;n<7;n++)
						{
							m_bTimeData[n] = bReceive[12+n];
						}
					}
					else
						m_nOrderType = UNDEFINE_ORDER;
				}
			else
				if (m_chTypeMark == 0x69) 
				{
					if(bReceive[8] == 0x06)
						m_nOrderType = RTU_RESET;
					else
						m_nOrderType = UNDEFINE_ORDER;
				}
			else
				m_nOrderType = UNDEFINE_ORDER;

			bReceive.RemoveAt(0,(bReceive[1]+6));
							
		}		
		return TRUE;
}

int CProtocol101::Respond(CByteArray& bSend)
{
	switch(m_nOrderType) 
	{
		case RTU_RESET:
			RespondRTUReset(bSend);
			break;
		case LINK_RESET:
			RespondLinkReset(bSend);
			break;
		case SYN_TIME:
			RespondSynTime(bSend);
			break;
		case READ_CLASS1:
			RespondReadClass1(bSend);
			break;
		case READ_CLASS2:
			RespondReadClass2(bSend);
			break;
		case OPEN_SELECT:
			RespondOpenSelect(bSend);
			break;
		case OPEN_EXECUTE:
			RespondOpenExecute(bSend);
			break;
		case CLOSE_SELECT:
			TRACE("close select");
			RespondCloseSelect(bSend);
			break;
		case CLOSE_EXECUTE:
			RespondCloseExecute(bSend);
			break;
		case READ_COUNT:
			RespondReadCount(bSend);
			break;
		case CANCEL_OPEN_SELECT:
			RespondCancelOpenSelect(bSend);
			break;
		case CANCEL_CLOSE_SELECT:
			RespondCancelCloseSelect(bSend);
			break;
		case READ_FAULT_DATA:
			RespondReadFaultData(bSend);
		default:
			;
	}

	return m_nOrderType;

}

void CProtocol101::RespondRTUReset(CByteArray &bSend)
{
	BYTE CSByte = 0;	
	BYTE bMessageLen;
	
	bMessageLen = 15;
	bSend.SetSize(bMessageLen);
	
	bSend[0] = 0x68;
	bSend[1] = bSend[2] = 0x09;
	bSend[3] = 0x68;
	bSend[4] = 0x80;
	bSend[5] = bSend[9] = BYTE(m_wAddr);
	bSend[6] = 0x69;
	bSend[7] = 0x01;
	bSend[8] = 0x07;
	
	bSend[10] = 0x00;
	bSend[11] = 0x00;
	bSend[12] = 0x01;
	for(int i=4;i<13;i++)
		CSByte += bSend[i];
	bSend[13] = CSByte;
	bSend[14] = 0x16;
	
}

void CProtocol101::RespondLinkReset(CByteArray& bSend)
{
	BYTE CSByte = 0;
	BYTE bMessageLen;
	
	bMessageLen = 5;
	bSend.SetSize(bMessageLen);
	bSend[0] = 0x10;
	bSend[1] = 0x80;
	bSend[2] = BYTE(m_wAddr);
	CSByte = bSend[1]+bSend[2];

	bSend[3] = CSByte;
	bSend[4] = 0x16;
	
}

void CProtocol101::RespondSynTime(CByteArray &bSend)
{
	BYTE CSByte = 0;
	BYTE bMessageLen;

	bMessageLen = 21;
	bSend.SetSize(bMessageLen);

	bSend[0] = 0x68;
	bSend[1] = bSend[2] = 0x15;
	bSend[3] = 0x68;
	bSend[4] = 0x80;//C
	bSend[5] = bSend[9] = BYTE(m_wAddr);
	bSend[6] = 0x67; //类型标识
	bSend[7] = 0x01;//信息体个数
	bSend[8] = 0x07;//传送原因

	bSend[10] = 0x00;
	bSend[11] = 0x00;

	for(int i=0;i<7;i++)
		bSend[12+i] = m_bTimeData[i];

	for(int n=4;n<19;n++)
		CSByte += bSend[n];
	bSend[19] = CSByte;
	bSend[20] = 0x16;
	
}

void CProtocol101::RespondReadClass1(CByteArray& bSend)
{
	BYTE CSBtyte= 0;
	BYTE bMessageLen;

	bMessageLen = 12 + 3*(m_baDigital.GetSize());
	bSend.SetSize(bMessageLen);
	
	bSend[0] = 0x68;
	bSend[1] = bSend[2] = bMessageLen - 6;
	bSend[3] = 0x68;
	bSend[4] = 0xa8;//C
	bSend[5] = bSend[9] = BYTE(m_wAddr);
	bSend[6] = 0x01; //类型标识
	bSend[7] = BYTE(m_baDigital.GetSize());//信息体个数
	bSend[8] = 0x05;//传送原因
	
	for(int i = 0,n = 0;i<m_baDigital.GetSize(); i++)//
	{
		bSend[10+n] = BYTE(0xa1+i);
		bSend[11+n] = 0x0c;
		bSend[12+i] = m_baDigital[i];
		n += 3;
	}

	for(i = 4;i<bMessageLen-2;i++)
	{
		CSBtyte += bSend[i]; 
	}

	bSend[bMessageLen-2] = CSBtyte;
	bSend[bMessageLen-1] = 0x16;
}

void CProtocol101::RespondReadClass2(CByteArray& bSend)
{
	DWORD YCData = 0;
	BYTE *pYCByte = 0;	
	BYTE bCSByte = 0x00;
	BYTE bMessageLen = 0x00;
	if (m_paSOE.GetSize()>0) //是否发生故障
	{		
		CSOERec* SOEData;
		BYTE FaultType;
		WORD Milliseconds;
		BYTE Minutes;
		BYTE *pSOETime;

        bMessageLen = (m_paSOE.GetSize())*8+12;
		bSend.SetSize(bMessageLen);

		bSend[0] = 0x68;
		bSend[1] = bSend[2] = bMessageLen - 6;
		bSend[3] = 0x68;
		bSend[4] = 0xa8;
		bSend[5] = bSend[9] = BYTE(m_wAddr);
		bSend[6] = 0x11;//类型标识
		bSend[7] = BYTE(m_paSOE.GetSize());//信息体数目
		bSend[8] = 0x03;//传送原因
		for(int i = 0,n = 0;m_paSOE.GetSize()>0;i++)
		{
			SOEData = (CSOERec*)(m_paSOE.GetAt(0));
			FaultType = (SOEData->m_uDigitalNO)*2+1;
			if (SOEData->m_bOpened) //如果状态变为1,则FaultType加1,
			{                       //如果变为0,FaultType不加,详见SOE表
				FaultType += 1;     //即:,FALSE状态的在前,TURE状态的在后
			}						//因为每个遥信号对应着开/合两种状态.
			bSend[10+n] = FaultType;
			bSend[11+n] = 0x08;
			bSend[12+n] = 0x00;

			Milliseconds = (SOEData->m_stTime.wSecond)*1000 + SOEData->m_stTime.wMilliseconds;
            pSOETime = (unsigned char *)(&Milliseconds);
			bSend[13+n] = bSend[15+n] = pSOETime[0];
			bSend[14+n] = bSend[16+n] = pSOETime[1];
			
			Minutes = (BYTE)SOEData->m_stTime.wMinute;
			bSend[17+n] = Minutes;
			n += 8;

			m_paSOE.RemoveAt(0);
			delete SOEData;
		}
		
		for( i=4;i<bMessageLen-2;i++)
		{
			bCSByte += bSend[i];
		}

		bSend[bMessageLen-2] = bCSByte;
		bSend[bMessageLen-1] = 0x16;
		
		m_paSOE.RemoveAll();
		
	}
	else//无状态变位

⌨️ 快捷键说明

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