started writer function

This commit is contained in:
Robin Müller 2022-06-15 01:29:28 +02:00
parent 007cf06141
commit 7f6adcfbc3
No known key found for this signature in database
GPG Key ID: 71B58F8A3CDFA9AC
3 changed files with 60 additions and 18 deletions

View File

@ -7,7 +7,7 @@ pub trait PusPacket: CcsdsPacket {
fn ack_flags(&self) -> u8; fn ack_flags(&self) -> u8;
fn user_data(&self) -> Option<&[u8]>; fn user_data(&self) -> Option<&[u8]>;
fn crc16(&self) -> u16; fn crc16(&self) -> Option<u16>;
/// Verify that the packet is valid. PUS packets have a CRC16 checksum to do this /// Verify that the packet is valid. PUS packets have a CRC16 checksum to do this
fn verify(&mut self) -> bool; fn verify(&mut self) -> bool;
} }

View File

@ -4,6 +4,14 @@ pub mod ecss;
pub mod tc; pub mod tc;
pub mod tm; pub mod tm;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum PacketError {
/// The passed slice is too small. Returns the required size of the failed size chgeck
ToBytesSliceTooSmall(usize),
/// The [zerocopy] library failed to write to bytes
ToBytesZeroCopyError,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)] #[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone)]
pub enum PacketType { pub enum PacketType {
Tm = 0, Tm = 0,
@ -355,9 +363,13 @@ pub mod zc {
} }
} }
pub fn from_slice(slice: impl AsRef<[u8]>) -> Option<Self> { pub fn from_bytes(slice: impl AsRef<[u8]>) -> Option<Self> {
SpHeader::read_from(slice.as_ref()) SpHeader::read_from(slice.as_ref())
} }
pub fn to_bytes(&self, mut slice: impl AsMut<[u8]>) -> Option<()> {
self.write_to(slice.as_mut())
}
} }
impl CcsdsPacket for SpHeader { impl CcsdsPacket for SpHeader {
@ -515,7 +527,7 @@ mod tests {
assert_eq!(slice[4], 0x00); assert_eq!(slice[4], 0x00);
assert_eq!(slice[5], 0x00); assert_eq!(slice[5], 0x00);
let sp_header = zc::SpHeader::from_slice(slice); let sp_header = zc::SpHeader::from_bytes(slice);
assert!(sp_header.is_some()); assert!(sp_header.is_some());
let sp_header = sp_header.unwrap(); let sp_header = sp_header.unwrap();
println!("Header: {:?}", sp_header); println!("Header: {:?}", sp_header);

View File

@ -11,11 +11,25 @@ pub enum PusVersion {
pub const CRC_CCITT_FALSE: Crc<u16> = Crc::<u16>::new(&CRC_16_IBM_3740); pub const CRC_CCITT_FALSE: Crc<u16> = Crc::<u16>::new(&CRC_16_IBM_3740);
pub mod zc {
use zerocopy::{AsBytes, FromBytes, NetworkEndian, Unaligned, U16};
#[derive(FromBytes, AsBytes, Unaligned)]
#[repr(C)]
pub struct PusTcDataFieldHeader {
version_ack: u8,
service: u8,
subservice: u8,
source_id: U16<NetworkEndian>,
}
}
pub mod srd { pub mod srd {
use crate::sp;
use crate::sp::ecss::PusPacket; use crate::sp::ecss::PusPacket;
use crate::sp::srd::SpHeader; use crate::sp::srd::SpHeader;
use crate::sp::tc::{PusVersion, CRC_CCITT_FALSE}; use crate::sp::tc::{PusVersion, CRC_CCITT_FALSE};
use crate::sp::{CcsdsPacket, PacketId, PacketSequenceCtrl}; use crate::sp::{CcsdsPacket, PacketError, PacketId, PacketSequenceCtrl, PacketType};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)] #[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
@ -39,29 +53,43 @@ pub mod srd {
} }
} }
#[derive(PartialEq, Copy, Clone, Serialize, Deserialize)]
pub struct PusTc<'slice> { pub struct PusTc<'slice> {
pub sph: SpHeader, pub sph: SpHeader,
pub data_field_header: PusTcDataFieldHeader, pub data_field_header: PusTcDataFieldHeader,
raw_data: Option<&'slice [u8]>, raw_data: Option<&'slice [u8]>,
app_data: Option<&'slice [u8]>, app_data: Option<&'slice [u8]>,
crc16: u16, crc16: Option<u16>,
} }
impl<'slice> PusTc<'slice> { impl<'slice> PusTc<'slice> {
pub fn new( pub fn new(
sph: &SpHeader, sph: &mut SpHeader,
service: u8, service: u8,
subservice: u8, subservice: u8,
app_data: Option<&'slice [u8]>, app_data: Option<&'slice [u8]>,
) -> Self { ) -> Self {
sph.packet_id.ptype = PacketType::Tc;
PusTc { PusTc {
sph: sph.clone(), sph: *sph,
raw_data: None, raw_data: None,
app_data, app_data,
data_field_header: PusTcDataFieldHeader::new(service, subservice, 0b1111), data_field_header: PusTcDataFieldHeader::new(service, subservice, 0b1111),
crc16: 0, crc16: None,
} }
} }
pub fn write(&mut self, mut slice: impl AsMut<[u8]>) -> Result<(), PacketError> {
let sph_zc = sp::zc::SpHeader::from(self.sph);
if slice.as_mut().len() < 6 {
return Err(PacketError::ToBytesSliceTooSmall(6));
}
sph_zc
.to_bytes(slice)
.ok_or(PacketError::ToBytesZeroCopyError)?;
// TODO: Finish impl
Ok(())
}
} }
impl CcsdsPacket for PusTc<'_> { impl CcsdsPacket for PusTc<'_> {
fn version(&self) -> u8 { fn version(&self) -> u8 {
@ -102,7 +130,7 @@ pub mod srd {
self.app_data self.app_data
} }
fn crc16(&self) -> u16 { fn crc16(&self) -> Option<u16> {
self.crc16 self.crc16
} }
@ -120,15 +148,17 @@ pub mod srd {
} }
} }
pub mod zc { #[cfg(test)]
use zerocopy::{AsBytes, FromBytes, NetworkEndian, Unaligned, U16}; mod tests {
use crate::sp::srd::SpHeader;
use crate::sp::tc::srd::PusTc;
use postcard::to_stdvec;
#[derive(FromBytes, AsBytes, Unaligned)] #[test]
#[repr(C)] fn test_tc() {
pub struct PusTcDataFieldHeader { let mut sph = SpHeader::tc(0x42, 12).unwrap();
version_ack: u8, let pus_tc = PusTc::new(&mut sph, 1, 1, None);
service: u8, let out = to_stdvec(&pus_tc).unwrap();
subservice: u8, println!("Vector {:#04x?} with length {}", out, out.len());
source_id: U16<NetworkEndian>,
} }
} }