Files
STM32F4-Base/IEC60870-Slave/104/business/IEC104_Command.h
T
STF cd42b4d61d
CI / L0 静态门禁 (pre-commit) (push) Failing after 2m51s
CI / L0.5 主机侧单测 (MSVC) (push) Successful in 18s
添加遥控业务代码
2026-10-30 20:03:19 -07:00

312 lines
24 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.
/*
* 模块:IEC104遥控业务层,单命令45、双命令46,COT=6激活、COT=8撤销。
* 职责:校验请求、选择/执行匹配、撤销、三类期限、原文确认和事务收尾。
* 点表、闭锁、远方/就地策略及实际输出由应用负责;本模块不判定设备操作是否安全。
* 每个Slave至多一个实例,每实例至多一个未释放事务;其他业务仍独立推进。
* 静态存储、无动态分配、不保存回调;所有入口须与Slave在同一事件循环串行调用。
* 只有Accept调用应用动作,先消费事件、再至多调用一次;Handle_Event/Process不调用应用。
* 返回信息由Submit_Return_Info沿原连接提交,确认/返回信息/终止保持顺序。
*
* 接入顺序:先Create,再按Slave通知FIFO分派Handle_Event;每轮Process后读空NextEvent。
* SELECT/EXECUTE事件由Accept或Reject消费;EXECUTE启动成功后,先Report_Result,
* 再逐帧Submit_Return_Info,全部OK后Complete;最终读取FINISHED清理应用资源。
* Report_Result也可晚于返回信息,但必须早于Complete,且设备结果产生后应及时报告。
* WAIT表示本次应用操作尚未接手,保留输入并在读取通知/推进网络后重试;OK不得重复提交。
* 动作/确认/设备结果/FINISHED是不同节点:FINISHED只结束协议事务,不撤销物理输出。
* STOP、断线或Cancel不回滚动作,也不把原连接的返回信息转交到新连接。
*
* 退出顺序:Cancel、读完FINISHED、Slave_Close、读空并分派通知、Destroy,
* 然后由应用移除站点并销毁Slave。模块不负责Slave或应用持有引用的释放。
*/
#ifndef IEC104_COMMAND_H
#define IEC104_COMMAND_H
#include "IEC104_Slave.h"
#ifdef __cplusplus
extern "C" {
#endif
/* 不透明静态池句柄;Destroy成功后失效,不得按值复制内部对象或继续使用旧指针。 */
typedef struct IEC104_Command IEC104_Command_t;
/* 供无副作用的类型常量使用;45..51映射bit0..6,58..64映射bit7..13。
* 范围外为0,不作非法移位。第一版Create只接受45、46两位。 */
#define IEC104_COMMAND_TYPE_BIT(type) ((uint16_t)( \
((type) >= 45U && (type) <= 51U) ? (1U << ((type) - 45U)) : \
(((type) >= 58U && (type) <= 64U) ? (1U << ((type) - 51U)) : 0U)))
/* 创建时复制的配置。期限以Net单调时钟计算,等于边界即到期;
* 0仅禁用时长限制,等待阶段遇到时钟倒退仍终结。选择期限包含确认的发送等待;
* Report_Result之后没有业务期限,应用漏调Complete会一直占用事务槽。 */
typedef struct {
uint16_t type_mask; /* 默认45|46,不能为空,不接受本版不支持的位。 */
uint16_t select_required_mask; /* 默认45|46,必须是type_mask子集;清除对应位允许直接执行。 */
uint32_t select_timeout_ms; /* 选择动作返回至匹配执行受理,默认30000,不得为0。 */
uint32_t decision_timeout_ms; /* 工作事件生成至Accept/Reject,默认15000;0禁用。 */
uint32_t execute_timeout_ms; /* 动作STARTED至Report_Result,默认60000;0禁用。 */
bool send_act_term; /* 成功后发ACT_TERM,默认true;false时失败也不发。 */
bool act_term_on_failure; /* 默认false;true且send_act_term时,启动后报告失败也发COT=10、P/N=0。 */
} IEC104_CommandConfig_t;
/* 可按值保存的请求快照;不含站点/ASDU等借用指针。
* state编码为单命令0/1、双命令1/2,通常对应分/合;具体操作含义由应用点表定义。
* accepted_ms为Handle_Event受理时刻,包含Slave通知排队时间,不是网络接收时间。 */
typedef struct {
uint64_t generation, receive_serial; /* 原连接代次、当前工作请求的I帧接收编号。 */
uint64_t station_id; /* 站点注册身份;同CA重新注册后此值不同。 */
uint16_t common_address; /* 请求公共地址CA,不接受广播65535。 */
uint8_t originator_address, type_id; /* 请求源发地址OA、类型45或46。 */
uint32_t ioa; /* 非零24位信息对象地址;存在性由应用点表确认。 */
bool is_select, selected; /* is_select为S/E;selected表示执行匹配了本事务的选择。 */
uint8_t state, qualifier; /* 原始状态编码、QU(0..31);1短脉冲/2长脉冲/3持续,其他由应用解释。 */
uint64_t accepted_ms; /* 当前工作请求受理时的单调毫秒。 */
} IEC104_CommandRequest_t;
/* SELECT和EXECUTE为待决定工作事件;FINISHED仅通知清理,无需应答。 */
typedef enum {
IEC104_COMMAND_SELECT = 1, /* 应用检查策略并Accept/Reject选择,可执行返校动作。 */
IEC104_COMMAND_EXECUTE, /* 应用Accept/Reject执行;selected区分选择后执行和直接执行。 */
IEC104_COMMAND_FINISHED /* 该事务唯一的结束通知,原因及副作用标志在事件中给出。 */
} IEC104_CommandEventType_t;
/* 首次结束时冻结,后续STOP/Cancel不会覆盖;枚举不表示设备输出已停止。 */
typedef enum {
IEC104_COMMAND_FINISH_NONE = 0, /* 工作事件的占位值,不是FINISHED的正常原因。 */
IEC104_COMMAND_FINISH_COMPLETED, /* 应用报告成功,Complete后最后应答已交接。 */
IEC104_COMMAND_FINISH_EXECUTION_FAILED, /* 输出已启动,但应用报告失败,协议收尾已交接。 */
IEC104_COMMAND_FINISH_REJECTED, /* 应用Reject,或动作返回NOT_STARTED。 */
IEC104_COMMAND_FINISH_ACTION_FAILED, /* 动作返回FAILED/非法值,可能存在副作用。 */
IEC104_COMMAND_FINISH_MISMATCH, /* 选择确认交接后,同一点执行的类型/OA/状态/QU不符。 */
IEC104_COMMAND_FINISH_DEACTIVATED, /* 主站COT=8成功撤销尚未启动执行的事务。 */
IEC104_COMMAND_FINISH_SELECT_TIMEOUT, /* 选择保持到期,释放选择,已交接的确认无法撤回。 */
IEC104_COMMAND_FINISH_DECISION_TIMEOUT, /* 未及时Accept/Reject,模块安排否定确认。 */
IEC104_COMMAND_FINISH_EXECUTE_TIMEOUT, /* 未及时Report_Result;保留肯定确认,不发ACT_TERM。 */
IEC104_COMMAND_FINISH_CANCELLED, /* 本地Cancel结束事务。 */
IEC104_COMMAND_FINISH_STOPPED, /* 原连接STOPDT停用。 */
IEC104_COMMAND_FINISH_DISCONNECTED, /* 原连接断开。 */
IEC104_COMMAND_FINISH_CONNECTION_CHANGED, /* 新连接代次或会话身份已失效。 */
IEC104_COMMAND_FINISH_SEND_ERROR, /* 发送ERROR/FATAL,且不是等待分派正常STOP通知。 */
IEC104_COMMAND_FINISH_SERVICE_ERROR /* Slave服务错误或内部身份/应答资源无法继续使用。 */
} IEC104_CommandFinishReason_t;
/* 事件是可保存的纯值,应答须原样传回;调用方不能用修改request改变实际执行内容。
* 任何工作事件曾被取走的事务,恰好交付一次FINISHED;后者无需应答。
* 应用跨循环持有站点/context或异步动作时,应在首个工作事件时自行Acquire,
* FINISHED清理且物理输出确已结束后Release,不能等读到FINISHED后才申请引用。 */
typedef struct {
IEC104_CommandEventType_t type; /* 决定事件的处理方式,参与身份校验。 */
uint64_t instance_id, transaction_id, event_serial; /* 实例、事务、事件三层身份,原样回传。 */
IEC104_CommandRequest_t request; /* 最后接纳的工作请求,不被撤销/不匹配请求覆盖。 */
IEC104_CommandFinishReason_t reason; /* 仅FINISHED有效;工作事件为NONE。 */
bool select_effect, execute_effect; /* 仅FINISHED有效:对应动作曾STARTED/FAILED,可能需清理。 */
} IEC104_CommandEvent_t;
typedef enum {
IEC104_COMMAND_ACTION_NOT_STARTED = 0, /* 必须保证没有任何副作用。 */
IEC104_COMMAND_ACTION_STARTED, /* 选择生效或输出启动;输出结果另行报告。 */
IEC104_COMMAND_ACTION_FAILED /* 未报告启动成功,但可能已留下副作用。 */
} IEC104_CommandActionResult_t;
/* Accept同步调用的动作,不保存函数/context指针。
* context为应用传入的上下文,可为NULL;request由模块内部快照构造,仅本次调用有效。
* 须短时返回,不得保存request指针、推进Slave或发布上报;设备的异步完成用Report_Result报告。
* 回调期间仅可Get_Status/Get_Transaction;其他修改入口拒绝重入。
* 返回值须准确说明是否有副作用,非法值按FAILED处理,模块不会重试动作。 */
typedef IEC104_CommandActionResult_t (*IEC104_CommandAction_t)(void *context,
const IEC104_CommandRequest_t *request);
typedef enum {
IEC104_COMMAND_RESULT_SUCCEEDED = 1, /* 启动后设备实际执行成功。 */
IEC104_COMMAND_RESULT_FAILED /* 启动后设备实际执行失败,不等同于拒绝启动。 */
} IEC104_CommandResult_t;
typedef enum {
IEC104_COMMAND_REJECT_NEGATIVE = 1, /* 通用策略拒绝,回COT=7、P/N=1。 */
IEC104_COMMAND_REJECT_UNKNOWN_IOA /* 点表不存在此IOA,回COT=47、P/N=1。 */
} IEC104_CommandRejectCause_t;
typedef enum {
IEC104_COMMAND_EVENT_ERROR = -1, /* 参数/来源/服务错误;不能据此重放已产生的动作。 */
IEC104_COMMAND_EVENT_IGNORED = 0, /* 不接手,I帧可继续交后续处理器。 */
IEC104_COMMAND_EVENT_HANDLED = 1 /* 已接手,包括校验拒绝/计数丢弃,不应再走44兜底。 */
} IEC104_CommandEventResult_t;
typedef enum {
IEC104_COMMAND_NEXT_ERROR = -1, /* 句柄/参数/重入或服务错误,输出未写入。 */
IEC104_COMMAND_NEXT_EMPTY = 0, /* 暂无可交付事件,可能须先读Slave通知;输出未写入。 */
IEC104_COMMAND_NEXT_READY = 1 /* 已交付纯值事件,同一事件不会再次出队。 */
} IEC104_CommandNextResult_t;
/* 以下为共同分类;OK究竟消费事件、记录结果还是固定帧序,以各接口说明为准。
* WAIT均未接手本次应用输入;只有Submit_Return_Info的OK直接代表该ASDU帧序已固定。 */
typedef enum {
IEC104_COMMAND_REPLY_STALE = -2, /* 身份/阶段已失效、事件已消费或事务结束,不得重试旧操作。 */
IEC104_COMMAND_REPLY_ERROR = -1, /* 参数/用法/重入或服务错误,检查接口具体前置条件。 */
IEC104_COMMAND_REPLY_WAIT = 0, /* 等待通知/确认/FIFO/网络,保留输入,推进事件循环后重试。 */
IEC104_COMMAND_REPLY_OK = 1 /* 本次操作已接手;不保证设备成功、网络ACK或FINISHED已就绪。 */
} IEC104_CommandReplyResult_t;
typedef enum {
IEC104_COMMAND_PHASE_SELECT_WAIT = 1, /* 等应用决定选择;决定期限从事件生成开始。 */
IEC104_COMMAND_PHASE_SELECTED, /* 已选择,等待匹配执行;选择确认可能仍未交接。 */
IEC104_COMMAND_PHASE_EXECUTE_WAIT, /* 等应用决定执行;已停止选择期限。 */
IEC104_COMMAND_PHASE_EXECUTING, /* 已启动,等待结果/返回信息/Complete/最后应答交接。 */
IEC104_COMMAND_PHASE_ENDED /* 协议已结束,可能仍保留FINISHED或未交接应答。 */
} IEC104_CommandPhase_t;
typedef struct {
bool active; /* 尚未ENDED;不是当前连接是否可操作的保证。 */
IEC104_CommandPhase_t phase; /* 当前协议阶段;结果报告和Complete不另建阶段。 */
bool confirm_submitted; /* 当前工作请求的确认已交给发送层,不表示写完或ACK。 */
/* result_reported:结果已冻结、执行期限停止;completed:已接手Complete,返回阶段关闭;
* term_submitted:ACT_TERM已交接。不配置ACT_TERM时此值一直false,不能据此等事务结束。 */
bool result_reported, completed, term_submitted;
} IEC104_CommandTransactionInfo_t;
/* 累计计数从Create起维护;查询不改变阶段、不做超时转换。
* busy包括待消费FINISHED和未交接的事务应答,不包含独立短应答。
* need_process不因发送WAIT持续置true;每轮网络推进后仍须Process重试。
* 计数用途是诊断,不是可靠账单;各计数可重叠,unsigned long到达上限后自然回绕。 */
typedef struct {
uint64_t generation; /* 当前已分派的连接代次,断线后为0。 */
/* active:模块已处理ACTIVATED且尚未停用,不代替操作前的实时会话校验;
* events_pending:须优先读取Slave通知;need_process:有可立即推进的内部工作;
* timer_active:当前启用了非零时长期限,时钟倒退检查不受此标志限制。 */
bool active, events_pending, need_process, timer_active;
bool busy; /* 唯一事务槽仍占用,此时其他站点/其他IOA也不能新建事务。 */
uint32_t timeout_remaining_ms; /* 当前期限剩余毫秒;无期限/已到期/时钟倒退时为0。 */
/* pending_replies为模块仍持有的应答数,不含发送层已接手的帧和应用保留的返回信息;
* pending_events为尚未取走的工作事件或FINISHED数,本版最多1。 */
unsigned pending_replies, pending_events;
/* accepted:生成的工作事件数(选择后执行计两次);selected/executed:对应STARTED次数;
* completed/execution_failed:成功/失败收尾数;action_failed:动作FAILED结束数。 */
unsigned long accepted, selected, executed, completed, execution_failed, action_failed;
/* submitted:所有已交接帧,含返回信息;negative_submitted:其中P/N=1的应答;
* return_info_submitted:已交接返回信息;waits:发送接口明确返回WAIT的次数。 */
unsigned long submitted, negative_submitted, return_info_submitted, waits;
/* rejected:接收校验/匹配/忙/无选择等拒绝数;app_rejected:Reject或NOT_STARTED数;
* busy_rejected:因事务槽占用拒绝数;overloads:独立应答池满或事务/事件序号耗尽次数;
* dropped_requests:过载丢新数及决定期间同点合法激活的静默丢弃数,后者不计rejected/busy_rejected/overloads;
* cancelled:本地取消、停用、断线、换代、发送/服务错误导致的事务结束总数。 */
unsigned long rejected, app_rejected, busy_rejected, overloads, dropped_requests, cancelled;
/* deactivated:成功撤销数;mismatches:选择失配数;其余三个为各期限导致的结束数。 */
unsigned long deactivated, mismatches, select_timeouts, decision_timeouts, execute_timeouts;
/* 等待阶段发现单调时钟倒退的次数;按到期路径处理,必要确认资源失败时可能改记SERVICE_ERROR。 */
unsigned long clock_errors;
} IEC104_CommandStatus_t;
/* 填写本版默认配置:45/46均要求先选择,决定15s、选择30s、执行60s,成功发ACT_TERM。
* 入参:config为调用方可写结构;NULL时无操作。返回:无;不创建实例或启动计时。 */
void IEC104_Command_Config_Default(IEC104_CommandConfig_t *config);
/* 从静态池创建并绑定一个遥控实例;不自动开启Slave或消费其通知。
* 入参:slave为有效Slave,寿命须覆盖实例;config非NULL,按值复制,调用后可修改原结构。
* 必须在开始消费Slave通知之前创建,以完整接收CONNECTED/ACTIVATED。
* 池容量IEC104_COMMAND_CAPACITY默认等于TCP服务容量;独立应答容量
* IEC104_COMMAND_REPLY_CAPACITY默认4,均在编译模块时通过宏配置。
* 返回:成功为实例句柄;配置/Slave非法、重复绑定、池或实例身份序号耗尽时为NULL。 */
IEC104_Command_t *IEC104_Command_Create(IEC104_Slave_t *slave, const IEC104_CommandConfig_t *config);
/* 归还静态实例槽;不隐式Cancel,不关闭Slave,也不代替应用释放站点引用。
* 入参:self为待销毁实例;事务槽、未读事件及全部独立应答槽必须均空,且不在动作回调内。
* 返回:成功true,句柄随即失效;条件不满足或句柄无效为false,实例保留。 */
bool IEC104_Command_Destroy(IEC104_Command_t *self);
/* 本地结束事务,原因CANCELLED;保留欠应用的FINISHED,清空模块尚持有的全部应答。
* 已交发送层的帧无法撤回;保持会话激活,不回滚物理动作。
* 入参:self为实例;回调中/无效句柄无操作。返回:无;应用仍须读完FINISHED。
* ENDED事务保持首次终结原因,不重复产生FINISHED。 */
void IEC104_Command_Cancel(IEC104_Command_t *self);
/* 接收Slave通知并推进会话/请求状态;不调用应用动作,不保存event或其ASDU借用指针。
* 入参:self为实例;event是所属Slave按FIFO取出的通知,须在通知内容仍有效时分派。
* 全部连接/启停通知必须送达;通知消费不受队列里后续WAIT_EVENTS阻挡。
* 返回:激活且视图可用时接手配置内45/46,当前会话状态通知也为HANDLED;
* 未激活的I帧、视图不可用、未接手类型或旧代次通知为IGNORED;
* 参数、来源、重入或服务错误为ERROR。非法请求可否定或丢新计数,HANDLED不表示已应答。
* SELECT_WAIT/EXECUTE_WAIT期间,同会话、同station_id、同IOA的合法激活静默丢弃,计dropped_requests,
* 返回HANDLED;不比较其他命令字段,不覆盖原请求/事件、不刷新期限。格式校验、撤销及其他点忙拒绝不变。
* 对IGNORED的I帧继续分派后续业务,最后由应用兜底;不要对HANDLED再发44。 */
IEC104_CommandEventResult_t IEC104_Command_Handle_Event(IEC104_Command_t *self,
const IEC104_SlaveEvent_t *event);
/* 推进会话检查、到期转换、发送队首及事务回收;不调用应用代码。
* 入参:self为实例;每轮网络/通知处理后调用,最多推进2*(1+独立应答槽数)步。
* 队首WAIT立即让出,不能用紧循环等待发送;需处理Slave通知/网络后再次调用。
* 返回:true包括无事、背压等待或事务已终结;false为参数/重入或服务错误。
* 发送故障也可能已经转成FINISHED,此函数返回true不代表链路或设备执行成功。 */
bool IEC104_Command_Process(IEC104_Command_t *self);
/* 取出一条应用事件,同一工作事件最多交付一次;取出不等于Accept/Reject消费。
* 入参:self为实例;event非NULL,接收可按值保存的事件副本,仅READY时写入。
* 返回:READY/EMPTY/ERROR,见NextResult;EMPTY也可能表示须先读Slave通知。
* 工作事件交付前检查会话/期限,已有FINISHED可在离线或尚有Slave通知时读取。
* 读取FINISHED可能立即释放模块的站点引用,应用跨循环引用必须此前已自行Acquire。 */
IEC104_CommandNextResult_t IEC104_Command_NextEvent(IEC104_Command_t *self,
IEC104_CommandEvent_t *event);
/* 接受一个已由NextEvent交付的工作事件;先消费身份,再同步至多调用一次action。
* 入参:self为实例;event须原样传回SELECT/EXECUTE事件;context原样转交action,不保存。
* SELECT的action可为NULL,选择生效但select_effect=false;EXECUTE必须提供action。
* 返回:OK只表示工作事件已消费,不表示动作STARTED或确认已交接;动作失败也返回OK。
* WAIT为先读Slave通知,事件未消费;STALE为身份/阶段失效,不得执行输出;
* ERROR为参数/重入/服务或确认资源错误,动作未调用。
* 即使action返回STARTED,提交确认时仍可能结束事务;应用应查询事务并继续接收FINISHED。 */
IEC104_CommandReplyResult_t IEC104_Command_Accept(IEC104_Command_t *self,
const IEC104_CommandEvent_t *event, IEC104_CommandAction_t action, void *context);
/* 不调用动作,消费工作事件,安排否定ACT_CON或未知IOA应答,以REJECTED结束事务。
* 入参:self为实例;event为尚未消费的SELECT/EXECUTE;cause为两个RejectCause之一。
* 返回:OK表示事件已消费且应答已安排,可能已提交或因随后故障被取消;
* WAIT未消费、须先处理通知;STALE身份/阶段已失效;ERROR参数/原因/重入或服务错误。
* FINISHED可先于否定应答交接,读取FINISHED不代表槽已释放。 */
IEC104_CommandReplyResult_t IEC104_Command_Reject(IEC104_Command_t *self,
const IEC104_CommandEvent_t *event, IEC104_CommandRejectCause_t cause);
/* 报告设备结果,结果只记录一次并冻结;不发返回信息,也不隐式Complete。
* 本函数及下列Submit_Return_Info/Complete只接受Accept动作返回STARTED的原EXECUTE事件。
* 入参:self为实例,event为上述事件,result为SUCCEEDED或FAILED。
* 可早于ACT_CON交接;设备完成后应及时报告,OK即停止执行期限,此后发送等待无业务超时。
* 返回:OK已记录;WAIT因未读通知尚未记录;STALE事务结束/超时或事件不符;
* ERROR参数/结果非法、已报告/已Complete、重入或服务错误。 */
IEC104_CommandReplyResult_t IEC104_Command_Report_Result(IEC104_Command_t *self,
const IEC104_CommandEvent_t *event, IEC104_CommandResult_t result);
/* 通过原连接Try路径提交一帧返回信息,不经过可覆盖的NORMAL队列。
* 入参:self为实例;event为启动成功的原EXECUTE;asdu为有效、完整的监视方向ASDU。
* 类型1..21/30..40,至少一对象,COT=11或3,P/N=0,TEST/CA与命令一致;完整校验对象。
* IOA可与命令IOA不同;本版命令TEST恒为0。调用可以早于或晚于Report_Result,但须早于Complete。
* 模块有更早待交应答、确认未交接、网络背压或未读通知时WAIT,不缓存ASDU、也不占排序位置。
* 返回:OK为发送层已接手且帧序固定,可释放/复用ASDU缓冲,不能重交;WAIT须保留ASDU重试;
* ERROR为ASDU/参数/重入/服务错误或Complete后仍待收尾,尚未接手;STALE为事务/事件失效。
* 正常STOP且通知待分派时先WAIT;其他发送ERROR/FATAL终结事务并返回STALE,不可重试旧ASDU。
* 必要的后续变位由应用另按COT=3上报。
* 同一变化勿再经Enqueue_Event重复发布;成功提交不表示对端ACK,断线不会迁移到新连接。 */
IEC104_CommandReplyResult_t IEC104_Command_Submit_Return_Info(IEC104_Command_t *self,
const IEC104_CommandEvent_t *event, const IEC60870_Asdu_t *asdu);
/* 声明本事务不再产生返回信息;按配置安排ACT_TERM并由Process完成后续交接。
* 入参:self为实例,event为启动成功的原EXECUTE;结果须已报告,全部返回信息须已提交OK。
* 允许零帧返回信息;可在确认未交接时调用,模块保持确认先于ACT_TERM的顺序。
* 返回:OK立即关闭返回阶段,不必重调;WAIT为未读通知,尚未接手;
* ERROR为尚未报告结果、仍待收尾时重复调用、参数/重入/服务错误;已结束/事件不符为STALE。
* 不发ACT_TERM时也须等待执行确认交接,之后才产生FINISHED;无发送等待时可能立即结束。
* 失败配置发TERM时P/N=0表示流程结束,不能据此认定设备成功。 */
IEC104_CommandReplyResult_t IEC104_Command_Complete(IEC104_Command_t *self,
const IEC104_CommandEvent_t *event);
/* 只读查询仍占槽的事务,可在动作回调内使用,不做会话推进或期限转换。
* 入参:self为实例;event可为该事务任一已交付的SELECT/EXECUTE/FINISHED;info非NULL。
* 返回:true写入快照,ENDED的active=false;无效参数/身份、槽已回收时false且不修改info。
* 不保留历史事务;刚读出的FINISHED若已触发槽回收,使用它查询也会false。 */
bool IEC104_Command_Get_Transaction(const IEC104_Command_t *self,
const IEC104_CommandEvent_t *event, IEC104_CommandTransactionInfo_t *info);
/* 只读查询会话、调度提示及累计计数,可在动作回调内使用。
* 入参:self为实例,status非NULL接收快照;计算剩余时间但不转换已到期事务。
* 返回:true写入快照;句柄/参数/Slave服务无效时false且不修改status。
* events_pending优先读Slave通知;need_process用于立即调度,timer_active配合剩余时间等待。
* need_process=false不免除每轮网络推进后的Process,也不代表应用没有待重试的ASDU/Complete。 */
bool IEC104_Command_Get_Status(const IEC104_Command_t *self, IEC104_CommandStatus_t *status);
#ifdef __cplusplus
}
#endif
#endif /* IEC104_COMMAND_H */