?? iec103_sf.cpp
字號:
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_SFPtl::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]; //裝置節點則是m_addrtoID[addr]
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_SFPtl::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); //buf指向ASDU的首地址TYPE
BYTE len = pRecvBuf[1] - 2; //len代表ASDU的長度
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://1.解遙測;2.通用分類服務總召結束
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 = eInitGenGroupAsk;//總召結束,進入通用分類數據總召
//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_SFPtl::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();
*/}
// 通道任務(復歸)
else if(WatchTask(pTask, taskChThree, byNodeID) && pTask)
{
/*
*
*=======================================================
* 描述 偏移量 占位空間
*-------------------------------------------------------
* 相應數據總長度 0~1 2
* **103數據幀總個數N 2~3 2
*-------------------------------------------------------
* **103數據幀1總長度L1 4 1
* **103數據幀1 5~L1+5 L1
* **103數據幀2總長度L2 L1+6 1
* **103數據幀2 L1+7~L1+7+8 L2
* **。。。 。。。 。。。
* **103數據幀2總長度LN X 1
* **103數據幀N X~X+LN LN
*/
pTask->pbyBuff = g_pTaskDataBuff->QueryBuf(pTask->byDataBufIndex);//分配空間
if(pTask->pbyBuff == NULL)
return;
pTask->nDataBufLen = 0;
pTask->bWithDataF = TRUE;
if(SaveTaskRespFmt(buf - sizeof(LPDU_Vol_Head), len + 8, pTask))
{
pTask->eRespType = taskZF;
m_pCH->TaskResp(pTask);
//m_pCH->m_pTaskQue->UnLockTask();
}
}
}
// 通用數據傳輸
else
{
// 主動傳送/測試模式(事項存儲)
BOOL bStateChg = FALSE;
eDataSort data;
nIndex = GetnIndexbyFuninf(pIED, dataYx, pFmt->head.funInf);//先取實遙信的索引
data = dataYx;
if(nIndex == -1)
{
nIndex = GetnIndexbyFuninf(pIED, dataBhYx, pFmt->head.funInf);//取保護虛遙信索引
data = dataBhYx;
}
TIME_STRUCT sysTime;
g_pMainApp->GetSystime(&sysTime);
if(data == dataBhYx)
{
//存事項
BHEVENT_STRUCT bhevent;
bhevent.eDS=(eDataSource)m_pCH->m_ChConfig.eDS; // 數據源
bhevent.nIEDType=pIED->m_IEDConfig.usIEDType;//iedSF103; // 裝置類型
//printf("裝置類型:%d\n",pIED->m_IEDConfig.usIEDType);
bhevent.eEventType=dataBh; // 事項類型()
bhevent.nEventNode=nIndex; // 事項點
bhevent.nNode=pIED->m_IEDConfig.byNodeID;
bhevent.nEventVal=0x10;
if(yxBit == 1)
bhevent.nEventVal = 0x01;
bhevent.nFunCode=bhevent.nEventVal;// 事項值
bhevent.TimeStamp.nMs = wb.bwUnion.wVal % 1000;
bhevent.TimeStamp.bySecond = wb.bwUnion.wVal / 1000;
bhevent.TimeStamp.byMinute = pFmt->tm.Minutes;
bhevent.TimeStamp.byHour = pFmt->tm.Hours;
bhevent.TimeStamp.byDay = sysTime.byDay;
bhevent.TimeStamp.byMonth = sysTime.byMonth;
bhevent.TimeStamp.nYear = sysTime.nYear;
memcpy(bhevent.byUserData, buf, len); //事項數據
bhevent.nUserDataLen = len; //記錄數據緩沖區長度
m_pCH->m_pBhSoeQue->Add(bhevent);
if(!m_IEC103PtlPara.bEventVirtualYX)//參數設置,保護事項不需要轉成虛遙信
return;
}
// 遙信變位判別
BYTE byYXRecvVal = pIED->GetDataRecvVal(data,0,nIndex);
if (nIndex >= 0)
{
if (byYXRecvVal != yxBit)
bStateChg = TRUE;
}
// 遙信存儲
if (nIndex >= 0)//設置遙信值
pIED->SetDataRecvVal(data,0,nIndex,yxBit);
// 事項存儲等待
if (bStateChg)
{
// 遙信變位存儲
// 事項存儲
EVENT_STRUCT bhent;
bhent.eDS = (eDataSource)m_pCH->m_ChConfig.eDS; // 數據源
bhent.eEventType = data; // 事項類型(開關類)
bhent.nEventNode = nIndex; // 事項點
bhent.nEventVal = 0x10; // 事項值
if(yxBit == 1)
bhent.nEventVal = 0x01;
bhent.nNode = pIED->m_IEDConfig.byNodeID;// 設備節點
bhent.TimeStamp.nMs = wb.bwUnion.wVal % 1000;
bhent.TimeStamp.bySecond = wb.bwUnion.wVal / 1000;
bhent.TimeStamp.byMinute = pFmt->tm.Minutes;
bhent.TimeStamp.byHour = pFmt->tm.Hours;
bhent.TimeStamp.byDay = sysTime.byDay;
bhent.TimeStamp.byMonth = sysTime.byMonth;
bhent.TimeStamp.nYear = sysTime.nYear;
m_pCH->m_pYxbwSoeQue->Add(bhent);
m_pCH->m_pYxSoeQue->Add(bhent);
}
}
}
// 帶相對時間的時標報文,在許繼103中是保護動作事項報文
void CIEC103_SFPtl::Unpack_Asdu_2(BYTE* buf, BYTE len, RealRunIED *pRunIed)
{
ASDU_2_Fmt *pFmt = (ASDU_2_Fmt *)buf;
TIME_STRUCT sysTime;
g_pMainApp->GetSystime(&sysTime);
//調整數據值
WB_UNION wb;
wb.bwUnion.byVal[0] = pFmt->ret.byHigh;
wb.bwUnion.byVal[1] = pFmt->ret.byLow;
wb.bwUnion.byVal[0] = pFmt->fan.byHigh;
wb.bwUnion.byVal[1] = pFmt->fan.byLow;
CIED *pIED = pRunIed->pDevData;
if(pIED == NULL)
return;
eDataSort data;
int nIndex = GetnIndexbyFuninf(pIED, dataBhYx, pFmt->head.funInf);//取保護虛遙信索引
data = dataBhYx;
if(nIndex == -1)
return;
BYTE yxBit = (pFmt->dpi & 0x03) >> 1;//單點遙信
//存事項
BHEVENT_STRUCT bhevent;
bhevent.eDS=(eDataSource)m_pCH->m_ChConfig.eDS; // 數據源
bhevent.nServID = 0; //new 08.9.12
bhevent.nIEDType=pIED->m_IEDConfig.usIEDType;//iedSF103; // 裝置類型
bhevent.eEventType=dataBh; // 事項類型()
bhevent.nEventNode=nIndex; // 事項點
bhevent.nNode=pIED->m_IEDConfig.byNodeID;
bhevent.nEventVal=0x10;
if(yxBit == 1)
bhevent.nEventVal = 0x01;
bhevent.nFunCode=bhevent.nEventVal;// 事項值
wb.bwUnion.byVal[0] = pFmt->tm.byHighMs;
wb.bwUnion.byVal[1] = pFmt->tm.byLowMs;
bhevent.TimeStamp.nMs = wb.bwUnion.wVal % 1000;
bhevent.TimeS
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -