⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnp3dll.cpp

📁 一个通讯管理机的源代码。比较好用。推荐
💻 CPP
字号:
#include "msystem.h"#include "Dnp3dll.h"void CDNP3DLL::BuildCID(BYTE& byCID,BYTE byFC,bool bPRM,bool bFCV){	byCID = byFC;	if (m_bDIR) byCID |= 0x80;	if (bPRM) 	{		byCID |= 0x40;		if (bFCV) 		{			byCID |= 0x10;			if (m_bFCB) byCID |= 0x20;			m_bFCB = !m_bFCB;		}	}	else	{		if (m_bDataFlowCtrl) byCID |= 0x10;	}}void CDNP3DLL::Resp(BYTE byFC){	CFrameNode FNSend;	FNSend.m_wSAddr = m_wSrcAddr;	FNSend.m_wDAddr = m_wDesAddr;	BuildCID(FNSend.m_byCID,byFC,false,false);	SetupFrame(&FNSend);	CDataNode dn;	FrameToBuffer(dn);	WriteToPL(dn.m_pbyData,dn.m_wSize);}void CDNP3DLL::ExpResp(){	CFrameNode* pFNResp;	if (m_queResp.Get(pFNResp,1000))	{		if (pFNResp->m_byCID & 0x10) // DFC			m_nStatus = 0x31;		else		{			BYTE byFC = pFNResp->m_byCID & 0xf;			switch (byFC)			{			case 0:			case 11:				m_nStatus = 0;				break;			case 1:				m_nStatus = 0x21;				break;			case 14:			case 15:			default:				m_nStatus = 0x11;				break;			}		}		delete pFNResp;	}	else m_nStatus = 0x41;}int CDNP3DLL::GetStatus(){	switch (m_nStatus)	{	case 0: break;	case 0x21://test peer link layer status		TestPLLS();		break;	case 0x31://query peer link layer status		QueryPLLS();		break;	case 0x11://Reset peer link layer	default: //ready for write, Get data From queue//		ResetPLL();		m_nStatus = 0;		break;	}	return m_nStatus & 0xf;}void CDNP3DLL::QueryPLLS(){	CFrameNode FNSend;	FNSend.m_wSAddr = m_wSrcAddr;	FNSend.m_wDAddr = m_wDesAddr;	BuildCID(FNSend.m_byCID,9,true,false);	SetupFrame(&FNSend);	CDataNode dn;	FrameToBuffer(dn);	WriteToPL(dn.m_pbyData,dn.m_wSize);	ExpResp();}void CDNP3DLL::TestPLLS(){}void CDNP3DLL::ResetPLL(){	CFrameNode FNSend;	FNSend.m_wSAddr = m_wSrcAddr;	FNSend.m_wDAddr = m_wDesAddr;	BuildCID(FNSend.m_byCID,0,true,false);	SetupFrame(&FNSend);	CDataNode dn;	FrameToBuffer(dn);	WriteToPL(dn.m_pbyData,dn.m_wSize);	ExpResp();}bool CDNP3DLL::WriteToPL(BYTE* pBuf,WORD wSize,DWORD dwTimeout){	bool bRet = false;	pthread_mutex_lock(&m_csWrite);	{		m_PhyService.Write(pBuf,wSize);		usleep(10000);/*if (wSize >= 18){			cout << endl <<"Resp:";	for (WORD w=0; w<wSize; w++)	{		char c[16];		sprintf(c," %02x" ,pBuf[w]);		cout << c;	}	cout <<endl;}*/		bRet = true;	}	pthread_mutex_unlock(&m_csWrite);	return bRet;}void* thrdRead(void* pVoid){	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);	CDNP3DLL *pDL = (CDNP3DLL *)pVoid;	sleep(5);	while (1) {		pDL->ReadFrmPL();	}	return 0;}CDNP3DLL::CDNP3DLL(CSerialPortDef* pChannel,bool bDIR,WORD wSrcAddr,WORD wDesAddr)	: CDLService(pChannel){	m_bDIR = bDIR;	pthread_mutex_init(&m_csWrite,NULL);// PTHREAD_MUTEX_INITIALIZER)	m_wSrcAddr = wSrcAddr;	m_wDesAddr = wDesAddr;	m_pFrame = new CDNP3Frame;	m_byMaxRepeatTimes = 2;	m_nStatus = 0x11;	m_bPeerStatus = false;	m_bDataFlowCtrl = false;}bool CDNP3DLL::Init(){	bool bRet = false;	if (m_PhyService.Status() == 0)	{		pthread_attr_t attr;		pthread_attr_init(&attr);		pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);		if (pthread_create(&m_pThrdReadFrmPL,&attr,thrdRead,(void *)this) == 0)			bRet = true;		pthread_attr_destroy(&attr);	}	return bRet;}CDNP3DLL::~CDNP3DLL(){	if (m_pThrdReadFrmPL)	{		cout << "CDNP3DLL: " << m_pThrdReadFrmPL << endl;		pthread_cancel(m_pThrdReadFrmPL);	}	if (m_pFrame)		delete m_pFrame;	pthread_mutex_destroy(&m_csWrite);}void CDNP3DLL::ReadFrmPL(){	CFrameNode FNRecv;	int nIndications = -1;	if (m_PhyService.Status() == 0)	{		nIndications = 0;		CDQue* pDQueRecv = m_PhyService.GetRecvQueue();		CDNP3Frame frmInput;		if (frmInput.BufferToFrame(pDQueRecv))		{			frmInput.FrameToBuf(FNRecv);			m_wDesAddr = FNRecv.m_wSAddr;			if ((FNRecv.m_wDAddr == m_wSrcAddr) || (FNRecv.m_wDAddr == 0xffff))				nIndications = 1;		}	}	if (nIndications == 1)	{		BYTE byFC = FNRecv.m_byCID & 0xf;		bool bPRM = (FNRecv.m_byCID & 0x40)?true:false;//		bool bDIR = (FNRecv.m_byCID & 0x80)?true:false;//		assert(bDIR != m_bDIR)		if (bPRM) //primary		{			bool bRefuse = false;			if (FNRecv.m_byCID & 0x10) //FCV			{				if (m_bPeerStatus == false)					bRefuse = true;				else if (((FNRecv.m_byCID & 0x20)?true:false) == m_bPeerFCB)					m_bPeerFCB = !m_bPeerFCB;				else //拒绝报文					bRefuse = true;			}			if (bRefuse == false)			{				switch (byFC)				{				case 0://reset link layer					m_bPeerFCB = true;					m_bPeerStatus = true;					Resp(0); //ack					break;				case 1://reset user process ???					break;				case 2://test					Resp(0); //ack					break;				case 3://Send/confirm 					Resp(0); //ack				case 4://Send/no confirm					{						CFrameNode* pfn = new CFrameNode;						*pfn = FNRecv;						m_queIND.Add(pfn);// append tsdu to queIND					}					break;				case 9://查询链路状态					//rep linklayer status					Resp(m_bPeerStatus ? 11 : 15); //ack					break;				default:					break;				}			}		}		else //FRM == 0:		{			CFrameNode* pfn = new CFrameNode;			*pfn = FNRecv;			m_queResp.Add(pfn);		}	}}int CDNP3DLL::REQ(BYTE byService,CFrameNode *pFNSend,BYTE byPriority/*0:H;1:L*/,bool bRetry){	int nConfirm = 4; //等待物理层可用	if (m_PhyService.Status() == 0)	{		BYTE b;		for (b=0;b<m_byMaxRepeatTimes;b++)		{			switch (byService)			{			case 0: //send-confirm; Request-Respond				if (GetStatus() == 0)				{					pFNSend->m_wSAddr = m_wSrcAddr;					pFNSend->m_wDAddr = m_wDesAddr;					BuildCID(pFNSend->m_byCID,3,true,true);					SetupFrame(pFNSend);					CDataNode dn;					FrameToBuffer(dn);					WriteToPL(dn.m_pbyData,dn.m_wSize);					ExpResp();					if (m_nStatus == 0)//ack						nConfirm = 0;					else if (m_nStatus == 0x21)//nack						nConfirm = 2;					else  if (m_nStatus == 0x41)//no resp						nConfirm = 3;					else if (m_nStatus == 0x11)//link layer service is not working or no use link layer service						nConfirm = 1;                   				}				break;/*				AddIOStream(1,dn.m_pbyData,dn.m_wSize);				if (BufferToFrame(pDQueRecv))				{					AddIOStream(2,m_pFrame->m_pbyInBuf,m_pFrame->m_wInLength);					m_pFrame->FrameToBuf(FNRecv);					nConfirm = 1;				}*/			case 1: //send-no-reply				if (GetStatus() == 0)				{					pFNSend->m_wSAddr = m_wSrcAddr;					pFNSend->m_wDAddr = m_wDesAddr;					BuildCID(pFNSend->m_byCID,4,true,false);					SetupFrame(pFNSend);										CDataNode dn;					FrameToBuffer(dn);					CDQue* pDQueRecv = m_PhyService.GetRecvQueue();					pDQueRecv->RemoveAll();					WriteToPL(dn.m_pbyData,dn.m_wSize);//					m_PhyService.Write(dn.m_pbyData,dn.m_wSize);//				AddIOStream(1,dn.m_pbyData,dn.m_wSize);					nConfirm = 0;				}				break;			case 2: //send-confirm ,cancel current secondary frames for half duplex				break;			case 3: //send-no-reply ,cancel current secondary frames for half duplex				break;			case 4: //return link status, return successful if the data link is not busy				nConfirm = GetStatus();				break;			default: break;			}			if ((nConfirm == 0) || (bRetry == false)) break;		}	}	return nConfirm;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -