sat-rs/satrs-core/src/pus/scheduler_srv.rs

177 lines
6.4 KiB
Rust
Raw Normal View History

2024-01-30 01:18:48 +01:00
use crate::pool::SharedPool;
2023-07-05 11:25:23 +02:00
use crate::pus::scheduler::PusScheduler;
2024-01-30 01:18:48 +01:00
use crate::pus::verification::StdVerifReporterWithSender;
2023-07-05 11:25:23 +02:00
use crate::pus::{
2024-01-30 01:18:48 +01:00
EcssTcReceiver, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError,
PusServiceBaseWithStore,
2023-07-05 11:25:23 +02:00
};
2023-07-11 00:44:48 +02:00
use spacepackets::ecss::tc::PusTcReader;
2023-07-05 11:25:23 +02:00
use spacepackets::ecss::{scheduling, PusPacket};
use spacepackets::time::cds::TimeProvider;
2023-07-09 13:32:59 +02:00
use std::boxed::Box;
2023-07-05 11:25:23 +02:00
2023-07-06 01:14:01 +02:00
/// This is a helper class for [std] environments to handle generic PUS 11 (scheduling service)
/// packets. This handler is constrained to using the [PusScheduler], but is able to process
/// the most important PUS requests for a scheduling service.
///
/// Please note that this class does not do the regular periodic handling like releasing any
/// telecommands inside the scheduler. The user can retrieve the wrapped scheduler via the
/// [Self::scheduler] and [Self::scheduler_mut] function and then use the scheduler API to release
/// telecommands when applicable.
2023-07-05 11:25:23 +02:00
pub struct PusService11SchedHandler {
2024-01-30 01:18:48 +01:00
psb: PusServiceBaseWithStore,
2023-07-05 11:25:23 +02:00
scheduler: PusScheduler,
}
impl PusService11SchedHandler {
pub fn new(
2023-07-09 20:05:45 +02:00
tc_receiver: Box<dyn EcssTcReceiver>,
2023-07-10 00:29:31 +02:00
shared_tc_store: SharedPool,
2023-07-09 13:32:59 +02:00
tm_sender: Box<dyn EcssTmSender>,
2023-07-05 11:25:23 +02:00
tm_apid: u16,
verification_handler: StdVerifReporterWithSender,
scheduler: PusScheduler,
) -> Self {
Self {
2024-01-30 01:18:48 +01:00
psb: PusServiceBaseWithStore::new(
2023-07-10 00:29:31 +02:00
tc_receiver,
shared_tc_store,
tm_sender,
tm_apid,
verification_handler,
),
2023-07-05 11:25:23 +02:00
scheduler,
}
}
2023-07-05 15:12:03 +02:00
pub fn scheduler_mut(&mut self) -> &mut PusScheduler {
&mut self.scheduler
}
2023-07-06 01:14:01 +02:00
pub fn scheduler(&self) -> &PusScheduler {
&self.scheduler
}
2023-07-05 11:25:23 +02:00
2024-01-30 01:18:48 +01:00
pub fn handle_one_tc(&mut self) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
2024-01-30 09:59:45 +01:00
let possible_packet = self.psb.retrieve_and_accept_next_packet()?;
2024-01-30 01:18:48 +01:00
if possible_packet.is_none() {
return Ok(PusPacketHandlerResult::Empty);
}
let (addr, token) = possible_packet.unwrap();
self.psb.copy_tc_to_buf(addr)?;
2023-07-11 00:44:48 +02:00
let (tc, _) = PusTcReader::new(&self.psb.pus_buf)?;
2023-07-10 00:29:31 +02:00
let subservice = tc.subservice();
let std_service = scheduling::Subservice::try_from(subservice);
2023-07-05 11:25:23 +02:00
if std_service.is_err() {
2023-07-05 11:58:43 +02:00
return Ok(PusPacketHandlerResult::CustomSubservice(
tc.subservice(),
2023-07-10 00:29:31 +02:00
token,
2023-07-05 11:58:43 +02:00
));
2023-07-05 11:25:23 +02:00
}
2023-07-05 21:08:04 +02:00
let mut partial_error = None;
2024-01-30 01:18:48 +01:00
let time_stamp = self.psb.get_current_timestamp(&mut partial_error);
2023-07-05 11:25:23 +02:00
match std_service.unwrap() {
scheduling::Subservice::TcEnableScheduling => {
let start_token = self
.psb
.verification_handler
2023-07-06 00:49:18 +02:00
.get_mut()
2023-07-05 21:08:04 +02:00
.start_success(token, Some(&time_stamp))
2023-07-05 11:25:23 +02:00
.expect("Error sending start success");
self.scheduler.enable();
if self.scheduler.is_enabled() {
self.psb
.verification_handler
2023-07-06 00:49:18 +02:00
.get_mut()
2023-07-05 21:08:04 +02:00
.completion_success(start_token, Some(&time_stamp))
2023-07-05 11:25:23 +02:00
.expect("Error sending completion success");
} else {
panic!("Failed to enable scheduler");
}
}
scheduling::Subservice::TcDisableScheduling => {
let start_token = self
.psb
.verification_handler
2023-07-06 00:49:18 +02:00
.get_mut()
2023-07-05 21:08:04 +02:00
.start_success(token, Some(&time_stamp))
2023-07-05 11:25:23 +02:00
.expect("Error sending start success");
self.scheduler.disable();
if !self.scheduler.is_enabled() {
self.psb
.verification_handler
2023-07-06 00:49:18 +02:00
.get_mut()
2023-07-05 21:08:04 +02:00
.completion_success(start_token, Some(&time_stamp))
2023-07-05 11:25:23 +02:00
.expect("Error sending completion success");
} else {
panic!("Failed to disable scheduler");
}
}
scheduling::Subservice::TcResetScheduling => {
let start_token = self
.psb
.verification_handler
2023-07-06 00:49:18 +02:00
.get_mut()
2023-07-05 21:08:04 +02:00
.start_success(token, Some(&time_stamp))
2023-07-05 11:25:23 +02:00
.expect("Error sending start success");
2023-07-10 00:29:31 +02:00
let mut pool = self
.psb
.shared_tc_store
.write()
.expect("Locking pool failed");
2023-07-05 11:25:23 +02:00
self.scheduler
.reset(pool.as_mut())
.expect("Error resetting TC Pool");
self.psb
.verification_handler
2023-07-06 00:49:18 +02:00
.get_mut()
2023-07-05 21:08:04 +02:00
.completion_success(start_token, Some(&time_stamp))
2023-07-05 11:25:23 +02:00
.expect("Error sending completion success");
}
scheduling::Subservice::TcInsertActivity => {
let start_token = self
.psb
.verification_handler
2023-07-06 00:49:18 +02:00
.get_mut()
2023-07-05 21:08:04 +02:00
.start_success(token, Some(&time_stamp))
2023-07-05 11:25:23 +02:00
.expect("error sending start success");
2023-07-10 00:29:31 +02:00
let mut pool = self
.psb
.shared_tc_store
.write()
.expect("locking pool failed");
2023-07-05 11:25:23 +02:00
self.scheduler
.insert_wrapped_tc::<TimeProvider>(&tc, pool.as_mut())
.expect("insertion of activity into pool failed");
self.psb
.verification_handler
2023-07-06 00:49:18 +02:00
.get_mut()
2023-07-05 21:08:04 +02:00
.completion_success(start_token, Some(&time_stamp))
2023-07-05 11:25:23 +02:00
.expect("sending completion success failed");
}
_ => {
2023-07-05 11:58:43 +02:00
return Ok(PusPacketHandlerResult::CustomSubservice(
tc.subservice(),
2023-07-10 00:29:31 +02:00
token,
2023-07-05 11:58:43 +02:00
));
2023-07-05 11:25:23 +02:00
}
}
if let Some(partial_error) = partial_error {
return Ok(PusPacketHandlerResult::RequestHandledPartialSuccess(
partial_error,
));
}
2023-07-05 11:58:43 +02:00
Ok(PusPacketHandlerResult::CustomSubservice(
tc.subservice(),
2023-07-10 00:29:31 +02:00
token,
2023-07-05 11:58:43 +02:00
))
2023-07-05 11:25:23 +02:00
}
}