#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(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