📄 iec103_xuji.cpp
字号:
//m_pCH->m_pTaskQue->LockTask();
break;
case taskChThree:
{// 通道任务
bRtn = ChanTask(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
default: // 其他类型任务不支持
pTask->eStatus = tsNull;
break;
}
if (!bRtn && tsNull != pTask->eStatus)
{
// 召唤1级数据
BYTE byCode = CallClass2_code;
if (pDevRun->acd)
byCode = CallClass1_code;
PackLPDU_Fix(pTask->byDestNodeID, byCode);
bRtn = TRUE;
}
}
return bRtn;
}
// 通道任务 - 校时
BOOL CIEC103_XUJIPtl::SendAdjustTime103(TASK* pTask)
{
ASDU_6_Fmt *pFmt = (ASDU_6_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
memset(pFmt, 0, sizeof(ASDU_6_Fmt));
pFmt->head.type = 6;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 8;
pFmt->head.addr = 0xff;
pFmt->head.fun = 0xff;
pFmt->head.inf = 0;
TIME_STRUCT st;
g_pMainApp->GetSystime(&st);
pFmt->dataTime.year = st.nYear % 100;
pFmt->dataTime.month = st.byMonth;
pFmt->dataTime.bay = st.byDay;
pFmt->dataTime.week = 0;
pFmt->dataTime.time.Hours = st.byHour;
pFmt->dataTime.time.Minutes = st.byMinute;
WORD wtmp = st.bySecond * 1000 + st.nMs;
pFmt->dataTime.time.byLowMs = lobyte(wtmp);
pFmt->dataTime.time.byHighMs = hibyte(wtmp);
LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)m_IEC103Data.m_bySend;
memset(pHead, 0, sizeof(LPDU_Vol_Head));
pHead->head1 = pHead->head2 = 0x68;
pHead->len1 = pHead->len2 = ASDU6Fmt_LEN + 2;
pHead->ctrl.funcode = NoReply_code;
pHead->ctrl.prm = 1;
pHead->addr = 0xff;
m_IEC103Data.m_wSendNum = sizeof(LPDU_Vol_Head) + ASDU6Fmt_LEN;
m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = SumMod(m_IEC103Data.m_bySend + 4, pHead->len1);
m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = 0x16;
pTask->eStatus = tsSuccess;
return TRUE;
}
BOOL CIEC103_XUJIPtl::SendAdjustTime103(BYTE byaddr)
{
ASDU_6_Fmt *pFmt = (ASDU_6_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
memset(pFmt, 0, sizeof(ASDU_6_Fmt));
pFmt->head.type = 6;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 8;
pFmt->head.addr = byaddr;
pFmt->head.fun = 0xff;
pFmt->head.inf = 0;
TIME_STRUCT st;
g_pMainApp->GetSystime(&st);
pFmt->dataTime.year = st.nYear % 100;
pFmt->dataTime.month = st.byMonth;
pFmt->dataTime.bay = st.byDay;
pFmt->dataTime.week = 0;
pFmt->dataTime.time.Hours = st.byHour;
pFmt->dataTime.time.Minutes = st.byMinute;
WORD wtmp = st.bySecond * 1000 + st.nMs;
pFmt->dataTime.time.byLowMs = lobyte(wtmp);
pFmt->dataTime.time.byHighMs = hibyte(wtmp);
LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)m_IEC103Data.m_bySend;
memset(pHead, 0, sizeof(LPDU_Vol_Head));
pHead->head1 = pHead->head2 = 0x68;
pHead->len1 = pHead->len2 = ASDU6Fmt_LEN + 2;
if(byaddr == 0xff)
pHead->ctrl.funcode = NoReply_code;
else
pHead->ctrl.funcode = SendCon_code;
pHead->ctrl.prm = 1;
pHead->addr = byaddr;
m_IEC103Data.m_wSendNum = sizeof(LPDU_Vol_Head) + ASDU6Fmt_LEN;
m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = SumMod(m_IEC103Data.m_bySend + 4, pHead->len1);
m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = 0x16;
return TRUE;
}
//遥控命令组帧
BOOL CIEC103_XUJIPtl::PackYaoKong(TASK *pTask, RealRunIED *pDevRun)
{
Task103& task = m_IEC103Data.m_task103;
YK_COMMAND* pYkCom = (YK_COMMAND *)(pTask->iUserData);
if(!pYkCom || !pDevRun)
return FALSE;
CIED *pIED = pDevRun->pDevData;
if(!pIED)
return FALSE;
BOOL bChk = FALSE;
if (0 == task.wStep)
{
task.wStep ++;
FunInf funInf;
if(!GetFunInf(pDevRun->pDevData, dataYk, pYkCom->byYkNode, funInf))// 遥控命令fun+inf
return FALSE;
YK_PARA para;
if(!pIED->GetDataPara(dataYk,0,pYkCom->byYkNode,(void*)¶))
return FALSE;
DCC dcc = {0};
switch(pTask->eTaskType)
{
case taskCmdYkSelect: //遥控选择
dcc.se = 1;
if(pYkCom->byAction == yk_PrevH)
{
dcc.dcs = 2;
bChk = TRUE;
}else if(pYkCom->byAction == yk_PrevF)
{
dcc.dcs = 1;
bChk = TRUE;
}
break;
case taskCmdYkExecute: //遥控执行
if (pYkCom->byAction == yk_exec )
{
dcc.dcs = (m_IEC103Data.m_OldCmd.dcc).dcs; // 动作类型
bChk = TRUE;
}
break;
case taskCmdYkCancel: //遥控撤销
if (pYkCom->byAction == yk_cancel) {
dcc.dcs = (m_IEC103Data.m_OldCmd.dcc).dcs; // 动作类型描述
dcc.se = 1;
dcc.act = 1;
bChk = TRUE;
}
break;
default:
break;
}
if (!bChk)
return bChk;
// 记录动作类型描述
m_IEC103Data.m_OldCmd.dcc = dcc;
// 组帧
ASDU_64_Fmt *pFmt = (ASDU_64_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = 64;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 12;
pFmt->head.addr = para.nReserved0;//分cpu地址号
pFmt->head.funInf = funInf;
pFmt->dcc = dcc;
pFmt->rii = m_IEC103Data.m_bySin ++;
m_IEC103Data.m_wSendNum = sizeof(ASDU_64_Fmt);
PackLPDU(pTask->byDestNodeID, SendCon_code);
}
return bChk;
}
//召唤保护模拟量
//召唤保护模拟量,pTask->iUserData数组中填放数据说明
// 0 1.....
// 要召唤模拟量组包含的 通用分类组号
// 通用分类组个数
BOOL CIEC103_XUJIPtl::PackCallProtMea(TASK *pTask, RealRunIED *pDevRun)
{
Task103 &task = m_IEC103Data.m_task103;
GenerReadDesc &genRead = task.genRead;
if (0 == task.wStep)
{
// 没有保护模拟量,则不进行组帧命令
if(pDevRun->pDevData->m_IEDConfig.nBhAcLoopNum <= 0)
{
return FALSE;
}
// 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_XUJIPtl::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_XUJIPtl::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_XUJIPtl::PackEnableProtSetting(TASK *pTask, RealRunIED *pDevRun)
{
return PackGenerExec(pTask, pDevRun, TRUE);
}
//取消修改保护定值
BOOL CIEC103_XUJIPtl::PackCancelProtSetting(TASK *pTask, RealRunIED *pDevRun)
{
return PackGenerExec(pTask, pDevRun, FALSE);
}
//设置保护定值组
BOOL CIEC103_XUJIPtl::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) + sizeof(ASDU_10_Item);
PackLPDU(pTask->byDestNodeID, SendCon_code);
return TRUE;
}
return FALSE;
}
//确认设置的保护定值组
BOOL CIEC103_XUJIPtl::PackEnableProtSettingGroup(TASK *pTask, RealRunIED *pDevRun)
{
return PackGenerExec(pTask, pDevRun, TRUE);
}
//取消修改保护定值组
BOOL CIEC103_XUJIPtl::PackCancelProtSettingGroup(TASK *pTask, RealRunIED *pDevRun)
{
return PackGenerExec(pTask, pDevRun, FALSE);
}
// 保护复归
BOOL CIEC103_XUJIPtl::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 bycpuaddr;
if(!GetProtResetFuninfFromPara(pDevRun,funinf,bycpuaddr))
return FALSE;
pFmt->head.addr = bycpuaddr;
pFmt->head.funInf = funinf;
pFmt->dco = Off_dco;
pFmt->rii = m_IEC103Data.m_bySin ++;
m_IEC103Data.m_wSendNum = sizeof(ASDU_20_Fmt);
PackLPDU(pTask->byDestNodeID, SendCon_code);
task.wStep ++;
bRtn = TRUE;
ResetBhYx(pTask,pDevRun);
}
return bRtn;
}
//对保护装置虚摇信信号进行复归
void CIEC103_XUJIPtl::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_XUJIPtl::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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -