79 lines
3.4 KiB
C
79 lines
3.4 KiB
C
/*
|
||
* 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 */
|