sat-rs/satrs-example/src/pus/hk.rs

184 lines
6.9 KiB
Rust
Raw Normal View History

2023-07-06 00:49:18 +02:00
use crate::requests::{Request, RequestWithToken};
use log::{error, warn};
use satrs_core::hk::{CollectionIntervalFactor, HkRequest};
2024-01-30 01:18:48 +01:00
use satrs_core::pool::SharedPool;
use satrs_core::pus::verification::{FailParams, StdVerifReporterWithSender};
2023-07-06 00:49:18 +02:00
use satrs_core::pus::{
2024-01-30 01:18:48 +01:00
EcssTcReceiver, EcssTmSender, PusPacketHandlerResult, PusPacketHandlingError,
PusServiceBaseWithStore,
2023-07-06 00:49:18 +02:00
};
2023-07-11 00:44:48 +02:00
use satrs_core::spacepackets::ecss::tc::PusTcReader;
2023-07-06 00:49:18 +02:00
use satrs_core::spacepackets::ecss::{hk, PusPacket};
use satrs_core::tmtc::{AddressableId, TargetId};
use satrs_example::{hk_err, tmtc_err};
use std::collections::HashMap;
2023-07-10 00:29:31 +02:00
use std::sync::mpsc::Sender;
2023-07-05 21:10:45 +02:00
2023-07-06 00:49:18 +02:00
pub struct PusService3HkHandler {
2024-01-30 01:18:48 +01:00
psb: PusServiceBaseWithStore,
2023-07-06 00:49:18 +02:00
request_handlers: HashMap<TargetId, Sender<RequestWithToken>>,
}
impl PusService3HkHandler {
pub fn new(
2023-07-10 00:29:31 +02:00
tc_receiver: Box<dyn EcssTcReceiver>,
shared_tc_pool: SharedPool,
2023-07-09 17:04:18 +02:00
tm_sender: Box<dyn EcssTmSender>,
2023-07-06 00:49:18 +02:00
tm_apid: u16,
verification_handler: StdVerifReporterWithSender,
request_handlers: HashMap<TargetId, Sender<RequestWithToken>>,
) -> 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_pool,
tm_sender,
tm_apid,
verification_handler,
),
2023-07-06 00:49:18 +02:00
request_handlers,
}
}
2024-01-30 01:18:48 +01:00
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)?;
let (tc, _) = PusTcReader::new(&self.psb.pus_buf).unwrap();
2023-07-06 00:49:18 +02:00
let subservice = tc.subservice();
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-11 00:28:28 +02:00
let user_data = tc.user_data();
if user_data.is_empty() {
2023-07-06 00:49:18 +02:00
self.psb
.verification_handler
.borrow_mut()
.start_failure(
token,
FailParams::new(Some(&time_stamp), &tmtc_err::NOT_ENOUGH_APP_DATA, None),
)
.expect("Sending start failure TM failed");
return Err(PusPacketHandlingError::NotEnoughAppData(
"Expected at least 8 bytes of app data".into(),
));
}
if user_data.len() < 8 {
let err = if user_data.len() < 4 {
&hk_err::TARGET_ID_MISSING
} else {
&hk_err::UNIQUE_ID_MISSING
};
self.psb
.verification_handler
.borrow_mut()
.start_failure(token, FailParams::new(Some(&time_stamp), err, None))
.expect("Sending start failure TM failed");
return Err(PusPacketHandlingError::NotEnoughAppData(
"Expected at least 8 bytes of app data".into(),
));
}
let addressable_id = AddressableId::from_raw_be(user_data).unwrap();
if !self
.request_handlers
.contains_key(&addressable_id.target_id)
{
self.psb
.verification_handler
.borrow_mut()
.start_failure(
token,
FailParams::new(Some(&time_stamp), &hk_err::UNKNOWN_TARGET_ID, None),
)
.expect("Sending start failure TM failed");
let tgt_id = addressable_id.target_id;
return Err(PusPacketHandlingError::NotEnoughAppData(format!(
"Unknown target ID {tgt_id}"
)));
}
let send_request = |target: TargetId, request: HkRequest| {
let sender = self
.request_handlers
.get(&addressable_id.target_id)
.unwrap();
sender
.send(RequestWithToken::new(target, Request::Hk(request), token))
.unwrap_or_else(|_| panic!("Sending HK request {request:?} failed"));
};
if subservice == hk::Subservice::TcEnableHkGeneration as u8 {
send_request(
addressable_id.target_id,
HkRequest::Enable(addressable_id.unique_id),
);
} else if subservice == hk::Subservice::TcDisableHkGeneration as u8 {
send_request(
addressable_id.target_id,
HkRequest::Disable(addressable_id.unique_id),
);
} else if subservice == hk::Subservice::TcGenerateOneShotHk as u8 {
send_request(
addressable_id.target_id,
HkRequest::OneShot(addressable_id.unique_id),
);
} else if subservice == hk::Subservice::TcModifyHkCollectionInterval as u8 {
if user_data.len() < 12 {
self.psb
.verification_handler
.borrow_mut()
.start_failure(
token,
FailParams::new(
Some(&time_stamp),
&hk_err::COLLECTION_INTERVAL_MISSING,
None,
),
)
.expect("Sending start failure TM failed");
return Err(PusPacketHandlingError::NotEnoughAppData(
"Collection interval missing".into(),
));
}
send_request(
addressable_id.target_id,
HkRequest::ModifyCollectionInterval(
addressable_id.unique_id,
CollectionIntervalFactor::from_be_bytes(user_data[8..12].try_into().unwrap()),
),
);
}
Ok(PusPacketHandlerResult::RequestHandled)
}
}
pub struct Pus3Wrapper {
pub(crate) pus_3_handler: PusService3HkHandler,
}
impl Pus3Wrapper {
pub fn handle_next_packet(&mut self) -> bool {
2024-01-30 01:18:48 +01:00
match self.pus_3_handler.handle_one_tc() {
2023-07-06 00:49:18 +02:00
Ok(result) => match result {
PusPacketHandlerResult::RequestHandled => {}
PusPacketHandlerResult::RequestHandledPartialSuccess(e) => {
warn!("PUS 3 partial packet handling success: {e:?}")
}
PusPacketHandlerResult::CustomSubservice(invalid, _) => {
warn!("PUS 3 invalid subservice {invalid}");
}
PusPacketHandlerResult::SubserviceNotImplemented(subservice, _) => {
warn!("PUS 3 subservice {subservice} not implemented");
}
PusPacketHandlerResult::Empty => {
return true;
}
},
Err(error) => {
error!("PUS packet handling error: {error:?}")
}
}
false
}
}