From 6daf3a55f27e68310aceb1ddfe12fdf6d6704f0b Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Sat, 9 Oct 2021 10:57:34 -0600 Subject: [PATCH] Added examples and better error reporting + The field that errors is now reported + The formats/ dir contains all predefined formats + Includes CCSDS packet for now + There appears to be an issue with bit formatting, the APID field is not being parsed correctly (upper 8 bits is not being factored in --- formats/ccsds.toml | 43 +++++++++++++++++++++++++++++++++++++++++ src/byte_stream/mod.rs | 4 ++-- src/formatter/format.rs | 26 +++++++++++++++++++++---- src/main.rs | 2 +- 4 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 formats/ccsds.toml diff --git a/formats/ccsds.toml b/formats/ccsds.toml new file mode 100644 index 0000000..9d5766d --- /dev/null +++ b/formats/ccsds.toml @@ -0,0 +1,43 @@ +# Consultative Committee for Space Data Systems (CCSDS) Space Packet Defenition +# Primary Header + Raw Payload +# Ref: https://public.ccsds.org/Pubs/133x0b2e1.pdfa +# +# Example Packet: +# [0x08, 0x55, 0xc0, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05] + +[[formats]] +name = "ccsds" + +[[formats.fields]] +name = "Version Number" +field_type = {type = "UInt", bit_width = 3} + +[[formats.fields]] +name = "Packet Type" +field_type = {type = "UInt", bit_width = 1} + +[[formats.fields]] +name = "Secondary Header Flag" +field_type = {type = "UInt", bit_width = 1} + +[[formats.fields]] +name = "APID" +field_type = {type = "UInt", bit_width = 11} + +[[formats.fields]] +name = "Sequency Flags" +field_type = {type = "UInt", bit_width = 2} + +[[formats.fields]] +name = "Packet Sequence Count" +field_type = {type = "UInt", bit_width = 14} + +[[formats.fields]] +name = "Data Length" +field_type = {type = "UInt", bit_width = 16} + +[[formats.fields]] +name = "Data" +# Allow payloads up to the max size that can be specfied in "Data Length" +field_type = {type = "Bytes", max_len = 65535} + diff --git a/src/byte_stream/mod.rs b/src/byte_stream/mod.rs index 6a6196c..02fcf1a 100644 --- a/src/byte_stream/mod.rs +++ b/src/byte_stream/mod.rs @@ -8,7 +8,7 @@ pub enum ByteStreamError { impl Display for ByteStreamError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - ByteStreamError::OutOfRange => write!(f, "Request values out of range") + ByteStreamError::OutOfRange => write!(f, "Requested values out of range") } } } @@ -44,7 +44,7 @@ impl ByteStream { byte_count }; - if bytes_needed > self.data.len() || bytes_needed + byte_ndx > self.data.len() { + if bytes_needed > self.data.len() || (bytes_needed + byte_ndx) > self.data.len() { return Err(ByteStreamError::OutOfRange); } diff --git a/src/formatter/format.rs b/src/formatter/format.rs index c534ec9..da5a4ef 100644 --- a/src/formatter/format.rs +++ b/src/formatter/format.rs @@ -30,7 +30,7 @@ impl From for FormatError { impl Display for FormatError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - FormatError::ByteSteamError(e) => writeln!(f, "Byte steam error: {}", e), + FormatError::ByteSteamError(e) => writeln!(f, "Byte stream error: {}", e), FormatError::NotSupported => write!(f, "Field type not supported"), FormatError::StringParseError(e) => write!(f, "String parse error: {}", e) } @@ -165,9 +165,16 @@ impl Format { let mut bit_ndx: usize = 0; for field in &self.fields { - let (data_str, bit_width) = field.format_data(&byte_stream, bit_ndx)?; - bit_ndx += bit_width; - writeln!(format_str, "{}: {}", field.name, data_str).unwrap(); + match field.format_data(&byte_stream, bit_ndx) { + Ok((data_str, bit_width)) => { + bit_ndx += bit_width; + writeln!(format_str, "{}: {}", field.name, data_str).unwrap(); + } + Err(e) => { + println!("Error formatting field: \"{}\": {}", field.name, e); + return Err(e); + } + } } Ok(format_str) @@ -278,4 +285,15 @@ mod tests { assert_eq!(output, "[222, 173]") } + + #[test] + fn test_format_bytes_max_len_bigger_than_data() { + let field = Field {field_type: FieldType::Bytes {max_len: 64}, name: "test".to_string()}; + + let byte_steam = ByteStream::from(vec![0xDE, 0xAD]); + + let (output, _) = field.format_data(&byte_steam, 0).unwrap(); + + assert_eq!(output, "[222, 173]") + } } diff --git a/src/main.rs b/src/main.rs index b079cb6..b6547a6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,6 +35,6 @@ fn main() { match format.format_data(&data) { Ok(data_str) => println!("{}", data_str), - Err(e) => println!("Unable to format data: {}", e) + Err(_) => println!("Error formatting data") } }