From bc9e0e4a9440b5671f94f896edae196d2d999e36 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 21 Oct 2025 12:10:26 +0200 Subject: [PATCH] Larger update - ComponentId is u32 now - Simplified TCP servers --- satrs-example/src/acs/mgm.rs | 3 +- satrs-example/src/eps/pcdu.rs | 3 +- satrs-example/src/events.rs | 3 +- satrs-example/src/hk.rs | 5 +- satrs-example/src/ids.rs | 61 ++++--- satrs-example/src/interface/tcp.rs | 11 +- satrs-example/src/interface/udp.rs | 5 +- satrs-example/src/pus/action.rs | 9 +- satrs-example/src/pus/hk.rs | 16 +- satrs-example/src/pus/mod.rs | 6 +- satrs-example/src/pus/mode.rs | 10 +- satrs-example/src/requests.rs | 3 +- satrs-example/src/tmtc/sender.rs | 31 ++-- satrs-shared/Cargo.toml | 12 +- satrs/CHANGELOG.md | 2 + satrs/Cargo.toml | 10 +- satrs/src/dev_mgmt.rs | 36 ++-- satrs/src/encoding/ccsds.rs | 30 ++-- satrs/src/encoding/cobs.rs | 21 +-- satrs/src/encoding/mod.rs | 6 +- satrs/src/hal/std/mod.rs | 4 +- satrs/src/hal/std/tcp_cobs_server.rs | 127 +++++++------- satrs/src/hal/std/tcp_server.rs | 127 ++++---------- satrs/src/hal/std/tcp_spacepackets_server.rs | 169 ++++++++++++------- satrs/src/hal/std/udp_server.rs | 18 +- satrs/src/lib.rs | 2 +- satrs/src/pus/event_man.rs | 4 +- satrs/src/pus/mod.rs | 6 +- satrs/src/pus/mode.rs | 7 +- satrs/src/pus/verification.rs | 4 +- satrs/src/request.rs | 39 ++--- satrs/src/subsystem.rs | 38 ++--- satrs/src/tmtc/mod.rs | 36 ++-- satrs/tests/mode_tree.rs | 46 ++--- satrs/tests/pus_events.rs | 4 +- satrs/tests/tcp_servers.rs | 14 +- 36 files changed, 475 insertions(+), 453 deletions(-) diff --git a/satrs-example/src/acs/mgm.rs b/satrs-example/src/acs/mgm.rs index b8c19fc..5bb18e8 100644 --- a/satrs-example/src/acs/mgm.rs +++ b/satrs-example/src/acs/mgm.rs @@ -484,6 +484,7 @@ mod tests { sync::{mpsc, Arc}, }; + use arbitrary_int::u21; use satrs::{ mode::{ModeReply, ModeRequest}, mode_tree::ModeParent, @@ -574,7 +575,7 @@ mod tests { let (request_tx, request_rx) = mpsc::sync_channel(5); let (reply_tx_to_pus, reply_rx_to_pus) = mpsc::sync_channel(5); let (reply_tx_to_parent, reply_rx_to_parent) = mpsc::sync_channel(5); - let id = UniqueApidTargetId::new(Apid::Acs.raw_value(), 1); + let id = UniqueApidTargetId::new(Apid::Acs.raw_value(), u21::new(1)); let mode_node = ModeRequestHandlerMpscBounded::new(id.into(), request_rx); let (composite_request_tx, composite_request_rx) = mpsc::channel(); let (hk_reply_tx, hk_reply_rx) = mpsc::sync_channel(10); diff --git a/satrs-example/src/eps/pcdu.rs b/satrs-example/src/eps/pcdu.rs index c6b83d7..d595d78 100644 --- a/satrs-example/src/eps/pcdu.rs +++ b/satrs-example/src/eps/pcdu.rs @@ -506,6 +506,7 @@ impl ModeChild for PcduHandler { mod tests { use std::sync::mpsc; + use arbitrary_int::u21; use satrs::{ mode::ModeRequest, power::SwitchStateBinary, request::GenericMessage, tmtc::PacketAsVec, }; @@ -572,7 +573,7 @@ mod tests { let (switch_request_tx, switch_reqest_rx) = mpsc::channel(); let shared_switch_map = Arc::new(Mutex::new(SwitchSet::default())); let mut handler = PcduHandler::new( - UniqueApidTargetId::new(Apid::Eps.raw_value(), 0), + UniqueApidTargetId::new(Apid::Eps.raw_value(), u21::new(0)), "TEST_PCDU", mode_node, composite_request_rx, diff --git a/satrs-example/src/events.rs b/satrs-example/src/events.rs index bbe25c4..bc91add 100644 --- a/satrs-example/src/events.rs +++ b/satrs-example/src/events.rs @@ -218,6 +218,7 @@ impl EventHandler { #[cfg(test)] mod tests { + use arbitrary_int::u21; use satrs::{ events_legacy::EventU32, pus::verification::VerificationReporterConfig, @@ -227,7 +228,7 @@ mod tests { use super::*; - const TEST_CREATOR_ID: UniqueApidTargetId = UniqueApidTargetId::new(u11::new(1), 2); + const TEST_CREATOR_ID: UniqueApidTargetId = UniqueApidTargetId::new(u11::new(1), u21::new(2)); const TEST_EVENT: EventU32 = EventU32::new(satrs::events_legacy::Severity::Info, 1, 1); pub struct EventManagementTestbench { diff --git a/satrs-example/src/hk.rs b/satrs-example/src/hk.rs index 44adbfb..e5bbf5d 100644 --- a/satrs-example/src/hk.rs +++ b/satrs-example/src/hk.rs @@ -1,3 +1,4 @@ +use arbitrary_int::traits::Integer as _; use derive_new::new; use satrs::hk::UniqueId; use satrs::request::UniqueApidTargetId; @@ -29,7 +30,7 @@ impl HkUniqueId { expected: 8, }); } - buf[0..4].copy_from_slice(&self.target_id.unique_id.to_be_bytes()); + buf[0..4].copy_from_slice(&self.target_id.unique_id.as_u32().to_be_bytes()); buf[4..8].copy_from_slice(&self.set_id.to_be_bytes()); Ok(8) @@ -55,7 +56,7 @@ impl PusHkHelper { ) -> Result, ByteConversionError> { let sec_header = PusTmSecondaryHeader::new(3, hk::Subservice::TmHkPacket as u8, 0, 0, timestamp); - buf[0..4].copy_from_slice(&self.component_id.unique_id.to_be_bytes()); + buf[0..4].copy_from_slice(&self.component_id.unique_id.as_u32().to_be_bytes()); buf[4..8].copy_from_slice(&set_id.to_be_bytes()); let (_, second_half) = buf.split_at_mut(8); let hk_data_len = hk_data_writer(second_half)?; diff --git a/satrs-example/src/ids.rs b/satrs-example/src/ids.rs index b52e4b3..11ae2f7 100644 --- a/satrs-example/src/ids.rs +++ b/satrs-example/src/ids.rs @@ -14,7 +14,8 @@ pub enum Apid { pub mod acs { - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Debug, PartialEq, Eq)] + #[bitbybit::bitenum(u21, exhaustive = false)] pub enum Id { Subsystem = 1, Assembly = 2, @@ -23,30 +24,32 @@ pub mod acs { } pub const SUBSYSTEM: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Subsystem as u32); + super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Subsystem.raw_value()); pub const ASSEMBLY: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Assembly as u32); + super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Assembly.raw_value()); pub const MGM0: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Mgm0 as u32); + super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Mgm0.raw_value()); pub const MGM1: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Mgm1 as u32); + super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Mgm1.raw_value()); } pub mod eps { - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Debug, PartialEq, Eq)] + #[bitbybit::bitenum(u21, exhaustive = false)] pub enum Id { Pcdu = 0, Subsystem = 1, } pub const PCDU: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Eps.raw_value(), Id::Pcdu as u32); + super::UniqueApidTargetId::new(super::Apid::Eps.raw_value(), Id::Pcdu.raw_value()); pub const SUBSYSTEM: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Eps.raw_value(), Id::Subsystem as u32); + super::UniqueApidTargetId::new(super::Apid::Eps.raw_value(), Id::Subsystem.raw_value()); } pub mod generic_pus { - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Debug, PartialEq, Eq)] + #[bitbybit::bitenum(u21, exhaustive = false)] pub enum Id { PusEventManagement = 0, PusRouting = 1, @@ -58,39 +61,49 @@ pub mod generic_pus { pub const PUS_EVENT_MANAGEMENT: super::UniqueApidTargetId = super::UniqueApidTargetId::new( super::Apid::GenericPus.raw_value(), - Id::PusEventManagement as u32, + Id::PusEventManagement.raw_value(), + ); + pub const PUS_ROUTING: super::UniqueApidTargetId = super::UniqueApidTargetId::new( + super::Apid::GenericPus.raw_value(), + Id::PusRouting.raw_value(), + ); + pub const PUS_TEST: super::UniqueApidTargetId = super::UniqueApidTargetId::new( + super::Apid::GenericPus.raw_value(), + Id::PusTest.raw_value(), + ); + pub const PUS_ACTION: super::UniqueApidTargetId = super::UniqueApidTargetId::new( + super::Apid::GenericPus.raw_value(), + Id::PusAction.raw_value(), + ); + pub const PUS_MODE: super::UniqueApidTargetId = super::UniqueApidTargetId::new( + super::Apid::GenericPus.raw_value(), + Id::PusMode.raw_value(), ); - pub const PUS_ROUTING: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusRouting as u32); - pub const PUS_TEST: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusTest as u32); - pub const PUS_ACTION: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusAction as u32); - pub const PUS_MODE: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusMode as u32); pub const PUS_HK: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusHk as u32); + super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusHk.raw_value()); } pub mod sched { - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Debug, PartialEq, Eq)] + #[bitbybit::bitenum(u21, exhaustive = false)] pub enum Id { PusSched = 0, } pub const PUS_SCHED: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Sched.raw_value(), Id::PusSched as u32); + super::UniqueApidTargetId::new(super::Apid::Sched.raw_value(), Id::PusSched.raw_value()); } pub mod tmtc { - #[derive(Debug, Copy, Clone, PartialEq, Eq)] + #[derive(Debug, PartialEq, Eq)] + #[bitbybit::bitenum(u21, exhaustive = false)] pub enum Id { UdpServer = 0, TcpServer = 1, } pub const UDP_SERVER: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Tmtc.raw_value(), Id::UdpServer as u32); + super::UniqueApidTargetId::new(super::Apid::Tmtc.raw_value(), Id::UdpServer.raw_value()); pub const TCP_SERVER: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Tmtc.raw_value(), Id::TcpServer as u32); + super::UniqueApidTargetId::new(super::Apid::Tmtc.raw_value(), Id::TcpServer.raw_value()); } diff --git a/satrs-example/src/interface/tcp.rs b/satrs-example/src/interface/tcp.rs index af0498c..b1ce05d 100644 --- a/satrs-example/src/interface/tcp.rs +++ b/satrs-example/src/interface/tcp.rs @@ -5,7 +5,7 @@ use std::{ }; use log::{info, warn}; -use satrs::tmtc::StoreAndSendError; +use satrs::hal::std::tcp_spacepackets_server::CcsdsPacketParser; use satrs::{ encoding::ccsds::{SpValidity, SpacePacketValidator}, hal::std::tcp_server::{HandledConnectionHandler, ServerConfig, TcpSpacepacketsServer}, @@ -103,16 +103,14 @@ impl PacketSource for SyncTcpTmSource { } } -pub type TcpServer = TcpSpacepacketsServer< +pub type TcpServer = TcpSpacepacketsServer< SyncTcpTmSource, ReceivesTc, SimplePacketValidator, ConnectionFinishedHandler, - (), - SendError, >; -pub struct TcpTask(pub TcpServer); +pub struct TcpTask(pub TcpServer); impl TcpTask { pub fn new( @@ -124,8 +122,7 @@ impl TcpTask { Ok(Self(TcpSpacepacketsServer::new( cfg, tm_source, - tc_sender, - SimplePacketValidator { valid_ids }, + CcsdsPacketParser::new(cfg.id, 2048, tc_sender, SimplePacketValidator { valid_ids }), ConnectionFinishedHandler::default(), None, )?)) diff --git a/satrs-example/src/interface/udp.rs b/satrs-example/src/interface/udp.rs index 08bd420..f34d56a 100644 --- a/satrs-example/src/interface/udp.rs +++ b/satrs-example/src/interface/udp.rs @@ -5,7 +5,8 @@ use std::sync::mpsc; use log::{info, warn}; use satrs::hal::std::udp_server::{ReceiveResult, UdpTcServer}; use satrs::pus::HandlingStatus; -use satrs::tmtc::{PacketAsVec, StoreAndSendError}; +use satrs::queue::GenericSendError; +use satrs::tmtc::PacketAsVec; use satrs::pool::{PoolProviderWithGuards, SharedStaticMemoryPool}; use satrs::tmtc::PacketInPool; @@ -68,7 +69,7 @@ impl UdpTmHandler for DynamicUdpTmHandler { } pub struct UdpTmtcServer { - pub udp_tc_server: UdpTcServer, + pub udp_tc_server: UdpTcServer, pub tm_handler: TmHandler, } diff --git a/satrs-example/src/pus/action.rs b/satrs-example/src/pus/action.rs index 4285fde..8f424ab 100644 --- a/satrs-example/src/pus/action.rs +++ b/satrs-example/src/pus/action.rs @@ -270,6 +270,7 @@ impl TargetedPusService for ActionServiceWrapper { #[cfg(test)] mod tests { + use arbitrary_int::traits::Integer as _; use satrs::pus::test_util::{ TEST_APID, TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1, TEST_UNIQUE_ID_0, TEST_UNIQUE_ID_1, }; @@ -452,7 +453,7 @@ mod tests { let sec_header = PusTcSecondaryHeader::new_simple(8, 128); let action_id = 5_u32; let mut app_data: [u8; 8] = [0; 8]; - app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_1.to_be_bytes()); + app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_1.as_u32().to_be_bytes()); app_data[4..8].copy_from_slice(&action_id.to_be_bytes()); let pus8_packet = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default()); @@ -521,7 +522,7 @@ mod tests { let action_id = 5_u32; let mut app_data: [u8; 8] = [0; 8]; // Invalid ID, routing should fail. - app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); + app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.as_u32().to_be_bytes()); app_data[4..8].copy_from_slice(&action_id.to_be_bytes()); let pus8_packet = PusTcCreator::new( SpHeader::new_from_apid(TEST_APID), @@ -557,7 +558,7 @@ mod tests { let action_id = 5_u32; let mut app_data: [u8; 16] = [0; 16]; // Invalid ID, routing should fail. - app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); + app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.as_u32().to_be_bytes()); app_data[4..8].copy_from_slice(&action_id.to_be_bytes()); for i in 0..8 { app_data[i + 8] = i as u8; @@ -696,7 +697,7 @@ mod tests { ReplyHandlerTestbench::new(TEST_COMPONENT_ID_0.id(), ActionReplyHandler::default()); let action_reply = ActionReplyPus::new(5_u32, ActionReplyVariant::Completed); let unrequested_reply = - GenericMessage::new(MessageMetadata::new(10_u32, 15_u64), action_reply); + GenericMessage::new(MessageMetadata::new(10_u32, 15_u32), action_reply); // Right now this function does not do a lot. We simply check that it does not panic or do // weird stuff. let result = testbench.handle_unrequested_reply(&unrequested_reply); diff --git a/satrs-example/src/pus/hk.rs b/satrs-example/src/pus/hk.rs index 36839e0..a6ee12e 100644 --- a/satrs-example/src/pus/hk.rs +++ b/satrs-example/src/pus/hk.rs @@ -303,7 +303,7 @@ impl TargetedPusService for HkServiceWrapper { #[cfg(test)] mod tests { use arbitrary_int::traits::Integer as _; - use arbitrary_int::u14; + use arbitrary_int::{u14, u21}; use satrs::pus::test_util::{ TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1, TEST_UNIQUE_ID_0, TEST_UNIQUE_ID_1, }; @@ -335,7 +335,7 @@ mod tests { let target_id = TEST_UNIQUE_ID_0; let unique_id = 5_u32; let mut app_data: [u8; 8] = [0; 8]; - app_data[0..4].copy_from_slice(&target_id.to_be_bytes()); + app_data[0..4].copy_from_slice(&target_id.as_u32().to_be_bytes()); app_data[4..8].copy_from_slice(&unique_id.to_be_bytes()); let hk_req = PusTcCreator::new_simple( @@ -365,7 +365,7 @@ mod tests { let target_id = TEST_UNIQUE_ID_0; let unique_id = 5_u32; let mut app_data: [u8; 8] = [0; 8]; - app_data[0..4].copy_from_slice(&target_id.to_be_bytes()); + app_data[0..4].copy_from_slice(&target_id.as_u32().to_be_bytes()); app_data[4..8].copy_from_slice(&unique_id.to_be_bytes()); let mut generic_check = |tc: &PusTcCreator| { let accepted_token = hk_bench.add_tc(tc); @@ -404,7 +404,7 @@ mod tests { let target_id = TEST_UNIQUE_ID_0; let unique_id = 5_u32; let mut app_data: [u8; 8] = [0; 8]; - app_data[0..4].copy_from_slice(&target_id.to_be_bytes()); + app_data[0..4].copy_from_slice(&target_id.as_u32().to_be_bytes()); app_data[4..8].copy_from_slice(&unique_id.to_be_bytes()); let mut generic_check = |tc: &PusTcCreator| { let accepted_token = hk_bench.add_tc(tc); @@ -444,7 +444,7 @@ mod tests { let unique_id = 5_u32; let mut app_data: [u8; 12] = [0; 12]; let collection_interval_factor = 5_u32; - app_data[0..4].copy_from_slice(&target_id.to_be_bytes()); + app_data[0..4].copy_from_slice(&target_id.as_u32().to_be_bytes()); app_data[4..8].copy_from_slice(&unique_id.to_be_bytes()); app_data[8..12].copy_from_slice(&collection_interval_factor.to_be_bytes()); @@ -482,8 +482,8 @@ mod tests { fn hk_reply_handler() { let mut reply_testbench = ReplyHandlerTestbench::new(TEST_COMPONENT_ID_0.id(), HkReplyHandler::default()); - let sender_id = 2_u64; - let apid_target_id = 3_u32; + let sender_id = 2_u32; + let apid_target_id = u21::new(3); let unique_id = 5_u32; let (req_id, active_req) = reply_testbench.add_tc(TEST_APID, apid_target_id, &[]); let reply = GenericMessage::new( @@ -504,7 +504,7 @@ mod tests { ReplyHandlerTestbench::new(TEST_COMPONENT_ID_1.id(), HkReplyHandler::default()); let action_reply = HkReply::new(5_u32, HkReplyVariant::Ack); let unrequested_reply = - GenericMessage::new(MessageMetadata::new(10_u32, 15_u64), action_reply); + GenericMessage::new(MessageMetadata::new(10_u32, 15_u32), action_reply); // Right now this function does not do a lot. We simply check that it does not panic or do // weird stuff. let result = testbench.handle_unrequested_reply(&unrequested_reply); diff --git a/satrs-example/src/pus/mod.rs b/satrs-example/src/pus/mod.rs index bc66116..0a83c8f 100644 --- a/satrs-example/src/pus/mod.rs +++ b/satrs-example/src/pus/mod.rs @@ -531,7 +531,7 @@ pub fn generic_pus_request_timeout_handler( pub(crate) mod tests { use std::time::Duration; - use arbitrary_int::u11; + use arbitrary_int::{u11, u21}; use satrs::pus::test_util::TEST_COMPONENT_ID_0; use satrs::pus::{MpscTmAsVecSender, PusTmVariant}; use satrs::request::RequestId; @@ -593,7 +593,7 @@ pub(crate) mod tests { pub fn add_tc( &mut self, apid: u11, - apid_target: u32, + apid_target: u21, time_stamp: &[u8], ) -> (verification::RequestId, ActivePusRequestStd) { let sp_header = SpHeader::new_from_apid(apid); @@ -722,7 +722,7 @@ pub(crate) mod tests { token: VerificationToken, time_stamp: &[u8], expected_apid: u11, - expected_apid_target: u32, + expected_apid_target: u21, ) -> Result<(ActiveRequestInfo, Request), Converter::Error> { if self.current_packet.is_none() { return Err(GenericConversionError::InvalidAppData( diff --git a/satrs-example/src/pus/mode.rs b/satrs-example/src/pus/mode.rs index 9ba8734..1089081 100644 --- a/satrs-example/src/pus/mode.rs +++ b/satrs-example/src/pus/mode.rs @@ -328,7 +328,7 @@ mod tests { let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0); let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcReadMode as u8); let mut app_data: [u8; 4] = [0; 4]; - app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); + app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.as_u32().to_be_bytes()); let tc = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default()); let token = testbench.add_tc(&tc); let (_active_req, req) = testbench @@ -345,7 +345,7 @@ mod tests { let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcSetMode as u8); let mut app_data: [u8; 4 + ModeAndSubmode::RAW_LEN] = [0; 4 + ModeAndSubmode::RAW_LEN]; let mode_and_submode = ModeAndSubmode::new(2, 1); - app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); + app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.as_u32().to_be_bytes()); mode_and_submode .write_to_be_bytes(&mut app_data[4..]) .unwrap(); @@ -370,7 +370,7 @@ mod tests { let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0); let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcAnnounceMode as u8); let mut app_data: [u8; 4] = [0; 4]; - app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); + app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.as_u32().to_be_bytes()); let tc = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default()); let token = testbench.add_tc(&tc); let (_active_req, req) = testbench @@ -387,7 +387,7 @@ mod tests { let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcAnnounceModeRecursive as u8); let mut app_data: [u8; 4] = [0; 4]; - app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); + app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.as_u32().to_be_bytes()); let tc = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default()); let token = testbench.add_tc(&tc); let (_active_req, req) = testbench @@ -404,7 +404,7 @@ mod tests { ); let mode_reply = ModeReply::ModeReply(ModeAndSubmode::new(5, 1)); let unrequested_reply = - GenericMessage::new(MessageMetadata::new(10_u32, 15_u64), mode_reply); + GenericMessage::new(MessageMetadata::new(10_u32, 15_u32), mode_reply); // Right now this function does not do a lot. We simply check that it does not panic or do // weird stuff. let result = testbench.handle_unrequested_reply(&unrequested_reply); diff --git a/satrs-example/src/requests.rs b/satrs-example/src/requests.rs index b5f817e..9b83c56 100644 --- a/satrs-example/src/requests.rs +++ b/satrs-example/src/requests.rs @@ -66,7 +66,8 @@ impl GenericRequestRouter { let apid_target_id = UniqueApidTargetId::from(id); warn!("Target APID for request: {}", apid_target_id.apid); warn!("Target Unique ID for request: {}", apid_target_id.unique_id); - let mut fail_data: [u8; 8] = [0; 8]; + let mut fail_data: [u8; core::mem::size_of::()] = + [0; core::mem::size_of::()]; fail_data.copy_from_slice(&id.to_be_bytes()); verif_reporter .completion_failure( diff --git a/satrs-example/src/tmtc/sender.rs b/satrs-example/src/tmtc/sender.rs index cb5d4ab..4d243b7 100644 --- a/satrs-example/src/tmtc/sender.rs +++ b/satrs-example/src/tmtc/sender.rs @@ -4,7 +4,7 @@ use satrs::{ pus::EcssTmSender, queue::GenericSendError, spacepackets::ecss::WritablePusPacket, - tmtc::{PacketAsVec, PacketSenderRaw, PacketSenderWithSharedPool, StoreAndSendError}, + tmtc::{PacketAsVec, PacketHandler, PacketSenderWithSharedPool}, ComponentId, }; @@ -48,26 +48,33 @@ impl EcssTmSender for TmTcSender { } } -impl PacketSenderRaw for TmTcSender { - type Error = StoreAndSendError; +impl PacketHandler for TmTcSender { + type Error = GenericSendError; - fn send_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> { + fn handle_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> { match self { TmTcSender::Static(packet_sender_with_shared_pool) => { - packet_sender_with_shared_pool.send_packet(sender_id, packet) + if let Err(e) = packet_sender_with_shared_pool.handle_packet(sender_id, packet) { + log::error!("Error sending packet via Static TM/TC sender: {:?}", e); + } + } + TmTcSender::Heap(sync_sender) => { + if let Err(e) = sync_sender.handle_packet(sender_id, packet) { + log::error!("Error sending packet via Heap TM/TC sender: {:?}", e); + } + } + TmTcSender::Mock(sender) => { + sender.handle_packet(sender_id, packet).unwrap(); } - TmTcSender::Heap(sync_sender) => sync_sender - .send_packet(sender_id, packet) - .map_err(StoreAndSendError::Send), - TmTcSender::Mock(sender) => sender.send_packet(sender_id, packet), } + Ok(()) } } -impl PacketSenderRaw for MockSender { - type Error = StoreAndSendError; +impl PacketHandler for MockSender { + type Error = GenericSendError; - fn send_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> { + fn handle_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> { let mut mut_queue = self.0.borrow_mut(); mut_queue.push_back(PacketAsVec::new(sender_id, tc_raw.to_vec())); Ok(()) diff --git a/satrs-shared/Cargo.toml b/satrs-shared/Cargo.toml index 256aa62..b6f63b1 100644 --- a/satrs-shared/Cargo.toml +++ b/satrs-shared/Cargo.toml @@ -12,16 +12,8 @@ license = "Apache-2.0" [dependencies] spacepackets = { version = ">=0.14, <=0.16", default-features = false } - -[dependencies.serde] -version = "1" -default-features = false -optional = true - -[dependencies.defmt] -version = "1" -optional = true - +serde = { version = "1", default-features = false, optional = true } +defmt = {version = "1", optional = true } [features] serde = ["dep:serde", "spacepackets/serde"] diff --git a/satrs/CHANGELOG.md b/satrs/CHANGELOG.md index 83bbfff..f03102f 100644 --- a/satrs/CHANGELOG.md +++ b/satrs/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Bump `sat-rs` edition to 2024. - Bumped `spacepackets` to v0.16 +- `ComponentId` is u32 now +- Simplified TCP servers ## Changed diff --git a/satrs/Cargo.toml b/satrs/Cargo.toml index c5f69b7..03c81d2 100644 --- a/satrs/Cargo.toml +++ b/satrs/Cargo.toml @@ -16,14 +16,14 @@ categories = ["aerospace", "aerospace::space-protocols", "no-std", "hardware-sup satrs-shared = { version = "0.2", path = "../satrs-shared" } spacepackets = { version = "0.16", default-features = false } -delegate = ">0.7, <=0.13" +delegate = "0.13" paste = "1" -derive-new = ">=0.6, <=0.7" -num_enum = { version = ">0.5, <=0.7", default-features = false } -cobs = { version = "0.4", default-features = false } +derive-new = "0.7" +num_enum = { version = "0.7", default-features = false } +cobs = { version = "0.5", default-features = false, features = ["alloc"] } thiserror = { version = "2", default-features = false } -hashbrown = { version = ">=0.14, <=0.15", optional = true } +hashbrown = { version = "0.16", optional = true } static_cell = { version = "2" } heapless = { version = "0.9", optional = true } dyn-clone = { version = "1", optional = true } diff --git a/satrs/src/dev_mgmt.rs b/satrs/src/dev_mgmt.rs index 7501e23..bf4c9e5 100644 --- a/satrs/src/dev_mgmt.rs +++ b/satrs/src/dev_mgmt.rs @@ -296,18 +296,18 @@ mod tests { fn test_mode_announce() { let mut assy_helper = DevManagerCommandingHelper::new(TransparentDevManagerHook::default()); let mode_req_sender = ModeReqSenderMock::default(); - assy_helper.add_mode_child(ExampleId::Id1 as u64, UNKNOWN_MODE); - assy_helper.add_mode_child(ExampleId::Id2 as u64, UNKNOWN_MODE); + assy_helper.add_mode_child(ExampleId::Id1 as ComponentId, UNKNOWN_MODE); + assy_helper.add_mode_child(ExampleId::Id2 as ComponentId, UNKNOWN_MODE); assy_helper .send_announce_mode_cmd_to_children(1, &mode_req_sender, false) .unwrap(); assert_eq!(mode_req_sender.requests.borrow().len(), 2); let mut req = mode_req_sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req.target_id, ExampleId::Id1 as u64); + assert_eq!(req.target_id, ExampleId::Id1 as ComponentId); assert_eq!(req.request_id, 1); assert_eq!(req.request, ModeRequest::AnnounceMode); req = mode_req_sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req.target_id, ExampleId::Id2 as u64); + assert_eq!(req.target_id, ExampleId::Id2 as ComponentId); assert_eq!(req.request_id, 1); assert_eq!(req.request, ModeRequest::AnnounceMode); } @@ -316,18 +316,18 @@ mod tests { fn test_mode_announce_recursive() { let mut assy_helper = DevManagerCommandingHelper::new(TransparentDevManagerHook::default()); let mode_req_sender = ModeReqSenderMock::default(); - assy_helper.add_mode_child(ExampleId::Id1 as u64, UNKNOWN_MODE); - assy_helper.add_mode_child(ExampleId::Id2 as u64, UNKNOWN_MODE); + assy_helper.add_mode_child(ExampleId::Id1 as ComponentId, UNKNOWN_MODE); + assy_helper.add_mode_child(ExampleId::Id2 as ComponentId, UNKNOWN_MODE); assy_helper .send_announce_mode_cmd_to_children(1, &mode_req_sender, true) .unwrap(); assert_eq!(mode_req_sender.requests.borrow().len(), 2); let mut req = mode_req_sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req.target_id, ExampleId::Id1 as u64); + assert_eq!(req.target_id, ExampleId::Id1 as ComponentId); assert_eq!(req.request_id, 1); assert_eq!(req.request, ModeRequest::AnnounceModeRecursive); req = mode_req_sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req.target_id, ExampleId::Id2 as u64); + assert_eq!(req.target_id, ExampleId::Id2 as ComponentId); assert_eq!(req.request_id, 1); assert_eq!(req.request, ModeRequest::AnnounceModeRecursive); } @@ -337,12 +337,12 @@ mod tests { let mut dev_mgmt_helper = DevManagerCommandingHelper::new(TransparentDevManagerHook::default()); let mode_req_sender = ModeReqSenderMock::default(); - dev_mgmt_helper.add_mode_child(ExampleId::Id1 as u64, UNKNOWN_MODE); + dev_mgmt_helper.add_mode_child(ExampleId::Id1 as ComponentId, UNKNOWN_MODE); let expected_mode = ModeAndSubmode::new(ExampleMode::Mode1 as u32, 0); dev_mgmt_helper .send_mode_cmd_to_one_child( 1, - ExampleId::Id1 as u64, + ExampleId::Id1 as ComponentId, expected_mode, false, &mode_req_sender, @@ -350,7 +350,7 @@ mod tests { .unwrap(); assert_eq!(mode_req_sender.requests.borrow().len(), 1); let req = mode_req_sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req.target_id, ExampleId::Id1 as u64); + assert_eq!(req.target_id, ExampleId::Id1 as ComponentId); assert_eq!(req.request_id, 1); assert_eq!( req.request, @@ -368,7 +368,7 @@ mod tests { assert_eq!(ctx.active_request_id, 1); } let reply = GenericMessage::new( - MessageMetadata::new(1, ExampleId::Id1 as u64), + MessageMetadata::new(1, ExampleId::Id1 as ComponentId), ModeReply::ModeReply(expected_mode), ); if let DevManagerHelperResult::ModeCommandingDone(ActiveModeCommandContext { @@ -387,15 +387,15 @@ mod tests { let mut dev_mgmt_helper = DevManagerCommandingHelper::new(TransparentDevManagerHook::default()); let mode_req_sender = ModeReqSenderMock::default(); - dev_mgmt_helper.add_mode_child(ExampleId::Id1 as u64, UNKNOWN_MODE); - dev_mgmt_helper.add_mode_child(ExampleId::Id2 as u64, UNKNOWN_MODE); + dev_mgmt_helper.add_mode_child(ExampleId::Id1 as ComponentId, UNKNOWN_MODE); + dev_mgmt_helper.add_mode_child(ExampleId::Id2 as ComponentId, UNKNOWN_MODE); let expected_mode = ModeAndSubmode::new(ExampleMode::Mode2 as u32, 0); dev_mgmt_helper .send_mode_cmd_to_all_children(1, expected_mode, false, &mode_req_sender) .unwrap(); assert_eq!(mode_req_sender.requests.borrow().len(), 2); let req = mode_req_sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req.target_id, ExampleId::Id1 as u64); + assert_eq!(req.target_id, ExampleId::Id1 as ComponentId); assert_eq!(req.request_id, 1); assert_eq!( req.request, @@ -405,7 +405,7 @@ mod tests { } ); let req = mode_req_sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req.target_id, ExampleId::Id2 as u64); + assert_eq!(req.target_id, ExampleId::Id2 as ComponentId); assert_eq!(req.request_id, 1); assert_eq!( req.request, @@ -424,7 +424,7 @@ mod tests { } let reply = GenericMessage::new( - MessageMetadata::new(1, ExampleId::Id1 as u64), + MessageMetadata::new(1, ExampleId::Id1 as ComponentId), ModeReply::ModeReply(expected_mode), ); assert_eq!( @@ -432,7 +432,7 @@ mod tests { DevManagerHelperResult::Busy ); let reply = GenericMessage::new( - MessageMetadata::new(1, ExampleId::Id2 as u64), + MessageMetadata::new(1, ExampleId::Id2 as ComponentId), ModeReply::ModeReply(expected_mode), ); if let DevManagerHelperResult::ModeCommandingDone(ActiveModeCommandContext { diff --git a/satrs/src/encoding/ccsds.rs b/satrs/src/encoding/ccsds.rs index 9ce5603..68365e2 100644 --- a/satrs/src/encoding/ccsds.rs +++ b/satrs/src/encoding/ccsds.rs @@ -1,6 +1,6 @@ use spacepackets::SpHeader; -use crate::{ComponentId, tmtc::PacketSenderRaw}; +use crate::{ComponentId, tmtc::PacketHandler}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum SpValidity { @@ -24,13 +24,17 @@ pub trait SpacePacketValidator { #[derive(Default, Debug, PartialEq, Eq)] pub struct ParseResult { pub packets_found: u32, - /// If an incomplete space packet was found, its start index is indicated by this value. - pub incomplete_tail_start: Option, + pub parsed_bytes: usize, + // If an incomplete space packet was found, its start index is indicated by this value. + //pub incomplete_packet_start: Option, } -/// This function parses a given buffer for tightly packed CCSDS space packets. It uses the -/// [spacepackets::SpHeader] of the CCSDS packets and a user provided [SpacePacketValidator] -/// to check whether a received space packet is relevant for processing. +/// This function parses a given buffer for tightly packed CCSDS space packets. +/// +/// Please note that it is recommended to use a proper data link layer instead to have proper +/// packet framing and to allow more reliable recovery from packet loss. +/// It uses the [spacepackets::SpHeader] of the CCSDS packets and a user provided +/// [SpacePacketValidator] to check whether a received space packet is relevant for processing. /// /// This function is also able to deal with broken tail packets at the end as long a the parser /// can read the full 7 bytes which constitue a space packet header plus one byte minimal size. @@ -41,17 +45,18 @@ pub struct ParseResult { /// [SpacePacketValidator]: /// /// 1. [SpValidity::Valid]: The parser will forward all packets to the given `packet_sender` and -/// return the number of packets found.If the [PacketSenderRaw::send_packet] calls fails, the +/// return the number of packets found.If the [PacketHandler::handle_packet] calls fails, the /// error will be returned. /// 2. [SpValidity::Invalid]: The parser assumes that the synchronization is lost and tries to /// find the start of a new space packet header by scanning all the following bytes. /// 3. [SpValidity::Skip]: The parser skips the packet using the packet length determined from the /// space packet header. +/// pub fn parse_buffer_for_ccsds_space_packets( buf: &[u8], packet_validator: &(impl SpacePacketValidator + ?Sized), sender_id: ComponentId, - packet_sender: &(impl PacketSenderRaw + ?Sized), + packet_sender: &(impl PacketHandler + ?Sized), ) -> Result { let mut parse_result = ParseResult::default(); let mut current_idx = 0; @@ -66,11 +71,12 @@ pub fn parse_buffer_for_ccsds_space_packets( let packet_size = sp_header.packet_len(); if (current_idx + packet_size) <= buf_len { packet_sender - .send_packet(sender_id, &buf[current_idx..current_idx + packet_size])?; + .handle_packet(sender_id, &buf[current_idx..current_idx + packet_size])?; parse_result.packets_found += 1; } else { // Move packet to start of buffer if applicable. - parse_result.incomplete_tail_start = Some(current_idx); + //parse_result.incomplete_packet_start = Some(current_idx); + break; } current_idx += packet_size; continue; @@ -84,6 +90,7 @@ pub fn parse_buffer_for_ccsds_space_packets( } } } + parse_result.parsed_bytes = current_idx; Ok(parse_result) } @@ -254,8 +261,7 @@ mod tests { assert!(parse_result.is_ok()); let parse_result = parse_result.unwrap(); assert_eq!(parse_result.packets_found, 1); - assert!(parse_result.incomplete_tail_start.is_some()); - let incomplete_tail_idx = parse_result.incomplete_tail_start.unwrap(); + let incomplete_tail_idx = parse_result.parsed_bytes; assert_eq!(incomplete_tail_idx, packet_len_ping); let queue = tc_cacher.tc_queue.borrow(); diff --git a/satrs/src/encoding/cobs.rs b/satrs/src/encoding/cobs.rs index c4f2d9e..0124086 100644 --- a/satrs/src/encoding/cobs.rs +++ b/satrs/src/encoding/cobs.rs @@ -1,5 +1,5 @@ -use crate::{ComponentId, tmtc::PacketSenderRaw}; -use cobs::{decode_in_place, encode, max_encoding_length}; +use crate::{ComponentId, tmtc::PacketHandler}; +use cobs::{decode_in_place, encode_including_sentinels, max_encoding_length}; /// This function encodes the given packet with COBS and also wraps the encoded packet with /// the sentinel value 0. It can be used repeatedly on the same encoded buffer by expecting @@ -37,15 +37,16 @@ pub fn encode_packet_with_cobs( if *current_idx + max_encoding_len + 2 > encoded_buf.len() { return false; } - encoded_buf[*current_idx] = 0; - *current_idx += 1; - *current_idx += encode(packet, &mut encoded_buf[*current_idx..]); - encoded_buf[*current_idx] = 0; - *current_idx += 1; + *current_idx += encode_including_sentinels(packet, &mut encoded_buf[*current_idx..]); true } -/// This function parses a given buffer for COBS encoded packets. The packet structure is +/// This function parses a given buffer for COBS encoded packets. +/// +/// Please note that, it is recommended to use [cobs::CobsDecoderOwned] or [cobs::CobsDecoder] +/// instead. +/// +/// The packet structure is /// expected to be like this, assuming a sentinel value of 0 as the packet delimiter: /// /// 0 | ... Encoded Packet Data ... | 0 | 0 | ... Encoded Packet Data ... | 0 @@ -58,7 +59,7 @@ pub fn encode_packet_with_cobs( pub fn parse_buffer_for_cobs_encoded_packets( buf: &mut [u8], sender_id: ComponentId, - packet_sender: &(impl PacketSenderRaw + ?Sized), + packet_sender: &(impl PacketHandler + ?Sized), next_write_idx: &mut usize, ) -> Result { let mut start_index_packet = 0; @@ -79,7 +80,7 @@ pub fn parse_buffer_for_cobs_encoded_packets( let decode_result = decode_in_place(&mut buf[start_index_packet..i]); if let Ok(packet_len) = decode_result { packets_found += 1; - packet_sender.send_packet( + packet_sender.handle_packet( sender_id, &buf[start_index_packet..start_index_packet + packet_len], )?; diff --git a/satrs/src/encoding/mod.rs b/satrs/src/encoding/mod.rs index e97fe95..12b192e 100644 --- a/satrs/src/encoding/mod.rs +++ b/satrs/src/encoding/mod.rs @@ -12,7 +12,7 @@ pub(crate) mod tests { use crate::{ ComponentId, - tmtc::{PacketAsVec, PacketSenderRaw}, + tmtc::{PacketAsVec, PacketHandler}, }; use super::cobs::encode_packet_with_cobs; @@ -25,10 +25,10 @@ pub(crate) mod tests { pub(crate) tc_queue: RefCell>, } - impl PacketSenderRaw for TcCacher { + impl PacketHandler for TcCacher { type Error = (); - fn send_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> { + fn handle_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> { let mut mut_queue = self.tc_queue.borrow_mut(); mut_queue.push_back(PacketAsVec::new(sender_id, tc_raw.to_vec())); Ok(()) diff --git a/satrs/src/hal/std/mod.rs b/satrs/src/hal/std/mod.rs index 50c19d7..4c25636 100644 --- a/satrs/src/hal/std/mod.rs +++ b/satrs/src/hal/std/mod.rs @@ -2,5 +2,5 @@ pub mod tcp_server; pub mod udp_server; -mod tcp_cobs_server; -mod tcp_spacepackets_server; +pub mod tcp_cobs_server; +pub mod tcp_spacepackets_server; diff --git a/satrs/src/hal/std/tcp_cobs_server.rs b/satrs/src/hal/std/tcp_cobs_server.rs index 67e7d0e..8e0a30b 100644 --- a/satrs/src/hal/std/tcp_cobs_server.rs +++ b/satrs/src/hal/std/tcp_cobs_server.rs @@ -1,5 +1,7 @@ use alloc::sync::Arc; use alloc::vec; +use cobs::CobsDecoderOwned; +use cobs::DecodeError; use cobs::encode; use core::sync::atomic::AtomicBool; use core::time::Duration; @@ -9,40 +11,58 @@ use std::io::Write; use std::net::SocketAddr; use std::vec::Vec; -use crate::encoding::parse_buffer_for_cobs_encoded_packets; -use crate::tmtc::PacketSenderRaw; +use crate::queue::GenericSendError; +use crate::tmtc::PacketHandler; use crate::tmtc::PacketSource; use crate::ComponentId; use crate::hal::std::tcp_server::{ - ConnectionResult, ServerConfig, TcpTcParser, TcpTmSender, TcpTmtcError, TcpTmtcGenericServer, + ConnectionResult, ServerConfig, TcpTcParser, TcpTmSender, TcpTmtcGenericServer, }; use super::tcp_server::HandledConnectionHandler; use super::tcp_server::HandledConnectionInfo; /// Concrete [TcpTcParser] implementation for the [TcpTmtcInCobsServer]. -#[derive(Default)] -pub struct CobsTcParser {} +pub struct CobsTcParser { + sender_id: ComponentId, + owned_decoder: CobsDecoderOwned, + packet_handler: PacketHandlerInstance, + last_decode_error: Option, +} -impl TcpTcParser for CobsTcParser { - fn handle_tc_parsing( - &mut self, - tc_buffer: &mut [u8], +impl CobsTcParser { + pub fn new( sender_id: ComponentId, - tc_sender: &(impl PacketSenderRaw + ?Sized), - conn_result: &mut HandledConnectionInfo, - current_write_idx: usize, - next_write_idx: &mut usize, - ) -> Result<(), TcpTmtcError> { - conn_result.num_received_tcs += parse_buffer_for_cobs_encoded_packets( - &mut tc_buffer[..current_write_idx], + decoder_buf_size: usize, + packet_handler: PacketHandlerInstance, + ) -> Self { + Self { sender_id, - tc_sender, - next_write_idx, - ) - .map_err(|e| TcpTmtcError::TcError(e))?; - Ok(()) + owned_decoder: CobsDecoderOwned::new(decoder_buf_size), + packet_handler, + last_decode_error: None, + } + } +} +impl TcpTcParser for CobsTcParser { + fn reset(&mut self) { + self.owned_decoder.reset(); + } + + fn push(&mut self, data: &[u8], conn_result: &mut HandledConnectionInfo) { + for byte in data { + match self.owned_decoder.feed(*byte) { + Ok(Some(packet_len)) => { + self.packet_handler + .handle_packet(self.sender_id, &self.owned_decoder.dest()[..packet_len]) + .ok(); + conn_result.num_received_tcs += 1; + } + Ok(None) => (), + Err(e) => self.last_decode_error = Some(e), + } + } } } @@ -61,22 +81,18 @@ impl CobsTmSender { } } -impl TcpTmSender for CobsTmSender { +impl TcpTmSender for CobsTmSender { fn handle_tm_sending( &mut self, tm_buffer: &mut [u8], - tm_source: &mut (impl PacketSource + ?Sized), + tm_source: &mut (impl PacketSource + ?Sized), conn_result: &mut HandledConnectionInfo, stream: &mut TcpStream, - ) -> Result> { + ) -> Result { let mut tm_was_sent = false; - loop { - // Write TM until TM source is exhausted. For now, there is no limit for the amount - // of TM written this way. - let read_tm_len = tm_source - .retrieve_packet(tm_buffer) - .map_err(|e| TcpTmtcError::TmError(e))?; - + // Write TM until TM source is exhausted or there is an unexpected error. For now, there + // is no limit for the amount of TM written this way. + while let Ok(read_tm_len) = tm_source.retrieve_packet(tm_buffer) { if read_tm_len == 0 { return Ok(tm_was_sent); } @@ -95,6 +111,7 @@ impl TcpTmSender for CobsTmSender { current_idx += 1; stream.write_all(&self.tm_encoding_buffer[..current_idx])?; } + Ok(tm_was_sent) } } @@ -108,8 +125,8 @@ impl TcpTmSender for CobsTmSender { /// /// Using a framing protocol like COBS imposes minimal restrictions on the type of TMTC data /// exchanged while also allowing packets with flexible size and a reliable way to reconstruct full -/// packets even from a data stream which is split up. The server wil use the -/// [parse_buffer_for_cobs_encoded_packets] function to parse for packets and pass them to a +/// packets even from a data stream which is split up. The server wil use the streaming +/// [CobsDecoderOwned] decoder to parse for packets and pass them to a /// generic TC receiver. The user can use [crate::encoding::encode_packet_with_cobs] to encode /// telecommands sent to the server. /// @@ -118,30 +135,19 @@ impl TcpTmSender for CobsTmSender { /// The [TCP integration tests](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs/tests/tcp_servers.rs) /// test also serves as the example application for this module. pub struct TcpTmtcInCobsServer< - TmSource: PacketSource, - TcSender: PacketSenderRaw, + TmSource: PacketSource, + TcHandler: PacketHandler, HandledConnection: HandledConnectionHandler, - TmError, - SendError: 'static, > { - pub generic_server: TcpTmtcGenericServer< - TmSource, - TcSender, - CobsTmSender, - CobsTcParser, - HandledConnection, - TmError, - SendError, - >, + pub generic_server: + TcpTmtcGenericServer, HandledConnection>, } impl< - TmSource: PacketSource, - TcReceiver: PacketSenderRaw, + TmSource: PacketSource, + TcHandler: PacketHandler, HandledConnection: HandledConnectionHandler, - TmError: 'static, - TcError: 'static, -> TcpTmtcInCobsServer +> TcpTmtcInCobsServer { /// Create a new TCP TMTC server which exchanges TMTC packets encoded with /// [COBS protocol](https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing). @@ -156,17 +162,16 @@ impl< pub fn new( cfg: ServerConfig, tm_source: TmSource, - tc_receiver: TcReceiver, + cobs_tc_parser: CobsTcParser, handled_connection: HandledConnection, stop_signal: Option>, ) -> Result { Ok(Self { generic_server: TcpTmtcGenericServer::new( cfg, - CobsTcParser::default(), + cobs_tc_parser, CobsTmSender::new(cfg.tm_buffer_size), tm_source, - tc_receiver, handled_connection, stop_signal, )?, @@ -185,7 +190,7 @@ impl< pub fn handle_all_connections( &mut self, poll_duration: Option, - ) -> Result>; + ) -> Result; } } } @@ -212,7 +217,6 @@ mod tests { ConnectionResult, ServerConfig, tests::{ConnectionFinishedHandler, SyncTmSource}, }, - queue::GenericSendError, tmtc::PacketAsVec, }; use alloc::sync::Arc; @@ -243,17 +247,12 @@ mod tests { tc_sender: mpsc::Sender, tm_source: SyncTmSource, stop_signal: Option>, - ) -> TcpTmtcInCobsServer< - SyncTmSource, - mpsc::Sender, - ConnectionFinishedHandler, - (), - GenericSendError, - > { + ) -> TcpTmtcInCobsServer, ConnectionFinishedHandler> + { TcpTmtcInCobsServer::new( ServerConfig::new(TCP_SERVER_ID, *addr, Duration::from_millis(2), 1024, 1024), tm_source, - tc_sender, + super::CobsTcParser::new(TCP_SERVER_ID, 1024, tc_sender), ConnectionFinishedHandler::default(), stop_signal, ) diff --git a/satrs/src/hal/std/tcp_server.rs b/satrs/src/hal/std/tcp_server.rs index ba5300c..a1a65ab 100644 --- a/satrs/src/hal/std/tcp_server.rs +++ b/satrs/src/hal/std/tcp_server.rs @@ -12,7 +12,7 @@ use std::net::SocketAddr; use std::thread; use crate::ComponentId; -use crate::tmtc::{PacketSenderRaw, PacketSource}; +use crate::tmtc::PacketSource; use thiserror::Error; // Re-export the TMTC in COBS server. @@ -73,11 +73,9 @@ impl ServerConfig { } #[derive(Error, Debug)] -pub enum TcpTmtcError { +pub enum TcpTmError { #[error("TM retrieval error: {0}")] TmError(TmError), - #[error("TC retrieval error: {0}")] - TcError(TcError), #[error("io error: {0}")] Io(#[from] std::io::Error), } @@ -116,32 +114,29 @@ pub trait HandledConnectionHandler { } /// Generic parser abstraction for an object which can parse for telecommands given a raw -/// bytestream received from a TCP socket and send them using a generic [PacketSenderRaw] -/// implementation. This allows different encoding schemes for telecommands. -pub trait TcpTcParser { - fn handle_tc_parsing( - &mut self, - tc_buffer: &mut [u8], - sender_id: ComponentId, - tc_sender: &(impl PacketSenderRaw + ?Sized), - conn_result: &mut HandledConnectionInfo, - current_write_idx: usize, - next_write_idx: &mut usize, - ) -> Result<(), TcpTmtcError>; +/// bytestream received from a TCP socket and extract packets from them. This allows different +/// encoding schemes for telecommands. +pub trait TcpTcParser { + /// Reset the state of the parser. + fn reset(&mut self); + + /// Pushes received data into the parser. + fn push(&mut self, tc_data: &[u8], conn_result: &mut HandledConnectionInfo); } /// Generic sender abstraction for an object which can pull telemetry from a given TM source /// using a [PacketSource] and then send them back to a client using a given [TcpStream]. /// The concrete implementation can also perform any encoding steps which are necessary before /// sending back the data to a client. -pub trait TcpTmSender { +pub trait TcpTmSender { + /// Returns whether any packets were sent back to the client. fn handle_tm_sending( &mut self, tm_buffer: &mut [u8], - tm_source: &mut (impl PacketSource + ?Sized), + tm_source: &mut (impl PacketSource + ?Sized), conn_result: &mut HandledConnectionInfo, stream: &mut TcpStream, - ) -> Result>; + ) -> Result; } /// TCP TMTC server implementation for exchange of generic TMTC packets in a generic way which @@ -151,7 +146,8 @@ pub trait TcpTmSender { /// through the following 4 core abstractions: /// /// 1. [TcpTcParser] to parse for telecommands from the raw bytestream received from a client. -/// 2. Parsed telecommands will be sent using the [PacketSenderRaw] object. +/// 2. Parsed telecommands will be handled by the [TcpTcParser] object as well. For example, this +/// parser can contain a message queue handle to send the packets somewhere. /// 3. [TcpTmSender] to send telemetry pulled from a TM source back to the client. /// 4. [PacketSource] as a generic TM source used by the [TcpTmSender]. /// @@ -163,13 +159,10 @@ pub trait TcpTmSender { /// 1. [TcpTmtcInCobsServer] to exchange TMTC wrapped inside the COBS framing protocol. /// 2. [TcpSpacepacketsServer] to exchange space packets via TCP. pub struct TcpTmtcGenericServer< - TmSource: PacketSource, - TcSender: PacketSenderRaw, - TmSender: TcpTmSender, - TcParser: TcpTcParser, + TmSource: PacketSource, + TmSender: TcpTmSender, + TcParser: TcpTcParser, HandledConnection: HandledConnectionHandler, - TmError, - TcSendError, > { pub id: ComponentId, pub finished_handler: HandledConnection, @@ -177,7 +170,6 @@ pub struct TcpTmtcGenericServer< pub(crate) inner_loop_delay: Duration, pub(crate) tm_source: TmSource, pub(crate) tm_buffer: Vec, - pub(crate) tc_sender: TcSender, pub(crate) tc_buffer: Vec, poll: Poll, events: Events, @@ -187,23 +179,11 @@ pub struct TcpTmtcGenericServer< } impl< - TmSource: PacketSource, - TcSender: PacketSenderRaw, - TmSender: TcpTmSender, - TcParser: TcpTcParser, + TmSource: PacketSource, + TmSender: TcpTmSender, + TcParser: TcpTcParser, HandledConnection: HandledConnectionHandler, - TmError: 'static, - TcSendError: 'static, -> - TcpTmtcGenericServer< - TmSource, - TcSender, - TmSender, - TcParser, - HandledConnection, - TmError, - TcSendError, - > +> TcpTmtcGenericServer { /// Create a new generic TMTC server instance. /// @@ -223,7 +203,6 @@ impl< tc_parser: TcParser, tm_sender: TmSender, tm_source: TmSource, - tc_receiver: TcSender, finished_handler: HandledConnection, stop_signal: Option>, ) -> Result { @@ -263,7 +242,6 @@ impl< inner_loop_delay: cfg.inner_loop_delay, tm_source, tm_buffer: vec![0; cfg.tm_buffer_size], - tc_sender: tc_receiver, tc_buffer: vec![0; cfg.tc_buffer_size], stop_signal, finished_handler, @@ -297,7 +275,7 @@ impl< pub fn handle_all_connections( &mut self, poll_timeout: Option, - ) -> Result> { + ) -> Result { let mut handled_connections = 0; // Poll Mio for events. self.poll.poll(&mut self.events, poll_timeout)?; @@ -327,7 +305,7 @@ impl< Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => break, Err(err) => { self.reregister_poll_interest()?; - return Err(TcpTmtcError::Io(err)); + return Err(err); } } } @@ -350,58 +328,24 @@ impl< &mut self, mut stream: TcpStream, addr: SocketAddr, - ) -> Result<(), TcpTmtcError> { - let mut current_write_idx; - let mut next_write_idx = 0; + ) -> Result<(), std::io::Error> { + self.tc_handler.reset(); let mut connection_result = HandledConnectionInfo::new(addr); - current_write_idx = next_write_idx; loop { - let read_result = stream.read(&mut self.tc_buffer[current_write_idx..]); + let read_result = stream.read(&mut self.tc_buffer); match read_result { Ok(0) => { - // Connection closed by client. If any TC was read, parse for complete packets. - // After that, break the outer loop. - if current_write_idx > 0 { - self.tc_handler.handle_tc_parsing( - &mut self.tc_buffer, - self.id, - &self.tc_sender, - &mut connection_result, - current_write_idx, - &mut next_write_idx, - )?; - } + // Connection closed by client. break; } Ok(read_len) => { - current_write_idx += read_len; - // TC buffer is full, we must parse for complete packets now. - if current_write_idx == self.tc_buffer.capacity() { - self.tc_handler.handle_tc_parsing( - &mut self.tc_buffer, - self.id, - &self.tc_sender, - &mut connection_result, - current_write_idx, - &mut next_write_idx, - )?; - current_write_idx = next_write_idx; - } + self.tc_handler + .push(&self.tc_buffer[0..read_len], &mut connection_result); } Err(e) => match e.kind() { // As per [TcpStream::set_read_timeout] documentation, this should work for // both UNIX and Windows. std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut => { - self.tc_handler.handle_tc_parsing( - &mut self.tc_buffer, - self.id, - &self.tc_sender, - &mut connection_result, - current_write_idx, - &mut next_write_idx, - )?; - current_write_idx = next_write_idx; - if !self.tm_handler.handle_tm_sending( &mut self.tm_buffer, &mut self.tm_source, @@ -426,7 +370,7 @@ impl< } } _ => { - return Err(TcpTmtcError::Io(e)); + return Err(e); } }, } @@ -502,8 +446,11 @@ pub(crate) mod tests { .connection_info .pop_back() .expect("no connection info available"); - assert_eq!(last_conn_result.num_received_tcs, num_tcs); - assert_eq!(last_conn_result.num_sent_tms, num_tms); + assert_eq!( + last_conn_result.num_received_tcs, num_tcs, + "received tcs mismatch" + ); + assert_eq!(last_conn_result.num_sent_tms, num_tms, "sent tms missmatch"); } pub fn check_no_connections_left(&self) { diff --git a/satrs/src/hal/std/tcp_spacepackets_server.rs b/satrs/src/hal/std/tcp_spacepackets_server.rs index 282589a..bf657dd 100644 --- a/satrs/src/hal/std/tcp_spacepackets_server.rs +++ b/satrs/src/hal/std/tcp_spacepackets_server.rs @@ -7,39 +7,104 @@ use std::{io::Write, net::SocketAddr}; use crate::{ ComponentId, encoding::{ccsds::SpacePacketValidator, parse_buffer_for_ccsds_space_packets}, - tmtc::{PacketSenderRaw, PacketSource}, + queue::GenericSendError, + tmtc::{PacketHandler, PacketSource}, }; use super::tcp_server::{ ConnectionResult, HandledConnectionHandler, HandledConnectionInfo, ServerConfig, TcpTcParser, - TcpTmSender, TcpTmtcError, TcpTmtcGenericServer, + TcpTmSender, TcpTmtcGenericServer, }; -impl TcpTcParser for T { - fn handle_tc_parsing( - &mut self, - tc_buffer: &mut [u8], +pub struct CcsdsPacketParser< + PacketValidator: SpacePacketValidator, + PacketHandlerInstance: PacketHandler, +> { + sender_id: ComponentId, + parsing_buffer: alloc::vec::Vec, + validator: PacketValidator, + packet_handler: PacketHandlerInstance, + current_write_index: usize, +} + +impl + CcsdsPacketParser +{ + pub fn new( sender_id: ComponentId, - tc_sender: &(impl PacketSenderRaw + ?Sized), - conn_result: &mut HandledConnectionInfo, - current_write_idx: usize, - next_write_idx: &mut usize, - ) -> Result<(), TcpTmtcError> { - // Reader vec full, need to parse for packets. - let parse_result = parse_buffer_for_ccsds_space_packets( - &tc_buffer[..current_write_idx], - self, + parsing_buf_size: usize, + packet_handler: PacketHandlerInstance, + validator: PacketValidator, + ) -> Self { + Self { sender_id, - tc_sender, - ) - .map_err(|e| TcpTmtcError::TcError(e))?; - if let Some(broken_tail_start) = parse_result.incomplete_tail_start { - // Copy broken tail to front of buffer. - tc_buffer.copy_within(broken_tail_start..current_write_idx, 0); - *next_write_idx = current_write_idx - broken_tail_start; + parsing_buffer: alloc::vec![0; parsing_buf_size], + validator, + packet_handler, + current_write_index: 0, + } + } + + fn write_to_buffer(&mut self, data: &[u8]) -> usize { + let available = self.parsing_buffer.len() - self.current_write_index; + let to_write = core::cmp::min(data.len(), available); + + self.parsing_buffer[self.current_write_index..self.current_write_index + to_write] + .copy_from_slice(&data[..to_write]); + self.current_write_index += to_write; + + to_write + } + + fn parse_and_handle_packets(&mut self) -> u32 { + match parse_buffer_for_ccsds_space_packets( + &self.parsing_buffer[..self.current_write_index], + &self.validator, + self.sender_id, + &self.packet_handler, + ) { + Ok(parse_result) => { + self.parsing_buffer + .copy_within(parse_result.parsed_bytes..self.current_write_index, 0); + self.current_write_index -= parse_result.parsed_bytes; + parse_result.packets_found + } + Err(_) => 0, + } + } + + fn drop_first_half_of_buffer(&mut self) { + let mid = self.parsing_buffer.len() / 2; + self.parsing_buffer.copy_within(mid.., 0); + self.current_write_index -= mid; + } +} +impl TcpTcParser + for CcsdsPacketParser +{ + fn reset(&mut self) { + self.current_write_index = 0; + } + + fn push(&mut self, mut tc_buffer: &[u8], conn_result: &mut HandledConnectionInfo) { + while !tc_buffer.is_empty() { + // Write as much as possible to buffer + let written = self.write_to_buffer(tc_buffer); + tc_buffer = &tc_buffer[written..]; + + // Parse for complete packets + let packets_found = self.parse_and_handle_packets(); + conn_result.num_received_tcs += packets_found; + + if tc_buffer.is_empty() { + break; + } + + // Handle buffer overflow + if self.current_write_index == self.parsing_buffer.len() { + self.drop_first_half_of_buffer(); + } } - conn_result.num_received_tcs += parse_result.packets_found; - Ok(()) } } @@ -47,21 +112,18 @@ impl TcpTcParser TcpTmSender for SpacepacketsTmSender { +impl TcpTmSender for SpacepacketsTmSender { fn handle_tm_sending( &mut self, tm_buffer: &mut [u8], - tm_source: &mut (impl PacketSource + ?Sized), + tm_source: &mut (impl PacketSource + ?Sized), conn_result: &mut HandledConnectionInfo, stream: &mut TcpStream, - ) -> Result> { + ) -> Result { let mut tm_was_sent = false; - loop { + while let Ok(read_tm_len) = tm_source.retrieve_packet(tm_buffer) { // Write TM until TM source is exhausted. For now, there is no limit for the amount // of TM written this way. - let read_tm_len = tm_source - .retrieve_packet(tm_buffer) - .map_err(|e| TcpTmtcError::TmError(e))?; if read_tm_len == 0 { return Ok(tm_was_sent); @@ -71,6 +133,7 @@ impl TcpTmSender for SpacepacketsTmSender { stream.write_all(&tm_buffer[..read_tm_len])?; } + Ok(tm_was_sent) } } @@ -88,32 +151,25 @@ impl TcpTmSender for SpacepacketsTmSender { /// The [TCP server integration tests](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs/tests/tcp_servers.rs) /// also serves as the example application for this module. pub struct TcpSpacepacketsServer< - TmSource: PacketSource, - TcSender: PacketSenderRaw, + TmSource: PacketSource, + TcSender: PacketHandler, Validator: SpacePacketValidator, HandledConnection: HandledConnectionHandler, - TmError, - SendError: 'static, > { pub generic_server: TcpTmtcGenericServer< TmSource, - TcSender, SpacepacketsTmSender, - Validator, + CcsdsPacketParser, HandledConnection, - TmError, - SendError, >, } impl< - TmSource: PacketSource, - TcSender: PacketSenderRaw, + TmSource: PacketSource, + TcSender: PacketHandler, Validator: SpacePacketValidator, HandledConnection: HandledConnectionHandler, - TmError: 'static, - TcError: 'static, -> TcpSpacepacketsServer +> TcpSpacepacketsServer { /// /// ## Parameter @@ -122,7 +178,7 @@ impl< /// * `tm_source` - Generic TM source used by the server to pull telemetry packets which are /// then sent back to the client. /// * `tc_sender` - Any received telecommands which were decoded successfully will be - /// forwarded using this [PacketSenderRaw]. + /// forwarded using this [PacketHandler]. /// * `validator` - Used to determine the space packets relevant for further processing and /// to detect broken space packets. /// * `handled_connection_hook` - Called to notify the user about a succesfully handled @@ -132,18 +188,16 @@ impl< pub fn new( cfg: ServerConfig, tm_source: TmSource, - tc_sender: TcSender, - validator: Validator, + tc_parser: CcsdsPacketParser, handled_connection_hook: HandledConnection, stop_signal: Option>, ) -> Result { Ok(Self { generic_server: TcpTmtcGenericServer::new( cfg, - validator, + tc_parser, SpacepacketsTmSender::default(), tm_source, - tc_sender, handled_connection_hook, stop_signal, )?, @@ -162,7 +216,7 @@ impl< pub fn handle_all_connections( &mut self, poll_timeout: Option - ) -> Result>; + ) -> Result; } } } @@ -197,7 +251,6 @@ mod tests { ConnectionResult, ServerConfig, tests::{ConnectionFinishedHandler, SyncTmSource}, }, - queue::GenericSendError, tmtc::PacketAsVec, }; @@ -224,23 +277,19 @@ mod tests { fn generic_tmtc_server( addr: &SocketAddr, - tc_sender: mpsc::Sender, + tc_parser: super::CcsdsPacketParser>, tm_source: SyncTmSource, - validator: SimpleValidator, stop_signal: Option>, ) -> TcpSpacepacketsServer< SyncTmSource, mpsc::Sender, SimpleValidator, ConnectionFinishedHandler, - (), - GenericSendError, > { TcpSpacepacketsServer::new( ServerConfig::new(TCP_SERVER_ID, *addr, Duration::from_millis(2), 1024, 1024), tm_source, - tc_sender, - validator, + tc_parser, ConnectionFinishedHandler::default(), stop_signal, ) @@ -256,9 +305,8 @@ mod tests { validator.0.insert(TEST_PACKET_ID_0); let mut tcp_server = generic_tmtc_server( &auto_port_addr, - tc_sender.clone(), + super::CcsdsPacketParser::new(TCP_SERVER_ID, 1024, tc_sender.clone(), validator), tm_source, - validator, None, ); let dest_addr = tcp_server @@ -347,9 +395,8 @@ mod tests { validator.0.insert(TEST_PACKET_ID_1); let mut tcp_server = generic_tmtc_server( &auto_port_addr, - tc_sender.clone(), + super::CcsdsPacketParser::new(TCP_SERVER_ID, 1024, tc_sender.clone(), validator), tm_source, - validator, None, ); let dest_addr = tcp_server diff --git a/satrs/src/hal/std/udp_server.rs b/satrs/src/hal/std/udp_server.rs index 4507871..f221907 100644 --- a/satrs/src/hal/std/udp_server.rs +++ b/satrs/src/hal/std/udp_server.rs @@ -1,6 +1,6 @@ //! Generic UDP TC server. use crate::ComponentId; -use crate::tmtc::PacketSenderRaw; +use crate::tmtc::PacketHandler; use core::fmt::Debug; use std::io::{self, ErrorKind}; use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; @@ -12,7 +12,7 @@ use std::vec::Vec; /// /// It caches all received telecomands into a vector. The maximum expected telecommand size should /// be declared upfront. This avoids dynamic allocation during run-time. The user can specify a TC -/// sender in form of a special trait object which implements [PacketSenderRaw]. For example, this +/// sender in form of a special trait object which implements [PacketHandler]. For example, this /// can be used to send the telecommands to a centralized TC source component for further /// processing and routing. /// @@ -24,7 +24,7 @@ use std::vec::Vec; /// use spacepackets::ecss::WritablePusPacket; /// use satrs::hal::std::udp_server::UdpTcServer; /// use satrs::ComponentId; -/// use satrs::tmtc::PacketSenderRaw; +/// use satrs::tmtc::PacketHandler; /// use spacepackets::SpHeader; /// use spacepackets::ecss::tc::{PusTcCreator, CreatorConfig}; /// use arbitrary_int::u11; @@ -60,7 +60,7 @@ use std::vec::Vec; /// [example code](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example/src/tmtc.rs#L67) /// on how to use this TC server. It uses the server to receive PUS telecommands on a specific port /// and then forwards them to a generic CCSDS packet receiver. -pub struct UdpTcServer, SendError> { +pub struct UdpTcServer, SendError> { pub id: ComponentId, pub socket: UdpSocket, recv_buf: Vec, @@ -78,7 +78,7 @@ pub enum ReceiveResult { Send(SendError), } -impl, SendError: Debug + 'static> +impl, SendError: Debug + 'static> UdpTcServer { pub fn new( @@ -112,7 +112,7 @@ impl, SendError: Debug + 'static> let (num_bytes, from) = res; self.sender_addr = Some(from); self.tc_sender - .send_packet(self.id, &self.recv_buf[0..num_bytes]) + .handle_packet(self.id, &self.recv_buf[0..num_bytes]) .map_err(ReceiveResult::Send)?; Ok(res) } @@ -127,7 +127,7 @@ mod tests { use crate::ComponentId; use crate::hal::std::udp_server::{ReceiveResult, UdpTcServer}; use crate::queue::GenericSendError; - use crate::tmtc::PacketSenderRaw; + use crate::tmtc::PacketHandler; use arbitrary_int::u11; use core::cell::RefCell; use spacepackets::SpHeader; @@ -146,10 +146,10 @@ mod tests { pub sent_cmds: RefCell>>, } - impl PacketSenderRaw for PingReceiver { + impl PacketHandler for PingReceiver { type Error = GenericSendError; - fn send_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> { + fn handle_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> { assert_eq!(sender_id, UDP_SERVER_ID); let mut sent_data = Vec::new(); sent_data.extend_from_slice(tc_raw); diff --git a/satrs/src/lib.rs b/satrs/src/lib.rs index 22b0cee..287a290 100644 --- a/satrs/src/lib.rs +++ b/satrs/src/lib.rs @@ -57,7 +57,7 @@ pub use spacepackets; use spacepackets::PacketId; /// Generic component ID type. -pub type ComponentId = u64; +pub type ComponentId = u32; pub trait ValidatorU16Id { fn validate(&self, id: u16) -> bool; diff --git a/satrs/src/pus/event_man.rs b/satrs/src/pus/event_man.rs index 11af4d1..8951911 100644 --- a/satrs/src/pus/event_man.rs +++ b/satrs/src/pus/event_man.rs @@ -311,7 +311,7 @@ pub mod alloc_mod { mod tests { use alloc::string::{String, ToString}; use alloc::vec; - use arbitrary_int::u11; + use arbitrary_int::{u11, u21}; use spacepackets::ecss::PusPacket; use spacepackets::ecss::event::Subservice; use spacepackets::ecss::tm::PusTmReader; @@ -325,7 +325,7 @@ mod tests { const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5); const EMPTY_STAMP: [u8; 7] = [0; 7]; const TEST_APID: u11 = u11::new(0x02); - const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05); + const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, u21::new(0x05)); fn create_basic_man_1() -> DefaultPusEventU32TmCreator { let reporter = EventReporter::new(TEST_ID.raw(), TEST_APID, 0, 128); diff --git a/satrs/src/pus/mod.rs b/satrs/src/pus/mod.rs index 90e24ff..48ef4a2 100644 --- a/satrs/src/pus/mod.rs +++ b/satrs/src/pus/mod.rs @@ -1258,7 +1258,7 @@ pub(crate) fn source_buffer_large_enough( #[cfg(any(feature = "test_util", test))] pub mod test_util { - use arbitrary_int::u11; + use arbitrary_int::{u11, u21}; use spacepackets::ecss::{tc::PusTcCreator, tm::PusTmReader}; use crate::request::UniqueApidTargetId; @@ -1269,8 +1269,8 @@ pub mod test_util { }; pub const TEST_APID: u11 = u11::new(0x101); - pub const TEST_UNIQUE_ID_0: u32 = 0x05; - pub const TEST_UNIQUE_ID_1: u32 = 0x06; + pub const TEST_UNIQUE_ID_0: u21 = u21::new(0x05); + pub const TEST_UNIQUE_ID_1: u21 = u21::new(0x06); pub const TEST_COMPONENT_ID_0: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, TEST_UNIQUE_ID_0); diff --git a/satrs/src/pus/mode.rs b/satrs/src/pus/mode.rs index 773ad90..17f9923 100644 --- a/satrs/src/pus/mode.rs +++ b/satrs/src/pus/mode.rs @@ -37,6 +37,7 @@ mod tests { use std::sync::mpsc; use crate::{ + ComponentId, mode::{ ModeAndSubmode, ModeReply, ModeReplySender, ModeRequest, ModeRequestSender, ModeRequestorAndHandlerMpsc, ModeRequestorOneChildMpsc, @@ -44,9 +45,9 @@ mod tests { request::{GenericMessage, MessageMetadata}, }; - const TEST_COMPONENT_ID_0: u64 = 5; - const TEST_COMPONENT_ID_1: u64 = 6; - const TEST_COMPONENT_ID_2: u64 = 7; + const TEST_COMPONENT_ID_0: ComponentId = 5; + const TEST_COMPONENT_ID_1: ComponentId = 6; + const TEST_COMPONENT_ID_2: ComponentId = 7; #[test] fn test_simple_mode_requestor() { diff --git a/satrs/src/pus/verification.rs b/satrs/src/pus/verification.rs index 27daa41..247317d 100644 --- a/satrs/src/pus/verification.rs +++ b/satrs/src/pus/verification.rs @@ -25,11 +25,11 @@ //! use spacepackets::SpHeader; //! use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader, CreatorConfig}; //! use spacepackets::ecss::tm::PusTmReader; -//! use arbitrary_int::u11; +//! use arbitrary_int::{u11, u21}; //! //! const EMPTY_STAMP: [u8; 7] = [0; 7]; //! const TEST_APID: u11 = u11::new(0x02); -//! const TEST_COMPONENT_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05); +//! const TEST_COMPONENT_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, u21::new(0x05)); //! //! let pool_cfg = StaticPoolConfig::new_from_subpool_cfg_tuples( //! vec![(10, 32), (10, 64), (10, 128), (10, 1024)], false diff --git a/satrs/src/request.rs b/satrs/src/request.rs index 11de9ac..087d079 100644 --- a/satrs/src/request.rs +++ b/satrs/src/request.rs @@ -1,4 +1,4 @@ -use arbitrary_int::u11; +use arbitrary_int::{prelude::*, u11, u21}; use core::{fmt, marker::PhantomData}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -29,11 +29,11 @@ pub type Apid = u11; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct UniqueApidTargetId { pub apid: Apid, - pub unique_id: u32, + pub unique_id: u21, } impl UniqueApidTargetId { - pub const fn new(apid: Apid, target: u32) -> Self { + pub const fn new(apid: Apid, target: u21) -> Self { Self { apid, unique_id: target, @@ -41,7 +41,7 @@ impl UniqueApidTargetId { } pub fn raw(&self) -> ComponentId { - ((self.apid.value() as u64) << 32) | (self.unique_id as u64) + ((self.apid.value() as u32) << 21) | (self.unique_id.value()) } pub fn id(&self) -> ComponentId { @@ -61,21 +61,21 @@ impl UniqueApidTargetId { } Ok(Self::new( tc.apid(), - u32::from_be_bytes(tc.user_data()[0..4].try_into().unwrap()), + u21::new(u32::from_be_bytes(tc.user_data()[0..4].try_into().unwrap())), )) } } -impl From for UniqueApidTargetId { - fn from(raw: u64) -> Self { +impl From for UniqueApidTargetId { + fn from(raw: ComponentId) -> Self { Self { - apid: u11::new((raw >> 32) as u16), - unique_id: raw as u32, + apid: u11::new((raw >> 21) as u16), + unique_id: u21::new(raw & u21::MAX.value()), } } } -impl From for u64 { +impl From for ComponentId { fn from(target_and_apid_id: UniqueApidTargetId) -> Self { target_and_apid_id.raw() } @@ -497,7 +497,7 @@ mod tests { use std::sync::mpsc; use alloc::string::ToString; - use arbitrary_int::{u11, u14}; + use arbitrary_int::{u11, u14, u21}; use spacepackets::{ ByteConversionError, SpHeader, ecss::{ @@ -507,27 +507,28 @@ mod tests { }; use crate::{ + ComponentId, queue::{GenericReceiveError, GenericSendError}, request::{Apid, MessageMetadata, MessageSenderMap, MessageSenderStoreProvider}, }; use super::{GenericMessage, MessageReceiverWithId, UniqueApidTargetId}; - const TEST_CHANNEL_ID_0: u64 = 1; - const TEST_CHANNEL_ID_1: u64 = 2; - const TEST_CHANNEL_ID_2: u64 = 3; + const TEST_CHANNEL_ID_0: ComponentId = 1; + const TEST_CHANNEL_ID_1: ComponentId = 2; + const TEST_CHANNEL_ID_2: ComponentId = 3; #[test] fn test_basic_target_id_with_apid() { - let id = UniqueApidTargetId::new(Apid::new(0x111), 0x01); + let id = UniqueApidTargetId::new(Apid::new(0x111), u21::new(0x01)); assert_eq!(id.apid.value(), 0x111); - assert_eq!(id.unique_id, 0x01); + assert_eq!(id.unique_id.value(), 0x01); assert_eq!(id.id(), id.raw()); - assert_eq!(u64::from(id), id.raw()); + assert_eq!(ComponentId::from(id), id.raw()); let id_raw = id.raw(); let id_from_raw = UniqueApidTargetId::from(id_raw); assert_eq!(id_from_raw, id); - assert_eq!(id.id(), (0x111 << 32) | 0x01); + assert_eq!(id.id(), (0x111 << 21) | 0x01); let string = id.to_string(); assert_eq!( string, @@ -543,7 +544,7 @@ mod tests { PusTcCreator::new_simple(sp_header, 17, 1, &app_data, CreatorConfig::default()); let id = UniqueApidTargetId::from_pus_tc(&pus_tc).unwrap(); assert_eq!(id.apid.value(), 0x111); - assert_eq!(id.unique_id, 1); + assert_eq!(id.unique_id.value(), 1); } #[test] diff --git a/satrs/src/subsystem.rs b/satrs/src/subsystem.rs index 578f22f..09836ed 100644 --- a/satrs/src/subsystem.rs +++ b/satrs/src/subsystem.rs @@ -782,7 +782,7 @@ mod tests { ); assert_eq!(self.sender.requests.borrow().len(), 2); let req_0 = self.sender.requests.get_mut().pop_front().unwrap(); - assert_eq!(req_0.target_id, ExampleTargetId::Target0 as u64); + assert_eq!(req_0.target_id, ExampleTargetId::Target0 as ComponentId); assert_eq!(req_0.request_id, expected_req_id); assert_eq!( req_0.request, @@ -792,7 +792,7 @@ mod tests { } ); let req_1 = self.sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req_1.target_id, ExampleTargetId::Target1 as u64); + assert_eq!(req_1.target_id, ExampleTargetId::Target1 as ComponentId); assert_eq!( req_1.request, ModeRequest::SetMode { @@ -808,7 +808,7 @@ mod tests { ); assert_eq!(self.sender.requests.borrow().len(), 1); let req_0 = self.sender.requests.get_mut().pop_front().unwrap(); - assert_eq!(req_0.target_id, ExampleTargetId::Target2 as u64); + assert_eq!(req_0.target_id, ExampleTargetId::Target2 as ComponentId); assert_eq!(req_0.request_id, expected_req_id); assert_eq!( req_0.request, @@ -827,7 +827,7 @@ mod tests { assert_eq!(self.execution_helper.current_sequence_index().unwrap(), 0); assert_eq!(self.sender.requests.borrow().len(), 2); let req_0 = self.sender.requests.get_mut().pop_front().unwrap(); - assert_eq!(req_0.target_id, ExampleTargetId::Target0 as u64); + assert_eq!(req_0.target_id, ExampleTargetId::Target0 as ComponentId); assert_eq!(req_0.request_id, expected_req_id); assert_eq!( req_0.request, @@ -837,7 +837,7 @@ mod tests { } ); let req_1 = self.sender.requests.borrow_mut().pop_front().unwrap(); - assert_eq!(req_1.target_id, ExampleTargetId::Target1 as u64); + assert_eq!(req_1.target_id, ExampleTargetId::Target1 as ComponentId); assert_eq!( req_1.request, ModeRequest::SetMode { @@ -850,9 +850,9 @@ mod tests { fn create_default_mode_store() -> ModeStoreVec { let mut mode_store = ModeStoreVec::default(); - mode_store.add_component(ExampleTargetId::Target0 as u64, UNKNOWN_MODE); - mode_store.add_component(ExampleTargetId::Target1 as u64, UNKNOWN_MODE); - mode_store.add_component(ExampleTargetId::Target2 as u64, UNKNOWN_MODE); + mode_store.add_component(ExampleTargetId::Target0 as ComponentId, UNKNOWN_MODE); + mode_store.add_component(ExampleTargetId::Target1 as ComponentId, UNKNOWN_MODE); + mode_store.add_component(ExampleTargetId::Target2 as ComponentId, UNKNOWN_MODE); mode_store } @@ -863,13 +863,13 @@ mod tests { let mut table_seq_0 = SequenceTableMapTable::new("MODE_0_SEQ_0"); table_seq_0.add_entry(SequenceTableEntry::new( "TARGET_0", - ExampleTargetId::Target0 as u64, + ExampleTargetId::Target0 as ComponentId, SUBSYSTEM_MD0_TGT0_MODE, false, )); table_seq_0.add_entry(SequenceTableEntry::new( "TARGET_1", - ExampleTargetId::Target1 as u64, + ExampleTargetId::Target1 as ComponentId, SUBSYSTEM_MD0_TGT1_MODE, false, )); @@ -881,13 +881,13 @@ mod tests { let mut table_seq_0 = SequenceTableMapTable::new("MODE_1_SEQ_0"); table_seq_0.add_entry(SequenceTableEntry::new( "MD1_SEQ0_TGT0", - ExampleTargetId::Target0 as u64, + ExampleTargetId::Target0 as ComponentId, SUBSYSTEM_MD1_ST0_TGT0_MODE, false, )); table_seq_0.add_entry(SequenceTableEntry::new( "MD1_SEQ0_TGT1", - ExampleTargetId::Target1 as u64, + ExampleTargetId::Target1 as ComponentId, SUBSYSTEM_MD1_ST0_TGT1_MODE, false, )); @@ -895,7 +895,7 @@ mod tests { let mut table_seq_1 = SequenceTableMapTable::new("MODE_1_SEQ_1"); table_seq_1.add_entry(SequenceTableEntry::new( "MD1_SEQ1_TGT2", - ExampleTargetId::Target2 as u64, + ExampleTargetId::Target2 as ComponentId, SUBSYSTEM_MD1_ST1_TGT2_MODE, false, )); @@ -1263,11 +1263,11 @@ mod tests { assert_eq!(req.request, ModeRequest::AnnounceModeRecursive); }; let req0 = tb.sender.requests.borrow_mut().pop_front().unwrap(); - check_req(req0, ExampleTargetId::Target0 as u64); + check_req(req0, ExampleTargetId::Target0 as ComponentId); let req1 = tb.sender.requests.borrow_mut().pop_front().unwrap(); - check_req(req1, ExampleTargetId::Target1 as u64); + check_req(req1, ExampleTargetId::Target1 as ComponentId); let req2 = tb.sender.requests.borrow_mut().pop_front().unwrap(); - check_req(req2, ExampleTargetId::Target2 as u64); + check_req(req2, ExampleTargetId::Target2 as ComponentId); } #[test] @@ -1283,11 +1283,11 @@ mod tests { assert_eq!(req.request, ModeRequest::AnnounceMode); }; let req0 = tb.sender.requests.borrow_mut().pop_front().unwrap(); - check_req(req0, ExampleTargetId::Target0 as u64); + check_req(req0, ExampleTargetId::Target0 as ComponentId); let req1 = tb.sender.requests.borrow_mut().pop_front().unwrap(); - check_req(req1, ExampleTargetId::Target1 as u64); + check_req(req1, ExampleTargetId::Target1 as ComponentId); let req2 = tb.sender.requests.borrow_mut().pop_front().unwrap(); - check_req(req2, ExampleTargetId::Target2 as u64); + check_req(req2, ExampleTargetId::Target2 as ComponentId); } #[test] diff --git a/satrs/src/tmtc/mod.rs b/satrs/src/tmtc/mod.rs index 3768a1e..ab2e9f3 100644 --- a/satrs/src/tmtc/mod.rs +++ b/satrs/src/tmtc/mod.rs @@ -50,20 +50,20 @@ impl PacketInPool { /// Generic trait for object which can send any packets in form of a raw bytestream, with /// no assumptions about the received protocol. -pub trait PacketSenderRaw: Send { +pub trait PacketHandler: Send { type Error; - fn send_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error>; + fn handle_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error>; } -/// Extension trait of [PacketSenderRaw] which allows downcasting by implementing [Downcast]. +/// Extension trait of [PacketHandler] which allows downcasting by implementing [Downcast]. #[cfg(feature = "alloc")] -pub trait PacketSenderRawExt: PacketSenderRaw + Downcast { +pub trait PacketSenderRawExt: PacketHandler + Downcast { // Remove this once trait upcasting coercion has been implemented. // Tracking issue: https://github.com/rust-lang/rust/issues/65991 - fn upcast(&self) -> &dyn PacketSenderRaw; + fn upcast(&self) -> &dyn PacketHandler; // Remove this once trait upcasting coercion has been implemented. // Tracking issue: https://github.com/rust-lang/rust/issues/65991 - fn upcast_mut(&mut self) -> &mut dyn PacketSenderRaw; + fn upcast_mut(&mut self) -> &mut dyn PacketHandler; } /// Blanket implementation to automatically implement [PacketSenderRawExt] when the [alloc] @@ -71,16 +71,16 @@ pub trait PacketSenderRawExt: PacketSenderRaw + Downcast { #[cfg(feature = "alloc")] impl PacketSenderRawExt for T where - T: PacketSenderRaw + Send + 'static, + T: PacketHandler + Send + 'static, { // Remove this once trait upcasting coercion has been implemented. // Tracking issue: https://github.com/rust-lang/rust/issues/65991 - fn upcast(&self) -> &dyn PacketSenderRaw { + fn upcast(&self) -> &dyn PacketHandler { self } // Remove this once trait upcasting coercion has been implemented. // Tracking issue: https://github.com/rust-lang/rust/issues/65991 - fn upcast_mut(&mut self) -> &mut dyn PacketSenderRaw { + fn upcast_mut(&mut self) -> &mut dyn PacketHandler { self } } @@ -288,19 +288,19 @@ pub mod std_mod { } } - impl PacketSenderRaw for mpsc::Sender { + impl PacketHandler for mpsc::Sender { type Error = GenericSendError; - fn send_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> { + fn handle_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> { self.send(PacketAsVec::new(sender_id, packet.to_vec())) .map_err(|_| GenericSendError::RxDisconnected) } } - impl PacketSenderRaw for mpsc::SyncSender { + impl PacketHandler for mpsc::SyncSender { type Error = GenericSendError; - fn send_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> { + fn handle_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> { self.try_send(PacketAsVec::new(sender_id, tc_raw.to_vec())) .map_err(|e| match e { mpsc::TrySendError::Full(_) => GenericSendError::QueueFull(None), @@ -402,12 +402,12 @@ pub mod std_mod { } } - impl PacketSenderRaw + impl PacketHandler for PacketSenderWithSharedPool { type Error = StoreAndSendError; - fn send_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> { + fn handle_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> { let mut shared_pool = self.shared_pool.borrow_mut(); let store_addr = shared_pool.add_raw_tc(packet)?; drop(shared_pool); @@ -450,7 +450,7 @@ pub mod std_mod { _sp_header: &SpHeader, tc_raw: &[u8], ) -> Result<(), Self::Error> { - self.send_packet(sender_id, tc_raw) + self.handle_packet(sender_id, tc_raw) } } @@ -494,10 +494,10 @@ pub(crate) mod tests { pub(crate) fn send_with_sender( sender_id: ComponentId, - packet_sender: &(impl PacketSenderRaw + ?Sized), + packet_sender: &(impl PacketHandler + ?Sized), packet: &[u8], ) -> Result<(), SendError> { - packet_sender.send_packet(sender_id, packet) + packet_sender.handle_packet(sender_id, packet) } #[test] diff --git a/satrs/tests/mode_tree.rs b/satrs/tests/mode_tree.rs index 5fee024..a0b0327 100644 --- a/satrs/tests/mode_tree.rs +++ b/satrs/tests/mode_tree.rs @@ -45,7 +45,7 @@ pub enum AcsMode { } #[derive(Debug, TryFromPrimitive)] -#[repr(u64)] +#[repr(u32)] pub enum TestComponentId { MagnetometerDevice0 = 1, MagnetometerDevice1 = 2, @@ -299,7 +299,7 @@ struct AcsSubsystem { impl AcsSubsystem { pub fn id() -> ComponentId { - TestComponentId::AcsSubsystem as u64 + TestComponentId::AcsSubsystem as ComponentId } pub fn new(mode_node: ModeRequestorAndHandlerMpscBounded) -> Self { @@ -518,7 +518,7 @@ struct MgmAssembly { impl MgmAssembly { pub fn id() -> ComponentId { - TestComponentId::MagnetometerAssembly as u64 + TestComponentId::MagnetometerAssembly as ComponentId } pub fn new(mode_node: ModeRequestorAndHandlerMpscBounded) -> Self { Self { @@ -923,7 +923,7 @@ impl ModeRequestHandler for CommonDevice { mode_and_submode: ModeAndSubmode, forced: bool, ) -> Result<(), ModeError> { - if self.id() == TestComponentId::MagnetorquerDevice as u64 { + if self.id() == TestComponentId::MagnetorquerDevice as ComponentId { println!("test"); } self.mode_and_submode = mode_and_submode; @@ -996,7 +996,7 @@ pub struct AcsController { impl AcsController { pub fn id() -> ComponentId { - TestComponentId::AcsController as u64 + TestComponentId::AcsController as ComponentId } pub fn new(mode_node: ModeRequestHandlerMpscBounded) -> Self { Self { @@ -1020,7 +1020,7 @@ impl AcsController { impl ModeNode for AcsController { fn id(&self) -> ComponentId { - TestComponentId::AcsController as u64 + TestComponentId::AcsController as ComponentId } } @@ -1185,22 +1185,22 @@ impl TreeTestbench { let mut mgm_dev_0 = CommonDevice::new( "MGM_0", - TestComponentId::MagnetometerDevice0 as u64, + TestComponentId::MagnetometerDevice0 as ComponentId, mgm_dev_node_0, ); let mut mgm_dev_1 = CommonDevice::new( "MGM_1", - TestComponentId::MagnetometerDevice1 as u64, + TestComponentId::MagnetometerDevice1 as ComponentId, mgm_dev_node_1, ); let mut mgt_dev = CommonDevice::new( "MGT", - TestComponentId::MagnetorquerDevice as u64, + TestComponentId::MagnetorquerDevice as ComponentId, mgt_dev_node, ); let mut mgt_manager = DeviceManager::new( "MGT_MANAGER", - TestComponentId::MgtDevManager as u64, + TestComponentId::MgtDevManager as ComponentId, mgt_dev_mgmt_node, ); let mut mgm_assy = MgmAssembly::new(mgm_assy_node); @@ -1212,38 +1212,38 @@ impl TreeTestbench { let mut target_table_safe = TargetTablesMapValue::new("SAFE_TARGET_TBL", None); target_table_safe.add_entry(TargetTableEntry::new( "CTRL_SAFE", - TestComponentId::AcsController as u64, + TestComponentId::AcsController as ComponentId, ModeAndSubmode::new(AcsMode::SAFE as u32, 0), // All submodes allowed. Some(0xffff), )); target_table_safe.add_entry(TargetTableEntry::new_with_precise_submode( "MGM_A_NML", - TestComponentId::MagnetometerAssembly as u64, + TestComponentId::MagnetometerAssembly as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0), )); target_table_safe.add_entry(TargetTableEntry::new_with_precise_submode( "MGT_MAN_NML", - TestComponentId::MgtDevManager as u64, + TestComponentId::MgtDevManager as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0), )); let mut sequence_tbl_safe_0 = SequenceTableMapTable::new("SAFE_SEQ_0_TBL"); sequence_tbl_safe_0.add_entry(SequenceTableEntry::new( "SAFE_SEQ_0_MGM_A", - TestComponentId::MagnetometerAssembly as u64, + TestComponentId::MagnetometerAssembly as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as Mode, 0), false, )); sequence_tbl_safe_0.add_entry(SequenceTableEntry::new( "SAFE_SEQ_0_MGT_MAN", - TestComponentId::MgtDevManager as u64, + TestComponentId::MgtDevManager as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as Mode, 0), false, )); let mut sequence_tbl_safe_1 = SequenceTableMapTable::new("SAFE_SEQ_1_TBL"); sequence_tbl_safe_1.add_entry(SequenceTableEntry::new( "SAFE_SEQ_1_ACS_CTRL", - TestComponentId::AcsController as u64, + TestComponentId::AcsController as ComponentId, ModeAndSubmode::new(AcsMode::SAFE as Mode, 0), false, )); @@ -1408,7 +1408,7 @@ fn announce_recursively() { fn generic_mode_reply_checker( reply_meta: MessageMetadata, mode_and_submode: ModeAndSubmode, - expected_modes: &mut HashMap, + expected_modes: &mut HashMap, ) { let id = TestComponentId::try_from(reply_meta.sender_id()).expect("invalid sender id"); if !expected_modes.contains_key(&reply_meta.sender_id()) { @@ -1528,15 +1528,15 @@ fn command_safe_mode() { ); let mut expected_modes = HashMap::new(); expected_modes.insert( - TestComponentId::AcsController as u64, + TestComponentId::AcsController as ComponentId, ModeAndSubmode::new(AcsMode::SAFE as u32, 0), ); expected_modes.insert( - TestComponentId::MagnetometerAssembly as u64, + TestComponentId::MagnetometerAssembly as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0), ); expected_modes.insert( - TestComponentId::MgtDevManager as u64, + TestComponentId::MgtDevManager as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0), ); while let Some(reply) = tb.subsystem.mode_reply_mock.mode_reply_messages.pop_front() { @@ -1558,11 +1558,11 @@ fn command_safe_mode() { ); let mut expected_modes = HashMap::new(); expected_modes.insert( - TestComponentId::MagnetometerDevice0 as u64, + TestComponentId::MagnetometerDevice0 as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0), ); expected_modes.insert( - TestComponentId::MagnetometerDevice1 as u64, + TestComponentId::MagnetometerDevice1 as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0), ); while let Some(reply) = tb.mgm_assy.mode_reply_mock.mode_reply_messages.pop_front() { @@ -1578,7 +1578,7 @@ fn command_safe_mode() { ); let mut expected_modes = HashMap::new(); expected_modes.insert( - TestComponentId::MagnetorquerDevice as u64, + TestComponentId::MagnetorquerDevice as ComponentId, ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0), ); let reply = tb diff --git a/satrs/tests/pus_events.rs b/satrs/tests/pus_events.rs index 0dd26dc..cc0a060 100644 --- a/satrs/tests/pus_events.rs +++ b/satrs/tests/pus_events.rs @@ -1,4 +1,4 @@ -use arbitrary_int::u11; +use arbitrary_int::{u11, u21}; use satrs::event_man_legacy::{ EventManagerWithMpsc, EventMessage, EventMessageU32, EventRoutingError, EventSendProvider, EventU32SenderMpsc, @@ -18,7 +18,7 @@ const INFO_EVENT: EventU32TypedSev = EventU32TypedSev::