242 lines
8.5 KiB
C++
242 lines
8.5 KiB
C++
#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;
|
|
}
|
|
}
|