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 {
|
impl Display for ByteStreamError {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
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
|
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);
|
return Err(ByteStreamError::OutOfRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ impl From<FromUtf8Error> for FormatError {
|
||||||
impl Display for FormatError {
|
impl Display for FormatError {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
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::NotSupported => write!(f, "Field type not supported"),
|
||||||
FormatError::StringParseError(e) => write!(f, "String parse error: {}", e)
|
FormatError::StringParseError(e) => write!(f, "String parse error: {}", e)
|
||||||
}
|
}
|
||||||
|
@ -165,10 +165,17 @@ impl Format {
|
||||||
let mut bit_ndx: usize = 0;
|
let mut bit_ndx: usize = 0;
|
||||||
|
|
||||||
for field in &self.fields {
|
for field in &self.fields {
|
||||||
let (data_str, bit_width) = field.format_data(&byte_stream, bit_ndx)?;
|
match field.format_data(&byte_stream, bit_ndx) {
|
||||||
|
Ok((data_str, bit_width)) => {
|
||||||
bit_ndx += bit_width;
|
bit_ndx += bit_width;
|
||||||
writeln!(format_str, "{}: {}", field.name, data_str).unwrap();
|
writeln!(format_str, "{}: {}", field.name, data_str).unwrap();
|
||||||
}
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("Error formatting field: \"{}\": {}", field.name, e);
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(format_str)
|
Ok(format_str)
|
||||||
}
|
}
|
||||||
|
@ -278,4 +285,15 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(output, "[222, 173]")
|
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) {
|
match format.format_data(&data) {
|
||||||
Ok(data_str) => println!("{}", data_str),
|
Ok(data_str) => println!("{}", data_str),
|
||||||
Err(e) => println!("Unable to format data: {}", e)
|
Err(_) => println!("Error formatting data")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue