diff --git a/fsrc-core/src/error.rs b/fsrc-core/src/error.rs index 8663467..e04bd13 100644 --- a/fsrc-core/src/error.rs +++ b/fsrc-core/src/error.rs @@ -6,7 +6,7 @@ pub struct FsrcErrorRaw { pub group_id: u8, pub unique_id: u8, pub group_name: &'static str, - pub error_info: &'static str, + pub info: &'static str, } pub trait FsrcErrorHandler { @@ -19,6 +19,22 @@ pub trait FsrcErrorHandler { } } +impl FsrcErrorRaw { + pub const fn new( + group_id: u8, + unique_id: u8, + group_name: &'static str, + info: &'static str, + ) -> Self { + FsrcErrorRaw { + group_id, + unique_id, + group_name, + info, + } + } +} + pub struct SimpleStdErrorHandler {} #[cfg(feature = "use_std")] @@ -26,7 +42,7 @@ impl FsrcErrorHandler for SimpleStdErrorHandler { fn error(&mut self, e: FsrcErrorRaw) { println!( "Received error from group {} with ID ({},{}): {}", - e.group_name, e.group_id, e.unique_id, e.error_info + e.group_name, e.group_id, e.unique_id, e.info ); } } diff --git a/fsrc-core/src/pool.rs b/fsrc-core/src/pool.rs index da53bd0..59ec88c 100644 --- a/fsrc-core/src/pool.rs +++ b/fsrc-core/src/pool.rs @@ -348,7 +348,7 @@ mod tests { for (i, val) in test_buf.iter_mut().enumerate() { *val = i as u8; } - let res = local_pool.add(test_buf); + let res = local_pool.add(&test_buf); assert!(res.is_ok()); let addr = res.unwrap(); // Only the second subpool has enough storage and only one bucket @@ -361,7 +361,7 @@ mod tests { ); // The subpool is now full and the call should fail accordingly - let res = local_pool.add(test_buf); + let res = local_pool.add(&test_buf); assert!(res.is_err()); let err = res.unwrap_err(); assert!(matches!(err, StoreError::StoreFull { .. })); @@ -445,7 +445,7 @@ mod tests { )); let data_too_large = [0; 20]; - let res = local_pool.add(data_too_large); + let res = local_pool.add(&data_too_large); assert!(res.is_err()); let err = res.unwrap_err(); assert_eq!(err, StoreError::DataTooLarge(20)); diff --git a/fsrc-core/src/tmtc/ccsds_distrib.rs b/fsrc-core/src/tmtc/ccsds_distrib.rs index 8fd0618..9a2b71d 100644 --- a/fsrc-core/src/tmtc/ccsds_distrib.rs +++ b/fsrc-core/src/tmtc/ccsds_distrib.rs @@ -4,13 +4,26 @@ use crate::tmtc::{ }; use spacepackets::{CcsdsPacket, PacketError, SpHeader}; -pub trait ApidHandler { - fn get_apid_handler(&self, apid: u16) -> Box; +pub trait HandlesPacketForApid { + fn get_apid_handler(&mut self, apid: u16) -> Option<&mut Box>; + fn handle_unknown_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]); } -struct CcsdsDistributor { +pub struct CcsdsDistributor { + apid_handlers: Box, error_handler: Box, - apid_handlers: Box, +} + +impl CcsdsDistributor { + pub fn new( + apid_handlers: Box, + error_handler: Box, + ) -> Self { + CcsdsDistributor { + apid_handlers, + error_handler, + } + } } impl ReceivesTc for CcsdsDistributor { @@ -36,7 +49,14 @@ impl ReceivesTc for CcsdsDistributor { return; } }; - let mut handler = self.apid_handlers.get_apid_handler(sp_header.apid()); - handler.pass_ccsds(&sp_header, tm_raw).unwrap(); + let apid = sp_header.apid(); + match self.apid_handlers.get_apid_handler(apid) { + None => { + self.apid_handlers.handle_unknown_apid(&sp_header, tm_raw); + } + Some(handler) => { + handler.pass_ccsds(&sp_header, tm_raw).ok(); + } + } } } diff --git a/fsrc-core/src/tmtc/mod.rs b/fsrc-core/src/tmtc/mod.rs index 57fda15..8fda760 100644 --- a/fsrc-core/src/tmtc/mod.rs +++ b/fsrc-core/src/tmtc/mod.rs @@ -6,23 +6,24 @@ use spacepackets::{PacketError, SpHeader}; pub mod ccsds_distrib; pub mod pus_distrib; -const RAW_PACKET_ERROR: &str = "tmtc-raw"; -const CCSDS_ERROR: &str = "tmtc-ccsds"; -const PUS_ERROR: &str = "tmtc-pus"; +const RAW_PACKET_ERROR: &str = "raw-tmtc"; +const _CCSDS_ERROR: &str = "ccsds-tmtc"; +const _PUS_ERROR: &str = "pus-tmtc"; // TODO: A macro for general and unknown errors would be nice -const FROM_BYTES_SLICE_TOO_SMALL_ERROR: FsrcErrorRaw = FsrcErrorRaw { - group_name: RAW_PACKET_ERROR, - group_id: FsrcGroupIds::Tmtc as u8, - unique_id: 0, - error_info: "FROM_BYTES_SLICE_TOO_SMALL_ERROR", -}; -const FROM_BYTES_ZEROCOPY_ERROR: FsrcErrorRaw = FsrcErrorRaw { - group_name: RAW_PACKET_ERROR, - group_id: FsrcGroupIds::Tmtc as u8, - unique_id: 1, - error_info: "FROM_BYTES_ZEROCOPY_ERROR", -}; +const FROM_BYTES_SLICE_TOO_SMALL_ERROR: FsrcErrorRaw = FsrcErrorRaw::new( + FsrcGroupIds::Tmtc as u8, + 0, + RAW_PACKET_ERROR, + "FROM_BYTES_SLICE_TOO_SMALL_ERROR", +); + +const FROM_BYTES_ZEROCOPY_ERROR: FsrcErrorRaw = FsrcErrorRaw::new( + FsrcGroupIds::Tmtc as u8, + 1, + RAW_PACKET_ERROR, + "FROM_BYTES_ZEROCOPY_ERROR", +); pub trait ReceivesTc { fn pass_tc(&mut self, tc_raw: &[u8]); @@ -35,3 +36,61 @@ pub trait ReceivesCcsds { pub trait ReceivesPus { fn pass_pus(&mut self, pus_tc: &PusTc) -> Result<(), PusError>; } + +#[cfg(test)] +mod tests { + use super::*; + use crate::error::SimpleStdErrorHandler; + use crate::tmtc::ccsds_distrib::{CcsdsDistributor, HandlesPacketForApid}; + use spacepackets::CcsdsPacket; + use std::collections::HashMap; + + #[derive(Copy, Clone)] + struct DummyCcsdsHandler {} + + impl ReceivesCcsds for DummyCcsdsHandler { + fn pass_ccsds(&mut self, header: &SpHeader, tm_raw: &[u8]) -> Result<(), PacketError> { + println!("CCSDS packet with header {:?} received", header); + println!("Raw data with len {}: {:x?}", tm_raw.len(), tm_raw); + Ok(()) + } + } + struct ApidHandler { + handler_map: HashMap>, + } + + impl ApidHandler { + pub fn add_ccsds_handler(&mut self, apid: u16, ccsds_receiver: Box) { + // TODO: Error handling + self.handler_map.insert(apid, ccsds_receiver); + } + } + impl HandlesPacketForApid for ApidHandler { + fn get_apid_handler(&mut self, apid: u16) -> Option<&mut Box> { + self.handler_map.get_mut(&apid) + } + + fn handle_unknown_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) { + println!("Packet with unknown APID {} received", sp_header.apid()); + println!("Packet with len {}: {:x?}", tc_raw.len(), tc_raw); + } + } + #[test] + fn test_distribs() { + let ccsds_handler = DummyCcsdsHandler {}; + let mut apid_handler = ApidHandler { + handler_map: HashMap::new(), + }; + let error_handler = SimpleStdErrorHandler {}; + apid_handler.add_ccsds_handler(0, Box::new(ccsds_handler)); + let mut ccsds_distrib = + CcsdsDistributor::new(Box::new(apid_handler), Box::new(error_handler)); + let mut sph = SpHeader::tc(0, 0x34, 0).unwrap(); + let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true); + let mut test_buf: [u8; 32] = [0; 32]; + pus_tc + .write_to(test_buf.as_mut_slice()) + .expect("Error writing TC to buffer"); + ccsds_distrib.pass_tc(&test_buf); + } +} diff --git a/fsrc-core/src/tmtc/pus_distrib.rs b/fsrc-core/src/tmtc/pus_distrib.rs index 0247360..7579258 100644 --- a/fsrc-core/src/tmtc/pus_distrib.rs +++ b/fsrc-core/src/tmtc/pus_distrib.rs @@ -1,6 +1,6 @@ use crate::error::FsrcErrorHandler; use crate::tmtc::{ReceivesCcsds, ReceivesPus, ReceivesTc}; -use spacepackets::ecss::PusPacket; +use spacepackets::ecss::{PusError, PusPacket}; use spacepackets::tc::PusTc; use spacepackets::{CcsdsPacket, PacketError, SpHeader}; @@ -10,7 +10,7 @@ pub trait PusServiceProvider { } pub struct PusDistributor { - error_handler: Box, + _error_handler: Box, service_provider: Box, } @@ -25,7 +25,20 @@ impl ReceivesTc for PusDistributor { impl ReceivesCcsds for PusDistributor { fn pass_ccsds(&mut self, _header: &SpHeader, tm_raw: &[u8]) -> Result<(), PacketError> { // TODO: Better error handling - let (tc, _) = PusTc::new_from_raw_slice(tm_raw).unwrap(); + let (tc, _) = match PusTc::new_from_raw_slice(tm_raw) { + Ok(tuple) => tuple, + Err(e) => { + match e { + PusError::VersionNotSupported(_) => {} + PusError::IncorrectCrc(_) => {} + PusError::RawDataTooShort(_) => {} + PusError::NoRawData => {} + PusError::CrcCalculationMissing => {} + PusError::PacketError(_) => {} + } + return Ok(()); + } + }; let mut srv_provider = self .service_provider diff --git a/spacepackets b/spacepackets index a209554..fde3fe9 160000 --- a/spacepackets +++ b/spacepackets @@ -1 +1 @@ -Subproject commit a20955437e94af164969b0d9eec2a62fac616745 +Subproject commit fde3fe9cba62b816e004a174821b2d4760003d23