diff --git a/satrs-core/src/pus/scheduling.rs b/satrs-core/src/pus/scheduling.rs index 8aac8f2..63d827f 100644 --- a/satrs-core/src/pus/scheduling.rs +++ b/satrs-core/src/pus/scheduling.rs @@ -1,4 +1,7 @@ //! # PUS Service 11 Scheduling Module +//! +//! The core data structure of this module is the [PusScheduler]. This structure can be used +//! to perform the scheduling of telecommands like specified in the ECSS standard. use crate::pool::{PoolProvider, StoreAddr, StoreError}; use alloc::collections::btree_map::{Entry, Range}; use alloc::vec; @@ -11,7 +14,7 @@ use spacepackets::ecss::scheduling::TimeWindowType; use spacepackets::ecss::{PusError, PusPacket}; use spacepackets::tc::{GenericPusTcSecondaryHeader, PusTc}; use spacepackets::time::cds::DaysLen24Bits; -use spacepackets::time::{CcsdsTimeProvider, cds, TimeReader, TimestampError, UnixTimestamp}; +use spacepackets::time::{cds, CcsdsTimeProvider, TimeReader, TimestampError, UnixTimestamp}; use spacepackets::CcsdsPacket; use std::collections::BTreeMap; #[cfg(feature = "std")] @@ -411,7 +414,7 @@ impl PusScheduler { pus_tc: &PusTc, pool: &mut (impl PoolProvider + ?Sized), ) -> Result { - self.insert_wrapped_tc::(pus_tc, pool) + self.insert_wrapped_tc::(pus_tc, pool) } /// Insert a telecommand based on the fully wrapped time-tagged telecommand using a CDS @@ -421,13 +424,17 @@ impl PusScheduler { pus_tc: &PusTc, pool: &mut (impl PoolProvider + ?Sized), ) -> Result { - self.insert_wrapped_tc::>(pus_tc, pool) + self.insert_wrapped_tc::>(pus_tc, pool) } /// This function uses [Self::retrieve_by_time_filter] to extract all scheduled commands inside - /// the time range and then deletes them from the provided store. Like specified in the - /// documentation of [Self::retrieve_by_time_filter], the range extraction for deletion is - /// always inclusive. + /// the time range and then deletes them from the provided store. + /// + /// Like specified in the documentation of [Self::retrieve_by_time_filter], the range extraction + /// for deletion is always inclusive. + /// + /// This function returns the number of deleted commands on success. In case any deletion fails, + /// the last deletion will be supplied in addition to the number of deleted commands. pub fn delete_by_time_filter( &mut self, time_window: TimeWindow, @@ -456,7 +463,13 @@ impl PusScheduler { } /// Deletes all the scheduled commands. This also deletes the packets from the passed TC pool. - pub fn delete_all(&mut self, pool: &mut (impl PoolProvider + ?Sized)) -> Result { + /// + /// This function returns the number of deleted commands on success. In case any deletion fails, + /// the last deletion will be supplied in addition to the number of deleted commands. + pub fn delete_all( + &mut self, + pool: &mut (impl PoolProvider + ?Sized), + ) -> Result { self.delete_by_time_filter(TimeWindow::::new_select_all(), pool) } @@ -466,6 +479,7 @@ impl PusScheduler { } /// This retrieves scheduled telecommands which are inside the provided time window. + /// /// It should be noted that the ranged extraction is always inclusive. For example, a range /// from 50 to 100 unix seconds would also include command scheduled at 100 unix seconds. pub fn retrieve_by_time_filter( @@ -1564,7 +1578,8 @@ mod tests { insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50); insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100); assert_eq!(scheduler.num_scheduled_telecommands(), 2); - let del_res = scheduler.delete_by_time_filter(TimeWindow::::new_select_all(), &mut pool); + let del_res = scheduler + .delete_by_time_filter(TimeWindow::::new_select_all(), &mut pool); assert!(del_res.is_ok()); assert_eq!(del_res.unwrap(), 2); assert_eq!(scheduler.num_scheduled_telecommands(), 0); @@ -1606,7 +1621,7 @@ mod tests { let end_stamp = cds::TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::new_only_seconds(100)) .expect("creating start stamp failed"); - let time_window = TimeWindow::new_from_time(&end_stamp); + let time_window = TimeWindow::new_to_time(&end_stamp); let del_res = scheduler.delete_by_time_filter(time_window, &mut pool); assert!(del_res.is_ok()); assert_eq!(del_res.unwrap(), 2); @@ -1614,4 +1629,33 @@ mod tests { assert!(!pool.has_element_at(&cmd_0_to_delete.addr()).unwrap()); assert!(!pool.has_element_at(&cmd_1_to_delete.addr()).unwrap()); } + + #[test] + fn test_deletion_from_start_time_to_end_time() { + let mut pool = LocalPool::new(PoolCfg::new(vec![(10, 32), (5, 64)])); + let mut scheduler = + PusScheduler::new(UnixTimestamp::new_only_seconds(0), Duration::from_secs(5)); + let cmd_out_of_range_0 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50); + let cmd_0_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100); + let cmd_1_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150); + let cmd_out_of_range_1 = + insert_command_with_release_time(&mut pool, &mut scheduler, 0, 200); + assert_eq!(scheduler.num_scheduled_telecommands(), 4); + + let start_stamp = + cds::TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::new_only_seconds(100)) + .expect("creating start stamp failed"); + let end_stamp = + cds::TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::new_only_seconds(150)) + .expect("creating end stamp failed"); + let time_window = TimeWindow::new_from_time_to_time(&start_stamp, &end_stamp); + let del_res = scheduler.delete_by_time_filter(time_window, &mut pool); + assert!(del_res.is_ok()); + assert_eq!(del_res.unwrap(), 2); + assert_eq!(scheduler.num_scheduled_telecommands(), 2); + assert!(pool.has_element_at(&cmd_out_of_range_0.addr()).unwrap()); + assert!(!pool.has_element_at(&cmd_0_to_delete.addr()).unwrap()); + assert!(!pool.has_element_at(&cmd_1_to_delete.addr()).unwrap()); + assert!(pool.has_element_at(&cmd_out_of_range_1.addr()).unwrap()); + } }