?? iec103_xuji.cpp
字號:
else
DafaultPtlPara();
m_pCH->m_ChConfig.byPtlKind=0;
m_ePtlType = ptl103;
for(i=0; i<m_pCH->m_ChConfig.byIEDNum; i++)
{
CIED *pIED = m_pCH->m_pIED[i];
if(pIED == NULL)
continue;
CreateRealRunIED(pIED);
m_IEC103Data.m_addrtoID[pIED->m_IEDConfig.byNodeAddr] = pIED->m_IEDConfig.byNodeID;
}
// 規約運行步驟
m_IEC103Data.m_runStep = PtlRun_PackASDU;
m_IEC103Data.m_byCycCnt = 0;
// 規約任務區
memset(&m_IEC103Data.m_task103, 0, sizeof(m_IEC103Data.m_task103));
// 服務原語
memset(&m_IEC103Data.m_prmSend, 0, sizeof(CommPrim));
memset(&m_IEC103Data.m_prmRecv, 0, sizeof(CommPrim));
// 收發緩沖區
m_IEC103Data.m_wLinkLen = 0;
m_IEC103Data.m_wSendNum = 0;
// 計時器初始化
DWORD dwRatio = GetChRatio();
DWORD dwDly = (3*11*1000 + dwRatio-1) / dwRatio;
// 幀超時時間
m_IEC103Data.m_frmOver.SetWaitSpan(m_IEC103PtlPara.dwFrameOver);
// 幀間隔時間
m_IEC103Data.m_frmDly33.SetWaitSpan(dwDly);
// 總召喚間隔
m_IEC103Data.m_queryCnt.SetWaitSpan((m_IEC103PtlPara.dwQuery/2) * 1000);
m_IEC103Data.m_queryCnt.Start(m_nCnt);
//校時間隔
m_IEC103Data.m_timeover.SetWaitSpan(m_IEC103PtlPara.wTimeOver * 1000);
m_IEC103Data.m_timeover.Start(m_nCnt);
// 通道無數據接收監視,
m_IEC103Data.m_lnkSerialError = 0;
m_IEC103Data.m_bySendCnt = 0;
m_IEC103Data.m_bySin = 0;
memset(&m_IEC103Data.m_OldCmd, 0, sizeof(m_IEC103Data.m_OldCmd));
QueryRecvLPDU();
m_nCnt = 0;
SetTimer(2);
m_bAdjustTime = false;
}
void CIEC103_XUJIPtl::OnTimer(void)
{
m_nCnt++;
}
//組幀函數
INT CIEC103_XUJIPtl::Frame(BYTE* pSendBuf, INT nLen)
{
INT nret = 0;
// 總召喚/召喚脈沖計數定時到
if (m_IEC103Data.m_queryCnt.IsOverTime(m_nCnt))
{
m_IEC103Data.m_queryCnt.Start(m_nCnt);
for (int i = 0; i < CH_MAX_IED_NUM; i++)
{
RealRunIED *pRunIED = m_IEC103Data.m_RunIed[i];
if(pRunIED)
{
pRunIED->queryFull ^= 1; // 查詢標志取反
pRunIED->query = 1;
}
}
}
/*應用層組幀
* 1) 發送通道任務命令
* 2) 發送普通的循環任務
*/
if (PtlRun_PackASDU == m_IEC103Data.m_runStep)
{
// 要求進行組幀處理
m_IEC103Data.m_wSendNum = 0;
m_IEC103Data.m_wLinkLen = 0;
// 初始化服務原語
memset(&m_IEC103Data.m_prmSend, 0, sizeof(CommPrim));
memset(&m_IEC103Data.m_prmRecv, 0, sizeof(CommPrim));
// 通道任務檢測
if (!PackTask())
{
PackCyc(); // 循環查詢任務
}
// 轉入鏈路幀發送過程
m_IEC103Data.m_bySendCnt = 0;
if (m_IEC103Data.m_wSendNum > 0)
m_IEC103Data.m_runStep = PtlRun_SendLPDU;
}
// 輔機直接轉入鏈路接收過程中
/*if (!lpCh->m_pDevDB->GetCcsModule( ))
{
pPtlData->m_runStep = PtlRun_RecvLPDU;
QueryRecvLPDU(lpCh);
}*/
// 等待鏈路接收
if (PtlRun_RecvLPDU == m_IEC103Data.m_runStep)
{
if (m_IEC103Data.m_frmOver.IsOverTime(m_nCnt))
{
m_IEC103Data.m_bySendCnt ++;
if (m_IEC103Data.m_bySendCnt > 2)
{
NoLPDU();
m_IEC103Data.m_runStep = PtlRun_PackASDU;
}
else
m_IEC103Data.m_runStep = PtlRun_SendLPDU;
}
}
// 鏈路層發送
if (PtlRun_SendLPDU == m_IEC103Data.m_runStep)
{
// 主機發送數據,輔機僅接收數據
//if (lpCh->m_pDevDB->GetCcsModule( ))
//{
// 等待超時監視
if(m_bAdjustTime)
{
m_bAdjustTime = false;
m_IEC103Data.m_runStep = PtlRun_PackASDU;
nret = m_IEC103Data.m_wSendNum;
}else
nret = PtlSendLPDU();
memcpy(pSendBuf, m_IEC103Data.m_bySend, nret);
//}
}
return nret;
}
// 鏈路層傳輸服務
// 1. 站初始化
// 2. 鏈路狀態控制
BOOL CIEC103_XUJIPtl::PackLinkCmm(BYTE byNodeID)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeID];
if(!pDevRun)
return FALSE;
if (!pDevRun->linkQuery && !pDevRun->linkRes)
return FALSE;
if (pDevRun->linkRes) { // 初始化
PackLPDU_Fix(byNodeID, ResCU_code);
pDevRun->bCommInitFlag = TRUE;
pDevRun->nASDU5Cnt = 0;
pDevRun->step = eInitStart;
}else if (pDevRun->linkQuery){ // 鏈路狀態
PackLPDU_Fix(byNodeID, QueryLink_code);
}
return TRUE;
}
// 固定幀長鏈路數據組幀
void CIEC103_XUJIPtl::PackLPDU_Fix(BYTE byNodeID, BYTE byCode)
{
// if(m_IEC103Data.m_frmOver.IsOverTime(m_nCnt))
{
PackLPDU(byNodeID, byCode);
}
}
void CIEC103_XUJIPtl::PackLPDU(BYTE byNodeID, BYTE code)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeID];
if(!pDevRun)
return;
LinkCtrl linkCtrl;
linkCtrl.funcode = code;
linkCtrl.res = 0;
linkCtrl.prm = 1;
switch(code)
{
case ResCU_code:
case ResFcb_code:
m_IEC103Data.m_lnkSvrCls = SendConfirm;
linkCtrl.fcvDfc = 0;
break;
case NoReply_code:
m_IEC103Data.m_lnkSvrCls = SendNoreply;
linkCtrl.fcvDfc = 0;
break;
case QueryLink_code:
m_IEC103Data.m_lnkSvrCls = RequestRespond;
linkCtrl.fcvDfc = 0;
break;
case SendCon_code:
m_IEC103Data.m_lnkSvrCls = SendConfirm;
linkCtrl.fcvDfc = 1;
break;
case CallClass1_code:
case CallClass2_code:
m_IEC103Data.m_lnkSvrCls = RequestRespond;
linkCtrl.fcvDfc = 1;
break;
default:
break;
}
// 鏈路幀控制字
linkCtrl.fcbAcd = 0;
if (linkCtrl.fcvDfc)
{
pDevRun->fcb = ~pDevRun->fcb;
linkCtrl.fcbAcd = pDevRun->fcb;
}
if (0 == m_IEC103Data.m_wSendNum)
{ // 固定幀長
LPDU_Fix_Fmt *pFmt = (LPDU_Fix_Fmt *)(m_IEC103Data.m_bySend);
pFmt->head = 0x10;
pFmt->ctrl = linkCtrl;
pFmt->addr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
pFmt->sum = pFmt->ctrl.lnkCtrl + pFmt->addr;
pFmt->tail = 0x16;
m_IEC103Data.m_wSendNum = sizeof(LPDU_Fix_Fmt);
}else {
LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)(m_IEC103Data.m_bySend);
pHead->head1 = pHead->head2 = 0x68;
pHead->len1 = pHead->len2 = m_IEC103Data.m_wSendNum + 2;
pHead->ctrl = linkCtrl;
pHead->addr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
m_IEC103Data.m_wSendNum += sizeof(LPDU_Vol_Head);
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;
}
}
//循環查詢組幀
/****
*PackCyc - 循環查詢組幀函數
*
*功能:
* 1。總查詢命令
* 2。故障錄波
* 3。通用分類服務總查詢
* 4。通用2級數據查詢
*
****/
void CIEC103_XUJIPtl::PackCyc(void)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[m_IEC103Data.m_byCycCnt];
if (pDevRun)
{
if (!PackLinkCmm(m_IEC103Data.m_byCycCnt))
{ // 鏈路層組幀
/*
* 應用層組幀
*
*命令優先級
* 1。擾動數據傳輸
* 2。通用分類服務總查詢
* 3。召喚電度脈沖量
* 4。總查詢(總召喚)
* 5。循環查詢2級數據
**/
if(pDevRun->bCommInitFlag && !pDevRun->acd)
{
if(eInitTime == pDevRun->step && pDevRun->nASDU5Cnt>=2)//校時
{
SendAdjustTime103(pDevRun->pDevData->m_IEDConfig.byNodeAddr);
}else if(eInitGenAsk == pDevRun->step)//總召喚
{
Pack_Asdu_7(m_IEC103Data.m_byCycCnt);
}else
{
BYTE Code = CallClass2_code;
PackLPDU_Fix(m_IEC103Data.m_byCycCnt, Code);
}
}else if (!pDevRun->acd && pDevRun->query && !pDevRun->bCommInitFlag)
{
if (!pDevRun->queryFull)
{// 召喚電度量
if(pDevRun->pDevData->m_IEDConfig.nDdNum > 0)
Pack_Asdu_88(m_IEC103Data.m_byCycCnt);
}else// 總召喚
Pack_Asdu_7(m_IEC103Data.m_byCycCnt);
// 清除查詢標志
pDevRun->query = 0;
}else if(m_IEC103Data.m_timeover.IsOverTime(m_nCnt) && !pDevRun->bCommInitFlag)//校時
{
m_IEC103Data.m_timeover.Start(m_nCnt);
BYTE byaddr = 0xff;
SendAdjustTime103(byaddr);
m_bAdjustTime = true;
}
else
{ // 通用查詢
BYTE byCode = CallClass2_code;
if (pDevRun->acd)
byCode = CallClass1_code;
PackLPDU_Fix(m_IEC103Data.m_byCycCnt, byCode);
}
}
}
m_IEC103Data.m_byCycCnt = (m_IEC103Data.m_byCycCnt+1) % CH_MAX_IED_NUM;
}
//asdu88
void CIEC103_XUJIPtl::Pack_Asdu_88(BYTE byNodeID)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeID];
BYTE byAddr = 0;
if(m_IEC103PtlPara.bCommAddr)
byAddr = m_IEC103PtlPara.byCKCPUAddr;
else
byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
ASDU_88_Fmt *pFmt = (ASDU_88_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = 88;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 0x02;
pFmt->head.addr = byAddr;//
pFmt->head.fun = 1;
pFmt->head.inf = 0;
pFmt->qcc.frz = 0;
pFmt->qcc.rqt = 5;
pFmt->rii = m_IEC103Data.m_bySin ++;
m_IEC103Data.m_wSendNum = sizeof(ASDU_88_Fmt);
PackLPDU(byNodeID, SendCon_code);
}
//asdu7
void CIEC103_XUJIPtl::Pack_Asdu_7(BYTE byNodeID)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeID];
BYTE byAddr = 0;
if(m_IEC103PtlPara.bCommAddr)
byAddr = m_IEC103PtlPara.byCKCPUAddr;
else
byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
ASDU_7_Fmt *pFmt = (ASDU_7_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = 7;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 9;
pFmt->head.addr = byAddr;
pFmt->head.fun = 0xff;
pFmt->head.inf = 0;
pFmt->scn = m_IEC103Data.m_bySin ++;
m_IEC103Data.m_wSendNum = sizeof(ASDU_7_Fmt);
PackLPDU(byNodeID, SendCon_code);
}
//任務組幀
BOOL CIEC103_XUJIPtl::PackTask(void)
{
TASK *pTask = NULL;
pTask = m_pCH->GetTask();
// 檢索通道命令
if (!pTask)
return FALSE;
// 時間校準命令
if (taskAdjustTime == pTask->eTaskType)
{
return FALSE;
/* m_bAdjustTime = true;
return SendAdjustTime103(pTask);
*/ }
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[pTask->byDestNodeID];
if(!pDevRun)
return FALSE;
if (tsNull == pTask->eStatus)
return FALSE;
//判斷是否任務隊列已經凍結,如果沒有凍結認為是新任務,則清數據區
// 任務檢測:數據區、設備描述區、系統描述區
// if(!m_pCH->m_pTaskQue->IsLock())
{
memset(&m_IEC103Data.m_task103, 0, sizeof(m_IEC103Data.m_task103));
// 記錄規約運行號
m_IEC103Data.m_task103.wStep = 0;
m_IEC103Data.m_task103.task = *pTask;
}
BOOL bRtn = FALSE;
//在下列任務類型中選擇需要凍結得任務類型,然后調用凍結函數凍結任務隊列
//在解幀函數中,調用解除任務隊列凍結函數
if (!PackLinkCmm(pTask->byDestNodeID))
{
switch(pTask->eTaskType)
{
// 任務類型
case taskCmdYkSelect: // 遙控選擇
case taskCmdYkExecute: // 遙控執行
case taskCmdYkCancel: // 遙控取消
{
bRtn = PackYaoKong(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskAskBhYc: //保護相關:模擬量、定值、復歸
{// 召喚保護模擬量
bRtn = PackCallProtMea(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskAskBhdz:
{// 召喚保護定值
bRtn = PackCallProtSetting(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdModifyBhdz:
{// 修改保護定值
bRtn = PackModifyProtSetting(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdEnableBhdz:
{// 確認保護定值
bRtn = PackEnableProtSetting(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdCancelBhdz:
{// 取消修改保護定值
bRtn = PackCancelProtSetting(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdSetBhdzGroup:
{// 設置保護定值組
bRtn = PackModifyProtSettingGroup(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdEnableBhdzGroup:
{// 確認設置的保護定值組
bRtn = PackEnableProtSettingGroup(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdCancelBhDzGroup:
{// 取消修改定值組號
bRtn = PackCancelProtSettingGroup(pTask, pDevRun);
// if(bRtn)
// m_pCH->m_pTaskQue->LockTask();
}
break;
case taskCmdBhReset: // 保護復歸
bRtn = PackProtRes(pTask, pDevRun);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -