327 lines
28 KiB
C
327 lines
28 KiB
C
/*
|
||
* 104召唤共用引擎:具体种类规则由GeneralInterrogation/CounterInterrogation创建入口提供。
|
||
* 总召旧入口Create保持兼容;计数量召唤入口见IEC104_CounterInterrogation.h。
|
||
* 借用一个Slave,不创建socket/线程,不保存业务回调;动作入口仅同步借用回调执行一次。
|
||
* 所有接口在同一事件循环串行调用,动作回调不得重入引擎。
|
||
* 先把Slave通知按FIFO交给Handle_Event,读空后Process,再NextEvent并显式应答。
|
||
* 事件来源和会话状态由Slave公共接口校验;本模块维护召唤阶段、业务期限和应用事件。
|
||
* 退出顺序:Cancel -> 读完业务FINISHED并清理应用资源 -> Destroy -> Destroy Slave。
|
||
*/
|
||
#ifndef IEC104_INTERROGATION_H
|
||
#define IEC104_INTERROGATION_H
|
||
#include "IEC104_Slave.h"
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/* 不透明静态池句柄,只能由Create取得、Destroy释放,不能自行分配、复制对象或free。
|
||
* 销毁成功后停止使用旧句柄;同一实例的全部接口须在所属事件循环中串行调用。 */
|
||
typedef struct IEC104_Interrogation IEC104_Interrogation_t;
|
||
|
||
/* 请求信息随事件按值复制,不暴露可发送的connection。
|
||
* 应用据此选择数据源、构造数据头;IOA、分组成员及遍历状态均由应用维护。
|
||
* 引擎不登记或冻结IOA列表;总召由应用逐批取当前值,计数量读取由应用固定本轮冻结快照。
|
||
* 冻结/复位命令在BEGIN执行应用动作,不进入NEED_DATA。 */
|
||
typedef struct {
|
||
uint64_t generation, receive_serial; /* 原TCP会话代次、接收I帧标识,供应用关联和诊断。 */
|
||
uint64_t station_id; /* 本次选中的注册编号,兼容裸CA模式为0;按编号查找避免同CA替换串站。 */
|
||
uint16_t common_address; /* 实际本站地址;广播65535解析为此地址,应用数据批次须使用同一CA。 */
|
||
uint8_t originator_address; /* 请求的源发地址OA,应答数据须原样保留。 */
|
||
uint8_t qualifier; /* 总召QOI=20..36;计数量RQT=1..5,应用维护分组点表。 */
|
||
bool is_test; /* 请求的TEST标志,数据批次须保持一致。 */
|
||
uint8_t max_objects_per_asdu; /* 1..127,实际另受249字节容量限制。 */
|
||
uint8_t freeze; /* 计数量FRZ:0读取,1冻结,2冻结并复位,3仅复位;总召恒为0。 */
|
||
uint8_t data_cause; /* 数据COT:总召等于QOI,计数量总请求37、分组38..41。 */
|
||
} IEC104_InterrogationRequest_t;
|
||
|
||
/* FINISHED通知应用清理本次游标及业务资源;终结原因不等于网络发送回执。
|
||
* COMPLETED表示结束帧被发送层接手,不表示写完或收到ACK;读取为ACT_TERM,动作命令为ACT_CON。 */
|
||
typedef enum {
|
||
IEC104_INTERROGATION_FINISH_NONE = 0, /* 未终结;BEGIN/NEED_DATA事件也使用此值。 */
|
||
IEC104_INTERROGATION_FINISH_COMPLETED, /* 读取的全部批次和ACT_TERM,或动作命令的ACT_CON已提交。 */
|
||
IEC104_INTERROGATION_FINISH_REJECTED, /* 应用拒绝;否定ACT_CON可能仍在排队。 */
|
||
IEC104_INTERROGATION_FINISH_CANCELLED, /* 应用调用本地Cancel放弃任务。 */
|
||
IEC104_INTERROGATION_FINISH_STOPPED, /* 收到Slave的停用通知,结束本次数据传输。 */
|
||
IEC104_INTERROGATION_FINISH_DISCONNECTED, /* 原TCP会话断开。 */
|
||
IEC104_INTERROGATION_FINISH_CONNECTION_CHANGED, /* 连接代次或当前传输状态已不再适用于任务。 */
|
||
IEC104_INTERROGATION_FINISH_SOURCE_ERROR, /* 应用通过Fail_Request报告数据源准备/取数失败。 */
|
||
IEC104_INTERROGATION_FINISH_SEND_ERROR, /* 提交应答失败且不是可等待的发送容量不足。 */
|
||
IEC104_INTERROGATION_FINISH_OVERLOAD, /* 兼容保留;满槽现在拒绝/丢弃新请求,不终结已有任务。 */
|
||
IEC104_INTERROGATION_FINISH_INVALID_REQUEST, /* 保留枚举值兼容;畸形新请求不再终结已有总召。 */
|
||
IEC104_INTERROGATION_FINISH_SERVICE_ERROR, /* 服务查询、内部状态或构造应答失败。 */
|
||
IEC104_INTERROGATION_FINISH_DEACTIVATED, /* 主站COT=8撤销;COT=9可能仍待发送。 */
|
||
IEC104_INTERROGATION_FINISH_BEGIN_TIMEOUT, /* BEGIN入队后未在期限内得到应用决定。 */
|
||
IEC104_INTERROGATION_FINISH_DATA_TIMEOUT, /* NEED_DATA入队后未在期限内得到应用应答。 */
|
||
IEC104_INTERROGATION_FINISH_TOTAL_TIMEOUT /* BEGIN生成至ACT_TERM提交超过执行整体期限。 */
|
||
} IEC104_InterrogationFinishReason_t;
|
||
|
||
typedef enum {
|
||
IEC104_INTERROGATION_BEGIN = 1, /* 检查数据源并接受/拒绝;取数游标可延至首个NEED_DATA建立。 */
|
||
IEC104_INTERROGATION_NEED_DATA, /* 应用选择本批IOA并读取当前值/品质;暂未就绪时保存事件。 */
|
||
IEC104_INTERROGATION_FINISHED /* 清理游标及业务资源,无需应答。 */
|
||
} IEC104_InterrogationEventType_t;
|
||
|
||
/* 纯值事件,无借用指针和自引用,可赋值、排入应用队列、保存到后续循环。
|
||
* 字段只读,应答时原样传回;实例/请求/批次标识用于拒绝迟到和重复应答。
|
||
* 每个已取出的BEGIN恰好配对一次FINISHED,取消也不丢失终结通知。
|
||
* BEGIN尚未取出便取消时移除BEGIN,不产生FINISHED(应用尚未建立资源)。
|
||
* 取消移除队列中的NEED_DATA;已取出的旧事件仍可读取,应答返回STALE。 */
|
||
typedef struct {
|
||
IEC104_InterrogationEventType_t type; /* 决定调用Reply_Begin、提交数据或只清理资源。 */
|
||
uint64_t instance_id, request_id; /* 实例及请求身份;必须与事件其他字段一起原样传回。 */
|
||
IEC104_InterrogationRequest_t request; /* 原激活请求的元数据,FINISHED仍保留此副本。 */
|
||
size_t batch_index, objects_submitted; /* 已被发送层接手的批次/对象数;首个NEED_DATA的批次号为0。 */
|
||
IEC104_InterrogationFinishReason_t reason; /* 仅FINISHED有意义。 */
|
||
} IEC104_InterrogationEvent_t;
|
||
|
||
/* 多站广播的调用方存储:每个目标站一项,不保存点值、ASDU或独立发送任务。
|
||
* config借用整个数组至Destroy,期间地址稳定、不得读写或与其他实例重叠。
|
||
* 模块初始化/清理内部字段,不要求调用方逐项初始化。 */
|
||
typedef struct {
|
||
IEC104_Station_t *_station; /* 本轮持有的原节点引用,直到整轮终结事件读完才释放。 */
|
||
uint64_t _request_id, _started_ms; /* 每站独立的请求身份和BEGIN时刻,切换当前站不丢失。 */
|
||
size_t _batch_index, _objects_submitted; /* 已提交进度,不是应用的IOA遍历游标。 */
|
||
uint8_t _state, _flags, _reason; /* 协议阶段、事件交付/撤销标志、终结原因,仅库内部使用。 */
|
||
} IEC104_InterrogationStationState_t;
|
||
|
||
/* Create复制此配置;创建后修改调用方对象不会改变已有实例,指向的广播数组仍为借用。
|
||
* 接受/取数期限从事件入队开始,包含应用尚未NextEvent读取它的时间。 */
|
||
typedef struct {
|
||
uint16_t common_address; /* station为NULL时的兼容站地址1..65534;绑定站点时从节点取得CA并忽略此值。 */
|
||
uint8_t max_objects_per_asdu; /* 每批1..127个对象,配置无业务函数指针。 */
|
||
bool use_station_registry; /* true按请求CA查共用站点表,广播分三阶段;station须NULL,common_address忽略。 */
|
||
uint32_t begin_timeout_ms; /* BEGIN入队至Reply_Begin/Fail_Request,默认15000ms。 */
|
||
uint32_t data_timeout_ms; /* NEED_DATA至首次有效批次/Complete/Fail,默认15000ms;发送WAIT后的重试不计。 */
|
||
uint32_t total_timeout_ms; /* 读取:每站BEGIN至ACT_TERM提交;动作:BEGIN至应用接受。默认0禁用。 */
|
||
/* 上述期限是业务策略,独立于104链路t0..t3;每项0表示禁用该项。
|
||
* BEGIN尚未生成时不计业务期限;START/CONFIRM超时转为否定ACT_CON并保留连接。
|
||
* 动作命令接受后的CONFIRM不再受业务期限约束,避免执行成功后被改发否定;连接期限仍生效。
|
||
* 肯定ACT_CON被发送层接手后,DATA/TERMINATE超时关闭原连接,不发送成功ACT_TERM。
|
||
* 同一执行任务的总期限与阶段期限同时到点时优先报告总超时。 */
|
||
IEC104_Station_t *station; /* 兼容固定站绑定:Create持有至Destroy;删除后不接新请求,已接受任务可完成。 */
|
||
IEC104_InterrogationStationState_t *broadcast_states; /* 调用方独占提供的状态数组,寿命覆盖实例。 */
|
||
size_t broadcast_capacity; /* 数组项数,即单轮多站广播能接纳的目标数,不是注册站数上限。 */
|
||
/* 默认NULL/0。广播涉及多个站时,容量须覆盖请求时的全部注册站,否则整轮否定确认。
|
||
* 单站/定向总召不需要数组。容量由应用决定,不限制注册站数;数组含已确认目标及终结记录。 */
|
||
} IEC104_InterrogationConfig_t;
|
||
|
||
/* 输入Slave通知的处理结果;其他类型I帧返回IGNORED,交后续业务处理。 */
|
||
typedef enum {
|
||
IEC104_INTERROGATION_EVENT_ERROR = -1, /* 参数、复制、关闭连接等处理失败。 */
|
||
IEC104_INTERROGATION_EVENT_IGNORED = 0, /* 本模块未接手,可转交其他业务处理器。 */
|
||
IEC104_INTERROGATION_EVENT_HANDLED = 1 /* 已处理,含畸形/满槽丢弃;不保证应用接受或已发送响应。 */
|
||
} IEC104_InterrogationEventResult_t;
|
||
|
||
typedef enum {
|
||
IEC104_INTERROGATION_NEXT_ERROR = -1, /* 非法句柄或NULL输出。 */
|
||
IEC104_INTERROGATION_NEXT_EMPTY = 0, /* 当前无业务事件,不代表总召已经结束。 */
|
||
IEC104_INTERROGATION_NEXT_READY = 1 /* 已复制并移除最早事件,输出可独立保存。 */
|
||
} IEC104_InterrogationNextResult_t;
|
||
|
||
/* 显式比较,不能按真假判断。
|
||
* OK:交互已消费;Submit_Batch已交发送层并固定顺序,其余应答由Process推进;不表示写完/ACK。
|
||
* WAIT:先处理Slave通知并推进网络;Submit_Batch还可能因发送背压WAIT,不缓存本次原文。
|
||
* 保留同一事件,批次游标不动,下次重读当前值组包。首次有效批次的发送WAIT结束本批取数计时。
|
||
* STALE:实例/请求/批次/类型不匹配、未取出、已应答、已取消或已超时;不要重试旧事件。
|
||
* ERROR:参数/批次/服务查询错误,不消费交互,可修正再提交。
|
||
* NEED_DATA阶段Fail_Request例外:即使关闭连接失败,仍取消并交付FINISHED,不能重试。 */
|
||
typedef enum {
|
||
IEC104_INTERROGATION_REPLY_STALE = -2,
|
||
IEC104_INTERROGATION_REPLY_ERROR = -1,
|
||
IEC104_INTERROGATION_REPLY_WAIT = 0,
|
||
IEC104_INTERROGATION_REPLY_OK = 1
|
||
} IEC104_InterrogationReplyResult_t;
|
||
|
||
/* 优先描述唯一未终结总召的诊断阶段;仅有应答时REPLY,无任务时IDLE。
|
||
* 阶段由模块推进,应用通过事件交互,不直接修改。 */
|
||
typedef enum {
|
||
IEC104_INTERROGATION_IDLE, /* 没有协议任务。 */
|
||
IEC104_INTERROGATION_REPLY, /* 等待提交单帧确认(含撤销确认)或错误应答。 */
|
||
IEC104_INTERROGATION_START, /* 等事件空位生成BEGIN,或等待应用接受/拒绝;两者均占用总召资格。 */
|
||
IEC104_INTERROGATION_CONFIRM, /* 应用已接受,等待提交肯定ACT_CON。 */
|
||
IEC104_INTERROGATION_DATA, /* 生成NEED_DATA,等待应用取值并尝试直接提交。 */
|
||
IEC104_INTERROGATION_TERMINATE, /* 应用声明数据结束,等待提交ACT_TERM。 */
|
||
IEC104_INTERROGATION_FINISHING /* 多站广播网络任务已结束,等NextEvent读完各站FINISHED后归还状态区。 */
|
||
} IEC104_InterrogationPhase_t;
|
||
|
||
/* Get_Status返回的独立副本;计数自Create起累计,Cancel和重连不清零。
|
||
* active/waiting反映最近已处理的通知/推进结果;events_pending及need_process在查询时计算。 */
|
||
typedef struct {
|
||
uint64_t generation; /* 已消费的连接代次,断线后0。 */
|
||
bool active; /* 已消费ACTIVATED且未停用,不是socket实时状态。 */
|
||
bool gi_pending; /* 总召网络流程尚未终结;FINISHING虽为false,读完终结事件前仍拒绝新激活。 */
|
||
bool waiting; /* 存在发送、应用或事件空位等待;总召等应用时仍可推进单帧应答。 */
|
||
bool application_waiting; /* 等待应用首次有效应答,包含事件尚未取出;发送背压另见data_send_waiting。 */
|
||
bool data_send_waiting; /* 有效批次提交曾遇发送WAIT;应用仍持有NEED_DATA,网络推进后重取再试。 */
|
||
bool events_pending; /* 当前Slave FIFO未空,须先处理网络通知。 */
|
||
bool need_process; /* 有本地工作/到期/会话失效待处理,应立即Process;未读Slave通知优先。 */
|
||
bool timer_active; /* 存在启用的业务期限;为false时timeout_remaining_ms无意义。 */
|
||
uint32_t timeout_remaining_ms; /* 最近期限距当前单调时钟的毫秒数;0表示应立即Process。 */
|
||
unsigned pending_requests, pending_events; /* 任务数含FINISHING;事件数含状态区中待交付的FINISHED,不含预留。 */
|
||
IEC104_InterrogationPhase_t phase; /* 当前站阶段;收尾为FINISHING,仅有应答为REPLY,无任务为IDLE。 */
|
||
size_t batch_index, objects_submitted; /* 活动总召已提交的批次/对象数;仅有应答时取最早应答保留的进度。 */
|
||
unsigned long submitted, gi_submitted; /* 接手ASDU数、完成协议提交的召唤数;动作命令以ACT_CON计。 */
|
||
unsigned long waits, cancelled, rejected, overloads;
|
||
/* waits统计发送层返回WAIT;cancelled统计取消的协议任务(含单帧应答);
|
||
* rejected统计校验拒绝(含无法应答的畸形请求)/总召忙/应用/确认前失败/容量拒绝;
|
||
* overloads含任务槽满或广播状态区不足。 */
|
||
unsigned long negative_submitted, dropped_requests; /* 已提交否定应答数、无法保存或提交而丢弃的新请求数。 */
|
||
unsigned long deactivated, timeouts; /* 成功匹配的主站撤销、执行阶段业务超时次数。 */
|
||
IEC104_InterrogationFinishReason_t last_finish_reason; /* 最近合法总召的终结原因,含BEGIN尚未交付的任务。 */
|
||
} IEC104_InterrogationStatus_t;
|
||
|
||
/* 初始化调用方的可写配置:station=NULL、兼容CA=1,broadcast_states=NULL、broadcast_capacity=0,每批最多127个对象,
|
||
* 接受/取数期限各15000ms,执行整体期限为0(禁用);NULL无操作。 */
|
||
void IEC104_Interrogation_Config_Default(IEC104_InterrogationConfig_t *config);
|
||
|
||
/* 复制配置,借用Slave;同一Slave的同一种类只能绑定一个实例,在消费Slave通知前创建。
|
||
* slave须保持有效直到本实例Destroy;config在返回后可释放或复用。
|
||
* station非NULL时校验其属于本Slave并占用节点,本站CA只取节点值;创建失败不泄漏引用。
|
||
* use_station_registry开启时按CA选站;广播共用一个任务,依次完成全部确认、各站数据、全部终止。
|
||
* 各站独立BEGIN/FINISHED和request_id;多目标广播须有足够broadcast_states,容量不足整轮否定。
|
||
* 接收时持有目标节点引用;尚未选入BEGIN便删除的站跳过,已经选中的站持原引用完成。
|
||
* 新增/替代节点不加入本轮;已确认站即使尚未取数或被删除,也必须完成或明确终结。
|
||
* BEGIN后需跨循环保留context的应用须按station_id查节点并Acquire,FINISHED清理后Release。
|
||
* 兼容模式use_station_registry=false保留单CA或固定station行为。
|
||
* NULL:参数非法、重复绑定、状态区重叠、池满或实例编号耗尽;无网络操作,无malloc。
|
||
* 编译.c可覆盖IEC104_INTERROGATION_CAPACITY(默认为TCP实例容量的两倍)、
|
||
* IEC104_INTERROGATION_TASK_CAPACITY(默认4)、IEC104_INTERROGATION_EVENT_CAPACITY
|
||
* (默认4,最小2)。任务池容纳至多一个总召及短应答,不是多个总召的等待队列。
|
||
* 单目标流程在FIFO预留FINISHED;多目标用每站状态区保留终结记录,NextEvent按空位交付。 */
|
||
IEC104_Interrogation_t *IEC104_Interrogation_Create(IEC104_Slave_t *slave,
|
||
const IEC104_InterrogationConfig_t *config);
|
||
|
||
/* 协议任务和业务事件均为空才释放槽,否则false并保持原状态。
|
||
* 先Cancel,再NextEvent读完FINISHED并清理应用资源,最后Destroy;成功后句柄失效。 */
|
||
bool IEC104_Interrogation_Destroy(IEC104_Interrogation_t *self);
|
||
|
||
/* 放弃未提交任务;保留已交付BEGIN的FINISHED(CANCELLED),移除未交付工作事件。
|
||
* 不撤回已接手帧、不补发ACT_TERM,也不回滚已执行的冻结/复位;非法句柄无操作。 */
|
||
void IEC104_Interrogation_Cancel(IEC104_Interrogation_t *self);
|
||
|
||
/* 按FIFO接收本Slave的每个通知,不消费Slave FIFO,不保存调用方指针。
|
||
* 下列QOI和撤销约定针对总召;计数量的RQT/FRZ规则见CounterInterrogation.h。
|
||
* 同时使用两个实例时,连接/启停通知交给两边;I帧仅在当前实例IGNORED后转交下一个。
|
||
* 总召须SQ=0、一个对象、COT=6或8、P/N=0、CA为本站或65535、IOA=0、QOI=20..36。
|
||
* 广播常量为IEC104_CA_BROADCAST;应用事件、确认、数据、否定应答及终止均使用实际本站CA。
|
||
* 原输入事件不修改;每次选站设置应答CA,同一站发送及重试沿用该地址。
|
||
* 空闲时保存一个COT=6激活并进入START;从保存起至终结,拒绝所有后续激活,不区分QOI。
|
||
* 忙或QOI/P/N非法时回否定ACT_CON;保留已有请求的QOI/OA/TEST、工作事件及数据进度。
|
||
* 单帧应答在无未读Slave通知、原会话有效且无更早REPLY时尝试立即提交,未接手再保存。
|
||
* 多站广播应答先保存一个遍历任务,再由Process逐站提交;无槽时整体丢新请求并计数。
|
||
* 满槽时尝试否定确认;无法安全提交/保存则仅丢新请求并累计dropped_requests,不断链。
|
||
* 撤销COT=8不受忙拒绝限制,按连接代次、实际站CA、OA、TEST、QOI匹配当前总召;
|
||
* 定向撤销停止匹配站,包括已确认但尚未取数/等待终止的站;其他站继续。
|
||
* 尚未选入BEGIN的站没有可撤销的活动事务。广播撤销停止整轮,按各活动站CA确认。
|
||
* 已完成/已拒绝站不补发撤销确认;无注册站且无匹配事务时,广播请求回复未知CA。
|
||
* 为已交付BEGIN保留FINISHED(DEACTIVATED),按单帧应答规则提交肯定COT=9;
|
||
* 不匹配/非法QOI或P/N回否定COT=9。
|
||
* 撤销无需应用再次批准;应用收到FINISHED后停止采样并释放本次资源。
|
||
* 匹配撤销复用原任务槽,并将确认排到单帧应答队尾;满池也不需要额外槽。
|
||
* 一组撤销确认尚未提交完时,重叠的新撤销按未匹配拒绝,不覆盖已有确认。
|
||
* COT/CA/IOA错误回45/46/47;撤销不撤回发送层已接手的帧,不补发ACT_TERM。
|
||
* 尚未生成/交付BEGIN的撤销不产生FINISHED;已有BEGIN交付才通知应用清理。
|
||
* 先安全读取Type,非100返回IGNORED;公共视图不可用也返回IGNORED,由公共入口处理。
|
||
* Type100仅一个对象且IOA/QOI完整时,SQ=1或多余尾字节回否定7/9(COT/CA/IOA错误优先45/46/47)。
|
||
* 此应答规范为10字节、VSQ=1,保留OA/TEST/IOA/QOI;绝不据规范化副本执行激活或撤销。
|
||
* 零对象/多对象等无法可靠对应请求的布局错误计入rejected并返回HANDLED,不生成应答。
|
||
* 上述请求错误不取消已有总召、不刷新其期限;基础帧错误仍由Receiver/连接层处理。
|
||
* STOPDT/断线取消总召及待发短应答并保留终结事件;不替其他业务回答UNKNOWN_TYPE。 */
|
||
IEC104_InterrogationEventResult_t IEC104_Interrogation_Handle_Event(
|
||
IEC104_Interrogation_t *self, const IEC104_SlaveEvent_t *event);
|
||
|
||
/* 自动推进当前就绪任务,不等待应用或网络;调用方不需要指定处理步数。
|
||
* Slave FIFO未空仅设置events_pending。顺序:START -> BEGIN -> 应用接受 -> ACT_CON ->
|
||
* NEED_DATA/提交批次(可重复)-> 应用Complete_Data -> ACT_TERM -> FINISHED。
|
||
* 动作命令例外:ACT_CON被发送层接手后直接FINISHED,不生成NEED_DATA或ACT_TERM。
|
||
* 多目标广播先完成所有站的BEGIN/ACT_CON,再逐站NEED_DATA,全部数据结束后才逐站ACT_TERM。
|
||
* 工作事件只交付一次;应用暂未就绪可保存事件,后续Process不会重复请求。
|
||
* 单帧应答保持FIFO,可在总召等待应用/业务事件空位时提交;双方可推进时先应答再总召轮转,
|
||
* 继续处理当前就绪任务,直至空闲、所有任务等待应用/事件空位,或发送返回WAIT。
|
||
* 每个站的REPLY成功后继续广播或释放任务;不保存后续主站新发来的总召激活。
|
||
* 每轮最多推进2倍任务容量步,广播余下站点由need_process提示继续,避免大量站点独占事件循环。
|
||
* 应答可穿插总召各批次,本次总召自身ACT_CON/数据/ACT_TERM顺序不变。
|
||
* 确认、终止和短应答沿原connection走HIGH,WAIT保留请求;DATA只生成NEED_DATA,
|
||
* 由应用Submit_Batch直接提交,OK才增加批次/对象计数,WAIT须重新取值后重试。
|
||
* WAIT让出本轮,下轮优先检查单帧应答;已被发送层接手的帧不被后到应答越过。
|
||
* 发送ERROR时复核原连接;正常STOP拒绝且通知未读时仅置events_pending并让出,由通知终结为STOPPED。
|
||
* 不因此增加waits、重置期限或撤销已接手帧;其他ERROR及FATAL仍按SEND_ERROR处理。
|
||
* 使用平台单调时钟检查期限,先处理Slave通知;START/CONFIRM超时转为否定REPLY并继续调度,
|
||
* 肯定ACT_CON提交后的DATA/TERMINATE超时关闭原连接;FINISHED保留具体超时原因。
|
||
* 执行总期限默认禁用,启用后按每站BEGIN独立开始,含等待其他站完成的时间。
|
||
* 已确认站总期限到点即关闭原连接;此前等待事件空位不计期限,应及时读FINISHED。
|
||
* 网络推进并读空Slave通知后须Process重试,即使need_process为false;发送WAIT不自行触发空转。
|
||
* 数据WAIT还须重试应用持有的NEED_DATA;本函数不会代为重读或重发数据。
|
||
* 本地应答/事件消费后重查Get_Status,need_process为true不得休眠;并用剩余期限限制等待时长。
|
||
* true本轮正常(可等待/取消/超时);false参数、组包、关闭连接或服务查询失败。 */
|
||
bool IEC104_Interrogation_Process(IEC104_Interrogation_t *self);
|
||
|
||
/* 取最早业务事件;event须为非NULL输出,只有READY写入,EMPTY/ERROR保持输出不变。
|
||
* READY后工作事件才允许应答;FINISHED仅用于应用清理,不调用应答接口。
|
||
* 多站终结记录超过FIFO容量时,本函数按需补入,连续NextEvent即可读完,无需Process。
|
||
* 最后一条FINISHED出队后归还广播状态区和节点引用;应用持有的节点引用仍须自行Release。
|
||
* 事件是可保存的纯值副本,本函数无网络操作,也不自动执行应用代码。 */
|
||
IEC104_InterrogationNextResult_t IEC104_Interrogation_NextEvent(
|
||
IEC104_Interrogation_t *self, IEC104_InterrogationEvent_t *event);
|
||
|
||
/* 应答已取出的BEGIN。true允许提交ACT_CON;false立即FINISHED(REJECTED),
|
||
* 并排队否定ACT_CON;不支持的分组可在这里拒绝。应用按instance_id/request_id管理遍历状态。
|
||
* 接受前检查数据源及业务资源;无需登记完整IOA列表或预先采样全部数据。
|
||
* event须原样传回;OK表示接受/拒绝决定已消费,实际ACT_CON由后续Process提交。
|
||
* 所有应答接口也检查期限,不能通过迟到应答绕过超时;Slave通知未读空时仍优先返回WAIT。
|
||
* 计数量FRZ!=0建议使用CounterInterrogation_Execute_Begin,在校验通过后才执行副作用。
|
||
* 不要在本函数之前无条件执行冻结/复位:WAIT会重试,STALE也不能撤销已经发生的动作。
|
||
* 动作命令接受后停止业务期限,保留确认等待;TEST动作始终拒绝。 */
|
||
IEC104_InterrogationReplyResult_t IEC104_Interrogation_Reply_Begin(
|
||
IEC104_Interrogation_t *self, const IEC104_InterrogationEvent_t *event, bool accept);
|
||
|
||
/* 应答已取出的NEED_DATA,验证非空ASDU后当场尝试不排队提交。
|
||
* OK表示已复制进发送缓冲并固定发送顺序,当场累计批次/对象数;输入缓冲及参数可立即复用。
|
||
* WAIT不接手、不推进游标;应用保存同一事件,网络推进后重新组包,不保留旧编码等待重发。
|
||
* 总召可重取当前值;计数量必须保持本轮冻结版本,值、序号、品质及可选时标一起固定。
|
||
* 首次有效批次发生发送WAIT后停止本批取数计时;下一NEED_DATA重新计时,显式整体期限仍有效。
|
||
* 参数须2/2/3,COT=request.data_cause、P/N=0、CA=本事件目标站地址、OA/TEST与事件相同。
|
||
* 广播请求的数据CA也不能使用65535;对象数不超配置。
|
||
* 总召接受Type 1/3/5/7/9/11/13/20/21,SQ=0/1均可;计数量读取接受Type 15(SQ=0/1)、37(SQ=0)。
|
||
* IOA及分组归属由调用方决定;库校验编码布局,不规定点表或强制固定IOA集合。
|
||
* 总召建议每次NEED_DATA读取当前值/品质,整轮不保证同一采样时刻;计数量由应用保证快照一致。
|
||
* 点值更新及突发发布、总召取值及本调用须由同一发布流程串行协调,不能迟交旧事件。
|
||
* HIGH/NORMAL有待发数据时总召退让;持续事件拥塞可能延后总召。OK后不再重新取值或重复提交。
|
||
* 发送ERROR若确认为原连接正常STOP拒绝且有未读通知,返回WAIT并保留事件,先处理DEACTIVATED。
|
||
* 此等待不设置data_send_waiting、不停止取数计时;通知处理后旧事件STALE,FINISHED为STOPPED。
|
||
* 其他发送ERROR/FATAL取消请求并返回STALE;FATAL可能已发出字节,不允许重试旧批次。
|
||
* 非法批次ERROR,保留NEED_DATA供修正,不断线;无法继续则Fail_Request。
|
||
* 应用使用Asdu_Create/InformationObject_Create/Add自行构造业务ASDU。 */
|
||
IEC104_InterrogationReplyResult_t IEC104_Interrogation_Submit_Batch(
|
||
IEC104_Interrogation_t *self, const IEC104_InterrogationEvent_t *event,
|
||
const IEC60870_Asdu_t *asdu);
|
||
|
||
/* 应答已取出的NEED_DATA,声明数据耗尽;不以空ASDU作为结束标记。
|
||
* OK后本请求不再取数,可归还其取数游标;多目标广播继续下一站数据,全部结束后才发终止。
|
||
* Process提交本站ACT_TERM成功后才交付FINISHED(COMPLETED)。 */
|
||
IEC104_InterrogationReplyResult_t IEC104_Interrogation_Complete_Data(
|
||
IEC104_Interrogation_t *self, const IEC104_InterrogationEvent_t *event);
|
||
|
||
/* 应答已取出的BEGIN/NEED_DATA,报告数据源失败,两者均交付FINISHED(SOURCE_ERROR)。
|
||
* BEGIN阶段复用原槽保存否定ACT_CON,保留连接和其他任务;OK不表示否定确认已发送,须继续Process。
|
||
* NEED_DATA阶段肯定ACT_CON已经提交:关闭原连接并取消任务,不发送成功终止,不影响后来新代次。
|
||
* 检查通过后即终结交互;即使NEED_DATA阶段关闭失败返回ERROR,任务仍已取消,不能重试。 */
|
||
IEC104_InterrogationReplyResult_t IEC104_Interrogation_Fail_Request(
|
||
IEC104_Interrogation_t *self, const IEC104_InterrogationEvent_t *event);
|
||
|
||
/* 取得独立状态副本,实时查询Slave通知、可推进任务和最近期限;不消费事件或触发I/O/超时。
|
||
* need_process表示无需等新网络事件就应尝试推进,不保证发送接手,也不是waiting的反值。
|
||
* 生成工作事件有空位、应答接手后可提交下一帧、业务期限到期时置位;Slave通知未读空时不置位。
|
||
* 当前帧提交WAIT后停止本地续跑,网络推进后仍须调用Process重试;不能仅凭本标志决定是否处理网络进展。
|
||
* data_send_waiting时应用仍须在网络推进后重取并重试保留的NEED_DATA,不能等新事件或need_process置位。
|
||
* pending_events非零先消费业务事件;释放空位或完成应答后须重查,不能沿用旧状态休眠。
|
||
* timer_active时,调用方等待时长不得超过timeout_remaining_ms;false时不限制等待。
|
||
* 返回false为非法句柄/NULL,输出保持不变。 */
|
||
bool IEC104_Interrogation_Get_Status(const IEC104_Interrogation_t *self,
|
||
IEC104_InterrogationStatus_t *status);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif /* IEC104_INTERROGATION_H */
|