This commit is contained in:
2023-07-05 14:25:51 +02:00
parent 363770066d
commit 52a7682a55
11 changed files with 226 additions and 407 deletions

View File

@ -10,7 +10,7 @@ use hashbrown::HashSet;
#[cfg(feature = "alloc")]
pub use crate::pus::event::EventReporter;
use crate::pus::verification::{TcStateStarted, VerificationToken};
use crate::pus::verification::TcStateToken;
#[cfg(feature = "alloc")]
use crate::pus::EcssTmSenderCore;
use crate::pus::EcssTmtcErrorWithSend;
@ -91,7 +91,7 @@ pub enum EventRequest<Event: GenericEvent = EventU32> {
#[derive(Debug)]
pub struct EventRequestWithToken<Event: GenericEvent = EventU32> {
pub request: EventRequest<Event>,
pub token: VerificationToken<TcStateStarted>,
pub token: TcStateToken,
}
#[derive(Debug)]

View File

@ -0,0 +1,144 @@
use crate::events::EventU32;
use crate::pool::{SharedPool, StoreAddr};
use crate::pus::event_man::{EventRequest, EventRequestWithToken};
use crate::pus::verification::{
StdVerifReporterWithSender, TcStateAccepted, TcStateToken, VerificationToken,
};
use crate::pus::{
AcceptedTc, PartialPusHandlingError, PusPacketHandlerResult, PusPacketHandlingError,
PusServiceBase, PusServiceHandler,
};
use crate::tmtc::tm_helper::SharedTmStore;
use spacepackets::ecss::event::Subservice;
use spacepackets::ecss::PusPacket;
use spacepackets::tc::PusTc;
use std::format;
use std::sync::mpsc::{Receiver, Sender};
pub struct PusService5EventHandler {
psb: PusServiceBase,
event_request_tx: Sender<EventRequestWithToken>,
}
impl PusService5EventHandler {
pub fn new(
receiver: Receiver<AcceptedTc>,
tc_pool: SharedPool,
tm_tx: Sender<StoreAddr>,
tm_store: SharedTmStore,
tm_apid: u16,
verification_handler: StdVerifReporterWithSender,
event_request_tx: Sender<EventRequestWithToken>,
) -> Self {
Self {
psb: PusServiceBase::new(
receiver,
tc_pool,
tm_tx,
tm_store,
tm_apid,
verification_handler,
),
event_request_tx,
}
}
}
impl PusServiceHandler for PusService5EventHandler {
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> {
{
// Keep locked section as short as possible.
let mut tc_pool = self
.psb
.tc_store
.write()
.map_err(|e| PusPacketHandlingError::RwGuardError(format!("{e}")))?;
let tc_guard = tc_pool.read_with_guard(addr);
let tc_raw = tc_guard.read().unwrap();
self.psb.pus_buf[0..tc_raw.len()].copy_from_slice(tc_raw);
}
let (tc, _) = PusTc::from_bytes(&self.psb.pus_buf).unwrap();
let srv = Subservice::try_from(tc.subservice());
if srv.is_err() {
return Ok(PusPacketHandlerResult::CustomSubservice(
tc.subservice(),
token,
));
}
let mut handle_enable_disable_request = |enable: bool| {
if tc.user_data().is_none() || tc.user_data().unwrap().len() < 4 {
return Err(PusPacketHandlingError::NotEnoughAppData(
"At least 4 bytes event ID expected".into(),
));
}
let user_data = tc.user_data().unwrap();
let event_u32 = EventU32::from(u32::from_be_bytes(user_data[0..4].try_into().unwrap()));
let start_token = self
.psb
.verification_handler
.start_success(token, Some(&self.psb.stamp_buf))
.map_err(|_| PartialPusHandlingError::VerificationError);
let partial_error = start_token.clone().err();
let mut token: TcStateToken = token.into();
if let Ok(start_token) = start_token {
token = start_token.into();
}
let event_req_with_token = if enable {
EventRequestWithToken {
request: EventRequest::Enable(event_u32),
token,
}
} else {
EventRequestWithToken {
request: EventRequest::Disable(event_u32),
token,
}
};
self.event_request_tx
.send(event_req_with_token)
.map_err(|_| {
PusPacketHandlingError::SendError("Forwarding event request failed".into())
})?;
if let Some(partial_error) = partial_error {
return Ok(PusPacketHandlerResult::RequestHandledPartialSuccess(
partial_error,
));
}
Ok(PusPacketHandlerResult::RequestHandled)
};
match srv.unwrap() {
Subservice::TmInfoReport
| Subservice::TmLowSeverityReport
| Subservice::TmMediumSeverityReport
| Subservice::TmHighSeverityReport => {
return Err(PusPacketHandlingError::InvalidSubservice(tc.subservice()))
}
Subservice::TcEnableEventGeneration => {
handle_enable_disable_request(true)?;
}
Subservice::TcDisableEventGeneration => {
handle_enable_disable_request(false)?;
}
Subservice::TcReportDisabledList | Subservice::TmDisabledEventsReport => {
return Ok(PusPacketHandlerResult::SubserviceNotImplemented(
tc.subservice(),
token,
));
}
}
Ok(PusPacketHandlerResult::RequestHandled)
}
}

View File

@ -11,6 +11,7 @@ use spacepackets::{ByteConversionError, SizeMissmatch};
pub mod event;
pub mod event_man;
pub mod event_srv;
pub mod hk;
pub mod mode;
pub mod scheduler;
@ -289,13 +290,17 @@ pub mod std_mod {
PusError(#[from] PusError),
#[error("Wrong service number {0} for packet handler")]
WrongService(u8),
#[error("Invalid subservice {0}")]
InvalidSubservice(u8),
#[error("Not enough application data available: {0}")]
NotEnoughAppData(String),
#[error("Generic store error: {0}")]
StoreError(#[from] StoreError),
#[error("Error with the pool RwGuard")]
#[error("Error with the pool RwGuard: {0}")]
RwGuardError(String),
#[error("MQ backend disconnect error")]
#[error("MQ send error: {0}")]
SendError(String),
#[error("TX message queue side has disconnected")]
QueueDisconnected,
#[error("Other error {0}")]
OtherError(String),
@ -315,6 +320,7 @@ pub mod std_mod {
pub enum PusPacketHandlerResult {
RequestHandled,
RequestHandledPartialSuccess(PartialPusHandlingError),
SubserviceNotImplemented(u8, VerificationToken<TcStateAccepted>),
CustomSubservice(u8, VerificationToken<TcStateAccepted>),
Empty,
}

View File

@ -227,6 +227,17 @@ impl From<VerificationToken<TcStateNone>> for TcStateToken {
}
}
impl TryFrom<TcStateToken> for VerificationToken<TcStateAccepted> {
type Error = ();
fn try_from(value: TcStateToken) -> Result<Self, Self::Error> {
if let TcStateToken::Accepted(token) = value {
Ok(token)
} else {
return Err(());
}
}
}
impl From<VerificationToken<TcStateAccepted>> for TcStateToken {
fn from(t: VerificationToken<TcStateAccepted>) -> Self {
TcStateToken::Accepted(t)