Files
STM32F4-Base/IEC60870-Slave/104/IEC104_Codec.h
T
STF 4c55544f05
CI / L0 静态门禁 (pre-commit) (push) Failing after 45s
CI / L0.5 主机侧单测 (MSVC) (push) Failing after 42s
通信协议代码
2026-10-26 08:31:48 -04:00

104 lines
4.6 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专用无状态编解码:APCI检查及I/S/U帧构造;ASDU公共头见IEC60870_Codec。 */
#ifndef IEC104_CODEC_H
#define IEC104_CODEC_H
#include "IEC104_Types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* IEC-104 帧类型。 */
typedef enum {
IEC104_FRAME_TYPE_I = 0,
IEC104_FRAME_TYPE_S,
IEC104_FRAME_TYPE_U
} IEC104_FrameType_t;
/* U 帧控制域首字节;ACT 为请求,CON 为对应确认。
* 编码入口用int接收待校验值,不依赖本枚举的存储宽度。 */
typedef enum {
IEC104_U_STARTDT_ACT = 0x07,
IEC104_U_STARTDT_CON = 0x0B,
IEC104_U_STOPDT_ACT = 0x13,
IEC104_U_STOPDT_CON = 0x23,
IEC104_U_TESTFR_ACT = 0x43,
IEC104_U_TESTFR_CON = 0x83
} IEC104_UFrameFunction_t;
/* 完整APDU中APCI控制信息及ASDU位置的解析结果;各字段是否有效由frame_type决定。 */
typedef struct {
IEC104_FrameType_t frame_type; /* I、S或U帧 */
uint16_t send_number; /* I帧的N(S) */
uint16_t receive_number; /* I帧或S帧的N(R) */
uint8_t u_function; /* U帧功能码 */
const uint8_t *asdu; /* I帧中的ASDU首地址 */
uint16_t asdu_len; /* I帧中的ASDU长度 */
} IEC104_ApciInfo_t;
/**
* 功能:根据 IEC-104 控制域首字节识别 I、S 或 U 帧。
* 输入参数:control——控制域首字节。
* 输出参数:无。
* 返回值:对应的 IEC104_FrameType_t 帧类型。
* 说明:仅按控制域低位分类,不验证保留位、U功能码或帧长度;完整APCI检查由Parse_APCI执行。
*/
extern IEC104_FrameType_t IEC104_Get_Frame_Type(uint8_t control);
/**
* 功能:检查完整APDU的外层长度和APCI控制域,解析控制信息及ASDU位置。
* 输入参数:frame——完整APDU首地址;frame_len——完整APDU长度。
* 输出参数:apci——解析成功时写入帧类型、序号、U功能码和ASDU位置。
* 返回值:解析成功返回1,否则返回0且不保证apci中的内容。
* 说明:I帧要求ASDU长度至少为IEC104_ASDU_HEADER_LEN,不足时返回0;不解析公共头字段或信息对象。
* apci->asdu直接指向frame内部,其有效期不超过frame缓冲区有效期。
*/
extern int IEC104_Parse_APCI(const uint8_t *frame,
uint16_t frame_len,
IEC104_ApciInfo_t *apci);
/**
* 功能:根据发送序号、接收序号和ASDU构造一个完整的I帧APDU。
* 输入参数:buf——输出缓冲区;send_seq——N(S);recv_seq——N(R);
* asdu——完整ASDU首地址;asdu_len——ASDU长度,范围为6..249。
* 输出参数:buf——成功时写入完整I帧。
* 返回值:成功返回APDU总长度,参数非法返回-1。
* 说明:调用方必须保证buf至少具有IEC104_APCI_LEN+asdu_len字节空间;
* 本函数不读取或修改IEC104_LinkState_t。调用方须保存recv_seq,并在
* 完整发送后把它作为实际N(R)提交给链路状态。
*/
extern int IEC104_Build_Iframe(uint8_t *buf,
uint16_t send_seq,
uint16_t recv_seq,
const uint8_t *asdu,
int asdu_len);
/**
* 功能:根据接收序号构造一个完整的S帧APDU。
* 输入参数:buf——输出缓冲区;recv_seq——待编码的N(R),范围为0..32767。
* 输出参数:buf——成功时写入6字节S帧。
* 返回值:成功返回IEC104_APCI_LEN,参数非法返回-1。
* 说明:调用方必须保证buf至少具有IEC104_APCI_LEN字节空间;
* 本函数不读取或修改IEC104_LinkState_t。调用方须保存recv_seq,并在
* 完整发送后把它作为实际N(R)提交给链路状态。
*/
extern int IEC104_Build_Sframe(uint8_t *buf, uint16_t recv_seq);
/**
* 功能:根据U帧功能码构造一个完整的U帧APDU。
* 输入参数:buf——输出缓冲区;function——待校验的整数功能码,只允许六种U帧功能值。
* 输出参数:buf——成功时写入6字节U帧,参数检查失败时不写入。
* 返回值:成功返回IEC104_APCI_LEN,参数或功能码非法返回-1。
* 说明:调用方必须保证buf至少具有IEC104_APCI_LEN字节空间;
* buf非NULL且功能码合法时固定返回6,容量由调用方保证,本函数无法检查。
* function使用int,短枚举配置下也能拒绝0x107等非法值;调用方不要预先收窄未校验值。
* 本函数不处理U帧状态转换或网络发送。
*/
extern int IEC104_Build_Uframe(uint8_t *buf, int function);
#ifdef __cplusplus
}
#endif
#endif /* IEC104_CODEC_H */