Added Protocol300Transmission to also decode control codes
This commit is contained in:
12
src/lib.rs
12
src/lib.rs
@@ -1,13 +1,15 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
#![expect(clippy::implicit_return, reason="Implicit return is fine in this crate")]
|
// #![expect(clippy::implicit_return, reason="Implicit return is fine in this crate")]
|
||||||
#![expect(clippy::exhaustive_structs, reason="All Structs are based on a fixed protocol")]
|
// #![expect(clippy::exhaustive_structs, reason="All Structs are based on a fixed protocol")]
|
||||||
#![expect(clippy::arbitrary_source_item_ordering, reason="Order is the same as in the protocl")]
|
// #![expect(clippy::arbitrary_source_item_ordering, reason="Order is the same as in the protocl")]
|
||||||
#![allow(clippy::question_mark_used, reason="I like ?")]
|
// #![allow(clippy::question_mark_used, reason="I like ?")]
|
||||||
|
|
||||||
mod message;
|
mod message;
|
||||||
mod enums;
|
mod enums;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod transmission;
|
||||||
|
|
||||||
pub use message::Protocol300Message;
|
pub use message::Protocol300Message;
|
||||||
pub use enums::{FunctionCode, MessageIdentifier, ResponseCode};
|
pub use enums::{FunctionCode, MessageIdentifier, ResponseCode};
|
||||||
|
pub use transmission::Protocol300Transmission;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
use log::{warn, error};
|
use log::warn;
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
|||||||
142
src/transmission.rs
Normal file
142
src/transmission.rs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
use crate::{Protocol300Message, message};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
pub enum Protocol300Transmission {
|
||||||
|
/// 0x06 - ACK, used by all clients as acknowledgement
|
||||||
|
Ack,
|
||||||
|
/// 0x05 - Gets sent periodically to indicate idle/not initialized connection by the heater
|
||||||
|
Enq,
|
||||||
|
/// 0x04 - Resets the connection to a known state
|
||||||
|
Eot,
|
||||||
|
/// 0x16 0x00 0x00 - Initializes the connection, sent by the client
|
||||||
|
Init,
|
||||||
|
/// 0x15 - Negative Acknowledgement, indicates an error in the last message
|
||||||
|
Nack,
|
||||||
|
/// A valid decoded message
|
||||||
|
Message(Protocol300Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Protocol300Transmission {
|
||||||
|
/// Try to convert bytes to a Protocol 300 Transmission
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// Returns a `FromBytesError` if the conversion fails in some way
|
||||||
|
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, FromBytesError> {
|
||||||
|
match bytes {
|
||||||
|
[0x06] => Ok(Self::Ack),
|
||||||
|
[0x05] => Ok(Self::Enq),
|
||||||
|
[0x04] => Ok(Self::Eot),
|
||||||
|
[0x15] => Ok(Self::Nack),
|
||||||
|
[0x16, 0x00, 0x00] => Ok(Self::Init),
|
||||||
|
[0x41, ..] => Ok(Self::Message(Protocol300Message::try_from_bytes(bytes)?)),
|
||||||
|
_ => Err(FromBytesError::InvalidByte),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn to_bytes(&self) -> Vec<u8> {
|
||||||
|
match self {
|
||||||
|
Self::Ack => vec![0x06],
|
||||||
|
Self::Enq => vec![0x05],
|
||||||
|
Self::Eot => vec![0x04],
|
||||||
|
Self::Init => vec![0x16, 0x00, 0x00],
|
||||||
|
Self::Nack => vec![0x15],
|
||||||
|
Self::Message(protocol300_message) => protocol300_message.to_bytes(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Errors that can occur when getting a Protocol 300 Transmission from bytes
|
||||||
|
#[derive(Error, Debug, PartialEq, Eq)]
|
||||||
|
pub enum FromBytesError{
|
||||||
|
#[error("Failed to parse message")]
|
||||||
|
MessageParsing(#[from] message::MessageDecodingError),
|
||||||
|
#[error("Invalid bytes in vec")]
|
||||||
|
InvalidByte
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::{FunctionCode, MessageIdentifier, Protocol300Message, transmission::Protocol300Transmission};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_bytes_ack() {
|
||||||
|
assert_eq!(Protocol300Transmission::Ack, Protocol300Transmission::try_from_bytes(&[0x06]).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_bytes_nack() {
|
||||||
|
assert_eq!(Protocol300Transmission::Nack, Protocol300Transmission::try_from_bytes(&[0x15]).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_bytes_eot() {
|
||||||
|
assert_eq!(Protocol300Transmission::Eot, Protocol300Transmission::try_from_bytes(&[0x04]).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_bytes_enq() {
|
||||||
|
assert_eq!(Protocol300Transmission::Enq, Protocol300Transmission::try_from_bytes(&[0x05]).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_bytes_init() {
|
||||||
|
assert_eq!(Protocol300Transmission::Init, Protocol300Transmission::try_from_bytes(&[0x16, 0x00, 0x00]).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn from_bytes_message() {
|
||||||
|
let message = Protocol300Message{
|
||||||
|
data_address: 0x5525,
|
||||||
|
telegram_length: 0x09,
|
||||||
|
function_code: FunctionCode::VirtualREAD,
|
||||||
|
message_identifier: MessageIdentifier::Response,
|
||||||
|
data_length: 0x04,
|
||||||
|
data: vec![0x07, 0x01, 0x27, 0x11],
|
||||||
|
checksum: 0xC9
|
||||||
|
};
|
||||||
|
let bytes = vec![0x41, 0x09, 0x01, 0x01, 0x55, 0x25, 0x04, 0x07, 0x01, 0x27, 0x11, 0xC9];
|
||||||
|
assert_eq!(Protocol300Transmission::Message(message), Protocol300Transmission::try_from_bytes(&bytes).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_bytes_ack() {
|
||||||
|
assert_eq!(Protocol300Transmission::Ack.to_bytes(), &[0x06]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_bytes_eot() {
|
||||||
|
assert_eq!(Protocol300Transmission::Eot.to_bytes(), &[0x04]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_bytes_nack() {
|
||||||
|
assert_eq!(Protocol300Transmission::Nack.to_bytes(), &[0x15]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_bytes_enq() {
|
||||||
|
assert_eq!(Protocol300Transmission::Enq.to_bytes(), &[0x05]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_bytes_init() {
|
||||||
|
assert_eq!(Protocol300Transmission::Init.to_bytes(), &[0x16, 0x00, 0x00]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn to_bytes_message() {
|
||||||
|
let message = Protocol300Message{
|
||||||
|
data_address: 0x5525,
|
||||||
|
telegram_length: 0x09,
|
||||||
|
function_code: FunctionCode::VirtualREAD,
|
||||||
|
message_identifier: MessageIdentifier::Response,
|
||||||
|
data_length: 0x04,
|
||||||
|
data: vec![0x07, 0x01, 0x27, 0x11],
|
||||||
|
checksum: 0xC9
|
||||||
|
};
|
||||||
|
assert_eq!(Protocol300Transmission::Message(message).to_bytes(), &[0x41, 0x09, 0x01, 0x01, 0x55, 0x25, 0x04, 0x07, 0x01, 0x27, 0x11, 0xC9]);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user