use core::str::FromStr;
use crate::errors::MbusError;
use heapless::String;
use super::retry::{BackoffStrategy, JitterStrategy, RetryRandomFn};
const MODBUS_TCP_DEFAULT_PORT: u16 = 502;
#[derive(Debug, Clone, Copy, Default)]
pub enum Parity {
None,
#[default]
Even,
Odd,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum DataBits {
Five,
Six,
Seven,
#[default]
Eight,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum SerialMode {
#[default]
Rtu,
Ascii,
}
#[derive(Debug, Clone, Copy, Default)]
pub enum BaudRate {
Baud9600,
#[default]
Baud19200,
Custom(u32),
}
#[derive(Debug)]
pub struct ModbusSerialConfig<const PORT_PATH_LEN: usize = 64> {
pub port_path: heapless::String<PORT_PATH_LEN>,
pub mode: SerialMode,
pub baud_rate: BaudRate,
pub data_bits: DataBits,
pub stop_bits: u8,
pub parity: Parity,
pub response_timeout_ms: u32,
pub retry_attempts: u8,
pub retry_backoff_strategy: BackoffStrategy,
pub retry_jitter_strategy: JitterStrategy,
pub retry_random_fn: Option<RetryRandomFn>,
}
#[derive(Debug, Clone)]
pub struct ModbusTcpConfig {
pub host: heapless::String<64>,
pub port: u16,
pub connection_timeout_ms: u32,
pub response_timeout_ms: u32,
pub retry_attempts: u8,
pub retry_backoff_strategy: BackoffStrategy,
pub retry_jitter_strategy: JitterStrategy,
pub retry_random_fn: Option<RetryRandomFn>,
}
impl ModbusTcpConfig {
pub fn with_default_port(host: &str) -> Result<Self, MbusError> {
let host_string: String<64> =
String::from_str(host).map_err(|_| MbusError::BufferTooSmall)?;
Self::new(&host_string, MODBUS_TCP_DEFAULT_PORT)
}
pub fn new(host: &str, port: u16) -> Result<Self, MbusError> {
let host_string = String::from_str(host).map_err(|_| MbusError::BufferTooSmall)?;
Ok(Self {
host: host_string,
port,
connection_timeout_ms: 5000,
response_timeout_ms: 5000,
retry_attempts: 3,
retry_backoff_strategy: BackoffStrategy::Immediate,
retry_jitter_strategy: JitterStrategy::None,
retry_random_fn: None,
})
}
}
#[derive(Debug)]
pub enum ModbusConfig {
Tcp(ModbusTcpConfig),
Serial(ModbusSerialConfig),
}
impl ModbusConfig {
pub fn retry_attempts(&self) -> u8 {
match self {
ModbusConfig::Tcp(config) => config.retry_attempts,
ModbusConfig::Serial(config) => config.retry_attempts,
}
}
pub fn retry_backoff_strategy(&self) -> BackoffStrategy {
match self {
ModbusConfig::Tcp(config) => config.retry_backoff_strategy,
ModbusConfig::Serial(config) => config.retry_backoff_strategy,
}
}
pub fn retry_jitter_strategy(&self) -> JitterStrategy {
match self {
ModbusConfig::Tcp(config) => config.retry_jitter_strategy,
ModbusConfig::Serial(config) => config.retry_jitter_strategy,
}
}
pub fn retry_random_fn(&self) -> Option<RetryRandomFn> {
match self {
ModbusConfig::Tcp(config) => config.retry_random_fn,
ModbusConfig::Serial(config) => config.retry_random_fn,
}
}
}