satrs_core/tmtc/
tm_helper.rs

1use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
2use spacepackets::time::cds::TimeProvider;
3use spacepackets::time::TimeWriter;
4use spacepackets::SpHeader;
5
6#[cfg(feature = "std")]
7pub use std_mod::*;
8
9#[cfg(feature = "std")]
10pub mod std_mod {
11    use crate::pool::{PoolProvider, SharedStaticMemoryPool, StaticMemoryPool, StoreAddr};
12    use crate::pus::EcssTmtcError;
13    use spacepackets::ecss::tm::PusTmCreator;
14    use spacepackets::ecss::WritablePusPacket;
15    use std::sync::{Arc, RwLock};
16
17    #[derive(Clone)]
18    pub struct SharedTmPool(pub SharedStaticMemoryPool);
19
20    impl SharedTmPool {
21        pub fn new(shared_pool: StaticMemoryPool) -> Self {
22            Self(Arc::new(RwLock::new(shared_pool)))
23        }
24
25        pub fn clone_backing_pool(&self) -> SharedStaticMemoryPool {
26            self.0.clone()
27        }
28        pub fn shared_pool(&self) -> &SharedStaticMemoryPool {
29            &self.0
30        }
31
32        pub fn shared_pool_mut(&mut self) -> &mut SharedStaticMemoryPool {
33            &mut self.0
34        }
35
36        pub fn add_pus_tm(&self, pus_tm: &PusTmCreator) -> Result<StoreAddr, EcssTmtcError> {
37            let mut pg = self.0.write().map_err(|_| EcssTmtcError::StoreLock)?;
38            let addr = pg.free_element(pus_tm.len_written(), |buf| {
39                pus_tm
40                    .write_to_bytes(buf)
41                    .expect("writing PUS TM to store failed");
42            })?;
43            Ok(addr)
44        }
45    }
46}
47
48pub struct PusTmWithCdsShortHelper {
49    apid: u16,
50    cds_short_buf: [u8; 7],
51}
52
53impl PusTmWithCdsShortHelper {
54    pub fn new(apid: u16) -> Self {
55        Self {
56            apid,
57            cds_short_buf: [0; 7],
58        }
59    }
60
61    #[cfg(feature = "std")]
62    pub fn create_pus_tm_timestamp_now<'a>(
63        &'a mut self,
64        service: u8,
65        subservice: u8,
66        source_data: &'a [u8],
67        seq_count: u16,
68    ) -> PusTmCreator {
69        let time_stamp = TimeProvider::from_now_with_u16_days().unwrap();
70        time_stamp.write_to_bytes(&mut self.cds_short_buf).unwrap();
71        self.create_pus_tm_common(service, subservice, source_data, seq_count)
72    }
73
74    pub fn create_pus_tm_with_stamper<'a>(
75        &'a mut self,
76        service: u8,
77        subservice: u8,
78        source_data: &'a [u8],
79        stamper: &TimeProvider,
80        seq_count: u16,
81    ) -> PusTmCreator {
82        stamper.write_to_bytes(&mut self.cds_short_buf).unwrap();
83        self.create_pus_tm_common(service, subservice, source_data, seq_count)
84    }
85
86    fn create_pus_tm_common<'a>(
87        &'a self,
88        service: u8,
89        subservice: u8,
90        source_data: &'a [u8],
91        seq_count: u16,
92    ) -> PusTmCreator {
93        let mut reply_header = SpHeader::tm_unseg(self.apid, seq_count, 0).unwrap();
94        let tc_header = PusTmSecondaryHeader::new_simple(service, subservice, &self.cds_short_buf);
95        PusTmCreator::new(&mut reply_header, tc_header, source_data, true)
96    }
97}
98
99#[cfg(test)]
100mod tests {
101    use spacepackets::{ecss::PusPacket, time::cds::TimeProvider, CcsdsPacket};
102
103    use super::PusTmWithCdsShortHelper;
104
105    #[test]
106    fn test_helper_with_stamper() {
107        let mut pus_tm_helper = PusTmWithCdsShortHelper::new(0x123);
108        let stamper = TimeProvider::new_with_u16_days(0, 0);
109        let tm = pus_tm_helper.create_pus_tm_with_stamper(17, 1, &[1, 2, 3, 4], &stamper, 25);
110        assert_eq!(tm.service(), 17);
111        assert_eq!(tm.subservice(), 1);
112        assert_eq!(tm.user_data(), &[1, 2, 3, 4]);
113        assert_eq!(tm.seq_count(), 25);
114        assert_eq!(tm.timestamp(), [64, 0, 0, 0, 0, 0, 0])
115    }
116
117    #[test]
118    fn test_helper_from_now() {
119        let mut pus_tm_helper = PusTmWithCdsShortHelper::new(0x123);
120        let tm = pus_tm_helper.create_pus_tm_timestamp_now(17, 1, &[1, 2, 3, 4], 25);
121        assert_eq!(tm.service(), 17);
122        assert_eq!(tm.subservice(), 1);
123        assert_eq!(tm.user_data(), &[1, 2, 3, 4]);
124        assert_eq!(tm.seq_count(), 25);
125        assert_eq!(tm.timestamp().len(), 7);
126    }
127}