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

📄 iec103_xuji.cpp

📁 许继公司103规约源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		}
		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_XUJIPtl::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 = sizeof(ASDU_21_Fmt);
		PackLPDU(pTask->byDestNodeID, SendCon_code);
		return TRUE;
	}

	return FALSE;
}

// 组通用分类服务写命令
BOOL CIEC103_XUJIPtl::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_XUJIPtl::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_XUJIPtl::UnFrame(BYTE* pRecvBuf, INT nLen)
{
	//if (PtlRun_RecvLPDU == m_IEC103Data.m_runStep)
	{
		PtlSearch(pRecvBuf, nLen);   
	}
}

//规约数据搜索函数
void CIEC103_XUJIPtl::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_XUJIPtl::NoLPDU(void)
{
	BYTE* pSend = m_IEC103Data.m_bySend;
	
	BYTE addr = 0;
	if (0x10 == pSend[0])
	{
		LPDU_Fix_Fmt *pFmt = (LPDU_Fix_Fmt *)pSend;
		addr = pFmt->addr;
	}
	else
	{
		LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)pSend;
		addr = pHead->addr;
	}

	BYTE byNodeID = m_IEC103Data.m_addrtoID[addr];
	RealRunIED *pRunIed = m_IEC103Data.m_RunIed[byNodeID];	
	if (pRunIed)
	{
		pRunIed->linkRes = 1;
		pRunIed->lnkNoRecvCnt ++;
		if (pRunIed->lnkNoRecvCnt > 5)
		{
			CIED* pIED = pRunIed->pDevData;
			//DevYxPara devYx = pBayDev->GetDevYxPara();
			//pIED->SetYaoXinRecvVal(devYx.wComYxId, 1);
		}
	}
}

//链路层解帧
void CIEC103_XUJIPtl::UnpackLPDU(BYTE *pRecvBuf)
{
    // 链路层解帧
	BYTE* pRecv = pRecvBuf;
	
	LinkCtrl lnkCtrl;
	BYTE	 addr;
	// 固定帧长
	if (0x10 == pRecv[0])
	{	
		LPDU_Fix_Fmt *pFmt = (LPDU_Fix_Fmt *)pRecv;
		lnkCtrl = pFmt->ctrl;
		addr = pFmt->addr;
	}
	else
	{	// 可变帧长
		LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)pRecv;
		lnkCtrl = pHead->ctrl;
		addr = pHead->addr;
	}
	
	BOOL bACD = FALSE;
	BYTE byNodeID = m_IEC103Data.m_addrtoID[addr];
	RealRunIED *pRunIed = m_IEC103Data.m_RunIed[byNodeID];
	if (pRunIed)
	{
		// 链路恢复正常
		if (pRunIed->linkRes)
		{
			pRunIed->linkRes = pRunIed->linkQuery = pRunIed->fcb = 0;
			pRunIed->queryFull = pRunIed->query = 1;

			// 通讯恢复正常
			pRunIed->lnkNoRecvCnt = 0;
			//CIED *pIED = pRunIed->pDevData;
			//DevYxPara devYx = pBayDev->GetDevYxPara();
			//pBayDev->SetYaoXinRecvVal(devYx.wComYxId, 0);
		}	
		if (0x68 == pRecv[0])
		{	
			UnpackASDU_Ied(pRecvBuf, pRunIed);
		}

		pRunIed->acd = lnkCtrl.fcbAcd;
		pRunIed->linkQuery = lnkCtrl.fcvDfc;

		if(pRunIed->acd)//080905修改,适应现场需要,如果有1级数据立刻查询,不再等到下一轮
		{
			m_IEC103Data.m_byCycCnt = byNodeID;
			bACD = TRUE;
		}
	}
	//if(!bACD)//080905修改,适应现场需要,如果有1级数据立刻查询,不再等到下一轮
	//	m_IEC103Data.m_byCycCnt = (m_IEC103Data.m_byCycCnt+1) % CH_MAX_IED_NUM;

	// 转入组帧过程
	m_IEC103Data.m_runStep = PtlRun_PackASDU;
}

/*****
*UnpackASDU_Ied - 应用层解帧函数
*
*功能:
*	应用服务数据单元解帧函数 
*
******/
void CIEC103_XUJIPtl::UnpackASDU_Ied(BYTE *pRecvBuf, RealRunIED *pRunIed)
{
	// 防护
	if (!pRunIed)
		return;

	ASDU_Head *pHead = (ASDU_Head *)(pRecvBuf + sizeof(LPDU_Vol_Head));

	BYTE* buf = pRecvBuf + sizeof(LPDU_Vol_Head);
	BYTE  len = pRecvBuf[1] - 2;

	switch (pHead->type)
	{
	case M_TM_TA_3:
		Unpack_Asdu_1(buf, len, pRunIed);
		break;
	case M_TMR_TA_3:
		Unpack_Asdu_2(buf, len, pRunIed);
		break;
	case M_GD_NTA_3:
		Unpack_Asdu_10(buf, len, pRunIed);
		break;
	case M_MEVII_NA_3:
		Unpack_Asdu_50(buf, len, pRunIed);
		break;
	case M_IT_NA_3:
		Unpack_Asdu_36(buf, len-1, pRunIed);
		break;
	case M_IT_TA_3:
		Unpack_Asdu_37(buf, len-1, pRunIed);
		break;
	case M_MEI_NA_3:
		Unpack_Asdu_3(buf, len, pRunIed);
		break;
	case M_TME_TA_3:
		Unpack_Asdu_4(buf, len, pRunIed);
		break;
	case M_IRC_NA_3:
		{
			Unpack_Asdu_5(buf, len, pRunIed);
			if(pRunIed->step == eInitStart)
			{
				pRunIed->nASDU5Cnt++;
				if(pRunIed->nASDU5Cnt >= 2)
					pRunIed->step = eInitTime;
			}
			break;
		}
	case M_SYN_TA_3://时钟同步
		Unpack_Asdu_6(buf, len, pRunIed);
		if(eInitTime == pRunIed->step)
			pRunIed->step = eInitGenAsk;
		break;
	case M_TGI_NA_3://总招结束
		Unpack_Asdu_8(buf, len, pRunIed);
		if(eInitGenAsk == pRunIed->step)
		{
			pRunIed->step = eInitEnd;
			pRunIed->bCommInitFlag = FALSE;
			pRunIed->nASDU5Cnt = 0;
		}
		break;
	case M_MEII_NA_3:
		Unpack_Asdu_9(buf, len, pRunIed);
		break;
	case M_GI_NTA_3:
		Unpack_Asdu_11(buf, len, pRunIed);
		break;
	case M_LRT_TA_3:
		Unpack_Asdu_23(buf, len, pRunIed);
		break;
	case M_RTD_TA_3:
		Unpack_Asdu_26(buf, len, pRunIed);
		break;
	case M_RTC_NA_3:
		Unpack_Asdu_27(buf, len, pRunIed);
		break;
	case M_RTT_NA_3:
		Unpack_Asdu_28(buf, len, pRunIed);
		break;
	case M_TDT_TA_3:
		Unpack_Asdu_29(buf, len, pRunIed);
		break;
	case M_TDN_NA_3:
		Unpack_Asdu_30(buf, len, pRunIed);
		break;
	case M_EOT_NA_3:
		Unpack_Asdu_31(buf, len, pRunIed);
		break;
	case M_MEIII_TA_3:
		Unpack_Asdu_32(buf, len, pRunIed);
		break;
	case M_MEIV_TA_3:
		Unpack_Asdu_33(buf, len, pRunIed);
		break;
	case M_MEV_TA_3:
		Unpack_Asdu_34(buf, len, pRunIed);
		break;
	case M_MEVI_TA_3:
		Unpack_Asdu_35(buf, len, pRunIed);
		break;
	case M_ST_NA_3:
		Unpack_Asdu_38(buf, len, pRunIed);
		break;
	case M_ST_TA_3:
		Unpack_Asdu_39(buf, len, pRunIed);
		break;
	case M_SP_NA_3:
	case M_DP_NA_3:
		Unpack_Asdu_4042(buf, len-1, pRunIed);
		break;
	case M_SP_TA_3:
	case M_DP_TA_3:
		Unpack_Asdu_4143(buf, len-1, pRunIed);
		break;
	case M_SS_NA_3:
	case M_DS_NA_3:
		Unpack_Asdu_4446(buf, len-1, pRunIed);
		break;
	case M_SS_TA_3:
	case M_DS_TA_3:
		Unpack_Asdu_4547(buf, len-1, pRunIed);
		break;
	case M_WL_TA_3:
		Unpack_Asdu_48(buf, len, pRunIed);
		break;
	case M_DC_NA_3:
		Unpack_Asdu_64(buf, len, pRunIed);
		break;
	case M_RC_NA_3:			
		Unpack_Asdu_65(buf, len, pRunIed);
		break;
	case M_SE_NA_3:
		Unpack_Asdu_66(buf, len, pRunIed);
		break;
	case M_CC_NA_3:
		Unpack_Asdu_67(buf, len, pRunIed);
		break;
	case M_ASDU_70:
		Unpack_Asdu_70(buf, len, pRunIed);
		break;
	case M_CI_NA_3:
		Unpack_Asdu_88(buf, len, pRunIed);
		break;
	case 0x31://VQC装置上送保护事项的桢格式
	//	Unpack_Asdu_49(buf, len, pRunIed);
	default:
		break;
	}
}

// 带时标的报文(事项)
void CIEC103_XUJIPtl::Unpack_Asdu_1(BYTE* buf, BYTE len, RealRunIED *pRunIed)
{
	int nIndex;
	TASK *pTask = NULL;
	CIED *pIED = pRunIed->pDevData;
	BYTE byNodeID = pIED->m_IEDConfig.byNodeID;

	ASDU_1_Fmt *pFmt = (ASDU_1_Fmt *)buf;
	//调整时间
	WB_UNION wb;
	wb.bwUnion.byVal[0] = pFmt->tm.byHighMs;
	wb.bwUnion.byVal[1] = pFmt->tm.byLowMs;

	BYTE yxBit = (pFmt->dpi & 0x03) >> 1;
	// 命令确认报文(肯定/否定)
	if (M_AFM_ORD == pFmt->head.cot || M_NEG_ORD == pFmt->head.cot) 
	{
		if((WatchTask(pTask, taskCmdYkSelect, byNodeID) ||
			WatchTask(pTask, taskCmdYkExecute, byNodeID) ||
			WatchTask(pTask, taskCmdYkCancel, byNodeID)) && pTask)
		{
			// 遥控命令
			YK_COMMAND *pCommand = (YK_COMMAND *)pTask->iUserData;
			nIndex = GetnIndexbyFuninf(pIED, dataYk, pFmt->head.funInf);
			if(nIndex >= 0)
			{
				if (nIndex != pCommand->byYkNode || M_NEG_ORD == pFmt->head.cot) 
				{
					if (pCommand->byAction == yk_PrevH ||pCommand->byAction == yk_PrevF)
						pCommand->eReturn = fj_wrong;
					else
						pCommand->eReturn = act_wrong;
					pTask->eTaskReturn=retWrong;
				}
				else
				{
					if (pCommand->byAction == yk_PrevH ||pCommand->byAction == yk_PrevF)
						pCommand->eReturn = fj_right;
					else
						pCommand->eReturn = act_right;
					pTask->eTaskReturn=retRight;
				}
				pTask->eRespType = taskCmdYkReturn;
				m_pCH->TaskResp(pTask);
				//m_pCH->m_pTaskQue->UnLockTask();
			}
		}
		else if(WatchTask(pTask, taskCmdBhReset, byNodeID) && pTask)
		{// 保护复归
		/*	if (M_NEG_ORD == pFmt->head.cot)
				pTask->iUserData[0] = retWrong;
			else
				pTask->iUserData[0] = retRight;

			pTask->eRespType = taskRespBhReset;
			m_pCH->TaskResp(pTask);
			m_pCH->m_pTaskQue->UnLockTask();
		*/}

⌨️ 快捷键说明

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