diff --git a/lib-bms-protocol/src/types.rs b/lib-bms-protocol/src/types.rs index 49993b8..e034e52 100644 --- a/lib-bms-protocol/src/types.rs +++ b/lib-bms-protocol/src/types.rs @@ -74,11 +74,15 @@ impl Stored_U26 { Self((value << 6) | ((hemming_code & 0x3F) << 1) as u32) } + pub fn calc_crc6(&self) -> u8 { + calc_crc6(self.0) + } + pub fn to_be_bytes(&self) -> [u8; 4] { self.0.to_be_bytes() } - pub fn from_be_bytes(bytes: [u8; 4]) -> Result { + pub fn from_be_bytes(bytes: [u8; 4], crc: u8) -> Result { let raw_u32 = u32::from_be_bytes(bytes); // the last bit is expetced to be 0 if raw_u32 & 0x1 != 0x0 { @@ -98,7 +102,12 @@ impl Stored_U26 { // to secure against this a crc is required Err(U26Error::IncorrectibleError) } else { - Ok(Self::new(value ^ dc)) + let value = Self::new(value ^ dc); + if value.calc_crc6() == crc { + Ok(value) + } else { + Err(U26Error::IncorrectibleError) + } } } } @@ -452,11 +461,15 @@ mod base_type_tests { #[test] fn stored_u26_to_from_bytes() { let data: Stored_U26 = 0x123456.try_into().unwrap(); + let crc = data.calc_crc6(); let mut bytes = data.to_be_bytes(); - assert_eq!(Stored_U26::from_be_bytes(bytes).unwrap(), data); + assert_eq!(Stored_U26::from_be_bytes(bytes, crc).unwrap(), data); // introduce 1 bit error bytes[2] = bytes[2] ^ 0x01; - assert_eq!(Stored_U26::from_be_bytes(bytes).unwrap(), data); + assert_eq!(Stored_U26::from_be_bytes(bytes, crc).unwrap(), data); + // introduce second bit error + bytes[0] = bytes[0] ^ 0x01; + assert_eq!(Stored_U26::from_be_bytes(bytes, crc).unwrap_err(), U26Error::IncorrectibleError); } #[test]