#include "sub_iec101_balanced.h" /***************************************************************************************/ BOOLEAN CIEC101SecondaryBalancedProcess::OnPreCreate(int id) { if (!CIEC101Process::OnPreCreate(id)) return FALSE; int i; int uid; CIEC101SecondaryBalancedProcessItem* pItem; for (i = 0; i < PROCESS_UNIT_NUM; i++) { pItem = (CIEC101SecondaryBalancedProcessItem *)GetItem(i); if (NULL == pItem) continue; uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) continue; BYTE phy_addr[2]; GetUnitAddr(uid, phy_addr, 2); pItem->Attach(uid, phy_addr[0], phy_addr[0], m_option.originatorAddress); //默认公共地址和物理地址一致 pItem->setAppLayerParameters(m_option.sizeOfCOT, m_option.sizeOfCA, m_option.sizeOfIOA, m_option.maxSizeOfASDU); Slave_setLinkLayerAddressOtherStation(pItem, phy_addr[1]); pItem->setAppLayerIOABase(); pItem->setAppLayerDataCount(GetUnitYXCount(uid), GetUnitYCCount(uid), GetUnitYMCount(uid)); } last_sec != (time_t)system32.timers; return TRUE; } BOOLEAN CIEC101SecondaryBalancedProcess::Run(void) { if (!CIEC101Process::Run()) return FALSE; FeedDog(); CIEC101ProcessItem* pItem = (CIEC101ProcessItem *)GetCurItem(); LinkLayerPrimaryBalanced_runStateMachine(pItem); return TRUE; } BOOLEAN CIEC101SecondaryBalancedProcess::OnTimer(void) { if (!CIEC101Process::OnTimer()) return FALSE; BOOLEAN sec_changed = FALSE; if (last_sec != (time_t)system32.timers) { last_sec = (time_t)system32.timers; sec_changed = TRUE; } CIEC101ProcessItem* pItem = (CIEC101ProcessItem *)GetCurItem(); if (NULL == pItem) return TRUE; int uid = pItem->GetUnitID(); if (uid < 0 || uid >= UNIT_NUM) return TRUE; //刷新事件记录库 GetItemEvents(pItem); //刷新遥测库 FetchUnitYC(0); if (pItem->interrogation_finish) { //总召唤结束,开始上送遥信变位 GetItemYXBWs(pItem); //总召唤结束,开始刷新遥测变位缓冲。 if (pItem->ycbws.count <= 0) { //当遥测变位发送结束后才更新 GetItemYCBWs(pItem); } //发送遥控返校 if (MakeYKFrame(pItem)) return TRUE; if (MakeYTFrame(pItem)) return TRUE; if (Send_Single_point_information(pItem)) return TRUE; if (Send_Single_point_information_with_time_tag_cp56time2a(pItem)) return TRUE; if (!pItem->interrogation_start) { //变位遥测优先级在总召唤之后。 if (sec_changed) { switch (m_option.yc_type) { case USE_YC_NB: //标度化值 return Send_Measured_value_scaled(pItem); case USE_YC_NC: //短浮点数 return Send_Measured_value_short_floating_point(pItem); case USE_YC_ND: //不带品质归一化值 return Send_Measured_value_normalised_without_quality(pItem); default: //USE_YC_NA: 归一化值 return Send_Measured_value_normalised(pItem); } } } } //响应总召唤命令 if (pItem->interrogation_start) { if (pItem->call_type != IEC_101_104_COT_INTERROGATION) { //组召唤 //激活终止 Send_FrameInterrogation(pItem); pItem->call_type = 0; pItem->interrogation_finish = TRUE; pItem->interrogation_start = FALSE; pItem->interrogation_yx_fin = TRUE; pItem->interrogation_yc_fin = TRUE; } else if (!pItem->interrogation_yx_fin) { Send_Single_point_information(pItem, IEC_101_104_COT_INTERROGATION); } else if (!pItem->interrogation_yc_fin) { switch (m_option.yc_type) { case USE_YC_NB: //标度化值 return Send_Measured_value_scaled(pItem, IEC_101_104_COT_INTERROGATION); case USE_YC_NC: //短浮点数 return Send_Measured_value_short_floating_point(pItem, IEC_101_104_COT_INTERROGATION); case USE_YC_ND: //不带品质归一化值 return Send_Measured_value_normalised_without_quality(pItem, IEC_101_104_COT_INTERROGATION); default: //USE_YC_NA: 归一化值 return Send_Measured_value_normalised(pItem, IEC_101_104_COT_INTERROGATION); } } else { Send_FrameInterrogation(pItem); pItem->call_type = 0; pItem->interrogation_finish = TRUE; pItem->interrogation_start = FALSE; pItem->interrogation_yx_fin = TRUE; pItem->interrogation_yc_fin = TRUE; } } else if (pItem->pulse_start) { if (!pItem->pulse_fin) { Send_Integrated_totals(pItem, IEC_101_104_COT_REQCOGEN); } else { Send_FrameCounterInterrogation(pItem); pItem->call_type = 0; pItem->pulse_start = FALSE; pItem->pulse_fin = TRUE; } } return TRUE; } //平衡方式从协议接收到主站报文 void CIEC101SecondaryBalancedProcess::LinkLayerSecondaryBalanced_ReceivedMessage(BYTE fc, BOOLEAN isBroadcast, BOOLEAN fcb, BOOLEAN fcv, int address, BYTE* msg, int userDataStart, int userDataLength) { CIEC101ProcessItem* pItem; if (address == -1) pItem = (CIEC101ProcessItem *)GetCurItem(); else { int uid = GetUnitByAddr((BYTE *)&address, m_linkLayer.linkLayerParameters.addressLength); if (uid < 0 || uid >= UNIT_NUM) return; pItem = (CIEC101ProcessItem *)GetItem(GetOrderByUnitID(uid)); UnitFeedDog(uid); } if (pItem == NULL) { vLog(LOG_DEBUG, "PLL RECV - response from unknown slave %i\n", address); return; } pIEC101_LinkLayerSecondaryBalanced self = &(pItem->secondaryLinkBalanced); if (fcv) { if (LinkLayerSecondaryBalanced_checkFCB(self, fcb) == FALSE) return; } switch (fc) { case LL_FC_00_RESET_REMOTE_LINK: //vLog(LOG_DEBUG, "SLL - RECV FC 00 - RESET REMOTE LINK\n"); self->expectedFcb = TRUE; //vLog(LOG_DEBUG, "SLL - SEND FC 00 - ACK\n"); if (m_linkLayer.linkLayerParameters.useSingleCharACK) { SendSingleCharCharacter(); } else { SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE); } break; case LL_FC_02_TEST_FUNCTION_FOR_LINK: //vLog(LOG_DEBUG, "SLL - RECV FC 02 - TEST FUNCTION FOR LINK\n"); //vLog(LOG_DEBUG, "SLL - SEND FC 00 - ACK\n"); if (m_linkLayer.linkLayerParameters.useSingleCharACK) { SendSingleCharCharacter(); } else { SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE); } break; case LL_FC_03_USER_DATA_CONFIRMED: //vLog(LOG_DEBUG, "SLL - RECV FC 03 - USER DATA CONFIRMED\n"); if (userDataLength > 0) { if (ApplicationLayer_ReceivedData(pItem, msg, isBroadcast, userDataStart, userDataLength)) { //vLog(LOG_DEBUG, "SLL - SEND FC 00 - ACK\n"); if (m_linkLayer.linkLayerParameters.useSingleCharACK) { SendSingleCharCharacter(); } else { SendFixedFrame(LL_FC_00_ACK, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE); } } } break; case LL_FC_04_USER_DATA_NO_REPLY: //vLog(LOG_DEBUG, "SLL -FC 04 - USER DATA NO REPLY\n"); if (userDataLength > 0) { ApplicationLayer_ReceivedData(pItem, msg, isBroadcast, userDataStart, userDataLength); } break; case LL_FC_09_REQUEST_LINK_STATUS: //vLog(LOG_DEBUG, "SLL - RECV FC 09 - REQUEST LINK STATUS"); //vLog(LOG_DEBUG, "SLL - SEND FC 11 - STATUS OF LINK\n"); SendFixedFrame(LL_FC_11_STATUS_OF_LINK_OR_ACCESS_DEMAND, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE); break; default: //vLog(LOG_DEBUG, "SLL - UNEXPECTED LINK LAYER MESSAGE"); //vLog(LOG_DEBUG, "SLL - SEND FC 15 - SERVICE NOT IMPLEMENTED\n"); SendFixedFrame(LL_FC_15_SERVICE_NOT_IMPLEMENTED, pItem->address, FALSE, m_linkLayer.dir, FALSE, FALSE); break; } }