pub mod request;
pub mod response;
pub use mbus_core::models::register::*;
mod apis;
mod service;
#[cfg(test)]
mod tests {
use heapless::Vec;
use crate::services::register::{request::ReqPduCompiler, response::ResponseParser};
use mbus_core::{
data_unit::common::Pdu, errors::MbusError, function_codes::public::FunctionCode,
};
#[test]
fn test_read_holding_registers_request_valid() {
let pdu = ReqPduCompiler::read_holding_registers_request(0x006B, 3).unwrap();
assert_eq!(pdu.function_code(), FunctionCode::ReadHoldingRegisters);
assert_eq!(pdu.data().as_slice(), &[0x00, 0x6B, 0x00, 0x03]);
}
#[test]
fn test_read_holding_registers_invalid_quantity() {
assert_eq!(
ReqPduCompiler::read_holding_registers_request(0, 0).unwrap_err(),
MbusError::InvalidPduLength
);
assert_eq!(
ReqPduCompiler::read_holding_registers_request(0, 126).unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_read_holding_registers_request_max_quantity() {
let pdu = ReqPduCompiler::read_holding_registers_request(0x0000, 125).unwrap();
assert_eq!(pdu.function_code(), FunctionCode::ReadHoldingRegisters);
assert_eq!(pdu.data().as_slice(), &[0x00, 0x00, 0x00, 0x7D]); assert_eq!(pdu.data_len(), 4);
}
#[test]
fn test_read_input_registers_request_valid() {
let pdu = ReqPduCompiler::read_input_registers_request(0x0008, 1).unwrap();
assert_eq!(pdu.function_code(), FunctionCode::ReadInputRegisters);
assert_eq!(pdu.data().as_slice(), &[0x00, 0x08, 0x00, 0x01]);
}
#[test]
fn test_read_input_registers_request_invalid_quantity_low() {
assert_eq!(
ReqPduCompiler::read_input_registers_request(0, 0).unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_read_input_registers_request_invalid_quantity_high() {
assert_eq!(
ReqPduCompiler::read_input_registers_request(0, 126).unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_read_input_registers_request_max_quantity() {
let pdu = ReqPduCompiler::read_input_registers_request(0x0000, 125).unwrap();
assert_eq!(pdu.function_code(), FunctionCode::ReadInputRegisters);
assert_eq!(pdu.data().as_slice(), &[0x00, 0x00, 0x00, 0x7D]); assert_eq!(pdu.data_len(), 4);
}
#[test]
fn test_write_single_register_request_valid() {
let pdu = ReqPduCompiler::write_single_register_request(0x0001, 0x0003).unwrap();
assert_eq!(pdu.function_code(), FunctionCode::WriteSingleRegister);
assert_eq!(pdu.data().as_slice(), &[0x00, 0x01, 0x00, 0x03]);
assert_eq!(pdu.data_len(), 4);
}
#[test]
fn test_write_multiple_registers_request_valid() {
let quantity = 2;
let values = [0x0001, 0x0002];
let pdu =
ReqPduCompiler::write_multiple_registers_request(0x0000, quantity, &values).unwrap();
assert_eq!(pdu.function_code(), FunctionCode::WriteMultipleRegisters);
assert_eq!(
pdu.data().as_slice(),
&[0x00, 0x00, 0x00, 0x02, 0x04, 0x00, 0x01, 0x00, 0x02]
);
assert_eq!(pdu.data_len(), 9); }
#[test]
fn test_write_multiple_registers_request_invalid_quantity_low() {
let values: [u16; 0] = [];
assert_eq!(
ReqPduCompiler::write_multiple_registers_request(0x0000, 0, &values).unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_write_multiple_registers_request_invalid_quantity_high() {
let values = [0x0000; 124]; assert_eq!(
ReqPduCompiler::write_multiple_registers_request(0x0000, 124, &values).unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_write_multiple_registers_request_quantity_values_mismatch() {
let values = [0x1234, 0x5678];
let result = ReqPduCompiler::write_multiple_registers_request(0x0001, 3, &values); assert_eq!(result.unwrap_err(), MbusError::InvalidPduLength);
}
#[test]
fn test_write_multiple_registers_request_max_quantity() {
let values = [0x0000; 123]; let pdu = ReqPduCompiler::write_multiple_registers_request(0x0000, 123, &values).unwrap();
assert_eq!(pdu.function_code(), FunctionCode::WriteMultipleRegisters);
assert_eq!(pdu.data_len(), 5 + (123 * 2)); }
#[test]
fn test_read_write_multiple_registers_request_valid() {
let write_values = [0x0001, 0x0002];
let pdu =
ReqPduCompiler::read_write_multiple_registers_request(0x0000, 1, 0x0001, &write_values)
.unwrap();
assert_eq!(
pdu.function_code(),
FunctionCode::ReadWriteMultipleRegisters
);
assert_eq!(
pdu.data().as_slice(),
&[
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x04, 0x00, 0x01, 0x00, 0x02
]
);
assert_eq!(pdu.data_len(), 13); }
#[test]
fn test_read_write_multiple_registers_request_invalid_read_quantity_low() {
let write_values = [0x0001];
assert_eq!(
ReqPduCompiler::read_write_multiple_registers_request(0x0000, 0, 0x0001, &write_values)
.unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_read_write_multiple_registers_request_invalid_read_quantity_high() {
let write_values = [0x0001];
assert_eq!(
ReqPduCompiler::read_write_multiple_registers_request(
0x0000,
126,
0x0001,
&write_values
)
.unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_read_write_multiple_registers_request_invalid_write_quantity_low() {
let write_values: [u16; 0] = [];
assert_eq!(
ReqPduCompiler::read_write_multiple_registers_request(0x0000, 1, 0x0001, &write_values)
.unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_read_write_multiple_registers_request_invalid_write_quantity_high() {
let write_values = [0x0000; 122]; assert_eq!(
ReqPduCompiler::read_write_multiple_registers_request(0x0000, 1, 0x0001, &write_values)
.unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_read_write_multiple_registers_request_max_quantities() {
let write_values = [0x0000; 121]; let pdu = ReqPduCompiler::read_write_multiple_registers_request(
0x0000,
125,
0x0001,
&write_values,
)
.unwrap();
assert_eq!(
pdu.function_code(),
FunctionCode::ReadWriteMultipleRegisters
);
assert_eq!(pdu.data_len(), 9 + (121 * 2)); }
#[test]
fn test_mask_write_register_request_valid() {
let pdu = ReqPduCompiler::mask_write_register_request(0x0004, 0xF002, 0x0025).unwrap();
assert_eq!(pdu.function_code(), FunctionCode::MaskWriteRegister);
assert_eq!(pdu.data().as_slice(), &[0x00, 0x04, 0xF0, 0x02, 0x00, 0x25]);
assert_eq!(pdu.data_len(), 6);
}
#[test]
fn test_parse_read_write_multiple_registers_response_valid() {
let response_bytes = [0x17, 0x04, 0x12, 0x34, 0x56, 0x78];
let pdu = Pdu::from_bytes(&response_bytes).unwrap();
let registers =
ResponseParser::parse_read_write_multiple_registers_response(&pdu, 2).unwrap();
assert_eq!(registers.as_slice(), &[0x1234, 0x5678]);
}
#[test]
fn test_parse_read_write_multiple_registers_response_wrong_fc() {
let response_bytes = [0x03, 0x04, 0x12, 0x34, 0x56, 0x78]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_read_write_multiple_registers_response(&pdu, 2).unwrap_err(),
MbusError::InvalidFunctionCode
);
}
#[test]
fn test_parse_read_write_multiple_registers_response_empty_data() {
let pdu = Pdu::new(FunctionCode::ReadWriteMultipleRegisters, Vec::new(), 0);
assert_eq!(
ResponseParser::parse_read_write_multiple_registers_response(&pdu, 2).unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_parse_read_write_multiple_registers_response_byte_count_mismatch() {
let response_bytes = [0x17, 0x02, 0x12, 0x34, 0x56, 0x78]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_read_write_multiple_registers_response(&pdu, 2).unwrap_err(),
MbusError::InvalidByteCount
);
}
#[test]
fn test_parse_read_write_multiple_registers_response_expected_quantity_mismatch() {
let response_bytes = [0x17, 0x04, 0x12, 0x34, 0x56, 0x78]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_read_write_multiple_registers_response(&pdu, 3).unwrap_err(),
MbusError::InvalidQuantity
); }
#[test]
fn test_parse_mask_write_register_response_valid() {
let response_bytes = [0x16, 0x00, 0x04, 0xF0, 0x02, 0x00, 0x25];
let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert!(
ResponseParser::parse_mask_write_register_response(&pdu, 0x0004, 0xF002, 0x0025)
.is_ok()
);
}
#[test]
fn test_parse_mask_write_register_response_wrong_fc() {
let response_bytes = [0x06, 0x00, 0x04, 0xF0, 0x02, 0x00, 0x25]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_mask_write_register_response(&pdu, 0x0004, 0xF002, 0x0025)
.unwrap_err(),
MbusError::InvalidFunctionCode
);
}
#[test]
fn test_parse_mask_write_register_response_invalid_len() {
let response_bytes = [0x16, 0x00, 0x04, 0xF0, 0x02]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_mask_write_register_response(&pdu, 0x0004, 0xF002, 0x0025)
.unwrap_err(),
MbusError::InvalidPduLength
);
}
#[test]
fn test_parse_mask_write_register_response_address_mismatch() {
let response_bytes = [0x16, 0x00, 0x05, 0xF0, 0x02, 0x00, 0x25]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_mask_write_register_response(&pdu, 0x0004, 0xF002, 0x0025)
.unwrap_err(),
MbusError::InvalidAddress
);
}
#[test]
fn test_parse_mask_write_register_response_and_mask_mismatch() {
let response_bytes = [0x16, 0x00, 0x04, 0xF0, 0x01, 0x00, 0x25]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_mask_write_register_response(&pdu, 0x0004, 0xF002, 0x0025)
.unwrap_err(),
MbusError::InvalidAndMask
);
}
#[test]
fn test_parse_mask_write_register_response_or_mask_mismatch() {
let response_bytes = [0x16, 0x00, 0x04, 0xF0, 0x02, 0x00, 0x26]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_mask_write_register_response(&pdu, 0x0004, 0xF002, 0x0025)
.unwrap_err(),
MbusError::InvalidOrMask
);
}
#[test]
fn test_parse_read_holding_registers_response_valid() {
let response_bytes = [0x03, 0x04, 0x12, 0x34, 0x56, 0x78];
let pdu = Pdu::from_bytes(&response_bytes).unwrap();
let registers = ResponseParser::parse_read_holding_registers_response(&pdu, 2).unwrap();
assert_eq!(registers.as_slice(), &[0x1234, 0x5678]);
}
#[test]
fn test_parse_read_holding_registers_response_wrong_fc() {
let response_bytes = [0x04, 0x04, 0x12, 0x34, 0x56, 0x78]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_read_holding_registers_response(&pdu, 2).unwrap_err(),
MbusError::InvalidFunctionCode
);
}
#[test]
fn test_parse_read_holding_registers_response_byte_count_mismatch() {
let response_bytes = [0x03, 0x03, 0x12, 0x34, 0x56, 0x78]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_read_holding_registers_response(&pdu, 2).unwrap_err(),
MbusError::InvalidByteCount
);
}
#[test]
fn test_parse_read_holding_registers_response_expected_quantity_mismatch() {
let response_bytes = [0x03, 0x04, 0x12, 0x34, 0x56, 0x78]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_read_holding_registers_response(&pdu, 3).unwrap_err(),
MbusError::InvalidQuantity
); }
#[test]
fn test_parse_write_single_register_response_valid() {
let response_bytes = [0x06, 0x00, 0x01, 0x12, 0x34]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert!(ResponseParser::parse_write_single_register_response(&pdu, 0x0001, 0x1234).is_ok());
}
#[test]
fn test_parse_write_single_register_response_address_mismatch() {
let response_bytes = [0x06, 0x00, 0x02, 0x12, 0x34];
let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_write_single_register_response(&pdu, 0x0001, 0x1234).unwrap_err(),
MbusError::InvalidAddress
);
}
#[test]
fn test_parse_write_single_register_response_value_mismatch() {
let response_bytes = [0x06, 0x00, 0x01, 0x56, 0x78];
let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_write_single_register_response(&pdu, 0x0001, 0x1234).unwrap_err(),
MbusError::InvalidValue
);
}
#[test]
fn test_parse_write_multiple_registers_response_valid() {
let response_bytes = [0x10, 0x00, 0x01, 0x00, 0x02]; let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert!(ResponseParser::parse_write_multiple_registers_response(&pdu, 0x0001, 2).is_ok());
}
#[test]
fn test_parse_write_multiple_registers_response_address_mismatch() {
let response_bytes = [0x10, 0x00, 0x02, 0x00, 0x02];
let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_write_multiple_registers_response(&pdu, 0x0001, 2).unwrap_err(),
MbusError::InvalidAddress
);
}
#[test]
fn test_parse_write_multiple_registers_response_quantity_mismatch() {
let response_bytes = [0x10, 0x00, 0x01, 0x00, 0x03];
let pdu = Pdu::from_bytes(&response_bytes).unwrap();
assert_eq!(
ResponseParser::parse_write_multiple_registers_response(&pdu, 0x0001, 2).unwrap_err(),
MbusError::InvalidQuantity
);
}
}