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 inpull/1/head
parent
4e9f4bff1d
commit
6daf3a55f2
|
@ -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}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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]")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue