map/das-dn/comm/iec104.cpp

4744 lines
176 KiB
C++
Raw Normal View History

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