map/das-dn/comm/iec104.cpp
2024-12-03 10:36:06 +08:00

4744 lines
176 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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