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

📄 iec103_sf.cpp

📁 四方公司103规约
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			}

			//	InitTaskRespBuf(pTask);

			genRead.grpCnt = 0;
			GetGininf(pDevRun->pDevData, pTask, dataBhAc, genRead.grpNum, genRead.readGrp);
		}

		return PackGenerReadCmd(pTask, pDevRun);
	}

	//召唤保护定值
	//召唤保护定值,pTask->iUserData数组中填放数据说明
	//   0				1				2					3.....
	//召唤定值组号	定值组总个数  要召唤定值组包含的	通用分类组号	
	//								通用分类组个数
	BOOL CIEC103_SFPtl::PackCallProtSetting(TASK *pTask, RealRunIED *pDevRun)
	{
		Task103 &task = m_IEC103Data.m_task103;
		GenerReadDesc &genRead = task.genRead;

		if (0 == task.wStep)
		{
			BYTE byReadID = pTask->iUserData[0];		//得到要召唤的定值组号
			BOOL bChk = FALSE;
			if (pDevRun->pDevData->m_IEDConfig.nDzNum > 0)
			{
				// 召唤的定值组号
				if (0xff == pTask->iUserData[0])	
					byReadID = 0;

				BYTE bySettingGrpNum = GetSettingGrpNum(pDevRun->pDevData, pTask);
				if (byReadID < bySettingGrpNum)
				{
					//InitTaskRespBuf(pTask);
					genRead.grpCnt = 0;
					GetGininf(pDevRun->pDevData, pTask, dataSetting, genRead.grpNum, genRead.readGrp);
					bChk = TRUE;
				}
			}
			if (!bChk) 
				return FALSE;
		}
		return PackGenerReadCmd(pTask, pDevRun);
	}
	//修改保护定值
	/*
	*PackModifyProtSetting - 修改保护定值组帧
	* 固定格式
	*	描述					偏移量				占位空间	
	*-------------------------------------------------------
	*	相应数据总长度			0~1				2
	*	**103数据帧总个数N		2~3				2
	*/
	BOOL CIEC103_SFPtl::PackModifyProtSetting(TASK *pTask, RealRunIED *pDevRun)
	{
		Task103 &task = m_IEC103Data.m_task103;
		GenerWriteDesc &genWrite = task.genWrite;

		//BYTE byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
		BYTE byAddr = 0;
		if(m_IEC103PtlPara.bCommAddr)
			byAddr = m_IEC103PtlPara.byBHCPUAddr;
		else
			byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;

		if(!pTask->bWithDataF || pTask->pbyBuff == NULL)//没有用户附加数据,直接返回
			return FALSE;
		ModifyProtSettingHead *pProtSetHead = (ModifyProtSettingHead *)(pTask->pbyBuff);
		BYTE  byLinkLen = 0;
		if (0 == task.wStep) 
		{
			genWrite.wSendFmtCnt = 0;
			genWrite.wSendPos = 4;
			genWrite.rii = m_IEC103Data.m_bySin ++;

			// 去除第一组的定值组号
			byLinkLen = *(pTask->pbyBuff + genWrite.wSendPos);
			genWrite.wSendPos += 1;
			genWrite.wSendFmtCnt ++;
		}

		if (task.wStep % 2 == 0) 
		{		
			if(task.wStep != 0)
			{
				byLinkLen = *(pTask->pbyBuff + genWrite.wSendPos);
				genWrite.wSendPos += 1;
				genWrite.wSendFmtCnt ++;
			}
			memcpy(m_IEC103Data.m_bySend, pTask->pbyBuff + genWrite.wSendPos, byLinkLen);
			genWrite.wSendPos += byLinkLen;

			task.wStep ++;

			ASDU_10_Head *pFmtHead = (ASDU_10_Head *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
			pFmtHead->head.type = 10;
			pFmtHead->head.vsq.vsq = 0x81;
			pFmtHead->head.cot = 40;
			pFmtHead->head.addr = byAddr;
			pFmtHead->head.fun = 254;
			pFmtHead->head.inf = (genWrite.wSendFmtCnt == pProtSetHead->fmtNum) ?250 : 249;
			pFmtHead->rii = genWrite.rii;
			pFmtHead->ngd.count = (task.wStep / 2) % 2;
			pFmtHead->ngd.cont = (genWrite.wSendFmtCnt != pProtSetHead->fmtNum);

			m_IEC103Data.m_wSendNum = byLinkLen - 8;
			PackLPDU(pTask->byDestNodeID, SendCon_code);

			return TRUE;
		}

		return FALSE;
	}

	//确认保护定值
	BOOL CIEC103_SFPtl::PackEnableProtSetting(TASK *pTask, RealRunIED *pDevRun)
	{
		return PackGenerExec(pTask, pDevRun, TRUE);
	}

	//取消修改保护定值
	BOOL CIEC103_SFPtl::PackCancelProtSetting(TASK *pTask, RealRunIED *pDevRun)
	{
		return PackGenerExec(pTask, pDevRun, FALSE);
	}

	//设置保护定值组
	BOOL CIEC103_SFPtl::PackModifyProtSettingGroup(TASK *pTask, RealRunIED *pDevRun)
	{
		//BYTE byAdd = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
		BYTE byAddr = 0;
		if(m_IEC103PtlPara.bCommAddr)
			byAddr = m_IEC103PtlPara.byBHCPUAddr;
		else
			byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;

		Task103 &task = m_IEC103Data.m_task103;
		if (0 == task.wStep)
		{
			task.wStep ++;

			ASDU_10_Head *pHead = (ASDU_10_Head *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
			pHead->head.type = 10;
			pHead->head.vsq.vsq = 0x81;
			pHead->head.cot = 40;
			pHead->head.addr = byAddr;
			pHead->head.fun = 254;
			pHead->head.inf = 249;
			pHead->rii = m_IEC103Data.m_bySin ++;
			pHead->ngd.cont = pHead->ngd.count = 0;
			pHead->ngd.num = 1;

			ASDU_10_Item *pItem = (ASDU_10_Item *)(pHead + 1);
			GIN gin;
			GetProtSetGrpGin(pTask, gin);
			pItem->gin = gin;
			pItem->gdd.byDataTyp = 3;
			pItem->gdd.byDataSize = 1;
			pItem->gdd.num = 1;
			pItem->gdd.cont = 0;
			pItem->kod = 1;
			pItem->byVal = pTask->iUserData[0];

			m_IEC103Data.m_wSendNum = sizeof(ASDU_10_Head) + ASDU10ITEMLEN;
			PackLPDU(pTask->byDestNodeID, SendCon_code);
			return TRUE;		
		}

		return FALSE;
	}

	//确认设置的保护定值组
	BOOL CIEC103_SFPtl::PackEnableProtSettingGroup(TASK *pTask, RealRunIED *pDevRun)
	{
		return PackGenerExec(pTask, pDevRun, TRUE);
	}

	//取消修改保护定值组
	BOOL CIEC103_SFPtl::PackCancelProtSettingGroup(TASK *pTask, RealRunIED *pDevRun)
	{
		return PackGenerExec(pTask, pDevRun, FALSE);
	}

	// 保护复归
	BOOL CIEC103_SFPtl::PackProtRes(TASK *pTask, RealRunIED *pDevRun)
	{
		BYTE byAdd = pDevRun->pDevData->m_IEDConfig.byNodeAddr;

		BOOL bRtn = FALSE;
		Task103 &task = m_IEC103Data.m_task103;
		if (0 == task.wStep) 
		{
			ASDU_20_Fmt *pFmt = (ASDU_20_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
			pFmt->head.type = 20;
			pFmt->head.vsq.vsq = 0x81;
			pFmt->head.cot =  20;

			FunInf funinf;
			BYTE addr;
			if(!GetProtResetFuninfFromPara(pDevRun,funinf,addr))
				return FALSE;
			pFmt->head.addr = addr;
			pFmt->head.funInf = funinf;
			pFmt->dco = Off_dco;
			pFmt->rii = m_IEC103Data.m_bySin ++;

			m_IEC103Data.m_wSendNum = sizeof(ASDU_20_Fmt);
			if (addr == 0xff)
				PackLPDU(pTask->byDestDataID,NoReply_code);
			else
				PackLPDU(pTask->byDestNodeID, SendCon_code);

			task.wStep ++;
			bRtn = TRUE;
			ResetBhYx(pTask,pDevRun);

			//printf("ADDR = %d,FUN = %d,INF = %d,DOC = %d",addr,pFmt->head.funInf.fun,pFmt->head.funInf.inf,pFmt->dco);
		}

		return bRtn;
	}

	//对保护装置虚摇信信号进行复归
	void CIEC103_SFPtl::ResetBhYx(TASK *pTask, RealRunIED *pDevRun)
	{
		CIED *pIED = pDevRun->pDevData;
		int nBhYxNum = pIED->m_IEDConfig.nBhNum;
		for(int i=0; i<nBhYxNum; i++)
		{
			pIED->SetDataRecvVal(dataBhYx,0,i,0);
		}
	}

	// 通道任务
	//任务区结构描述
	//---------------------------------
	// 总长度		0~1			2
	// 帧个数		2~3			2
	// 第1帧长度	4			1
	// 第1帧		5			L+5
	BOOL CIEC103_SFPtl::ChanTask(TASK *pTask, RealRunIED *pDevRun)
	{
		Task103 &task = m_IEC103Data.m_task103;
		GenerWriteDesc &genWrite = task.genWrite;

		BYTE *pbyData = pTask->pbyBuff;
		if(!pTask->bWithDataF || pbyData == NULL)//没有附加数据
			return FALSE;

		WORD *pwLen = (WORD *)pbyData;
		WORD *pwFmtCnt = (WORD *)(pbyData + 2);
		genWrite.wSendNum = *(WORD *)(pbyData + 2);

		BYTE byAsduLen = 0;
		ASDU_Head *pHead = NULL;
		if (0 == task.wStep)
		{
			genWrite.wSendFmtCnt = 0;
			genWrite.wSendPos = 4;
			genWrite.rii = m_IEC103Data.m_bySin ++;

			byAsduLen = pbyData[genWrite.wSendPos];
			genWrite.wSendPos++;
			genWrite.wSendFmtCnt++;
			pHead = (ASDU_Head *)(pbyData + genWrite.wSendPos);
			// 复归命令
			if (C_GRC_NA_3 == pHead->type) 
			{	
				//task.pTask->status = timeOut;
			}
			else if (10 == pHead->type || 21 == pHead->type)
				;//InitTaskRespBuf(pTask);
		}

		if (task.wStep % 2 == 0)
		{
			// 链路数据
			if(task.wStep != 0)
			{
				byAsduLen = pbyData[genWrite.wSendPos];
				genWrite.wSendPos++;
				genWrite.wSendFmtCnt++;
				pHead = (ASDU_Head *)(pbyData + genWrite.wSendPos);
			}
			memcpy(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head), (BYTE *)pHead, byAsduLen);
			genWrite.wSendPos += byAsduLen;

			task.wStep ++;

			pHead = (ASDU_Head *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));

			BYTE byAddr = 0;
			if(m_IEC103PtlPara.bCommAddr)
				byAddr = m_IEC103PtlPara.byBHCPUAddr;
			else
				byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;

			pHead->addr = byAddr;

			m_IEC103Data.m_wSendNum = byAsduLen;
			PackLPDU(pTask->byDestNodeID, SendCon_code);
			return TRUE;
		}
		return FALSE;
	}

	// 通用分类服务读命令
	BOOL CIEC103_SFPtl::PackGenerReadCmd(TASK* pTask, RealRunIED *pDevRun)
	{
		Task103 &task = m_IEC103Data.m_task103;
		GenerReadDesc &genRead = task.genRead;

		//BYTE byAdd = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
		BYTE byAddr = 0;
		if(m_IEC103PtlPara.bCommAddr)
			byAddr = m_IEC103PtlPara.byBHCPUAddr;
		else
			byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
		// 通用分类读命令组帧
		if ((task.wStep % 2 == 0) && (genRead.grpCnt < genRead.grpNum))
		{
			task.wStep ++;

			ASDU_21_Fmt *pFmt = (ASDU_21_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
			pFmt->head.type = 21;
			pFmt->head.vsq.vsq = 0x81;
			pFmt->head.cot = 42;
			pFmt->head.addr = byAddr;
			pFmt->head.fun = 254;
			pFmt->head.inf = 241;
			pFmt->rii = m_IEC103Data.m_bySin ++;
			pFmt->nog = 1;
			pFmt->group = genRead.readGrp[genRead.grpCnt ++];
			pFmt->entry = 0;
			pFmt->kod = 1;

			m_IEC103Data.m_wSendNum = ASDU21FMTLEN;
			PackLPDU(pTask->byDestNodeID, SendCon_code);
			return TRUE;
		}

		return FALSE;
	}

	// 组通用分类服务写命令
	BOOL CIEC103_SFPtl::PackGenerExec(TASK* pTask, RealRunIED *pDevRun, BOOL bExec = TRUE)
	{
		Task103 &task = m_IEC103Data.m_task103;
		GenerReadDesc &genTask = task.genRead;

		//BYTE byAdd = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
		BYTE byAddr = 0;
		if(m_IEC103PtlPara.bCommAddr)
			byAddr = m_IEC103PtlPara.byBHCPUAddr;
		else
			byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;

		if (0 == task.wStep) 
		{
			task.wStep ++;

			ASDU_10_Head *pHead = (ASDU_10_Head *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
			pHead->head.type = 10;
			pHead->head.vsq.vsq = 0x81;
			pHead->head.cot = 40;
			pHead->head.addr = byAddr;
			pHead->head.fun = 254;
			pHead->head.inf = bExec ? 250 : 251;
			pHead->rii = m_IEC103Data.m_bySin ++;
			pHead->ngd.cont = pHead->ngd.count = pHead->ngd.num = 0;

			m_IEC103Data.m_wSendNum = sizeof(ASDU_10_Head);
			PackLPDU(pTask->byDestNodeID, SendCon_code);
			return TRUE;
		}
		return FALSE;
	}

	//链路发送数据
	INT CIEC103_SFPtl::PtlSendLPDU(void)
	{
		// 帧间隔判别
		if (!m_IEC103Data.m_frmDly33.IsOverTime(m_nCnt))
			return 0;

		m_IEC103Data.m_frmDly33.Start(m_nCnt);
		m_IEC103Data.m_frmOver.Start(m_nCnt);

		// 准备接收数据
		QueryRecvLPDU();

		// 转入应用层组帧过程
		if (SendNoreply == m_IEC103Data.m_lnkSvrCls)
			m_IEC103Data.m_runStep = PtlRun_PackASDU;
		else
			m_IEC103Data.m_runStep = PtlRun_RecvLPDU;

		return m_IEC103Data.m_wSendNum;
	}

	//解帧函数
	void CIEC103_SFPtl::UnFrame(BYTE* pRecvBuf, INT nLen)
	{
		//if (PtlRun_RecvLPDU == m_IEC103Data.m_runStep)
		{
			PtlSearch(pRecvBuf, nLen);   
		}
	}

	//规约数据搜索函数
	void CIEC103_SFPtl::PtlSearch(BYTE *pRecvBuf, INT nLen)
	{	
		BYTE *pbyhead = NULL;
		for(INT nCnt=0; nCnt<nLen; nCnt++)
		{
			if(0x10 == pRecvBuf[nCnt] || 0x68 == pRecvBuf[nCnt])//搜索到帧头
			{
				pbyhead = pRecvBuf + nCnt;
				break;
			}
		}
		BYTE bySum = 0;
		if(pbyhead != NULL)
		{
			BOOL bLnkUnpack = FALSE;
			if(0x10 == pbyhead[0])			//固定帧
			{
				bySum = pbyhead[1] + pbyhead[2];
				if(bySum == pbyhead[3] && 0x16 == pbyhead[4])
				{
					bLnkUnpack = TRUE;
					m_IEC103Data.m_wLinkLen = 5;
				}
				else
					m_IEC103Data.m_lnkSerialError ++;
			}
			else if(0x68 == pbyhead[0])	//可变帧
			{
				if (pbyhead[3] == pbyhead[0] && pbyhead[1] == pbyhead[2]) 
				{
					BYTE byLnkLen = pbyhead[1];
					bySum = SumMod(pbyhead + 4, pbyhead[1]);
					if(bySum == pbyhead[byLnkLen + 4] && 0x16 == pbyhead[byLnkLen + 4 + 1])
					{
						bLnkUnpack = TRUE;
						m_IEC103Data.m_wLinkLen = 4 + 2 + byLnkLen; 
					}
					else
						m_IEC103Data.m_lnkSerialError ++;
				}
				else
					m_IEC103Data.m_lnkSerialError ++;
			}
			if(bLnkUnpack)				//开始解帧
			{
				// 链路层解帧
				UnpackLPDU(pbyhead);
				QueryRecvLPDU();
				m_IEC103Data.m_lnkSerialError = 0;
			}
		}
	}

	// 链路层无数据接收
	void CIEC103_SFPtl::NoLPDU(void)
	{
		BYTE* pSend = m_IEC103Data.m_bySend;

		BYTE addr = 0;

⌨️ 快捷键说明

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