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

📄 msghdler.cpp

📁 用VC编写的设备通讯程序,里面有很多规约,自己下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//**************************************************************************
//
//  Filename   :  Msghdler.cpp
//
//  Subsystem  :
//
//  Description:  Protocol message handlers.
//
//**************************************************************************

/*
 * NT Definitions
 */
#include <windows.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

#include "gencom.h"
#include "comiosrv.h"
#include "locmsgdef.h"

#define	GET_BIT(a, b)		(BYTE)a & (1 << b)
#define	GET_BCD(a)			(a >> 4) * 10 + (a & 0x0f)
#define	SET_BCD(a)			((a / 10) << 4) + (a % 10)

static UINT SendCommand(CPio *pPio, REQUEST_MSGS *pMsg, int *respnum);

static USHORT mod_crc(BYTE *message,  UINT message_length)

{
    USHORT  crc = 0xFFFF;
    UINT    byte;
    UINT    flag;
    UINT    shift;
	
	if (message_length > 512)
		return 0;

    for ( byte = 0; byte < message_length; byte++ ) {
		
		crc ^= message[ byte ];
		
		for ( shift = 1; shift <= 8; shift++ ) {
			flag = crc & 0x0001;
			crc = crc>>1;
			if ( flag == 1 ) {
				crc ^= 0xA001;
			}
		}
    }	    
    return ( crc );
}

VOID PollMarshall(REQUEST_MSGS* pReqMsg, CPio* pPio)
{
	int    curtim, respsiz, msg_size = 0;
	USHORT shtnum = 0;
	BYTE   *p_buf;
	F2CMD  *pF2Cmd;
	F3CMD  *pF3Cmd;
	F12CMD *pF12Cmd;

	/*
	 *  If we are starting a poll, the command setup device in polled mode.
	 */
	p_buf = GetPioWrtBuf(pPio);
	switch ( pReqMsg->FuncCode ) {
	case INIT_POLL:
	case INFO_POLL:		// normal polling, digital input
		if (pReqMsg->FuncCode != INIT_POLL) {
			// do time related action if any
			curtim = GetComSystim();

			if (GetRtuClkSyn(pReqMsg->pRtu)) {
				// need manually set time sync command
				ClrRtuClkSyn(pReqMsg->pRtu);

				SetRtuSoeSts(pReqMsg->pRtu);
				respsiz = (BYTE)GetRtuNetId(pReqMsg->pRtu);
				pReqMsg->FuncCode = TIME_SYNC;
				msg_size = SendCommand(pPio, pReqMsg, &respsiz);
				SetPioReadHeadCnt(pPio, respsiz);
				SetPioReadCnt(pPio, respsiz);

				// clear polling flag for next polling
				ClrRtuPollSts(pReqMsg->pRtu);
			}
			else if ((curtim % 300) < 30 && !GetRtuSoeSts(pReqMsg->pRtu)) {

				if (IsCommFirstRtu(pReqMsg->pRtu)) {
					// need set time sync command
					SetRtuSoeSts(pReqMsg->pRtu);
					respsiz = 0;		// broadcast on this channel
					pReqMsg->FuncCode = TIME_SYNC;
					msg_size = SendCommand(pPio, pReqMsg, &respsiz);
					SetPioReadHeadCnt(pPio, respsiz);
					SetPioReadCnt(pPio, respsiz);
					
					// clear polling flag for next polling
					ClrRtuPollSts(pReqMsg->pRtu);
				}
			}

			// for next trigger, clear the flags
			if ((curtim % 300) > 150 && GetRtuSoeSts(pReqMsg->pRtu))
				ClrRtuSoeSts(pReqMsg->pRtu);
		}

		if (msg_size == 0) {
			// issue poll command
			SetRtuCmdStep(pReqMsg->pRtu, 0);
			pF2Cmd = (F2CMD *)p_buf;
			pF2Cmd->addr = (BYTE)GetRtuNetId(pReqMsg->pRtu);
			pF2Cmd->func = FUNC_2;
			pF2Cmd->reg  = 0;
			pF2Cmd->num  = byte_swap(DIGDATBYT * 8);
			pF2Cmd->crc  = mod_crc(p_buf, (MODBUS_F2_SIZ - 2 ) );
			msg_size = MODBUS_F2_SIZ;
			SetPioReadHeadCnt(pPio, MODBUS_F2_REPLY_SIZ);
			SetPioReadCnt(pPio, MODBUS_F2_REPLY_SIZ);
		}
		SetPioUnPackFunc(pPio, PollUnmarshall);
		break;

	case RFLH_POLL:		// send additional polling
		switch (GetRtuCmdStep(pReqMsg->pRtu)) {
		case 1:			// get soe message
			pF12Cmd = (F12CMD *)p_buf;
			pF12Cmd->addr = (BYTE)GetRtuNetId(pReqMsg->pRtu);
			pF12Cmd->func = FUNC_12;
			pF12Cmd->reg  = 0;
			pF12Cmd->num  = byte_swap(SOEDATNUM);
			pF12Cmd->crc  = mod_crc(p_buf, (MODBUS_F12_SIZ - 2 ) );
			msg_size = MODBUS_F12_SIZ;
			SetPioReadHeadCnt(pPio, MODBUS_F12_REPLY_SIZ);
			SetPioReadCnt(pPio, MODBUS_F12_REPLY_SIZ);
			SetPioUnPackFunc(pPio, PollUnmarshall);
			break;
		case 2:			// analog input
			pF3Cmd = (F3CMD *)p_buf;
			pF3Cmd->addr = (BYTE)GetRtuNetId(pReqMsg->pRtu);
			pF3Cmd->func = FUNC_3;
			pF3Cmd->reg  = 0;
			shtnum = GetDefGrpPnt(pReqMsg->pRtu, AINORMSLOT);
			pF3Cmd->num  = byte_swap(shtnum * 2);
			pF3Cmd->crc  = mod_crc(p_buf, (MODBUS_F3_SIZ - 2 ) );
			msg_size = MODBUS_F3_SIZ;
			respsiz  = shtnum * 2 + 6;
			SetPioReadHeadCnt(pPio, respsiz);
			SetPioReadCnt(pPio, respsiz);
			SetPioUnPackFunc(pPio, PollUnmarshall);
			break;
		}
		break;

	case DIGI_COMD:		// digital output command
		// form command by frame type
		msg_size = SendCommand(pPio, pReqMsg, &respsiz);

		SetPioReadHeadCnt(pPio, respsiz);
		SetPioReadCnt(pPio, respsiz);
		SetPioUnPackFunc(pPio, PollUnmarshall);
		SetPioWriteCnt(pPio, msg_size);
		break;

	case ANAL_COMD:		// register output command
		// form command by frame type
		msg_size = SendCommand(pPio, pReqMsg, &respsiz);

		SetPioReadHeadCnt(pPio, respsiz);
		SetPioReadCnt(pPio, respsiz);
		SetPioUnPackFunc(pPio, PollUnmarshall);
		SetPioWriteCnt(pPio, msg_size);
		break;

	case RELY_COMD:		// relay control command
		// form command by frame type
		msg_size = SendCommand(pPio, pReqMsg, &respsiz);

		SetPioReadHeadCnt(pPio, respsiz);
		SetPioReadCnt(pPio, respsiz);
		SetPioUnPackFunc(pPio, PollUnmarshall);
		SetPioWriteCnt(pPio, msg_size);
		break;

	default:
		printf( "PollMarshall(), Unexpected Cmd: %d\n", pReqMsg->FuncCode);
		break;
	}

	memcpy(GetPioUserDefMsg(pPio), pReqMsg, sizeof(REQUEST_MSGS) );

	SetPioWriteCnt(pPio, msg_size);
	SetPioWriteOffset(pPio, 0);

	//
	// STS commands are acknowledged
	// Set this stuff for a reply!
	//
	//  One pass read, Simple two pass, purge
	SetPioComState(pPio, FALSE, FALSE, TRUE);

	// write data to debug buffer if rtu in debug mode
	SetPioRtuDbgOutMsg(pPio, pReqMsg->pRtu);

	SetPioReadOffset(pPio, 0);
	SetPioReadFixupCnt(pPio, 0);
}


VOID PollUnmarshall(CPio *pPio, int ioStream)
{
	BYTE    *p_buf, *pSts, data[8], valtyp;
	int     i, j, gix, nStep, sts, pix, value, len, procdi  = 0;
	int     setval, startidx, setidx, cpuidx, setnum, inpcnt;
	USHORT  shtval, crc;
	float   fvalue = 0.0f;
	BOOL    bChange = FALSE;
	REQUEST_MSGS *sendInfo = (REQUEST_MSGS*)GetPioUserDefMsg(pPio);
	F2RSP   *pF2Rsp;
	F3RSP   *pF3Rsp;
	F5RSP   *pF5Rsp;
	F12RSP  *pF12Rsp;
	SOETIME soeTime;
	char    comstr[64];

	p_buf = GetPioReadBuf(pPio);

	sts = GetPioRecvStatus(pPio);
	if ( sts == PIO__SUCCESS ||
		 sts == PIO__BAD_MSG_LENGTH ) {
		// write data to debug buffer if rtu in debug mode
		SetPioRtuDbgInMsg(pPio, sendInfo->pRtu);

		if (p_buf[0] != (BYTE)GetRtuNetId(sendInfo->pRtu)) {
			SetPioRecvStatus(pPio, PIO__ACK_NOT_FOUND);
			SetRtuCmdStep(sendInfo->pRtu, 0);
			
			// clear polling flag for next polling
			ClrRtuPollSts(sendInfo->pRtu);
			ClrPioRtuStream(ioStream);
			return;
		}

		len = GetPioReadCnt(pPio);
		crc = mod_crc(p_buf, len - 2);

		switch (sendInfo->FuncCode) {
		case INIT_POLL:
		case INFO_POLL:		// normal polling, digital input
		case RFLH_POLL:		// send additional polling
			nStep = GetRtuCmdStep(sendInfo->pRtu);
			switch (nStep) {
			case 0:				// digital input
				pF2Rsp = (F2RSP *)p_buf;
				if (crc != *(USHORT *)&p_buf[len - 2]) {
					SetPioRecvStatus(pPio, PIO__BAD_CHECKSUM);
					SetRtuCmdStep(sendInfo->pRtu, 0);
					
					// clear polling flag for next polling
					ClrRtuPollSts(sendInfo->pRtu);
				}
				else {
					gix = DINORMSLOT;
					pix = 0;
					for (i = 0; i < (len - 6); i++) {
						for (j = 0; j < 8; j++) {
							value = (UCHAR)GET_BIT(pF2Rsp->pts[i], j) ? 1 : 0;
							procdi = UpdRtuRawData(sendInfo->pRtu, gix, pix, value);
							if (procdi) {
								bChange = TRUE;
							}
							pix++;
						}
						if ((i % 4) == 3) {
							gix++;
							pix = 0;
						}
					}
					if (GET_BIT(pF2Rsp->pts[3], 7)) {	// has soe message
						SetRtuCmdStep(sendInfo->pRtu, 1);
					}
					else {			// to poll analog input data
						SetRtuCmdStep(sendInfo->pRtu, 2);
					}
					if (bChange) {	// any DI change during process
						UpdRtuPntSts(sendInfo->pRtu, 1);
					}
					if ( sts == PIO__BAD_MSG_LENGTH ) {
						SetPioRecvStatus(pPio, PIO__SUCCESS);
					}
					
					// send additional polling command
					sendInfo->FuncCode = RFLH_POLL;
					// add a high priority refresh poll
					AddMorePollCmd(sendInfo, TRUE);
				}
				break;
				
			case 1:				// soe message
				pF12Rsp = (F12RSP *)p_buf;
				if (crc != *(USHORT *)&p_buf[len - 2]) {
					SetPioRecvStatus(pPio, PIO__BAD_CHECKSUM);
					SetRtuCmdStep(sendInfo->pRtu, 0);
					
					// clear polling flag for next polling
					ClrRtuPollSts(sendInfo->pRtu);
				}
				else {
					SetRtuCmdStep(sendInfo->pRtu, 2);
					
					soeTime.year = 2000 + GET_BCD(pF12Rsp->year);
					soeTime.mon  = GET_BCD(pF12Rsp->mon);
					
					soeTime.day  = GET_BCD(pF12Rsp->day);
					soeTime.hour = GET_BCD(pF12Rsp->hour);
					
					soeTime.min  = GET_BCD(pF12Rsp->min);
					soeTime.sec  = GET_BCD(pF12Rsp->sec);
					soeTime.cms  = GET_BCD(pF12Rsp->ms[0]) * 100 + GET_BCD(pF12Rsp->ms[1]);
					
					switch (pF12Rsp->type) {
					case 1:			// normal di soe
						gix = DINORMSLOT;
						pix = pF12Rsp->idx;
						if (pix < 8) {
							value = (UCHAR)GET_BIT(pF12Rsp->state[1], pix) ? 1 : 0;
						}
						else if (pix < 16) {
							value = (UCHAR)GET_BIT(pF12Rsp->state[0], pix) ? 1 : 0;
						}
						else {		// control wire broken
							value = 1;
						}
						// generate SOE message
						UpdRtuSoeData(sendInfo->pRtu, gix, pix, value, &soeTime);
						break;
					case 2:			// protect relay soe
						gix = DINORMSLOT;
						pix = pF12Rsp->idx + DIPROOFFSET;
						value = (pF12Rsp->state[3] | pF12Rsp->state[2] << 8 |
								 pF12Rsp->state[1] << 16 | pF12Rsp->state[0] << 24) / 2;
						switch (pF12Rsp->attr) {
						case 0:		// 电流
						case 5:		// 正序电流
						case 6:		// 负序电流
						case 8:		// 横差
							fvalue = (float)sqrt((double)value) * 100.0f / CURRRATIO / 12.0f;

							sprintf(comstr, "%s%6.2f", evtstr[pF12Rsp->attr], fvalue);
							// send soe message
							UpdRtuSoeData(sendInfo->pRtu, gix, pix, 1, &soeTime, comstr);
							break;
						case 1:		// 电压
						case 4:		// 零序电压
							fvalue = (float)sqrt((double)value) * 100.0f / VOLTRATIO / 12.0f;

							sprintf(comstr, "%s%6.2f", evtstr[pF12Rsp->attr], fvalue);
							// send soe message
							UpdRtuSoeData(sendInfo->pRtu, gix, pix, 1, &soeTime, comstr);
							break;
						case 2:		// 频率(动作值取前两字节)
							value = pF12Rsp->state[1] | pF12Rsp->state[0] << 8;
							fvalue = FREQRATIO / (float)value;

							sprintf(comstr, "%s%6.2f", evtstr[pF12Rsp->attr], fvalue);
							// send soe message
							UpdRtuSoeData(sendInfo->pRtu, gix, pix, 1, &soeTime, comstr);
							break;
						case 3:		// 零序电流
							fvalue = (float)sqrt((double)value) * 100.0f / ZCURRATIO / 12.0f;

							sprintf(comstr, "%s%6.2f", evtstr[pF12Rsp->attr], fvalue);
							// send soe message
							UpdRtuSoeData(sendInfo->pRtu, gix, pix, 1, &soeTime, comstr);
							break;
						case 7:		// 温度
							UpdRtuSoeData(sendInfo->pRtu, gix, pix, 1, &soeTime);
							break;
						case 9:		// 功率
							UpdRtuSoeData(sendInfo->pRtu, gix, pix, 1, &soeTime);
							break;
						}

						// issue alarm for this point as well
						// UpsRtuSoeAlm(sendInfo->pRtu, gix, pix);
						break;
					}
				}
				
				// send additional polling command
				sendInfo->FuncCode = RFLH_POLL;
				// add a high priority refresh poll
				AddMorePollCmd(sendInfo, TRUE);
				break;

⌨️ 快捷键说明

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