diff --git a/satrs-example/src/interface/udp.rs b/satrs-example/src/interface/udp.rs index d7816e2..e7720bb 100644 --- a/satrs-example/src/interface/udp.rs +++ b/satrs-example/src/interface/udp.rs @@ -3,14 +3,13 @@ use std::net::{SocketAddr, UdpSocket}; use std::sync::mpsc; use log::{info, warn}; +use satrs::pus::HandlingStatus; use satrs::tmtc::{PacketAsVec, PacketInPool, PacketSenderRaw}; use satrs::{ hal::std::udp_server::{ReceiveResult, UdpTcServer}, pool::{PoolProviderWithGuards, SharedStaticMemoryPool}, }; -use crate::pus::HandlingStatus; - pub trait UdpTmHandler { fn send_tm_to_udp_client(&mut self, socket: &UdpSocket, recv_addr: &SocketAddr); } diff --git a/satrs-example/src/pus/action.rs b/satrs-example/src/pus/action.rs index 7f4e76f..445ad86 100644 --- a/satrs-example/src/pus/action.rs +++ b/satrs-example/src/pus/action.rs @@ -1,4 +1,4 @@ -use log::{error, warn}; +use log::warn; use satrs::action::{ActionRequest, ActionRequestVariant}; use satrs::pool::SharedStaticMemoryPool; use satrs::pus::action::{ @@ -12,7 +12,7 @@ use satrs::pus::verification::{ use satrs::pus::{ ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTmSender, EcssTmtcError, GenericConversionError, MpscTcReceiver, - MpscTmAsVecSender, PusPacketHandlerResult, PusReplyHandler, PusServiceHelper, + MpscTmAsVecSender, PusPacketHandlingError, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter, }; use satrs::request::{GenericMessage, UniqueApidTargetId}; @@ -278,43 +278,23 @@ pub struct ActionServiceWrapper TargetedPusService for ActionServiceWrapper { - /// Returns [true] if the packet handling is finished. - fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus { - match self.service.poll_and_handle_next_tc(time_stamp) { - Ok(result) => match result { - PusPacketHandlerResult::RequestHandled => {} - PusPacketHandlerResult::RequestHandledPartialSuccess(e) => { - warn!("PUS 8 partial packet handling success: {e:?}") - } - PusPacketHandlerResult::CustomSubservice(invalid, _) => { - warn!("PUS 8 invalid subservice {invalid}"); - } - PusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { - warn!("PUS 8 subservice {subservice} not implemented"); - } - PusPacketHandlerResult::Empty => return HandlingStatus::Empty, - }, - Err(error) => { - error!("PUS packet handling error: {error:?}"); - // To avoid permanent loops on error cases. - return HandlingStatus::Empty; - } + const SERVICE_ID: u8 = 8; + const SERVICE_STR: &'static str = "action"; + + delegate::delegate! { + to self.service { + fn poll_and_handle_next_tc( + &mut self, + time_stamp: &[u8], + ) -> Result; + + fn poll_and_handle_next_reply( + &mut self, + time_stamp: &[u8], + ) -> Result; + + fn check_for_request_timeouts(&mut self); } - HandlingStatus::HandledOne - } - - fn poll_and_handle_next_reply(&mut self, time_stamp: &[u8]) -> HandlingStatus { - // This only fails if all senders disconnected. Treat it like an empty queue. - self.service - .poll_and_check_next_reply(time_stamp) - .unwrap_or_else(|e| { - warn!("PUS 8: Handling reply failed with error {e:?}"); - HandlingStatus::Empty - }) - } - - fn check_for_request_timeouts(&mut self) { - self.service.check_for_request_timeouts(); } } @@ -429,7 +409,7 @@ mod tests { } let result = result.unwrap(); match result { - PusPacketHandlerResult::RequestHandled => (), + HandlingStatus::HandledOne => (), _ => panic!("unexpected result {result:?}"), } } @@ -441,19 +421,19 @@ mod tests { } let result = result.unwrap(); match result { - PusPacketHandlerResult::Empty => (), + HandlingStatus::Empty => (), _ => panic!("unexpected result {result:?}"), } } pub fn verify_next_reply_is_handled_properly(&mut self, time_stamp: &[u8]) { - let result = self.service.poll_and_check_next_reply(time_stamp); + let result = self.service.poll_and_handle_next_reply(time_stamp); assert!(result.is_ok()); assert_eq!(result.unwrap(), HandlingStatus::HandledOne); } pub fn verify_all_replies_handled(&mut self, time_stamp: &[u8]) { - let result = self.service.poll_and_check_next_reply(time_stamp); + let result = self.service.poll_and_handle_next_reply(time_stamp); assert!(result.is_ok()); assert_eq!(result.unwrap(), HandlingStatus::Empty); } diff --git a/satrs-example/src/pus/event.rs b/satrs-example/src/pus/event.rs index 4726ba0..2f96ba9 100644 --- a/satrs-example/src/pus/event.rs +++ b/satrs-example/src/pus/event.rs @@ -7,8 +7,9 @@ use satrs::pus::event_man::EventRequestWithToken; use satrs::pus::event_srv::PusEventServiceHandler; use satrs::pus::verification::VerificationReporter; use satrs::pus::{ - EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, - EcssTmSender, MpscTcReceiver, MpscTmAsVecSender, PusPacketHandlerResult, PusServiceHelper, + DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConverter, + EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTmSender, MpscTcReceiver, + MpscTmAsVecSender, PartialPusHandlingError, PusServiceHelper, }; use satrs::tmtc::{PacketAsVec, PacketSenderWithSharedPool}; use satrs_example::config::components::PUS_EVENT_MANAGEMENT; @@ -65,22 +66,24 @@ impl EventServiceWrapper { pub fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus { - match self.handler.poll_and_handle_next_tc(time_stamp) { + let error_handler = |partial_error: &PartialPusHandlingError| { + log::warn!("PUS 5 partial error: {:?}", partial_error); + }; + match self + .handler + .poll_and_handle_next_tc(error_handler, time_stamp) + { Ok(result) => match result { - PusPacketHandlerResult::RequestHandled => {} - PusPacketHandlerResult::RequestHandledPartialSuccess(e) => { - warn!("PUS 5 partial packet handling success: {e:?}") - } - PusPacketHandlerResult::CustomSubservice(invalid, _) => { + DirectPusPacketHandlerResult::Handled(handling_status) => return handling_status, + DirectPusPacketHandlerResult::CustomSubservice(invalid, _) => { warn!("PUS 5 invalid subservice {invalid}"); } - PusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { + DirectPusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { warn!("PUS 5 subservice {subservice} not implemented"); } - PusPacketHandlerResult::Empty => return HandlingStatus::Empty, }, Err(error) => { - error!("PUS packet handling error: {error:?}") + error!("PUS 5 packet handling error: {error:?}") } } HandlingStatus::HandledOne diff --git a/satrs-example/src/pus/hk.rs b/satrs-example/src/pus/hk.rs index bbecf19..33e01ac 100644 --- a/satrs-example/src/pus/hk.rs +++ b/satrs-example/src/pus/hk.rs @@ -1,5 +1,4 @@ use derive_new::new; -use log::{error, warn}; use satrs::hk::{CollectionIntervalFactor, HkRequest, HkRequestVariant, UniqueId}; use satrs::pool::SharedStaticMemoryPool; use satrs::pus::verification::{ @@ -10,7 +9,7 @@ use satrs::pus::{ ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap, EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTmSender, EcssTmtcError, GenericConversionError, MpscTcReceiver, MpscTmAsVecSender, - PusPacketHandlerResult, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter, + PusPacketHandlingError, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter, }; use satrs::request::{GenericMessage, UniqueApidTargetId}; use satrs::spacepackets::ecss::tc::PusTcReader; @@ -24,7 +23,7 @@ use std::time::Duration; use crate::pus::{create_verification_reporter, generic_pus_request_timeout_handler}; use crate::requests::GenericRequestRouter; -use super::{HandlingStatus, PusTargetedRequestService}; +use super::{HandlingStatus, PusTargetedRequestService, TargetedPusService}; #[derive(Clone, PartialEq, Debug, new)] pub struct HkReply { @@ -297,45 +296,27 @@ pub struct HkServiceWrapper, } -impl - HkServiceWrapper +impl TargetedPusService + for HkServiceWrapper { - pub fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus { - match self.service.poll_and_handle_next_tc(time_stamp) { - Ok(result) => match result { - PusPacketHandlerResult::RequestHandled => {} - PusPacketHandlerResult::RequestHandledPartialSuccess(e) => { - warn!("PUS 3 partial packet handling success: {e:?}") - } - PusPacketHandlerResult::CustomSubservice(invalid, _) => { - warn!("PUS 3 invalid subservice {invalid}"); - } - PusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { - warn!("PUS 3 subservice {subservice} not implemented"); - } - PusPacketHandlerResult::Empty => return HandlingStatus::Empty, - }, - Err(error) => { - error!("PUS packet handling error: {error:?}"); - // To avoid permanent loops on error cases. - return HandlingStatus::Empty; - } + const SERVICE_ID: u8 = 3; + + const SERVICE_STR: &'static str = "housekeeping"; + + delegate::delegate! { + to self.service { + fn poll_and_handle_next_tc( + &mut self, + time_stamp: &[u8], + ) -> Result; + + fn poll_and_handle_next_reply( + &mut self, + time_stamp: &[u8], + ) -> Result; + + fn check_for_request_timeouts(&mut self); } - HandlingStatus::HandledOne - } - - pub fn poll_and_handle_next_reply(&mut self, time_stamp: &[u8]) -> HandlingStatus { - // This only fails if all senders disconnected. Treat it like an empty queue. - self.service - .poll_and_check_next_reply(time_stamp) - .unwrap_or_else(|e| { - warn!("PUS 3: Handling reply failed with error {e:?}"); - HandlingStatus::Empty - }) - } - - pub fn check_for_request_timeouts(&mut self) { - self.service.check_for_request_timeouts(); } } diff --git a/satrs-example/src/pus/mod.rs b/satrs-example/src/pus/mod.rs index 75b5be3..25fbdf6 100644 --- a/satrs-example/src/pus/mod.rs +++ b/satrs-example/src/pus/mod.rs @@ -8,8 +8,8 @@ use satrs::pus::verification::{ use satrs::pus::{ ActiveRequestMapProvider, ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConverter, EcssTcReceiver, EcssTmSender, EcssTmtcError, GenericConversionError, GenericRoutingError, - PusPacketHandlerResult, PusPacketHandlingError, PusReplyHandler, PusRequestRouter, - PusServiceHelper, PusTcToRequestConverter, TcInMemory, + HandlingStatus, PusPacketHandlingError, PusReplyHandler, PusRequestRouter, PusServiceHelper, + PusTcToRequestConverter, TcInMemory, }; use satrs::queue::{GenericReceiveError, GenericSendError}; use satrs::request::{Apid, GenericMessage, MessageMetadata}; @@ -31,12 +31,6 @@ pub mod scheduler; pub mod stack; pub mod test; -#[derive(Debug, PartialEq, Eq, Copy, Clone)] -pub enum HandlingStatus { - Empty, - HandledOne, -} - pub fn create_verification_reporter(owner_id: ComponentId, apid: Apid) -> VerificationReporter { let verif_cfg = VerificationReporterCfg::new(apid, 1, 2, 8).unwrap(); // Every software component which needs to generate verification telemetry, gets a cloned @@ -79,7 +73,7 @@ impl PusTcDistributor { pub fn handle_tc_packet_vec( &mut self, packet_as_vec: PacketAsVec, - ) -> Result { + ) -> Result { self.handle_tc_generic(packet_as_vec.sender_id, None, &packet_as_vec.packet) } @@ -87,7 +81,7 @@ impl PusTcDistributor { &mut self, packet_in_pool: PacketInPool, pus_tc_copy: &[u8], - ) -> Result { + ) -> Result { self.handle_tc_generic( packet_in_pool.sender_id, Some(packet_in_pool.store_addr), @@ -100,7 +94,7 @@ impl PusTcDistributor { sender_id: ComponentId, addr_opt: Option, raw_tc: &[u8], - ) -> Result { + ) -> Result { let pus_tc_result = PusTcReader::new(raw_tc); if pus_tc_result.is_err() { log::warn!( @@ -109,7 +103,8 @@ impl PusTcDistributor { pus_tc_result.unwrap_err() ); log::warn!("raw data: {:x?}", raw_tc); - return Ok(PusPacketHandlerResult::RequestHandled); + // TODO: Shouldn't this be an error? + return Ok(HandlingStatus::HandledOne); } let pus_tc = pus_tc_result.unwrap().0; let init_token = self.verif_reporter.add_tc(&pus_tc); @@ -189,14 +184,53 @@ impl PusTcDistributor { } } } - Ok(PusPacketHandlerResult::RequestHandled) + Ok(HandlingStatus::HandledOne) } } pub trait TargetedPusService { - /// Returns [true] if the packet handling is finished. - fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus; - fn poll_and_handle_next_reply(&mut self, time_stamp: &[u8]) -> HandlingStatus; + const SERVICE_ID: u8; + const SERVICE_STR: &'static str; + + fn poll_and_handle_next_tc_default_handler(&mut self, time_stamp: &[u8]) -> HandlingStatus { + let result = self.poll_and_handle_next_tc(time_stamp); + if let Err(e) = result { + log::error!( + "PUS service {}({})packet handling error: {:?}", + Self::SERVICE_ID, + Self::SERVICE_STR, + e + ); + // To avoid permanent loops on error cases. + return HandlingStatus::Empty; + } + result.unwrap() + } + + fn poll_and_handle_next_reply_default_handler(&mut self, time_stamp: &[u8]) -> HandlingStatus { + // This only fails if all senders disconnected. Treat it like an empty queue. + self.poll_and_handle_next_reply(time_stamp) + .unwrap_or_else(|e| { + warn!( + "PUS servce {}({}): Handling reply failed with error {:?}", + Self::SERVICE_ID, + Self::SERVICE_STR, + e + ); + HandlingStatus::Empty + }) + } + + fn poll_and_handle_next_tc( + &mut self, + time_stamp: &[u8], + ) -> Result; + + fn poll_and_handle_next_reply( + &mut self, + time_stamp: &[u8], + ) -> Result; + fn check_for_request_timeouts(&mut self); } @@ -297,10 +331,10 @@ where pub fn poll_and_handle_next_tc( &mut self, time_stamp: &[u8], - ) -> Result { + ) -> Result { let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?; if possible_packet.is_none() { - return Ok(PusPacketHandlerResult::Empty); + return Ok(HandlingStatus::Empty); } let ecss_tc_and_token = possible_packet.unwrap(); self.service_helper @@ -356,7 +390,7 @@ where return Err(e.into()); } } - Ok(PusPacketHandlerResult::RequestHandled) + Ok(HandlingStatus::HandledOne) } fn handle_conversion_to_request_error( @@ -409,7 +443,7 @@ where } } - pub fn poll_and_check_next_reply( + pub fn poll_and_handle_next_reply( &mut self, time_stamp: &[u8], ) -> Result { diff --git a/satrs-example/src/pus/mode.rs b/satrs-example/src/pus/mode.rs index 5f3c0ff..e990a80 100644 --- a/satrs-example/src/pus/mode.rs +++ b/satrs-example/src/pus/mode.rs @@ -1,5 +1,4 @@ use derive_new::new; -use log::{error, warn}; use satrs::tmtc::{PacketAsVec, PacketSenderWithSharedPool}; use std::sync::mpsc; use std::time::Duration; @@ -9,7 +8,7 @@ use satrs::pool::SharedStaticMemoryPool; use satrs::pus::verification::VerificationReporter; use satrs::pus::{ DefaultActiveRequestMap, EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, - EcssTcInVecConverter, MpscTcReceiver, MpscTmAsVecSender, PusPacketHandlerResult, + EcssTcInVecConverter, MpscTcReceiver, MpscTmAsVecSender, PusPacketHandlingError, PusServiceHelper, }; use satrs::request::GenericMessage; @@ -36,7 +35,7 @@ use satrs::{ ComponentId, }; use satrs_example::config::components::PUS_MODE_SERVICE; -use satrs_example::config::{mode_err, tmtc_err}; +use satrs_example::config::{mode_err, tmtc_err, CustomPusServiceId}; use super::{ create_verification_reporter, generic_pus_request_timeout_handler, HandlingStatus, @@ -272,44 +271,27 @@ pub struct ModeServiceWrapper TargetedPusService for ModeServiceWrapper { - /// Returns [true] if the packet handling is finished. - fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus { - match self.service.poll_and_handle_next_tc(time_stamp) { - Ok(result) => match result { - PusPacketHandlerResult::RequestHandled => {} - PusPacketHandlerResult::RequestHandledPartialSuccess(e) => { - warn!("PUS mode service: partial packet handling success: {e:?}") - } - PusPacketHandlerResult::CustomSubservice(invalid, _) => { - warn!("PUS mode service: invalid subservice {invalid}"); - } - PusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { - warn!("PUS mode service: {subservice} not implemented"); - } - PusPacketHandlerResult::Empty => return HandlingStatus::Empty, - }, - Err(error) => { - error!("PUS mode service: packet handling error: {error:?}"); - // To avoid permanent loops on error cases. - return HandlingStatus::Empty; - } + const SERVICE_ID: u8 = CustomPusServiceId::Mode as u8; + + const SERVICE_STR: &'static str = "mode"; + + delegate::delegate! { + to self.service { + fn poll_and_handle_next_tc( + &mut self, + time_stamp: &[u8], + ) -> Result; + + fn poll_and_handle_next_reply( + &mut self, + time_stamp: &[u8], + ) -> Result; + + fn check_for_request_timeouts(&mut self); } - HandlingStatus::HandledOne - } - - fn poll_and_handle_next_reply(&mut self, time_stamp: &[u8]) -> HandlingStatus { - self.service - .poll_and_check_next_reply(time_stamp) - .unwrap_or_else(|e| { - warn!("PUS action service: Handling reply failed with error {e:?}"); - HandlingStatus::HandledOne - }) - } - - fn check_for_request_timeouts(&mut self) { - self.service.check_for_request_timeouts(); } } + #[cfg(test)] mod tests { use satrs::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0, TEST_UNIQUE_ID_0}; diff --git a/satrs-example/src/pus/scheduler.rs b/satrs-example/src/pus/scheduler.rs index 5346e19..9fa534f 100644 --- a/satrs-example/src/pus/scheduler.rs +++ b/satrs-example/src/pus/scheduler.rs @@ -8,8 +8,9 @@ use satrs::pus::scheduler::{PusScheduler, TcInfo}; use satrs::pus::scheduler_srv::PusSchedServiceHandler; use satrs::pus::verification::VerificationReporter; use satrs::pus::{ - EcssTcAndToken, EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, - EcssTmSender, MpscTcReceiver, MpscTmAsVecSender, PusPacketHandlerResult, PusServiceHelper, + DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConverter, + EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTmSender, MpscTcReceiver, + MpscTmAsVecSender, PartialPusHandlingError, PusServiceHelper, }; use satrs::tmtc::{PacketAsVec, PacketInPool, PacketSenderWithSharedPool}; use satrs::ComponentId; @@ -105,25 +106,25 @@ impl } pub fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus { - match self - .pus_11_handler - .poll_and_handle_next_tc(time_stamp, &mut self.sched_tc_pool) - { + let error_handler = |patial_error: &PartialPusHandlingError| { + log::warn!("PUS 11 partial error: {:?}", patial_error); + }; + match self.pus_11_handler.poll_and_handle_next_tc( + error_handler, + time_stamp, + &mut self.sched_tc_pool, + ) { Ok(result) => match result { - PusPacketHandlerResult::RequestHandled => {} - PusPacketHandlerResult::RequestHandledPartialSuccess(e) => { - warn!("PUS11 partial packet handling success: {e:?}") + DirectPusPacketHandlerResult::Handled(handling_status) => return handling_status, + DirectPusPacketHandlerResult::CustomSubservice(invalid, _) => { + warn!("PUS 11 invalid subservice {invalid}"); } - PusPacketHandlerResult::CustomSubservice(invalid, _) => { - warn!("PUS11 invalid subservice {invalid}"); + DirectPusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { + warn!("PUS 11 Subservice {subservice} not implemented"); } - PusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { - warn!("PUS11: Subservice {subservice} not implemented"); - } - PusPacketHandlerResult::Empty => return HandlingStatus::Empty, }, Err(error) => { - error!("PUS packet handling error: {error:?}") + error!("PUS 11 packet handling error: {error:?}") } } HandlingStatus::HandledOne diff --git a/satrs-example/src/pus/stack.rs b/satrs-example/src/pus/stack.rs index fac9bce..d964935 100644 --- a/satrs-example/src/pus/stack.rs +++ b/satrs-example/src/pus/stack.rs @@ -2,8 +2,12 @@ use crate::pus::mode::ModeServiceWrapper; use derive_new::new; use satrs::{ pus::{EcssTcInMemConverter, EcssTmSender}, - spacepackets::time::{cds, TimeWriter}, + spacepackets::{ + ecss::PusServiceId, + time::{cds, TimeWriter}, + }, }; +use satrs_example::config::CustomPusServiceId; use super::{ action::ActionServiceWrapper, event::EventServiceWrapper, hk::HkServiceWrapper, @@ -32,6 +36,7 @@ impl .expect("time stamp generation error") .to_vec() .unwrap(); + // Hot loop which will run continuously until all request and reply handling is done. loop { let mut nothing_to_do = true; let mut is_srv_finished = @@ -46,33 +51,46 @@ impl } }; is_srv_finished( - 17, - self.test_srv.poll_and_handle_next_packet(&time_stamp), + PusServiceId::Test as u8, + self.test_srv.poll_and_handle_next_tc(&time_stamp), None, ); is_srv_finished( - 11, + PusServiceId::Scheduling as u8, self.schedule_srv.poll_and_handle_next_tc(&time_stamp), None, ); - is_srv_finished(5, self.event_srv.poll_and_handle_next_tc(&time_stamp), None); is_srv_finished( - 8, - self.action_srv_wrapper.poll_and_handle_next_tc(&time_stamp), + PusServiceId::Event as u8, + self.event_srv.poll_and_handle_next_tc(&time_stamp), + None, + ); + is_srv_finished( + PusServiceId::Action as u8, + self.action_srv_wrapper + .poll_and_handle_next_tc_default_handler(&time_stamp), Some( self.action_srv_wrapper - .poll_and_handle_next_reply(&time_stamp), + .poll_and_handle_next_reply_default_handler(&time_stamp), ), ); is_srv_finished( - 3, - self.hk_srv_wrapper.poll_and_handle_next_tc(&time_stamp), - Some(self.hk_srv_wrapper.poll_and_handle_next_reply(&time_stamp)), + PusServiceId::Housekeeping as u8, + self.hk_srv_wrapper + .poll_and_handle_next_tc_default_handler(&time_stamp), + Some( + self.hk_srv_wrapper + .poll_and_handle_next_reply_default_handler(&time_stamp), + ), ); is_srv_finished( - 200, - self.mode_srv.poll_and_handle_next_tc(&time_stamp), - Some(self.mode_srv.poll_and_handle_next_reply(&time_stamp)), + CustomPusServiceId::Mode as u8, + self.mode_srv + .poll_and_handle_next_tc_default_handler(&time_stamp), + Some( + self.mode_srv + .poll_and_handle_next_reply_default_handler(&time_stamp), + ), ); if nothing_to_do { // Timeout checking is only done once. diff --git a/satrs-example/src/pus/test.rs b/satrs-example/src/pus/test.rs index 585e93b..933c679 100644 --- a/satrs-example/src/pus/test.rs +++ b/satrs-example/src/pus/test.rs @@ -4,11 +4,11 @@ use satrs::event_man::{EventMessage, EventMessageU32}; use satrs::pool::SharedStaticMemoryPool; use satrs::pus::test::PusService17TestHandler; use satrs::pus::verification::{FailParams, VerificationReporter, VerificationReportingProvider}; -use satrs::pus::EcssTcInSharedStoreConverter; use satrs::pus::{ - EcssTcAndToken, EcssTcInMemConverter, EcssTcInVecConverter, EcssTmSender, MpscTcReceiver, - MpscTmAsVecSender, PusPacketHandlerResult, PusServiceHelper, + DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConverter, EcssTcInVecConverter, + EcssTmSender, MpscTcReceiver, MpscTmAsVecSender, PusServiceHelper, }; +use satrs::pus::{EcssTcInSharedStoreConverter, PartialPusHandlingError}; use satrs::spacepackets::ecss::tc::PusTcReader; use satrs::spacepackets::ecss::PusPacket; use satrs::spacepackets::time::cds::CdsTime; @@ -67,27 +67,29 @@ pub struct TestCustomServiceWrapper TestCustomServiceWrapper { - pub fn poll_and_handle_next_packet(&mut self, time_stamp: &[u8]) -> HandlingStatus { - let res = self.handler.poll_and_handle_next_tc(time_stamp); + pub fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus { + let error_handler = |patial_error: &PartialPusHandlingError| { + log::warn!("PUS 17 partial error: {:?}", patial_error); + }; + let res = self + .handler + .poll_and_handle_next_tc(error_handler, time_stamp); if res.is_err() { - warn!("PUS17 handler failed with error {:?}", res.unwrap_err()); + warn!("PUS 17 handler error: {:?}", res.unwrap_err()); return HandlingStatus::HandledOne; } match res.unwrap() { - PusPacketHandlerResult::RequestHandled => { - info!("Received PUS ping command TC[17,1]"); - info!("Sent ping reply PUS TM[17,2]"); + DirectPusPacketHandlerResult::Handled(handling_status) => { + if handling_status == HandlingStatus::HandledOne { + info!("Received PUS ping command TC[17,1]"); + info!("Sent ping reply PUS TM[17,2]"); + } + return handling_status; } - PusPacketHandlerResult::RequestHandledPartialSuccess(partial_err) => { - warn!( - "Handled PUS ping command with partial success: {:?}", - partial_err - ); - } - PusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { + DirectPusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => { warn!("PUS17: Subservice {subservice} not implemented") } - PusPacketHandlerResult::CustomSubservice(subservice, token) => { + DirectPusPacketHandlerResult::CustomSubservice(subservice, token) => { let (tc, _) = PusTcReader::new( self.handler .service_helper @@ -135,7 +137,6 @@ impl .expect("Sending start failure verification failed"); } } - PusPacketHandlerResult::Empty => return HandlingStatus::Empty, } HandlingStatus::HandledOne } diff --git a/satrs-example/src/tmtc/tc_source.rs b/satrs-example/src/tmtc/tc_source.rs index bd99fb2..94b642c 100644 --- a/satrs-example/src/tmtc/tc_source.rs +++ b/satrs-example/src/tmtc/tc_source.rs @@ -1,12 +1,13 @@ use satrs::{ pool::PoolProvider, + pus::HandlingStatus, tmtc::{PacketAsVec, PacketInPool, PacketSenderWithSharedPool, SharedPacketPool}, }; use std::sync::mpsc::{self, TryRecvError}; use satrs::pus::MpscTmAsVecSender; -use crate::pus::{HandlingStatus, PusTcDistributor}; +use crate::pus::PusTcDistributor; // TC source components where static pools are the backing memory of the received telecommands. pub struct TcSourceTaskStatic { diff --git a/satrs/src/pus/action.rs b/satrs/src/pus/action.rs index 75d5962..6bcd270 100644 --- a/satrs/src/pus/action.rs +++ b/satrs/src/pus/action.rs @@ -54,11 +54,11 @@ pub type GenericActionReplyPus = GenericMessage; impl GenericActionReplyPus { pub fn new_action_reply( - requestor_info: MessageMetadata, + replier_info: MessageMetadata, action_id: ActionId, reply: ActionReplyVariant, ) -> Self { - Self::new(requestor_info, ActionReplyPus::new(action_id, reply)) + Self::new(replier_info, ActionReplyPus::new(action_id, reply)) } } diff --git a/satrs/src/pus/event_srv.rs b/satrs/src/pus/event_srv.rs index 8ea54ec..cb1bcb5 100644 --- a/satrs/src/pus/event_srv.rs +++ b/satrs/src/pus/event_srv.rs @@ -1,7 +1,7 @@ use crate::events::EventU32; use crate::pus::event_man::{EventRequest, EventRequestWithToken}; use crate::pus::verification::TcStateToken; -use crate::pus::{PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError}; +use crate::pus::{DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError}; use crate::queue::GenericSendError; use spacepackets::ecss::event::Subservice; use spacepackets::ecss::PusPacket; @@ -10,7 +10,7 @@ use std::sync::mpsc::Sender; use super::verification::VerificationReportingProvider; use super::{ EcssTcInMemConverter, EcssTcReceiver, EcssTmSender, GenericConversionError, - GenericRoutingError, PusServiceHelper, + GenericRoutingError, HandlingStatus, PusServiceHelper, }; pub struct PusEventServiceHandler< @@ -46,13 +46,14 @@ impl< } } - pub fn poll_and_handle_next_tc( + pub fn poll_and_handle_next_tc( &mut self, + mut error_callback: ErrorCb, time_stamp: &[u8], - ) -> Result { + ) -> Result { let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?; if possible_packet.is_none() { - return Ok(PusPacketHandlerResult::Empty); + return Ok(HandlingStatus::Empty.into()); } let ecss_tc_and_token = possible_packet.unwrap(); self.service_helper @@ -62,13 +63,13 @@ impl< let subservice = tc.subservice(); let srv = Subservice::try_from(subservice); if srv.is_err() { - return Ok(PusPacketHandlerResult::CustomSubservice( + return Ok(DirectPusPacketHandlerResult::CustomSubservice( tc.subservice(), ecss_tc_and_token.token, )); } - let handle_enable_disable_request = - |enable: bool| -> Result { + let mut handle_enable_disable_request = + |enable: bool| -> Result { if tc.user_data().len() < 4 { return Err(GenericConversionError::NotEnoughAppData { expected: 4, @@ -79,21 +80,20 @@ impl< let user_data = tc.user_data(); let event_u32 = EventU32::from(u32::from_be_bytes(user_data[0..4].try_into().unwrap())); - let start_token = self - .service_helper - .common - .verif_reporter - .start_success( - &self.service_helper.common.tm_sender, - ecss_tc_and_token.token, - time_stamp, - ) - .map_err(|_| PartialPusHandlingError::Verification); - let partial_error = start_token.clone().err(); let mut token: TcStateToken = ecss_tc_and_token.token.into(); - if let Ok(start_token) = start_token { - token = start_token.into(); + match self.service_helper.common.verif_reporter.start_success( + &self.service_helper.common.tm_sender, + ecss_tc_and_token.token, + time_stamp, + ) { + Ok(start_token) => { + token = start_token.into(); + } + Err(e) => { + error_callback(&PartialPusHandlingError::Verification(e)); + } } + let event_req_with_token = if enable { EventRequestWithToken { request: EventRequest::Enable(event_u32), @@ -112,12 +112,7 @@ impl< GenericSendError::RxDisconnected, )) })?; - if let Some(partial_error) = partial_error { - return Ok(PusPacketHandlerResult::RequestHandledPartialSuccess( - partial_error, - )); - } - Ok(PusPacketHandlerResult::RequestHandled) + Ok(HandlingStatus::HandledOne.into()) }; match srv.unwrap() { @@ -136,14 +131,14 @@ impl< handle_enable_disable_request(false)?; } Subservice::TcReportDisabledList | Subservice::TmDisabledEventsReport => { - return Ok(PusPacketHandlerResult::SubserviceNotImplemented( + return Ok(DirectPusPacketHandlerResult::SubserviceNotImplemented( subservice, ecss_tc_and_token.token, )); } } - Ok(PusPacketHandlerResult::RequestHandled) + Ok(HandlingStatus::HandledOne.into()) } } @@ -167,7 +162,7 @@ mod tests { use crate::pus::verification::{ RequestId, VerificationReporter, VerificationReportingProvider, }; - use crate::pus::{GenericConversionError, MpscTcReceiver}; + use crate::pus::{GenericConversionError, HandlingStatus, MpscTcReceiver}; use crate::tmtc::PacketSenderWithSharedPool; use crate::{ events::EventU32, @@ -175,7 +170,7 @@ mod tests { event_man::EventRequestWithToken, tests::PusServiceHandlerWithSharedStoreCommon, verification::{TcStateAccepted, VerificationToken}, - EcssTcInSharedStoreConverter, PusPacketHandlerResult, PusPacketHandlingError, + DirectPusPacketHandlerResult, EcssTcInSharedStoreConverter, PusPacketHandlingError, }, }; @@ -229,9 +224,11 @@ mod tests { } impl SimplePusPacketHandler for Pus5HandlerWithStoreTester { - fn handle_one_tc(&mut self) -> Result { + fn handle_one_tc( + &mut self, + ) -> Result { let time_stamp = cds::CdsTime::new_with_u16_days(0, 0).to_vec().unwrap(); - self.handler.poll_and_handle_next_tc(&time_stamp) + self.handler.poll_and_handle_next_tc(|_| {}, &time_stamp) } } @@ -293,10 +290,13 @@ mod tests { let result = test_harness.handle_one_tc(); assert!(result.is_ok()); let result = result.unwrap(); - if let PusPacketHandlerResult::Empty = result { - } else { - panic!("unexpected result type {result:?}") - } + assert!( + matches!( + result, + DirectPusPacketHandlerResult::Handled(HandlingStatus::Empty) + ), + "unexpected result type {result:?}" + ) } #[test] @@ -311,7 +311,7 @@ mod tests { let result = test_harness.handle_one_tc(); assert!(result.is_ok()); let result = result.unwrap(); - if let PusPacketHandlerResult::CustomSubservice(subservice, _) = result { + if let DirectPusPacketHandlerResult::CustomSubservice(subservice, _) = result { assert_eq!(subservice, 200); } else { panic!("unexpected result type {result:?}") diff --git a/satrs/src/pus/mod.rs b/satrs/src/pus/mod.rs index 4a76757..349df62 100644 --- a/satrs/src/pus/mod.rs +++ b/satrs/src/pus/mod.rs @@ -45,6 +45,15 @@ pub use std_mod::*; use self::verification::VerificationReportingProvider; +/// Generic handling status for an object which is able to continuosly handle a queue to handle +/// request or replies until the queue is empty. +#[derive(Debug, PartialEq, Eq, Copy, Clone)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum HandlingStatus { + HandledOne, + Empty, +} + #[derive(Debug, PartialEq, Eq, Clone)] pub enum PusTmVariant<'time, 'src_data> { InStore(PoolAddr), @@ -649,14 +658,11 @@ pub mod alloc_mod { #[cfg(feature = "std")] pub mod std_mod { + use super::*; use crate::pool::{ PoolAddr, PoolError, PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool, }; use crate::pus::verification::{TcStateAccepted, VerificationToken}; - use crate::pus::{ - EcssTcAndToken, EcssTcReceiver, EcssTmSender, EcssTmtcError, GenericReceiveError, - GenericSendError, PusTmVariant, TryRecvTmtcError, - }; use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool}; use crate::ComponentId; use alloc::vec::Vec; @@ -920,26 +926,24 @@ pub mod std_mod { #[error("generic timestamp generation error")] Time(#[from] StdTimestampError), #[error("error sending telemetry: {0}")] - TmSend(#[from] EcssTmtcError), + TmSend(EcssTmtcError), #[error("error sending verification message")] - Verification, + Verification(EcssTmtcError), #[error("invalid verification token")] NoVerificationToken, } /// Generic result type for handlers which can process PUS packets. #[derive(Debug, Clone)] - pub enum PusPacketHandlerResult { - RequestHandled, - RequestHandledPartialSuccess(PartialPusHandlingError), + pub enum DirectPusPacketHandlerResult { + Handled(HandlingStatus), SubserviceNotImplemented(u8, VerificationToken), CustomSubservice(u8, VerificationToken), - Empty, } - impl From for PusPacketHandlerResult { - fn from(value: PartialPusHandlingError) -> Self { - Self::RequestHandledPartialSuccess(value) + impl From for DirectPusPacketHandlerResult { + fn from(value: HandlingStatus) -> Self { + Self::Handled(value) } } @@ -1222,7 +1226,7 @@ pub mod test_util { use super::{ verification::{self, TcStateAccepted, VerificationToken}, - PusPacketHandlerResult, PusPacketHandlingError, + DirectPusPacketHandlerResult, PusPacketHandlingError, }; pub const TEST_APID: u16 = 0x101; @@ -1246,7 +1250,8 @@ pub mod test_util { } pub trait SimplePusPacketHandler { - fn handle_one_tc(&mut self) -> Result; + fn handle_one_tc(&mut self) + -> Result; } } diff --git a/satrs/src/pus/scheduler_srv.rs b/satrs/src/pus/scheduler_srv.rs index 4d538b8..a3930d9 100644 --- a/satrs/src/pus/scheduler_srv.rs +++ b/satrs/src/pus/scheduler_srv.rs @@ -1,11 +1,12 @@ use super::scheduler::PusSchedulerProvider; use super::verification::{VerificationReporter, VerificationReportingProvider}; use super::{ - EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiver, - EcssTmSender, MpscTcReceiver, PusServiceHelper, + DirectPusPacketHandlerResult, EcssTcInMemConverter, EcssTcInSharedStoreConverter, + EcssTcInVecConverter, EcssTcReceiver, EcssTmSender, HandlingStatus, MpscTcReceiver, + PartialPusHandlingError, PusServiceHelper, }; use crate::pool::PoolProvider; -use crate::pus::{PusPacketHandlerResult, PusPacketHandlingError}; +use crate::pus::PusPacketHandlingError; use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool}; use alloc::string::ToString; use spacepackets::ecss::{scheduling, PusPacket}; @@ -64,14 +65,15 @@ impl< &self.scheduler } - pub fn poll_and_handle_next_tc( + pub fn poll_and_handle_next_tc( &mut self, + mut error_callback: ErrorCb, time_stamp: &[u8], sched_tc_pool: &mut (impl PoolProvider + ?Sized), - ) -> Result { + ) -> Result { let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?; if possible_packet.is_none() { - return Ok(PusPacketHandlerResult::Empty); + return Ok(HandlingStatus::Empty.into()); } let ecss_tc_and_token = possible_packet.unwrap(); self.service_helper @@ -81,34 +83,34 @@ impl< let subservice = PusPacket::subservice(&tc); let standard_subservice = scheduling::Subservice::try_from(subservice); if standard_subservice.is_err() { - return Ok(PusPacketHandlerResult::CustomSubservice( + return Ok(DirectPusPacketHandlerResult::CustomSubservice( subservice, ecss_tc_and_token.token, )); } - let partial_error = None; match standard_subservice.unwrap() { scheduling::Subservice::TcEnableScheduling => { - let start_token = self - .service_helper - .verif_reporter() - .start_success( - &self.service_helper.common.tm_sender, - ecss_tc_and_token.token, - time_stamp, - ) - .expect("Error sending start success"); - + let opt_started_token = match self.service_helper.verif_reporter().start_success( + &self.service_helper.common.tm_sender, + ecss_tc_and_token.token, + time_stamp, + ) { + Ok(started_token) => Some(started_token), + Err(e) => { + error_callback(&PartialPusHandlingError::Verification(e)); + None + } + }; self.scheduler.enable(); - if self.scheduler.is_enabled() { - self.service_helper - .verif_reporter() - .completion_success( - &self.service_helper.common.tm_sender, - start_token, - time_stamp, - ) - .expect("Error sending completion success"); + + if self.scheduler.is_enabled() && opt_started_token.is_some() { + if let Err(e) = self.service_helper.verif_reporter().completion_success( + &self.service_helper.common.tm_sender, + opt_started_token.unwrap(), + time_stamp, + ) { + error_callback(&PartialPusHandlingError::Verification(e)); + } } else { return Err(PusPacketHandlingError::Other( "failed to enabled scheduler".to_string(), @@ -116,26 +118,27 @@ impl< } } scheduling::Subservice::TcDisableScheduling => { - let start_token = self - .service_helper - .verif_reporter() - .start_success( - &self.service_helper.common.tm_sender, - ecss_tc_and_token.token, - time_stamp, - ) - .expect("Error sending start success"); + let opt_started_token = match self.service_helper.verif_reporter().start_success( + &self.service_helper.common.tm_sender, + ecss_tc_and_token.token, + time_stamp, + ) { + Ok(started_token) => Some(started_token), + Err(e) => { + error_callback(&PartialPusHandlingError::Verification(e)); + None + } + }; self.scheduler.disable(); - if !self.scheduler.is_enabled() { - self.service_helper - .verif_reporter() - .completion_success( - &self.service_helper.common.tm_sender, - start_token, - time_stamp, - ) - .expect("Error sending completion success"); + if !self.scheduler.is_enabled() && opt_started_token.is_some() { + if let Err(e) = self.service_helper.verif_reporter().completion_success( + &self.service_helper.common.tm_sender, + opt_started_token.unwrap(), + time_stamp, + ) { + error_callback(&PartialPusHandlingError::Verification(e)); + } } else { return Err(PusPacketHandlingError::Other( "failed to disable scheduler".to_string(), @@ -194,18 +197,13 @@ impl< } _ => { // Treat unhandled standard subservices as custom subservices for now. - return Ok(PusPacketHandlerResult::CustomSubservice( + return Ok(DirectPusPacketHandlerResult::CustomSubservice( subservice, ecss_tc_and_token.token, )); } } - if let Some(partial_error) = partial_error { - return Ok(PusPacketHandlerResult::RequestHandledPartialSuccess( - partial_error, - )); - } - Ok(PusPacketHandlerResult::RequestHandled) + Ok(HandlingStatus::HandledOne.into()) } } /// Helper type definition for a PUS 11 handler with a dynamic TMTC memory backend and regular @@ -257,7 +255,7 @@ mod tests { verification::{RequestId, TcStateAccepted, VerificationToken}, EcssTcInSharedStoreConverter, }; - use crate::pus::{MpscTcReceiver, PusPacketHandlerResult, PusPacketHandlingError}; + use crate::pus::{DirectPusPacketHandlerResult, MpscTcReceiver, PusPacketHandlingError}; use crate::tmtc::PacketSenderWithSharedPool; use alloc::collections::VecDeque; use delegate::delegate; @@ -298,10 +296,12 @@ mod tests { } } - pub fn handle_one_tc(&mut self) -> Result { + pub fn handle_one_tc( + &mut self, + ) -> Result { let time_stamp = cds::CdsTime::new_with_u16_days(0, 0).to_vec().unwrap(); self.handler - .poll_and_handle_next_tc(&time_stamp, &mut self.sched_tc_pool) + .poll_and_handle_next_tc(|_| {}, &time_stamp, &mut self.sched_tc_pool) } } @@ -387,7 +387,7 @@ mod tests { let time_stamp = cds::CdsTime::new_with_u16_days(0, 0).to_vec().unwrap(); test_harness .handler - .poll_and_handle_next_tc(&time_stamp, &mut test_harness.sched_tc_pool) + .poll_and_handle_next_tc(|_| {}, &time_stamp, &mut test_harness.sched_tc_pool) .unwrap(); test_harness.check_next_verification_tm(1, request_id); test_harness.check_next_verification_tm(3, request_id); diff --git a/satrs/src/pus/test.rs b/satrs/src/pus/test.rs index a1ca93e..9bd0937 100644 --- a/satrs/src/pus/test.rs +++ b/satrs/src/pus/test.rs @@ -1,5 +1,5 @@ use crate::pus::{ - PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError, PusTmVariant, + DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError, PusTmVariant, }; use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool}; use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader}; @@ -10,7 +10,7 @@ use std::sync::mpsc; use super::verification::{VerificationReporter, VerificationReportingProvider}; use super::{ EcssTcInMemConverter, EcssTcInSharedStoreConverter, EcssTcInVecConverter, EcssTcReceiver, - EcssTmSender, GenericConversionError, MpscTcReceiver, PusServiceHelper, + EcssTmSender, GenericConversionError, HandlingStatus, MpscTcReceiver, PusServiceHelper, }; /// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets. @@ -43,13 +43,14 @@ impl< Self { service_helper } } - pub fn poll_and_handle_next_tc( + pub fn poll_and_handle_next_tc( &mut self, + mut error_callback: ErrorCb, time_stamp: &[u8], - ) -> Result { + ) -> Result { let possible_packet = self.service_helper.retrieve_and_accept_next_packet()?; if possible_packet.is_none() { - return Ok(PusPacketHandlerResult::Empty); + return Ok(HandlingStatus::Empty.into()); } let ecss_tc_and_token = possible_packet.unwrap(); self.service_helper @@ -60,21 +61,16 @@ impl< return Err(GenericConversionError::WrongService(tc.service()).into()); } if tc.subservice() == 1 { - let mut partial_error = None; - let result = self - .service_helper - .verif_reporter() - .start_success( - &self.service_helper.common.tm_sender, - ecss_tc_and_token.token, - time_stamp, - ) - .map_err(|_| PartialPusHandlingError::Verification); - let start_token = if let Ok(result) = result { - Some(result) - } else { - partial_error = Some(result.unwrap_err()); - None + let opt_started_token = match self.service_helper.verif_reporter().start_success( + &self.service_helper.common.tm_sender, + ecss_tc_and_token.token, + time_stamp, + ) { + Ok(token) => Some(token), + Err(e) => { + error_callback(&PartialPusHandlingError::Verification(e)); + None + } }; // Sequence count will be handled centrally in TM funnel. // It is assumed that the verification reporter was built with a valid APID, so we use @@ -83,42 +79,30 @@ impl< SpHeader::new_for_unseg_tm(self.service_helper.verif_reporter().apid(), 0, 0); let tc_header = PusTmSecondaryHeader::new_simple(17, 2, time_stamp); let ping_reply = PusTmCreator::new(reply_header, tc_header, &[], true); - let result = self + if let Err(e) = self .service_helper .common .tm_sender .send_tm(self.service_helper.id(), PusTmVariant::Direct(ping_reply)) - .map_err(PartialPusHandlingError::TmSend); - if let Err(err) = result { - partial_error = Some(err); + { + error_callback(&PartialPusHandlingError::TmSend(e)); } - - if let Some(start_token) = start_token { - if self - .service_helper - .verif_reporter() - .completion_success( - &self.service_helper.common.tm_sender, - start_token, - time_stamp, - ) - .is_err() - { - partial_error = Some(PartialPusHandlingError::Verification) + if let Some(start_token) = opt_started_token { + if let Err(e) = self.service_helper.verif_reporter().completion_success( + &self.service_helper.common.tm_sender, + start_token, + time_stamp, + ) { + error_callback(&PartialPusHandlingError::Verification(e)); } } - if let Some(partial_error) = partial_error { - return Ok(PusPacketHandlerResult::RequestHandledPartialSuccess( - partial_error, - )); - }; } else { - return Ok(PusPacketHandlerResult::CustomSubservice( + return Ok(DirectPusPacketHandlerResult::CustomSubservice( tc.subservice(), ecss_tc_and_token.token, )); } - Ok(PusPacketHandlerResult::RequestHandled) + Ok(HandlingStatus::HandledOne.into()) } } @@ -158,8 +142,9 @@ mod tests { }; use crate::pus::verification::{TcStateAccepted, VerificationToken}; use crate::pus::{ - EcssTcInSharedStoreConverter, EcssTcInVecConverter, GenericConversionError, MpscTcReceiver, - MpscTmAsVecSender, PusPacketHandlerResult, PusPacketHandlingError, + DirectPusPacketHandlerResult, EcssTcInSharedStoreConverter, EcssTcInVecConverter, + GenericConversionError, HandlingStatus, MpscTcReceiver, MpscTmAsVecSender, + PartialPusHandlingError, PusPacketHandlingError, }; use crate::tmtc::PacketSenderWithSharedPool; use crate::ComponentId; @@ -221,9 +206,12 @@ mod tests { } } impl SimplePusPacketHandler for Pus17HandlerWithStoreTester { - fn handle_one_tc(&mut self) -> Result { + fn handle_one_tc( + &mut self, + ) -> Result { let time_stamp = cds::CdsTime::new_with_u16_days(0, 0).to_vec().unwrap(); - self.handler.poll_and_handle_next_tc(&time_stamp) + self.handler + .poll_and_handle_next_tc(|_partial_error: &PartialPusHandlingError| {}, &time_stamp) } } @@ -276,9 +264,12 @@ mod tests { } } impl SimplePusPacketHandler for Pus17HandlerWithVecTester { - fn handle_one_tc(&mut self) -> Result { + fn handle_one_tc( + &mut self, + ) -> Result { let time_stamp = cds::CdsTime::new_with_u16_days(0, 0).to_vec().unwrap(); - self.handler.poll_and_handle_next_tc(&time_stamp) + self.handler + .poll_and_handle_next_tc(|_partial_error: &PartialPusHandlingError| {}, &time_stamp) } } @@ -328,10 +319,11 @@ mod tests { let mut test_harness = Pus17HandlerWithStoreTester::new(0); let result = test_harness.handle_one_tc(); assert!(result.is_ok()); - let result = result.unwrap(); - if let PusPacketHandlerResult::Empty = result { - } else { - panic!("unexpected result type {result:?}") + match result.unwrap() { + DirectPusPacketHandlerResult::Handled(handled) => { + assert_eq!(handled, HandlingStatus::Empty); + }, + _ => panic!("unexpected result"), } } @@ -367,7 +359,7 @@ mod tests { let result = test_harness.handle_one_tc(); assert!(result.is_ok()); let result = result.unwrap(); - if let PusPacketHandlerResult::CustomSubservice(subservice, _) = result { + if let DirectPusPacketHandlerResult::CustomSubservice(subservice, _) = result { assert_eq!(subservice, 200); } else { panic!("unexpected result type {result:?}")