Fixes and optimizations for camera #27

Merged
muellerr merged 5 commits from fixes-and-optimizations-camera into main 2024-04-30 17:34:28 +02:00
10 changed files with 252 additions and 180 deletions
Showing only changes of commit 9d8104be40 - Show all commits

View File

@ -2,6 +2,7 @@ use lazy_static::lazy_static;
use num_enum::{IntoPrimitive, TryFromPrimitive}; use num_enum::{IntoPrimitive, TryFromPrimitive};
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use satrs::events::{EventU32TypedSev, SeverityInfo}; use satrs::events::{EventU32TypedSev, SeverityInfo};
use satrs::res_code::ResultU16;
use satrs::spacepackets::PacketId; use satrs::spacepackets::PacketId;
use satrs_mib::res_code::ResultU16Info; use satrs_mib::res_code::ResultU16Info;
use satrs_mib::resultcode; use satrs_mib::resultcode;
@ -40,11 +41,13 @@ pub enum CustomPusServiceId {
#[derive(Debug)] #[derive(Debug)]
pub enum GroupId { pub enum GroupId {
Tmtc = 0, Generic = 0,
Hk = 1, Tmtc = 1,
Mode = 2, Hk = 2,
Action = 3, Mode = 3,
Controller = 4, Action = 4,
Controller = 5,
Camera = 6,
} }
pub const TEST_EVENT: EventU32TypedSev<SeverityInfo> = pub const TEST_EVENT: EventU32TypedSev<SeverityInfo> =
@ -187,9 +190,11 @@ pub mod cfg_file {
} }
} }
#[resultcode]
pub const GENERIC_FAILED: ResultU16 = ResultU16::new(GroupId::Generic as u8, 1);
pub mod tmtc_err { pub mod tmtc_err {
use super::*; use super::*;
use satrs::res_code::ResultU16;
#[resultcode] #[resultcode]
pub const INVALID_PUS_SERVICE: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 0); pub const INVALID_PUS_SERVICE: ResultU16 = ResultU16::new(GroupId::Tmtc as u8, 0);
@ -225,7 +230,6 @@ pub mod tmtc_err {
pub mod action_err { pub mod action_err {
use super::*; use super::*;
use satrs::res_code::ResultU16;
#[resultcode] #[resultcode]
pub const INVALID_ACTION_ID: ResultU16 = ResultU16::new(GroupId::Action as u8, 0); pub const INVALID_ACTION_ID: ResultU16 = ResultU16::new(GroupId::Action as u8, 0);
@ -235,7 +239,6 @@ pub mod action_err {
pub mod hk_err { pub mod hk_err {
use super::*; use super::*;
use satrs::res_code::ResultU16;
#[resultcode] #[resultcode]
pub const TARGET_ID_MISSING: ResultU16 = ResultU16::new(GroupId::Hk as u8, 0); pub const TARGET_ID_MISSING: ResultU16 = ResultU16::new(GroupId::Hk as u8, 0);
@ -256,7 +259,6 @@ pub mod hk_err {
pub mod mode_err { pub mod mode_err {
use super::*; use super::*;
use satrs::res_code::ResultU16;
#[resultcode] #[resultcode]
pub const WRONG_MODE: ResultU16 = ResultU16::new(GroupId::Mode as u8, 0); pub const WRONG_MODE: ResultU16 = ResultU16::new(GroupId::Mode as u8, 0);
@ -264,7 +266,6 @@ pub mod mode_err {
pub mod ctrl_err { pub mod ctrl_err {
use super::*; use super::*;
use satrs::res_code::ResultU16;
#[resultcode] #[resultcode]
pub const INVALID_CMD_FORMAT: ResultU16 = ResultU16::new(GroupId::Controller as u8, 0); pub const INVALID_CMD_FORMAT: ResultU16 = ResultU16::new(GroupId::Controller as u8, 0);
@ -290,6 +291,35 @@ pub mod ctrl_err {
]; ];
} }
pub mod cam_error {
use super::*;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum CameraError {
#[error("Error taking image: {0}")]
TakeImageError(String),
#[error("error listing image files: {0}")]
ListFileError(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
}
#[resultcode]
pub const TAKE_IMAGE_ERROR: ResultU16 = ResultU16::new(GroupId::Camera as u8, 0);
#[resultcode]
pub const NO_DATA: ResultU16 = ResultU16::new(GroupId::Camera as u8, 1);
#[resultcode]
pub const ACTION_REQ_VARIANT_NOT_IMPL: ResultU16 = ResultU16::new(GroupId::Camera as u8, 2);
#[resultcode]
pub const DESERIALIZE_ERROR: ResultU16 = ResultU16::new(GroupId::Camera as u8, 3);
// TODO: Probably could be in a dedicated modules for these returnvalues.
#[resultcode]
pub const LIST_FILE_ERROR: ResultU16 = ResultU16::new(GroupId::Camera as u8, 4);
#[resultcode]
pub const IO_ERROR: ResultU16 = ResultU16::new(GroupId::Camera as u8, 5);
}
pub mod pool { pub mod pool {
use satrs::pool::{StaticMemoryPool, StaticPoolConfig}; use satrs::pool::{StaticMemoryPool, StaticPoolConfig};

View File

@ -174,7 +174,7 @@ impl EventHandler {
let mut event_manager = EventManagerWithBoundedMpsc::new(event_rx); let mut event_manager = EventManagerWithBoundedMpsc::new(event_rx);
let pus_event_handler = PusEventHandler::new( let pus_event_handler = PusEventHandler::new(
tm_sender, tm_sender,
create_verification_reporter(PUS_EVENT_MANAGEMENT.id(), PUS_EVENT_MANAGEMENT.apid), create_verification_reporter(PUS_EVENT_MANAGEMENT.id(), PUS_EVENT_MANAGEMENT.apid, 16),
&mut event_manager, &mut event_manager,
event_request_rx, event_request_rx,
); );

View File

@ -27,22 +27,22 @@
use crate::pus::action::send_data_reply; use crate::pus::action::send_data_reply;
use crate::requests::CompositeRequest; use crate::requests::CompositeRequest;
use derive_new::new; use derive_new::new;
use log::{debug, info}; use log::info;
use num_enum::TryFromPrimitive; use num_enum::TryFromPrimitive;
use ops_sat_rs::config::cam_error::{self, CameraError};
use ops_sat_rs::config::GENERIC_FAILED;
use ops_sat_rs::TimeStampHelper; use ops_sat_rs::TimeStampHelper;
use satrs::action::{ActionRequest, ActionRequestVariant}; use satrs::action::{ActionRequest, ActionRequestVariant};
use satrs::hk::HkRequest; use satrs::hk::HkRequest;
use satrs::params::Params;
use satrs::pus::action::{ActionReplyPus, ActionReplyVariant}; use satrs::pus::action::{ActionReplyPus, ActionReplyVariant};
use satrs::pus::EcssTmtcError;
use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId}; use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId};
use satrs::res_code::ResultU16;
use satrs::tmtc::PacketAsVec; use satrs::tmtc::PacketAsVec;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt;
use std::fmt::Formatter;
use std::process::{Command, Output}; use std::process::{Command, Output};
use std::sync::mpsc; use std::sync::mpsc;
// const IMS_TESTAPP: &str = "scripts/ims100_testapp";
const IMS_TESTAPP: &str = "ims100_testapp"; const IMS_TESTAPP: &str = "ims100_testapp";
const DEFAULT_SINGLE_CAM_PARAMS: CameraPictureParameters = CameraPictureParameters { const DEFAULT_SINGLE_CAM_PARAMS: CameraPictureParameters = CameraPictureParameters {
@ -112,58 +112,6 @@ pub struct CameraPictureParameters {
pub W: u32, // wait time between pictures in ms, max: 40000 pub W: u32, // wait time between pictures in ms, max: 40000
} }
#[derive(Debug)]
#[allow(dead_code)]
pub enum CameraError {
TakeImageError,
NoDataSent,
VariantNotImplemented,
DeserializeError,
ListFileError,
IoError(std::io::Error),
EcssTmtcError(EcssTmtcError),
}
impl From<std::io::Error> for CameraError {
fn from(value: std::io::Error) -> Self {
Self::IoError(value)
}
}
impl From<EcssTmtcError> for CameraError {
fn from(value: EcssTmtcError) -> Self {
Self::EcssTmtcError(value)
}
}
impl fmt::Display for CameraError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
CameraError::TakeImageError => {
write!(f, "Error taking image.")
}
CameraError::NoDataSent => {
write!(f, "No data sent.")
}
CameraError::VariantNotImplemented => {
write!(f, "Request variant not implemented.")
}
CameraError::DeserializeError => {
write!(f, "Unable to deserialize parameters.")
}
CameraError::ListFileError => {
write!(f, "Error listing image files.")
}
CameraError::IoError(io_error) => {
write!(f, "{}", io_error)
}
CameraError::EcssTmtcError(ecss_tmtc_error) => {
write!(f, "{}", ecss_tmtc_error)
}
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Ims100BatchHandler { pub struct Ims100BatchHandler {
id: UniqueApidTargetId, id: UniqueApidTargetId,
@ -205,11 +153,7 @@ impl Ims100BatchHandler {
self.handle_hk_request(&msg.requestor_info, hk_request); self.handle_hk_request(&msg.requestor_info, hk_request);
} }
CompositeRequest::Action(action_request) => { CompositeRequest::Action(action_request) => {
if let Err(e) = self.handle_action_request(&msg.requestor_info, action_request);
self.handle_action_request(&msg.requestor_info, action_request)
{
log::warn!("camera action request IO error: {e}");
}
} }
}, },
Err(e) => match e { Err(e) => match e {
@ -235,53 +179,124 @@ impl Ims100BatchHandler {
&mut self, &mut self,
requestor_info: &MessageMetadata, requestor_info: &MessageMetadata,
action_request: &ActionRequest, action_request: &ActionRequest,
) -> Result<(), CameraError> { ) {
let param = match ActionId::try_from(action_request.action_id).expect("Invalid action id") { let param = match ActionId::try_from(action_request.action_id).expect("Invalid action id") {
ActionId::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS, ActionId::DefaultSingle => DEFAULT_SINGLE_CAM_PARAMS,
ActionId::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS, ActionId::BalancedSingle => BALANCED_SINGLE_CAM_PARAMS,
ActionId::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS, ActionId::DefaultSingleFlatSat => DEFAULT_SINGLE_FLATSAT_CAM_PARAMS,
ActionId::BalancedSingleFlatSat => BALANCED_SINGLE_FLATSAT_CAM_PARAMS, ActionId::BalancedSingleFlatSat => BALANCED_SINGLE_FLATSAT_CAM_PARAMS,
ActionId::CustomParameters => match &action_request.variant { ActionId::CustomParameters => match &action_request.variant {
ActionRequestVariant::NoData => return Err(CameraError::NoDataSent), ActionRequestVariant::NoData => {
ActionRequestVariant::StoreData(_) => { self.send_completion_failure(
// let param = serde_json::from_slice() requestor_info,
// TODO implement non dynamic version action_request,
return Err(CameraError::VariantNotImplemented); cam_error::NO_DATA,
None,
);
return;
} }
ActionRequestVariant::VecData(data) => { ActionRequestVariant::VecData(data) => {
let param: serde_json::Result<CameraPictureParameters> = let param: serde_json::Result<CameraPictureParameters> =
serde_json::from_slice(data.as_slice()); serde_json::from_slice(data.as_slice());
match param { match param {
Ok(param) => param, Ok(param) => param,
Err(_) => { Err(e) => {
return Err(CameraError::DeserializeError); self.send_completion_failure(
requestor_info,
action_request,
cam_error::DESERIALIZE_ERROR,
Some(e.to_string().into()),
);
return;
} }
} }
} }
_ => return Err(CameraError::VariantNotImplemented), _ => {
self.send_completion_failure(
requestor_info,
action_request,
cam_error::ACTION_REQ_VARIANT_NOT_IMPL,
None,
);
return;
}
}, },
}; };
let output = self.take_picture(param)?; match self.take_picture(&param) {
info!("Sending action reply!"); Ok(ref output) => {
send_data_reply(self.id, output.stdout, &self.stamp_helper, &self.tm_tx)?; self.send_completion_success(requestor_info, action_request);
self.action_reply_tx if let Err(e) =
.send(GenericMessage::new( send_data_reply(self.id, &output.stdout, &self.stamp_helper, &self.tm_tx)
*requestor_info, {
ActionReplyPus::new(action_request.action_id, ActionReplyVariant::Completed), log::error!("sending data reply unexpectedly failed: {e}");
)) }
.unwrap(); }
Ok(()) Err(e) => match e {
CameraError::TakeImageError(ref err_str) => {
self.send_completion_failure(
requestor_info,
action_request,
cam_error::TAKE_IMAGE_ERROR,
Some(err_str.to_string().into()),
);
}
CameraError::IoError(ref e) => {
self.send_completion_failure(
requestor_info,
action_request,
cam_error::IO_ERROR,
Some(e.to_string().into()),
);
}
_ => {
log::warn!("unexpected error: {:?}", e);
self.send_completion_failure(
requestor_info,
action_request,
GENERIC_FAILED,
None,
);
}
},
}
} }
pub fn take_picture(&mut self, param: CameraPictureParameters) -> Result<Output, CameraError> { pub fn send_completion_success(&self, requestor: &MessageMetadata, action_req: &ActionRequest) {
info!("Taking image!"); let result = self.action_reply_tx.send(GenericMessage::new_action_reply(
*requestor,
action_req.action_id,
ActionReplyVariant::Completed,
));
if result.is_err() {
log::error!("sending action reply failed");
}
}
pub fn send_completion_failure(
&self,
requestor: &MessageMetadata,
action_req: &ActionRequest,
error_code: ResultU16,
params: Option<Params>,
) {
let result = self.action_reply_tx.send(GenericMessage::new_action_reply(
*requestor,
action_req.action_id,
ActionReplyVariant::CompletionFailed { error_code, params },
));
if result.is_err() {
log::error!("sending action reply failed");
}
}
pub fn take_picture(&mut self, param: &CameraPictureParameters) -> Result<Output, CameraError> {
let mut cmd = Command::new(IMS_TESTAPP); let mut cmd = Command::new(IMS_TESTAPP);
cmd.arg("-R") cmd.arg("-R")
.arg(&param.R.to_string()) .arg(param.R.to_string())
.arg("-G") .arg("-G")
.arg(&param.G.to_string()) .arg(param.G.to_string())
.arg("-B") .arg("-B")
.arg(&param.B.to_string()) .arg(param.B.to_string())
.arg("-c") .arg("-c")
.arg("/dev/cam_tty") .arg("/dev/cam_tty")
.arg("-m") .arg("-m")
@ -289,18 +304,27 @@ impl Ims100BatchHandler {
.arg("-v") .arg("-v")
.arg("0") .arg("0")
.arg("-n") .arg("-n")
.arg(&param.N.to_string()); .arg(param.N.to_string());
if param.P { if param.P {
cmd.arg("-p"); cmd.arg("-p");
} }
cmd.arg("-e") cmd.arg("-e")
.arg(&param.E.to_string()) .arg(param.E.to_string())
.arg("-w") .arg("-w")
.arg(&param.W.to_string()); .arg(param.W.to_string());
info!("taking image with command: {cmd:?}");
let output = cmd.output()?; let output = cmd.output()?;
debug!("Imager Output: {}", String::from_utf8_lossy(&output.stdout)); info!("imager cmd status: {}", &output.status);
info!("imager output: {}", String::from_utf8_lossy(&output.stdout));
let mut error_string = String::new();
if !output.stderr.is_empty() {
error_string = String::from_utf8_lossy(&output.stderr).to_string();
log::warn!("imager error: {}", error_string);
}
if !output.status.success() {
return Err(CameraError::TakeImageError(error_string.to_string()));
}
Ok(output) Ok(output)
} }
@ -313,49 +337,11 @@ impl Ims100BatchHandler {
let files: Vec<String> = output_str.lines().map(|s| s.to_string()).collect(); let files: Vec<String> = output_str.lines().map(|s| s.to_string()).collect();
Ok(files) Ok(files)
} else { } else {
Err(CameraError::ListFileError) Err(CameraError::ListFileError(
String::from_utf8_lossy(&output.stderr).to_string(),
))
} }
} }
#[allow(clippy::too_many_arguments)]
#[allow(dead_code)]
pub fn take_picture_from_str(
&mut self,
R: &str,
G: &str,
B: &str,
N: &str,
P: &str,
E: &str,
W: &str,
) -> Result<(), CameraError> {
let mut cmd = Command::new("ims100_testapp");
cmd.arg("-R")
.arg(R)
.arg("-G")
.arg(G)
.arg("-B")
.arg(B)
.arg("-c")
.arg("/dev/cam_tty")
.arg("-m")
.arg("/dev/cam_sd")
.arg("-v")
.arg("0")
.arg("-n")
.arg(N)
.arg(P)
.arg("-e")
.arg(E)
.arg("-w")
.arg(W);
let output = cmd.output()?;
debug!("{}", String::from_utf8_lossy(&output.stdout));
Ok(())
}
} }
#[cfg(test)] #[cfg(test)]
@ -372,6 +358,7 @@ mod tests {
use satrs::tmtc::PacketAsVec; use satrs::tmtc::PacketAsVec;
use std::sync::mpsc; use std::sync::mpsc;
#[allow(dead_code)]
struct Ims1000Testbench { struct Ims1000Testbench {
pub handler: Ims100BatchHandler, pub handler: Ims100BatchHandler,
pub composite_req_tx: mpsc::Sender<GenericMessage<CompositeRequest>>, pub composite_req_tx: mpsc::Sender<GenericMessage<CompositeRequest>>,
@ -393,13 +380,7 @@ mod tests {
time_helper, time_helper,
); );
Ims1000Testbench { Ims1000Testbench {
handler: Ims100BatchHandler::new( handler: cam_handler,
CAMERA_HANDLER,
composite_request_rx,
tm_tx,
action_reply_tx,
time_helper,
),
composite_req_tx: composite_request_tx, composite_req_tx: composite_request_tx,
tm_receiver: tm_rx, tm_receiver: tm_rx,
action_reply_rx, action_reply_rx,
@ -412,7 +393,7 @@ mod tests {
let mut testbench = Ims1000Testbench::default(); let mut testbench = Ims1000Testbench::default();
testbench testbench
.handler .handler
.take_picture(DEFAULT_SINGLE_FLATSAT_CAM_PARAMS) .take_picture(&DEFAULT_SINGLE_FLATSAT_CAM_PARAMS)
.unwrap(); .unwrap();
} }
@ -436,7 +417,6 @@ mod tests {
testbench testbench
.handler .handler
.handle_action_request(&MessageMetadata::new(1, 1), &req) .handle_action_request(&MessageMetadata::new(1, 1), &req)
.unwrap();
} }
#[test] #[test]

View File

@ -1,4 +1,4 @@
use log::{debug, error, warn}; use log::{error, warn};
use ops_sat_rs::config::components::PUS_ACTION_SERVICE; use ops_sat_rs::config::components::PUS_ACTION_SERVICE;
use ops_sat_rs::config::tmtc_err; use ops_sat_rs::config::tmtc_err;
use ops_sat_rs::TimeStampHelper; use ops_sat_rs::TimeStampHelper;
@ -35,13 +35,13 @@ use super::{
pub const DATA_REPLY: u8 = 130; pub const DATA_REPLY: u8 = 130;
pub struct ActionReplyHandler { pub struct ActionReplyHandler {
fail_data_buf: [u8; 128], fail_data_buf: [u8; 2048],
} }
impl Default for ActionReplyHandler { impl Default for ActionReplyHandler {
fn default() -> Self { fn default() -> Self {
Self { Self {
fail_data_buf: [0; 128], fail_data_buf: [0; 2048],
} }
} }
} }
@ -74,8 +74,57 @@ impl PusReplyHandler<ActivePusActionRequestStd, ActionReplyPus> for ActionReplyH
ActionReplyVariant::CompletionFailed { error_code, params } => { ActionReplyVariant::CompletionFailed { error_code, params } => {
let mut fail_data_len = 0; let mut fail_data_len = 0;
if let Some(params) = params { if let Some(params) = params {
fail_data_len = params.write_to_be_bytes(&mut self.fail_data_buf)?; match params {
satrs::params::Params::Heapless(heapless_param) => {
// TODO: This should be part of the framework.
match heapless_param {
satrs::params::ParamsHeapless::Raw(raw) => {
// TODO: size check.
let _ = raw.write_to_be_bytes(
&mut self.fail_data_buf[0..raw.written_len()],
);
} }
satrs::params::ParamsHeapless::EcssEnum(ecss_enum) => {
// TODO: size check.
let _ = ecss_enum.write_to_be_bytes(
&mut self.fail_data_buf[0..ecss_enum.written_len()],
);
}
}
}
satrs::params::Params::Store(_) => {
log::warn!("can not process store parameters")
}
satrs::params::Params::Vec(vec) => {
// Truncate the string for now.
fail_data_len = vec.len();
if vec.len() > self.fail_data_buf.len() {
log::warn!(
"action reply vec too large, truncating to {} bytes",
self.fail_data_buf.len()
);
}
self.fail_data_buf[0..fail_data_len]
.copy_from_slice(&vec[0..fail_data_len]);
}
satrs::params::Params::String(str) => {
fail_data_len = str.len();
// Truncate the string for now.
if str.len() > self.fail_data_buf.len() {
fail_data_len = self.fail_data_buf.len();
log::warn!(
"action reply string too large, truncating to {} bytes",
self.fail_data_buf.len()
);
}
self.fail_data_buf[0..fail_data_len]
.copy_from_slice(&str.as_bytes()[0..fail_data_len]);
log::warn!("received string param with len {}", str.len());
}
_ => todo!(),
}
}
log::warn!("completion failure with fail data len: {}", fail_data_len);
verification_handler.completion_failure( verification_handler.completion_failure(
tm_sender, tm_sender,
verif_token, verif_token,
@ -209,7 +258,7 @@ pub fn create_action_service(
PUS_ACTION_SERVICE.id(), PUS_ACTION_SERVICE.id(),
pus_action_rx, pus_action_rx,
tm_funnel_tx, tm_funnel_tx,
create_verification_reporter(PUS_ACTION_SERVICE.id(), PUS_ACTION_SERVICE.apid), create_verification_reporter(PUS_ACTION_SERVICE.id(), PUS_ACTION_SERVICE.apid, 2048),
EcssTcInVecConverter::default(), EcssTcInVecConverter::default(),
), ),
ActionRequestConverter::default(), ActionRequestConverter::default(),
@ -277,7 +326,7 @@ impl TargetedPusService for ActionServiceWrapper {
pub fn send_data_reply<TmSender: EcssTmSender>( pub fn send_data_reply<TmSender: EcssTmSender>(
apid_target: UniqueApidTargetId, apid_target: UniqueApidTargetId,
reply_data: Vec<u8>, reply_data: &Vec<u8>,
stamp_helper: &TimeStampHelper, stamp_helper: &TimeStampHelper,
tm_sender: &TmSender, tm_sender: &TmSender,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
@ -287,8 +336,8 @@ pub fn send_data_reply<TmSender: EcssTmSender>(
data.extend(apid_target.apid.to_be_bytes()); data.extend(apid_target.apid.to_be_bytes());
data.extend(apid_target.unique_id.to_be_bytes()); data.extend(apid_target.unique_id.to_be_bytes());
data.extend(reply_data); data.extend(reply_data);
debug!( log::trace!(
"{}", "PUS action reply: {}",
String::from_utf8(data.clone()[6..].to_vec()).expect("Error decoding data reply.") String::from_utf8(data.clone()[6..].to_vec()).expect("Error decoding data reply.")
); );
let data_reply_tm = PusTmCreator::new(sp_header, sec_header, &data, true); let data_reply_tm = PusTmCreator::new(sp_header, sec_header, &data, true);

View File

@ -22,7 +22,7 @@ pub fn create_event_service(
PUS_EVENT_MANAGEMENT.id(), PUS_EVENT_MANAGEMENT.id(),
pus_event_rx, pus_event_rx,
tm_funnel_tx, tm_funnel_tx,
create_verification_reporter(PUS_EVENT_MANAGEMENT.id(), PUS_EVENT_MANAGEMENT.apid), create_verification_reporter(PUS_EVENT_MANAGEMENT.id(), PUS_EVENT_MANAGEMENT.apid, 16),
EcssTcInVecConverter::default(), EcssTcInVecConverter::default(),
), ),
event_request_tx, event_request_tx,

View File

@ -241,7 +241,7 @@ pub fn create_hk_service(
PUS_HK_SERVICE.id(), PUS_HK_SERVICE.id(),
pus_hk_rx, pus_hk_rx,
tm_funnel_tx, tm_funnel_tx,
create_verification_reporter(PUS_HK_SERVICE.id(), PUS_HK_SERVICE.apid), create_verification_reporter(PUS_HK_SERVICE.id(), PUS_HK_SERVICE.apid, 16),
EcssTcInVecConverter::default(), EcssTcInVecConverter::default(),
), ),
HkRequestConverter::default(), HkRequestConverter::default(),

View File

@ -37,8 +37,12 @@ pub enum HandlingStatus {
HandledOne, HandledOne,
} }
pub fn create_verification_reporter(owner_id: ComponentId, apid: Apid) -> VerificationReporter { pub fn create_verification_reporter(
let verif_cfg = VerificationReporterCfg::new(apid, 1, 2, 8).unwrap(); owner_id: ComponentId,
apid: Apid,
max_fail_data_len: usize,
) -> VerificationReporter {
let verif_cfg = VerificationReporterCfg::new(apid, 1, 2, max_fail_data_len).unwrap();
// Every software component which needs to generate verification telemetry, gets a cloned // Every software component which needs to generate verification telemetry, gets a cloned
// verification reporter. // verification reporter.
VerificationReporter::new(owner_id, &verif_cfg) VerificationReporter::new(owner_id, &verif_cfg)
@ -70,6 +74,7 @@ impl<TmSender: EcssTmSender> PusTcDistributor<TmSender> {
verif_reporter: create_verification_reporter( verif_reporter: create_verification_reporter(
PUS_ROUTING_SERVICE.id(), PUS_ROUTING_SERVICE.id(),
PUS_ROUTING_SERVICE.apid, PUS_ROUTING_SERVICE.apid,
16,
), ),
pus_router, pus_router,
stamp_helper: TimeStampHelper::default(), stamp_helper: TimeStampHelper::default(),
@ -406,21 +411,25 @@ where
return Ok(()); return Ok(());
} }
let active_request = active_req_opt.unwrap(); let active_request = active_req_opt.unwrap();
let request_finished = self match self.reply_handler.handle_reply(
.reply_handler
.handle_reply(
reply, reply,
active_request, active_request,
&self.service_helper.common.tm_sender, &self.service_helper.common.tm_sender,
&self.service_helper.common.verif_reporter, &self.service_helper.common.verif_reporter,
time_stamp, time_stamp,
) ) {
.unwrap_or(false); Ok(finished) => {
if request_finished { if finished {
self.active_request_map.remove(reply.request_id()); self.active_request_map.remove(reply.request_id());
} }
Ok(()) Ok(())
} }
Err(e) => {
self.active_request_map.remove(reply.request_id());
Err(e)
}
}
}
pub fn check_for_request_timeouts(&mut self) { pub fn check_for_request_timeouts(&mut self) {
let mut requests_to_delete = Vec::new(); let mut requests_to_delete = Vec::new();

View File

@ -212,7 +212,7 @@ pub fn create_mode_service(
PUS_MODE_SERVICE.id(), PUS_MODE_SERVICE.id(),
pus_action_rx, pus_action_rx,
tm_funnel_tx, tm_funnel_tx,
create_verification_reporter(PUS_MODE_SERVICE.id(), PUS_MODE_SERVICE.apid), create_verification_reporter(PUS_MODE_SERVICE.id(), PUS_MODE_SERVICE.apid, 16),
EcssTcInVecConverter::default(), EcssTcInVecConverter::default(),
), ),
ModeRequestConverter::default(), ModeRequestConverter::default(),

View File

@ -139,7 +139,11 @@ pub fn create_scheduler_service(
PUS_SCHEDULER_SERVICE.id(), PUS_SCHEDULER_SERVICE.id(),
pus_sched_rx, pus_sched_rx,
tm_funnel_tx, tm_funnel_tx,
create_verification_reporter(PUS_SCHEDULER_SERVICE.id(), PUS_SCHEDULER_SERVICE.apid), create_verification_reporter(
PUS_SCHEDULER_SERVICE.id(),
PUS_SCHEDULER_SERVICE.apid,
16,
),
EcssTcInVecConverter::default(), EcssTcInVecConverter::default(),
), ),
scheduler, scheduler,

View File

@ -27,7 +27,7 @@ pub fn create_test_service(
PUS_TEST_SERVICE.id(), PUS_TEST_SERVICE.id(),
pus_test_rx, pus_test_rx,
tm_funnel_tx, tm_funnel_tx,
create_verification_reporter(PUS_TEST_SERVICE.id(), PUS_TEST_SERVICE.apid), create_verification_reporter(PUS_TEST_SERVICE.id(), PUS_TEST_SERVICE.apid, 16),
EcssTcInVecConverter::default(), EcssTcInVecConverter::default(),
)); ));
TestCustomServiceWrapper { TestCustomServiceWrapper {