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

📄 tcp103.cpp

📁 此程序适用于电力系统中的网关程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************
* Copyright (c) 2004-2005, 许继日立公司
* All rights reserved.
* 
* 文件名称:tcp103.cpp
* 文件标识:
* 摘    要:tcp103类。主要处理103应用层信息,链路层套用104。
*
* 当前版本:1.0
* 作    者:李龙伟  <lilongwei1@hotmail.com>
* 完成日期:2004年11月24日
*
* 取代版本:1.0 
* 原作者  :李龙伟
* 完成日期:2004年11月24日
******************************************************************/

#include "tcp103.h"
#include "ntdef.h"
#include "ext.h"

/*====================================================================================
*                                                                                    
* Subroutine  : CTcp103()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from :                                     
* 
* Description : CTcp103类构造函数
* 
* Return	  :
*                                             
* Modification: 
*				 2004-11-24: 
*                                                                                     
*====================================================================================*/
CTcp103::CTcp103(BYTE no, short rlen, short slen) : BaseRule(no,rlen,slen)
{
	m_wSendCount = 0;
	m_wRevCount = 0;
	m_bRii = 0;
	m_bDataSend = false;			//是否连接标志

	m_bFrameLen = 0;
	memset(&m_bFrameBuf, 0x00, sizeof(unsigned char)*0x100);
	memset(&m_bYXInfBuf, 0x00, sizeof(BYTE)*512);
	memset(&m_bSector, 0x00, sizeof(BYTE)*512);

	ReadYXInf103();
}

/*====================================================================================
*                                                                                    
* Subroutine  : ~CTcp103()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from :                                     
* 
* Description : CTcp103类析构函数
* 
* Return	  :
*                                             
* Modification: 
*				 2004-11-24: 
*                                                                                     
*====================================================================================*/
CTcp103::~CTcp103()
{
}

/*====================================================================================
*                                                                                    
* Subroutine  : RuleLoop()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from : Rule_Data()                                    
* 
* Description : tcp103数据大循环函数
* 
* Return	  :
*                                             
* Modification: 
*				 2004-11-24: 
*                                                                                     
*====================================================================================*/
void CTcp103::RuleLoop()
{
	int			nResult = 0;	//返回值
	int			nResult1 = 0;	//返回值
	bool			bConnect = false;	//连接成功
	unsigned long	i_start;		//收到报文判断开始
	unsigned long	i_end;		//结束时间

	int tstop = 30;//??????

	i_start = GetTickCount();	//初始化
	i_end = GetTickCount();		//初始化
	//延时5秒钟,等待CDT规约连接正常
	Sleep(5000);

	while (1)
	{
		if (g_bSysStop) 
		{
			break;
		}
		if (BaseConnect(CHANNEL_SOCK) == 0) 
		{
			Sleep(10);
			continue;
		}

		while (1)
		{			
			Sleep(10);
			
			nResult = BaseRead(1, 0, CHANNEL_SOCK);	
			
			
			if ( nResult > 0 ) 
			{
///////////////////////////
				printf("receive \n");
				for (int i=0; i<m_wRevLen; i++)
				{
					printf("%02x ", m_bRevBuf[i]);
				}
				printf("\n");
///////////////////////////
				do
				{
					nResult = CheckRevData();
					if (nResult != 0)
					{
						nResult1 = TcpHeart();
						if ((nResult1 == 0) 
							&& (m_bDataSend))
						{
							UnpackData(); 
						}
						else if (m_bDataSend)
						{
							GetYC();
						}
						SetNetState(GATE_CLOSE);
						i_start = GetTickCount();
						bConnect = true;
						PackData();
///////////////////////////
						printf("send \n");
				for (int i=0; i<m_wSendLen; i++)
				{
					printf("%02x ", m_bSendBuf[i]);
				}
				printf("\n");
///////////////////////////
					}
					else 
					{
						i_end = GetTickCount();
						if (((i_end-i_start) / 1000) > tstop)
						{
							SetNetState(GATE_UNCLOSE);
							m_bDataSend = false;	//连接失败
							bConnect = false;
							break;
						}
					}
				}while(m_wRevLen != 0);

				if (!bConnect)
				{
					break;
				}
			}
			
			else
			{
				i_end = GetTickCount();				
				if ((i_end-i_start) / 1000 > tstop) 
				{
					m_bDataSend = false;	//连接失败
					bConnect = false;
					SetNetState(GATE_UNCLOSE);
					break;
				}
			}
//			PackData();
		}
	}
}

/*====================================================================================
*                                                                                    
* Subroutine  : CheckRevData()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from : RuleLoop()                                    
* 
* Description : 校验收到的数据是否正确
* 
* Return	  : 0   不正确
*               !=0 正确                       
* Modification: 
*				 2004-12-03: 
*                                                                                     
*====================================================================================*/
int CTcp103::CheckRevData(void)
{
	unsigned int	nLength = 0;	//长度
	unsigned char	nResult = 0;	//起始符

	nLength = m_bRevBuf[1];
	if ((m_bRevBuf[0] == 0x68)
		|| (m_wRevLen >= (nLength+2)))
	{
		m_bFrameLen = nLength + 2;
		memcpy(&m_bFrameBuf[0], &m_bRevBuf[0], m_bFrameLen);
		memcpy(&m_bRevBuf[0], &m_bRevBuf[m_bFrameLen], m_wRevLen-m_bFrameLen);
		m_wRevLen -= m_bFrameLen;
		nResult = 1;
	}
	else
	{
		m_wRevLen = 0;
	}

	return nResult;
}

/*====================================================================================
*                                                                                    
* Subroutine  : TcpHeart()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from : UnpackData()                                    
* 
* Description : 控制域数据处理
* 
* Return	  : 0 数据没有处理完,需要应用层数据
*               !0 数据已经处理完并打包                  
* Modification: 
*				 2004-12-13: 
*                                                                                     
*====================================================================================*/
int CTcp103::TcpHeart(void)
{
	int			nResult = 0;	//返回值
	int			iLength = 0;	//数据长度
	unsigned char	bType1 = 0;//报文类型
	unsigned char	bType2 = 0;//报文类型
	bool			bStart = false;	//开始标志
	bool			bStop = false;	//结束标志
	bool			bTest = false;	//测试标志
	DATA_STR		DataInfo;		//数据信息格式

	memset(&DataInfo, 0x00, sizeof(DATA_STR));
	iLength = m_bFrameBuf[1];
	bType1 = m_bFrameBuf[2] & 0x01;

	m_wRevCount+=2;		//最低位未使用
//	m_wSendCount+=2;		//最低位未使用
	//固定长的报文格式
	if (bType1 != 0)
	{
		nResult = 1;
		if (m_bFrameBuf[2] & 0x04)
		{
			bStart = true;
		}
		if (m_bFrameBuf[2] & 0x10)
		{
			bStop = true;
		}
		if (m_bFrameBuf[2] & 0x40)
		{
			bTest = true;
		}

		DataInfo.ApduHead.bStartCode = 0x68;
		DataInfo.ApduHead.bApduLength = 0x04;
		DataInfo.ApduHead.bControlCode2 = 0;
		DataInfo.ApduHead.bControlCode3 = 0;
		DataInfo.ApduHead.bControlCode4 = 0;
		bType2 = m_bFrameBuf[2] & 0x02;
		if ( (iLength == 4)
			&& (bType2!=0x00)
			&& (bStart)
			&& (!bTest))
		{
			m_bDataSend = true;
			DataInfo.ApduHead.bControlCode1 = 0x0b;
			m_SendList.push_back(DataInfo);
			ID_State(m_iAddress, 1);////////////////??
		}
		else if ((iLength == 4)
			&& (bType2 != 0x00)
			&& (bStop))
		{
			m_bDataSend = false;
			DataInfo.ApduHead.bControlCode1 = 0x23;
			m_SendList.push_back(DataInfo);
		}
		else if ( (iLength == 4)
			&& (bType2 != 0x00)
			&& (bTest))
		{
			DataInfo.ApduHead.bControlCode1 = 0x83;
			m_SendList.push_back(DataInfo);
		}
		else
		{
			DataInfo.ApduHead.bControlCode1 = 1;
			DataInfo.ApduHead.bControlCode3 = m_wRevCount % 0x100;
			DataInfo.ApduHead.bControlCode4 = m_wRevCount / 0x100;
			m_SendList.push_back(DataInfo);
		}
	}

	return nResult;
}

/*====================================================================================
*                                                                                    
* Subroutine  : UnpackData()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from : RuleLoop()                                    
* 
* Description : 对103数据进行解包处理
* 
* Return	  : 
*                                     
* Modification: 
*				 2004-12-03: 
*                                                                                     
*====================================================================================*/
void CTcp103::UnpackData(void)
{
	unsigned char	bFrameType = 0;	//帧类型
	unsigned char	bInf = 0;		//信息序号

	bInf = m_bFrameBuf[13];

	bFrameType = m_bFrameBuf[6];
	switch (bFrameType) 
	{
	case CMDCODE_GI_103:		//总召唤
		GeneralInquire();
		break;
	case CMDCODE_TIME_103:		//时间同步
		CalibrateTime();
		m_wSendCount += 2;	//最低位未使用
		break;
	case CMDCODE_NORMAL_103:	//一般命令,复归使用
		NormalCommand();
		m_wSendCount += 2;	//最低位未使用
		break;
	case CMDCODE_BREAK_103:		//断路器控制
	case CMDCODE_SWITCH_103:	//调压开关升降
		RtuControl();
		m_wSendCount += 2;	//最低位未使用
		break;
	case CMDCODE_VALUE_103:		//定值命令
		SettingOperate(bInf);
		m_wSendCount += 2;	//最低位未使用
		break;
	case CMDCODE_REPORT_103:	//故障报告
		break;
	case CMDCODE_AMMETER_103:	//电度信息
		break;
	case CMDCODE_FREEZE_103:	//电度冻结
		break;
	case CMDCODE_CHECK_103:		//自检与运行事件信息
		break;	
	default:
		break;
	}
	return;
}

/*====================================================================================
*                                                                                    
* Subroutine  : PackData()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from : RuleLoop()                                    
* 
* Description : 对103数据进行打包处理
* 
* Return	  : 
*                                     
* Modification: 
*				 2004-12-03: 
*                                                                                     
*====================================================================================*/
void CTcp103::PackData(void)
{
	int			i = 0;	//一般变量
	int			bLength = 0;//存储的值长度
	int			ret = 0;	//返回值变量
	unsigned char	index = 0;	//序号
	DATA_STR		DataInfo;	//数据信息格式

	memset(&DataInfo, 0x00, sizeof(DATA_STR));
	ret = PutSendList();

	while (!m_SendList.empty()) 
	{
		DataInfo = m_SendList.front();
		m_SendList.pop_front();

		m_bSendBuf[index++] = DataInfo.ApduHead.bStartCode;
		m_bSendBuf[index++] = DataInfo.ApduHead.bApduLength;	
		m_bSendBuf[index++] = DataInfo.ApduHead.bControlCode1;
		m_bSendBuf[index++] = DataInfo.ApduHead.bControlCode2;
		m_bSendBuf[index++] = DataInfo.ApduHead.bControlCode3;
		m_bSendBuf[index++] = DataInfo.ApduHead.bControlCode4;

		if (DataInfo.ApduHead.bApduLength > 4)
		{
			m_bSendBuf[index++] = DataInfo.AsduHead.bAsduType;
			m_bSendBuf[index++] = DataInfo.AsduHead.bAsduVsq;
			m_bSendBuf[index++] = DataInfo.AsduHead.nAsduCot % 0x100;
			m_bSendBuf[index++] = DataInfo.AsduHead.nAsduCot / 0x100;
			m_bSendBuf[index++] = DataInfo.AsduHead.nAsduComAddr % 0x100;//单元公共地址//?? 
			m_bSendBuf[index++] = DataInfo.AsduHead.nAsduComAddr / 0x100;//单元公共地址 //??
			m_bSendBuf[index++] = DataInfo.AsduHead.bAsduFun;//fun 
			m_bSendBuf[index++] = DataInfo.AsduHead.bAsduInf;//inf 

			bLength = DataInfo.bDataVec.size();
			for (i=0; i<bLength; ++i)
			{
				m_bSendBuf[index++] = DataInfo.bDataVec[i];
			}
		}
		m_wSendLen = index;

		BaseSend(CHANNEL_SOCK);
	}

	return;

}

/*====================================================================================
*                                                                                    
* Subroutine  : GeneralInquire()
*                                                                                    
* Parameters  :
*               
*                                                                                    
* Called from : RuleLoop()
* 
* Description : 总召唤响应
* 
* Return	  : 
*               
*                                             
* Modification: 
*				 2004-07-29: 
*                                                                                     
*====================================================================================*/
void CTcp103::GeneralInquire(void)
{
	int			i = 0;		//常用变量
	int			nResult;		//常用变量,返回值
	int			nNumber;		//遥信数量

⌨️ 快捷键说明

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