2023-07-05 11:25:23 +02:00
|
|
|
use crate::pool::{SharedPool, StoreAddr};
|
|
|
|
use crate::pus::scheduler::PusScheduler;
|
|
|
|
use crate::pus::verification::{StdVerifReporterWithSender, TcStateAccepted, VerificationToken};
|
|
|
|
use crate::pus::{
|
2023-07-05 21:08:04 +02:00
|
|
|
AcceptedTc, PusPacketHandlerResult, PusPacketHandlingError, PusServiceBase, PusServiceHandler,
|
2023-07-05 11:25:23 +02:00
|
|
|
};
|
|
|
|
use crate::tmtc::tm_helper::SharedTmStore;
|
|
|
|
use spacepackets::ecss::{scheduling, PusPacket};
|
|
|
|
use spacepackets::tc::PusTc;
|
|
|
|
use spacepackets::time::cds::TimeProvider;
|
|
|
|
use std::sync::mpsc::{Receiver, Sender};
|
|
|
|
|
|
|
|
pub struct PusService11SchedHandler {
|
|
|
|
psb: PusServiceBase,
|
|
|
|
scheduler: PusScheduler,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PusService11SchedHandler {
|
|
|
|
pub fn new(
|
|
|
|
receiver: Receiver<AcceptedTc>,
|
|
|
|
tc_pool: SharedPool,
|
|
|
|
tm_tx: Sender<StoreAddr>,
|
|
|
|
tm_store: SharedTmStore,
|
|
|
|
tm_apid: u16,
|
|
|
|
verification_handler: StdVerifReporterWithSender,
|
|
|
|
scheduler: PusScheduler,
|
|
|
|
) -> Self {
|
|
|
|
Self {
|
|
|
|
psb: PusServiceBase::new(
|
|
|
|
receiver,
|
|
|
|
tc_pool,
|
|
|
|
tm_tx,
|
|
|
|
tm_store,
|
|
|
|
tm_apid,
|
|
|
|
verification_handler,
|
|
|
|
),
|
|
|
|
scheduler,
|
|
|
|
}
|
|
|
|
}
|
2023-07-05 15:12:03 +02:00
|
|
|
|
|
|
|
pub fn scheduler_mut(&mut self) -> &mut PusScheduler {
|
|
|
|
&mut self.scheduler
|
|
|
|
}
|
2023-07-05 11:25:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl PusServiceHandler for PusService11SchedHandler {
|
|
|
|
fn psb_mut(&mut self) -> &mut PusServiceBase {
|
|
|
|
&mut self.psb
|
|
|
|
}
|
|
|
|
fn psb(&self) -> &PusServiceBase {
|
|
|
|
&self.psb
|
|
|
|
}
|
|
|
|
|
|
|
|
fn handle_one_tc(
|
|
|
|
&mut self,
|
|
|
|
addr: StoreAddr,
|
|
|
|
token: VerificationToken<TcStateAccepted>,
|
|
|
|
) -> Result<PusPacketHandlerResult, PusPacketHandlingError> {
|
2023-07-05 21:08:04 +02:00
|
|
|
self.copy_tc_to_buf(addr)?;
|
2023-07-05 11:25:23 +02:00
|
|
|
let (tc, _) = PusTc::from_bytes(&self.psb.pus_buf).unwrap();
|
|
|
|
let std_service = scheduling::Subservice::try_from(tc.subservice());
|
|
|
|
if std_service.is_err() {
|
2023-07-05 11:58:43 +02:00
|
|
|
return Ok(PusPacketHandlerResult::CustomSubservice(
|
|
|
|
tc.subservice(),
|
|
|
|
token,
|
|
|
|
));
|
2023-07-05 11:25:23 +02:00
|
|
|
}
|
2023-07-05 21:08:04 +02:00
|
|
|
let mut partial_error = None;
|
|
|
|
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-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-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-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-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-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");
|
|
|
|
|
|
|
|
let mut pool = self.psb.tc_store.write().expect("Locking pool failed");
|
|
|
|
|
|
|
|
self.scheduler
|
|
|
|
.reset(pool.as_mut())
|
|
|
|
.expect("Error resetting TC Pool");
|
|
|
|
|
|
|
|
self.psb
|
|
|
|
.verification_handler
|
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-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");
|
|
|
|
|
|
|
|
let mut pool = self.psb.tc_store.write().expect("locking pool failed");
|
|
|
|
self.scheduler
|
|
|
|
.insert_wrapped_tc::<TimeProvider>(&tc, pool.as_mut())
|
|
|
|
.expect("insertion of activity into pool failed");
|
|
|
|
|
|
|
|
self.psb
|
|
|
|
.verification_handler
|
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(),
|
|
|
|
token,
|
|
|
|
));
|
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(),
|
|
|
|
token,
|
|
|
|
))
|
2023-07-05 11:25:23 +02:00
|
|
|
}
|
|
|
|
}
|