287 lines
21 KiB
C
287 lines
21 KiB
C
/*
|
||
* 104子站业务入口:内部持有TcpServer,NextEvent自动提供ASDU及原连接的发送接口。
|
||
* 服务来自静态池;业务只驱动Slave的事件循环,无需创建TCP对象或手动绑定generation。
|
||
* 仅包含本头文件即可使用服务接口、共用ASDU及IEC60870_MasterConnection_Send_*应答接口。
|
||
*
|
||
* 常规顺序:Create -> Config_Default/Init -> 循环Poll、NextEvent -> Close -> NextEvent读空 -> Destroy。
|
||
* 自有事件循环可用Prepare/应用等待/Process替代Poll;两种方式使用同一套底层调度。
|
||
* 处理I_FRAME前检查asdu_result==IEC60870_ASDU_OK,再通过&event.connection提交业务应答。
|
||
* 主动上报由Enqueue_Event提交;NextEvent不自动执行请求、确认或终止业务。
|
||
* 应用未接手的I帧可在当前事件处理时交给Reject_Request,沿普通应答路径回否定回显。
|
||
*
|
||
* 带error参数的接口允许error为NULL;非NULL时完整填写本次结果、阶段和网络错误。
|
||
* 服务结果须比较IEC104_TCP_OK;事件结果须比较IEC104_TCP_EVENT_READY,不能混用真假判断。
|
||
* 所有操作在同一事件循环线程串行执行,Create/Destroy也须跨服务串行。
|
||
*/
|
||
#ifndef IEC104_SLAVE_H
|
||
#define IEC104_SLAVE_H
|
||
|
||
#include "IEC60870_Slave.h"
|
||
#include "IEC104_TcpTypes.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/* 不透明的子站句柄:完整结构只在IEC104_Slave.c定义,业务不能访问或分配内部成员。
|
||
* Slave与TcpServer是两个分别管理的对象;这里是持有关系,不可把两种句柄互相强转。 */
|
||
typedef struct IEC104_Slave IEC104_Slave_t;
|
||
/* 复用TCP监听和协议配置的值类型,不暴露TcpServer的对象布局或操作接口。 */
|
||
typedef IEC104_TcpServerConfig_t IEC104_SlaveConfig_t;
|
||
|
||
/* 共用逻辑站点:调用方提供零初始化、固定地址的存储,Add后直到Is_Reusable为true均须存活。
|
||
* 字段仅供库维护,禁止直接改写、复制、清零或搬移已注册节点;不拥有context指向的业务数据。
|
||
* 同一Slave按CA唯一,多个Slave可分别注册相同CA;节点本身只能属于一个Slave。
|
||
* 站点不分配socket、发送队列或点表,IOA及点值仍由context对应的应用管理。 */
|
||
typedef struct IEC104_Station {
|
||
struct IEC104_Station *_next; /* 注册顺序链,也保留尚不能回收的已删除节点。 */
|
||
IEC104_Slave_t *_owner; /* 回收后才清NULL;Remove成功不一定立即解除所有权。 */
|
||
void *_context; /* 调用方业务上下文,须与节点一起保留至可复用。 */
|
||
uint64_t _id; /* 本次注册的唯一编号;同CA重新注册得到新编号。 */
|
||
uint32_t _users; /* 显式Acquire引用数;活动快照另由Slave统一保护。 */
|
||
uint16_t _common_address; /* ASDU公共地址,不是点的IOA或连接编号。 */
|
||
bool _registered; /* 是否参与新请求的CA路由,独立于节点是否仍被引用。 */
|
||
} IEC104_Station_t;
|
||
|
||
/* 跨循环遍历的轻量快照,仅固定注册编号上界,不复制点表/点值、不阻止增删。
|
||
* 零初始化并保持地址不变,Begin/End配对;内部字段只读,活动期间禁止复制或搬移。 */
|
||
typedef struct IEC104_StationSnapshot {
|
||
IEC104_Slave_t *_owner; /* Begin至End期间保护所属服务的退役节点。 */
|
||
IEC104_Station_t *_next; /* 下次扫描位置;即使该节点被删除也不能提前回收。 */
|
||
uint64_t _last_id; /* Begin时的注册编号上界,排除后来新增或同CA替换的节点。 */
|
||
const struct IEC104_StationSnapshot *_self; /* 校验地址未变,拒绝活动快照的副本。 */
|
||
} IEC104_StationSnapshot_t;
|
||
|
||
/* 站点操作结果,与TCP发送/网络错误分开;须显式比较OK。 */
|
||
typedef enum {
|
||
IEC104_STATION_OK = 0,
|
||
IEC104_STATION_INVALID_ARGUMENT,
|
||
IEC104_STATION_DUPLICATE_CA,
|
||
IEC104_STATION_ALREADY_REGISTERED,
|
||
IEC104_STATION_NOT_FOUND,
|
||
IEC104_STATION_BUSY,
|
||
IEC104_STATION_LIMIT
|
||
} IEC104_StationResult_t;
|
||
|
||
/* 注册到服务末尾;CA须1..65534,0和广播65535不能成为站点。context允许NULL。
|
||
* 无固定站点池上限、无堆分配;容量取决于应用提供的节点与实际RAM。
|
||
* 重复CA/已注册节点/站点表锁定时失败且不改变任何节点。所有操作与Slave事件循环串行。 */
|
||
IEC104_StationResult_t IEC104_Slave_Add_Station(IEC104_Slave_t *self,
|
||
IEC104_Station_t *station, uint16_t common_address, void *context);
|
||
|
||
/* 立即从CA查找/普通遍历中移除;已有引用和快照延迟回收节点,不中断已接手业务。
|
||
* OK仅表示已移除,Is_Reusable为true后才可释放/复用节点和context;不撤回已接手ASDU。
|
||
* 显式Lock仍返回BUSY;重复删除返回NOT_FOUND。已移除CA可由另一个节点重新注册。 */
|
||
IEC104_StationResult_t IEC104_Slave_Remove_Station(IEC104_Slave_t *self, IEC104_Station_t *station);
|
||
|
||
/* 按CA查找借用节点;无效服务、未知CA、0及65535返回NULL。不会自动接受或应答任何请求。
|
||
* 跨事件循环保存节点前须Acquire;短时查找后直接使用可不占用,期间不得删除节点。
|
||
* 广播是否允许、涉及哪些站、如何应答由各业务决定,不能把65535当作某个默认站。 */
|
||
IEC104_Station_t *IEC104_Slave_Get_Station(const IEC104_Slave_t *self, uint16_t common_address);
|
||
size_t IEC104_Slave_Get_Station_Count(const IEC104_Slave_t *self);
|
||
/* 注册编号在同一Slave槽内不复用;可找到仍被引用保留的已删除节点,避免按CA误取替代站点。 */
|
||
IEC104_Station_t *IEC104_Slave_Get_Station_By_Id(const IEC104_Slave_t *self, uint64_t station_id);
|
||
uint64_t IEC104_Station_Get_Id(const IEC104_Station_t *station);
|
||
bool IEC104_Station_Is_Registered(const IEC104_Station_t *station);
|
||
bool IEC104_Station_Is_Reusable(const IEC104_Station_t *station);
|
||
|
||
/* Begin记录当前注册上界;Next按注册顺序借用节点,跳过已删除节点,不包含后来新增节点。
|
||
* 即使Next返回NULL也须End。快照期间退役节点的存储仍须保留;不锁点值,不做堆分配。
|
||
* Next返回值跨End使用前须Acquire;这些接口与所有站点操作在同一事件循环串行调用。 */
|
||
IEC104_StationResult_t IEC104_Slave_StationSnapshot_Begin(IEC104_Slave_t *self,
|
||
IEC104_StationSnapshot_t *snapshot);
|
||
IEC104_Station_t *IEC104_Slave_StationSnapshot_Next(IEC104_StationSnapshot_t *snapshot);
|
||
IEC104_StationResult_t IEC104_Slave_StationSnapshot_End(IEC104_StationSnapshot_t *snapshot);
|
||
|
||
/* 按注册顺序遍历,current为NULL时取首站;非法/外来节点或末尾返回NULL。
|
||
* 短时串行遍历不修改站点表;跨循环保留游标或要求固定站点集合时须配对Lock/Unlock。
|
||
* Lock可嵌套,阻止Add/Remove及Slave_Destroy,允许查找和Acquire/Release;不锁点值或网络。
|
||
* 最后一次Unlock后所有未Acquire的借用节点/游标均不可继续依赖旧集合。 */
|
||
IEC104_Station_t *IEC104_Slave_Next_Station(const IEC104_Slave_t *self, const IEC104_Station_t *current);
|
||
IEC104_StationResult_t IEC104_Slave_Lock_Stations(IEC104_Slave_t *self);
|
||
IEC104_StationResult_t IEC104_Slave_Unlock_Stations(IEC104_Slave_t *self);
|
||
|
||
/* 业务持有引用:每次成功Acquire必须配对一次Release,计数溢出返回LIMIT、零计数释放报错。
|
||
* 只占用指定站点,其他站仍可增删;不能用一个业务的Release替另一个业务归还引用。
|
||
* 异步业务须一直持有到延迟事件和清理完成;引用不代表原连接仍有效,仍须Check_Request。 */
|
||
IEC104_StationResult_t IEC104_Slave_Acquire_Station(IEC104_Slave_t *self, IEC104_Station_t *station);
|
||
IEC104_StationResult_t IEC104_Slave_Release_Station(IEC104_Slave_t *self, IEC104_Station_t *station);
|
||
|
||
/* station须为NULL或仍有效的调用方节点;已回收/NULL时返回0或NULL,退役但被引用时仍可读取。
|
||
* context只读出指针,库不读取其内容,也不规定点表、权限或各业务状态的布局。 */
|
||
uint16_t IEC104_Station_Get_Common_Address(const IEC104_Station_t *station);
|
||
void *IEC104_Station_Get_Context(const IEC104_Station_t *station);
|
||
|
||
/* transport保存原通知;I_FRAME且asdu_result为OK时,asdu和connection可直接使用。
|
||
* asdu借用本对象transport中的字节;确认/终止会原地修改这份副本的COT/P/N。
|
||
* 具体对象、地址及业务权限仍须由应用校验,ASDU_OK不代表允许执行请求。
|
||
* NextEvent为EMPTY/ERROR时整个输出保持不变;READY会替换上次事件。
|
||
* 使用期间地址必须稳定。延迟处理可直接读入任务存储,或使用Copy_Event复制;
|
||
* 禁止用赋值/memcpy搬移含自引用的事件。一个事件的多个应答沿用同一connection。
|
||
* transport元数据、connection及以下内部字段只读;用ASDU接口修改报文。
|
||
* 内部字段保存原服务实例和原代次,重连、重新Init及静态槽复用均不重新绑定旧请求。
|
||
*/
|
||
typedef struct {
|
||
IEC104_TcpEvent_t transport; /* 原通知的独立副本;只有type对应的data成员有效。 */
|
||
IEC60870_Asdu_t asdu; /* 借用本事件I帧中APCI之后的字节;仅asdu_result为OK时可用。 */
|
||
IEC60870_AsduResult_t asdu_result; /* 非I_FRAME为UNSUPPORTED;异常原文为ERROR。 */
|
||
IEC60870_MasterConnection_t connection; /* 仅ASDU_OK的I_FRAME提供发送函数。 */
|
||
IEC104_Slave_t *_owner; /* 以下字段由模块维护:产生本事件的Slave地址。 */
|
||
uint64_t _owner_serial; /* 原Slave_Create编号,防止静态槽销毁重用后旧应答串入新服务。 */
|
||
uint64_t _generation; /* 原TCP会话代次,防止断线重连后把旧应答发给新主站。 */
|
||
IEC104_TcpSubmitResult_t _last_submit_result; /* 此接口最近的提交结果,不表示实时发送/ACK状态。 */
|
||
} IEC104_SlaveEvent_t;
|
||
|
||
/* Get_Event_Identity校验后给出的来源身份,可按值保存,不借用事件原文或自引用视图。
|
||
* 三个字段只读,调用Check_Request时原样传回;slave只用于身份比较,不延长服务寿命。
|
||
* 不同Slave实例的局部编号可能相同,不能丢弃slave而只比较两个编号。 */
|
||
typedef struct {
|
||
const IEC104_Slave_t *slave; /* 产生事件的服务句柄。 */
|
||
uint64_t instance_id; /* 区分该服务静态槽的历次使用。 */
|
||
uint64_t generation; /* 原TCP会话代次;断线重连后旧身份不会重新绑定。 */
|
||
} IEC104_SlaveEventIdentity_t;
|
||
|
||
/* 业务请求推进检查,与发送容量/ACK状态无关;须按枚举值显式分支。 */
|
||
typedef enum {
|
||
IEC104_SLAVE_REQUEST_ERROR = -1, /* 非法服务/NULL身份,或服务状态查询失败。 */
|
||
IEC104_SLAVE_REQUEST_STALE = 0, /* 身份未绑定、服务/代次不符,或原连接不再处于激活状态。 */
|
||
IEC104_SLAVE_REQUEST_WAIT_EVENTS = 1, /* 先按FIFO处理Slave通知,再检查请求,防止漏过STOP/撤销。 */
|
||
IEC104_SLAVE_REQUEST_READY = 2 /* 原请求会话仍可处理;实际发送是否接手以发送接口为准。 */
|
||
} IEC104_SlaveRequestState_t;
|
||
|
||
/* 从静态池取得子站及其私有TCP服务,无malloc、无网络操作;容量不足返回NULL。
|
||
* 容量由IEC104_TCP_SERVER_CAPACITY决定,与直接使用TcpServer共享底层名额。
|
||
* 成功后配对Close、读空事件、Destroy;业务不得自行分配、复制或free服务对象。 */
|
||
IEC104_Slave_t *IEC104_Slave_Create(void);
|
||
|
||
/* 只销毁已关闭且事件读空的服务;失败保留句柄。成功后所有旧句柄失效。
|
||
* 未Init或Init失败后也可直接销毁;运行中为INVALID_STATE,未读事件为EVENTS_PENDING。
|
||
* 站点须Remove并归还引用,快照须End,站点表锁须Unlock,否则INVALID_STATE;Close/Init保留站点。
|
||
* 旧事件仍可读其原文字节,但发送接口不能用于新的服务实例。error允许NULL。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Destroy(IEC104_Slave_t *self, IEC104_TcpError_t *error);
|
||
|
||
/* 默认监听0.0.0.0:2404及推荐协议参数;NULL无操作。 */
|
||
void IEC104_Slave_Config_Default(IEC104_SlaveConfig_t *config);
|
||
|
||
/* 初始化网络和监听,复制config;成功后用Prepare/Process或Poll驱动。
|
||
* 初始化成功只表示可以接入主站;TCP连接及104激活状态分别由事件/状态查询反映。
|
||
* 失败不会销毁句柄;再次Init要求服务已Close且旧事件读空。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Init(IEC104_Slave_t *self,
|
||
const IEC104_SlaveConfig_t *config, IEC104_TcpError_t *error);
|
||
|
||
/* 只读查询调度条件。need_process或pending_event_count非零时不得阻塞等待。
|
||
* socket只供事件循环注册;业务不得直接recv/send/close。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Prepare(const IEC104_Slave_t *self,
|
||
IEC104_TcpWaitInfo_t *info, IEC104_TcpError_t *error);
|
||
|
||
/* 有界处理一批socket/定时就绪,不等待;ready的service_token及socket token来自原注册。
|
||
* 返回后读取NextEvent并重新Prepare;旧通知的身份不可替换成当前token。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Process(IEC104_Slave_t *self,
|
||
const IEC104_TcpReady_t *ready, IEC104_TcpError_t *error);
|
||
|
||
/* 独立循环入口:组合准备、最多等待max_wait_ms和有界推进;0不等待。
|
||
* 有待消费通知时不阻塞等待,调用方仍须读取NextEvent;等待上限不等于整个调用的耗时上限。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Poll(IEC104_Slave_t *self,
|
||
uint32_t max_wait_ms, IEC104_TcpError_t *error);
|
||
|
||
/* 按原FIFO取一个事件,自动绑定原服务/代次并创建I帧的可写ASDU视图。
|
||
* READY交付事件;EMPTY/ERROR保持输出。不执行业务、不自动确认、不进行I/O。
|
||
* I_FRAME须检查asdu_result;解析失败仍交付原事件,connection为空,不丢弃诊断原文。 */
|
||
IEC104_TcpEventResult_t IEC104_Slave_NextEvent(IEC104_Slave_t *self, IEC104_SlaveEvent_t *event);
|
||
|
||
/* 把事件及原文字节复制到稳定的任务存储,重建目标ASDU与接口的自引用。
|
||
* 不改变原服务实例/代次,不提交或重发任何报文;源和目标相同时只校验。
|
||
* true成功;false为NULL、非法事件/视图或未经本函数修复的按值副本,目标保持原值。 */
|
||
bool IEC104_Slave_Copy_Event(IEC104_SlaveEvent_t *destination, const IEC104_SlaveEvent_t *source);
|
||
|
||
/* 校验event的服务归属、身份字段和有效I帧视图,再写出来源身份;失败不改identity。
|
||
* self须为当前有效服务,event须由NextEvent/Copy_Event取得;identity为非NULL输出。
|
||
* 允许同一服务的历史连接事件,不要求原连接仍在线,便于按FIFO处理断开/重连通知。
|
||
* 其他服务、已销毁复用实例及未经Copy_Event修复的I帧副本返回false;不进行I/O或消费事件。 */
|
||
bool IEC104_Slave_Get_Event_Identity(const IEC104_Slave_t *self,
|
||
const IEC104_SlaveEvent_t *event, IEC104_SlaveEventIdentity_t *identity);
|
||
|
||
/* 检查由Get_Event_Identity取得的请求身份是否仍允许业务推进,不发送、不消费通知。
|
||
* 服务查询成功后,未读通知优先返回WAIT_EVENTS;读空后再判断来源、代次和激活状态。
|
||
* 零初始化身份在通知读空后返回STALE,可用于业务尚未绑定会话时的检查。
|
||
* READY不预留发送资源,不保证窗口/队列有空间;也不检查总召等业务自己的阶段或期限。 */
|
||
IEC104_SlaveRequestState_t IEC104_Slave_Check_Request(const IEC104_Slave_t *self,
|
||
const IEC104_SlaveEventIdentity_t *identity);
|
||
|
||
/* 查询该事件连接最近一次发送的OK/WAIT/ERROR/FATAL;空或无效接口返回ERROR。
|
||
* connection传&event.connection;结果仅在该接口提交时更新,不随Poll或ACK自动改变。
|
||
* true/OK为已接手,不代表已写完或已ACK;仅WAIT可保存原事件/ASDU等待重试。
|
||
* 确认/终止提交失败也不恢复已修改的字段;FATAL可能已写出字节。 */
|
||
IEC104_TcpSubmitResult_t IEC104_Slave_Get_Last_Submit_Result(
|
||
const IEC60870_MasterConnection_t *connection);
|
||
|
||
/* 使用原事件连接尝试直接提交,HIGH/NORMAL有待发数据或无法构帧时WAIT,不排队。
|
||
* OK已复制原文并固定发送顺序,不能重交;WAIT未接手,允许重取当前值后再试。
|
||
* ERROR为参数/身份/阶段非法,FATAL可能已发出字节;均不可当作背压盲目重试。
|
||
* 先读空Slave通知;取值、突发发布及本调用须在应用发布流程中串行协调。
|
||
* 同时更新Get_Last_Submit_Result;不改变普通MasterConnection_Send_*的排队行为。 */
|
||
IEC104_TcpSubmitResult_t IEC104_Slave_Try_Send_ASDU(
|
||
IEC60870_MasterConnection_t *connection, const IEC60870_Asdu_t *asdu);
|
||
|
||
/* 按Get_Event_Identity保存的原身份提交独立ASDU,无需长期保存完整SlaveEvent。
|
||
* identity可按值保存;三个字段保持原值,self必须是原服务,旧实例/旧代次不能发送。
|
||
* 普通路径可直接发送或排入HIGH;Try路径只有当前缓冲空闲且HIGH/NORMAL无待发条目时尝试构帧,
|
||
* 不能构帧则WAIT且不缓存。两者均直接返回OK/WAIT/ERROR/FATAL,不借用输入、不保存最近结果。
|
||
* 调用前须处理Slave通知并检查请求是否仍有效;此入口不管理业务撤销或业务超时。
|
||
* OK后不可重交;Try的WAIT后允许重读当前值重试,FATAL可能已发出字节。 */
|
||
IEC104_TcpSubmitResult_t IEC104_Slave_Send_Response(IEC104_Slave_t *self,
|
||
const IEC104_SlaveEventIdentity_t *identity, const IEC60870_Asdu_t *asdu);
|
||
IEC104_TcpSubmitResult_t IEC104_Slave_Try_Send_Response(IEC104_Slave_t *self,
|
||
const IEC104_SlaveEventIdentity_t *identity, const IEC60870_Asdu_t *asdu);
|
||
|
||
/* 对应用未接手的I帧当场回否定回显:复制请求,只改COT=cause(44..47)和P/N=1,
|
||
* 保留TEST、OA、CA、VSQ及对象原文;不修改输入事件或其最近提交结果。
|
||
* 沿原连接走普通应答路径,直接构帧或复制进HIGH,按提交顺序发送,不另建暂存队列。
|
||
* 仅在串行事件循环中、本次NextEvent之后且读取后续事件之前调用,无需先读空通知。
|
||
* 不得保存事件后延迟调用;延迟应答仍用Copy_Event/Check_Request并在启停、断线时取消。
|
||
* 返回:OK已接手,不表示已写完或已ACK;
|
||
* WAIT为HIGH剩余空间不足、未接手,兜底应答可丢弃并计数,不要求重试;
|
||
* ERROR为参数/事件非法、cause越界、原连接停用/断开/换代,或有未读启停通知;
|
||
* FATAL为发送故障,可能已写出字节,不得重试,继续读取断线收尾通知。
|
||
* 未读启停通知使本请求不跨启停提交;该检查不能识别已经被应用读完的历史启停。 */
|
||
IEC104_TcpSubmitResult_t IEC104_Slave_Reject_Request(IEC104_Slave_t *self,
|
||
const IEC104_SlaveEvent_t *event, int cause);
|
||
|
||
/* 返回标准104只读参数2/2/3、最大249,供主动上报构造ASDU;无效句柄返回NULL。
|
||
* 参数为静态常量,已取得的指针不借用服务存储。 */
|
||
const IEC60870_AppLayerParameters_t *IEC104_Slave_Get_Application_Layer_Parameters(
|
||
const IEC104_Slave_t *self);
|
||
|
||
/* 校验104布局后把ASDU复制到NORMAL,支持离线缓存;本次不直接写socket。
|
||
* 空间不足沿用NORMAL覆盖最旧原文的策略;返回OK表示已接手。 */
|
||
IEC104_TcpSubmitResult_t IEC104_Slave_Enqueue_Event(IEC104_Slave_t *self, IEC60870_Asdu_t *asdu);
|
||
|
||
/* 取得当前主站地址副本;尚未连接返回NOT_CONNECTED,不使用历史请求代替当前状态。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Get_Remote_Address(const IEC104_Slave_t *self,
|
||
IEC104_TcpPeerInfo_t *peer, IEC104_TcpError_t *error);
|
||
|
||
/* 关闭指定事件的原连接,保留监听/NORMAL;无需业务提取或传入generation。
|
||
* event须来自本服务实例;其他服务或已销毁复用实例的事件为INVALID_ARGUMENT。
|
||
* 当前无连接为NOT_CONNECTED;仍有连接但原代次已过期为STALE_GENERATION,不影响新连接。
|
||
* 成功后继续读取收尾事件;本操作不等待STOPDT或ACK。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Close_Connection(IEC104_Slave_t *self,
|
||
const IEC104_SlaveEvent_t *event, IEC104_TcpError_t *error);
|
||
|
||
/* 使用已保存的事件身份关闭原连接,适用于不保留完整事件的延迟业务。
|
||
* 身份来自Get_Event_Identity;原服务实例不符为INVALID_ARGUMENT,旧连接代次为STALE_GENERATION。
|
||
* 无连接为NOT_CONNECTED;OK保留监听/NORMAL并交付收尾通知,不影响后来复用槽位的新连接。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Close_Connection_By_Identity(IEC104_Slave_t *self,
|
||
const IEC104_SlaveEventIdentity_t *identity, IEC104_TcpError_t *error);
|
||
|
||
/* 只读取得服务、队列、连接状态副本;Create后、Init失败后、Close后也可调用。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Get_Status(const IEC104_Slave_t *self,
|
||
IEC104_TcpServerStatus_t *status, IEC104_TcpError_t *error);
|
||
|
||
/* 关闭监听和当前连接,保留未读通知;随后NextEvent读空,再Destroy归还静态槽。 */
|
||
IEC104_TcpResult_t IEC104_Slave_Close(IEC104_Slave_t *self, IEC104_TcpError_t *error);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif /* IEC104_SLAVE_H */
|