satrs_core/tmtc/
tm_helper.rs1use 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}