📄 dnp3sas.cpp
字号:
#include "allmgr.h"#include "dnp3sas.h"void CDNP3SAS::Load(){ m_YCInfos.Load(); m_YCInfos.Sort(); m_YXInfos.Load(); m_YXInfos.Sort(); m_SOEInfos.Load(); m_SOEInfos.Sort(); m_YKInfos.Load(); m_YKInfos.Sort();}void* DNP3SlaveGetIND(void *pVoid){ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); CDNP3SAS *pAS = (CDNP3SAS *)pVoid; sleep(2);// int i=0; while (1) { CFrameNode FNRecv;/* FNRecv.m_wSize = 5; FNRecv.m_pbyData[0] = 0xc0; FNRecv.m_pbyData[1] = 0x01; FNRecv.m_pbyData[2] = 60; FNRecv.m_pbyData[3] = 02; FNRecv.m_pbyData[4] = 0x06; FNRecv.m_pbyData[5] = 0x1; FNRecv.m_pbyData[6] = 0x1; FNRecv.m_pbyData[7] = 0x06;*/ // pAS->m_YXInfos.SetValue(1,31,(i++%50)?true:false);// if (i%50 == 0)// pAS->m_YCInfos.SetValue(1,2,i); if (pAS->m_TLService.IND(FNRecv) == 1) //有指示; pAS->ExplainIND(&FNRecv); }}bool CDNP3SAS::Init(){ bool bRet = false; if (m_TLService.Init()) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); if (pthread_create(&m_hThreadGet,&attr,DNP3SlaveGetIND,(void *)this) == 0) { Load(); bRet = true; } else m_hThreadGet = 0; pthread_attr_destroy(&attr); } return bRet;}CDNP3SAS::CDNP3SAS(CAllMgr* pAllMgr,CSerialPortDef* pChannel,WORD wSAddr,WORD wDAddr) : CSAppService(pAllMgr,true) , m_TLService(pChannel,false,wSAddr,wDAddr){ m_hThreadGet = 0; WORD *pw = (WORD *)&m_IINs; *pw = 0;}CDNP3SAS::~CDNP3SAS(){ if (m_hThreadGet > 0) { cout << "DNP3Get: " << m_hThreadGet << endl; pthread_cancel(m_hThreadGet); }}void CDNP3SAS::ExplainIND(CFrameNode* pFNRecv){ BYTE abySendBuf[2048]; WORD wSendSize = 0; // BYTE byCID = pFNRecv->m_byCID; WORD wSize = pFNRecv->m_wSize; BYTE* pbyRD=pFNRecv->m_pbyData; if (wSize >= 5) { BYTE byAppCtrl,byFunctionCode,byObject,byVariation,byIndexSize,byQualifierCode,byQualifierField; byAppCtrl = *pbyRD++; byFunctionCode = *pbyRD++; BYTE *pbytemp = pbyRD; wSize -= 2; WORD wTempSize =wSize; *(abySendBuf + wSendSize++) = 0xc0 | (byAppCtrl & 0x1f); // | 0x20 *(abySendBuf + wSendSize++) = 129; //resp wSendSize += 2; while (wSize >= 3) { byObject = *pbyRD++; byVariation = *pbyRD++; byQualifierField = *pbyRD; byIndexSize = (*pbyRD & 0x70)>>4; byQualifierCode = *pbyRD++ & 0xf; wSize -= 3; switch(byFunctionCode) { case 0: //Ack break; case 1: //Read m_IINs.bitRequestAck = 0; if ((byObject == 1) && ((byVariation == 1) || (byVariation == 2))) //yx { *(abySendBuf+wSendSize++) = 1; //object *(abySendBuf+wSendSize++) = 1; //variation *(abySendBuf+wSendSize++) = 1; //index = 0; range=2 byte index-2 byte Index WORD* pw = (WORD *)(abySendBuf+wSendSize); wSendSize += 4; *pw++ = 0; *pw = m_YXInfos.GetSize() - 1; m_YXInfos.GetAllValues(abySendBuf+wSendSize,wSendSize,1); } else if (((byObject == 2) && ((byVariation == 1) || (byVariation == 2))) //soe || ((byObject == 60) && (byVariation == 3))) //2 class data //soe { if (m_SOEInfos.HasData()) { *(abySendBuf+wSendSize++) = 2; //object *(abySendBuf+wSendSize++) = 2; //variation *(abySendBuf+wSendSize++) = 0x27; //index = 2 byte index; range=2 byte count BYTE* pbyCount = (abySendBuf+wSendSize); wSendSize ++; BYTE byCount = m_SOEInfos.GetSOEData(abySendBuf+wSendSize,wSendSize,1); *pbyCount = byCount; } } else if ((byObject == 30) && ((byVariation == 2) || (byVariation == 4))) //yc { *(abySendBuf+wSendSize++) = 30; *(abySendBuf+wSendSize++) = 4; *(abySendBuf+wSendSize++) = 1; //index = 0; range=2 byte index-2 byte Index WORD* pw = (WORD *)(abySendBuf+wSendSize); wSendSize += 4; *pw++ = 2560; //start index; *pw = 2560+m_YCInfos.GetSize()-1; //end index m_YCInfos.GetAllValues(abySendBuf+wSendSize,wSendSize,1); } else if (((byObject == 32) && (byVariation == 2)) //changed yc || ((byObject == 60) && (byVariation == 4))) //3 class data //changed yc { if (m_YCInfos.HasChanged()) { *(abySendBuf+wSendSize++) = 32; //object *(abySendBuf+wSendSize++) = 2; //variation *(abySendBuf+wSendSize++) = 0x27; //index = 2 byte index; range=2 byte count BYTE* pbyCount = (abySendBuf+wSendSize); wSendSize++; BYTE byCount = m_YCInfos.GetChangedValues(abySendBuf+wSendSize,wSendSize,2); *pbyCount = byCount; } } else if ((byObject == 60) && (byVariation == 1)) //0 class data { *(abySendBuf+wSendSize++) = 1; *(abySendBuf+wSendSize++) = 1; *(abySendBuf+wSendSize++) = 1; //index = 0; range=2 byte index-2 byte Index WORD* pw = (WORD *)(abySendBuf+wSendSize); wSendSize += 4; *pw++ = 0; *pw = m_YXInfos.GetSize()-1; m_YXInfos.GetAllValues(abySendBuf+wSendSize,wSendSize,1); *(abySendBuf+wSendSize++) = 30; *(abySendBuf+wSendSize++) = 4; *(abySendBuf+wSendSize++) = 1; //index = 0; range=2 byte index-2 byte Index pw = (WORD *)(abySendBuf+wSendSize); wSendSize += 4; *pw++ = 2560; //start index; *pw = 2560+m_YCInfos.GetSize()-1; //end index m_YCInfos.GetAllValues(abySendBuf+wSendSize,wSendSize,1); } else if ((byObject == 60) && (byVariation == 2)) //1 class data //changed yx { if (m_YXInfos.HasChanged()) { *(abySendBuf+wSendSize++) = 2; //object *(abySendBuf+wSendSize++) = 1; //variation *(abySendBuf+wSendSize++) = 0x27; //index = 2 byte index; range=2 byte count BYTE* pbyCount = (abySendBuf+wSendSize); wSendSize ++; BYTE byCount = m_YXInfos.GetChangedValues(abySendBuf+wSendSize,wSendSize,byVariation); *pbyCount = byCount; } } break; case 2: //Write {/* *(abySendBuf+wSendSize++) = 30; *(abySendBuf+wSendSize++) = 4; *(abySendBuf+wSendSize++) = 1; //index = 0; range=2 byte index-2 byte Index WORD* pw = (WORD *)(abySendBuf+wSendSize); wSendSize += 4; *pw++ = 2560; //start index; *pw = 2560+m_YCInfos.GetSize()-1; //end index m_YCInfos.GetAllValues(abySendBuf+wSendSize,wSendSize,1);*/ m_IINs.bitRequestAck = 1; break; } case 3: //Select switch(byQualifierField) { //1 byte count case 0x17: //no index { BYTE byCount = *pbyRD++; wSize -= 1; for (BYTE b=0; b<byCount; b++) { BYTE byIndex = *pbyRD++; BYTE byControl = *pbyRD++;// struCtrlBlk* pCtrlBlk = (struCtrlBlk *)pbyRD;// pbyRD += sizeof(struCtrlBlk);// wSize -= sizeof(struCtrlBlk)+1;// if (m_YXInfos.HasChanged())// {//Send Work Info// }// else// {// if ((pCtrlBlk->byTrip == 1) || (pCtrlBlk->byTrip == 2)) //close || trip if ((byIndex < 25) && (byControl == 0x41)) { if (m_YKInfos.Select(byIndex,true)) abySendBuf[0] |= 0x20; }// } // Send YK return; } memcpy(abySendBuf+wSendSize,pbytemp,wTempSize); wSendSize += wTempSize; break; }/* case 0x27: //2 byte index { BYTE byCount = *pbyRD++; wSize -= 1; for (BYTE b=0; b<byCount; b++) { WORD wIndex,*pw; pw = (WORD *)pbyRD; wIndex = *pw; pbyRD += 2; struCtrlBlk* pCtrlBlk = (struCtrlBlk *)pbyRD; pbyRD += sizeof(struCtrlBlk); wSize -= sizeof(struCtrlBlk)+2; if (m_YXInfos.HasChanged()) {//Send Work Info } else { if ((pCtrlBlk->byTrip == 1) || (pCtrlBlk->byTrip == 2)) //close || trip { m_YKInfos.Select((BYTE)wIndex,(pCtrlBlk->byTrip == 1)); } } // Send YK return; } memcpy(abySendBuf+wSendSize,pbytemp,3+byCount*(2+sizeof(struCtrlBlk))); wSendSize += 3+byCount*(2+sizeof(struCtrlBlk)); break; }*/ default: break; } break; case 4: //Operate switch(byQualifierField) { //1 byte count case 0x17: //1 byte index { BYTE byCount = *pbyRD++; wSize -= 1; for (BYTE b=0; b<byCount; b++) { BYTE byIndex = *pbyRD++; BYTE byControl = *pbyRD++;// struCtrlBlk* pCtrlBlk = (struCtrlBlk *)pbyRD;// pbyRD += sizeof(struCtrlBlk);// wSize -= sizeof(struCtrlBlk)+1; BYTE byDev; WORD wDevPubAddr; bool bOn; if (m_YKInfos.Operate(byIndex,byDev,wDevPubAddr,bOn)) {// if (m_YXInfos.HasChanged())// {//Send Work Info// ;// } if (bOn && (byControl == 0x41))//((bOn && (pCtrlBlk->byTrip == 1)) || (!bOn && (pCtrlBlk->byTrip == 2))) //close || trip { if ((byDev > 20) && (wDevPubAddr == 3)) { m_pAllMgr->YK(1,3,true); m_pAllMgr->YK(2,3,true); m_pAllMgr->YK(3,3,true); m_pAllMgr->YK(4,3,true); m_pAllMgr->YK(5,3,true); m_pAllMgr->YK(7,3,true); m_pAllMgr->YK(10,3,true); m_pAllMgr->YK(11,3,true); m_pAllMgr->YK(12,3,true); m_pAllMgr->YK(13,3,true); m_pAllMgr->YK(14,3,true); } else m_pAllMgr->YK(byDev,wDevPubAddr,bOn); abySendBuf[0] |= 0x20; } } } memcpy(abySendBuf+wSendSize,pbytemp,wTempSize); wSendSize += wTempSize; break; }/* case 0x27: //2 byte index { BYTE byCount = *pbyRD++; wSize -= 1; for (BYTE b=0; b<byCount; b++) { WORD wIndex,*pw; pw = (WORD *)pbyRD; wIndex = *pw; pbyRD += 2; struCtrlBlk* pCtrlBlk = (struCtrlBlk *)pbyRD; pbyRD += sizeof(struCtrlBlk); wSize -= sizeof(struCtrlBlk)+2; BYTE byDev; WORD wDevPubAddr; bool bOn; if (m_YKInfos.Operate((BYTE)wIndex,byDev,wDevPubAddr,bOn)) { if (m_YXInfos.HasChanged()) {//Send Work Info ; } else if ((bOn && (pCtrlBlk->byTrip == 1)) || (!bOn && (pCtrlBlk->byTrip == 2))) //close || trip m_pAllMgr->YK(byDev,wDevPubAddr,bOn); } } memcpy(abySendBuf+wSendSize,pbytemp,3+byCount*(2+sizeof(struCtrlBlk))); wSendSize += 3+byCount*(2+sizeof(struCtrlBlk)); break; }*/ default: break; } break; default: m_IINs.bitFCNotComplete = 1; break; } if ((byFunctionCode == 1) && (byQualifierField == 6)) continue; else break; } WORD* pwtemp = (WORD *)(abySendBuf + 2); *pwtemp = GetIINs();// if (wSendSize > 2)// {// abySendBuf[0] |= 0x20;// } timeval tv; CFrameNode FNSend(tv,abySendBuf,wSendSize,pFNRecv->m_bySrcAddr); m_TLService.REQ(1,&FNSend,0,true); }}WORD CDNP3SAS::GetIINs(){ WORD *pw = (WORD *)&m_IINs; if (m_YXInfos.HasChanged()) m_IINs.bitReadyFor1Class = 1; else m_IINs.bitReadyFor1Class = 0; if (m_YCInfos.HasChanged()) m_IINs.bitReadyFor3Class = 1; else m_IINs.bitReadyFor3Class = 0; if (m_SOEInfos.HasData()) m_IINs.bitReadyFor2Class = 1; else m_IINs.bitReadyFor2Class = 0; return *pw;}void CDNP3SAS::YC(YCData* pYCValue,WORD wCount){// cout << "DNP3 Hello YC" <<endl; for (WORD www=0; www<wCount;www++) { m_YCInfos.SetValue(pYCValue[www].m_wDevNo,pYCValue[www].m_wDevPtNo,pYCValue[www].m_fValue); }}void CDNP3SAS::YX(YXData* pBoolValue,WORD wCount){ for (WORD www=0; www<wCount;www++) { m_YXInfos.SetValue(pBoolValue[www].m_wDevNo,pBoolValue[www].m_wDevPtNo,pBoolValue[www].m_bValue); }// cout << "DNP3 Hello YX" <<endl;}void CDNP3SAS::DD(DDData* pDDValue,WORD wCount){// for (WORD www=0; www<wCount;www++)// {// m_DDInfos.SetValue(pDDValue[www].m_wDevNo,pDDValue[www].m_wDevPtNo,pDDValue[www].m_dwValue);// }// cout << "DNP3 Hello DD" <<endl;}void CDNP3SAS::SOE(SOEData* pSOEValue,WORD wCount){ for (WORD www=0; www<wCount;www++) { m_SOEInfos.SetValue(pSOEValue+www); }// cout << "DNP3 Hello SOE" <<endl;}void CDNP3SAS::ProtInfo(BYTE* pBuf, WORD wSize){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -