This commit is contained in:
parent
c586fd7fef
commit
a00c843698
@ -68,12 +68,8 @@ impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter> DirectPusSe
|
|||||||
const SERVICE_ID: u8 = PusServiceId::Event as u8;
|
const SERVICE_ID: u8 = PusServiceId::Event as u8;
|
||||||
|
|
||||||
const SERVICE_STR: &'static str = "events";
|
const SERVICE_STR: &'static str = "events";
|
||||||
}
|
|
||||||
|
|
||||||
impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter>
|
fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus {
|
||||||
EventServiceWrapper<TmSender, TcInMemConverter>
|
|
||||||
{
|
|
||||||
pub fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus {
|
|
||||||
let error_handler = |partial_error: &PartialPusHandlingError| {
|
let error_handler = |partial_error: &PartialPusHandlingError| {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"PUS {}({}) partial error: {:?}",
|
"PUS {}({}) partial error: {:?}",
|
||||||
|
@ -234,6 +234,15 @@ pub trait TargetedPusService {
|
|||||||
fn check_for_request_timeouts(&mut self);
|
fn check_for_request_timeouts(&mut self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generic trait for services which handle packets directly. Kept minimal right now because
|
||||||
|
/// of the difficulty to allow flexible user code for these services..
|
||||||
|
pub trait DirectPusService {
|
||||||
|
const SERVICE_ID: u8;
|
||||||
|
const SERVICE_STR: &'static str;
|
||||||
|
|
||||||
|
fn poll_and_handle_next_tc(&mut self, timestamp: &[u8]) -> HandlingStatus;
|
||||||
|
}
|
||||||
|
|
||||||
/// This is a generic handler class for all PUS services where a PUS telecommand is converted
|
/// This is a generic handler class for all PUS services where a PUS telecommand is converted
|
||||||
/// to a targeted request.
|
/// to a targeted request.
|
||||||
///
|
///
|
||||||
@ -524,11 +533,6 @@ pub fn generic_pus_request_timeout_handler(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DirectPusService {
|
|
||||||
const SERVICE_ID: u8;
|
|
||||||
const SERVICE_STR: &'static str;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -84,36 +84,8 @@ impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter> DirectPusSe
|
|||||||
const SERVICE_ID: u8 = PusServiceId::Verification as u8;
|
const SERVICE_ID: u8 = PusServiceId::Verification as u8;
|
||||||
|
|
||||||
const SERVICE_STR: &'static str = "verification";
|
const SERVICE_STR: &'static str = "verification";
|
||||||
}
|
|
||||||
|
|
||||||
impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter>
|
fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus {
|
||||||
SchedulingServiceWrapper<TmSender, TcInMemConverter>
|
|
||||||
{
|
|
||||||
pub fn release_tcs(&mut self) {
|
|
||||||
let id = self.pus_11_handler.service_helper.id();
|
|
||||||
let releaser = |enabled: bool, info: &TcInfo, tc: &[u8]| -> bool {
|
|
||||||
self.tc_releaser.release(id, enabled, info, tc)
|
|
||||||
};
|
|
||||||
|
|
||||||
self.pus_11_handler
|
|
||||||
.scheduler_mut()
|
|
||||||
.update_time_from_now()
|
|
||||||
.unwrap();
|
|
||||||
let released_tcs = self
|
|
||||||
.pus_11_handler
|
|
||||||
.scheduler_mut()
|
|
||||||
.release_telecommands_with_buffer(
|
|
||||||
releaser,
|
|
||||||
&mut self.sched_tc_pool,
|
|
||||||
&mut self.releaser_buf,
|
|
||||||
)
|
|
||||||
.expect("releasing TCs failed");
|
|
||||||
if released_tcs > 0 {
|
|
||||||
info!("{released_tcs} TC(s) released from scheduler");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn poll_and_handle_next_tc(&mut self, time_stamp: &[u8]) -> HandlingStatus {
|
|
||||||
let error_handler = |partial_error: &PartialPusHandlingError| {
|
let error_handler = |partial_error: &PartialPusHandlingError| {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"PUS {}({}) partial error: {:?}",
|
"PUS {}({}) partial error: {:?}",
|
||||||
@ -160,6 +132,34 @@ impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter>
|
||||||
|
SchedulingServiceWrapper<TmSender, TcInMemConverter>
|
||||||
|
{
|
||||||
|
pub fn release_tcs(&mut self) {
|
||||||
|
let id = self.pus_11_handler.service_helper.id();
|
||||||
|
let releaser = |enabled: bool, info: &TcInfo, tc: &[u8]| -> bool {
|
||||||
|
self.tc_releaser.release(id, enabled, info, tc)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.pus_11_handler
|
||||||
|
.scheduler_mut()
|
||||||
|
.update_time_from_now()
|
||||||
|
.unwrap();
|
||||||
|
let released_tcs = self
|
||||||
|
.pus_11_handler
|
||||||
|
.scheduler_mut()
|
||||||
|
.release_telecommands_with_buffer(
|
||||||
|
releaser,
|
||||||
|
&mut self.sched_tc_pool,
|
||||||
|
&mut self.releaser_buf,
|
||||||
|
)
|
||||||
|
.expect("releasing TCs failed");
|
||||||
|
if released_tcs > 0 {
|
||||||
|
info!("{released_tcs} TC(s) released from scheduler");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_scheduler_service_static(
|
pub fn create_scheduler_service_static(
|
||||||
tm_sender: PacketSenderWithSharedPool,
|
tm_sender: PacketSenderWithSharedPool,
|
||||||
tc_releaser: PacketSenderWithSharedPool,
|
tc_releaser: PacketSenderWithSharedPool,
|
||||||
|
@ -2,19 +2,17 @@ use crate::pus::mode::ModeServiceWrapper;
|
|||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use satrs::{
|
use satrs::{
|
||||||
pus::{EcssTcInMemConverter, EcssTmSender},
|
pus::{EcssTcInMemConverter, EcssTmSender},
|
||||||
spacepackets::{
|
spacepackets::time::{cds, TimeWriter},
|
||||||
ecss::PusServiceId,
|
|
||||||
time::{cds, TimeWriter},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use satrs_example::config::CustomPusServiceId;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
action::ActionServiceWrapper, event::EventServiceWrapper, hk::HkServiceWrapper,
|
action::ActionServiceWrapper, event::EventServiceWrapper, hk::HkServiceWrapper,
|
||||||
scheduler::SchedulingServiceWrapper, test::TestCustomServiceWrapper, HandlingStatus,
|
scheduler::SchedulingServiceWrapper, test::TestCustomServiceWrapper, DirectPusService,
|
||||||
TargetedPusService,
|
HandlingStatus, TargetedPusService,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: For better extensibility, we could create 2 vectors: One for direct PUS services and one
|
||||||
|
// for targeted services..
|
||||||
#[derive(new)]
|
#[derive(new)]
|
||||||
pub struct PusStack<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter> {
|
pub struct PusStack<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter> {
|
||||||
test_srv: TestCustomServiceWrapper<TmSender, TcInMemConverter>,
|
test_srv: TestCustomServiceWrapper<TmSender, TcInMemConverter>,
|
||||||
@ -28,70 +26,56 @@ pub struct PusStack<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConvert
|
|||||||
impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter>
|
impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter>
|
||||||
PusStack<TmSender, TcInMemConverter>
|
PusStack<TmSender, TcInMemConverter>
|
||||||
{
|
{
|
||||||
|
pub fn direct_service_checker<S: DirectPusService>(
|
||||||
|
service: &mut S,
|
||||||
|
timestamp: &[u8],
|
||||||
|
nothing_to_do: &mut bool,
|
||||||
|
) {
|
||||||
|
let handling_status = service.poll_and_handle_next_tc(timestamp);
|
||||||
|
if handling_status == HandlingStatus::HandledOne {
|
||||||
|
*nothing_to_do = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn targeted_service_checker<S: TargetedPusService>(
|
||||||
|
service: &mut S,
|
||||||
|
timestamp: &[u8],
|
||||||
|
nothing_to_do: &mut bool,
|
||||||
|
) {
|
||||||
|
let request_handling = service.poll_and_handle_next_tc_default_handler(timestamp);
|
||||||
|
let reply_handling = service.poll_and_handle_next_reply_default_handler(timestamp);
|
||||||
|
if request_handling == HandlingStatus::HandledOne
|
||||||
|
|| reply_handling == HandlingStatus::HandledOne
|
||||||
|
{
|
||||||
|
*nothing_to_do = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn periodic_operation(&mut self) {
|
pub fn periodic_operation(&mut self) {
|
||||||
// Release all telecommands which reached their release time before calling the service
|
// Release all telecommands which reached their release time before calling the service
|
||||||
// handlers.
|
// handlers.
|
||||||
self.schedule_srv.release_tcs();
|
self.schedule_srv.release_tcs();
|
||||||
let time_stamp = cds::CdsTime::now_with_u16_days()
|
let timestamp = cds::CdsTime::now_with_u16_days()
|
||||||
.expect("time stamp generation error")
|
.expect("time stamp generation error")
|
||||||
.to_vec()
|
.to_vec()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// Hot loop which will run continuously until all request and reply handling is done.
|
// Hot loop which will run continuously until all request and reply handling is done.
|
||||||
loop {
|
loop {
|
||||||
let mut nothing_to_do = true;
|
let mut nothing_to_do = true;
|
||||||
let mut is_srv_finished =
|
Self::direct_service_checker(&mut self.test_srv, ×tamp, &mut nothing_to_do);
|
||||||
|_srv_id: u8,
|
Self::direct_service_checker(&mut self.schedule_srv, ×tamp, &mut nothing_to_do);
|
||||||
tc_handling_status: HandlingStatus,
|
Self::direct_service_checker(&mut self.event_srv, ×tamp, &mut nothing_to_do);
|
||||||
reply_handling_status: Option<HandlingStatus>| {
|
Self::targeted_service_checker(
|
||||||
if tc_handling_status == HandlingStatus::HandledOne
|
&mut self.action_srv_wrapper,
|
||||||
|| (reply_handling_status.is_some()
|
×tamp,
|
||||||
&& reply_handling_status.unwrap() == HandlingStatus::HandledOne)
|
&mut nothing_to_do,
|
||||||
{
|
|
||||||
nothing_to_do = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
is_srv_finished(
|
|
||||||
PusServiceId::Test as u8,
|
|
||||||
self.test_srv.poll_and_handle_next_tc(&time_stamp),
|
|
||||||
None,
|
|
||||||
);
|
);
|
||||||
is_srv_finished(
|
Self::targeted_service_checker(
|
||||||
PusServiceId::Scheduling as u8,
|
&mut self.hk_srv_wrapper,
|
||||||
self.schedule_srv.poll_and_handle_next_tc(&time_stamp),
|
×tamp,
|
||||||
None,
|
&mut nothing_to_do,
|
||||||
);
|
|
||||||
is_srv_finished(
|
|
||||||
PusServiceId::Event as u8,
|
|
||||||
self.event_srv.poll_and_handle_next_tc(&time_stamp),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
is_srv_finished(
|
|
||||||
PusServiceId::Action as u8,
|
|
||||||
self.action_srv_wrapper
|
|
||||||
.poll_and_handle_next_tc_default_handler(&time_stamp),
|
|
||||||
Some(
|
|
||||||
self.action_srv_wrapper
|
|
||||||
.poll_and_handle_next_reply_default_handler(&time_stamp),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
is_srv_finished(
|
|
||||||
PusServiceId::Housekeeping as u8,
|
|
||||||
self.hk_srv_wrapper
|
|
||||||
.poll_and_handle_next_tc_default_handler(&time_stamp),
|
|
||||||
Some(
|
|
||||||
self.hk_srv_wrapper
|
|
||||||
.poll_and_handle_next_reply_default_handler(&time_stamp),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
is_srv_finished(
|
|
||||||
CustomPusServiceId::Mode as u8,
|
|
||||||
self.mode_srv
|
|
||||||
.poll_and_handle_next_tc_default_handler(&time_stamp),
|
|
||||||
Some(
|
|
||||||
self.mode_srv
|
|
||||||
.poll_and_handle_next_reply_default_handler(&time_stamp),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
Self::targeted_service_checker(&mut self.mode_srv, ×tamp, &mut nothing_to_do);
|
||||||
if nothing_to_do {
|
if nothing_to_do {
|
||||||
// Timeout checking is only done once.
|
// Timeout checking is only done once.
|
||||||
self.action_srv_wrapper.check_for_request_timeouts();
|
self.action_srv_wrapper.check_for_request_timeouts();
|
||||||
|
@ -33,7 +33,7 @@ pub fn create_test_service_static(
|
|||||||
));
|
));
|
||||||
TestCustomServiceWrapper {
|
TestCustomServiceWrapper {
|
||||||
handler: pus17_handler,
|
handler: pus17_handler,
|
||||||
test_srv_event_sender: event_sender,
|
event_tx: event_sender,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ pub fn create_test_service_dynamic(
|
|||||||
));
|
));
|
||||||
TestCustomServiceWrapper {
|
TestCustomServiceWrapper {
|
||||||
handler: pus17_handler,
|
handler: pus17_handler,
|
||||||
test_srv_event_sender: event_sender,
|
event_tx: event_sender,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ pub struct TestCustomServiceWrapper<TmSender: EcssTmSender, TcInMemConverter: Ec
|
|||||||
{
|
{
|
||||||
pub handler:
|
pub handler:
|
||||||
PusService17TestHandler<MpscTcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
PusService17TestHandler<MpscTcReceiver, TmSender, TcInMemConverter, VerificationReporter>,
|
||||||
pub test_srv_event_sender: mpsc::SyncSender<EventMessageU32>,
|
pub event_tx: mpsc::SyncSender<EventMessageU32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter> DirectPusService
|
impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter> DirectPusService
|
||||||
@ -68,12 +68,8 @@ impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter> DirectPusSe
|
|||||||
const SERVICE_ID: u8 = PusServiceId::Test as u8;
|
const SERVICE_ID: u8 = PusServiceId::Test as u8;
|
||||||
|
|
||||||
const SERVICE_STR: &'static str = "test";
|
const SERVICE_STR: &'static str = "test";
|
||||||
}
|
|
||||||
|
|
||||||
impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter>
|
fn poll_and_handle_next_tc(&mut self, timestamp: &[u8]) -> HandlingStatus {
|
||||||
TestCustomServiceWrapper<TmSender, TcInMemConverter>
|
|
||||||
{
|
|
||||||
pub fn poll_and_handle_next_tc(&mut self, timestamp: &[u8]) -> HandlingStatus {
|
|
||||||
let error_handler = |partial_error: &PartialPusHandlingError| {
|
let error_handler = |partial_error: &PartialPusHandlingError| {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"PUS {}({}) partial error: {:?}",
|
"PUS {}({}) partial error: {:?}",
|
||||||
@ -120,7 +116,7 @@ impl<TmSender: EcssTmSender, TcInMemConverter: EcssTcInMemConverter>
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
if subservice == 128 {
|
if subservice == 128 {
|
||||||
info!("generating test event");
|
info!("generating test event");
|
||||||
self.test_srv_event_sender
|
self.event_tx
|
||||||
.send(EventMessage::new(PUS_TEST_SERVICE.id(), TEST_EVENT.into()))
|
.send(EventMessage::new(PUS_TEST_SERVICE.id(), TEST_EVENT.into()))
|
||||||
.expect("Sending test event failed");
|
.expect("Sending test event failed");
|
||||||
match self.handler.service_helper.verif_reporter().start_success(
|
match self.handler.service_helper.verif_reporter().start_success(
|
||||||
|
Loading…
Reference in New Issue
Block a user