diff --git a/satrs/src/tmtc/ccsds_distrib.rs b/satrs/src/tmtc/ccsds_distrib.rs index 14fbfa5..a336a2b 100644 --- a/satrs/src/tmtc/ccsds_distrib.rs +++ b/satrs/src/tmtc/ccsds_distrib.rs @@ -224,6 +224,13 @@ pub(crate) mod tests { &buf[0..size] } + pub fn generate_ping_tc_as_vec() -> Vec { + let mut sph = SpHeader::tc_unseg(0x002, 0x34, 0).unwrap(); + PusTcCreator::new_simple(&mut sph, 17, 1, None, true) + .to_vec() + .unwrap() + } + type SharedPacketQueue = Arc)>>>; pub struct BasicApidHandlerSharedQueue { pub known_packet_queue: SharedPacketQueue, @@ -324,13 +331,8 @@ pub(crate) mod tests { } #[test] - fn test_distribs_unknown_apid() { - let known_packet_queue = Arc::new(Mutex::default()); - let unknown_packet_queue = Arc::new(Mutex::default()); - let apid_handler = BasicApidHandlerSharedQueue { - known_packet_queue: known_packet_queue.clone(), - unknown_packet_queue: unknown_packet_queue.clone(), - }; + fn test_unknown_apid_handling() { + let apid_handler = BasicApidHandlerOwnedQueue::default(); let mut ccsds_distrib = CcsdsDistributor::new(apid_handler); let mut sph = SpHeader::tc_unseg(0x004, 0x34, 0).unwrap(); let pus_tc = PusTcCreator::new_simple(&mut sph, 17, 1, None, true); @@ -339,11 +341,52 @@ pub(crate) mod tests { .write_to_bytes(test_buf.as_mut_slice()) .expect("Error writing TC to buffer"); ccsds_distrib.pass_tc(&test_buf).expect("Passing TC failed"); - let recvd = unknown_packet_queue.lock().unwrap().pop_front(); - assert!(known_packet_queue.lock().unwrap().is_empty()); + assert!(ccsds_distrib.packet_handler().known_packet_queue.is_empty()); + let apid_handler = ccsds_distrib.packet_handler_mut(); + let recvd = apid_handler.unknown_packet_queue.pop_front(); assert!(recvd.is_some()); let (apid, packet) = recvd.unwrap(); assert_eq!(apid, 0x004); assert_eq!(packet.as_slice(), test_buf); } + + #[test] + fn test_ccsds_distribution() { + let mut ccsds_distrib = CcsdsDistributor::new(BasicApidHandlerOwnedQueue::default()); + let mut sph = SpHeader::tc_unseg(0x002, 0x34, 0).unwrap(); + let pus_tc = PusTcCreator::new_simple(&mut sph, 17, 1, None, true); + let tc_vec = pus_tc.to_vec().unwrap(); + ccsds_distrib + .pass_ccsds(&sph, &tc_vec) + .expect("passing CCSDS TC failed"); + let recvd = ccsds_distrib + .packet_handler_mut() + .known_packet_queue + .pop_front(); + assert!(recvd.is_some()); + let recvd = recvd.unwrap(); + assert_eq!(recvd.0, 0x002); + assert_eq!(recvd.1, tc_vec); + } + + #[test] + fn test_distribution_short_packet_fails() { + let mut ccsds_distrib = CcsdsDistributor::new(BasicApidHandlerOwnedQueue::default()); + let mut sph = SpHeader::tc_unseg(0x002, 0x34, 0).unwrap(); + let pus_tc = PusTcCreator::new_simple(&mut sph, 17, 1, None, true); + let tc_vec = pus_tc.to_vec().unwrap(); + let result = ccsds_distrib.pass_tc(&tc_vec[0..6]); + assert!(result.is_err()); + let error = result.unwrap_err(); + if let CcsdsError::ByteConversionError(ByteConversionError::FromSliceTooSmall { + found, + expected, + }) = error + { + assert_eq!(found, 6); + assert_eq!(expected, 7); + } else { + panic!("Unexpected error variant"); + } + } } diff --git a/satrs/src/tmtc/pus_distrib.rs b/satrs/src/tmtc/pus_distrib.rs index ad12937..ff0ff1d 100644 --- a/satrs/src/tmtc/pus_distrib.rs +++ b/satrs/src/tmtc/pus_distrib.rs @@ -87,14 +87,16 @@ pub trait PusServiceDistributor { /// This distributor expects the passed trait object to be [Send]able to allow more ergonomic /// usage with threads. pub struct PusDistributor, E> { - service_provider: ServiceDistributor, + service_distributor: ServiceDistributor, } impl, E> PusDistributor { pub fn new(service_provider: ServiceDistributor) -> Self { - PusDistributor { service_provider } + PusDistributor { + service_distributor: service_provider, + } } } @@ -107,8 +109,8 @@ pub enum PusDistribError { impl Display for PusDistribError { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { - PusDistribError::CustomError(e) => write!(f, "{e}"), - PusDistribError::PusError(e) => write!(f, "{e}"), + PusDistribError::CustomError(e) => write!(f, "pus distribution error: {e}"), + PusDistribError::PusError(e) => write!(f, "pus distribution error: {e}"), } } } @@ -150,7 +152,7 @@ impl, E: 'static> ReceivesE { type Error = PusDistribError; fn pass_pus_tc(&mut self, header: &SpHeader, pus_tc: &PusTcReader) -> Result<(), Self::Error> { - self.service_provider + self.service_distributor .distribute_packet(pus_tc.service(), header, pus_tc) .map_err(|e| PusDistribError::CustomError(e)) } @@ -160,26 +162,30 @@ impl, E: 'static> PusDistributor { pub fn service_distributor(&self) -> &ServiceDistributor { - &self.service_provider + &self.service_distributor } pub fn service_distributor_mut(&mut self) -> &mut ServiceDistributor { - &mut self.service_provider + &mut self.service_distributor } } #[cfg(test)] mod tests { use super::*; + use crate::queue::GenericSendError; use crate::tmtc::ccsds_distrib::tests::{ - generate_ping_tc, BasicApidHandlerOwnedQueue, BasicApidHandlerSharedQueue, + generate_ping_tc, generate_ping_tc_as_vec, BasicApidHandlerOwnedQueue, + BasicApidHandlerSharedQueue, }; use crate::tmtc::ccsds_distrib::{CcsdsDistributor, CcsdsPacketHandler}; + use alloc::format; use alloc::vec::Vec; use spacepackets::ecss::PusError; use spacepackets::CcsdsPacket; #[cfg(feature = "std")] use std::collections::VecDeque; + use std::fmt::format; #[cfg(feature = "std")] use std::sync::{Arc, Mutex}; @@ -190,6 +196,7 @@ mod tests { pub apid: u16, pub packet: Vec, } + struct PusHandlerSharedQueue(Arc>>); #[derive(Default)] @@ -295,8 +302,20 @@ mod tests { } #[test] - #[cfg(feature = "std")] - fn test_pus_distribution() { + fn test_pus_distribution_as_raw_packet() { + let mut pus_distrib = PusDistributor::new(PusHandlerOwnedQueue::default()); + let tc = generate_ping_tc_as_vec(); + let result = pus_distrib.pass_tc(&tc); + assert!(result.is_ok()); + assert_eq!(pus_distrib.service_distributor_mut().0.len(), 1); + let packet_info = pus_distrib.service_distributor_mut().0.pop_front().unwrap(); + assert_eq!(packet_info.service, 17); + assert_eq!(packet_info.apid, 0x002); + assert_eq!(packet_info.packet, tc); + } + + #[test] + fn test_pus_distribution_combined_handler() { let known_packet_queue = Arc::new(Mutex::default()); let unknown_packet_queue = Arc::new(Mutex::default()); let pus_queue = Arc::new(Mutex::default()); @@ -306,9 +325,7 @@ mod tests { unknown_packet_queue: unknown_packet_queue.clone(), }; - let pus_distrib = PusDistributor { - service_provider: pus_handler, - }; + let pus_distrib = PusDistributor::new(pus_handler); is_send(&pus_distrib); let apid_handler = ApidHandlerShared { pus_distrib, @@ -337,7 +354,7 @@ mod tests { } #[test] - fn test_accessing_distributor() { + fn test_accessing_combined_distributor() { let pus_handler = PusHandlerOwnedQueue::default(); let handler_base = BasicApidHandlerOwnedQueue::default(); let pus_distrib = PusDistributor::new(pus_handler); @@ -369,4 +386,24 @@ mod tests { assert_eq!(packet_info.apid, 0x002); assert_eq!(packet_info.packet, tc_slice); } + + #[test] + fn test_pus_distrib_error_custom_error() { + let error = PusDistribError::CustomError(GenericSendError::RxDisconnected); + let error_string = format!("{}", error); + assert_eq!( + error_string, + "pus distribution error: rx side has disconnected" + ); + } + + #[test] + fn test_pus_distrib_error_pus_error() { + let error = PusDistribError::::PusError(PusError::CrcCalculationMissing); + let error_string = format!("{}", error); + assert_eq!( + error_string, + "pus distribution error: crc16 was not calculated" + ); + } }