tested basic frame parser
Some checks failed
Rust/spacepackets/pipeline/head There was a failure building this commit

This commit is contained in:
Robin Müller 2024-10-08 16:24:16 +02:00
parent 0a7fa4ecf0
commit 35d48671fb

View File

@ -77,7 +77,7 @@ pub struct PrimaryHeader {
pub source_or_dest_field: SourceOrDestField, pub source_or_dest_field: SourceOrDestField,
pub vc_id: u8, pub vc_id: u8,
pub map_id: u8, pub map_id: u8,
pub frame_len: u16, frame_len_field: u16,
pub sequence_control_flag: BypassSequenceControlFlag, pub sequence_control_flag: BypassSequenceControlFlag,
pub protocol_control_command_flag: ProtocolControlCommandFlag, pub protocol_control_command_flag: ProtocolControlCommandFlag,
pub ocf_flag: bool, pub ocf_flag: bool,
@ -104,7 +104,7 @@ impl PrimaryHeader {
source_or_dest_field, source_or_dest_field,
vc_id, vc_id,
map_id, map_id,
frame_len, frame_len_field: frame_len.saturating_sub(1),
sequence_control_flag: BypassSequenceControlFlag::SequenceControlledQoS, sequence_control_flag: BypassSequenceControlFlag::SequenceControlledQoS,
protocol_control_command_flag: ProtocolControlCommandFlag::TfdfContainsUserData, protocol_control_command_flag: ProtocolControlCommandFlag::TfdfContainsUserData,
ocf_flag: false, ocf_flag: false,
@ -129,10 +129,12 @@ impl PrimaryHeader {
Ok(()) Ok(())
} }
#[inline(always)]
pub fn vc_frame_count(&self) -> u64 { pub fn vc_frame_count(&self) -> u64 {
self.vc_frame_count self.vc_frame_count
} }
#[inline(always)]
pub fn vc_frame_count_len(&self) -> u8 { pub fn vc_frame_count_len(&self) -> u8 {
self.vc_frame_count_len self.vc_frame_count_len
} }
@ -196,7 +198,7 @@ impl PrimaryHeader {
source_or_dest_field, source_or_dest_field,
vc_id: ((buf[2] & 0b111) << 3) | (buf[3] >> 5) & 0b111, vc_id: ((buf[2] & 0b111) << 3) | (buf[3] >> 5) & 0b111,
map_id: (buf[3] >> 1) & 0b1111, map_id: (buf[3] >> 1) & 0b1111,
frame_len: ((buf[4] as u16) << 8) | buf[5] as u16, frame_len_field: ((buf[4] as u16) << 8) | buf[5] as u16,
sequence_control_flag: ((buf[6] >> 7) & 0b1).try_into().unwrap(), sequence_control_flag: ((buf[6] >> 7) & 0b1).try_into().unwrap(),
protocol_control_command_flag: ((buf[6] >> 6) & 0b1).try_into().unwrap(), protocol_control_command_flag: ((buf[6] >> 6) & 0b1).try_into().unwrap(),
ocf_flag: ((buf[6] >> 3) & 0b1) != 0, ocf_flag: ((buf[6] >> 3) & 0b1) != 0,
@ -218,7 +220,7 @@ impl PrimaryHeader {
| ((self.source_or_dest_field as u8) << 3) | ((self.source_or_dest_field as u8) << 3)
| (self.vc_id >> 3) & 0b111; | (self.vc_id >> 3) & 0b111;
buf[3] = ((self.vc_id & 0b111) << 5) | (self.map_id << 1); buf[3] = ((self.vc_id & 0b111) << 5) | (self.map_id << 1);
buf[4..6].copy_from_slice(&self.frame_len.to_be_bytes()); buf[4..6].copy_from_slice(&self.frame_len_field.to_be_bytes());
buf[6] = ((self.sequence_control_flag as u8) << 7) buf[6] = ((self.sequence_control_flag as u8) << 7)
| ((self.protocol_control_command_flag as u8) << 6) | ((self.protocol_control_command_flag as u8) << 6)
| ((self.ocf_flag as u8) << 3) | ((self.ocf_flag as u8) << 3)
@ -231,6 +233,14 @@ impl PrimaryHeader {
Ok(self.len_header()) Ok(self.len_header())
} }
#[inline(always)]
pub fn set_frame_len(&mut self, frame_len: usize) {
// 4.1.2.7.2
// The field contains a length count C that equals one fewer than the total octets
// in the transfer frame.
self.frame_len_field = frame_len.saturating_sub(1) as u16;
}
#[inline(always)] #[inline(always)]
pub fn len_header(&self) -> usize { pub fn len_header(&self) -> usize {
7 + self.vc_frame_count_len as usize 7 + self.vc_frame_count_len as usize
@ -241,7 +251,7 @@ impl PrimaryHeader {
// 4.1.2.7.2 // 4.1.2.7.2
// The field contains a length count C that equals one fewer than the total octets // The field contains a length count C that equals one fewer than the total octets
// in the transfer frame. // in the transfer frame.
self.frame_len as usize + 1 self.frame_len_field as usize + 1
} }
} }
@ -253,7 +263,7 @@ impl PartialEq for PrimaryHeader {
&& self.source_or_dest_field == other.source_or_dest_field && self.source_or_dest_field == other.source_or_dest_field
&& self.vc_id == other.vc_id && self.vc_id == other.vc_id
&& self.map_id == other.map_id && self.map_id == other.map_id
&& self.frame_len == other.frame_len && self.frame_len_field == other.frame_len_field
&& self.sequence_control_flag == other.sequence_control_flag && self.sequence_control_flag == other.sequence_control_flag
&& self.protocol_control_command_flag == other.protocol_control_command_flag && self.protocol_control_command_flag == other.protocol_control_command_flag
&& self.ocf_flag == other.ocf_flag && self.ocf_flag == other.ocf_flag
@ -322,7 +332,8 @@ pub struct TransferFrameDataFieldHeader {
/// Construction rule for the TFDZ. /// Construction rule for the TFDZ.
construction_rule: ConstructionRule, construction_rule: ConstructionRule,
uslp_protocol_id: UslpProtocolId, uslp_protocol_id: UslpProtocolId,
/// First header or last valid octet pointer /// First header or last valid octet pointer. Only present if the constuction rule indicated
/// a fixed-length TFDZ.
fhp_or_lvo: Option<u16>, fhp_or_lvo: Option<u16>,
} }
@ -394,14 +405,15 @@ impl<'buf> TransferFrameReader<'buf> {
has_fecf: bool, has_fecf: bool,
) -> Result<TransferFrameReader<'buf>, UslpError> { ) -> Result<TransferFrameReader<'buf>, UslpError> {
let primary_header = PrimaryHeader::from_bytes(buf)?; let primary_header = PrimaryHeader::from_bytes(buf)?;
if primary_header.len_frame() < buf.len() { if primary_header.len_frame() > buf.len() {
return Err(ByteConversionError::FromSliceTooSmall { return Err(ByteConversionError::FromSliceTooSmall {
found: buf.len(),
expected: primary_header.len_frame(), expected: primary_header.len_frame(),
found: buf.len(),
} }
.into()); .into());
} }
let data_field_header = TransferFrameDataFieldHeader::from_bytes(buf)?; let data_field_header =
TransferFrameDataFieldHeader::from_bytes(&buf[primary_header.len_header()..])?;
let data_idx = primary_header.len_header() + data_field_header.len_header(); let data_idx = primary_header.len_header() + data_field_header.len_header();
let frame_len = primary_header.len_frame(); let frame_len = primary_header.len_frame();
let mut operational_control_field = None; let mut operational_control_field = None;
@ -433,6 +445,10 @@ impl<'buf> TransferFrameReader<'buf> {
}) })
} }
pub fn len_frame(&self) -> usize {
self.primary_header.len_frame()
}
pub fn primary_header(&self) -> &PrimaryHeader { pub fn primary_header(&self) -> &PrimaryHeader {
&self.primary_header &self.primary_header
} }
@ -452,6 +468,8 @@ impl<'buf> TransferFrameReader<'buf> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::println;
use super::*; use super::*;
fn common_basic_check(buf: &[u8]) { fn common_basic_check(buf: &[u8]) {
@ -632,5 +650,36 @@ mod tests {
} }
#[test] #[test]
fn test_frame_parsing() {} fn test_frame_parser() {
let mut buf: [u8; 32] = [0; 32];
// Build a variable frame manually.
let mut primary_header =
PrimaryHeader::new(0x01, SourceOrDestField::Dest, 0b110101, 0b1010, 0).unwrap();
let header_len = primary_header.len_header();
buf[header_len] = ((ConstructionRule::NoSegmentation as u8) << 5)
| (UslpProtocolId::UserDefinedOctetStream as u8) & 0b11111;
buf[header_len + 1] = 0x42;
// 1 byte TFDH, 1 byte data, 2 bytes CRC.
primary_header.set_frame_len(header_len + 4);
primary_header.write_to_be_bytes(&mut buf).unwrap();
// Calculate and write CRC16.
let mut digest = CRC_CCITT_FALSE.digest();
digest.update(&buf[0..header_len + 2]);
buf[header_len + 2..header_len + 4].copy_from_slice(&digest.finalize().to_be_bytes());
println!("Buffer: {:x?}", buf);
// Now parse the frame.
let frame = TransferFrameReader::from_bytes(&buf, true).unwrap();
assert_eq!(frame.data().len(), 1);
assert_eq!(frame.data()[0], 0x42);
assert_eq!(
frame.data_field_header().uslp_protocol_id,
UslpProtocolId::UserDefinedOctetStream
);
assert_eq!(
frame.data_field_header().construction_rule,
ConstructionRule::NoSegmentation
);
assert!(frame.data_field_header().fhp_or_lvo().is_none());
assert_eq!(frame.len_frame(), 11);
}
} }