Files
STM32F4-Base/IEC60870-Slave/104/business/IEC104_CounterInterrogation.c
T
STF 7596f3371a
CI / L0 静态门禁 (pre-commit) (push) Failing after 44s
CI / L0.5 主机侧单测 (MSVC) (push) Failing after 42s
补充总召唤的广播地址,电度召唤+时钟同步业务的实现
2026-10-29 03:20:19 -07:00

59 lines
3.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 104计数量种类规则:解析C_CI_NA_1的QCC,限定RQT和读取数据类型,选择完成方式。
* 规则函数不保存状态、不访问网络;计数器存储及冻结/复位由应用提供。
* 创建和动作入口只委托共用引擎,避免另建一套任务、广播、期限及取消流程。
*/
#include "IEC104_CounterInterrogation.h"
#include "IEC104_Interrogation_Internal.h"
/* 从首对象取IOA和QCC;对象层已将低6位RQT与高2位FRZ拆开。
* 这里只解析,不校验是否支持该分组;失败时不写调用方的输出。 */
static bool Counter_Decode(const IEC60870_AsduInfo_t *info, uint32_t *ioa, uint8_t *qualifier, uint8_t *freeze)
{
IEC60870_CounterInterrogationCommand_t command;
if (IEC60870_Asdu_Get_Element(info, 0U, &command, sizeof(command)) != IEC60870_ASDU_OK) { return false; }
*ioa = command.object.ioa;
*qualifier = command.qualifier;
*freeze = command.freeze;
return true;
}
/* RQT=1..4为分组,5为总请求;0未用、6..63保留。具体分组是否配置由应用在BEGIN决定。 */
static bool Counter_Qualifier_Valid(uint8_t qualifier) { return qualifier >= 1U && qualifier <= 5U; }
/* 引擎准入后使用:总请求的数据COT为37,第1..4组依次为38..41。 */
static uint8_t Counter_Data_Cause(uint8_t qualifier)
{
return (uint8_t)(qualifier == 5U ? IEC60870_ASDU_COT_COUNTER_INTERROGATION :
IEC60870_ASDU_COT_COUNTER_INTERROGATION + qualifier);
}
/* 只有读取存在数据阶段;冻结/复位在肯定确认提交后直接完成。 */
static bool Counter_Has_Data(uint8_t freeze) { return freeze == 0U; }
/* 读取接受无时标Type15和CP56时标Type37;Type37仅SQ=0,Type16不用于104。
* 报文完整布局、对象数和头部一致性仍由共用引擎及ASDU层检查。 */
static bool Counter_Data_Allowed(const IEC60870_AsduInfo_t *info, uint8_t freeze)
{
return freeze == 0U && (info->type_id == IEC60870_ASDU_M_IT_NA_1 ||
(info->type_id == IEC60870_ASDU_M_IT_TB_1 && info->is_sequence == 0U));
}
/* 只读规则存活至进程结束;has_deactivation=false使COT=8按未知传送原因处理。 */
const IEC104_InterrogationRules_t IEC104_COUNTER_INTERROGATION_RULES = {
IEC60870_ASDU_C_CI_NA_1, false, Counter_Decode, Counter_Qualifier_Valid,
Counter_Data_Cause, Counter_Data_Allowed, Counter_Has_Data
};
/* 用计数量规则创建独立实例;配置、站点引用、重复实例和状态区重叠统一由引擎校验。 */
IEC104_Interrogation_t *IEC104_CounterInterrogation_Create(IEC104_Slave_t *slave,
const IEC104_InterrogationConfig_t *config)
{
return IEC104_Interrogation_Create_With_Rules(slave, config, &IEC104_COUNTER_INTERROGATION_RULES);
}
/* 传入本种类规则作为身份约束,防止误把总召句柄交给动作入口。 */
IEC104_InterrogationReplyResult_t IEC104_CounterInterrogation_Execute_Begin(
IEC104_Interrogation_t *self, const IEC104_InterrogationEvent_t *event,
IEC104_CounterInterrogationAction_t action, void *context)
{
return IEC104_Interrogation_Execute_Action(self, event, &IEC104_COUNTER_INTERROGATION_RULES, action, context);
}