diff --git a/example/src/main.rs b/example/src/main.rs index bba4c25..73daee0 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -124,7 +124,7 @@ fn main() -> ! { let _ = can_controller.set_filter_object(filter); // Create message frame - let message_type = Can20 {}; + let message_type = Can20::<8> {}; let payload = [1, 2, 3, 4, 5, 6, 7, 8]; let pl_bytes = Bytes::copy_from_slice(&payload); let can_message = TxMessage::new(message_type, pl_bytes, can_id).unwrap(); diff --git a/src/message.rs b/src/message.rs index c83ecff..bd49594 100644 --- a/src/message.rs +++ b/src/message.rs @@ -96,38 +96,49 @@ pub struct TxHeader { pub data_length_code: DLC, } -/// CAN 2.0 message type -#[derive(Debug, Copy, Clone)] -pub struct Can20 {} +pub trait MessageType { + /// Setup CAN message header depending on message type + fn setup_header(&self, header: &mut TxHeader, payload_length: usize) -> Result<(), DLCError>; +} -impl MessageType<8> for Can20 { - fn setup_header(&self, _header: &mut TxHeader) -> Result<(), DLCError> { +/// CAN 2.0 message type where L is the number // if payload_length > MAX_LENGTH { +#[derive(Debug, Copy, Clone)] +pub struct Can20 {} + +impl MessageType for Can20 { + fn setup_header(&self, _header: &mut TxHeader, payload_length: usize) -> Result<(), DLCError> { + if L > 8 || payload_length > 8 { + let max = payload_length.max(L); + debug!("Maximum of 8 bytes allowed. Current size: {max} bytes"); + return Err(DLCError::InvalidLength(max)); + } Ok(()) } } -/// CAN FD message type +/// CAN FD message type where L is number data bytes #[derive(Debug, Copy, Clone)] -pub struct CanFd { +pub struct CanFd { pub bitrate_switch: bool, } -impl MessageType<64> for CanFd { - fn setup_header(&self, header: &mut TxHeader) -> Result<(), DLCError> { +impl MessageType for CanFd { + fn setup_header(&self, header: &mut TxHeader, payload_length: usize) -> Result<(), DLCError> { + if L > 64 || payload_length > 64 { + let max = payload_length.max(L); + debug!("Maximum of 64 bytes allowed. Current size: {max} bytes"); + return Err(DLCError::InvalidLength(max)); + } + header.set_bit_rate_switch(self.bitrate_switch); header.set_fd_frame(true); Ok(()) } } -pub trait MessageType { - /// Setup CAN message header depending on message type - fn setup_header(&self, header: &mut TxHeader) -> Result<(), DLCError>; -} - /// Transmit Message Object #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] -pub struct TxMessage { +pub struct TxMessage, const L: usize> { /// first 2 bytes of Transmit Message Object pub(crate) header: TxHeader, /// Payload bytes of Message Object @@ -136,18 +147,13 @@ pub struct TxMessage { pub(crate) message_type: T, } -impl, const MAX_LENGTH: usize> TxMessage { +impl, const L: usize> TxMessage { pub fn new(message_type: T, data: Bytes, identifier: Id) -> Result { let mut header = TxHeader::new(); let mut payload_length = data.len(); - if payload_length > MAX_LENGTH { - debug!("Maximum of {MAX_LENGTH} bytes allowed. Current size: {payload_length} bytes"); - return Err(DLCError::InvalidLength(payload_length)); - } - - message_type.setup_header(&mut header)?; + message_type.setup_header(&mut header, payload_length)?; // length used to choose the next supported DLC while let Err(DLCError::InvalidLength(_)) = DLC::from_length(payload_length) { diff --git a/src/tests/can.rs b/src/tests/can.rs index b770946..6f64095 100644 --- a/src/tests/can.rs +++ b/src/tests/can.rs @@ -178,7 +178,7 @@ fn test_transmit_can20() { let payload: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8]; let payload_bytes = Bytes::copy_from_slice(&payload); - let msg_type = Can20 {}; + let msg_type = Can20::<8> {}; let identifier = ExtendedId::new(EXTENDED_ID).unwrap(); let tx_message = TxMessage::new(msg_type, payload_bytes, Id::Extended(identifier)).unwrap(); @@ -285,7 +285,7 @@ fn test_transmit_can_fd() { let payload = [1u8; 64]; let payload_bytes = Bytes::copy_from_slice(&payload); - let msg_type = CanFd { bitrate_switch: false }; + let msg_type = CanFd::<64> { bitrate_switch: false }; let identifier = ExtendedId::new(EXTENDED_ID).unwrap(); let tx_message = TxMessage::new(msg_type, payload_bytes, Id::Extended(identifier)).unwrap(); diff --git a/src/tests/message.rs b/src/tests/message.rs index f42d1fa..7758b5b 100644 --- a/src/tests/message.rs +++ b/src/tests/message.rs @@ -12,7 +12,7 @@ fn test_extended_id() { let payload_bytes = Bytes::copy_from_slice(&[0u8; 8]); let extended_id = ExtendedId::new(EXTENDED_ID).unwrap(); - let msg_type = Can20 {}; + let msg_type = Can20::<8> {}; let message = TxMessage::new(msg_type, payload_bytes, Id::Extended(extended_id)).unwrap(); @@ -26,7 +26,7 @@ fn test_standard_id() { let payload_bytes = Bytes::copy_from_slice(&[0u8; 8]); let standard_id = StandardId::new(STANDARD_ID).unwrap(); - let msg_type = Can20 {}; + let msg_type = Can20::<8> {}; let message = TxMessage::new(msg_type, payload_bytes, Id::Standard(standard_id)).unwrap(); @@ -40,7 +40,7 @@ fn test_dlc_success() { let payload_bytes = Bytes::copy_from_slice(&[0u8; 13]); let standard_id = StandardId::new(STANDARD_ID).unwrap(); - let msg_type = CanFd { bitrate_switch: false }; + let msg_type = CanFd::<13> { bitrate_switch: false }; let message = TxMessage::new(msg_type, payload_bytes, Id::Standard(standard_id)).unwrap(); @@ -60,8 +60,8 @@ fn test_dlc_error() { let payload_bytes_2_0 = Bytes::copy_from_slice(&data_2_0); let payload_bytes_fd = Bytes::copy_from_slice(&data_fd); - let can_msg_20 = Can20 {}; - let can_msg_fd = CanFd { bitrate_switch: false }; + let can_msg_20 = Can20::<8> {}; + let can_msg_fd = CanFd::<64> { bitrate_switch: false }; let standard_id = StandardId::new(STANDARD_ID).unwrap();