65 lines
2.4 KiB
Rust
65 lines
2.4 KiB
Rust
use crate::enums::{FunctionCode, MessageIdentifier};
|
|
|
|
#[expect(clippy::big_endian_bytes, reason="Function is needed for the Protocol 300")]
|
|
/// Calculate the checksum for a Protocol 300 message
|
|
///
|
|
/// The inputs are seperate as the function is needed without have a construced
|
|
/// `Protocol300Message` sometimes.
|
|
pub fn calculate_checksum(length: u8, message_identifier: MessageIdentifier, function_code: FunctionCode, address: u16, data_length: u8, data: &[u8]) -> u8 {
|
|
let mut checksum: u8 = 0;
|
|
let [addr_hi, addr_lo] = address.to_be_bytes();
|
|
|
|
for byte in [length, message_identifier.into(), function_code.into(), data_length, addr_hi, addr_lo].iter().chain(data) {
|
|
checksum = checksum.wrapping_add(*byte);
|
|
}
|
|
|
|
checksum
|
|
}
|
|
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::{enums::{FunctionCode, MessageIdentifier}, message::Protocol300Message, utils::calculate_checksum};
|
|
#[cfg(not(feature = "std"))]
|
|
extern crate alloc;
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
use alloc::vec;
|
|
|
|
#[cfg(not(feature = "std"))]
|
|
use alloc::vec::Vec;
|
|
|
|
#[test]
|
|
fn check_checksum_1() {
|
|
let test_msg = Protocol300Message {
|
|
data_address: 0x5525,
|
|
telegram_length: 0x05,
|
|
function_code: FunctionCode::VirtualREAD,
|
|
message_identifier: MessageIdentifier::Request,
|
|
data_length: 0x02,
|
|
data: vec![],
|
|
checksum: 0x82,
|
|
};
|
|
assert_eq!(calculate_checksum(test_msg.telegram_length, test_msg.message_identifier, test_msg.function_code, test_msg.data_address, test_msg.data_length, &test_msg.data), 0x82);
|
|
}
|
|
|
|
#[test]
|
|
fn check_checksum_2() {
|
|
let test_msg = Protocol300Message {
|
|
data_address: 0x5525,
|
|
telegram_length: 0x07,
|
|
function_code: FunctionCode::VirtualREAD,
|
|
message_identifier: MessageIdentifier::Response,
|
|
data_length: 0x02,
|
|
data: vec![0x07, 0x01],
|
|
checksum: 0x8D,
|
|
};
|
|
assert_eq!(calculate_checksum(test_msg.telegram_length, test_msg.message_identifier, test_msg.function_code, test_msg.data_address, test_msg.data_length, &test_msg.data), 0x8D);
|
|
}
|
|
|
|
#[test]
|
|
fn received_message_wrapping_add_from_bytes() {
|
|
let checksum = calculate_checksum(0x06, MessageIdentifier::Request, FunctionCode::VirtualWRITE, 0x2323, 0x01, &[0xB6]);
|
|
assert_eq!(checksum, 0x05);
|
|
}
|
|
} |