RTU/src/protocol/libmodbus/inc/modbus-tcp-private.h

79 lines
3.4 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.

/*
* Copyright © Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef MODBUS_TCP_PRIVATE_H
#define MODBUS_TCP_PRIVATE_H
/*
* Modbus TCP 协议的帧格式定义:
*
* TCP ADU 帧结构(基于 MBAP 头 + PDU):
* ┌──────────────────────────┬───────────────┬──────────┐
* │ MBAP 头部(7字节) │ PDU(变长) │ ... │
* └──────────────────────────┴───────────────┴──────────┘
*
* MBAP 头部分解:
* ┌──────────────┬──────────────┬──────────────┬──────────┐
* │ 事务标识符 │ 协议标识符 │ 长度字段 │ 单元标识符 │
* │ (2字节) │ (2字节,=0) │ (2字节) │ (1字节) │
* └──────────────┴──────────────┴──────────────┴──────────┘
*/
/* TCP MBAP 头长度:事务ID(2) + 协议ID(2) + 长度(2) + 单元ID(1) = 7 字节 */
#define _MODBUS_TCP_HEADER_LENGTH 7
/* TCP 预设请求帧的总长度:MBAP头(7) + PDU(5) = 12 字节 */
#define _MODBUS_TCP_PRESET_REQ_LENGTH 12
/* TCP 预设响应帧的总长度:MBAP头(7) + PDU(1) = 8 字节 */
#define _MODBUS_TCP_PRESET_RSP_LENGTH 8
/*
* TCP 模式下没有独立的校验和字段。
* TCP 协议本身通过底层 TCP/IP 栈的校验和机制保证数据完整性,
* 因此 Modbus TCP 的 checksum 长度为 0。
*/
#define _MODBUS_TCP_CHECKSUM_LENGTH 0
/*
* modbus_tcp_t — Modbus TCP 后端的私有数据结构体。
* 在两个结构体中,事务标识符(t_id)都必须放在第一个字段位置,
* 这样无论使用哪个 TCP 后端变体,都可以通过相同的内存偏移量快速访问事务ID。
*/
typedef struct _modbus_tcp {
/*
* 事务标识符。
* 摘录自《MODBUS Messaging on TCP/IP Implementation Guide V1.0b》
* (第 23/46 页):
* 事务标识符用于将未来的响应与对应的请求关联起来。
* 在每个 TCP 连接上,此标识符是唯一的。
* 客户端生成一个事务ID,服务器在响应中原样返回,
* 从而允许客户端匹配请求和响应。
*/
uint16_t t_id;
/* TCP 端口号(标准 Modbus TCP 端口为 502) */
int port;
/* IP 地址字符串(如 "192.168.1.100"),最大 15 字符 + '\0' 结尾 */
char ip[16];
} modbus_tcp_t;
/*
* modbus_tcp_pi_t — Modbus TCP PI(协议独立)后端的私有数据结构体。
* "PI" 表示 Protocol Independent(协议独立),即使用 getaddrinfo()
* 解析的主机名和服务名,而非仅限 IPv4 地址。
* 这使得该结构体同时支持 IPv4 和 IPv6 地址。
*/
typedef struct _modbus_tcp_pi {
/* 事务标识符(放在首位,便于快速访问) */
uint16_t t_id;
/* TCP 端口号 */
int port;
/* 主机节点名(如 "modbus-server.local" 或 IPv4/IPv6 地址字符串) */
char *node;
/* 服务名(如 "502" 或 "/etc/services 中定义的服务名") */
char *service;
} modbus_tcp_pi_t;
#endif /* MODBUS_TCP_PRIVATE_H */