2024-07-08 10:27:17 +08:00
# include "iec104.h"
CIEC104ProcessItem : : CIEC104ProcessItem ( )
{
apdu_addr = 0 ;
apdu_setup = FALSE ;
apdu_setup_sent = FALSE ;
end_of_initialisation = FALSE ;
apdu_ns = 0 ;
apdu_nr = 0 ;
apdu_ack = 0 ;
apdu_t0_begin = 0 ;
apdu_t1_begin = 0 ;
apdu_t2_begin = 0 ;
apdu_t3_begin = 0 ;
apdu_t4_begin = 0 ;
apdu_t5_begin = 0 ;
background_scan_begin = 0 ;
apdu_wait_test = FALSE ;
apdu_i_buffer = NULL ;
apdu_unack = NULL ;
apdu_k_max = 12 ;
apdu_k = 0 ;
apdu_w_max = 8 ;
apdu_w = 0 ;
2024-09-24 15:59:22 +08:00
interrogation_type = 0 ;
2024-07-08 10:27:17 +08:00
interrogation_start = FALSE ; //总召启动
interrogation_yx_fin = FALSE ; //遥信发送完毕
interrogation_yc_fin = FALSE ; //遥测发送完毕
2024-09-24 15:59:22 +08:00
pulse_type = 0 ;
2024-07-08 10:27:17 +08:00
pulse_start = FALSE ;
pulse_fin = FALSE ;
clock_synchronized_start = FALSE ;
clock_synchronized_finish = FALSE ;
interrogation_start = FALSE ;
interrogation_finish = FALSE ;
memset ( & ycbws , 0 , sizeof ( ycbws ) ) ;
memset ( & yxbws , 0 , sizeof ( yxbws ) ) ;
memset ( & events , 0 , sizeof ( events ) ) ;
}
CIEC104ProcessItem : : ~ CIEC104ProcessItem ( )
{
apdu_addr = 0 ;
apdu_setup = FALSE ;
apdu_setup_sent = FALSE ;
end_of_initialisation = FALSE ;
apdu_ns = 0 ;
apdu_nr = 0 ;
apdu_ack = 0 ;
apdu_t0_begin = 0 ;
apdu_t1_begin = 0 ;
apdu_t2_begin = 0 ;
apdu_t3_begin = system32 . timers ;
apdu_t4_begin = 0 ;
apdu_t5_begin = 0 ;
apdu_wait_test = FALSE ;
apdu_k = 0 ;
if ( apdu_i_buffer )
{
delete [ ] apdu_i_buffer ;
apdu_i_buffer = NULL ;
}
if ( apdu_unack )
{
delete [ ] apdu_unack ;
apdu_unack = NULL ;
}
apdu_w = 0 ;
2024-09-24 15:59:22 +08:00
interrogation_type = 0 ;
2024-07-08 10:27:17 +08:00
interrogation_start = FALSE ; //总召启动
interrogation_yx_fin = FALSE ; //遥信发送完毕
interrogation_yc_fin = FALSE ; //遥测发送完毕
2024-09-24 15:59:22 +08:00
pulse_type = 0 ;
pulse_start = FALSE ;
pulse_fin = FALSE ;
2024-07-08 10:27:17 +08:00
clock_synchronized_start = FALSE ;
clock_synchronized_finish = FALSE ;
interrogation_start = FALSE ;
interrogation_finish = FALSE ;
memset ( & ycbws , 0 , sizeof ( ycbws ) ) ;
memset ( & yxbws , 0 , sizeof ( yxbws ) ) ;
memset ( & events , 0 , sizeof ( events ) ) ;
}
void CIEC104ProcessItem : : Attach ( int uid , int sock , DWORD peer_addr , WORD peer_port )
{
int i ;
CNetProcessItem : : Attach ( uid , sock , peer_addr , peer_port ) ;
apdu_setup = FALSE ;
apdu_setup_sent = FALSE ;
apdu_ns = 0 ;
apdu_nr = 0 ;
apdu_ack = 0 ;
apdu_t1_begin = 0 ;
apdu_t2_begin = 0 ;
apdu_t3_begin = system32 . timers ;
apdu_t4_begin = 0 ;
apdu_t5_begin = 0 ;
apdu_wait_test = FALSE ;
apdu_k = 0 ;
if ( apdu_i_buffer )
{
delete [ ] apdu_i_buffer ;
apdu_i_buffer = NULL ;
}
apdu_i_buffer = new APDUBuffer [ apdu_k_max ] ;
memset ( apdu_i_buffer , 0 , sizeof ( APDUBuffer ) * apdu_k_max ) ;
if ( apdu_unack )
{
delete [ ] apdu_unack ;
apdu_unack = NULL ;
}
apdu_unack = new int [ apdu_k_max ] ;
for ( i = 0 ; i < apdu_k_max ; i + + )
{
apdu_unack [ i ] = i ;
}
apdu_w = 0 ;
2024-09-24 15:59:22 +08:00
interrogation_type = 0 ;
2024-07-08 10:27:17 +08:00
interrogation_start = FALSE ; //总召启动
interrogation_yx_fin = FALSE ; //遥信发送完毕
interrogation_yc_fin = FALSE ; //遥测发送完毕
2024-09-24 15:59:22 +08:00
pulse_type = 0 ;
pulse_start = FALSE ;
pulse_fin = FALSE ;
2024-07-08 10:27:17 +08:00
clock_synchronized_start = FALSE ;
clock_synchronized_finish = FALSE ;
interrogation_start = FALSE ;
interrogation_finish = FALSE ;
}
void CIEC104ProcessItem : : Release ( void )
{
apdu_setup = FALSE ;
apdu_setup_sent = FALSE ;
apdu_ns = 0 ;
apdu_nr = 0 ;
apdu_ack = 0 ;
apdu_t1_begin = 0 ;
apdu_t2_begin = 0 ;
apdu_t3_begin = system32 . timers ;
apdu_t4_begin = 0 ;
apdu_t5_begin = 0 ;
apdu_wait_test = FALSE ;
apdu_k = 0 ;
if ( apdu_i_buffer )
{
delete [ ] apdu_i_buffer ;
apdu_i_buffer = NULL ;
}
if ( apdu_unack )
{
delete [ ] apdu_unack ;
apdu_unack = NULL ;
}
apdu_w = 0 ;
2024-09-24 15:59:22 +08:00
interrogation_type = 0 ;
2024-07-08 10:27:17 +08:00
interrogation_start = FALSE ; //总召启动
interrogation_yx_fin = FALSE ; //遥信发送完毕
interrogation_yc_fin = FALSE ; //遥测发送完毕
2024-09-24 15:59:22 +08:00
pulse_type = 0 ;
pulse_start = FALSE ;
pulse_fin = FALSE ;
2024-07-08 10:27:17 +08:00
clock_synchronized_start = FALSE ;
clock_synchronized_finish = FALSE ;
interrogation_start = FALSE ;
interrogation_finish = FALSE ;
CNetProcessItem : : Release ( ) ;
}
CIEC104Process : : CIEC104Process ( )
{
asdu_addr_length = 2 ;
cot_length = 2 ;
info_addr_length = 3 ;
max_frame = 254 ;
apdu_t0_max = 30 ; //t0的最大值(设定)
apdu_t1_max = 15 ; //t1的最大值(设定)
apdu_t2_max = 10 ; //t2的最大值(设定)
apdu_t3_max = 20 ; //t3的最大值(设定)
apdu_t4_max = 300 ; //t4的最大值(设定)
apdu_t5_max = 900 ; //t5的最大值(设定)
background_scan_cycle = 600 ; //背景扫描时间
use_cycle_interrogation_command = FALSE ; //使用循环总召唤
send_start_dt = FALSE ; //发送启动帧
use_send_test = FALSE ; //使用发送测试帧
send_test_type = 0 ; //发送测试帧类型
use_send_end_of_initialisation = FALSE ;
use_ns_nr_check = FALSE ;
last_sec = 0 ;
m_yx_start_address = IEC_101_104_YX_START_ADDR ;
m_yc_start_address = IEC_101_104_YC_START_ADDR ;
m_ym_start_address = IEC_101_104_YM_START_ADDR ;
}
CIEC104Process : : ~ CIEC104Process ( )
{
}
CNetProcessItem * CIEC104Process : : CreateItem ( int ord )
{
return dynamic_cast < CNetProcessItem * > ( new CIEC104ProcessItem ) ;
}
void CIEC104Process : : DestroyItem ( int ord , BOOLEAN bDeleted )
{
CIEC104ProcessItem * pItem = ( CIEC104ProcessItem * ) GetItem ( ord ) ;
if ( pItem ! = NULL & & ! bDeleted )
{
delete pItem ;
return CNetProcess : : DestroyItem ( ord , TRUE ) ;
}
return CNetProcess : : DestroyItem ( ord , bDeleted ) ;
}
BOOLEAN CIEC104Process : : OnPreCreate ( int id )
{
if ( ! CNetProcess : : OnPreCreate ( id ) ) return FALSE ;
if ( ! GetOption ( & m_nOption , sizeof ( m_nOption ) ) )
{
return FALSE ;
}
asdu_addr_length = m_nOption . asdu_addr_size ;
cot_length = m_nOption . cot_size ;
info_addr_length = m_nOption . info_addr_size ;
max_frame = 254 ;
apdu_t0_max = m_nOption . t0 ; //t0的最大值(设定)
apdu_t1_max = m_nOption . t1 ; //t1的最大值(设定)
apdu_t2_max = m_nOption . t2 ; //t2的最大值(设定)
apdu_t3_max = m_nOption . t3 ; //t3的最大值(设定)
apdu_t4_max = m_nOption . t4 ; //t4的最大值(设定)
apdu_t5_max = m_nOption . t5 ; //t5的最大值(设定)
background_scan_cycle = m_nOption . background_scan_cycle ; //背景扫描时间
use_cycle_interrogation_command = m_nOption . use_cycle_interrogation_command ; //使用循环总召唤
send_start_dt = m_nOption . send_start_dt ; //发送启动帧
use_send_test = m_nOption . use_send_test ; //使用发送测试帧
send_test_type = m_nOption . send_test_type ; //发送测试帧类型
use_send_end_of_initialisation = m_nOption . use_send_end_of_initialisation ;
use_ns_nr_check = m_nOption . use_ns_nr_check ;
return TRUE ;
}
void CIEC104Process : : GetItemYXBWs ( CIEC104ProcessItem * pItem )
{
int i , uid , count ;
int yxbw_point ;
BOOLEAN yxbw_value ;
BYTE yxbw_qds ;
if ( NULL = = pItem ) return ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return ;
2024-12-03 10:36:06 +08:00
//if (NULL == pItem->yxbws.data) return;
2024-07-08 10:27:17 +08:00
count = pItem - > yxbws . count ;
if ( count < 0 | | count > = DATABASE_YXBW_NUM ) count = 0 ;
int max_count = DATABASE_YXBW_NUM - count ;
for ( i = 0 ; i < max_count ; i + + )
{
yxbw_point = GetUnitYXBW ( uid , yxbw_value , yxbw_qds ) ;
if ( yxbw_point < 0 ) break ;
if ( count > = DATABASE_YXBW_NUM ) break ;
pItem - > yxbws . data [ count ] . order = yxbw_point ;
pItem - > yxbws . data [ count ] . value = yxbw_value ;
pItem - > yxbws . data [ count ] . qds = yxbw_qds ;
count + + ;
}
pItem - > yxbws . count = count ;
}
void CIEC104Process : : GetItemEvents ( CIEC104ProcessItem * pItem )
{
int i , uid , count ;
int soe_point ;
BOOLEAN soe_value ;
BYTE soe_qds ;
unionCP56Time soe_time ;
if ( NULL = = pItem ) return ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return ;
2024-12-03 10:36:06 +08:00
//if (NULL == pItem->events.data) return;
2024-07-08 10:27:17 +08:00
count = pItem - > events . count ;
if ( count < 0 | | count > = DATABASE_SOE_NUM ) count = 0 ;
int max_count = DATABASE_SOE_NUM - count ;
for ( i = 0 ; i < max_count ; i + + )
{
soe_point = GetUnitSOE ( uid , soe_value , soe_qds , soe_time ) ;
if ( soe_point < 0 ) break ;
pItem - > events . data [ count ] . order = soe_point ;
pItem - > events . data [ count ] . value = soe_value ;
pItem - > events . data [ count ] . qds = soe_qds ;
memcpy ( & pItem - > events . data [ count ] . ct , & soe_time , sizeof ( soe_time ) ) ;
count + + ;
}
pItem - > events . count = count ;
}
void CIEC104Process : : GetItemYCBWs ( CIEC104ProcessItem * pItem )
{
int i , uid , count ;
if ( NULL = = pItem ) return ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return ;
2024-12-03 10:36:06 +08:00
//if (NULL == pItem->ycbws.data) return;
2024-07-08 10:27:17 +08:00
count = pItem - > ycbws . count ;
if ( count < 0 | | count > = pItem - > total_yc ) count = 0 ;
for ( i = 0 ; i < pItem - > total_yc ; i + + )
{
if ( TRUE = = IsUnitYCBW ( uid , i ) )
{ //有变位产生
pItem - > ycbws . data [ count ] . order = i ;
pItem - > ycbws . data [ count ] . value = GetUnitYC ( uid , i ) ;
pItem - > ycbws . data [ count ] . flVal = GetUnitYCReal ( uid , i ) ;
pItem - > ycbws . data [ count ] . qds = GetUnitYCQDS ( uid , i ) ;
ClearUnitYCBW ( uid , i ) ;
count + + ;
}
}
pItem - > ycbws . count = count ;
}
int CIEC104Process : : OnPackageReceived ( BYTE * pBuf , int count , int ord )
{
int uid ;
int len ;
CIEC104ProcessItem * pItem ;
pItem = ( CIEC104ProcessItem * ) GetItem ( ord ) ;
if ( NULL = = pItem ) return - 1 ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return - 1 ;
if ( count < 6 ) return 0 ;
if ( pBuf [ 0 ] ! = 0x68 )
{ //无效链路报文
DisplayRxData ( pBuf , count , FALSE , uid ) ;
vLog ( LOG_ERROR , " Invalid STX character of 0x%02x. \n " , ( int ) pBuf [ 0 ] ) ;
return - 1 ;
}
len = pBuf [ 1 ] ;
if ( count < ( len + 2 ) )
{ //数据长度不足
return 0 ;
}
//处理接收到的报文
DisplayRxData ( pBuf , ( len + 2 ) , TRUE , uid ) ;
if ( ( pBuf [ 2 ] & 0x01 ) = = 0x00 )
{ //I frame
WORD ns = ( ( ( pBuf [ 3 ] < < 8 ) | pBuf [ 2 ] ) > > 1 ) & 0x7fff ;
WORD nr = ( ( ( pBuf [ 5 ] < < 8 ) | pBuf [ 4 ] ) > > 1 ) & 0x7fff ;
if ( ! OnIFrameReceived ( ns , nr , & pBuf [ 6 ] , len - 4 , ord ) )
{
return - 1 ;
}
}
else if ( ( pBuf [ 2 ] & 0x03 ) = = 0x01 )
{ //S frame
WORD nr = ( ( ( pBuf [ 5 ] < < 8 ) | pBuf [ 4 ] ) > > 1 ) & 0x7fff ;
if ( ! OnSFrameReceived ( nr , ord ) )
{
return - 1 ;
}
}
else
{ //U frame
BOOLEAN STARTDT_ACT = ( pBuf [ 2 ] & 0x04 ) = = 0x04 ? TRUE : FALSE ;
BOOLEAN STARTDT_CON = ( pBuf [ 2 ] & 0x08 ) = = 0x08 ? TRUE : FALSE ;
BOOLEAN STOPDT_ACT = ( pBuf [ 2 ] & 0x10 ) = = 0x10 ? TRUE : FALSE ;
BOOLEAN STOPDT_CON = ( pBuf [ 2 ] & 0x20 ) = = 0x20 ? TRUE : FALSE ;
BOOLEAN TESTFR_ACT = ( pBuf [ 2 ] & 0x40 ) = = 0x40 ? TRUE : FALSE ;
BOOLEAN TESTFR_CON = ( pBuf [ 2 ] & 0x80 ) = = 0x80 ? TRUE : FALSE ;
if ( ! OnUFrameReceived ( STARTDT_ACT , STARTDT_CON , STOPDT_ACT , STOPDT_CON , TESTFR_ACT , TESTFR_CON , ord ) )
{
return - 1 ;
}
}
if ( pItem - > apdu_setup )
{ //startdt 后开始喂单元狗
UnitFeedDog ( uid ) ;
}
return ( len + 2 ) ;
}
BOOLEAN CIEC104Process : : OnDealWithPeerNR ( CIEC104ProcessItem * pItem , WORD nr )
{
///////此处需要调试一下!!!!
int i ;
int uid ;
int pos ;
int buffer [ 256 ] ;
APDUBuffer * pAPDU ;
if ( NULL = = pItem ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( ! use_ns_nr_check )
{
//确认全部的缓冲报文
pItem - > apdu_k = 0 ;
pItem - > apdu_ack = nr ;
//停止t1计时
pItem - > apdu_t1_begin = 0 ;
return TRUE ;
}
if ( nr = = pItem - > apdu_ns )
{ ///pass
//确认全部的缓冲报文
pItem - > apdu_k = 0 ;
pItem - > apdu_ack = nr ;
//停止t1计时
pItem - > apdu_t1_begin = 0 ;
}
else if ( pItem - > apdu_ack = = pItem - > apdu_ns )
{ ///pass
vLog ( LOG_ERROR , " Unit(%d) invalid I frame order(nr=%d,ack=%d,ns=%d). \n " , uid , nr , pItem - > apdu_ack , pItem - > apdu_ns ) ;
return FALSE ;
}
else if ( pItem - > apdu_ack < pItem - > apdu_ns )
{
if ( nr < pItem - > apdu_ack | | nr > pItem - > apdu_ns )
{ //I帧序列错误,主动断开链路
vLog ( LOG_ERROR , " Unit(%d) invalid I frame order(nr=%d,ack=%d,ns=%d). \n " , uid , nr , pItem - > apdu_ack , pItem - > apdu_ns ) ;
return FALSE ;
}
if ( nr = = pItem - > apdu_ack )
{ //无报文需要确认
vLog ( LOG_DEBUG , " Unit(%d) not ack order(nr=%d,ack=%d,ns=%d). \n " , uid , nr , pItem - > apdu_ack , pItem - > apdu_ns ) ;
return TRUE ;
}
//确认ACK至NR之间的缓冲报文(******)
for ( i = 0 ; i < pItem - > apdu_k ; i + + )
{
pos = pItem - > apdu_unack [ i ] ;
pAPDU = & pItem - > apdu_i_buffer [ pos ] ;
if ( pAPDU - > NS < pItem - > apdu_ack | | pAPDU - > NS > nr )
{ //错误的I帧缓冲数据,主动断开链路
vLog ( LOG_ERROR , " Unit(%d) invalid I frame buffer. \n " , uid ) ;
return FALSE ;
}
if ( pAPDU - > NS = = nr ) break ;
}
if ( i > = pItem - > apdu_k )
{ //超出了可能的缓冲数量,缓冲区错误,主动断开链路
vLog ( LOG_ERROR , " Unit(%d) I frame buffer overflow. \n " , uid ) ;
return FALSE ;
}
//移动缓冲区内的数据
memcpy ( buffer , pItem - > apdu_unack , sizeof ( int ) * pItem - > apdu_k_max ) ;
memcpy ( pItem - > apdu_unack , & buffer [ i ] , sizeof ( int ) * ( pItem - > apdu_k_max - i ) ) ;
memcpy ( & pItem - > apdu_unack [ pItem - > apdu_k_max - i ] , buffer , sizeof ( int ) * i ) ;
pItem - > apdu_k - = i ;
if ( pItem - > apdu_k ! = 0 )
{ //更新t1计时
pAPDU = & pItem - > apdu_i_buffer [ pItem - > apdu_unack [ 0 ] ] ;
pItem - > apdu_t1_begin = ( DWORD ) pAPDU - > timer ;
vLog ( LOG_DEBUG , " Unit(%d) ack < NS, renew t1 timer to %lu. \n " , uid , pAPDU - > timer ) ;
}
pItem - > apdu_ack = nr ;
}
else if ( pItem - > apdu_ack > pItem - > apdu_ns )
{ //序列号出现环回的情况
if ( nr > pItem - > apdu_ns & & nr < pItem - > apdu_ack )
{ //I帧序列错误,主动断开链路
vLog ( LOG_ERROR , " Unit(%d) invalid I frame order(nr=%d,ack=%d,ns=%d). \n " , uid , nr , pItem - > apdu_ack , pItem - > apdu_ns ) ;
return FALSE ;
}
if ( nr = = pItem - > apdu_ack )
{ //无报文需要确认
vLog ( LOG_DEBUG , " Unit(%d) not ack order(nr=%d,ack=%d,ns=%d). \n " , uid , nr , pItem - > apdu_ack , pItem - > apdu_ns ) ;
return TRUE ;
}
//确认ACK至NR之间的缓冲报文
for ( i = 0 ; i < pItem - > apdu_k ; i + + )
{
pos = pItem - > apdu_unack [ i ] ;
pAPDU = & pItem - > apdu_i_buffer [ pos ] ;
if ( pAPDU - > NS > pItem - > apdu_ns & & pAPDU - > NS < pItem - > apdu_ack )
{ //错误的I帧缓冲数据,主动断开链路
vLog ( LOG_ERROR , " Unit(%d) invalid I frame buffer. \n " , uid ) ;
return FALSE ;
}
if ( pAPDU - > NS = = nr ) break ;
}
if ( i > = pItem - > apdu_k )
{ //超出了可能的缓冲数量,缓冲区错误,主动断开链路
vLog ( LOG_ERROR , " Unit(%d) I frame buffer overflow. \n " , uid ) ;
return FALSE ;
}
//移动缓冲区内的数据
memcpy ( buffer , pItem - > apdu_unack , sizeof ( int ) * pItem - > apdu_k_max ) ;
memcpy ( pItem - > apdu_unack , & buffer [ i ] , sizeof ( int ) * ( pItem - > apdu_k_max - i ) ) ;
memcpy ( & pItem - > apdu_unack [ pItem - > apdu_k_max - i ] , buffer , sizeof ( int ) * i ) ;
pItem - > apdu_k - = i ;
if ( pItem - > apdu_k ! = 0 )
{ //更新t1计时
pAPDU = & pItem - > apdu_i_buffer [ pItem - > apdu_unack [ 0 ] ] ;
pItem - > apdu_t1_begin = ( DWORD ) pAPDU - > timer ;
vLog ( LOG_DEBUG , " Unit(%d) ack > NS, renew t1 timer to %lu. \n " , uid , pAPDU - > timer ) ;
}
pItem - > apdu_ack = nr ;
}
return TRUE ;
}
BOOLEAN CIEC104Process : : OnDealWithPeerNS ( CIEC104ProcessItem * pItem , WORD ns )
{
int uid ;
if ( NULL = = pItem ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( ! use_ns_nr_check )
{
pItem - > apdu_nr + + ;
pItem - > apdu_nr & = 0x7fff ;
return TRUE ;
}
if ( ns ! = pItem - > apdu_nr )
{ //I帧数据产生丢失,主动断开链路
vLog ( LOG_ERROR , " Unit(%d) I frame lost (%d of %d). \n " , uid , pItem - > apdu_nr , ns ) ;
return FALSE ;
}
pItem - > apdu_nr + + ;
pItem - > apdu_nr & = 0x7fff ;
return TRUE ;
}
BOOLEAN CIEC104Process : : OnSFrameReceived ( WORD nr , int ord )
{
int uid ;
CIEC104ProcessItem * pItem = ( CIEC104ProcessItem * ) GetItem ( ord ) ;
if ( NULL = = pItem ) return FALSE ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
//重置t3计时
pItem - > apdu_t3_begin = system32 . timers ;
//assouan
vLog ( LOG_DEBUG , " Unit(%d) On S Frame Received nr = %d \n " , uid , ( int ) nr ) ;
return OnDealWithPeerNR ( pItem , nr ) ;
}
BOOLEAN CIEC104Process : : OnIFrameReceived ( WORD ns , WORD nr , BYTE * pBuf , int count , int ord )
{
return TRUE ;
}
BOOLEAN CIEC104Process : : OnUFrameReceived ( BOOLEAN STARTDT_ACT , BOOLEAN STARTDT_CON , BOOLEAN STOPDT_ACT , BOOLEAN STOPDT_CON , BOOLEAN TESTFR_ACT , BOOLEAN TESTFR_CON , int ord )
{
return TRUE ;
}
BOOLEAN CIEC104Process : : SendUFrame ( BOOLEAN STARTDT_ACT , BOOLEAN STARTDT_CON , BOOLEAN STOPDT_ACT , BOOLEAN STOPDT_CON , BOOLEAN TESTFR_ACT , BOOLEAN TESTFR_CON , int ord )
{
int uid ;
BYTE buffer [ 6 ] ;
CIEC104ProcessItem * pItem = ( CIEC104ProcessItem * ) GetItem ( ord ) ;
if ( NULL = = pItem ) return FALSE ;
uid = ( int ) pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
buffer [ 0 ] = 0x68 ;
buffer [ 1 ] = 0x04 ;
buffer [ 2 ] = 0x03 | ( STARTDT_ACT ? 0x04 : 0x00 ) | ( STARTDT_CON ? 0x08 : 0x00 ) |
( STOPDT_ACT ? 0x10 : 0x00 ) | ( STOPDT_CON ? 0x20 : 0x00 ) |
( TESTFR_ACT ? 0x40 : 0x00 ) | ( TESTFR_CON ? 0x80 : 0x00 ) ;
if ( ! WriteData ( buffer , 6 , ord ) )
{
vLog ( LOG_ERROR , " Unit(%d) Send U Frame Write Data Error. \n " , uid ) ;
return FALSE ;
}
DisplayTxData ( buffer , 6 , TRUE , uid ) ;
return TRUE ;
}
BOOLEAN CIEC104Process : : SendIFrame ( BYTE * pBuf , int len , int ord )
{
int uid ;
int pos ;
APDUBuffer * pAPDU ;
CIEC104ProcessItem * pItem = ( CIEC104ProcessItem * ) GetItem ( ord ) ;
if ( NULL = = pItem ) return FALSE ;
uid = ( int ) pItem - > GetUnitID ( ) ;
//是否达到k值(若达到k值则不应再发送)
if ( pItem - > apdu_k > = pItem - > apdu_k_max )
{
vLog ( LOG_WARN , " Unit(%d) reached k value of %d, blocked! \n " , uid , pItem - > apdu_k ) ;
return FALSE ;
}
//取得当前缓冲区位置
pos = pItem - > apdu_unack [ pItem - > apdu_k ] ;
pAPDU = & pItem - > apdu_i_buffer [ pos ] ;
pItem - > apdu_k + + ;
//组装I帧报文
pAPDU - > NS = pItem - > apdu_ns ;
memset ( pAPDU - > data , 0 , sizeof ( pAPDU - > data ) ) ;
pAPDU - > data [ 0 ] = 0x68 ;
pAPDU - > data [ 1 ] = ( len + 4 ) ;
pAPDU - > data [ 2 ] = ( BYTE ) ( ( pItem - > apdu_ns < < 1 ) & 0x00ff ) ;
pAPDU - > data [ 3 ] = ( BYTE ) ( ( ( pItem - > apdu_ns < < 1 ) > > 8 ) & 0x00ff ) ;
pAPDU - > data [ 4 ] = ( BYTE ) ( ( pItem - > apdu_nr < < 1 ) & 0x00ff ) ;
pAPDU - > data [ 5 ] = ( BYTE ) ( ( ( pItem - > apdu_nr < < 1 ) > > 8 ) & 0x00ff ) ;
memcpy ( & pAPDU - > data [ 6 ] , pBuf , len ) ;
pAPDU - > length = len + 6 ;
int sent = WriteData ( pAPDU - > data , len + 6 , ord ) ;
if ( sent < = 0 )
{
vLog ( LOG_ERROR , " Unit(%d) Send I Frame Write Data Error. \n " , uid ) ;
return FALSE ;
}
DisplayTxData ( pAPDU - > data , len + 6 , TRUE , uid ) ;
pAPDU - > timer = system32 . timers ;
//清除t2计时
pItem - > apdu_t2_begin = 0 ;
pItem - > apdu_w = 0 ;
//启动t1计时
if ( pItem - > apdu_t1_begin = = 0 )
{
pItem - > apdu_t1_begin = ( DWORD ) pAPDU - > timer ;
}
pItem - > apdu_ns + + ; pItem - > apdu_ns & = 0x7fff ;
return TRUE ;
}
BOOLEAN CIEC104Process : : SendSFrame ( int ord )
{
int uid ;
BYTE buffer [ 6 ] ;
CIEC104ProcessItem * pItem = ( CIEC104ProcessItem * ) GetItem ( ord ) ;
if ( NULL = = pItem ) return FALSE ;
uid = ( int ) pItem - > GetUnitID ( ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
buffer [ 0 ] = 0x68 ;
buffer [ 1 ] = 0x04 ;
buffer [ 2 ] = 0x01 ;
buffer [ 3 ] = 0x00 ;
buffer [ 4 ] = ( BYTE ) ( ( pItem - > apdu_nr < < 1 ) & 0x00ff ) ;
buffer [ 5 ] = ( BYTE ) ( ( ( pItem - > apdu_nr < < 1 ) > > 8 ) & 0x00ff ) ;
if ( ! WriteData ( buffer , 6 , ord ) )
{
vLog ( LOG_ERROR , " Unit(%d) Send S Frame Write Data Error. \n " , uid ) ;
return FALSE ;
}
DisplayTxData ( buffer , 6 , TRUE , uid ) ;
//清除t2计时
pItem - > apdu_t2_begin = 0 ;
pItem - > apdu_w = 0 ;
return TRUE ;
}
//host begin
BOOLEAN CIEC104Process : : OnReceiveSingle_point_information ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //单点遥信
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_BACK = = ( cot & 0x3f ) | | IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | |
IEC_101_104_COT_REQ = = ( cot & 0x3f ) | | IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) | | IEC_101_104_COT_INTERROGATION = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO1 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO2 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO3 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO4 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO5 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO6 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO7 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO8 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO9 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO10 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO11 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO12 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO13 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO14 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO15 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO16 = = ( cot & 0x3f ) | |
IEC_101_104_COT_PER_CYC = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
DWORD i ;
DWORD information_address ;
BOOLEAN value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
if ( sq ) //顺序寻址
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
for ( i = 0 ; i < num ; i + + , information_address + + )
{
value = ( * pData & 0x01 ) = = 0x01 ? TRUE : FALSE ;
qds = ( * pData & 0xf0 ) ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYXPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYX ( uid , point , value , FALSE , qds ) ;
}
}
}
else //单一寻址自动生成YXBW信号
{
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = ( * pData & 0x01 ) = = 0x01 ? TRUE : FALSE ;
qds = ( * pData & 0xf0 ) ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYXPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYX ( uid , point , value , TRUE , qds ) ;
}
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveSingle_point_information_with_time_tag ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带时标的单点遥信
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | | IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
BOOLEAN value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = ( * pData & 0x01 ) = = 0x01 ? TRUE : FALSE ;
qds = ( * pData & 0xf0 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYXPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYX ( uid , point , value , TRUE , qds ) ;
SetUnitSOE ( uid , point , value , st ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveDouble_point_information ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //双点遥信
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_BACK = = ( cot & 0x3f ) | | IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | |
IEC_101_104_COT_REQ = = ( cot & 0x3f ) | | IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) | | IEC_101_104_COT_INTERROGATION = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO1 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO2 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO3 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO4 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO5 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO6 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO7 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO8 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO9 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO10 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO11 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO12 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO13 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO14 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO15 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO16 = = ( cot & 0x3f ) | |
IEC_101_104_COT_PER_CYC = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
DWORD i ;
DWORD information_address ;
BOOLEAN value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
if ( sq ) //顺序寻址
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
for ( i = 0 ; i < num ; i + + , information_address + + )
{
value = ( * pData & 0x03 ) = = 0x02 ? TRUE : FALSE ;
qds = ( * pData & 0xf0 ) ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYXPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYX ( uid , point , value , FALSE , qds ) ;
}
}
}
else //单一寻址自动生成YXBW信号
{
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = ( * pData & 0x03 ) = = 0x02 ? TRUE : FALSE ;
qds = ( * pData & 0xf0 ) ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYXPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYX ( uid , point , value , TRUE , qds ) ;
}
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveDouble_point_information_with_time_tag ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带时标的双点遥信
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | | IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
BOOLEAN value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = ( * pData & 0x03 ) = = 0x02 ? TRUE : FALSE ;
qds = ( * pData & 0xf0 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYXPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYX ( uid , point , value , TRUE , qds ) ;
SetUnitSOE ( uid , point , value , st ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_normalised ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //测量值,归一化值
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_PER_CYC = = ( cot & 0x3f ) | | IEC_101_104_COT_BACK = = ( cot & 0x3f ) | |
IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | | IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) | |
IEC_101_104_COT_INTERROGATION = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO1 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO2 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO3 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO4 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO5 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO6 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO7 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO8 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO9 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO10 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO11 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO12 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO13 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO14 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO15 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO16 = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
DWORD i ;
DWORD information_address ;
short value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
if ( sq ) //顺序寻址
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
for ( i = 0 ; i < num ; i + + , information_address + + )
{
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = ( * pData & 0xf1 ) ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
}
else //单一寻址
{
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = ( * pData & 0xf1 ) ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_normalised_with_time_tag ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带时标的遥测量,归一化值
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
short value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = ( * pData & 0xf1 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_scaled ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //测量值,标度化值
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_PER_CYC = = ( cot & 0x3f ) | | IEC_101_104_COT_BACK = = ( cot & 0x3f ) | |
IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | | IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) | |
IEC_101_104_COT_INTERROGATION = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO1 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO2 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO3 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO4 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO5 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO6 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO7 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO8 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO9 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO10 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO11 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO12 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO13 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO14 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO15 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO16 = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
DWORD i ;
DWORD information_address ;
short value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
if ( sq ) //顺序寻址
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
for ( i = 0 ; i < num ; i + + , information_address + + )
{
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = ( * pData & 0xf1 ) ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
}
else //单一寻址
{
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = ( * pData & 0xf1 ) ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_scaled_with_time_tag ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带时标的遥测量,标度化值
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
short value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = ( * pData & 0xf1 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_short_floating_point ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //测量值,短浮点数
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_PER_CYC = = ( cot & 0x3f ) | | IEC_101_104_COT_BACK = = ( cot & 0x3f ) | |
IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | | IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) | |
IEC_101_104_COT_INTERROGATION = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO1 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO2 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO3 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO4 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO5 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO6 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO7 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO8 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO9 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO10 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO11 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO12 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO13 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO14 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO15 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO16 = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
DWORD i ;
DWORD information_address ;
DWORD dwValue ;
float fValue ;
BYTE qds ;
BYTE ioa [ 4 ] ;
if ( sq ) //顺序寻址
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
for ( i = 0 ; i < num ; i + + , information_address + + )
{
dwValue = ( DWORD ) ( ( pData [ 3 ] < < 24 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 1 ] < < 8 ) | pData [ 0 ] ) ;
pData + = 4 ;
memcpy ( & fValue , & dwValue , sizeof ( DWORD ) ) ;
qds = ( * pData & 0xf1 ) ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , fValue , qds ) ;
}
}
}
else //单一寻址
{
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
dwValue = ( DWORD ) ( ( pData [ 3 ] < < 24 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 1 ] < < 8 ) | pData [ 0 ] ) ;
pData + = 4 ;
memcpy ( & fValue , & dwValue , sizeof ( DWORD ) ) ;
qds = ( * pData & 0xf1 ) ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , fValue , qds ) ;
}
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_short_floating_point_with_time_tag ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带时标的遥测量值,短浮点数
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
DWORD dwValue ;
float fValue ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
dwValue = ( DWORD ) ( ( pData [ 3 ] < < 24 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 1 ] < < 8 ) | pData [ 0 ] ) ;
pData + = 4 ;
memcpy ( & fValue , & dwValue , sizeof ( DWORD ) ) ;
qds = ( * pData & 0xf1 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , fValue , qds ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_normalised_without_quality ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //测量值,不带品质描述的归一化测量值
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_PER_CYC = = ( cot & 0x3f ) | | IEC_101_104_COT_BACK = = ( cot & 0x3f ) | |
IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | | IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) | |
IEC_101_104_COT_INTERROGATION = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO1 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO2 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO3 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO4 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO5 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO6 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO7 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO8 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO9 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO10 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO11 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO12 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO13 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO14 = = ( cot & 0x3f ) | | IEC_101_104_COT_INRO15 = = ( cot & 0x3f ) | |
IEC_101_104_COT_INRO16 = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
DWORD i ;
DWORD information_address ;
short value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
if ( sq ) //顺序寻址
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
for ( i = 0 ; i < num ; i + + , information_address + + )
{
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = 0x00 ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
}
else //单一寻址
{
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = 0x00 ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveSingle_point_information_with_time_tag_cp56time2a ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带CP56Time2a时标的单点信息
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | | IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
BOOLEAN value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = ( * pData & 0x01 ) = = 0x01 ? TRUE : FALSE ;
qds = ( * pData & 0xf0 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . hour = * pData & 0x1f ;
st . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . dayofmonth = * pData & 0x1f ;
st . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
st . month = * pData & 0x0f ; pData + + ;
st . year = * pData & 0x7f ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYXPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYX ( uid , point , value , TRUE , qds ) ;
SetUnitSOE ( uid , point , value , st ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveDouble_point_information_with_time_tag_cp56time2a ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带CP56Time2a时标的双点信息
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) | |
IEC_101_104_COT_RETREM = = ( cot & 0x3f ) | | IEC_101_104_COT_RETLOC = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
BOOLEAN value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = ( * pData & 0x03 ) = = 0x02 ? TRUE : FALSE ;
qds = ( * pData & 0xf0 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . hour = * pData & 0x1f ;
st . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . dayofmonth = * pData & 0x1f ;
st . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
st . month = * pData & 0x0f ; pData + + ;
st . year = * pData & 0x7f ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYXPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYX ( uid , point , value , TRUE , qds ) ;
SetUnitSOE ( uid , point , value , st ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_normalised_with_time_tag_cp56time2a ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带CP56Time2a时标的遥测量值, 归一化值
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
short value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = ( * pData & 0xf1 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . hour = * pData & 0x1f ;
st . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . dayofmonth = * pData & 0x1f ;
st . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
st . month = * pData & 0x0f ; pData + + ;
st . year = * pData & 0x7f ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_scaled_with_time_tag_cp56time2a ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带CP56Time2a时标的遥测量值, 标度化值
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
short value ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
qds = ( * pData & 0xf1 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . hour = * pData & 0x1f ;
st . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . dayofmonth = * pData & 0x1f ;
st . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
st . month = * pData & 0x0f ; pData + + ;
st . year = * pData & 0x7f ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , ( LONG ) value , qds ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveMeasured_value_short_floating_point_with_time_tag_cp56time2a ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //带CP56Time2a时标的遥测量值, 短浮点数
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQ = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
DWORD i ;
DWORD information_address ;
DWORD dwValue ;
float fValue ;
BYTE qds ;
BYTE ioa [ 4 ] ;
unionCP56Time st ;
memcpy ( & st , & system32 . now , sizeof ( st ) ) ;
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
dwValue = ( DWORD ) ( ( pData [ 3 ] < < 24 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 1 ] < < 8 ) | pData [ 0 ] ) ;
pData + = 4 ;
memcpy ( & fValue , & dwValue , sizeof ( DWORD ) ) ;
qds = ( * pData & 0xf1 ) ; pData + + ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . hour = * pData & 0x1f ;
st . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . dayofmonth = * pData & 0x1f ;
st . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
st . month = * pData & 0x0f ; pData + + ;
st . year = * pData & 0x7f ; pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYCPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYC ( uid , point , fValue , qds ) ;
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveIntegrated_totals ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //累积量
{
BYTE * pData = pBuf ;
int point ;
if ( IEC_101_104_COT_SPONT = = ( cot & 0x3f ) | | IEC_101_104_COT_REQCOGEN = = ( cot & 0x3f ) | |
IEC_101_104_COT_REQCO1 = = ( cot & 0x3f ) | | IEC_101_104_COT_REQCO2 = = ( cot & 0x3f ) | |
IEC_101_104_COT_REQCO3 = = ( cot & 0x3f ) | | IEC_101_104_COT_REQCO4 = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
int i ;
DWORD information_address ;
DWORD value ;
// BYTE sn;
BYTE ioa [ 4 ] ;
if ( sq ) //顺序寻址
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
for ( i = 0 ; i < num ; i + + , information_address + + )
{
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
value | = ( * pData < < 16 ) ; pData + + ;
value | = ( * pData < < 24 ) ; pData + + ;
//sn = *pData;
pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYMPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYM ( uid , point , value ) ;
}
}
}
else //单一寻址
{
for ( i = 0 ; i < num ; i + + )
{
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
value | = ( * pData < < 16 ) ; pData + + ;
value | = ( * pData < < 24 ) ; pData + + ;
//sn = *pData;
pData + + ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYMPointByParam ( uid , ioa , 4 ) ;
if ( point > = 0 )
{
SetUnitYM ( uid , point , value ) ;
}
}
}
return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveInterrogation_command ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //总召唤
{
BYTE * pData = pBuf ;
DWORD information_address ;
BYTE QOI ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) | | IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) | |
IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_TI = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_COT = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_ASDU = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_INFO = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
if ( num ! = 1 ) return FALSE ;
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
if ( information_address ! = 0 ) return FALSE ;
QOI = * pData ; pData + + ;
if ( QOI < 20 | | QOI > 36 )
{
return FALSE ;
}
if ( IEC_101_104_COT_ACT = = ( cot & 0x3f ) )
{
return FALSE ;
}
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{
return TRUE ;
}
if ( IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) )
{ //激活终止
//总召唤结束
pItem - > interrogation_finish = TRUE ;
return TRUE ;
}
if ( IEC_101_104_COT_DEACT = = ( cot & 0x3f ) )
{
return FALSE ;
}
if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{
return TRUE ;
}
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveClock_synchronisation_command ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //时钟同步
{
BYTE * pData = pBuf ;
DWORD information_address ;
unionCP56Time st ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) | | IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_TI = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_COT = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_ASDU = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_INFO = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
if ( num ! = 1 ) return FALSE ;
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
if ( information_address ! = 0 ) return FALSE ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . hour = * pData & 0x1f ;
st . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . dayofmonth = * pData & 0x1f ;
st . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
st . month = * pData & 0x0f ; pData + + ;
st . year = * pData & 0x7f ; pData + + ;
if ( ( cot & 0x3f ) = = IEC_101_104_COT_ACTCON )
{
pItem - > clock_synchronized_finish = TRUE ;
return TRUE ;
}
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveCounter_Interrogation_command ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //召唤电度量
{
BYTE * pData = pBuf ;
DWORD information_address ;
BYTE QCC ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) | | IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) | |
IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_TI = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_COT = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_ASDU = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_INFO = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址 never happend;
if ( num ! = 1 ) return FALSE ;
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
if ( information_address ! = 0 ) return FALSE ;
QCC = * pData ; pData + + ;
if ( ( QCC & 0x3f ) < 1 | | ( QCC & 0x3f ) > 5 ) return FALSE ;
if ( IEC_101_104_COT_ACT = = ( cot & 0x3f ) ) return FALSE ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) ) return TRUE ;
//激活终止
//召唤电度结束
if ( IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) ) return TRUE ;
if ( IEC_101_104_COT_DEACT = = ( cot & 0x3f ) ) return FALSE ;
if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) ) return TRUE ;
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveSingle_command ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //单点遥控
{
BYTE * pData = pBuf ;
BYTE SE , value ;
int point ;
DWORD information_address ;
BYTE ioa [ 4 ] ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) | | IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) | |
IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_TI = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_COT = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_ASDU = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_INFO = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
if ( num ! = 1 ) return FALSE ;
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYKPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
vLog ( LOG_WARN , " Unit(%d) information address error. \n " , uid ) ;
return FALSE ;
}
SE = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ;
value = ( * pData & 0x01 ) = = 0x01 ? TRUE : FALSE ;
BYTE * pYKParam = GetUnitYKParamByPoint ( uid , point ) ;
if ( pYKParam = = NULL ) return FALSE ;
switch ( pYKParam [ 5 ] )
{
case 1 : //单触点合圈
if ( value ! = TRUE ) return FALSE ;
break ;
case 2 : //单触点分圈
if ( value ! = FALSE ) return FALSE ;
break ;
}
value = pItem - > yk_value ;
if ( SE )
{ //遥控选择
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
SetUnitYK ( uid , point , value , YKS_SELED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYK ( uid , point , value , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
return FALSE ;
}
else
{ //遥控执行
if ( IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) )
{ //激活终止
SetUnitYK ( uid , point , value , YKS_EXEED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_EXEED result is YKR_SUCC. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYK ( uid , point , value , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s ACTCON. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
return FALSE ;
}
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveDouble_command ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //双点遥控
{
BYTE * pData = pBuf ;
BYTE SE , value ;
int point ;
DWORD information_address ;
BYTE ioa [ 4 ] ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) | | IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) | |
IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_TI = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_COT = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_ASDU = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_INFO = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
if ( num ! = 1 ) return FALSE ;
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYKPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
vLog ( LOG_WARN , " Unit(%d) information address error. \n " , uid ) ;
return FALSE ;
}
SE = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ;
value = ( * pData & 0x03 ) = = 0x02 ? TRUE : FALSE ;
BYTE * pYKParam = GetUnitYKParamByPoint ( uid , point ) ;
if ( pYKParam = = NULL ) return FALSE ;
switch ( pYKParam [ 5 ] )
{
case 1 : //单触点合圈
if ( value ! = TRUE ) return FALSE ;
break ;
case 2 : //单触点分圈
if ( value ! = FALSE ) return FALSE ;
break ;
}
value = pItem - > yk_value ;
if ( SE )
{ //遥控选择
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
SetUnitYK ( uid , point , value , YKS_SELED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELED result is YKR_SUCC. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYK ( uid , point , value , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
return FALSE ;
}
else
{ //遥控执行
if ( IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) )
{ //激活终止
SetUnitYK ( uid , point , value , YKS_EXEED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_EXEED result is YKR_SUCC. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYK ( uid , point , value , YKS_ABRED , YKR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRED result is YKR_SUCC. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s ACTCON. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return TRUE ;
}
return FALSE ;
}
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveSet_point_command_normalized ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //设定归一化值命令
{
BYTE * pData = pBuf ;
BYTE SE ;
WORD value ;
int point ;
DWORD information_address ;
BYTE ioa [ 4 ] ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) | | IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) | |
IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_TI = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_COT = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_ASDU = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_INFO = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
if ( num ! = 1 ) return FALSE ;
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
vLog ( LOG_WARN , " Unit(%d) information address error. \n " , uid ) ;
return FALSE ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
SE = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
if ( SE )
{ //遥控选择
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
SetUnitYT ( uid , point , value , YTS_SELED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYT ( uid , point , value , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
return FALSE ;
}
else
{ //遥控执行
if ( IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_EXEED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_EXEED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYT ( uid , point , value , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d ACTCON. \n " , uid , point , value ) ;
return TRUE ;
}
return FALSE ;
}
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveSet_point_command_scaled ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //设定标度化值命令
{
BYTE * pData = pBuf ;
BYTE SE ;
WORD value ;
int point ;
DWORD information_address ;
BYTE ioa [ 4 ] ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) | | IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) | |
IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_TI = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_COT = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_ASDU = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_INFO = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
if ( num ! = 1 ) return FALSE ;
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
vLog ( LOG_WARN , " Unit(%d) information address error. \n " , uid ) ;
return FALSE ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
SE = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
if ( SE )
{ //遥控选择
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
SetUnitYT ( uid , point , value , YTS_SELED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYT ( uid , point , value , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
return FALSE ;
}
else
{ //遥控执行
if ( IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_EXEED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_EXEED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYT ( uid , point , value , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d ACTCON. \n " , uid , point , value ) ;
return TRUE ;
}
return FALSE ;
}
}
return FALSE ;
}
BOOLEAN CIEC104Process : : OnReceiveSet_point_command_short_floating ( CIEC104ProcessItem * pItem , int uid , BYTE * pBuf , BOOLEAN sq , BOOLEAN pn , BOOLEAN test , BYTE num , WORD cot ) //设定短浮点值命令
{
BYTE * pData = pBuf ;
BYTE SE ;
DWORD value ;
int point ;
DWORD information_address ;
BYTE ioa [ 4 ] ;
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) | | IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) | |
IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_TI = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_COT = = ( cot & 0x3f ) | | IEC_101_104_COT_UNKNOWN_ASDU = = ( cot & 0x3f ) | |
IEC_101_104_COT_UNKNOWN_INFO = = ( cot & 0x3f ) )
{
if ( pn ) return FALSE ; //否定
if ( test ) return FALSE ; //试验
if ( sq ) return FALSE ; //顺序寻址
if ( num ! = 1 ) return FALSE ;
information_address = 0 ;
if ( 1 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address = * pData ; pData + + ;
information_address | = ( * pData < < 8 ) ; pData + + ;
information_address | = ( * pData < < 16 ) ; pData + + ;
}
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
vLog ( LOG_WARN , " Unit(%d) information address error. \n " , uid ) ;
return FALSE ;
}
value = * pData ; pData + + ;
value | = ( * pData < < 8 ) ; pData + + ;
value | = ( * pData < < 16 ) ; pData + + ;
value | = ( * pData < < 24 ) ; pData + + ;
SE = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
if ( SE )
{ //遥控选择
if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
SetUnitYT ( uid , point , value , YTS_SELED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_SELED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYT ( uid , point , value , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
return FALSE ;
}
else
{ //遥控执行
if ( IEC_101_104_COT_ACTTREM = = ( cot & 0x3f ) )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_EXEED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_EXEED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_DEACTCON = = ( cot & 0x3f ) )
{ //停止激活确认
SetUnitYT ( uid , point , value , YTS_ABRED , YTR_SUCC ) ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is YTS_ABRED result is YTR_SUCC. \n " , uid , point , value ) ;
return TRUE ;
}
else if ( IEC_101_104_COT_ACTCON = = ( cot & 0x3f ) )
{ //激活确认
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d ACTCON. \n " , uid , point , value ) ;
return TRUE ;
}
return FALSE ;
}
}
return FALSE ;
}
BOOLEAN CIEC104Process : : SendInterrogation_command ( CIEC104ProcessItem * pItem , int ord ) //总召唤
{
DWORD len ;
BYTE buffer [ 64 ] ;
len = 0 ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
buffer [ len + + ] = C_IC_NA_1 ;
buffer [ len + + ] = 0x01 ;
//传输原因
if ( 1 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( IEC_101_104_COT_ACT & 0xff ) ;
}
else if ( 2 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( IEC_101_104_COT_ACT & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( IEC_101_104_COT_ACT > > 8 ) & 0x00ff ) ;
}
//应用地址
if ( 1 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0xff ) ;
}
else if ( 2 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( pItem - > apdu_addr > > 8 ) & 0x00ff ) ;
}
//信息体地址
if ( 1 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
}
buffer [ len + + ] = 0x14 ; //QOI总召唤
return SendIFrame ( buffer , len , ord ) ;
}
BOOLEAN CIEC104Process : : SendClock_synchronisation_command ( CIEC104ProcessItem * pItem , int ord ) //时钟同步
{
DWORD len ;
BYTE buffer [ 64 ] ;
len = 0 ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
buffer [ len + + ] = C_CS_NA_1 ;
buffer [ len + + ] = 0x01 ;
//传输原因
if ( 1 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( IEC_101_104_COT_ACT & 0xff ) ;
}
else if ( 2 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( IEC_101_104_COT_ACT & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( IEC_101_104_COT_ACT > > 8 ) & 0x00ff ) ;
}
//应用地址
if ( 1 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0xff ) ;
}
else if ( 2 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( pItem - > apdu_addr > > 8 ) & 0x00ff ) ;
}
//信息体地址
if ( 1 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
}
unionCP56Time st ;
if ( ! get_system_time ( & st ) )
{
vLog ( LOG_ERROR , " Get system time error. \n " ) ;
return FALSE ;
}
if ( ( st . millisecond % 1000 ) > 900 )
{
return FALSE ;
}
st . IV = FALSE ;
st . SU = FALSE ;
buffer [ len + + ] = ( BYTE ) ( st . millisecond & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( st . millisecond > > 8 ) & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( st . minute | ( st . IV < < 7 ) ) ;
buffer [ len + + ] = ( BYTE ) ( st . hour | ( st . SU < < 7 ) ) ;
buffer [ len + + ] = ( BYTE ) ( st . dayofmonth | ( st . dayofweek < < 5 ) ) ;
buffer [ len + + ] = ( BYTE ) st . month ;
buffer [ len + + ] = ( BYTE ) st . year ;
return SendIFrame ( buffer , len , ord ) ;
}
BOOLEAN CIEC104Process : : SendCounter_Interrogation_command ( CIEC104ProcessItem * pItem , int ord ) //召唤电度量
{
DWORD len ;
BYTE buffer [ 64 ] ;
len = 0 ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
buffer [ len + + ] = C_CI_NA_1 ;
buffer [ len + + ] = 0x01 ;
//传输原因
if ( 1 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( IEC_101_104_COT_ACT & 0xff ) ;
}
else if ( 2 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( IEC_101_104_COT_ACT & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( IEC_101_104_COT_ACT > > 8 ) & 0x00ff ) ;
}
//应用地址
if ( 1 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0xff ) ;
}
else if ( 2 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( pItem - > apdu_addr > > 8 ) & 0x00ff ) ;
}
//信息体地址
if ( 1 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
buffer [ len + + ] = 0 ;
}
buffer [ len + + ] = 5 ; //QCC总召唤
return SendIFrame ( buffer , len , ord ) ;
}
BOOLEAN CIEC104Process : : GetYKFrame ( CIEC104ProcessItem * pItem , int ord )
{
int uid , order , len ;
DWORD information_address ;
BYTE value , state , result , command , yk_type , relay_type , QU ;
WORD cause_of_transmission = 0 ;
BYTE buffer [ 64 ] ;
if ( NULL = = pItem ) return FALSE ;
command = 0 ;
len = 0 ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( ! GetUnitYK ( uid , order , value , state , result ) ) return FALSE ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is %s result is %s. \n " , uid , order , ( value ? " CLOSE " : " TRIP " ) , val_to_str ( state , yk_state , " STATE= %d " ) , val_to_str ( result , yk_result , " RESULT= %d " ) ) ;
//获取遥控信息体地址
BYTE * pParam = GetUnitYKParamByPoint ( uid , order ) ;
if ( NULL = = pParam ) return FALSE ;
pItem - > yk_value = value ;
information_address = MAKEDWORD ( MAKEWORD ( pParam [ 0 ] , pParam [ 1 ] ) , MAKEWORD ( pParam [ 2 ] , pParam [ 3 ] ) ) ;
yk_type = pParam [ 4 ] ;
relay_type = pParam [ 5 ] ;
QU = pParam [ 6 ] ;
QU < < = 2 ; QU & = 0x7c ;
if ( yk_type = = USE_YK_DC | | yk_type = = USE_YK_DEF )
{ //双点遥控
command = ( value = = TRUE ) ? DCO_ON : DCO_OFF ;
buffer [ len + + ] = C_DC_NA_1 ;
}
else if ( yk_type = = USE_YK_SC )
{
switch ( relay_type )
{
case 1 : //单触点合圈
command = TRUE ;
break ;
case 2 : //单触点分圈
command = FALSE ;
break ;
default : //双触点线圈
command = value ;
break ;
}
buffer [ len + + ] = C_SC_NA_1 ;
}
if ( YKS_SELREQ = = state )
{
cause_of_transmission = IEC_101_104_COT_ACT ;
command | = 0x80 ;
}
else if ( YKS_EXEREQ = = state )
{
cause_of_transmission = IEC_101_104_COT_ACT ;
}
else if ( ( YKS_ABRREQ = = state ) | | ( ( YKS_SELING = = state | | YKS_SELED = = state ) & & YKR_OVER = = result ) )
{
cause_of_transmission = IEC_101_104_COT_DEACT ;
command | = 0x80 ;
}
buffer [ len + + ] = 0x01 ;
//传输原因
if ( 1 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( cause_of_transmission & 0xff ) ;
}
else if ( 2 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( cause_of_transmission & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( cause_of_transmission > > 8 ) & 0x00ff ) ;
}
//应用地址
if ( 1 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0xff ) ;
}
else if ( 2 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( pItem - > apdu_addr > > 8 ) & 0x00ff ) ;
}
//信息体地址
if ( 1 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( information_address & 0xff ) ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( information_address & 0xff ) ;
buffer [ len + + ] = ( BYTE ) ( ( information_address > > 8 ) & 0xff ) ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( information_address & 0xff ) ;
buffer [ len + + ] = ( BYTE ) ( ( information_address > > 8 ) & 0xff ) ;
buffer [ len + + ] = ( BYTE ) ( ( information_address > > 16 ) & 0xff ) ;
}
buffer [ len + + ] = ( command | QU ) ;
return SendIFrame ( buffer , len , ord ) ;
}
BOOLEAN CIEC104Process : : GetYTFrame ( CIEC104ProcessItem * pItem , int ord )
{
int uid , order , len , data_length ;
DWORD information_address , value ;
BYTE state , result , yt_type ;
BYTE command = 0 ;
WORD cause_of_transmission = 0 ;
BYTE buffer [ 64 ] ;
if ( NULL = = pItem ) return FALSE ;
data_length = 2 ;
len = 0 ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
uid = pItem - > GetUnitID ( ) ;
if ( uid < 0 | | uid > = UNIT_NUM ) return FALSE ;
if ( ! GetUnitYT ( uid , order , value , state , result ) ) return FALSE ;
vLog ( LOG_WARN , " Unit(%d) set point(%d) %d state is %s result is %s. \n " , uid , order , value , val_to_str ( state , yt_state , " STATE= %d " ) , val_to_str ( result , yt_result , " RESULT= %d " ) ) ;
//获取遥调信息体地址
BYTE * pParam = GetUnitYTParamByPoint ( uid , order ) ;
if ( NULL = = pParam ) return FALSE ;
information_address = MAKEDWORD ( MAKEWORD ( pParam [ 0 ] , pParam [ 1 ] ) , MAKEWORD ( pParam [ 2 ] , pParam [ 3 ] ) ) ;
yt_type = pParam [ 4 ] ;
if ( yt_type = = USE_YT_NA )
{
data_length = 2 ;
buffer [ len + + ] = C_SE_NA_1 ;
}
else if ( yt_type = = USE_YT_NB )
{
data_length = 2 ;
buffer [ len + + ] = C_SE_NB_1 ;
}
else if ( yt_type = = USE_YT_NC )
{
data_length = 4 ;
buffer [ len + + ] = C_SE_NC_1 ;
}
else
{
vLog ( LOG_WARN , " Unit(%d) set point(%d) type(%d) error. \n " , uid , order , yt_type ) ;
return FALSE ;
}
if ( YTS_SELREQ = = state )
{
cause_of_transmission = IEC_101_104_COT_ACT ;
command | = IEC_101_104_SE ;
}
else if ( YTS_EXEREQ = = state )
{
cause_of_transmission = IEC_101_104_COT_ACT ;
command = 0 ;
}
else if ( ( YTS_ABRREQ = = state ) | | ( ( YTS_SELING = = state | | YTS_SELED = = state ) & & YTR_OVER = = result ) )
{
cause_of_transmission = IEC_101_104_COT_DEACT ;
command = 0 ;
}
buffer [ len + + ] = 0x01 ;
//传输原因
if ( 1 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( cause_of_transmission & 0xff ) ;
}
else if ( 2 = = m_nOption . cot_size )
{
buffer [ len + + ] = ( BYTE ) ( cause_of_transmission & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( cause_of_transmission > > 8 ) & 0x00ff ) ;
}
//应用地址
if ( 1 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0xff ) ;
}
else if ( 2 = = m_nOption . asdu_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( pItem - > apdu_addr & 0x00ff ) ;
buffer [ len + + ] = ( BYTE ) ( ( pItem - > apdu_addr > > 8 ) & 0x00ff ) ;
}
//信息体地址
if ( 1 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( information_address & 0xff ) ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( information_address & 0xff ) ;
buffer [ len + + ] = ( BYTE ) ( ( information_address > > 8 ) & 0xff ) ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
buffer [ len + + ] = ( BYTE ) ( information_address & 0xff ) ;
buffer [ len + + ] = ( BYTE ) ( ( information_address > > 8 ) & 0xff ) ;
buffer [ len + + ] = ( BYTE ) ( ( information_address > > 16 ) & 0xff ) ;
}
if ( data_length = = 2 )
{
buffer [ len + + ] = value & 0xff ;
buffer [ len + + ] = ( value > > 8 ) & 0xff ;
}
else if ( data_length = = 4 )
{
buffer [ len + + ] = value & 0xff ;
buffer [ len + + ] = ( value > > 8 ) & 0xff ;
buffer [ len + + ] = ( value > > 16 ) & 0xff ;
buffer [ len + + ] = ( value > > 24 ) & 0xff ;
}
buffer [ len + + ] = command ;
return SendIFrame ( buffer , len , ord ) ;
}
//host end
//sub begin
int CIEC104Process : : MakeYKFrame ( CIEC104ProcessItem * pItem , int ord )
{
BYTE buffer [ 32 ] ;
if ( NULL = = pItem ) return - 1 ;
int order ;
BYTE value , action , result ;
if ( ! GetUnitYK ( pItem - > GetUnitID ( ) , order , value , action , result ) )
{
return 0 ;
}
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is %s result is %s \n " , pItem - > GetUnitID ( ) , order , ( value ? " CLOSE " : " TRIP " ) , val_to_str ( action , yk_state , " STATE=%d " ) , val_to_str ( result , yk_result , " RESULT=%d " ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( YKS_SELED = = action & & YKR_FAIL = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = IEC_101_104_SE ;
action = YKS_ABRED ;
}
else if ( YKS_SELREQ = = action & & YKR_OVER = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = IEC_101_104_SE ;
action = YKS_ABRED ;
}
else if ( YKS_SELING = = action & & YKR_OVER = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = IEC_101_104_SE ;
action = YKS_ABRED ;
}
BYTE * param ;
BOOLEAN yk_type ;
//BYTE relay_type;
DWORD ioa ;
param = GetUnitYKParamByPoint ( pItem - > GetUnitID ( ) , order ) ;
ioa = MAKEDWORD ( MAKEWORD ( param [ 0 ] , param [ 1 ] ) , MAKEWORD ( param [ 2 ] , param [ 3 ] ) ) ;
yk_type = param [ 4 ] ;
//relay_type = param[5];
if ( yk_type = = USE_YK_DC | | yk_type = = USE_YK_DEF )
{ //双点遥控
buffer [ 0 ] = C_DC_NA_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = value ? DCO_ON : DCO_OFF ;
}
else
{
buffer [ 0 ] = C_SC_NA_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = value ? SCO_ON : SCO_OFF ;
}
buffer [ 1 ] = 1 ;
if ( YKS_SELED = = action )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] | = IEC_101_104_SE ;
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_ACTCON ) ;
}
else if ( YKS_ABRED = = action )
{
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
}
else if ( YKS_EXEED = = action )
{
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_ACTTREM ) ;
}
else
{
return 0 ;
}
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ioa ) ;
if ( ! SendIFrame ( buffer , ( 3 + cot_length + asdu_addr_length + info_addr_length ) , ord ) ) return - 1 ;
return 1 ;
}
int CIEC104Process : : MakeYTFrame ( CIEC104ProcessItem * pItem , int ord )
{
BYTE buffer [ 32 ] ;
if ( NULL = = pItem ) return - 1 ;
int order ;
BYTE action , result ;
DWORD value ;
if ( ! GetUnitYT ( pItem - > GetUnitID ( ) , order , value , action , result ) )
{
return 0 ;
}
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is %s result is %s \n " , pItem - > GetUnitID ( ) , order , value , val_to_str ( action , yt_state , " STATE=%d " ) , val_to_str ( result , yt_result , " RESULT=%d " ) ) ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
BYTE * param ;
BOOLEAN yt_type ;
DWORD ioa ;
int data_length = 2 ;
param = GetUnitYTParamByPoint ( pItem - > GetUnitID ( ) , order ) ;
ioa = MAKEDWORD ( MAKEWORD ( param [ 0 ] , param [ 1 ] ) , MAKEWORD ( param [ 2 ] , param [ 3 ] ) ) ;
yt_type = param [ 4 ] ;
if ( yt_type = = USE_YT_NA )
{ //双点遥控
data_length = 2 ;
buffer [ 0 ] = C_SE_NA_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
}
else if ( yt_type = = USE_YT_NB )
{
data_length = 2 ;
buffer [ 0 ] = C_SE_NB_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
}
else
{
data_length = 4 ;
buffer [ 0 ] = C_SE_NC_1 ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 2 ] = ( value > > 16 ) & 0xff ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + 3 ] = ( value > > 24 ) & 0xff ;
}
buffer [ 1 ] = 1 ;
if ( YTS_SELED = = action & & YTR_FAIL = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + data_length ] | = IEC_101_104_SE ;
action = YTS_ABRED ;
}
else if ( YTS_SELREQ = = action & & YTR_OVER = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + data_length ] | = IEC_101_104_SE ;
action = YTS_ABRED ;
}
else if ( YTS_SELING = = action & & YTR_OVER = = result )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + data_length ] | = IEC_101_104_SE ;
action = YTS_ABRED ;
}
if ( YTS_SELED = = action )
{
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length + data_length ] | = IEC_101_104_SE ;
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_ACTCON ) ;
}
else if ( YTS_ABRED = = action )
{
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
}
else if ( YTS_EXEED = = action )
{
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_ACTTREM ) ;
}
else
{
return FALSE ;
}
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ioa ) ;
if ( ! SendIFrame ( buffer , ( 3 + cot_length + asdu_addr_length + info_addr_length + data_length ) , ord ) ) return - 1 ;
return 1 ;
}
int CIEC104Process : : Receive_Interrogation_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //总召唤
{
BYTE QOI ;
BYTE * pData = ( BYTE * ) pBuf ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
pData + = info_addr_length ;
QOI = * pData ;
pTarget [ 0 ] = C_IC_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = QOI ;
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{
if ( QOI < 20 | | QOI > 36 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON | IEC_101_104_COT_PN ) ;
return ERROR_PARAM ;
}
else
{ //总召唤,分组召唤
2024-09-24 15:59:22 +08:00
pItem - > interrogation_type = QOI ;
2024-07-08 10:27:17 +08:00
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
}
return NO_ERROR ;
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ; //传输原因错误
}
int CIEC104Process : : Receive_Clock_synchronisation_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //时钟同步
{
BYTE * pData = ( BYTE * ) pBuf ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
unionCP56Time st ;
pData + = info_addr_length ;
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . hour = * pData & 0x1f ;
st . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . dayofmonth = * pData & 0x1f ;
st . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
st . month = * pData & 0x0f ; pData + + ;
st . year = * pData & 0x7f ; pData + + ;
pTarget [ 0 ] = C_CS_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( st . millisecond & 0x00ff ) ;
pTarget [ 3 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( ( st . millisecond > > 8 ) & 0x00ff ) ;
pTarget [ 4 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( st . minute | ( st . IV < < 7 ) ) ;
pTarget [ 5 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( st . hour | ( st . SU < < 7 ) ) ;
pTarget [ 6 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( st . dayofmonth | ( st . dayofweek < < 5 ) ) ;
pTarget [ 7 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st . month ;
pTarget [ 8 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st . year ;
count = 9 + cot_length + asdu_addr_length + info_addr_length ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{
if ( st . IV )
{
vLog ( LOG_WARN , " Remote Control system time is invalid. \n " ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON | IEC_101_104_COT_PN ) ;
return ERROR_PARAM ;
}
/*if (!IsAcceptTime())
{
vLog ( LOG_WARN , " Local clock sync is not supported or not configured. \n " ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON | IEC_101_104_COT_PN ) ;
return NO_ERROR ;
} */
set_system_time ( & st ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
return NO_ERROR ;
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ; //传输原因错误
}
int CIEC104Process : : Receive_Counter_interrogation_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //累积量
{
BYTE QCC ;
BYTE * pData = ( BYTE * ) pBuf ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
pData + = info_addr_length ;
QCC = * pData ;
pTarget [ 0 ] = C_CI_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = QCC ;
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
//累计量召唤命令限定词出错
/*
if ( ( QCC & 0x3f ) < 1 | | ( QCC & 0x3f ) > 5 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON | IEC_101_104_COT_PN ) ;
return ERROR_PARAM ;
}
*/
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{
2024-09-24 15:59:22 +08:00
pItem - > pulse_type = QCC ;
2024-07-08 10:27:17 +08:00
pItem - > ym_pos = 0 ;
pItem - > pulse_start = TRUE ;
pItem - > pulse_fin = FALSE ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
return NO_ERROR ;
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ; //传输原因错误
}
int CIEC104Process : : Receive_Reset_process_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //复位进程
{
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{
return NO_ERROR ;
}
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CIEC104Process : : Receive_Single_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //单点令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
DWORD information_address ;
BOOLEAN value ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ; pData + = info_addr_length ;
command = * pData ;
pTarget [ 0 ] = C_SC_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYKPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{ //信息体地址错误
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
value = GET_SCO ( command ) ; pData + + ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BYTE yk_type ;
BYTE relay_type ;
param = GetUnitYKParamByPoint ( uid , point ) ;
yk_type = param [ 4 ] ;
relay_type = param [ 5 ] ;
if ( yk_type ! = USE_YK_SC )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( relay_type )
{
if ( relay_type = = 1 )
{ //Only on
if ( ! value )
{
vLog ( LOG_ERROR , " Only on,Cann't off! \n " ) ;
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
}
else
{ //Only off
if ( value )
{
vLog ( LOG_ERROR , " Only off,Cann't on! \n " ) ;
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
}
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYK ( uid , point , value , YKS_SELREQ , YKR_IDLE ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYK ( uid , point , value , YKS_EXEREQ , YKR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_EXEREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYK ( uid , point , value , YKS_ABRREQ , YKR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CIEC104Process : : Receive_Double_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //单点令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
DWORD information_address ;
BOOLEAN value ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ; pData + = info_addr_length ;
command = * pData ;
pTarget [ 0 ] = C_DC_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYKPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
value = GET_DCO ( command ) ; pData + + ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BYTE yk_type ;
//BYTE relay_type;
param = GetUnitYKParamByPoint ( uid , point ) ;
yk_type = param [ 4 ] ;
//relay_type = param[5];
if ( yk_type = = USE_YK_SC )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYK ( uid , point , value , YKS_SELREQ , YKR_IDLE ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_SELREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYK ( uid , point , value , YKS_EXEREQ , YKR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_EXEREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYK ( uid , point , value , YKS_ABRREQ , YKR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_WARN , " Unit(%d) yk(%d) %s state is YKS_ABRREQ result is YKR_IDLE. \n " , uid , point , ( value ? " CLOSE " : " TRIP " ) ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CIEC104Process : : Receive_Set_point_command_normalized ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //设定规一化值命令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
int information_address ;
WORD value = 0 ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ;
pData + = info_addr_length ;
value = ( WORD ) ( pData [ 0 ] | pData [ 1 ] < < 8 ) ;
pData + = 2 ;
command = * pData ;
pTarget [ 0 ] = C_SE_NA_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 2 ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 2 ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 2 ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BYTE yt_type ;
param = GetUnitYTParamByPoint ( pItem - > GetUnitID ( ) , point ) ;
yt_type = param [ 4 ] ;
if ( yt_type ! = USE_YT_NA )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYT ( uid , point , value , YTS_SELREQ , YTR_IDLE ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_SELREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYT ( uid , point , value , YTS_EXEREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_ABRREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_ABRREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CIEC104Process : : Receive_Set_point_command_scaled ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //设定标度化值命令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
int information_address ;
WORD value = 0 ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ;
pData + = info_addr_length ;
value = ( WORD ) ( pData [ 0 ] | pData [ 1 ] < < 8 ) ;
pData + = 2 ;
command = * pData ;
pTarget [ 0 ] = C_SE_NB_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 2 ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 2 ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 2 ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BYTE yt_type ;
param = GetUnitYTParamByPoint ( pItem - > GetUnitID ( ) , point ) ;
yt_type = param [ 4 ] ;
if ( yt_type ! = USE_YT_NB )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYT ( uid , point , value , YTS_SELREQ , YTR_IDLE ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_SELREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYT ( uid , point , value , YTS_EXEREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_ABRREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_ABRREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CIEC104Process : : Receive_Set_point_command_short_floating ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //设定短浮点值命令
{
BYTE * pData = ( BYTE * ) pBuf ;
BYTE command ;
int uid , point ;
int information_address ;
DWORD value ;
BYTE SE ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
information_address = GetInformationAddr ( pData ) ;
pData + = info_addr_length ;
value = ( DWORD ) ( pData [ 0 ] | ( pData [ 1 ] < < 8 ) | ( pData [ 2 ] < < 16 ) | ( pData [ 3 ] < < 24 ) ) ;
pData + = 4 ;
command = * pData ;
pTarget [ 0 ] = C_SE_NC_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , information_address ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = value & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 1 ] = ( value > > 8 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 2 ] = ( value > > 16 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 3 ] = ( value > > 24 ) & 0xff ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length + 4 ] = command ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 4 ;
if ( IEC_101_104_COT_ACT = = cause_of_transmission | | IEC_101_104_COT_DEACT = = cause_of_transmission )
{
uid = pItem - > GetUnitID ( ) ;
BYTE ioa [ 4 ] ;
ioa [ 0 ] = information_address & 0xff ;
ioa [ 1 ] = ( information_address > > 8 ) & 0xff ;
ioa [ 2 ] = ( information_address > > 16 ) & 0xff ;
ioa [ 3 ] = ( information_address > > 24 ) & 0xff ;
point = GetUnitYTPointByParam ( uid , ioa , 4 ) ;
if ( point < 0 )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_INFO ) ;
count = 3 + cot_length + asdu_addr_length + info_addr_length + 4 ;
return ERROR_INFORMATION_ADDRESS ;
}
SE = GET_SE ( command ) ;
//判断该点是否为单点遥控及参数状态
BYTE * param ;
BYTE yt_type ;
param = GetUnitYTParamByPoint ( pItem - > GetUnitID ( ) , point ) ;
yt_type = param [ 4 ] ;
if ( yt_type ! = USE_YT_NC )
{ //遥控类型错误,返回否定确认
SetCOT ( & pTarget [ 2 ] , ( ( cause_of_transmission + 1 ) | IEC_101_104_COT_PN ) ) ;
return ERROR_PARAM ;
}
if ( IEC_101_104_COT_ACT = = cause_of_transmission )
{ //激活
if ( SE )
{ //选择
count = 0 ;
SetUnitYT ( uid , point , value , YTS_SELREQ , YTR_IDLE ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_SELREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
else
{ //执行
SetUnitYT ( uid , point , value , YTS_EXEREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_EXEREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
else if ( IEC_101_104_COT_DEACT = = cause_of_transmission )
{ //激活终止
SetUnitYT ( uid , point , value , YTS_ABRREQ , YTR_IDLE ) ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON ) ;
vLog ( LOG_DEBUG , " Unit(%d) set point(%d) %d state is YTS_ABRREQ result is YTR_IDLE. \n " , uid , point , value ) ;
return NO_ERROR ;
}
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ;
}
int CIEC104Process : : Send_End_of_initialisation ( CIEC104ProcessItem * pItem , int ord )
{
BYTE buffer [ 32 ] ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( pItem = = NULL ) return - 1 ;
buffer [ 0 ] = M_EI_NA_1 ; //初始化结束
buffer [ 1 ] = 1 ;
SetCOT ( & buffer [ 2 ] , IEC_101_104_COT_INIT ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = 0 ;
if ( ! SendIFrame ( buffer , ( 3 + cot_length + asdu_addr_length + info_addr_length ) , ord ) ) return - 1 ;
return 1 ;
}
int CIEC104Process : : Send_Single_point_information ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int uid ;
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_SP_NA_1 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //遥信变位
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 1 ) ) ;
count = pItem - > yxbws . count > count ? count : pItem - > yxbws . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > yxbws . data [ i ] . order + m_yx_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > yxbws . data [ i ] . value ; pData + + ;
}
pItem - > yxbws . count - = count ;
if ( pItem - > yxbws . count < = 0 | | pItem - > yxbws . count > = DATABASE_YXBW_NUM )
{ //遥信变位发送结束
pItem - > yxbws . count = 0 ;
}
else
{
memcpy ( pItem - > yxbws . data , & pItem - > yxbws . data [ count ] , sizeof ( struYXData ) * pItem - > yxbws . count ) ;
}
if ( ! SendIFrame ( buffer , ( 2 + cot_length + asdu_addr_length + ( info_addr_length + 1 ) * count ) , ord ) ) return - 1 ;
return 1 ;
}
else
{ //召唤
count = ( max_frame - 8 - cot_length - asdu_addr_length - info_addr_length ) ;
count = count > 127 ? 127 : count ; //遥信最大为127个信息
count = ( pItem - > total_yx - pItem - > yx_pos ) > count ? count : ( pItem - > total_yx - pItem - > yx_pos ) ;
if ( count < = 0 )
{
pItem - > yx_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yx_fin = TRUE ; //遥信发送完毕
}
return 0 ;
}
buffer [ 1 ] = 0x80 | count ;
SetInformationAddr ( pData , pItem - > yx_pos + m_yx_start_address ) ;
pData + = info_addr_length ;
uid = pItem - > GetUnitID ( ) ;
for ( i = 0 ; i < count ; i + + )
{
* pData = GetUnitYX ( uid , pItem - > yx_pos + i ) | GetUnitYXQDS ( uid , pItem - > yx_pos + i ) ;
pData + + ;
}
pItem - > yx_pos + = count ;
if ( pItem - > yx_pos < 0 | | pItem - > yx_pos > = pItem - > total_yx )
{
pItem - > yx_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yx_fin = TRUE ; //遥信发送完毕
}
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + info_addr_length + count , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Single_point_information_with_time_tag ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_SP_TA_1 ;
buffer [ 1 ] = 9 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //短时标事件记录
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 4 ) ) ;
count = pItem - > events . count > count ? count : pItem - > events . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > events . data [ i ] . order + m_yx_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > events . data [ i ] . value ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . millisecond & 0x00ff ) ; pData + + ;
* pData = ( BYTE ) ( ( pItem - > events . data [ i ] . ct . millisecond > > 8 ) & 0x00ff ) ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . minute | ( pItem - > events . data [ i ] . ct . IV < < 7 ) ) ; pData + + ;
}
pItem - > events . count - = count ;
if ( pItem - > events . count < = 0 | | pItem - > events . count > = DATABASE_SOE_NUM )
{ //事件记录发送结束
pItem - > events . count = 0 ;
}
else
{
memcpy ( pItem - > events . data , & pItem - > events . data [ count ] , sizeof ( struEventsData ) * pItem - > events . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 4 ) * count , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Single_point_information_with_time_tag_cp56time2a ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_SP_TB_1 ;
buffer [ 1 ] = 9 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //长时标事件记录
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 8 ) ) ;
count = pItem - > events . count > count ? count : pItem - > events . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > events . data [ i ] . order + m_yx_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > events . data [ i ] . value ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . millisecond & 0x00ff ) ; pData + + ;
* pData = ( BYTE ) ( ( pItem - > events . data [ i ] . ct . millisecond > > 8 ) & 0x00ff ) ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . minute | ( pItem - > events . data [ i ] . ct . IV < < 7 ) ) ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . hour | ( pItem - > events . data [ i ] . ct . SU < < 7 ) ) ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . dayofmonth | ( pItem - > events . data [ i ] . ct . dayofweek < < 5 ) ) ; pData + + ;
* pData = ( BYTE ) pItem - > events . data [ i ] . ct . month ; pData + + ;
* pData = ( BYTE ) pItem - > events . data [ i ] . ct . year ; pData + + ;
}
pItem - > events . count - = count ;
if ( pItem - > events . count < = 0 | | pItem - > events . count > = DATABASE_SOE_NUM )
{ //事件记录发送结束
pItem - > events . count = 0 ;
}
else
{
memcpy ( pItem - > events . data , & pItem - > events . data [ count ] , sizeof ( struEventsData ) * pItem - > events . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 8 ) * count , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Double_point_information ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int uid ;
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_DP_NA_1 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //遥信变位
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 1 ) ) ;
count = pItem - > yxbws . count > count ? count : pItem - > yxbws . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > yxbws . data [ i ] . order + m_yx_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > yxbws . data [ i ] . value ? DPI_ON : DPI_OFF ; pData + + ;
}
pItem - > yxbws . count - = count ;
if ( pItem - > yxbws . count < = 0 | | pItem - > yxbws . count > = DATABASE_YXBW_NUM )
{ //遥信变位发送结束
pItem - > yxbws . count = 0 ;
}
else
{
memcpy ( pItem - > yxbws . data , & pItem - > yxbws . data [ count ] , sizeof ( struYXData ) * pItem - > yxbws . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 1 ) * count , ord ) ) return - 1 ;
return 1 ;
}
else
{ //召唤
count = ( max_frame - 8 - cot_length - asdu_addr_length - info_addr_length ) ;
count = count > 127 ? 127 : count ; //遥信最大为127个信息
count = ( pItem - > total_yx - pItem - > yx_pos ) > count ? count : ( pItem - > total_yx - pItem - > yx_pos ) ;
if ( count < = 0 )
{
pItem - > yx_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yx_fin = TRUE ; //遥信发送完毕
}
return 0 ;
}
buffer [ 1 ] = 0x80 | count ;
SetInformationAddr ( pData , pItem - > yx_pos + m_yx_start_address ) ;
pData + = info_addr_length ;
BOOLEAN value ;
uid = pItem - > GetUnitID ( ) ;
for ( i = 0 ; i < count ; i + + )
{
value = GetUnitYX ( uid , pItem - > yx_pos + i ) ? DPI_ON : DPI_OFF ;
* pData = value | GetUnitYXQDS ( uid , pItem - > yx_pos + i ) ;
pData + + ;
}
pItem - > yx_pos + = count ;
if ( pItem - > yx_pos < 0 | | pItem - > yx_pos > = pItem - > total_yx )
{
pItem - > yx_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yx_fin = TRUE ; //遥信发送完毕
}
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + info_addr_length + count , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Double_point_information_with_time_tag ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_DP_TA_1 ;
buffer [ 1 ] = 9 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //短时标事件记录
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 4 ) ) ;
count = pItem - > events . count > count ? count : pItem - > events . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > events . data [ i ] . order + m_yx_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > events . data [ i ] . value ? DPI_ON : DPI_OFF ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . millisecond & 0x00ff ) ; pData + + ;
* pData = ( BYTE ) ( ( pItem - > events . data [ i ] . ct . millisecond > > 8 ) & 0x00ff ) ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . minute | ( pItem - > events . data [ i ] . ct . IV < < 7 ) ) ; pData + + ;
}
pItem - > events . count - = count ;
if ( pItem - > events . count < = 0 | | pItem - > events . count > = DATABASE_SOE_NUM )
{ //事件记录发送结束
pItem - > events . count = 0 ;
}
else
{
memcpy ( pItem - > events . data , & pItem - > events . data [ count ] , sizeof ( struEventsData ) * pItem - > events . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 4 ) * count , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Double_point_information_with_time_tag_cp56time2a ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_DP_TB_1 ;
buffer [ 1 ] = 9 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //短时标事件记录
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 8 ) ) ;
count = pItem - > events . count > count ? count : pItem - > events . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > events . data [ i ] . order + m_yx_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > events . data [ i ] . value ? DPI_ON : DPI_OFF ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . millisecond & 0x00ff ) ; pData + + ;
* pData = ( BYTE ) ( ( pItem - > events . data [ i ] . ct . millisecond > > 8 ) & 0x00ff ) ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . minute | ( pItem - > events . data [ i ] . ct . IV < < 7 ) ) ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . hour | ( pItem - > events . data [ i ] . ct . SU < < 7 ) ) ; pData + + ;
* pData = ( BYTE ) ( pItem - > events . data [ i ] . ct . dayofmonth | ( pItem - > events . data [ i ] . ct . dayofweek < < 5 ) ) ; pData + + ;
* pData = ( BYTE ) pItem - > events . data [ i ] . ct . month ; pData + + ;
* pData = ( BYTE ) pItem - > events . data [ i ] . ct . year ; pData + + ;
}
pItem - > events . count - = count ;
if ( pItem - > events . count < = 0 | | pItem - > events . count > = DATABASE_SOE_NUM )
{ //事件记录发送结束
pItem - > events . count = 0 ;
}
else
{
memcpy ( pItem - > events . data , & pItem - > events . data [ count ] , sizeof ( struEventsData ) * pItem - > events . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 8 ) * count , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Measured_value_normalised ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int uid ;
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_ME_NA_1 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //遥测变位
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 3 ) ) ;
count = pItem - > ycbws . count > count ? count : pItem - > ycbws . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > ycbws . data [ i ] . order + m_yc_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > ycbws . data [ i ] . value & 0xff ; pData + + ;
* pData = ( pItem - > ycbws . data [ i ] . value > > 8 ) & 0xff ; pData + + ;
* pData = 0 ; pData + + ;
}
pItem - > ycbws . count - = count ;
if ( pItem - > ycbws . count < = 0 | | pItem - > ycbws . count > = UNIT_YC_MAX )
{ //遥测变位发送结束
pItem - > ycbws . count = 0 ;
}
else
{
memcpy ( pItem - > ycbws . data , & pItem - > ycbws . data [ count ] , sizeof ( struYCBW ) * pItem - > ycbws . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 3 ) * count , ord ) ) return - 1 ;
return 1 ;
}
else
{ //召唤
count = ( max_frame - 8 - cot_length - asdu_addr_length - info_addr_length ) / 3 ;
count = ( pItem - > total_yc - pItem - > yc_pos ) > count ? count : ( pItem - > total_yc - pItem - > yc_pos ) ;
if ( count < = 0 )
{
pItem - > yc_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yc_fin = TRUE ; //遥测发送完毕
}
return 0 ;
}
buffer [ 1 ] = 0x80 | count ;
SetInformationAddr ( pData , pItem - > yc_pos + m_yc_start_address ) ;
pData + = info_addr_length ;
short value ;
uid = pItem - > GetUnitID ( ) ;
for ( i = 0 ; i < count ; i + + )
{
value = ( short ) GetUnitYC ( uid , pItem - > yc_pos + i ) ;
* pData = value & 0xff ; pData + + ;
* pData = ( value > > 8 ) & 0xff ; pData + + ;
* pData = GetUnitYCQDS ( uid , pItem - > yc_pos + i ) ; pData + + ;
}
pItem - > yc_pos + = count ;
if ( pItem - > yc_pos < 0 | | pItem - > yc_pos > = pItem - > total_yc )
{
pItem - > yc_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yc_fin = TRUE ; //遥测发送完毕
}
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + info_addr_length + count * 3 , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Measured_value_scaled ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int uid ;
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_ME_NB_1 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //遥测变位
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 3 ) ) ;
count = pItem - > ycbws . count > count ? count : pItem - > ycbws . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > ycbws . data [ i ] . order + m_yc_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > ycbws . data [ i ] . value & 0xff ; pData + + ;
* pData = ( pItem - > ycbws . data [ i ] . value > > 8 ) & 0xff ; pData + + ;
* pData = 0 ; pData + + ;
}
pItem - > ycbws . count - = count ;
if ( pItem - > ycbws . count < = 0 | | pItem - > ycbws . count > = UNIT_YC_MAX )
{ //遥测变位发送结束
pItem - > ycbws . count = 0 ;
}
else
{
memcpy ( pItem - > ycbws . data , & pItem - > ycbws . data [ count ] , sizeof ( struYCBW ) * pItem - > ycbws . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 3 ) * count , ord ) ) return - 1 ;
return 1 ;
}
else
{ //召唤
count = ( max_frame - 8 - cot_length - asdu_addr_length - info_addr_length ) / 3 ;
count = ( pItem - > total_yc - pItem - > yc_pos ) > count ? count : ( pItem - > total_yc - pItem - > yc_pos ) ;
if ( count < = 0 )
{
pItem - > yc_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yc_fin = TRUE ; //遥测发送完毕
}
return 0 ;
}
buffer [ 1 ] = 0x80 | count ;
SetInformationAddr ( pData , pItem - > yc_pos + m_yc_start_address ) ;
pData + = info_addr_length ;
short value ;
uid = pItem - > GetUnitID ( ) ;
for ( i = 0 ; i < count ; i + + )
{
value = ( short ) GetUnitYC ( uid , pItem - > yc_pos + i ) ;
* pData = value & 0xff ; pData + + ;
* pData = ( value > > 8 ) & 0xff ; pData + + ;
* pData = GetUnitYCQDS ( uid , pItem - > yc_pos + i ) ; pData + + ;
}
pItem - > yc_pos + = count ;
if ( pItem - > yc_pos < 0 | | pItem - > yc_pos > = pItem - > total_yc )
{
pItem - > yc_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yc_fin = TRUE ; //遥测发送完毕
}
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + info_addr_length + count * 3 , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Measured_value_short_floating_point ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int uid ;
int i , count ;
float fvalue ;
DWORD dwValue ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_ME_NC_1 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //遥测变位
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 5 ) ) ;
count = pItem - > ycbws . count > count ? count : pItem - > ycbws . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
uid = pItem - > GetUnitID ( ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > ycbws . data [ i ] . order + m_yc_start_address ) ;
pData + = info_addr_length ;
//fvalue = GetUnitYCRealFromValue(uid, pItem->ycbws.data[i].order, pItem->ycbws.data[i].value);
fvalue = pItem - > ycbws . data [ i ] . flVal ; //GetUnitYCRealFromValue(uid, pItem->ycbws.data[i].order, pItem->ycbws.data[i].value);
dwValue = 0 ;
memcpy ( & dwValue , & fvalue , sizeof ( DWORD ) ) ;
* pData = dwValue & 0xff ; pData + + ;
* pData = ( dwValue > > 8 ) & 0xff ; pData + + ;
* pData = ( dwValue > > 16 ) & 0xff ; pData + + ;
* pData = ( dwValue > > 24 ) & 0xff ; pData + + ;
* pData = 0 ; pData + + ;
}
pItem - > ycbws . count - = count ;
if ( pItem - > ycbws . count < = 0 | | pItem - > ycbws . count > = UNIT_YC_MAX )
{ //遥测变位发送结束
pItem - > ycbws . count = 0 ;
}
else
{
memcpy ( pItem - > ycbws . data , & pItem - > ycbws . data [ count ] , sizeof ( struYCBW ) * pItem - > ycbws . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 5 ) * count , ord ) ) return - 1 ;
return 1 ;
}
else
{ //召唤
count = ( max_frame - 8 - cot_length - asdu_addr_length - info_addr_length ) / 5 ;
count = ( pItem - > total_yc - pItem - > yc_pos ) > count ? count : ( pItem - > total_yc - pItem - > yc_pos ) ;
if ( count < = 0 )
{
pItem - > yc_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yc_fin = TRUE ; //遥测发送完毕
}
return 0 ;
}
buffer [ 1 ] = 0x80 | count ;
SetInformationAddr ( pData , pItem - > yc_pos + m_yc_start_address ) ;
pData + = info_addr_length ;
uid = pItem - > GetUnitID ( ) ;
for ( i = 0 ; i < count ; i + + )
{
fvalue = GetUnitYCReal ( uid , pItem - > yc_pos + i ) ;
dwValue = 0 ;
memcpy ( & dwValue , & fvalue , sizeof ( DWORD ) ) ;
* pData = dwValue & 0xff ; pData + + ;
* pData = ( dwValue > > 8 ) & 0xff ; pData + + ;
* pData = ( dwValue > > 16 ) & 0xff ; pData + + ;
* pData = ( dwValue > > 24 ) & 0xff ; pData + + ;
* pData = GetUnitYCQDS ( uid , pItem - > yc_pos + i ) ; pData + + ;
}
pItem - > yc_pos + = count ;
if ( pItem - > yc_pos < 0 | | pItem - > yc_pos > = pItem - > total_yc )
{
pItem - > yc_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yc_fin = TRUE ; //遥测发送完毕
}
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + info_addr_length + count * 5 , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Measured_value_normalised_without_quality ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission /* = IEC_101_104_COT_SPONT */ )
{
int uid ;
int i , count ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_ME_ND_1 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //遥测变位
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 2 ) ) ;
count = pItem - > ycbws . count > count ? count : pItem - > ycbws . count ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , pItem - > ycbws . data [ i ] . order + m_yc_start_address ) ;
pData + = info_addr_length ;
* pData = pItem - > ycbws . data [ i ] . value & 0xff ; pData + + ;
* pData = ( pItem - > ycbws . data [ i ] . value > > 8 ) & 0xff ; pData + + ;
}
pItem - > ycbws . count - = count ;
if ( pItem - > ycbws . count < = 0 | | pItem - > ycbws . count > = UNIT_YC_MAX )
{ //遥测变位发送结束
pItem - > ycbws . count = 0 ;
}
else
{
memcpy ( pItem - > ycbws . data , & pItem - > ycbws . data [ count ] , sizeof ( struYCBW ) * pItem - > ycbws . count ) ;
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 2 ) * count , ord ) ) return - 1 ;
return 1 ;
}
else
{ //召唤
count = ( max_frame - 8 - cot_length - asdu_addr_length - info_addr_length ) / 2 ;
count = ( pItem - > total_yc - pItem - > yc_pos ) > count ? count : ( pItem - > total_yc - pItem - > yc_pos ) ;
if ( count < = 0 )
{
pItem - > yc_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yc_fin = TRUE ; //遥测发送完毕
}
return 0 ;
}
buffer [ 1 ] = 0x80 | count ;
SetInformationAddr ( pData , pItem - > yc_pos + m_yc_start_address ) ;
pData + = info_addr_length ;
short value ;
uid = pItem - > GetUnitID ( ) ;
for ( i = 0 ; i < count ; i + + )
{
value = ( short ) GetUnitYC ( uid , pItem - > yc_pos + i ) ;
* pData = value & 0xff ; pData + + ;
* pData = ( value > > 8 ) & 0xff ; pData + + ;
}
pItem - > yc_pos + = count ;
if ( pItem - > yc_pos < 0 | | pItem - > yc_pos > = pItem - > total_yc )
{
pItem - > yc_pos = 0 ;
if ( IEC_101_104_COT_INTERROGATION = = cause_of_transimission & & pItem - > interrogation_start )
{
pItem - > interrogation_yc_fin = TRUE ; //遥测发送完毕
}
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + info_addr_length + count * 2 , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_Integrated_totals ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission )
{
int uid ;
int i , count ;
DWORD value ;
BYTE buffer [ 256 ] , * pData ;
memset ( buffer , 0 , sizeof ( buffer ) ) ;
if ( NULL = = pItem ) return - 1 ;
uid = pItem - > GetUnitID ( ) ;
pData = & buffer [ 2 + cot_length + asdu_addr_length ] ;
buffer [ 0 ] = M_IT_NA_1 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
if ( IEC_101_104_COT_SPONT = = cause_of_transimission )
{ //遥脉变位
count = ( ( max_frame - 8 - cot_length - asdu_addr_length ) / ( info_addr_length + 5 ) ) ;
count = ( pItem - > total_ym - pItem - > ym_pos ) > count ? count : ( pItem - > total_ym - pItem - > ym_pos ) ;
if ( count < = 0 ) return 0 ;
buffer [ 1 ] = ( count & 0x7f ) ;
for ( i = 0 ; i < count ; i + + )
{
SetInformationAddr ( pData , i + m_ym_start_address + pItem - > ym_pos ) ;
pData + = info_addr_length ;
value = GetUnitYM ( uid , pItem - > ym_pos + i ) ;
* pData = value & 0xff ; pData + + ;
* pData = ( value > > 8 ) & 0xff ; pData + + ;
* pData = ( value > > 16 ) & 0xff ; pData + + ;
* pData = ( value > > 24 ) & 0xff ; pData + + ;
* pData = ( pItem - > ym_pos + i ) % 32 ; pData + + ;
}
pItem - > ym_pos + = count ;
if ( pItem - > ym_pos < 0 | | pItem - > ym_pos > = pItem - > total_ym )
{
pItem - > ym_pos = 0 ;
if ( ( IEC_101_104_COT_REQCOGEN = = cause_of_transimission | | IEC_101_104_COT_INTERROGATION = = cause_of_transimission ) & & pItem - > pulse_start )
{
pItem - > pulse_fin = TRUE ; //遥脉发送完毕
}
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + ( info_addr_length + 5 ) * count , ord ) ) return - 1 ;
return 1 ;
}
else
{ //召唤
count = ( max_frame - 8 - cot_length - asdu_addr_length - info_addr_length ) / 5 ;
count = ( pItem - > total_ym - pItem - > ym_pos ) > count ? count : ( pItem - > total_ym - pItem - > ym_pos ) ;
if ( count < = 0 )
{
pItem - > ym_pos = 0 ;
if ( ( IEC_101_104_COT_REQCOGEN = = cause_of_transimission | | IEC_101_104_COT_INTERROGATION = = cause_of_transimission ) & & pItem - > pulse_start )
{
pItem - > pulse_fin = TRUE ; //遥脉发送完毕
}
return 0 ;
}
buffer [ 1 ] = 0x80 | count ;
SetInformationAddr ( pData , pItem - > ym_pos + m_ym_start_address ) ;
pData + = info_addr_length ;
for ( i = 0 ; i < count ; i + + )
{
value = GetUnitYM ( uid , pItem - > ym_pos + i ) ;
* pData = value & 0xff ; pData + + ;
* pData = ( value > > 8 ) & 0xff ; pData + + ;
* pData = ( value > > 16 ) & 0xff ; pData + + ;
* pData = ( value > > 24 ) & 0xff ; pData + + ;
* pData = ( pItem - > ym_pos + i ) % 32 ; pData + + ;
}
pItem - > ym_pos + = count ;
if ( pItem - > ym_pos < 0 | | pItem - > ym_pos > = pItem - > total_ym )
{
pItem - > ym_pos = 0 ;
if ( ( IEC_101_104_COT_REQCOGEN = = cause_of_transimission | | IEC_101_104_COT_INTERROGATION = = cause_of_transimission ) & & pItem - > pulse_start )
{
pItem - > pulse_fin = TRUE ; //遥脉发送完毕
}
}
if ( ! SendIFrame ( buffer , 2 + cot_length + asdu_addr_length + info_addr_length + count * 5 , ord ) ) return - 1 ;
return 1 ;
}
return - 1 ;
}
int CIEC104Process : : Send_FrameInterrogation ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission )
{
BYTE buffer [ 10 ] ;
int count ;
buffer [ 0 ] = C_IC_NA_1 ;
buffer [ 1 ] = 0x01 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
2024-09-24 15:59:22 +08:00
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = pItem - > interrogation_type ;
2024-07-08 10:27:17 +08:00
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
if ( ! SendIFrame ( buffer , count , ord ) ) return - 1 ;
return 1 ;
}
int CIEC104Process : : Send_FrameCounterInterrogation ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission )
{
BYTE buffer [ 10 ] ;
int count ;
buffer [ 0 ] = C_CI_NA_1 ;
buffer [ 1 ] = 0x01 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
2024-09-24 15:59:22 +08:00
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = pItem - > pulse_type ;
2024-07-08 10:27:17 +08:00
count = 3 + cot_length + asdu_addr_length + info_addr_length ;
if ( ! SendIFrame ( buffer , count , ord ) ) return - 1 ;
return 1 ;
}
int CIEC104Process : : Send_Test_command ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission )
{
BYTE buffer [ 32 ] ;
int count ;
buffer [ 0 ] = C_TS_NA_1 ;
buffer [ 1 ] = 0x01 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = 0xAA ;
buffer [ 3 + cot_length + asdu_addr_length + info_addr_length ] = 0x55 ;
count = 4 + cot_length + asdu_addr_length + info_addr_length ;
if ( ! SendIFrame ( buffer , count , ord ) ) return - 1 ;
return 1 ;
}
int CIEC104Process : : Send_Test_command_with_time_tag_cp56time2a ( CIEC104ProcessItem * pItem , int ord , BYTE cause_of_transimission )
{
BYTE buffer [ 32 ] ;
int count ;
buffer [ 0 ] = C_TS_TA_1 ;
buffer [ 1 ] = 0x01 ;
SetCOT ( & buffer [ 2 ] , cause_of_transimission ) ;
SetAsduAddr ( & buffer [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & buffer [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
buffer [ 2 + cot_length + asdu_addr_length + info_addr_length ] = 0xAA ;
buffer [ 3 + cot_length + asdu_addr_length + info_addr_length ] = 0x55 ;
unionCP56Time st ;
if ( ! get_system_time ( & st ) )
{
vLog ( LOG_ERROR , " Get system time error. \n " ) ;
return 0 ;
}
st . IV = FALSE ;
st . SU = FALSE ;
buffer [ 4 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( st . millisecond & 0x00ff ) ;
buffer [ 5 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( ( st . millisecond > > 8 ) & 0x00ff ) ;
buffer [ 6 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( st . minute | ( st . IV < < 7 ) ) ;
buffer [ 7 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( st . hour | ( st . SU < < 7 ) ) ;
buffer [ 8 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( st . dayofmonth | ( st . dayofweek < < 5 ) ) ;
buffer [ 9 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st . month ;
buffer [ 10 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st . year ;
count = 11 + cot_length + asdu_addr_length + info_addr_length ;
if ( ! SendIFrame ( buffer , count , ord ) ) return - 1 ;
return 1 ;
}
//start his data
int CIEC104Process : : Receive_HisDataRequest_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE * pTarget , int & count ) //补录数据
{
BYTE * pData = ( BYTE * ) pBuf ;
struct tm * p ;
time_t st , et ;
int st_year , st_mon , st_mday , st_hour , st_min , st_sec ;
int et_year , et_mon , et_mday , et_hour , et_min , et_sec ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
time_t temp = ( time_t ) system32 . timers ;
p = localtime ( & temp ) ;
pData + = info_addr_length ;
st_year = ( pData [ 1 ] < < 8 | pData [ 0 ] ) ; pData + = 2 ;
st_mon = * pData ; pData + + ;
st_mday = * pData ; pData + + ;
st_hour = * pData ; pData + + ;
st_min = * pData ; pData + + ;
st_sec = * pData ; pData + + ;
p - > tm_year = st_year - 1900 ;
p - > tm_mon = st_mon - 1 ;
p - > tm_mday = st_mday ;
p - > tm_hour = st_hour ;
p - > tm_min = st_min ;
p - > tm_sec = st_sec ;
st = mktime ( p ) ;
vLog ( LOG_DEBUG , " st is: %04d/%02d/%02d %02d:%02d:%02d and " , st_year , st_mon , st_mday , st_hour , st_min , st_sec ) ;
et_year = ( pData [ 1 ] < < 8 | pData [ 0 ] ) ; pData + = 2 ;
et_mon = * pData ; pData + + ;
et_mday = * pData ; pData + + ;
et_hour = * pData ; pData + + ;
et_min = * pData ; pData + + ;
et_sec = * pData ; pData + + ;
vLog ( LOG_DEBUG , " et is: %04d/%02d/%02d %02d:%02d:%02d \n " , et_year , et_mon , et_mday , et_hour , et_min , et_sec ) ;
p - > tm_year = et_year - 1900 ;
p - > tm_mon = et_mon - 1 ;
p - > tm_mday = et_mday ;
p - > tm_hour = et_hour ;
p - > tm_min = et_min ;
p - > tm_sec = et_sec ;
et = mktime ( p ) ;
pTarget [ 0 ] = C_HD_NB_1 ;
pTarget [ 1 ] = 1 ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0x8100 ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st_year ;
pTarget [ 3 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) ( ( st_year > > 8 ) & 0x00ff ) ;
pTarget [ 4 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st_mon ;
pTarget [ 5 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st_mday ;
pTarget [ 6 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st_hour ;
pTarget [ 7 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st_min ;
pTarget [ 8 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) st_sec ;
count = 9 + cot_length + asdu_addr_length + info_addr_length ;
//后期需要添加对时间的判断
if ( IEC_101_104_COT_REQ = = cause_of_transmission )
{
if ( st > et )
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_DEACTCON | IEC_101_104_COT_PN ) ;
return ERROR_PARAM ;
}
// pItem->call_time = st;
// pItem->call_time_start = st;
// pItem->call_time_finish = et;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACT ) ;
return NO_ERROR ;
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ; //传输原因错误
}
int CIEC104Process : : Receive_His_Interrogation_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE VSQ , BYTE * pTarget , int & count ) //补录数据
{
BYTE * pData = ( BYTE * ) pBuf ;
if ( NULL = = pItem ) return ERROR_UNKNOWN ;
//BYTE interval;
unionCP56Time st ;
unionCP56Time et ;
int info_count ;
DWORD information_address [ 80 ] ;
info_count = VSQ & 0x7f ;
if ( info_count > = 80 | | info_count < = 0 ) return ERROR_PARAM ;
//interval = *pData;
pData + + ; //补采的时间间隔单位
//开始时间(包括开始时间)
st . millisecond = * pData ; pData + + ;
st . millisecond | = ( * pData < < 8 ) ; pData + + ;
st . minute = * pData & 0x3f ;
st . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . hour = * pData & 0x1f ;
st . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
st . dayofmonth = * pData & 0x1f ;
st . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
st . month = * pData & 0x0f ; pData + + ;
st . year = * pData & 0x7f ; pData + + ;
//结束时间(不包括结束时间)
et . millisecond = * pData ; pData + + ;
et . millisecond | = ( * pData < < 8 ) ; pData + + ;
et . minute = * pData & 0x3f ;
et . IV = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
et . hour = * pData & 0x1f ;
et . SU = ( * pData & 0x80 ) = = 0x80 ? TRUE : FALSE ; pData + + ;
et . dayofmonth = * pData & 0x1f ;
et . dayofweek = ( ( * pData & 0xe0 ) > > 5 ) ; pData + + ;
et . month = * pData & 0x0f ; pData + + ;
et . year = * pData & 0x7f ; pData + + ;
for ( int i = 0 ; i < info_count ; i + + )
{
if ( 1 = = m_nOption . info_addr_size )
{
information_address [ i ] = * pData ; pData + + ;
}
else if ( 2 = = m_nOption . info_addr_size )
{
information_address [ i ] = * pData ; pData + + ;
information_address [ i ] | = ( * pData < < 8 ) ; pData + + ;
}
else if ( 3 = = m_nOption . info_addr_size )
{
information_address [ i ] = * pData ; pData + + ;
information_address [ i ] | = ( * pData < < 8 ) ; pData + + ;
information_address [ i ] | = ( * pData < < 16 ) ; pData + + ;
}
}
if ( IEC_101_104_COT_REQ = = cause_of_transmission )
{
pTarget [ 0 ] = C_HD_NC_1 ;
pTarget [ 1 ] = 1 ;
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_ACT ) ;
SetAsduAddr ( & pTarget [ 2 + cot_length ] , pItem - > apdu_addr ) ;
SetInformationAddr ( & pTarget [ 2 + cot_length + asdu_addr_length ] , ( DWORD ) 0 ) ;
pTarget [ 2 + cot_length + asdu_addr_length + info_addr_length ] = ( BYTE ) 0x14 ;
count = 9 + cot_length + asdu_addr_length + info_addr_length ;
return NO_ERROR ;
}
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ; //传输原因错误
}
int CIEC104Process : : Receive_His_Counter_Interrogation_command ( CIEC104ProcessItem * pItem , const BYTE * pBuf , BYTE cause_of_transmission , BYTE VSQ , BYTE * pTarget , int & count ) //补录数据
{
SetCOT ( & pTarget [ 2 ] , IEC_101_104_COT_UNKNOWN_COT ) ;
return ERROR_CAUSE_OF_TRANSMISSION ; //传输原因错误
}
//sub end