📄 device.cpp
字号:
// 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 + -