Skip to main content

mbus_core/transport/
config.rs

1//! Transport configuration types: TCP and Serial.
2
3use core::str::FromStr;
4
5use crate::errors::MbusError;
6use heapless::String;
7
8use super::retry::{BackoffStrategy, JitterStrategy, RetryRandomFn};
9
10/// The default TCP port for Modbus communication.
11const MODBUS_TCP_DEFAULT_PORT: u16 = 502;
12
13/// Parity bit configuration for serial communication.
14#[derive(Debug, Clone, Copy, Default)]
15pub enum Parity {
16    /// No parity bit is used.
17    None,
18    /// Even parity: the number of 1-bits in the data plus parity bit is even.
19    #[default]
20    Even,
21    /// Odd parity: the number of 1-bits in the data plus parity bit is odd.
22    Odd,
23}
24
25/// Number of data bits per serial character.
26#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
27pub enum DataBits {
28    /// 5 data bits.
29    Five,
30    /// 6 data bits.
31    Six,
32    /// 7 data bits.
33    Seven,
34    /// 8 data bits.
35    #[default]
36    Eight,
37}
38
39/// Serial framing mode.
40#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
41pub enum SerialMode {
42    /// Modbus RTU mode, which uses binary encoding and CRC error checking.
43    #[default]
44    Rtu,
45    /// Modbus ASCII mode, which uses ASCII encoding and LRC error checking.
46    Ascii,
47}
48
49/// Baud rate configuration for serial communication.
50#[derive(Debug, Clone, Copy, Default)]
51pub enum BaudRate {
52    /// Standard baud rate of 9600 bits per second.
53    Baud9600,
54    /// Standard baud rate of 19200 bits per second.
55    #[default]
56    Baud19200,
57    /// Custom baud rate.
58    Custom(u32),
59}
60
61/// Configuration parameters for establishing a Modbus Serial connection.
62#[derive(Debug)]
63pub struct ModbusSerialConfig<const PORT_PATH_LEN: usize = 64> {
64    /// The path to the serial port (e.g., "/dev/ttyUSB0" or "COM1").
65    pub port_path: heapless::String<PORT_PATH_LEN>,
66    /// The serial mode to use (RTU or ASCII).
67    pub mode: SerialMode,
68    /// Communication speed in bits per second (e.g., 9600, 115200).
69    pub baud_rate: BaudRate,
70    /// Number of data bits per character (typically `DataBits::Eight` for RTU, `DataBits::Seven` for ASCII).
71    pub data_bits: DataBits,
72    /// Number of stop bits (This will be recalculated before calling the transport layer).
73    pub stop_bits: u8,
74    /// The parity checking mode.
75    pub parity: Parity,
76    /// Timeout for waiting for a response in milliseconds.
77    pub response_timeout_ms: u32,
78    /// Number of retries for failed operations.
79    pub retry_attempts: u8,
80    /// Backoff strategy used when scheduling retries.
81    pub retry_backoff_strategy: BackoffStrategy,
82    /// Optional jitter strategy applied on top of retry backoff delay.
83    pub retry_jitter_strategy: JitterStrategy,
84    /// Optional application-provided random callback used by jitter.
85    pub retry_random_fn: Option<RetryRandomFn>,
86}
87
88/// Configuration parameters for establishing a Modbus TCP connection.
89#[derive(Debug, Clone)]
90pub struct ModbusTcpConfig {
91    /// The hostname or IP address of the Modbus TCP server to connect to.
92    pub host: heapless::String<64>,
93    /// The TCP port number on which the Modbus server is listening (default is typically 502).
94    pub port: u16,
95    /// Timeout for establishing a connection in milliseconds.
96    pub connection_timeout_ms: u32,
97    /// Timeout for waiting for a response in milliseconds.
98    pub response_timeout_ms: u32,
99    /// Number of retry attempts for failed operations.
100    pub retry_attempts: u8,
101    /// Backoff strategy used when scheduling retries.
102    pub retry_backoff_strategy: BackoffStrategy,
103    /// Optional jitter strategy applied on top of retry backoff delay.
104    pub retry_jitter_strategy: JitterStrategy,
105    /// Optional application-provided random callback used by jitter.
106    pub retry_random_fn: Option<RetryRandomFn>,
107}
108
109impl ModbusTcpConfig {
110    /// Creates a new `ModbusTcpConfig` using the default Modbus TCP port (502).
111    pub fn with_default_port(host: &str) -> Result<Self, MbusError> {
112        let host_string: String<64> =
113            String::from_str(host).map_err(|_| MbusError::BufferTooSmall)?;
114        Self::new(&host_string, MODBUS_TCP_DEFAULT_PORT)
115    }
116
117    /// Creates a new `ModbusTcpConfig` with the specified host and port.
118    pub fn new(host: &str, port: u16) -> Result<Self, MbusError> {
119        let host_string = String::from_str(host).map_err(|_| MbusError::BufferTooSmall)?;
120        Ok(Self {
121            host: host_string,
122            port,
123            connection_timeout_ms: 5000,
124            response_timeout_ms: 5000,
125            retry_attempts: 3,
126            retry_backoff_strategy: BackoffStrategy::Immediate,
127            retry_jitter_strategy: JitterStrategy::None,
128            retry_random_fn: None,
129        })
130    }
131}
132
133/// Top-level configuration for Modbus communication, supporting different transport layers.
134#[derive(Debug)]
135pub enum ModbusConfig {
136    /// Configuration for Modbus TCP/IP.
137    Tcp(ModbusTcpConfig),
138    /// Configuration for Modbus Serial (RTU or ASCII).
139    Serial(ModbusSerialConfig),
140}
141
142impl ModbusConfig {
143    /// Returns the number of retry attempts configured for the transport.
144    pub fn retry_attempts(&self) -> u8 {
145        match self {
146            ModbusConfig::Tcp(config) => config.retry_attempts,
147            ModbusConfig::Serial(config) => config.retry_attempts,
148        }
149    }
150
151    /// Returns the configured retry backoff strategy.
152    pub fn retry_backoff_strategy(&self) -> BackoffStrategy {
153        match self {
154            ModbusConfig::Tcp(config) => config.retry_backoff_strategy,
155            ModbusConfig::Serial(config) => config.retry_backoff_strategy,
156        }
157    }
158
159    /// Returns the configured retry jitter strategy.
160    pub fn retry_jitter_strategy(&self) -> JitterStrategy {
161        match self {
162            ModbusConfig::Tcp(config) => config.retry_jitter_strategy,
163            ModbusConfig::Serial(config) => config.retry_jitter_strategy,
164        }
165    }
166
167    /// Returns the optional application-provided random callback for jitter.
168    pub fn retry_random_fn(&self) -> Option<RetryRandomFn> {
169        match self {
170            ModbusConfig::Tcp(config) => config.retry_random_fn,
171            ModbusConfig::Serial(config) => config.retry_random_fn,
172        }
173    }
174}