?? iec103_sf.cpp
字號:
}
// 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 + -