2024-02-12 15:51:37 +01:00
|
|
|
use satrs::event_man::{
|
2024-04-03 11:46:01 +02:00
|
|
|
EventManagerWithMpsc, EventMessage, EventMessageU32, EventRoutingError, EventSendProvider,
|
|
|
|
EventU32SenderMpsc, MpscEventU32Receiver,
|
2023-01-11 10:30:03 +01:00
|
|
|
};
|
2024-02-12 15:51:37 +01:00
|
|
|
use satrs::events::{EventU32, EventU32TypedSev, Severity, SeverityInfo};
|
|
|
|
use satrs::params::U32Pair;
|
|
|
|
use satrs::params::{Params, ParamsHeapless, WritableToBeBytes};
|
2024-02-23 14:19:30 +01:00
|
|
|
use satrs::pus::event_man::{DefaultPusEventMgmtBackend, EventReporter, PusEventDispatcher};
|
2024-04-03 11:28:20 +02:00
|
|
|
use satrs::pus::test_util::TEST_COMPONENT_ID_0;
|
2024-04-02 16:50:09 +02:00
|
|
|
use satrs::pus::PusTmAsVec;
|
|
|
|
use satrs::request::UniqueApidTargetId;
|
2023-07-11 22:25:43 +02:00
|
|
|
use spacepackets::ecss::tm::PusTmReader;
|
2023-02-27 17:00:21 +01:00
|
|
|
use spacepackets::ecss::{PusError, PusPacket};
|
2024-02-26 11:41:42 +01:00
|
|
|
use std::sync::mpsc::{self, SendError, TryRecvError};
|
2023-01-11 10:30:03 +01:00
|
|
|
use std::thread;
|
|
|
|
|
|
|
|
const INFO_EVENT: EventU32TypedSev<SeverityInfo> =
|
|
|
|
EventU32TypedSev::<SeverityInfo>::const_new(1, 0);
|
|
|
|
const LOW_SEV_EVENT: EventU32 = EventU32::const_new(Severity::LOW, 1, 5);
|
|
|
|
const EMPTY_STAMP: [u8; 7] = [0; 7];
|
2024-04-02 16:50:09 +02:00
|
|
|
const TEST_APID: u16 = 0x02;
|
|
|
|
const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
|
2023-01-11 10:30:03 +01:00
|
|
|
|
2023-02-27 17:00:21 +01:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum CustomTmSenderError {
|
|
|
|
SendError(SendError<Vec<u8>>),
|
|
|
|
PusError(PusError),
|
|
|
|
}
|
|
|
|
|
2023-01-11 10:30:03 +01:00
|
|
|
#[test]
|
|
|
|
fn test_threaded_usage() {
|
2024-02-26 11:41:42 +01:00
|
|
|
let (event_sender, event_man_receiver) = mpsc::channel();
|
2023-01-11 10:30:03 +01:00
|
|
|
let event_receiver = MpscEventU32Receiver::new(event_man_receiver);
|
2024-02-23 14:19:30 +01:00
|
|
|
let mut event_man = EventManagerWithMpsc::new(event_receiver);
|
2023-01-11 10:30:03 +01:00
|
|
|
|
2024-02-26 11:41:42 +01:00
|
|
|
let (pus_event_man_tx, pus_event_man_rx) = mpsc::channel();
|
2024-02-23 14:19:30 +01:00
|
|
|
let pus_event_man_send_provider = EventU32SenderMpsc::new(1, pus_event_man_tx);
|
2024-04-02 16:50:09 +02:00
|
|
|
event_man.subscribe_all(pus_event_man_send_provider.target_id());
|
2023-01-11 10:30:03 +01:00
|
|
|
event_man.add_sender(pus_event_man_send_provider);
|
2024-04-02 16:50:09 +02:00
|
|
|
let (event_tx, event_rx) = mpsc::channel::<PusTmAsVec>();
|
|
|
|
let reporter =
|
|
|
|
EventReporter::new(TEST_ID.raw(), 0x02, 128).expect("Creating event reporter failed");
|
|
|
|
let pus_event_man = PusEventDispatcher::new(reporter, DefaultPusEventMgmtBackend::default());
|
2024-04-03 11:46:01 +02:00
|
|
|
let error_handler = |event_msg: &EventMessageU32, error: EventRoutingError| {
|
|
|
|
panic!("received routing error for event {event_msg:?}: {error:?}");
|
2024-04-03 11:28:20 +02:00
|
|
|
};
|
2023-01-11 10:30:03 +01:00
|
|
|
// PUS + Generic event manager thread
|
|
|
|
let jh0 = thread::spawn(move || {
|
|
|
|
let mut event_cnt = 0;
|
|
|
|
let mut params_array: [u8; 128] = [0; 128];
|
|
|
|
loop {
|
2024-04-03 11:28:20 +02:00
|
|
|
event_man.try_event_handling(error_handler);
|
2023-01-11 10:30:03 +01:00
|
|
|
match pus_event_man_rx.try_recv() {
|
2024-04-03 11:28:20 +02:00
|
|
|
Ok(event_msg) => {
|
2024-04-02 16:50:09 +02:00
|
|
|
let gen_event = |aux_data| {
|
2023-01-11 10:30:03 +01:00
|
|
|
pus_event_man.generate_pus_event_tm_generic(
|
2024-04-02 16:50:09 +02:00
|
|
|
&event_tx,
|
2023-01-11 10:30:03 +01:00
|
|
|
&EMPTY_STAMP,
|
2024-04-03 11:28:20 +02:00
|
|
|
event_msg.event(),
|
2023-01-11 10:30:03 +01:00
|
|
|
aux_data,
|
|
|
|
)
|
|
|
|
};
|
2024-04-03 11:28:20 +02:00
|
|
|
let res = if let Some(aux_data) = event_msg.params() {
|
2023-01-11 10:30:03 +01:00
|
|
|
match aux_data {
|
|
|
|
Params::Heapless(heapless) => match heapless {
|
|
|
|
ParamsHeapless::Raw(raw) => {
|
|
|
|
raw.write_to_be_bytes(&mut params_array)
|
|
|
|
.expect("Writing raw parameter failed");
|
2024-04-02 16:50:09 +02:00
|
|
|
gen_event(Some(¶ms_array[0..raw.written_len()]))
|
2023-01-11 10:30:03 +01:00
|
|
|
}
|
|
|
|
ParamsHeapless::EcssEnum(e) => {
|
|
|
|
e.write_to_be_bytes(&mut params_array)
|
|
|
|
.expect("Writing ECSS enum failed");
|
2024-04-02 16:50:09 +02:00
|
|
|
gen_event(Some(¶ms_array[0..e.written_len()]))
|
2023-01-11 10:30:03 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
Params::Vec(vec) => gen_event(Some(vec.as_slice())),
|
|
|
|
Params::String(str) => gen_event(Some(str.as_bytes())),
|
|
|
|
Params::Store(_) => gen_event(None),
|
2024-02-23 14:19:30 +01:00
|
|
|
_ => panic!("unsupported parameter type"),
|
2023-01-11 10:30:03 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
gen_event(None)
|
|
|
|
};
|
|
|
|
event_cnt += 1;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
assert!(res.unwrap());
|
|
|
|
if event_cnt == 2 {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
if let TryRecvError::Disconnected = e {
|
|
|
|
panic!("Event receiver disconnected!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Event sender and TM checker thread
|
|
|
|
let jh1 = thread::spawn(move || {
|
|
|
|
event_sender
|
2024-04-03 11:28:20 +02:00
|
|
|
.send(EventMessage::new(
|
|
|
|
TEST_COMPONENT_ID_0.id(),
|
|
|
|
INFO_EVENT.into(),
|
|
|
|
))
|
2023-01-11 10:30:03 +01:00
|
|
|
.expect("Sending info event failed");
|
|
|
|
loop {
|
|
|
|
match event_rx.try_recv() {
|
|
|
|
// Event TM received successfully
|
|
|
|
Ok(event_tm) => {
|
2024-04-02 16:50:09 +02:00
|
|
|
let tm = PusTmReader::new(event_tm.packet.as_slice(), 7)
|
|
|
|
.expect("Deserializing TM failed");
|
2023-01-11 10:30:03 +01:00
|
|
|
assert_eq!(tm.0.service(), 5);
|
|
|
|
assert_eq!(tm.0.subservice(), 1);
|
|
|
|
let src_data = tm.0.source_data();
|
2023-07-11 00:28:28 +02:00
|
|
|
assert!(!src_data.is_empty());
|
2023-01-11 10:30:03 +01:00
|
|
|
assert_eq!(src_data.len(), 4);
|
|
|
|
let event =
|
|
|
|
EventU32::from(u32::from_be_bytes(src_data[0..4].try_into().unwrap()));
|
|
|
|
assert_eq!(event, INFO_EVENT);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
if let TryRecvError::Disconnected = e {
|
|
|
|
panic!("Event sender disconnected!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
event_sender
|
2024-04-03 11:28:20 +02:00
|
|
|
.send(EventMessage::new_with_params(
|
|
|
|
TEST_COMPONENT_ID_0.id(),
|
|
|
|
LOW_SEV_EVENT,
|
2024-04-03 11:46:01 +02:00
|
|
|
&Params::Heapless((2_u32, 3_u32).into()),
|
2024-04-03 11:28:20 +02:00
|
|
|
))
|
2023-01-11 10:30:03 +01:00
|
|
|
.expect("Sending low severity event failed");
|
|
|
|
loop {
|
|
|
|
match event_rx.try_recv() {
|
|
|
|
// Event TM received successfully
|
|
|
|
Ok(event_tm) => {
|
2024-04-02 16:50:09 +02:00
|
|
|
let tm = PusTmReader::new(event_tm.packet.as_slice(), 7)
|
|
|
|
.expect("Deserializing TM failed");
|
2023-01-11 10:30:03 +01:00
|
|
|
assert_eq!(tm.0.service(), 5);
|
|
|
|
assert_eq!(tm.0.subservice(), 2);
|
|
|
|
let src_data = tm.0.source_data();
|
2023-07-11 00:28:28 +02:00
|
|
|
assert!(!src_data.is_empty());
|
2023-01-11 10:30:03 +01:00
|
|
|
assert_eq!(src_data.len(), 12);
|
|
|
|
let event =
|
|
|
|
EventU32::from(u32::from_be_bytes(src_data[0..4].try_into().unwrap()));
|
|
|
|
assert_eq!(event, LOW_SEV_EVENT);
|
|
|
|
let u32_pair: U32Pair =
|
|
|
|
src_data[4..].try_into().expect("Creating U32Pair failed");
|
|
|
|
assert_eq!(u32_pair.0, 2);
|
|
|
|
assert_eq!(u32_pair.1, 3);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
Err(e) => {
|
|
|
|
if let TryRecvError::Disconnected = e {
|
|
|
|
panic!("Event sender disconnected!")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
jh0.join().expect("Joining manager thread failed");
|
|
|
|
jh1.join().expect("Joining creator thread failed");
|
|
|
|
}
|