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
pull/1/head
Joey Hines 2021-10-09 10:57:34 -06:00
parent 4e9f4bff1d
commit 6daf3a55f2
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
4 changed files with 68 additions and 7 deletions

43
formats/ccsds.toml 100644
View File

@ -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}

View File

@ -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);
}

View File

@ -30,7 +30,7 @@ impl From<FromUtf8Error> 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]")
}
}

View File

@ -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")
}
}