1use crate::events::{EventU32, GenericEvent, Severity};
2#[cfg(feature = "alloc")]
3use crate::events::{EventU32TypedSev, HasSeverity};
4#[cfg(feature = "alloc")]
5use alloc::boxed::Box;
6#[cfg(feature = "alloc")]
7use core::hash::Hash;
8#[cfg(feature = "alloc")]
9use hashbrown::HashSet;
10
11#[cfg(feature = "alloc")]
12pub use crate::pus::event::EventReporter;
13use crate::pus::verification::TcStateToken;
14#[cfg(feature = "alloc")]
15use crate::pus::EcssTmSenderCore;
16use crate::pus::EcssTmtcError;
17#[cfg(feature = "alloc")]
18#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
19pub use alloc_mod::*;
20#[cfg(feature = "heapless")]
21#[cfg_attr(doc_cfg, doc(cfg(feature = "heapless")))]
22pub use heapless_mod::*;
23
24pub trait PusEventMgmtBackendProvider<Provider: GenericEvent> {
36 type Error;
37
38 fn event_enabled(&self, event: &Provider) -> bool;
39 fn enable_event_reporting(&mut self, event: &Provider) -> Result<bool, Self::Error>;
40 fn disable_event_reporting(&mut self, event: &Provider) -> Result<bool, Self::Error>;
41}
42
43#[cfg(feature = "heapless")]
44pub mod heapless_mod {
45 use super::*;
46 use crate::events::{GenericEvent, LargestEventRaw};
47 use std::marker::PhantomData;
48
49 #[cfg_attr(doc_cfg, doc(cfg(feature = "heapless")))]
50 #[derive(Default)]
53 pub struct HeaplessPusMgmtBackendProvider<const N: usize, Provider: GenericEvent> {
54 disabled: heapless::FnvIndexSet<LargestEventRaw, N>,
55 phantom: PhantomData<Provider>,
56 }
57
58 unsafe impl<const N: usize, Event: GenericEvent + Send> Send
60 for HeaplessPusMgmtBackendProvider<N, Event>
61 {
62 }
63
64 impl<const N: usize, Provider: GenericEvent> PusEventMgmtBackendProvider<Provider>
65 for HeaplessPusMgmtBackendProvider<N, Provider>
66 {
67 type Error = ();
68
69 fn event_enabled(&self, event: &Provider) -> bool {
70 self.disabled.contains(&event.raw_as_largest_type())
71 }
72
73 fn enable_event_reporting(&mut self, event: &Provider) -> Result<bool, Self::Error> {
74 self.disabled
75 .insert(event.raw_as_largest_type())
76 .map_err(|_| ())
77 }
78
79 fn disable_event_reporting(&mut self, event: &Provider) -> Result<bool, Self::Error> {
80 Ok(self.disabled.remove(&event.raw_as_largest_type()))
81 }
82 }
83}
84
85#[derive(Debug, PartialEq, Eq)]
86pub enum EventRequest<Event: GenericEvent = EventU32> {
87 Enable(Event),
88 Disable(Event),
89}
90
91#[derive(Debug)]
92pub struct EventRequestWithToken<Event: GenericEvent = EventU32> {
93 pub request: EventRequest<Event>,
94 pub token: TcStateToken,
95}
96
97#[derive(Debug)]
98pub enum EventManError {
99 EcssTmtcError(EcssTmtcError),
100 SeverityMissmatch(Severity, Severity),
101}
102
103impl From<EcssTmtcError> for EventManError {
104 fn from(v: EcssTmtcError) -> Self {
105 Self::EcssTmtcError(v)
106 }
107}
108
109#[cfg(feature = "alloc")]
110pub mod alloc_mod {
111 use super::*;
112
113 pub struct DefaultPusMgmtBackendProvider<Event: GenericEvent = EventU32> {
119 disabled: HashSet<Event>,
120 }
121
122 unsafe impl<Event: GenericEvent + Send> Send for DefaultPusMgmtBackendProvider<Event> {}
124
125 impl<Event: GenericEvent> Default for DefaultPusMgmtBackendProvider<Event> {
126 fn default() -> Self {
127 Self {
128 disabled: HashSet::default(),
129 }
130 }
131 }
132
133 impl<Provider: GenericEvent + PartialEq + Eq + Hash + Copy + Clone>
134 PusEventMgmtBackendProvider<Provider> for DefaultPusMgmtBackendProvider<Provider>
135 {
136 type Error = ();
137 fn event_enabled(&self, event: &Provider) -> bool {
138 !self.disabled.contains(event)
139 }
140
141 fn enable_event_reporting(&mut self, event: &Provider) -> Result<bool, Self::Error> {
142 Ok(self.disabled.remove(event))
143 }
144
145 fn disable_event_reporting(&mut self, event: &Provider) -> Result<bool, Self::Error> {
146 Ok(self.disabled.insert(*event))
147 }
148 }
149
150 pub struct PusEventDispatcher<BackendError, Provider: GenericEvent> {
151 reporter: EventReporter,
152 backend: Box<dyn PusEventMgmtBackendProvider<Provider, Error = BackendError>>,
153 }
154
155 unsafe impl<E: Send, Event: GenericEvent + Send> Send for PusEventDispatcher<E, Event> {}
157
158 impl<BackendError, Provider: GenericEvent> PusEventDispatcher<BackendError, Provider> {
159 pub fn new(
160 reporter: EventReporter,
161 backend: Box<dyn PusEventMgmtBackendProvider<Provider, Error = BackendError>>,
162 ) -> Self {
163 Self { reporter, backend }
164 }
165 }
166
167 impl<BackendError, Event: GenericEvent> PusEventDispatcher<BackendError, Event> {
168 pub fn enable_tm_for_event(&mut self, event: &Event) -> Result<bool, BackendError> {
169 self.backend.enable_event_reporting(event)
170 }
171
172 pub fn disable_tm_for_event(&mut self, event: &Event) -> Result<bool, BackendError> {
173 self.backend.disable_event_reporting(event)
174 }
175
176 pub fn generate_pus_event_tm_generic(
177 &mut self,
178 sender: &mut (impl EcssTmSenderCore + ?Sized),
179 time_stamp: &[u8],
180 event: Event,
181 aux_data: Option<&[u8]>,
182 ) -> Result<bool, EventManError> {
183 if !self.backend.event_enabled(&event) {
184 return Ok(false);
185 }
186 match event.severity() {
187 Severity::INFO => self
188 .reporter
189 .event_info(sender, time_stamp, event, aux_data)
190 .map(|_| true)
191 .map_err(|e| e.into()),
192 Severity::LOW => self
193 .reporter
194 .event_low_severity(sender, time_stamp, event, aux_data)
195 .map(|_| true)
196 .map_err(|e| e.into()),
197 Severity::MEDIUM => self
198 .reporter
199 .event_medium_severity(sender, time_stamp, event, aux_data)
200 .map(|_| true)
201 .map_err(|e| e.into()),
202 Severity::HIGH => self
203 .reporter
204 .event_high_severity(sender, time_stamp, event, aux_data)
205 .map(|_| true)
206 .map_err(|e| e.into()),
207 }
208 }
209 }
210
211 impl<BackendError> PusEventDispatcher<BackendError, EventU32> {
212 pub fn enable_tm_for_event_with_sev<Severity: HasSeverity>(
213 &mut self,
214 event: &EventU32TypedSev<Severity>,
215 ) -> Result<bool, BackendError> {
216 self.backend.enable_event_reporting(event.as_ref())
217 }
218
219 pub fn disable_tm_for_event_with_sev<Severity: HasSeverity>(
220 &mut self,
221 event: &EventU32TypedSev<Severity>,
222 ) -> Result<bool, BackendError> {
223 self.backend.disable_event_reporting(event.as_ref())
224 }
225
226 pub fn generate_pus_event_tm<Severity: HasSeverity>(
227 &mut self,
228 sender: &mut (impl EcssTmSenderCore + ?Sized),
229 time_stamp: &[u8],
230 event: EventU32TypedSev<Severity>,
231 aux_data: Option<&[u8]>,
232 ) -> Result<bool, EventManError> {
233 self.generate_pus_event_tm_generic(sender, time_stamp, event.into(), aux_data)
234 }
235 }
236}
237#[cfg(test)]
238mod tests {
239 use super::*;
240 use crate::events::SeverityInfo;
241 use crate::pus::MpscTmAsVecSender;
242 use std::sync::mpsc::{channel, TryRecvError};
243
244 const INFO_EVENT: EventU32TypedSev<SeverityInfo> =
245 EventU32TypedSev::<SeverityInfo>::const_new(1, 0);
246 const LOW_SEV_EVENT: EventU32 = EventU32::const_new(Severity::LOW, 1, 5);
247 const EMPTY_STAMP: [u8; 7] = [0; 7];
248
249 fn create_basic_man() -> PusEventDispatcher<(), EventU32> {
250 let reporter = EventReporter::new(0x02, 128).expect("Creating event repoter failed");
251 let backend = DefaultPusMgmtBackendProvider::<EventU32>::default();
252 PusEventDispatcher::new(reporter, Box::new(backend))
253 }
254
255 #[test]
256 fn test_basic() {
257 let mut event_man = create_basic_man();
258 let (event_tx, event_rx) = channel();
259 let mut sender = MpscTmAsVecSender::new(0, "test_sender", event_tx);
260 let event_sent = event_man
261 .generate_pus_event_tm(&mut sender, &EMPTY_STAMP, INFO_EVENT, None)
262 .expect("Sending info event failed");
263
264 assert!(event_sent);
265 event_rx.try_recv().expect("Receiving event TM failed");
267 }
268
269 #[test]
270 fn test_disable_event() {
271 let mut event_man = create_basic_man();
272 let (event_tx, event_rx) = channel();
273 let mut sender = MpscTmAsVecSender::new(0, "test", event_tx);
274 let res = event_man.disable_tm_for_event(&LOW_SEV_EVENT);
275 assert!(res.is_ok());
276 assert!(res.unwrap());
277 let mut event_sent = event_man
278 .generate_pus_event_tm_generic(&mut sender, &EMPTY_STAMP, LOW_SEV_EVENT, None)
279 .expect("Sending low severity event failed");
280 assert!(!event_sent);
281 let res = event_rx.try_recv();
282 assert!(res.is_err());
283 assert!(matches!(res.unwrap_err(), TryRecvError::Empty));
284 event_sent = event_man
286 .generate_pus_event_tm(&mut sender, &EMPTY_STAMP, INFO_EVENT, None)
287 .expect("Sending info event failed");
288 assert!(event_sent);
289 event_rx.try_recv().expect("No info event received");
290 }
291
292 #[test]
293 fn test_reenable_event() {
294 let mut event_man = create_basic_man();
295 let (event_tx, event_rx) = channel();
296 let mut sender = MpscTmAsVecSender::new(0, "test", event_tx);
297 let mut res = event_man.disable_tm_for_event_with_sev(&INFO_EVENT);
298 assert!(res.is_ok());
299 assert!(res.unwrap());
300 res = event_man.enable_tm_for_event_with_sev(&INFO_EVENT);
301 assert!(res.is_ok());
302 assert!(res.unwrap());
303 let event_sent = event_man
304 .generate_pus_event_tm(&mut sender, &EMPTY_STAMP, INFO_EVENT, None)
305 .expect("Sending info event failed");
306 assert!(event_sent);
307 event_rx.try_recv().expect("No info event received");
308 }
309}