4744 lines
176 KiB
C++
4744 lines
176 KiB
C++
#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;
|
||
|
||
interrogation_type = 0;
|
||
interrogation_start = FALSE; //总召启动
|
||
interrogation_yx_fin = FALSE; //遥信发送完毕
|
||
interrogation_yc_fin = FALSE; //遥测发送完毕
|
||
|
||
pulse_type = 0;
|
||
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;
|
||
|
||
interrogation_type = 0;
|
||
interrogation_start = FALSE; //总召启动
|
||
interrogation_yx_fin = FALSE; //遥信发送完毕
|
||
interrogation_yc_fin = FALSE; //遥测发送完毕
|
||
|
||
pulse_type = 0;
|
||
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));
|
||
}
|
||
|
||
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;
|
||
|
||
interrogation_type = 0;
|
||
interrogation_start = FALSE; //总召启动
|
||
interrogation_yx_fin = FALSE; //遥信发送完毕
|
||
interrogation_yc_fin = FALSE; //遥测发送完毕
|
||
|
||
pulse_type = 0;
|
||
pulse_start = FALSE;
|
||
pulse_fin = FALSE;
|
||
|
||
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;
|
||
|
||
interrogation_type = 0;
|
||
interrogation_start = FALSE; //总召启动
|
||
interrogation_yx_fin = FALSE; //遥信发送完毕
|
||
interrogation_yc_fin = FALSE; //遥测发送完毕
|
||
|
||
pulse_type = 0;
|
||
pulse_start = FALSE;
|
||
pulse_fin = FALSE;
|
||
|
||
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;
|
||
if (NULL == pItem->yxbws.data) return;
|
||
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;
|
||
if (NULL == pItem->events.data) return;
|
||
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;
|
||
if (NULL == pItem->ycbws.data) return;
|
||
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
|
||
{ //总召唤,分组召唤
|
||
pItem->interrogation_type = QOI;
|
||
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)
|
||
{
|
||
pItem->pulse_type = QCC;
|
||
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);
|
||
buffer[2 + cot_length + asdu_addr_length + info_addr_length] = pItem->interrogation_type;
|
||
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);
|
||
buffer[2 + cot_length + asdu_addr_length + info_addr_length] = pItem->pulse_type;
|
||
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
|