Changes
This commit is contained in:
@@ -1,16 +1,8 @@
|
||||
use log::{warn, error};
|
||||
|
||||
// Use std::vec when std exists, otherwise alloc::vec
|
||||
#[cfg(feature = "std")]
|
||||
use std::vec;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
extern crate alloc;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::vec::Vec;
|
||||
|
||||
use thiserror::Error;
|
||||
@@ -38,6 +30,7 @@ pub struct Protocol300Message {
|
||||
}
|
||||
|
||||
impl Protocol300Message {
|
||||
#[inline]
|
||||
/// Creates a new `Protocol300message` used to request data from the device
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -60,6 +53,7 @@ impl Protocol300Message {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Creates a new `Protocol300message` used to write data to the device
|
||||
///
|
||||
/// # Arguments
|
||||
@@ -86,8 +80,25 @@ impl Protocol300Message {
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Decode a byte string into a `Protocol300Message`
|
||||
pub fn try_from_bytes(bytes: &[u8]) -> Result<Protocol300Message, MessageDecodingError> {
|
||||
///
|
||||
/// Tries to decode a vec of bytes into an `Protocol300Message`. Includes
|
||||
/// checking for valid start bytes and checking the checksum to detect
|
||||
/// transmission errors
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns a `MessageDecodingError` on failure. Can be caused by multiple
|
||||
/// things (for details look at `MessageDecodingError`):
|
||||
/// - Invalid Start byte
|
||||
/// - Length does not match actual length
|
||||
/// - Invalid values for Message Identifier or Function code
|
||||
/// - Checksum mismatch
|
||||
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, MessageDecodingError> {
|
||||
if bytes.len() < 8 {
|
||||
return Err(MessageDecodingError::VecTooShort)
|
||||
}
|
||||
|
||||
if bytes[0] != 0x41 {
|
||||
return Err(MessageDecodingError::InvalidTelegramStart(bytes[0]));
|
||||
}
|
||||
@@ -123,7 +134,13 @@ impl Protocol300Message {
|
||||
},
|
||||
};
|
||||
|
||||
let checksum = calculate_checksum(telegram_length, message_identifier, function_code, data_address, data_length, &data);
|
||||
let checksum_calculated = calculate_checksum(telegram_length, message_identifier, function_code, data_address, data_length, &data);
|
||||
let checksum = bytes[telegram_length as usize + 2];
|
||||
|
||||
// Fail if the checksums do not match
|
||||
if checksum != checksum_calculated {
|
||||
return Err(MessageDecodingError::Checksum)
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
telegram_length,
|
||||
@@ -137,6 +154,9 @@ impl Protocol300Message {
|
||||
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline]
|
||||
/// Converts a `Protocol300Message` to a vec of bytes
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
let telegram_start_byte = 0x41;
|
||||
let address_as_bytes = self.data_address.to_be_bytes();
|
||||
@@ -157,13 +177,13 @@ impl Protocol300Message {
|
||||
|
||||
}
|
||||
|
||||
// TODO docs and test
|
||||
#[inline]
|
||||
/// Returns the expected length of the return telegram, include start byte but excluding ACK byte
|
||||
///
|
||||
/// Currently only implemented for Read and Write requests, as the rest is not needed and/or
|
||||
/// unknown behaviour
|
||||
///
|
||||
/// # Errors:
|
||||
/// # Errors
|
||||
/// - `MessageReturnLengthError` - Describes the error which occured when converting
|
||||
pub const fn get_expected_return_telegram_length(&self) -> Result<usize, MessageReturnLengthError> {
|
||||
match (self.message_identifier, self.function_code) {
|
||||
@@ -213,6 +233,12 @@ pub enum MessageDecodingError {
|
||||
/// Error getting function code enum variant by number
|
||||
#[error("Function Code not valid")]
|
||||
InvalidFunctionCode(#[from] num_enum::TryFromPrimitiveError<FunctionCode>),
|
||||
/// Checksum does not match the calculated checksum
|
||||
#[error("Checksums do not match")]
|
||||
Checksum,
|
||||
/// The message vec is too short
|
||||
#[error("The message vec is too short")]
|
||||
VecTooShort
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -229,7 +255,7 @@ mod tests {
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_new_request_message() {
|
||||
fn new_request_message_works() {
|
||||
let expected_message = Protocol300Message{
|
||||
telegram_length: 5,
|
||||
message_identifier: MessageIdentifier::Request,
|
||||
@@ -244,7 +270,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_write_message() {
|
||||
fn new_write_message() {
|
||||
let expected_message = Protocol300Message{
|
||||
telegram_length: 9,
|
||||
message_identifier: MessageIdentifier::Request,
|
||||
@@ -259,14 +285,14 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_write_message_data_too_long() {
|
||||
fn new_write_message_data_too_long() {
|
||||
let generated_message = Protocol300Message::try_new_write_message(0x0101, &vec![0x00; 300]);
|
||||
assert!(generated_message.is_err());
|
||||
assert!(matches!(generated_message.err().unwrap(), MessageCreationError::DataTooLong(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_received_message_read_response_from_bytes() {
|
||||
fn received_message_read_response_from_bytes() {
|
||||
let expected_msg = Protocol300Message{
|
||||
data_address: 0x5525,
|
||||
telegram_length: 0x09,
|
||||
@@ -282,7 +308,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_received_message_write_response_from_bytes() {
|
||||
fn received_message_write_response_from_bytes() {
|
||||
let expected_msg = Protocol300Message{
|
||||
data_address: 0x2101,
|
||||
telegram_length: 0x05,
|
||||
@@ -298,7 +324,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_received_message_read_request_from_bytes() {
|
||||
fn received_message_read_request_from_bytes() {
|
||||
let expected_msg = Protocol300Message{
|
||||
data_address: 0x5525,
|
||||
telegram_length: 0x05,
|
||||
@@ -314,7 +340,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_received_message_write_request_from_bytes() {
|
||||
fn received_message_write_request_from_bytes() {
|
||||
let expected_msg = Protocol300Message{
|
||||
data_address: 0x2323,
|
||||
telegram_length: 0x06,
|
||||
@@ -330,7 +356,7 @@ mod tests {
|
||||
}
|
||||
// TO BYTES
|
||||
#[test]
|
||||
fn test_received_message_write_request_to_bytes() {
|
||||
fn received_message_write_request_to_bytes() {
|
||||
let test_msg = Protocol300Message{
|
||||
data_address: 0x2323,
|
||||
telegram_length: 0x06,
|
||||
@@ -346,7 +372,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_received_message_read_request_to_bytes() {
|
||||
fn received_message_read_request_to_bytes() {
|
||||
let test_msg = Protocol300Message{
|
||||
data_address: 0x5525,
|
||||
telegram_length: 0x05,
|
||||
@@ -362,7 +388,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_received_message_write_response_to_bytes() {
|
||||
fn received_message_write_response_to_bytes() {
|
||||
let test_msg = Protocol300Message{
|
||||
data_address: 0x2101,
|
||||
telegram_length: 0x05,
|
||||
@@ -378,7 +404,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_received_message_read_response_to_bytes() {
|
||||
fn received_message_read_response_to_bytes() {
|
||||
let test_msg = Protocol300Message{
|
||||
data_address: 0x5525,
|
||||
telegram_length: 0x09,
|
||||
@@ -394,7 +420,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expected_return_length_read() {
|
||||
fn expected_return_length_read() {
|
||||
let expected_message = Protocol300Message{
|
||||
telegram_length: 5,
|
||||
message_identifier: MessageIdentifier::Request,
|
||||
@@ -408,7 +434,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expected_return_length_write() {
|
||||
fn expected_return_length_write() {
|
||||
let expected_message = Protocol300Message{
|
||||
telegram_length: 9,
|
||||
message_identifier: MessageIdentifier::Request,
|
||||
|
||||
Reference in New Issue
Block a user