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

📄 device.cpp

📁 一个电力系统方面的ISA通讯规约
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Device.cpp: implementation of the CDevice class.
//
//////////////////////////////////////////////////////////////////////
// create : Benny 2001.7.25

#include "stdafx.h"
#include "ISA.h"
#include "Datafile.h"
#include "Manevt.h"
#include "Premapi.h"
#include "Serial.h"
#include <math.h>
#include "IPremSvr.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
extern CISAApp theApp;

BYTE GetBcd(BYTE btValue)
{
	btValue	%=100;
	BYTE btRet;
	btRet = btValue /10;
	btRet = btRet *16 +btValue %10;
	return btRet;
}
BYTE FromBcd(BYTE btValue)
{
	BYTE btRet = ((btValue >>4 )&0x0f ) * 10 ;
	btRet += btValue & 0x0f;
	return btRet;
}


CDevice::CDevice()
{
	m_btAddr = (BYTE)-1;
	m_wParent = (WORD)-1;
	m_btCPU = (BYTE)-1;
	m_btArea = (BYTE)-1;

	m_nState = STATE_FREE;
	m_nCommand = STATE_REQ;
	m_nLastReqCommand = STATE_REQ;

	m_uTimeOutCount = 0;
	m_uWait = 0;

	m_uDZHMsg = -1;

	m_szName = "";
	m_szType = "";
	m_szParent = "";


	m_bComm = TRUE;

	m_hComPort = NULL;

	memset( &m_DZHParam, 0, sizeof(PREMDZHPARAM) );
}

CDevice::~CDevice()
{
}

void CDevice::OnCommError()
{
	m_uWait = 0;
	m_bComm = FALSE;

	EVENTITEM EventItem;
	memset( &EventItem, 0, sizeof( EVENTITEM ) );
	
	EventItem.lTime = time( NULL );
	EventItem.btEvent = EVENT_EXPLAIN;
	EventItem.wStation = m_wParent;

	CString szInfo = m_szName;
	szInfo += "通讯中断";
	strncpy( EventItem.szExplain, szInfo, EVENTEXPLEN );

	::DoEvent( &EventItem );

	BYTE btCom[32] = "";
	BYTE* pbtCom = btCom;
	*(WORD*)pbtCom = (WORD)m_btAddr;
	pbtCom += sizeof(WORD);
	*pbtCom++ = DIGIT_RAW_DATA;

	*(WORD*)pbtCom = sizeof(WORD) + sizeof(BYTE);
	pbtCom += sizeof(WORD);

	*(WORD*)pbtCom = 0;
	pbtCom += sizeof(WORD);
	*pbtCom = 0;
	::WriteRdbData( ( const char* )btCom );
}

void CDevice::OnCommOK()
{
	m_bComm = TRUE;

	EVENTITEM EventItem;
	memset( &EventItem, 0, sizeof( EVENTITEM ) );
	
	EventItem.lTime = time( NULL );
	EventItem.btEvent = EVENT_EXPLAIN;
	EventItem.wStation = m_wParent;

	CString szInfo = m_szName;
	szInfo += "通讯恢复";
	strncpy( EventItem.szExplain, szInfo, EVENTEXPLEN );

	::DoEvent( &EventItem );

		BYTE btCom[32] = "";
	BYTE* pbtCom = btCom;
	*(WORD*)pbtCom = (WORD)m_btAddr;
	pbtCom += sizeof(WORD);
	*pbtCom++ = DIGIT_RAW_DATA;

	*(WORD*)pbtCom = sizeof(WORD) + sizeof(BYTE);
	pbtCom += sizeof(WORD);

	*(WORD*)pbtCom = 0;
	pbtCom += sizeof(WORD);
	*pbtCom = 1;
	::WriteRdbData( ( const char*)btCom );

}


int CDevice::SignalReset(PREMDZHPARAM* pDZHParam, UINT uMsg)
{
	if ( !m_bComm || m_nCommand > STATE_REQ )
		return PREM_ERR_MSG;

//	if ( !InitProtParam( pDZHParam, uMsg ) )
//		return PREM_ERR_MSG;


	m_nCommand = STATE_SIGNALRESET;
	return PREM_OK;
}

int CDevice::CheckTime(PREMDZHPARAM* pDZHParam, UINT uMsg)
{
	if ( !m_bComm || m_nCommand > STATE_REQ )
		return PREM_ERR_MSG;

	if ( !InitProtParam( pDZHParam, uMsg ) )
		return PREM_ERR_MSG;

	m_nCommand = STATE_CHECKTIME;
	
	return PREM_OK;
}


int CDevice::AskProtectAna(PREMDZHPARAM* pDZHParam, UINT uMsg)
{
	if ( !m_bComm || m_nCommand > STATE_REQ )
		return PREM_ERR_MSG;

	if ( !InitProtParam( pDZHParam, uMsg ) )
		return PREM_ERR_MSG;
	g_pTable = (nsIRdbTable*)pDZHParam->pDZHTable;
	g_pTable->ClearFields();
	g_pTable->ClearRecords();
	g_pTable->SetFieldCount(ANAFIELDCOUNT);
	RDBFIELDINFO RdbFieldInfo;
	for ( int i = 0; i < ANAFIELDCOUNT ; i++ )
	{
		GetFieldInfo( RdbFieldInfo, &ANAFieldInfos[i] );
		if( !g_pTable->SetFieldInfo( i, &RdbFieldInfo ) )
		{
			g_pTable->Release();
			g_pTable = NULL;
			break;
		}
	}

	m_nCommand = STATE_ASKSIMULATION;
	return PREM_OK;
}


void CDevice::GetFieldInfo( RDBFIELDINFO& RdbFieldInfo, DZTableFieldInfo* pInfo )
{
	 RdbFieldInfo.ODBCFieldInfo.m_strName = pInfo->strName;
	 RdbFieldInfo.ODBCFieldInfo.m_nSQLType = pInfo->nSQLType;
	 RdbFieldInfo.ODBCFieldInfo.m_nPrecision = 0;
	 RdbFieldInfo.ODBCFieldInfo.m_nScale = 0;
	 RdbFieldInfo.ODBCFieldInfo.m_nNullability = SQL_NULLABLE;
}


int CDevice::AskValue(PREMDZHPARAM* pDZHParam, UINT uMsg)
{

	if ( !m_bComm || m_nCommand > STATE_REQ )
		return PREM_ERR_MSG;

	if ( !InitProtParam( pDZHParam, uMsg ) )
		return PREM_ERR_MSG;

	g_pTable =(nsIRdbTable*)pDZHParam->pDZHTable;
	g_pTable->ClearFields();
	g_pTable->ClearRecords();
	g_pTable->SetFieldCount(DZFIELDCOUNT);
	RDBFIELDINFO RdbFieldInfo;
	for ( int i = 0; i < DZFIELDCOUNT ; i++ )
	{
		GetFieldInfo( RdbFieldInfo, &DZFieldInfos[i] );
		if( !g_pTable->SetFieldInfo( i, &RdbFieldInfo ) )
		{
			g_pTable->Release();
			g_pTable = NULL;
			break;
		}
	}

	m_nCommand = STATE_ASKVALUE;
	
	return PREM_OK;
}

int CDevice::ChangeValue(PREMDZHPARAM* pDZHParam, UINT uMsg)
{
	if ( !m_bComm || m_nCommand > STATE_REQ )
		return PREM_ERR_MSG;
	if ( !InitProtParam( pDZHParam, uMsg ) )
		return PREM_ERR_MSG;
	g_pTable =(nsIRdbTable*)pDZHParam->pDZHTable;

	m_nCommand = STATE_CHANGEVALUE;
	
	return PREM_OK;	

}

int CDevice::AckChangeValue(PREMDZHPARAM* pDZHParam, UINT uMsg)
{
	if ( !m_bComm || m_nCommand > STATE_REQ )
		return PREM_ERR_MSG;

	if ( !InitProtParam( pDZHParam, uMsg ) )
		return PREM_ERR_MSG;
	g_pTable =(nsIRdbTable*)pDZHParam->pDZHTable;
	
	m_nCommand = STATE_ACKCHANGEVALUE;
		
	return PREM_OK;
}

int CDevice::NakChangeValue(PREMDZHPARAM* pDZHParam, UINT uMsg)
{
	if ( !m_bComm || m_nCommand > STATE_REQ )
		return PREM_ERR_MSG;

	if ( !InitProtParam( pDZHParam, uMsg ) )
		return PREM_ERR_MSG;
	g_pTable =(nsIRdbTable*)pDZHParam->pDZHTable;
	
	m_nCommand = STATE_NAKCHANGEVALUE;
		
	return PREM_OK;
}

BOOL CDevice::CheckRecvFrame(BYTE* pData, int nLength)
{
	if ( 0xeb != pData[ISA_SYNCCODE0]
		|| 0x90 != pData[ISA_SYNCCODE1]
		|| 0xeb != pData[ISA_SYNCCODE2]
		|| 0x90 != pData[ISA_SYNCCODE3] )
		return FALSE;

	if ( ISA_START_CODE != pData[ISA_STARTCODE])
		return FALSE;
	if (ISA_ACK == pData[ISA_CODE] || ISA_NAK == pData[ISA_CODE])
		return TRUE;

	if ( ISA_END_CODE != *(pData + nLength - 1) )
		return FALSE;
	if (nLength <9)
		return FALSE;
//	if ( *(WORD*)(pData + nLength - 3) != CheckSum( pData + ISA_CODE, nLength - 9  ) )
//		return FALSE;

	if ( m_wParent != pData[ISA_ADDR]
		|| nLength - 9 != pData[ISA_LENGTH] )
		return FALSE;

	return TRUE;
}

BOOL CDevice::CheckProtParam(PREMDZHPARAM *pDZHParam)
{
	/* 若传递的定值表参数中回调窗口句柄和回掉函数
	   均无效,则返回参数错误                     */
	if ( NULL == pDZHParam ||
		!::IsWindow( pDZHParam->callback.hWnd ) &&
		NULL == pDZHParam->callback.lpCallBack )
		return FALSE;

	//从参数中取得两个表
	nsIRdbTable* pProtectParam = (nsIRdbTable*)pDZHParam->pProtectParam;
	nsIRdbTable* pDZHTable = (nsIRdbTable*)pDZHParam->pDZHTable;

	if ( pDZHTable != NULL )
	{
		//表中不存在“定值”域和“定值性质”域,则报错返回
		int	nDZHPropFieldIndex = pDZHTable->GetFieldIndex( "定值性质" );
		int	nDZHValueFieldIndex = pDZHTable->GetFieldIndex( "定值" );
		if ( nDZHPropFieldIndex < 0 || nDZHValueFieldIndex < 0 )
			return FALSE;
	}

	if ( pProtectParam != NULL )
	{
		int nDZHAreaFieldIndex = pProtectParam->GetFieldIndex( "区号" );
		int nDZHCPUFieldIndex = pProtectParam->GetFieldIndex( "CPU号" );
		if ( nDZHAreaFieldIndex < 0 || nDZHCPUFieldIndex < 0 )
			return FALSE;
	}
	
	return TRUE;
}

//对上层保护类命令的回调处理
void CDevice::DZHCallBack(int nResultCode)
{
	m_DZHParam.result.nResult = nResultCode;
	if ( m_DZHParam.callback.hWnd != NULL )
	{
		if ( IsWindow( m_DZHParam.callback.hWnd ) )
			::SendMessage( m_DZHParam.callback.hWnd, WM_PREM_RESULT,
				(WPARAM)m_uDZHMsg, (LPARAM)&m_DZHParam );
		else
		{
			if ( m_DZHParam.pProtectParam != NULL )
				((nsIRdbTable*)(m_DZHParam.pProtectParam))->Release();
			if ( m_DZHParam.pDZHTable != NULL )
				((nsIRdbTable*)(m_DZHParam.pDZHTable))->Release();
		}
	}
	else if ( m_DZHParam.callback.lpCallBack )
		m_DZHParam.callback.lpCallBack( (WPARAM)m_uDZHMsg,
			(LPARAM)&m_DZHParam );

	m_DZHParam.pDZHTable = NULL;
	m_DZHParam.pProtectParam = NULL;
}



void CDevice::GetDeviceType()
{
	m_szType = "未定义";
	nsCOMPtr<nsIRdbTable> pTable;
	if ( !::GetDeviceTable( getter_AddRefs( pTable ) ) )
		return;

	BYTE btAddr;
	pTable->MoveFirst();
	while( !pTable->IsEOF() )
	{
		if ( pTable->GetFieldValue( "地址", &btAddr, DBVT_UCHAR, sizeof(UCHAR) )
			&& btAddr == m_btAddr )
		{
			pTable->GetFieldValue( "模板名称", m_szType );
			break;
		}

		pTable->MoveNext();
	}
}

BOOL CDevice::InitProtParam(PREMDZHPARAM *pDZHParam, UINT uMsg)
{
	m_DZHParam  =  *pDZHParam;
	m_uDZHMsg = uMsg;

	return TRUE;
}

void CDevice::OnTimer()
{

}

void CDevice::OnTimeOut()
{
	switch( m_nState )
	{
	case STATE_ASKVALUE:
	case STATE_CHANGEVALUE:
	case STATE_ACKCHANGEVALUE:
		DZHCallBack( PREM_ERR_PROTECT );
		break;

	default:
		break;
	}
	m_nCommand = STATE_FREE;
	m_nState = STATE_FREE;
	m_btSendState = SENDIDLE;
}

void CDevice::OnInit(DBHANDLE dbHandle)
{
	WORD wAddr = (WORD)-1;
	WORD wParent = (WORD)-1;
	char szName[DEVICENAMELEN] = "";
	char szParent[DEVICENAMELEN] = "";
	char szAddr[COMSETTINGLEN] = "";

	::GetAttr( dbHandle, ATTR_ST_RTUNO, &wAddr );
	::GetAttr( dbHandle, ATTR_ST_NAME, szName );	
	::GetAttr( dbHandle, ATTR_ST_COM, szAddr );
		
	DBHANDLE dbParent = ::GetParentDbHandle( dbHandle );
	char szCom[COMSETTINGLEN] = "";
	if ( ::IsValidDbHandle( dbParent ) )
	{
		::GetAttr( dbParent, ATTR_ST_RTUNO, &wParent );
		::GetAttr( dbParent, ATTR_ST_NAME, &szParent );
		::GetAttr( dbParent, ATTR_ST_COM, szCom );
	}
	
	m_btAddr = wAddr;
	m_btArea = atoi(szAddr);
	m_szName = szName;
	m_wParent = wParent;
	m_szParent = szParent;
	GetDeviceType();
	m_nState = STATE_FREE;
	m_nCommand = STATE_REQ;
	m_nLastReqCommand = STATE_REQ;
	m_btSendState =SENDIDLE;
}

void CDevice::ProcessSend()
{
	m_nState = m_nCommand;
	//正点对时
    SYSTEMTIME SystemTime;
	::GetSystemTime( &SystemTime );
    if(SystemTime.wMinute == 0 && SystemTime.wSecond<= 6)
	{
      m_nCommand = STATE_CHECKTIME;
	}
	else
	{
	////////////////
	 m_nCommand = STATE_REQ;
	}



	switch ( m_nState )
	{
	case STATE_FREE:			// 空闲
		break;
	case STATE_ACK_R:
		SendCommand(ISA_ACK);
		m_nCommand = STATE_REQ;
        m_nState = STATE_FREE;
		break;
	case STATE_REQ:			// 查询命令1
		SendCommand( ISA_C1 );
		m_nLastReqCommand = STATE_REQ;
		break;
	case STATE_ASKVALUE:		// 申请定值
		SendCommand( ISA_C3 );
		break;

	case STATE_ASKSIMULATION:	// 申请模拟量
		SendCommand( ISA_C4 );
		break;

	case STATE_SIGNALRESET:		// 申请信号复归
		SendCommand( ISA_C5 );
		m_nState = STATE_FREE;
		break;
	case STATE_CHANGEVALUE:		// 修改定值
		SendCommand( ISA_C6 );
		break;
	case STATE_CHECKTIME:
		SendCommand( ISA_C7 );
		break;
	case STATE_ACKCHANGEVALUE:
		SendCommand( ISA_ACK );
		DZHCallBack( PREM_OK );
		
		break;
	case STATE_NAKCHANGEVALUE:
		SendCommand( ISA_NAK );
		DZHCallBack( PREM_OK );
		break;
	default:
		break;
	}

}

void CDevice::ProcessReceive(BYTE* pData, int nLength)
{
//	if ( m_uTimeOutCount >= theApp.m_uTimes )
//		OnCommOK();

	m_uTimeOutCount = 0;

	if ( !CheckRecvFrame( pData, nLength ) )
		return;

	BYTE btAddr = pData[ISA_ADDR];
	BYTE btCode = pData[ISA_CODE];
	BYTE btLength = 0;


	switch( btCode )
	{
	case ISA_ACK:
		break;

	case ISA_NAK:
		//if ( STATE_ACKCHANGEVALUE != m_nState )
		//	break;

		pData += ISA_DATA;
		ProcessNak( pData, btLength );
		break;

	case ISA_R1:
		//if ( STATE_REQ != m_nState )
		//	break;
        
		btLength = pData[ISA_LENGTH]-4;
		pData += ISA_DATA;
		if ( ProcessR1( pData, btLength ) )
			SendCommand( ISA_ACK );
		else
			SendCommand( ISA_NAK );

		break;

	case ISA_R2:
		//add by llj to ack 
		if(STATE_REQ == m_nState || m_nState == STATE_FREE )
		{
          SendCommand( ISA_ACK );
		  break;
		}
		if ( STATE_ASKVALUE != m_nState && STATE_CHANGEVALUE != m_nState  )
			break;

		btLength = pData[ISA_LENGTH];
		pData += ISA_DATA;
		if ( ProcessR2( pData, btLength ) )
		{
			DZHCallBack( PREM_OK );
			//add by llj to ack 
            SendCommand( ISA_ACK );
			//m_nCommand = STATE_ACK;

⌨️ 快捷键说明

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