Compare commits
1 Commits
bump-space
...
mode-tree-
Author | SHA1 | Date | |
---|---|---|---|
6a4417c954
|
@@ -4,7 +4,6 @@
|
||||
[](https://robamu.github.io/sat-rs/book/)
|
||||
[](https://crates.io/crates/satrs)
|
||||
[](https://docs.rs/satrs)
|
||||
[](https://matrix.to/#/#sat-rs:matrix.org)
|
||||
|
||||
sat-rs
|
||||
=========
|
||||
@@ -62,8 +61,6 @@ Each project has its own `CHANGELOG.md`.
|
||||
packet protocol implementations. This repository is re-exported in the
|
||||
[`satrs`](https://egit.irs.uni-stuttgart.de/rust/satrs/src/branch/main/satrs)
|
||||
crate.
|
||||
* [`cfdp`](https://egit.irs.uni-stuttgart.de/rust/cfdp): CCSDS File Delivery Protocol
|
||||
(CFDP) high-level library components.
|
||||
|
||||
# Flight Heritage
|
||||
|
||||
|
@@ -11,8 +11,6 @@ repository = "https://egit.irs.uni-stuttgart.de/rust/sat-rs"
|
||||
fern = "0.7"
|
||||
chrono = "0.4"
|
||||
log = "0.4"
|
||||
arbitrary-int = "2"
|
||||
bitbybit = "1.4"
|
||||
crossbeam-channel = "0.5"
|
||||
delegate = "0.13"
|
||||
zerocopy = "0.8"
|
||||
@@ -20,7 +18,7 @@ csv = "1"
|
||||
num_enum = "0.7"
|
||||
thiserror = "2"
|
||||
lazy_static = "1"
|
||||
strum = { version = "0.27", features = ["derive"] }
|
||||
strum = { version = "0.26", features = ["derive"] }
|
||||
derive-new = "0.7"
|
||||
cfg-if = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
@@ -1 +1,175 @@
|
||||
// TODO: Write the assembly
|
||||
//
|
||||
|
||||
use std::sync::mpsc;
|
||||
|
||||
use satrs::{
|
||||
dev_mgmt::{DevManagerCommandingHelper, DevManagerHelperResult, TransparentDevManagerHook},
|
||||
mode::{
|
||||
ModeAndSubmode, ModeError, ModeProvider, ModeReply, ModeReplyReceiver as _,
|
||||
ModeReplySender as _, ModeRequest, ModeRequestHandler, ModeRequestReceiver as _,
|
||||
ModeRequestorAndHandlerMpscBounded, UNKNOWN_MODE,
|
||||
},
|
||||
mode_tree::{ModeChild, ModeNode, ModeParent},
|
||||
queue::GenericTargetedMessagingError,
|
||||
request::{GenericMessage, MessageMetadata},
|
||||
ComponentId,
|
||||
};
|
||||
use satrs_example::{ids, DeviceMode};
|
||||
|
||||
pub type RequestSenderType = mpsc::SyncSender<GenericMessage<ModeRequest>>;
|
||||
pub type ReplySenderType = mpsc::SyncSender<GenericMessage<ModeReply>>;
|
||||
|
||||
// TODO: Needs to perform same functions as the integration test assembly, but also needs
|
||||
// to track mode changes and health changes of children.
|
||||
pub struct MgmAssembly {
|
||||
pub mode_node: ModeRequestorAndHandlerMpscBounded,
|
||||
pub mode_requestor_info: Option<MessageMetadata>,
|
||||
pub mode_and_submode: ModeAndSubmode,
|
||||
pub commanding_helper: DevManagerCommandingHelper<TransparentDevManagerHook>,
|
||||
}
|
||||
|
||||
impl MgmAssembly {
|
||||
pub fn new(mode_node: ModeRequestorAndHandlerMpscBounded) -> Self {
|
||||
Self {
|
||||
mode_node,
|
||||
mode_requestor_info: None,
|
||||
mode_and_submode: UNKNOWN_MODE,
|
||||
commanding_helper: DevManagerCommandingHelper::new(TransparentDevManagerHook::default()),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn id() -> ComponentId {
|
||||
ids::acs::MGM_ASSEMBLY.raw()
|
||||
}
|
||||
|
||||
pub fn periodic_operation(&mut self) {
|
||||
self.check_mode_requests().expect("mode messaging error");
|
||||
self.check_mode_replies().expect("mode messaging error");
|
||||
// TODO: perform target keeping, check whether children are in correct mode.
|
||||
}
|
||||
|
||||
pub fn check_mode_requests(&mut self) -> Result<(), GenericTargetedMessagingError> {
|
||||
while let Some(request) = self.mode_node.try_recv_mode_request()? {
|
||||
self.handle_mode_request(request).unwrap();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn check_mode_replies(&mut self) -> Result<(), ModeError> {
|
||||
while let Some(reply_and_id) = self.mode_node.try_recv_mode_reply()? {
|
||||
match self.commanding_helper.handle_mode_reply(&reply_and_id) {
|
||||
Ok(result) => {
|
||||
if let DevManagerHelperResult::ModeCommandingDone(context) = result {
|
||||
// Complete the mode command.
|
||||
self.mode_and_submode = context.target_mode;
|
||||
self.handle_mode_reached(self.mode_requestor_info)?;
|
||||
}
|
||||
}
|
||||
Err(err) => match err {
|
||||
satrs::dev_mgmt::DevManagerHelperError::ChildNotInStore => todo!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ModeNode for MgmAssembly {
|
||||
fn id(&self) -> ComponentId {
|
||||
Self::id()
|
||||
}
|
||||
}
|
||||
impl ModeParent for MgmAssembly {
|
||||
type Sender = RequestSenderType;
|
||||
|
||||
fn add_mode_child(&mut self, id: ComponentId, request_sender: RequestSenderType) {
|
||||
self.mode_node.add_request_target(id, request_sender);
|
||||
self.commanding_helper.add_mode_child(id, UNKNOWN_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
impl ModeChild for MgmAssembly {
|
||||
type Sender = ReplySenderType;
|
||||
|
||||
fn add_mode_parent(&mut self, id: ComponentId, reply_sender: ReplySenderType) {
|
||||
self.mode_node.add_reply_target(id, reply_sender);
|
||||
}
|
||||
}
|
||||
|
||||
impl ModeProvider for MgmAssembly {
|
||||
fn mode_and_submode(&self) -> ModeAndSubmode {
|
||||
self.mode_and_submode
|
||||
}
|
||||
}
|
||||
|
||||
impl ModeRequestHandler for MgmAssembly {
|
||||
type Error = ModeError;
|
||||
fn start_transition(
|
||||
&mut self,
|
||||
requestor: MessageMetadata,
|
||||
mode_and_submode: ModeAndSubmode,
|
||||
forced: bool,
|
||||
) -> Result<(), Self::Error> {
|
||||
// Always accept forced commands and commands to mode OFF.
|
||||
if self.commanding_helper.target_mode().is_some()
|
||||
&& !forced
|
||||
&& mode_and_submode.mode() != DeviceMode::Off as u32
|
||||
{
|
||||
return Err(ModeError::Busy);
|
||||
}
|
||||
self.mode_requestor_info = Some(requestor);
|
||||
self.commanding_helper.send_mode_cmd_to_all_children(
|
||||
requestor.request_id(),
|
||||
mode_and_submode,
|
||||
forced,
|
||||
&self.mode_node,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn announce_mode(&self, requestor_info: Option<MessageMetadata>, recursive: bool) {
|
||||
println!(
|
||||
"TestAssembly: Announcing mode (recursively: {}): {:?}",
|
||||
recursive, self.mode_and_submode
|
||||
);
|
||||
let request_id = requestor_info.map_or(0, |info| info.request_id());
|
||||
self.commanding_helper
|
||||
.send_announce_mode_cmd_to_children(request_id, &self.mode_node, recursive)
|
||||
.expect("sending mode request failed");
|
||||
// TODO: Send announce event.
|
||||
log::info!(
|
||||
"MGM assembly announcing mode: {:?}",
|
||||
self.mode_and_submode()
|
||||
);
|
||||
}
|
||||
|
||||
fn handle_mode_reached(
|
||||
&mut self,
|
||||
mode_requestor: Option<MessageMetadata>,
|
||||
) -> Result<(), Self::Error> {
|
||||
if let Some(requestor) = mode_requestor {
|
||||
self.send_mode_reply(requestor, ModeReply::ModeReply(self.mode_and_submode))?;
|
||||
}
|
||||
self.announce_mode(mode_requestor, false);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_mode_info(
|
||||
&mut self,
|
||||
requestor_info: MessageMetadata,
|
||||
info: ModeAndSubmode,
|
||||
) -> Result<(), Self::Error> {
|
||||
// TODO: Perform mode keeping.
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_mode_reply(
|
||||
&self,
|
||||
requestor: MessageMetadata,
|
||||
reply: ModeReply,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.mode_node.send_mode_reply(requestor, reply)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@@ -83,7 +83,7 @@ impl SpiInterface for SpiSimInterface {
|
||||
.sim_request_tx
|
||||
.send(SimRequest::new_with_epoch_time(mgm_sensor_request))
|
||||
{
|
||||
log::error!("failed to send MGM LIS3 request: {e}");
|
||||
log::error!("failed to send MGM LIS3 request: {}", e);
|
||||
}
|
||||
match self.sim_reply_rx.recv_timeout(Duration::from_millis(50)) {
|
||||
Ok(sim_reply) => {
|
||||
@@ -97,7 +97,7 @@ impl SpiInterface for SpiSimInterface {
|
||||
.copy_from_slice(&sim_reply_lis3.raw.z.to_le_bytes());
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("MGM LIS3 SIM reply timeout: {e}");
|
||||
log::warn!("MGM LIS3 SIM reply timeout: {}", e);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -400,6 +400,7 @@ impl<
|
||||
}
|
||||
|
||||
fn announce_mode(&self, _requestor_info: Option<MessageMetadata>, _recursive: bool) {
|
||||
// TODO: Event
|
||||
log::info!(
|
||||
"{} announcing mode: {:?}",
|
||||
self.dev_str,
|
||||
@@ -492,7 +493,7 @@ mod tests {
|
||||
tmtc::PacketAsVec,
|
||||
ComponentId,
|
||||
};
|
||||
use satrs_example::ids::{acs::ASSEMBLY, Apid};
|
||||
use satrs_example::ids::{acs::MGM_ASSEMBLY, Apid};
|
||||
use satrs_minisim::acs::lis3mdl::MgmLis3RawValues;
|
||||
|
||||
use crate::{eps::TestSwitchHelper, pus::hk::HkReply, requests::CompositeRequest};
|
||||
@@ -574,7 +575,7 @@ mod tests {
|
||||
let (request_tx, request_rx) = mpsc::sync_channel(5);
|
||||
let (reply_tx_to_pus, reply_rx_to_pus) = mpsc::sync_channel(5);
|
||||
let (reply_tx_to_parent, reply_rx_to_parent) = mpsc::sync_channel(5);
|
||||
let id = UniqueApidTargetId::new(Apid::Acs.raw_value(), 1);
|
||||
let id = UniqueApidTargetId::new(Apid::Acs as u16, 1);
|
||||
let mode_node = ModeRequestHandlerMpscBounded::new(id.into(), request_rx);
|
||||
let (composite_request_tx, composite_request_rx) = mpsc::channel();
|
||||
let (hk_reply_tx, hk_reply_rx) = mpsc::sync_channel(10);
|
||||
@@ -593,7 +594,7 @@ mod tests {
|
||||
shared_mgm_set,
|
||||
);
|
||||
handler.add_mode_parent(PUS_MODE.into(), reply_tx_to_pus);
|
||||
handler.add_mode_parent(ASSEMBLY.into(), reply_tx_to_parent);
|
||||
handler.add_mode_parent(MGM_ASSEMBLY.into(), reply_tx_to_parent);
|
||||
Self {
|
||||
mode_request_tx: request_tx,
|
||||
mode_reply_rx_to_pus: reply_rx_to_pus,
|
||||
|
@@ -1,9 +1,7 @@
|
||||
use arbitrary_int::u11;
|
||||
use satrs::pus::verification::RequestId;
|
||||
use satrs::spacepackets::ecss::tc::PusTcCreator;
|
||||
use satrs::spacepackets::ecss::tm::PusTmReader;
|
||||
use satrs::spacepackets::ecss::CreatorConfig;
|
||||
use satrs::spacepackets::SpHeader;
|
||||
use satrs::{spacepackets::ecss::PusPacket, spacepackets::SpHeader};
|
||||
use satrs_example::config::{OBSW_SERVER_ADDR, SERVER_PORT};
|
||||
use std::net::{IpAddr, SocketAddr, UdpSocket};
|
||||
use std::time::Duration;
|
||||
@@ -11,13 +9,7 @@ use std::time::Duration;
|
||||
fn main() {
|
||||
let mut buf = [0; 32];
|
||||
let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT);
|
||||
let pus_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(u11::new(0x02)),
|
||||
17,
|
||||
1,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let pus_tc = PusTcCreator::new_simple(SpHeader::new_from_apid(0x02), 17, 1, &[], true);
|
||||
let client = UdpSocket::bind("127.0.0.1:7302").expect("Connecting to UDP server failed");
|
||||
let tc_req_id = RequestId::new(&pus_tc);
|
||||
println!("Packing and sending PUS ping command TC[17,1] with request ID {tc_req_id}");
|
||||
|
@@ -44,7 +44,7 @@ lazy_static! {
|
||||
pub static ref PACKET_ID_VALIDATOR: HashSet<PacketId> = {
|
||||
let mut set = HashSet::new();
|
||||
for id in crate::ids::Apid::iter() {
|
||||
set.insert(PacketId::new(PacketType::Tc, true, id.raw_value()));
|
||||
set.insert(PacketId::new(PacketType::Tc, true, id as u16));
|
||||
}
|
||||
set
|
||||
};
|
||||
|
@@ -401,7 +401,7 @@ impl<ComInterface: SerialInterface> PcduHandler<ComInterface> {
|
||||
}
|
||||
}
|
||||
}) {
|
||||
log::warn!("receiving PCDU replies failed: {e:?}");
|
||||
log::warn!("receiving PCDU replies failed: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -572,7 +572,7 @@ mod tests {
|
||||
let (switch_request_tx, switch_reqest_rx) = mpsc::channel();
|
||||
let shared_switch_map = Arc::new(Mutex::new(SwitchSet::default()));
|
||||
let mut handler = PcduHandler::new(
|
||||
UniqueApidTargetId::new(Apid::Eps.raw_value(), 0),
|
||||
UniqueApidTargetId::new(Apid::Eps as u16, 0),
|
||||
"TEST_PCDU",
|
||||
mode_node,
|
||||
composite_request_rx,
|
||||
|
@@ -1,9 +1,8 @@
|
||||
use std::sync::mpsc::{self};
|
||||
|
||||
use crate::pus::create_verification_reporter;
|
||||
use arbitrary_int::u11;
|
||||
use satrs::event_man::{EventMessageU32, EventRoutingError};
|
||||
use satrs::pus::event::EventTmHook;
|
||||
use satrs::pus::event::EventTmHookProvider;
|
||||
use satrs::pus::verification::VerificationReporter;
|
||||
use satrs::pus::EcssTmSender;
|
||||
use satrs::request::UniqueApidTargetId;
|
||||
@@ -24,10 +23,10 @@ use crate::update_time;
|
||||
// This helper sets the APID of the event sender for the PUS telemetry.
|
||||
#[derive(Default)]
|
||||
pub struct EventApidSetter {
|
||||
pub next_apid: u11,
|
||||
pub next_apid: u16,
|
||||
}
|
||||
|
||||
impl EventTmHook for EventApidSetter {
|
||||
impl EventTmHookProvider for EventApidSetter {
|
||||
fn modify_tm(&self, tm: &mut satrs::spacepackets::ecss::tm::PusTmCreator) {
|
||||
tm.set_apid(self.next_apid);
|
||||
}
|
||||
@@ -60,7 +59,7 @@ impl<TmSender: EcssTmSender> PusEventHandler<TmSender> {
|
||||
// telemetry for each event.
|
||||
let event_reporter = EventReporter::new_with_hook(
|
||||
PUS_EVENT_MANAGEMENT.raw(),
|
||||
u11::new(0),
|
||||
0,
|
||||
0,
|
||||
128,
|
||||
EventApidSetter::default(),
|
||||
@@ -220,14 +219,17 @@ impl<TmSender: EcssTmSender> EventHandler<TmSender> {
|
||||
mod tests {
|
||||
use satrs::{
|
||||
events::EventU32,
|
||||
pus::verification::VerificationReporterConfig,
|
||||
spacepackets::ecss::{tm::PusTmReader, PusPacket},
|
||||
pus::verification::VerificationReporterCfg,
|
||||
spacepackets::{
|
||||
ecss::{tm::PusTmReader, PusPacket},
|
||||
CcsdsPacket,
|
||||
},
|
||||
tmtc::PacketAsVec,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
const TEST_CREATOR_ID: UniqueApidTargetId = UniqueApidTargetId::new(u11::new(1), 2);
|
||||
const TEST_CREATOR_ID: UniqueApidTargetId = UniqueApidTargetId::new(1, 2);
|
||||
const TEST_EVENT: EventU32 = EventU32::new(satrs::events::Severity::Info, 1, 1);
|
||||
|
||||
pub struct EventManagementTestbench {
|
||||
@@ -242,8 +244,7 @@ mod tests {
|
||||
let (event_tx, event_rx) = mpsc::sync_channel(10);
|
||||
let (_event_req_tx, event_req_rx) = mpsc::sync_channel(10);
|
||||
let (tm_sender, tm_receiver) = mpsc::channel();
|
||||
let verif_reporter_cfg =
|
||||
VerificationReporterConfig::new(u11::new(0x05), 2, 2, 128).unwrap();
|
||||
let verif_reporter_cfg = VerificationReporterCfg::new(0x05, 2, 2, 128).unwrap();
|
||||
let verif_reporter =
|
||||
VerificationReporter::new(PUS_EVENT_MANAGEMENT.id(), &verif_reporter_cfg);
|
||||
let mut event_manager = EventManagerWithBoundedMpsc::new(event_rx);
|
||||
|
@@ -1,8 +1,8 @@
|
||||
use derive_new::new;
|
||||
use satrs::hk::UniqueId;
|
||||
use satrs::request::UniqueApidTargetId;
|
||||
use satrs::spacepackets::ecss::hk;
|
||||
use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use satrs::spacepackets::ecss::{hk, CreatorConfig};
|
||||
use satrs::spacepackets::{ByteConversionError, SpHeader};
|
||||
|
||||
#[derive(Debug, new, Copy, Clone)]
|
||||
@@ -63,7 +63,7 @@ impl PusHkHelper {
|
||||
SpHeader::new_from_apid(self.component_id.apid),
|
||||
sec_header,
|
||||
&buf[0..8 + hk_data_len],
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@@ -1,8 +1,7 @@
|
||||
//! This is an auto-generated configuration module.
|
||||
use satrs::request::UniqueApidTargetId;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, strum::EnumIter)]
|
||||
#[bitbybit::bitenum(u11, exhaustive = false)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, strum::EnumIter)]
|
||||
pub enum Apid {
|
||||
Sched = 1,
|
||||
GenericPus = 2,
|
||||
@@ -16,19 +15,19 @@ pub mod acs {
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum Id {
|
||||
Subsystem = 1,
|
||||
Assembly = 2,
|
||||
MgmAssembly = 2,
|
||||
Mgm0 = 3,
|
||||
Mgm1 = 4,
|
||||
}
|
||||
|
||||
pub const SUBSYSTEM: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Subsystem as u32);
|
||||
pub const ASSEMBLY: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Assembly as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::Acs as u16, Id::Subsystem as u32);
|
||||
pub const MGM_ASSEMBLY: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Acs as u16, Id::MgmAssembly as u32);
|
||||
pub const MGM0: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Mgm0 as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::Acs as u16, Id::Mgm0 as u32);
|
||||
pub const MGM1: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Mgm1 as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::Acs as u16, Id::Mgm1 as u32);
|
||||
}
|
||||
|
||||
pub mod eps {
|
||||
@@ -39,9 +38,9 @@ pub mod eps {
|
||||
}
|
||||
|
||||
pub const PCDU: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Eps.raw_value(), Id::Pcdu as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::Eps as u16, Id::Pcdu as u32);
|
||||
pub const SUBSYSTEM: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Eps.raw_value(), Id::Subsystem as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::Eps as u16, Id::Subsystem as u32);
|
||||
}
|
||||
|
||||
pub mod generic_pus {
|
||||
@@ -56,19 +55,19 @@ pub mod generic_pus {
|
||||
}
|
||||
|
||||
pub const PUS_EVENT_MANAGEMENT: super::UniqueApidTargetId = super::UniqueApidTargetId::new(
|
||||
super::Apid::GenericPus.raw_value(),
|
||||
super::Apid::GenericPus as u16,
|
||||
Id::PusEventManagement as u32,
|
||||
);
|
||||
pub const PUS_ROUTING: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusRouting as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus as u16, Id::PusRouting as u32);
|
||||
pub const PUS_TEST: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusTest as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus as u16, Id::PusTest as u32);
|
||||
pub const PUS_ACTION: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusAction as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus as u16, Id::PusAction as u32);
|
||||
pub const PUS_MODE: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusMode as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus as u16, Id::PusMode as u32);
|
||||
pub const PUS_HK: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusHk as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::GenericPus as u16, Id::PusHk as u32);
|
||||
}
|
||||
|
||||
pub mod sched {
|
||||
@@ -78,7 +77,7 @@ pub mod sched {
|
||||
}
|
||||
|
||||
pub const PUS_SCHED: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Sched.raw_value(), Id::PusSched as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::Sched as u16, Id::PusSched as u32);
|
||||
}
|
||||
|
||||
pub mod tmtc {
|
||||
@@ -89,7 +88,7 @@ pub mod tmtc {
|
||||
}
|
||||
|
||||
pub const UDP_SERVER: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Tmtc.raw_value(), Id::UdpServer as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::Tmtc as u16, Id::UdpServer as u32);
|
||||
pub const TCP_SERVER: super::UniqueApidTargetId =
|
||||
super::UniqueApidTargetId::new(super::Apid::Tmtc.raw_value(), Id::TcpServer as u32);
|
||||
super::UniqueApidTargetId::new(super::Apid::Tmtc as u16, Id::TcpServer as u32);
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ pub fn create_sim_client(sim_request_rx: mpsc::Receiver<SimRequest>) -> Option<S
|
||||
return Some(sim_client);
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("sim client creation error: {e}");
|
||||
log::warn!("sim client creation error: {}", e);
|
||||
}
|
||||
}
|
||||
None
|
||||
@@ -116,7 +116,7 @@ impl SimClientUdp {
|
||||
.udp_client
|
||||
.send_to(request_json.as_bytes(), self.simulator_addr)
|
||||
{
|
||||
log::error!("error sending data to UDP SIM server: {e}");
|
||||
log::error!("error sending data to UDP SIM server: {}", e);
|
||||
break;
|
||||
} else {
|
||||
no_sim_requests_handled = false;
|
||||
@@ -151,7 +151,7 @@ impl SimClientUdp {
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("failed to deserialize SIM reply: {e}");
|
||||
log::warn!("failed to deserialize SIM reply: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ impl SimClientUdp {
|
||||
{
|
||||
break;
|
||||
}
|
||||
log::error!("error receiving data from UDP SIM server: {e}");
|
||||
log::error!("error receiving data from UDP SIM server: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ impl SpacePacketValidator for SimplePacketValidator {
|
||||
if self.valid_ids.contains(&sp_header.packet_id()) {
|
||||
return SpValidity::Valid;
|
||||
}
|
||||
log::warn!("ignoring space packet with header {sp_header:?}");
|
||||
log::warn!("ignoring space packet with header {:?}", sp_header);
|
||||
// We could perform a CRC check.. but lets keep this simple and assume that TCP ensures
|
||||
// data integrity.
|
||||
SpValidity::Skip
|
||||
|
@@ -15,7 +15,6 @@ pub trait UdpTmHandler {
|
||||
fn send_tm_to_udp_client(&mut self, socket: &UdpSocket, recv_addr: &SocketAddr);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct StaticUdpTmHandler {
|
||||
pub tm_rx: mpsc::Receiver<PacketInPool>,
|
||||
pub tm_store: SharedStaticMemoryPool,
|
||||
@@ -113,9 +112,6 @@ mod tests {
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use arbitrary_int::traits::Integer as _;
|
||||
use arbitrary_int::u14;
|
||||
use satrs::spacepackets::ecss::CreatorConfig;
|
||||
use satrs::{
|
||||
spacepackets::{
|
||||
ecss::{tc::PusTcCreator, WritablePusPacket},
|
||||
@@ -180,8 +176,8 @@ mod tests {
|
||||
udp_tc_server,
|
||||
tm_handler,
|
||||
};
|
||||
let sph = SpHeader::new_for_unseg_tc(ids::Apid::GenericPus.raw_value(), u14::ZERO, 0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default())
|
||||
let sph = SpHeader::new_for_unseg_tc(ids::Apid::GenericPus as u16, 0, 0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true)
|
||||
.to_vec()
|
||||
.unwrap();
|
||||
let client = UdpSocket::bind("127.0.0.1:0").expect("Connecting to UDP server failed");
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use satrs::spacepackets::time::cds::CdsTime;
|
||||
use satrs::spacepackets::time::{cds::CdsTime, TimeWriter};
|
||||
|
||||
pub mod config;
|
||||
pub mod ids;
|
||||
|
@@ -5,7 +5,10 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use acs::mgm::{MgmHandlerLis3Mdl, SpiDummyInterface, SpiSimInterface, SpiSimInterfaceWrapper};
|
||||
use acs::{
|
||||
assembly::MgmAssembly,
|
||||
mgm::{MgmHandlerLis3Mdl, SpiDummyInterface, SpiSimInterface, SpiSimInterfaceWrapper},
|
||||
};
|
||||
use eps::{
|
||||
pcdu::{PcduHandler, SerialInterfaceDummy, SerialInterfaceToSim, SerialSimInterfaceWrapper},
|
||||
PowerSwitchHelper,
|
||||
@@ -31,11 +34,14 @@ use pus::{
|
||||
use requests::GenericRequestRouter;
|
||||
use satrs::{
|
||||
hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer},
|
||||
mode::{Mode, ModeAndSubmode, ModeRequest, ModeRequestHandlerMpscBounded},
|
||||
mode::{
|
||||
Mode, ModeAndSubmode, ModeRequest, ModeRequestHandlerMpscBounded,
|
||||
ModeRequestorAndHandlerMpscBounded,
|
||||
},
|
||||
mode_tree::connect_mode_nodes,
|
||||
pus::{event_man::EventRequestWithToken, EcssTcCacher, HandlingStatus},
|
||||
pus::{event_man::EventRequestWithToken, EcssTcInMemConverter, HandlingStatus},
|
||||
request::{GenericMessage, MessageMetadata},
|
||||
spacepackets::time::cds::CdsTime,
|
||||
spacepackets::time::{cds::CdsTime, TimeWriter},
|
||||
};
|
||||
use satrs_example::{
|
||||
config::{
|
||||
@@ -57,12 +63,12 @@ use tmtc::{tc_source::TcSourceTask, tm_sink::TmSink};
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "heap_tmtc")] {
|
||||
use interface::udp::DynamicUdpTmHandler;
|
||||
use satrs::pus::EcssTcVecCacher;
|
||||
use satrs::pus::EcssTcInVecConverter;
|
||||
use tmtc::{tc_source::TcSourceTaskDynamic, tm_sink::TmSinkDynamic};
|
||||
} else {
|
||||
use std::sync::RwLock;
|
||||
use interface::udp::StaticUdpTmHandler;
|
||||
use satrs::pus::EcssTcInSharedPoolCacher;
|
||||
use satrs::pus::EcssTcInSharedPoolConverter;
|
||||
use satrs::tmtc::{PacketSenderWithSharedPool, SharedPacketPool};
|
||||
use satrs_example::config::pool::create_static_pools;
|
||||
use tmtc::{
|
||||
@@ -143,9 +149,9 @@ fn main() {
|
||||
let tc_sender_with_shared_pool =
|
||||
PacketSenderWithSharedPool::new(tc_source_tx, shared_tc_pool_wrapper.clone());
|
||||
let tc_in_mem_converter =
|
||||
EcssTcCacher::Static(EcssTcInSharedPoolCacher::new(shared_tc_pool, 4096));
|
||||
EcssTcInMemConverter::Static(EcssTcInSharedPoolConverter::new(shared_tc_pool, 4096));
|
||||
} else if #[cfg(feature = "heap_tmtc")] {
|
||||
let tc_in_mem_converter = EcssTcCacher::Heap(EcssTcVecCacher::default());
|
||||
let tc_in_mem_converter = EcssTcInMemConverter::Heap(EcssTcInVecConverter::default());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,6 +309,15 @@ fn main() {
|
||||
let (switch_request_tx, switch_request_rx) = mpsc::sync_channel(20);
|
||||
let switch_helper = PowerSwitchHelper::new(switch_request_tx, shared_switch_set.clone());
|
||||
|
||||
let (mgm_assy_mode_req_tx, mgm_assy_mode_req_rx) = mpsc::sync_channel(20);
|
||||
let (mgm_assy_mode_reply_tx, mgm_assy_mode_reply_rx) = mpsc::sync_channel(20);
|
||||
let mgm_assembly_mode_node = ModeRequestorAndHandlerMpscBounded::new(
|
||||
MgmAssembly::id(),
|
||||
mgm_assy_mode_req_rx,
|
||||
mgm_assy_mode_reply_rx,
|
||||
);
|
||||
let mut mgm_assembly = MgmAssembly::new(mgm_assembly_mode_node);
|
||||
|
||||
let shared_mgm_0_set = Arc::default();
|
||||
let shared_mgm_1_set = Arc::default();
|
||||
let mgm_0_mode_node = ModeRequestHandlerMpscBounded::new(MGM0.into(), mgm_0_handler_mode_rx);
|
||||
@@ -364,6 +379,19 @@ fn main() {
|
||||
&mut mgm_1_handler,
|
||||
pus_mode_reply_tx.clone(),
|
||||
);
|
||||
// Connect assembly to device handlers.
|
||||
connect_mode_nodes(
|
||||
&mut mgm_assembly,
|
||||
mgm_assy_mode_req_tx.clone(),
|
||||
&mut mgm_1_handler,
|
||||
mgm_assy_mode_reply_tx.clone(),
|
||||
);
|
||||
connect_mode_nodes(
|
||||
&mut mgm_assembly,
|
||||
mgm_assy_mode_req_tx,
|
||||
&mut mgm_1_handler,
|
||||
mgm_assy_mode_reply_tx,
|
||||
);
|
||||
|
||||
let pcdu_serial_interface = if let Some(sim_client) = opt_sim_client.as_mut() {
|
||||
sim_client.add_reply_recipient(satrs_minisim::SimComponent::Pcdu, pcdu_sim_reply_tx);
|
||||
@@ -455,6 +483,7 @@ fn main() {
|
||||
let jh_aocs = thread::Builder::new()
|
||||
.name("sat-rs aocs".to_string())
|
||||
.spawn(move || loop {
|
||||
mgm_assembly.periodic_operation();
|
||||
mgm_0_handler.periodic_operation();
|
||||
mgm_1_handler.periodic_operation();
|
||||
thread::sleep(Duration::from_millis(FREQ_MS_AOCS));
|
||||
|
@@ -9,7 +9,7 @@ use satrs::pus::verification::{
|
||||
VerificationReportingProvider, VerificationToken,
|
||||
};
|
||||
use satrs::pus::{
|
||||
ActiveRequest, EcssTcAndToken, EcssTcCacher, EcssTmSender, EcssTmtcError,
|
||||
ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConverter, EcssTmSender, EcssTmtcError,
|
||||
GenericConversionError, MpscTcReceiver, PusPacketHandlingError, PusReplyHandler,
|
||||
PusServiceHelper, PusTcToRequestConverter,
|
||||
};
|
||||
@@ -208,7 +208,7 @@ impl PusTcToRequestConverter<ActivePusActionRequestStd, ActionRequest> for Actio
|
||||
|
||||
pub fn create_action_service(
|
||||
tm_sender: TmTcSender,
|
||||
tc_in_mem_converter: EcssTcCacher,
|
||||
tc_in_mem_converter: EcssTcInMemConverter,
|
||||
pus_action_rx: mpsc::Receiver<EcssTcAndToken>,
|
||||
action_router: GenericRequestRouter,
|
||||
reply_receiver: mpsc::Receiver<GenericMessage<ActionReplyPus>>,
|
||||
@@ -274,9 +274,8 @@ mod tests {
|
||||
TEST_APID, TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1, TEST_UNIQUE_ID_0, TEST_UNIQUE_ID_1,
|
||||
};
|
||||
use satrs::pus::verification::test_util::TestVerificationReporter;
|
||||
use satrs::pus::{verification, EcssTcVecCacher};
|
||||
use satrs::pus::{verification, EcssTcInVecConverter};
|
||||
use satrs::request::MessageMetadata;
|
||||
use satrs::spacepackets::ecss::CreatorConfig;
|
||||
use satrs::tmtc::PacketAsVec;
|
||||
use satrs::ComponentId;
|
||||
use satrs::{
|
||||
@@ -326,7 +325,7 @@ mod tests {
|
||||
pus_action_rx,
|
||||
TmTcSender::Heap(tm_funnel_tx.clone()),
|
||||
verif_reporter,
|
||||
EcssTcCacher::Heap(EcssTcVecCacher::default()),
|
||||
EcssTcInMemConverter::Heap(EcssTcInVecConverter::default()),
|
||||
),
|
||||
ActionRequestConverter::default(),
|
||||
DefaultActiveActionRequestMap::default(),
|
||||
@@ -454,9 +453,7 @@ mod tests {
|
||||
let mut app_data: [u8; 8] = [0; 8];
|
||||
app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_1.to_be_bytes());
|
||||
app_data[4..8].copy_from_slice(&action_id.to_be_bytes());
|
||||
let pus8_packet =
|
||||
PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default());
|
||||
|
||||
let pus8_packet = PusTcCreator::new(sp_header, sec_header, &app_data, true);
|
||||
testbench.add_tc(&pus8_packet);
|
||||
let time_stamp: [u8; 7] = [0; 7];
|
||||
testbench.verify_next_tc_is_handled_properly(&time_stamp);
|
||||
@@ -502,7 +499,7 @@ mod tests {
|
||||
SpHeader::new_from_apid(TEST_APID),
|
||||
sec_header,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
testbench.add_tc(&pus8_packet);
|
||||
let time_stamp: [u8; 7] = [0; 7];
|
||||
@@ -528,7 +525,7 @@ mod tests {
|
||||
SpHeader::new_from_apid(TEST_APID),
|
||||
sec_header,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
let token = testbench.add_tc(&pus8_packet);
|
||||
let result = testbench.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0);
|
||||
@@ -567,7 +564,7 @@ mod tests {
|
||||
SpHeader::new_from_apid(TEST_APID),
|
||||
sec_header,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
let token = testbench.add_tc(&pus8_packet);
|
||||
let result = testbench.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0);
|
||||
|
@@ -6,7 +6,7 @@ use satrs::pus::event_man::EventRequestWithToken;
|
||||
use satrs::pus::event_srv::PusEventServiceHandler;
|
||||
use satrs::pus::verification::VerificationReporter;
|
||||
use satrs::pus::{
|
||||
DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcCacher, MpscTcReceiver,
|
||||
DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConverter, MpscTcReceiver,
|
||||
PartialPusHandlingError, PusServiceHelper,
|
||||
};
|
||||
use satrs::spacepackets::ecss::PusServiceId;
|
||||
@@ -16,7 +16,7 @@ use super::{DirectPusService, HandlingStatus};
|
||||
|
||||
pub fn create_event_service(
|
||||
tm_sender: TmTcSender,
|
||||
tm_in_pool_converter: EcssTcCacher,
|
||||
tm_in_pool_converter: EcssTcInMemConverter,
|
||||
pus_event_rx: mpsc::Receiver<EcssTcAndToken>,
|
||||
event_request_tx: mpsc::Sender<EventRequestWithToken>,
|
||||
) -> EventServiceWrapper {
|
||||
@@ -36,8 +36,12 @@ pub fn create_event_service(
|
||||
}
|
||||
|
||||
pub struct EventServiceWrapper {
|
||||
pub handler:
|
||||
PusEventServiceHandler<MpscTcReceiver, TmTcSender, EcssTcCacher, VerificationReporter>,
|
||||
pub handler: PusEventServiceHandler<
|
||||
MpscTcReceiver,
|
||||
TmTcSender,
|
||||
EcssTcInMemConverter,
|
||||
VerificationReporter,
|
||||
>,
|
||||
}
|
||||
|
||||
impl DirectPusService for EventServiceWrapper {
|
||||
|
@@ -5,9 +5,9 @@ use satrs::pus::verification::{
|
||||
VerificationReportingProvider, VerificationToken,
|
||||
};
|
||||
use satrs::pus::{
|
||||
ActivePusRequestStd, ActiveRequest, DefaultActiveRequestMap, EcssTcAndToken, EcssTcCacher,
|
||||
EcssTmSender, EcssTmtcError, GenericConversionError, MpscTcReceiver, PusPacketHandlingError,
|
||||
PusReplyHandler, PusServiceHelper, PusTcToRequestConverter,
|
||||
ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap, EcssTcAndToken,
|
||||
EcssTcInMemConverter, EcssTmSender, EcssTmtcError, GenericConversionError, MpscTcReceiver,
|
||||
PusPacketHandlingError, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter,
|
||||
};
|
||||
use satrs::request::{GenericMessage, UniqueApidTargetId};
|
||||
use satrs::res_code::ResultU16;
|
||||
@@ -242,7 +242,7 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for HkRequestConver
|
||||
|
||||
pub fn create_hk_service(
|
||||
tm_sender: TmTcSender,
|
||||
tc_in_mem_converter: EcssTcCacher,
|
||||
tc_in_mem_converter: EcssTcInMemConverter,
|
||||
pus_hk_rx: mpsc::Receiver<EcssTcAndToken>,
|
||||
request_router: GenericRequestRouter,
|
||||
reply_receiver: mpsc::Receiver<GenericMessage<HkReply>>,
|
||||
@@ -302,13 +302,10 @@ impl TargetedPusService for HkServiceWrapper {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use arbitrary_int::traits::Integer;
|
||||
use arbitrary_int::u14;
|
||||
use satrs::pus::test_util::{
|
||||
TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1, TEST_UNIQUE_ID_0, TEST_UNIQUE_ID_1,
|
||||
};
|
||||
use satrs::request::MessageMetadata;
|
||||
use satrs::spacepackets::ecss::CreatorConfig;
|
||||
use satrs::{
|
||||
hk::HkRequestVariant,
|
||||
pus::test_util::TEST_APID,
|
||||
@@ -327,12 +324,11 @@ mod tests {
|
||||
|
||||
use super::{HkReply, HkReplyHandler, HkRequestConverter};
|
||||
|
||||
pub const ZERO_SEQ: u14 = u14::ZERO;
|
||||
#[test]
|
||||
fn hk_converter_one_shot_req() {
|
||||
let mut hk_bench =
|
||||
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default());
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, ZERO_SEQ, 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let target_id = TEST_UNIQUE_ID_0;
|
||||
let unique_id = 5_u32;
|
||||
let mut app_data: [u8; 8] = [0; 8];
|
||||
@@ -344,7 +340,7 @@ mod tests {
|
||||
3,
|
||||
Subservice::TcGenerateOneShotHk as u8,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
let accepted_token = hk_bench.add_tc(&hk_req);
|
||||
let (_active_req, req) = hk_bench
|
||||
@@ -362,7 +358,7 @@ mod tests {
|
||||
fn hk_converter_enable_periodic_generation() {
|
||||
let mut hk_bench =
|
||||
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default());
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, ZERO_SEQ, 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let target_id = TEST_UNIQUE_ID_0;
|
||||
let unique_id = 5_u32;
|
||||
let mut app_data: [u8; 8] = [0; 8];
|
||||
@@ -384,7 +380,7 @@ mod tests {
|
||||
3,
|
||||
Subservice::TcEnableHkGeneration as u8,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
generic_check(&tc0);
|
||||
let tc1 = PusTcCreator::new_simple(
|
||||
@@ -392,7 +388,7 @@ mod tests {
|
||||
3,
|
||||
Subservice::TcEnableDiagGeneration as u8,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
generic_check(&tc1);
|
||||
}
|
||||
@@ -401,7 +397,7 @@ mod tests {
|
||||
fn hk_conversion_disable_periodic_generation() {
|
||||
let mut hk_bench =
|
||||
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default());
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, ZERO_SEQ, 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let target_id = TEST_UNIQUE_ID_0;
|
||||
let unique_id = 5_u32;
|
||||
let mut app_data: [u8; 8] = [0; 8];
|
||||
@@ -423,7 +419,7 @@ mod tests {
|
||||
3,
|
||||
Subservice::TcDisableHkGeneration as u8,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
generic_check(&tc0);
|
||||
let tc1 = PusTcCreator::new_simple(
|
||||
@@ -431,7 +427,7 @@ mod tests {
|
||||
3,
|
||||
Subservice::TcDisableDiagGeneration as u8,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
generic_check(&tc1);
|
||||
}
|
||||
@@ -440,7 +436,7 @@ mod tests {
|
||||
fn hk_conversion_modify_interval() {
|
||||
let mut hk_bench =
|
||||
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default());
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, ZERO_SEQ, 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let target_id = TEST_UNIQUE_ID_0;
|
||||
let unique_id = 5_u32;
|
||||
let mut app_data: [u8; 12] = [0; 12];
|
||||
@@ -466,7 +462,7 @@ mod tests {
|
||||
3,
|
||||
Subservice::TcModifyHkCollectionInterval as u8,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
generic_check(&tc0);
|
||||
let tc1 = PusTcCreator::new_simple(
|
||||
@@ -474,7 +470,7 @@ mod tests {
|
||||
3,
|
||||
Subservice::TcModifyDiagCollectionInterval as u8,
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
generic_check(&tc1);
|
||||
}
|
||||
|
@@ -4,13 +4,13 @@ use log::warn;
|
||||
use satrs::pool::PoolAddr;
|
||||
use satrs::pus::verification::{
|
||||
self, FailParams, TcStateAccepted, TcStateStarted, VerificationReporter,
|
||||
VerificationReporterConfig, VerificationReportingProvider, VerificationToken,
|
||||
VerificationReporterCfg, VerificationReportingProvider, VerificationToken,
|
||||
};
|
||||
use satrs::pus::{
|
||||
ActiveRequest, ActiveRequestStore, CacheAndReadRawEcssTc, EcssTcAndToken, EcssTcCacher,
|
||||
EcssTcReceiver, EcssTmSender, EcssTmtcError, GenericConversionError, GenericRoutingError,
|
||||
HandlingStatus, PusPacketHandlingError, PusReplyHandler, PusRequestRouter, PusServiceHelper,
|
||||
PusTcToRequestConverter, TcInMemory,
|
||||
ActiveRequestMapProvider, ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConversionProvider,
|
||||
EcssTcInMemConverter, EcssTcReceiver, EcssTmSender, EcssTmtcError, GenericConversionError,
|
||||
GenericRoutingError, HandlingStatus, PusPacketHandlingError, PusReplyHandler, PusRequestRouter,
|
||||
PusServiceHelper, PusTcToRequestConverter, TcInMemory,
|
||||
};
|
||||
use satrs::queue::{GenericReceiveError, GenericSendError};
|
||||
use satrs::request::{Apid, GenericMessage, MessageMetadata};
|
||||
@@ -33,7 +33,7 @@ pub mod stack;
|
||||
pub mod test;
|
||||
|
||||
pub fn create_verification_reporter(owner_id: ComponentId, apid: Apid) -> VerificationReporter {
|
||||
let verif_cfg = VerificationReporterConfig::new(apid, 1, 2, 8).unwrap();
|
||||
let verif_cfg = VerificationReporterCfg::new(apid, 1, 2, 8).unwrap();
|
||||
// Every software component which needs to generate verification telemetry, gets a cloned
|
||||
// verification reporter.
|
||||
VerificationReporter::new(owner_id, &verif_cfg)
|
||||
@@ -102,7 +102,7 @@ impl PusTcDistributor {
|
||||
sender_id,
|
||||
pus_tc_result.unwrap_err()
|
||||
);
|
||||
log::warn!("raw data: {raw_tc:x?}");
|
||||
log::warn!("raw data: {:x?}", raw_tc);
|
||||
// TODO: Shouldn't this be an error?
|
||||
return Ok(HandlingStatus::HandledOne);
|
||||
}
|
||||
@@ -269,16 +269,16 @@ pub struct PusTargetedRequestService<
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>,
|
||||
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
|
||||
ActiveRequestMapInstance: ActiveRequestStore<ActiveRequestInfo>,
|
||||
ActiveRequestInfo: ActiveRequest,
|
||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
|
||||
ActiveRequestInfo: ActiveRequestProvider,
|
||||
RequestType,
|
||||
ReplyType,
|
||||
> {
|
||||
pub service_helper:
|
||||
PusServiceHelper<TcReceiver, TmTcSender, EcssTcCacher, VerificationReporter>,
|
||||
PusServiceHelper<TcReceiver, TmTcSender, EcssTcInMemConverter, VerificationReporter>,
|
||||
pub request_router: GenericRequestRouter,
|
||||
pub request_converter: RequestConverter,
|
||||
pub active_request_map: ActiveRequestMapInstance,
|
||||
pub active_request_map: ActiveRequestMap,
|
||||
pub reply_handler: ReplyHandler,
|
||||
pub reply_receiver: mpsc::Receiver<GenericMessage<ReplyType>>,
|
||||
phantom: std::marker::PhantomData<(RequestType, ActiveRequestInfo, ReplyType)>,
|
||||
@@ -289,8 +289,8 @@ impl<
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>,
|
||||
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
|
||||
ActiveRequestMapInstance: ActiveRequestStore<ActiveRequestInfo>,
|
||||
ActiveRequestInfo: ActiveRequest,
|
||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
|
||||
ActiveRequestInfo: ActiveRequestProvider,
|
||||
RequestType,
|
||||
ReplyType,
|
||||
>
|
||||
@@ -299,7 +299,7 @@ impl<
|
||||
VerificationReporter,
|
||||
RequestConverter,
|
||||
ReplyHandler,
|
||||
ActiveRequestMapInstance,
|
||||
ActiveRequestMap,
|
||||
ActiveRequestInfo,
|
||||
RequestType,
|
||||
ReplyType,
|
||||
@@ -311,11 +311,11 @@ where
|
||||
service_helper: PusServiceHelper<
|
||||
TcReceiver,
|
||||
TmTcSender,
|
||||
EcssTcCacher,
|
||||
EcssTcInMemConverter,
|
||||
VerificationReporter,
|
||||
>,
|
||||
request_converter: RequestConverter,
|
||||
active_request_map: ActiveRequestMapInstance,
|
||||
active_request_map: ActiveRequestMap,
|
||||
reply_hook: ReplyHandler,
|
||||
request_router: GenericRequestRouter,
|
||||
reply_receiver: mpsc::Receiver<GenericMessage<ReplyType>>,
|
||||
@@ -509,7 +509,7 @@ where
|
||||
/// and also log the error.
|
||||
pub fn generic_pus_request_timeout_handler(
|
||||
sender: &(impl EcssTmSender + ?Sized),
|
||||
active_request: &(impl ActiveRequest + Debug),
|
||||
active_request: &(impl ActiveRequestProvider + Debug),
|
||||
verification_handler: &impl VerificationReportingProvider,
|
||||
time_stamp: &[u8],
|
||||
service_str: &'static str,
|
||||
@@ -531,15 +531,13 @@ pub fn generic_pus_request_timeout_handler(
|
||||
pub(crate) mod tests {
|
||||
use std::time::Duration;
|
||||
|
||||
use arbitrary_int::u11;
|
||||
use satrs::pus::test_util::TEST_COMPONENT_ID_0;
|
||||
use satrs::pus::{MpscTmAsVecSender, PusTmVariant};
|
||||
use satrs::request::RequestId;
|
||||
use satrs::spacepackets::ecss::CreatorConfig;
|
||||
use satrs::{
|
||||
pus::{
|
||||
verification::test_util::TestVerificationReporter, ActivePusRequestStd,
|
||||
ActiveRequestStore, MpscTcReceiver,
|
||||
ActiveRequestMapProvider, MpscTcReceiver,
|
||||
},
|
||||
request::UniqueApidTargetId,
|
||||
spacepackets::{
|
||||
@@ -558,7 +556,7 @@ pub(crate) mod tests {
|
||||
// Testbench dedicated to the testing of [PusReplyHandler]s
|
||||
pub struct ReplyHandlerTestbench<
|
||||
ReplyHandler: PusReplyHandler<ActiveRequestInfo, Reply, Error = EcssTmtcError>,
|
||||
ActiveRequestInfo: ActiveRequest,
|
||||
ActiveRequestInfo: ActiveRequestProvider,
|
||||
Reply,
|
||||
> {
|
||||
pub id: ComponentId,
|
||||
@@ -572,7 +570,7 @@ pub(crate) mod tests {
|
||||
|
||||
impl<
|
||||
ReplyHandler: PusReplyHandler<ActiveRequestInfo, Reply, Error = EcssTmtcError>,
|
||||
ActiveRequestInfo: ActiveRequest,
|
||||
ActiveRequestInfo: ActiveRequestProvider,
|
||||
Reply,
|
||||
> ReplyHandlerTestbench<ReplyHandler, ActiveRequestInfo, Reply>
|
||||
{
|
||||
@@ -592,7 +590,7 @@ pub(crate) mod tests {
|
||||
|
||||
pub fn add_tc(
|
||||
&mut self,
|
||||
apid: u11,
|
||||
apid: u16,
|
||||
apid_target: u32,
|
||||
time_stamp: &[u8],
|
||||
) -> (verification::RequestId, ActivePusRequestStd) {
|
||||
@@ -602,7 +600,7 @@ pub(crate) mod tests {
|
||||
sp_header,
|
||||
sec_header_dummy,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
));
|
||||
let accepted = self
|
||||
.verif_reporter
|
||||
@@ -673,7 +671,7 @@ pub(crate) mod tests {
|
||||
// Testbench dedicated to the testing of [PusTcToRequestConverter]s
|
||||
pub struct PusConverterTestbench<
|
||||
Converter: PusTcToRequestConverter<ActiveRequestInfo, Request, Error = GenericConversionError>,
|
||||
ActiveRequestInfo: ActiveRequest,
|
||||
ActiveRequestInfo: ActiveRequestProvider,
|
||||
Request,
|
||||
> {
|
||||
pub id: ComponentId,
|
||||
@@ -687,7 +685,7 @@ pub(crate) mod tests {
|
||||
|
||||
impl<
|
||||
Converter: PusTcToRequestConverter<ActiveRequestInfo, Request, Error = GenericConversionError>,
|
||||
ActiveRequestInfo: ActiveRequest,
|
||||
ActiveRequestInfo: ActiveRequestProvider,
|
||||
Request,
|
||||
> PusConverterTestbench<Converter, ActiveRequestInfo, Request>
|
||||
{
|
||||
@@ -721,7 +719,7 @@ pub(crate) mod tests {
|
||||
&mut self,
|
||||
token: VerificationToken<TcStateAccepted>,
|
||||
time_stamp: &[u8],
|
||||
expected_apid: u11,
|
||||
expected_apid: u16,
|
||||
expected_apid_target: u32,
|
||||
) -> Result<(ActiveRequestInfo, Request), Converter::Error> {
|
||||
if self.current_packet.is_none() {
|
||||
@@ -753,8 +751,8 @@ pub(crate) mod tests {
|
||||
pub struct TargetedPusRequestTestbench<
|
||||
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>,
|
||||
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
|
||||
ActiveRequestMapInstance: ActiveRequestStore<ActiveRequestInfo>,
|
||||
ActiveRequestInfo: ActiveRequest,
|
||||
ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
|
||||
ActiveRequestInfo: ActiveRequestProvider,
|
||||
RequestType,
|
||||
ReplyType,
|
||||
> {
|
||||
@@ -763,7 +761,7 @@ pub(crate) mod tests {
|
||||
TestVerificationReporter,
|
||||
RequestConverter,
|
||||
ReplyHandler,
|
||||
ActiveRequestMapInstance,
|
||||
ActiveRequestMap,
|
||||
ActiveRequestInfo,
|
||||
RequestType,
|
||||
ReplyType,
|
||||
|
@@ -1,7 +1,5 @@
|
||||
use arbitrary_int::u14;
|
||||
use derive_new::new;
|
||||
use satrs::mode_tree::{ModeNode, ModeParent};
|
||||
use satrs::spacepackets::ecss::CreatorConfig;
|
||||
use satrs_example::ids;
|
||||
use std::sync::mpsc;
|
||||
use std::time::Duration;
|
||||
@@ -10,8 +8,8 @@ use crate::requests::GenericRequestRouter;
|
||||
use crate::tmtc::sender::TmTcSender;
|
||||
use satrs::pus::verification::VerificationReporter;
|
||||
use satrs::pus::{
|
||||
DefaultActiveRequestMap, EcssTcAndToken, EcssTcCacher, MpscTcReceiver, PusPacketHandlingError,
|
||||
PusServiceHelper,
|
||||
DefaultActiveRequestMap, EcssTcAndToken, EcssTcInMemConverter, MpscTcReceiver,
|
||||
PusPacketHandlingError, PusServiceHelper,
|
||||
};
|
||||
use satrs::request::GenericMessage;
|
||||
use satrs::{
|
||||
@@ -22,8 +20,8 @@ use satrs::{
|
||||
self, FailParams, TcStateAccepted, TcStateStarted, VerificationReportingProvider,
|
||||
VerificationToken,
|
||||
},
|
||||
ActivePusRequestStd, ActiveRequest, EcssTmSender, EcssTmtcError, GenericConversionError,
|
||||
PusReplyHandler, PusTcToRequestConverter, PusTmVariant,
|
||||
ActivePusRequestStd, ActiveRequestProvider, EcssTmSender, EcssTmtcError,
|
||||
GenericConversionError, PusReplyHandler, PusTcToRequestConverter, PusTmVariant,
|
||||
},
|
||||
request::UniqueApidTargetId,
|
||||
spacepackets::{
|
||||
@@ -79,16 +77,10 @@ impl PusReplyHandler<ActivePusRequestStd, ModeReply> for ModeReplyHandler {
|
||||
.write_to_be_bytes(&mut source_data)
|
||||
.expect("writing mode reply failed");
|
||||
let req_id = verification::RequestId::from(reply.request_id());
|
||||
let sp_header =
|
||||
SpHeader::new_for_unseg_tm(req_id.packet_id().apid(), u14::new(0), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tm(req_id.packet_id().apid(), 0, 0);
|
||||
let sec_header =
|
||||
PusTmSecondaryHeader::new(200, Subservice::TmModeReply as u8, 0, 0, time_stamp);
|
||||
let pus_tm = PusTmCreator::new(
|
||||
sp_header,
|
||||
sec_header,
|
||||
&source_data,
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let pus_tm = PusTmCreator::new(sp_header, sec_header, &source_data, true);
|
||||
tm_sender.send_tm(self.owner_id, PusTmVariant::Direct(pus_tm))?;
|
||||
verification_handler.completion_success(tm_sender, started_token, time_stamp)?;
|
||||
}
|
||||
@@ -218,7 +210,7 @@ impl PusTcToRequestConverter<ActivePusRequestStd, ModeRequest> for ModeRequestCo
|
||||
|
||||
pub fn create_mode_service(
|
||||
tm_sender: TmTcSender,
|
||||
tc_in_mem_converter: EcssTcCacher,
|
||||
tc_in_mem_converter: EcssTcInMemConverter,
|
||||
pus_action_rx: mpsc::Receiver<EcssTcAndToken>,
|
||||
mode_router: GenericRequestRouter,
|
||||
reply_receiver: mpsc::Receiver<GenericMessage<ModeReply>>,
|
||||
@@ -298,10 +290,8 @@ impl TargetedPusService for ModeServiceWrapper {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use arbitrary_int::u14;
|
||||
use satrs::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0, TEST_UNIQUE_ID_0};
|
||||
use satrs::request::MessageMetadata;
|
||||
use satrs::spacepackets::ecss::CreatorConfig;
|
||||
use satrs::{
|
||||
mode::{ModeAndSubmode, ModeReply, ModeRequest},
|
||||
pus::mode::Subservice,
|
||||
@@ -324,11 +314,11 @@ mod tests {
|
||||
fn mode_converter_read_mode_request() {
|
||||
let mut testbench =
|
||||
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default());
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcReadMode as u8);
|
||||
let mut app_data: [u8; 4] = [0; 4];
|
||||
app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes());
|
||||
let tc = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default());
|
||||
let tc = PusTcCreator::new(sp_header, sec_header, &app_data, true);
|
||||
let token = testbench.add_tc(&tc);
|
||||
let (_active_req, req) = testbench
|
||||
.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0)
|
||||
@@ -340,7 +330,7 @@ mod tests {
|
||||
fn mode_converter_set_mode_request() {
|
||||
let mut testbench =
|
||||
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default());
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcSetMode as u8);
|
||||
let mut app_data: [u8; 4 + ModeAndSubmode::RAW_LEN] = [0; 4 + ModeAndSubmode::RAW_LEN];
|
||||
let mode_and_submode = ModeAndSubmode::new(2, 1);
|
||||
@@ -348,7 +338,7 @@ mod tests {
|
||||
mode_and_submode
|
||||
.write_to_be_bytes(&mut app_data[4..])
|
||||
.unwrap();
|
||||
let tc = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default());
|
||||
let tc = PusTcCreator::new(sp_header, sec_header, &app_data, true);
|
||||
let token = testbench.add_tc(&tc);
|
||||
let (_active_req, req) = testbench
|
||||
.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0)
|
||||
@@ -366,11 +356,11 @@ mod tests {
|
||||
fn mode_converter_announce_mode() {
|
||||
let mut testbench =
|
||||
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default());
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcAnnounceMode as u8);
|
||||
let mut app_data: [u8; 4] = [0; 4];
|
||||
app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes());
|
||||
let tc = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default());
|
||||
let tc = PusTcCreator::new(sp_header, sec_header, &app_data, true);
|
||||
let token = testbench.add_tc(&tc);
|
||||
let (_active_req, req) = testbench
|
||||
.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0)
|
||||
@@ -382,12 +372,12 @@ mod tests {
|
||||
fn mode_converter_announce_mode_recursively() {
|
||||
let mut testbench =
|
||||
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default());
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header =
|
||||
PusTcSecondaryHeader::new_simple(200, Subservice::TcAnnounceModeRecursive as u8);
|
||||
let mut app_data: [u8; 4] = [0; 4];
|
||||
app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes());
|
||||
let tc = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default());
|
||||
let tc = PusTcCreator::new(sp_header, sec_header, &app_data, true);
|
||||
let token = testbench.add_tc(&tc);
|
||||
let (_active_req, req) = testbench
|
||||
.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0)
|
||||
|
@@ -9,7 +9,7 @@ use satrs::pus::scheduler::{PusScheduler, TcInfo};
|
||||
use satrs::pus::scheduler_srv::PusSchedServiceHandler;
|
||||
use satrs::pus::verification::VerificationReporter;
|
||||
use satrs::pus::{
|
||||
DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcCacher, MpscTcReceiver,
|
||||
DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConverter, MpscTcReceiver,
|
||||
PartialPusHandlingError, PusServiceHelper,
|
||||
};
|
||||
use satrs::spacepackets::ecss::PusServiceId;
|
||||
@@ -84,7 +84,7 @@ pub struct SchedulingServiceWrapper {
|
||||
pub pus_11_handler: PusSchedServiceHandler<
|
||||
MpscTcReceiver,
|
||||
TmTcSender,
|
||||
EcssTcCacher,
|
||||
EcssTcInMemConverter,
|
||||
VerificationReporter,
|
||||
PusScheduler,
|
||||
>,
|
||||
@@ -174,7 +174,7 @@ impl SchedulingServiceWrapper {
|
||||
|
||||
pub fn create_scheduler_service(
|
||||
tm_sender: TmTcSender,
|
||||
tc_in_mem_converter: EcssTcCacher,
|
||||
tc_in_mem_converter: EcssTcInMemConverter,
|
||||
tc_releaser: TcReleaser,
|
||||
pus_sched_rx: mpsc::Receiver<EcssTcAndToken>,
|
||||
sched_tc_pool: StaticMemoryPool,
|
||||
|
@@ -6,8 +6,8 @@ use satrs::pus::test::PusService17TestHandler;
|
||||
use satrs::pus::verification::{FailParams, VerificationReporter, VerificationReportingProvider};
|
||||
use satrs::pus::PartialPusHandlingError;
|
||||
use satrs::pus::{
|
||||
CacheAndReadRawEcssTc, DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcCacher,
|
||||
MpscTcReceiver, PusServiceHelper,
|
||||
DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConversionProvider,
|
||||
EcssTcInMemConverter, MpscTcReceiver, PusServiceHelper,
|
||||
};
|
||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||
use satrs::spacepackets::ecss::{PusPacket, PusServiceId};
|
||||
@@ -19,7 +19,7 @@ use super::{DirectPusService, HandlingStatus};
|
||||
|
||||
pub fn create_test_service(
|
||||
tm_sender: TmTcSender,
|
||||
tc_in_mem_converter: EcssTcCacher,
|
||||
tc_in_mem_converter: EcssTcInMemConverter,
|
||||
event_sender: mpsc::SyncSender<EventMessageU32>,
|
||||
pus_test_rx: mpsc::Receiver<EcssTcAndToken>,
|
||||
) -> TestCustomServiceWrapper {
|
||||
@@ -37,8 +37,12 @@ pub fn create_test_service(
|
||||
}
|
||||
|
||||
pub struct TestCustomServiceWrapper {
|
||||
pub handler:
|
||||
PusService17TestHandler<MpscTcReceiver, TmTcSender, EcssTcCacher, VerificationReporter>,
|
||||
pub handler: PusService17TestHandler<
|
||||
MpscTcReceiver,
|
||||
TmTcSender,
|
||||
EcssTcInMemConverter,
|
||||
VerificationReporter,
|
||||
>,
|
||||
pub event_tx: mpsc::SyncSender<EventMessageU32>,
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@ use satrs::mode::ModeRequest;
|
||||
use satrs::pus::verification::{
|
||||
FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken,
|
||||
};
|
||||
use satrs::pus::{ActiveRequest, EcssTmSender, GenericRoutingError, PusRequestRouter};
|
||||
use satrs::pus::{ActiveRequestProvider, EcssTmSender, GenericRoutingError, PusRequestRouter};
|
||||
use satrs::queue::GenericSendError;
|
||||
use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId};
|
||||
use satrs::spacepackets::ecss::tc::PusTcReader;
|
||||
@@ -46,7 +46,7 @@ impl Default for GenericRequestRouter {
|
||||
impl GenericRequestRouter {
|
||||
pub(crate) fn handle_error_generic(
|
||||
&self,
|
||||
active_request: &impl ActiveRequest,
|
||||
active_request: &impl ActiveRequestProvider,
|
||||
tc: &PusTcReader,
|
||||
error: GenericRoutingError,
|
||||
tm_sender: &(impl EcssTmSender + ?Sized),
|
||||
|
@@ -3,19 +3,18 @@ use std::{
|
||||
sync::mpsc::{self},
|
||||
};
|
||||
|
||||
use arbitrary_int::{u11, u14};
|
||||
use log::info;
|
||||
use satrs::{
|
||||
pool::PoolProvider,
|
||||
spacepackets::{
|
||||
ecss::{tm::PusTmZeroCopyWriter, PusPacket},
|
||||
seq_count::SequenceCounterCcsdsSimple,
|
||||
seq_count::CcsdsSimpleSeqCountProvider,
|
||||
time::cds::MIN_CDS_FIELD_LEN,
|
||||
CcsdsPacket,
|
||||
},
|
||||
};
|
||||
use satrs::{
|
||||
spacepackets::seq_count::SequenceCounter,
|
||||
spacepackets::seq_count::SequenceCountProvider,
|
||||
tmtc::{PacketAsVec, PacketInPool, SharedPacketPool},
|
||||
};
|
||||
|
||||
@@ -23,16 +22,14 @@ use crate::interface::tcp::SyncTcpTmSource;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CcsdsSeqCounterMap {
|
||||
apid_seq_counter_map: HashMap<u11, SequenceCounterCcsdsSimple>,
|
||||
apid_seq_counter_map: HashMap<u16, CcsdsSimpleSeqCountProvider>,
|
||||
}
|
||||
impl CcsdsSeqCounterMap {
|
||||
pub fn get_and_increment(&mut self, apid: u11) -> u14 {
|
||||
u14::new(
|
||||
self.apid_seq_counter_map
|
||||
.entry(apid)
|
||||
.or_default()
|
||||
.get_and_increment(),
|
||||
)
|
||||
pub fn get_and_increment(&mut self, apid: u16) -> u16 {
|
||||
self.apid_seq_counter_map
|
||||
.entry(apid)
|
||||
.or_default()
|
||||
.get_and_increment()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +114,7 @@ impl TmSinkStatic {
|
||||
let mut tm_copy = Vec::new();
|
||||
pool_guard
|
||||
.modify(&pus_tm_in_pool.store_addr, |buf| {
|
||||
let zero_copy_writer = PusTmZeroCopyWriter::new(buf, MIN_CDS_FIELD_LEN, true)
|
||||
let zero_copy_writer = PusTmZeroCopyWriter::new(buf, MIN_CDS_FIELD_LEN)
|
||||
.expect("Creating TM zero copy writer failed");
|
||||
self.common.apply_packet_processing(zero_copy_writer);
|
||||
tm_copy = buf.to_vec()
|
||||
@@ -157,9 +154,8 @@ impl TmSinkDynamic {
|
||||
if let Ok(mut tm) = self.tm_funnel_rx.recv() {
|
||||
// Read the TM, set sequence counter and message counter, and finally update
|
||||
// the CRC.
|
||||
let zero_copy_writer =
|
||||
PusTmZeroCopyWriter::new(&mut tm.packet, MIN_CDS_FIELD_LEN, true)
|
||||
.expect("Creating TM zero copy writer failed");
|
||||
let zero_copy_writer = PusTmZeroCopyWriter::new(&mut tm.packet, MIN_CDS_FIELD_LEN)
|
||||
.expect("Creating TM zero copy writer failed");
|
||||
self.common.apply_packet_processing(zero_copy_writer);
|
||||
self.common.sync_tm_tcp_source.add_tm(&tm.packet);
|
||||
self.tm_server_tx
|
||||
|
@@ -8,10 +8,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v0.1.3] 2024-08-26
|
||||
|
||||
Bump `satrs-shared`.
|
||||
|
||||
# [v0.1.2] 2024-04-17
|
||||
|
||||
Allow `satrs-shared` from `v0.1.3` to `<v0.2`.
|
||||
@@ -23,6 +19,3 @@ Allow `satrs-shared` from `v0.1.3` to `<v0.2`.
|
||||
# [v0.1.0] 2024-02-12
|
||||
|
||||
Initial release containing the `resultcode` macro.
|
||||
|
||||
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-mib-v0.1.3...HEAD
|
||||
[v0.1.3]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-mib-v0.1.2...satrs-mib-v0.1.3
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "satrs-mib"
|
||||
version = "0.1.3"
|
||||
version = "0.1.2"
|
||||
edition = "2021"
|
||||
rust-version = "1.61"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
@@ -23,7 +23,7 @@ version = "1"
|
||||
optional = true
|
||||
|
||||
[dependencies.satrs-shared]
|
||||
version = "0.2"
|
||||
version = "0.2.2"
|
||||
path = "../satrs-shared"
|
||||
features = ["serde"]
|
||||
|
||||
|
@@ -28,7 +28,7 @@ features = ["full"]
|
||||
trybuild = { version = "1", features = ["diff"] }
|
||||
|
||||
[dev-dependencies.satrs-shared]
|
||||
version = "0.2"
|
||||
version = "0.2.2"
|
||||
path = "../../satrs-shared"
|
||||
|
||||
[dev-dependencies.satrs-mib]
|
||||
|
@@ -11,7 +11,7 @@ serde_json = "1"
|
||||
log = "0.4"
|
||||
thiserror = "2"
|
||||
fern = "0.7"
|
||||
strum = { version = "0.27", features = ["derive"] }
|
||||
strum = { version = "0.26", features = ["derive"] }
|
||||
num_enum = "0.7"
|
||||
humantime = "2"
|
||||
tai-time = { version = "0.3", features = ["serde"] }
|
||||
|
@@ -120,7 +120,7 @@ impl SimController {
|
||||
fn handle_ctrl_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> {
|
||||
let sim_ctrl_request = SimCtrlRequest::from_sim_message(request)?;
|
||||
if SIM_CTRL_REQ_WIRETAPPING {
|
||||
log::info!("received sim ctrl request: {sim_ctrl_request:?}");
|
||||
log::info!("received sim ctrl request: {:?}", sim_ctrl_request);
|
||||
}
|
||||
match sim_ctrl_request {
|
||||
SimCtrlRequest::Ping => {
|
||||
@@ -139,7 +139,7 @@ impl SimController {
|
||||
) -> Result<(), SimRequestError> {
|
||||
let mgm_request = MgmRequestLis3Mdl::from_sim_message(request)?;
|
||||
if MGM_REQ_WIRETAPPING {
|
||||
log::info!("received MGM request: {mgm_request:?}");
|
||||
log::info!("received MGM request: {:?}", mgm_request);
|
||||
}
|
||||
match mgm_request {
|
||||
MgmRequestLis3Mdl::RequestSensorData => {
|
||||
@@ -160,7 +160,7 @@ impl SimController {
|
||||
fn handle_pcdu_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> {
|
||||
let pcdu_request = PcduRequest::from_sim_message(request)?;
|
||||
if PCDU_REQ_WIRETAPPING {
|
||||
log::info!("received PCDU request: {pcdu_request:?}");
|
||||
log::info!("received PCDU request: {:?}", pcdu_request);
|
||||
}
|
||||
match pcdu_request {
|
||||
PcduRequest::RequestSwitchInfo => {
|
||||
@@ -188,7 +188,7 @@ impl SimController {
|
||||
fn handle_mgt_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> {
|
||||
let mgt_request = MgtRequest::from_sim_message(request)?;
|
||||
if MGT_REQ_WIRETAPPING {
|
||||
log::info!("received MGT request: {mgt_request:?}");
|
||||
log::info!("received MGT request: {:?}", mgt_request);
|
||||
}
|
||||
match mgt_request {
|
||||
MgtRequest::ApplyTorque { duration, dipole } => self
|
||||
|
@@ -130,7 +130,7 @@ fn main() {
|
||||
let mut udp_server =
|
||||
SimUdpServer::new(SIM_CTRL_PORT, request_sender, reply_receiver, 200, None)
|
||||
.expect("could not create UDP request server");
|
||||
log::info!("starting UDP server on port {SIM_CTRL_PORT}");
|
||||
log::info!("starting UDP server on port {}", SIM_CTRL_PORT);
|
||||
// This thread manages the simulator UDP server.
|
||||
let udp_tc_thread = thread::spawn(move || {
|
||||
udp_server.run();
|
||||
|
@@ -8,10 +8,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v0.2.3] 2025-07-22
|
||||
|
||||
`spacepackets` range v0.14 to v0.15
|
||||
|
||||
# [v0.2.2] 2025-05-10
|
||||
|
||||
- Bump to `spacepackests` v0.14
|
||||
@@ -50,6 +46,5 @@ Allow `spacepackets` range starting with v0.10 and v0.11.
|
||||
|
||||
Initial release.
|
||||
|
||||
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.3...HEAD
|
||||
[v0.2.3]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.1...satrs-shared-v0.2.3
|
||||
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.2...HEAD
|
||||
[v0.2.2]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.1...satrs-shared-v0.2.2
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "satrs-shared"
|
||||
description = "Components shared by multiple sat-rs crates"
|
||||
version = "0.2.3"
|
||||
version = "0.2.2"
|
||||
edition = "2021"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
homepage = "https://absatsw.irs.uni-stuttgart.de/projects/sat-rs/"
|
||||
@@ -11,7 +11,7 @@ license = "Apache-2.0"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
spacepackets = { git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", version = ">=0.14, <=0.16", default-features = false }
|
||||
spacepackets = { version = ">=0.14, <=0.15", git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", default-features = false }
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
|
@@ -8,26 +8,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
- Bump `sat-rs` edition to 2024.
|
||||
|
||||
## Changed
|
||||
|
||||
Some trait renaming to be more in-line with Rust naming conventions.
|
||||
|
||||
- `EventTmHookProvider` -> `EventTmHook`
|
||||
- `ActiveRequestProvider` -> `ActiveRequest`
|
||||
- `EcssTcInMemConversionProvider` -> `CacheAndReadRawEcssTc`
|
||||
- `ActiveRequestMapProvider` -> `ActiveRequestStore`
|
||||
- `CountdownProvider` -> `Countdown`
|
||||
|
||||
# [v0.3.0-alpha.2] 2025-07-22
|
||||
|
||||
`satrs-shared` update
|
||||
|
||||
# [v0.3.0-alpha.1] 2025-07-22
|
||||
|
||||
`spacepackets` range v0.14 to v0.15
|
||||
|
||||
# [v0.3.0-alpha.0] 2025-02-18
|
||||
|
||||
`spacepackets` v0.13
|
||||
@@ -218,8 +198,3 @@ docs-rs hotfix
|
||||
# [v0.1.0] 2024-02-12
|
||||
|
||||
Initial release.
|
||||
|
||||
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-v0.3.0-alpha.2...HEAD
|
||||
[v0.3.0-alpha.2]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-v0.3.0-alpha.1...satrs-v0.3.0-alpha.2
|
||||
[v0.3.0-alpha.1]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-v0.3.0-alpha.0...satrs-v0.3.0-alpha.1
|
||||
[v0.3.0-alpha.0]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-v0.2.1...satrs-v0.3.0-alpha.0
|
||||
|
@@ -1,8 +1,8 @@
|
||||
[package]
|
||||
name = "satrs"
|
||||
version = "0.3.0-alpha.2"
|
||||
edition = "2024"
|
||||
rust-version = "1.85.0"
|
||||
version = "0.3.0-alpha.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.82.0"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
description = "A library collection to build software for remote systems"
|
||||
homepage = "https://github.com/us-irs/sat-rs"
|
||||
@@ -13,28 +13,27 @@ keywords = ["no-std", "space", "aerospace"]
|
||||
categories = ["aerospace", "aerospace::space-protocols", "no-std", "hardware-support", "embedded"]
|
||||
|
||||
[dependencies]
|
||||
satrs-shared = { version = "0.2", path = "../satrs-shared" }
|
||||
spacepackets = { git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", version = "0.16", default-features = false }
|
||||
satrs-shared = { version = "0.2.2", path = "../satrs-shared" }
|
||||
spacepackets = { version = ">=0.14, <=0.15", git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", default-features = false }
|
||||
|
||||
arbitrary-int = "2"
|
||||
delegate = ">0.7, <=0.13"
|
||||
paste = "1"
|
||||
derive-new = ">=0.6, <=0.7"
|
||||
num_enum = { version = ">0.5, <=0.7", default-features = false }
|
||||
cobs = { version = "0.4", default-features = false }
|
||||
cobs = { version = "0.4", default-features = false, git = "https://github.com/jamesmunns/cobs.rs.git", branch = "main" }
|
||||
thiserror = { version = "2", default-features = false }
|
||||
|
||||
hashbrown = { version = ">=0.14, <=0.15", optional = true }
|
||||
static_cell = { version = "2", optional = true }
|
||||
dyn-clone = { version = "1", optional = true }
|
||||
heapless = { version = "0.9", optional = true }
|
||||
heapless = { version = "0.8", optional = true }
|
||||
downcast-rs = { version = "2", default-features = false, optional = true }
|
||||
bus = { version = "2.2", optional = true }
|
||||
crossbeam-channel = { version = "0.5", default-features = false, optional = true }
|
||||
serde = { version = "1", default-features = false, optional = true }
|
||||
socket2 = { version = "0.6", features = ["all"], optional = true }
|
||||
socket2 = { version = "0.5", features = ["all"], optional = true }
|
||||
mio = { version = "1", features = ["os-poll", "net"], optional = true }
|
||||
defmt = { version = "1", optional = true }
|
||||
defmt = { version = "0.3", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
serde = "1"
|
||||
|
@@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
ComponentId,
|
||||
mode::{ModeAndSubmode, ModeReply, ModeRequest, ModeRequestSender},
|
||||
mode_tree::{ModeStoreProvider, ModeStoreVec},
|
||||
queue::{GenericSendError, GenericTargetedMessagingError},
|
||||
request::{GenericMessage, RequestId},
|
||||
ComponentId,
|
||||
};
|
||||
use core::fmt::Debug;
|
||||
|
||||
@@ -270,7 +270,7 @@ impl<UserHook: DevManagerUserHook> DevManagerCommandingHelper<UserHook> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
mode::{UNKNOWN_MODE, tests::ModeReqSenderMock},
|
||||
mode::{tests::ModeReqSenderMock, UNKNOWN_MODE},
|
||||
request::MessageMetadata,
|
||||
};
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
use spacepackets::{CcsdsPacket, SpHeader};
|
||||
|
||||
use crate::{ComponentId, tmtc::PacketSenderRaw};
|
||||
use crate::{tmtc::PacketSenderRaw, ComponentId};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum SpValidity {
|
||||
@@ -63,7 +63,7 @@ pub fn parse_buffer_for_ccsds_space_packets<SendError>(
|
||||
let sp_header = SpHeader::from_be_bytes(&buf[current_idx..]).unwrap().0;
|
||||
match packet_validator.validate(&sp_header, &buf[current_idx..]) {
|
||||
SpValidity::Valid => {
|
||||
let packet_size = sp_header.packet_len();
|
||||
let packet_size = sp_header.total_len();
|
||||
if (current_idx + packet_size) <= buf_len {
|
||||
packet_sender
|
||||
.send_packet(sender_id, &buf[current_idx..current_idx + packet_size])?;
|
||||
@@ -76,7 +76,7 @@ pub fn parse_buffer_for_ccsds_space_packets<SendError>(
|
||||
continue;
|
||||
}
|
||||
SpValidity::Skip => {
|
||||
current_idx += sp_header.packet_len();
|
||||
current_idx += sp_header.total_len();
|
||||
}
|
||||
// We might have lost sync. Try to find the start of a new space packet header.
|
||||
SpValidity::Invalid => {
|
||||
@@ -89,19 +89,18 @@ pub fn parse_buffer_for_ccsds_space_packets<SendError>(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use arbitrary_int::{u11, u14};
|
||||
use spacepackets::{
|
||||
CcsdsPacket, PacketId, PacketSequenceControl, PacketType, SequenceFlags, SpHeader,
|
||||
ecss::{CreatorConfig, tc::PusTcCreator},
|
||||
ecss::{tc::PusTcCreator, WritablePusPacket},
|
||||
CcsdsPacket, PacketId, PacketSequenceCtrl, PacketType, SequenceFlags, SpHeader,
|
||||
};
|
||||
|
||||
use crate::{ComponentId, encoding::tests::TcCacher};
|
||||
use crate::{encoding::tests::TcCacher, ComponentId};
|
||||
|
||||
use super::{SpValidity, SpacePacketValidator, parse_buffer_for_ccsds_space_packets};
|
||||
use super::{parse_buffer_for_ccsds_space_packets, SpValidity, SpacePacketValidator};
|
||||
|
||||
const PARSER_ID: ComponentId = 0x05;
|
||||
const TEST_APID_0: u11 = u11::new(0x02);
|
||||
const TEST_APID_1: u11 = u11::new(0x10);
|
||||
const TEST_APID_0: u16 = 0x02;
|
||||
const TEST_APID_1: u16 = 0x10;
|
||||
const TEST_PACKET_ID_0: PacketId = PacketId::new_for_tc(true, TEST_APID_0);
|
||||
const TEST_PACKET_ID_1: PacketId = PacketId::new_for_tc(true, TEST_APID_1);
|
||||
|
||||
@@ -132,7 +131,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
let sph = SpHeader::new_from_apid(TEST_APID_0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
|
||||
let mut buffer: [u8; 32] = [0; 32];
|
||||
let packet_len = ping_tc
|
||||
.write_to_bytes(&mut buffer)
|
||||
@@ -157,8 +156,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_multi_packet() {
|
||||
let sph = SpHeader::new_from_apid(TEST_APID_0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let action_tc = PusTcCreator::new_simple(sph, 8, 0, &[], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
|
||||
let action_tc = PusTcCreator::new_simple(sph, 8, 0, &[], true);
|
||||
let mut buffer: [u8; 32] = [0; 32];
|
||||
let packet_len_ping = ping_tc
|
||||
.write_to_bytes(&mut buffer)
|
||||
@@ -192,9 +191,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_multi_apid() {
|
||||
let sph = SpHeader::new_from_apid(TEST_APID_0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
|
||||
let sph = SpHeader::new_from_apid(TEST_APID_1);
|
||||
let action_tc = PusTcCreator::new_simple(sph, 8, 0, &[], CreatorConfig::default());
|
||||
let action_tc = PusTcCreator::new_simple(sph, 8, 0, &[], true);
|
||||
let mut buffer: [u8; 32] = [0; 32];
|
||||
let packet_len_ping = ping_tc
|
||||
.write_to_bytes(&mut buffer)
|
||||
@@ -222,20 +221,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_split_packet_multi() {
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
17,
|
||||
1,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let action_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_1),
|
||||
8,
|
||||
0,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let ping_tc =
|
||||
PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 17, 1, &[], true);
|
||||
let action_tc =
|
||||
PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_1), 8, 0, &[], true);
|
||||
let mut buffer: [u8; 32] = [0; 32];
|
||||
let packet_len_ping = ping_tc
|
||||
.write_to_bytes(&mut buffer)
|
||||
@@ -266,13 +255,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_one_split_packet() {
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
17,
|
||||
1,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let ping_tc =
|
||||
PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 17, 1, &[], true);
|
||||
let mut buffer: [u8; 32] = [0; 32];
|
||||
let packet_len_ping = ping_tc
|
||||
.write_to_bytes(&mut buffer)
|
||||
@@ -297,7 +281,7 @@ mod tests {
|
||||
fn test_smallest_packet() {
|
||||
let ccsds_header_only = SpHeader::new(
|
||||
PacketId::new(PacketType::Tc, true, TEST_APID_0),
|
||||
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(0)),
|
||||
PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 0),
|
||||
0,
|
||||
);
|
||||
let mut buf: [u8; 7] = [0; 7];
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use crate::{ComponentId, tmtc::PacketSenderRaw};
|
||||
use crate::{tmtc::PacketSenderRaw, ComponentId};
|
||||
use cobs::{decode_in_place, encode, max_encoding_length};
|
||||
|
||||
/// This function encodes the given packet with COBS and also wraps the encoded packet with
|
||||
@@ -104,8 +104,8 @@ pub(crate) mod tests {
|
||||
use cobs::encode;
|
||||
|
||||
use crate::{
|
||||
encoding::tests::{encode_simple_packet, TcCacher, INVERTED_PACKET, SIMPLE_PACKET},
|
||||
ComponentId,
|
||||
encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET, TcCacher, encode_simple_packet},
|
||||
};
|
||||
|
||||
use super::parse_buffer_for_cobs_encoded_packets;
|
||||
|
@@ -11,8 +11,8 @@ pub(crate) mod tests {
|
||||
use alloc::collections::VecDeque;
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
tmtc::{PacketAsVec, PacketSenderRaw},
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
use super::cobs::encode_packet_with_cobs;
|
||||
|
@@ -71,14 +71,18 @@ pub enum ListenerKey {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EventMessage<Event: GenericEvent, Parameters: Debug = Params> {
|
||||
pub struct EventMessage<Event: GenericEvent, ParamProvider: Debug = Params> {
|
||||
sender_id: ComponentId,
|
||||
event: Event,
|
||||
params: Option<Parameters>,
|
||||
params: Option<ParamProvider>,
|
||||
}
|
||||
|
||||
impl<Event: GenericEvent, Parameters: Debug + Clone> EventMessage<Event, Parameters> {
|
||||
pub fn new_generic(sender_id: ComponentId, event: Event, params: Option<&Parameters>) -> Self {
|
||||
impl<Event: GenericEvent, ParamProvider: Debug + Clone> EventMessage<Event, ParamProvider> {
|
||||
pub fn new_generic(
|
||||
sender_id: ComponentId,
|
||||
event: Event,
|
||||
params: Option<&ParamProvider>,
|
||||
) -> Self {
|
||||
Self {
|
||||
sender_id,
|
||||
event,
|
||||
@@ -94,7 +98,7 @@ impl<Event: GenericEvent, Parameters: Debug + Clone> EventMessage<Event, Paramet
|
||||
self.event
|
||||
}
|
||||
|
||||
pub fn params(&self) -> Option<&Parameters> {
|
||||
pub fn params(&self) -> Option<&ParamProvider> {
|
||||
self.params.as_ref()
|
||||
}
|
||||
|
||||
@@ -102,7 +106,7 @@ impl<Event: GenericEvent, Parameters: Debug + Clone> EventMessage<Event, Paramet
|
||||
Self::new_generic(sender_id, event, None)
|
||||
}
|
||||
|
||||
pub fn new_with_params(sender_id: ComponentId, event: Event, params: &Parameters) -> Self {
|
||||
pub fn new_with_params(sender_id: ComponentId, event: Event, params: &ParamProvider) -> Self {
|
||||
Self::new_generic(sender_id, event, Some(params))
|
||||
}
|
||||
}
|
||||
@@ -132,7 +136,7 @@ pub trait ListenerMapProvider {
|
||||
#[cfg(feature = "alloc")]
|
||||
fn get_listeners(&self) -> alloc::vec::Vec<ListenerKey>;
|
||||
fn contains_listener(&self, key: &ListenerKey) -> bool;
|
||||
fn get_listener_ids(&self, key: &ListenerKey) -> Option<Iter<'_, ComponentId>>;
|
||||
fn get_listener_ids(&self, key: &ListenerKey) -> Option<Iter<ComponentId>>;
|
||||
fn add_listener(&mut self, key: ListenerKey, listener_id: ComponentId) -> bool;
|
||||
fn remove_duplicates(&mut self, key: &ListenerKey);
|
||||
}
|
||||
@@ -194,13 +198,13 @@ pub enum EventRoutingError {
|
||||
}
|
||||
|
||||
impl<
|
||||
EventReceiver: EventReceiveProvider<Event, ParamProvider>,
|
||||
SenderMap: SenderMapProvider<EventSender, Event, ParamProvider>,
|
||||
ListenerMap: ListenerMapProvider,
|
||||
EventSender: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent + Copy,
|
||||
ParamProvider: Debug,
|
||||
> EventManager<EventReceiver, SenderMap, ListenerMap, EventSender, Event, ParamProvider>
|
||||
EventReceiver: EventReceiveProvider<Event, ParamProvider>,
|
||||
SenderMap: SenderMapProvider<EventSender, Event, ParamProvider>,
|
||||
ListenerMap: ListenerMapProvider,
|
||||
EventSender: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent + Copy,
|
||||
ParamProvider: Debug,
|
||||
> EventManager<EventReceiver, SenderMap, ListenerMap, EventSender, Event, ParamProvider>
|
||||
{
|
||||
pub fn remove_duplicates(&mut self, key: &ListenerKey) {
|
||||
self.listener_map.remove_duplicates(key)
|
||||
@@ -225,13 +229,13 @@ impl<
|
||||
}
|
||||
}
|
||||
impl<
|
||||
EventReceiver: EventReceiveProvider<Event, ParamProvider>,
|
||||
SenderMap: SenderMapProvider<EventSenderMap, Event, ParamProvider>,
|
||||
ListenerMap: ListenerMapProvider,
|
||||
EventSenderMap: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent + Copy,
|
||||
ParamProvider: Debug,
|
||||
> EventManager<EventReceiver, SenderMap, ListenerMap, EventSenderMap, Event, ParamProvider>
|
||||
EventReceiver: EventReceiveProvider<Event, ParamProvider>,
|
||||
SenderMap: SenderMapProvider<EventSenderMap, Event, ParamProvider>,
|
||||
ListenerMap: ListenerMapProvider,
|
||||
EventSenderMap: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent + Copy,
|
||||
ParamProvider: Debug,
|
||||
> EventManager<EventReceiver, SenderMap, ListenerMap, EventSenderMap, Event, ParamProvider>
|
||||
{
|
||||
pub fn new_with_custom_maps(
|
||||
event_receiver: EventReceiver,
|
||||
@@ -263,13 +267,13 @@ impl<
|
||||
}
|
||||
|
||||
impl<
|
||||
EventReceiver: EventReceiveProvider<Event, ParamProvider>,
|
||||
SenderMap: SenderMapProvider<EventSenderMap, Event, ParamProvider>,
|
||||
ListenerMap: ListenerMapProvider,
|
||||
EventSenderMap: EventSendProvider<Event, ParamProvider, Error = GenericSendError>,
|
||||
Event: GenericEvent + Copy,
|
||||
ParamProvider: Clone + Debug,
|
||||
> EventManager<EventReceiver, SenderMap, ListenerMap, EventSenderMap, Event, ParamProvider>
|
||||
EventReceiver: EventReceiveProvider<Event, ParamProvider>,
|
||||
SenderMap: SenderMapProvider<EventSenderMap, Event, ParamProvider>,
|
||||
ListenerMap: ListenerMapProvider,
|
||||
EventSenderMap: EventSendProvider<Event, ParamProvider, Error = GenericSendError>,
|
||||
Event: GenericEvent + Copy,
|
||||
ParamProvider: Clone + Debug,
|
||||
> EventManager<EventReceiver, SenderMap, ListenerMap, EventSenderMap, Event, ParamProvider>
|
||||
{
|
||||
/// This function will use the cached event receiver and try to receive one event.
|
||||
/// If an event was received, it will try to route that event to all subscribed event listeners.
|
||||
@@ -351,11 +355,11 @@ pub mod alloc_mod {
|
||||
>;
|
||||
|
||||
impl<
|
||||
EventReceiver: EventReceiveProvider<Event, ParamProvider>,
|
||||
EventSender: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent + Copy,
|
||||
ParamProvider: 'static + Debug,
|
||||
>
|
||||
EventReceiver: EventReceiveProvider<Event, ParamProvider>,
|
||||
EventSender: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent + Copy,
|
||||
ParamProvider: 'static + Debug,
|
||||
>
|
||||
EventManager<
|
||||
EventReceiver,
|
||||
DefaultSenderMap<EventSender, Event, ParamProvider>,
|
||||
@@ -398,7 +402,7 @@ pub mod alloc_mod {
|
||||
self.listeners.contains_key(key)
|
||||
}
|
||||
|
||||
fn get_listener_ids(&self, key: &ListenerKey) -> Option<Iter<'_, ComponentId>> {
|
||||
fn get_listener_ids(&self, key: &ListenerKey) -> Option<Iter<ComponentId>> {
|
||||
self.listeners.get(key).map(|vec| vec.iter())
|
||||
}
|
||||
|
||||
@@ -433,10 +437,10 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
EventSender: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent,
|
||||
ParamProvider: Debug,
|
||||
> Default for DefaultSenderMap<EventSender, Event, ParamProvider>
|
||||
EventSender: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent,
|
||||
ParamProvider: Debug,
|
||||
> Default for DefaultSenderMap<EventSender, Event, ParamProvider>
|
||||
{
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -447,10 +451,10 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
EventSender: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent,
|
||||
ParamProvider: Debug,
|
||||
> SenderMapProvider<EventSender, Event, ParamProvider>
|
||||
EventSender: EventSendProvider<Event, ParamProvider>,
|
||||
Event: GenericEvent,
|
||||
ParamProvider: Debug,
|
||||
> SenderMapProvider<EventSender, Event, ParamProvider>
|
||||
for DefaultSenderMap<EventSender, Event, ParamProvider>
|
||||
{
|
||||
fn contains_send_event_provider(&self, id: &ComponentId) -> bool {
|
||||
|
@@ -31,9 +31,9 @@ use core::fmt::Debug;
|
||||
use core::hash::Hash;
|
||||
use core::marker::PhantomData;
|
||||
use delegate::delegate;
|
||||
use spacepackets::ByteConversionError;
|
||||
use spacepackets::ecss::EcssEnumeration;
|
||||
use spacepackets::util::{ToBeBytes, UnsignedEnum};
|
||||
use spacepackets::ByteConversionError;
|
||||
|
||||
/// Using a type definition allows to change this to u64 in the future more easily
|
||||
pub type LargestEventRaw = u32;
|
||||
|
@@ -55,35 +55,33 @@ pub fn exec_sched_single<
|
||||
let mut cycle_count = 0;
|
||||
thread::Builder::new()
|
||||
.name(String::from(executable.task_name()))
|
||||
.spawn(move || {
|
||||
loop {
|
||||
if let Some(ref mut terminator) = termination {
|
||||
match terminator.try_recv() {
|
||||
Ok(_) | Err(TryRecvError::Disconnected) => {
|
||||
return Ok(OpResult::Ok);
|
||||
}
|
||||
Err(TryRecvError::Empty) => (),
|
||||
}
|
||||
}
|
||||
match executable.exec_type() {
|
||||
ExecutionType::OneShot => {
|
||||
executable.periodic_op(op_code)?;
|
||||
.spawn(move || loop {
|
||||
if let Some(ref mut terminator) = termination {
|
||||
match terminator.try_recv() {
|
||||
Ok(_) | Err(TryRecvError::Disconnected) => {
|
||||
return Ok(OpResult::Ok);
|
||||
}
|
||||
ExecutionType::Infinite => {
|
||||
executable.periodic_op(op_code)?;
|
||||
}
|
||||
ExecutionType::Cycles(cycles) => {
|
||||
executable.periodic_op(op_code)?;
|
||||
cycle_count += 1;
|
||||
if cycle_count == cycles {
|
||||
return Ok(OpResult::Ok);
|
||||
}
|
||||
Err(TryRecvError::Empty) => (),
|
||||
}
|
||||
}
|
||||
match executable.exec_type() {
|
||||
ExecutionType::OneShot => {
|
||||
executable.periodic_op(op_code)?;
|
||||
return Ok(OpResult::Ok);
|
||||
}
|
||||
ExecutionType::Infinite => {
|
||||
executable.periodic_op(op_code)?;
|
||||
}
|
||||
ExecutionType::Cycles(cycles) => {
|
||||
executable.periodic_op(op_code)?;
|
||||
cycle_count += 1;
|
||||
if cycle_count == cycles {
|
||||
return Ok(OpResult::Ok);
|
||||
}
|
||||
}
|
||||
if let Some(freq) = task_freq {
|
||||
thread::sleep(freq);
|
||||
}
|
||||
}
|
||||
if let Some(freq) = task_freq {
|
||||
thread::sleep(freq);
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -112,53 +110,51 @@ pub fn exec_sched_multi<
|
||||
|
||||
thread::Builder::new()
|
||||
.name(String::from(task_name))
|
||||
.spawn(move || {
|
||||
loop {
|
||||
if let Some(ref mut terminator) = termination {
|
||||
match terminator.try_recv() {
|
||||
Ok(_) | Err(TryRecvError::Disconnected) => {
|
||||
removal_flags.iter_mut().for_each(|x| *x = true);
|
||||
}
|
||||
Err(TryRecvError::Empty) => (),
|
||||
.spawn(move || loop {
|
||||
if let Some(ref mut terminator) = termination {
|
||||
match terminator.try_recv() {
|
||||
Ok(_) | Err(TryRecvError::Disconnected) => {
|
||||
removal_flags.iter_mut().for_each(|x| *x = true);
|
||||
}
|
||||
Err(TryRecvError::Empty) => (),
|
||||
}
|
||||
for (idx, executable) in executable_vec.iter_mut().enumerate() {
|
||||
match executable.exec_type() {
|
||||
ExecutionType::OneShot => {
|
||||
executable.periodic_op(op_code)?;
|
||||
}
|
||||
for (idx, executable) in executable_vec.iter_mut().enumerate() {
|
||||
match executable.exec_type() {
|
||||
ExecutionType::OneShot => {
|
||||
executable.periodic_op(op_code)?;
|
||||
removal_flags[idx] = true;
|
||||
}
|
||||
ExecutionType::Infinite => {
|
||||
executable.periodic_op(op_code)?;
|
||||
}
|
||||
ExecutionType::Cycles(cycles) => {
|
||||
executable.periodic_op(op_code)?;
|
||||
cycle_counts[idx] += 1;
|
||||
if cycle_counts[idx] == cycles {
|
||||
removal_flags[idx] = true;
|
||||
}
|
||||
ExecutionType::Infinite => {
|
||||
executable.periodic_op(op_code)?;
|
||||
}
|
||||
ExecutionType::Cycles(cycles) => {
|
||||
executable.periodic_op(op_code)?;
|
||||
cycle_counts[idx] += 1;
|
||||
if cycle_counts[idx] == cycles {
|
||||
removal_flags[idx] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut removal_iter = removal_flags.iter();
|
||||
executable_vec.retain(|_| !*removal_iter.next().unwrap());
|
||||
removal_iter = removal_flags.iter();
|
||||
cycle_counts.retain(|_| !*removal_iter.next().unwrap());
|
||||
removal_flags.retain(|&i| !i);
|
||||
if executable_vec.is_empty() {
|
||||
return Ok(OpResult::Ok);
|
||||
}
|
||||
let freq = task_freq.unwrap_or_else(|| panic!("No task frequency specified"));
|
||||
thread::sleep(freq);
|
||||
}
|
||||
let mut removal_iter = removal_flags.iter();
|
||||
executable_vec.retain(|_| !*removal_iter.next().unwrap());
|
||||
removal_iter = removal_flags.iter();
|
||||
cycle_counts.retain(|_| !*removal_iter.next().unwrap());
|
||||
removal_flags.retain(|&i| !i);
|
||||
if executable_vec.is_empty() {
|
||||
return Ok(OpResult::Ok);
|
||||
}
|
||||
let freq = task_freq.unwrap_or_else(|| panic!("No task frequency specified"));
|
||||
thread::sleep(freq);
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{
|
||||
Executable, ExecutableWithType, ExecutionType, OpResult, exec_sched_multi,
|
||||
exec_sched_single,
|
||||
exec_sched_multi, exec_sched_single, Executable, ExecutableWithType, ExecutionType,
|
||||
OpResult,
|
||||
};
|
||||
use bus::Bus;
|
||||
use std::boxed::Box;
|
||||
|
@@ -13,10 +13,10 @@ use crate::encoding::parse_buffer_for_cobs_encoded_packets;
|
||||
use crate::tmtc::PacketSenderRaw;
|
||||
use crate::tmtc::PacketSource;
|
||||
|
||||
use crate::ComponentId;
|
||||
use crate::hal::std::tcp_server::{
|
||||
ConnectionResult, ServerConfig, TcpTcParser, TcpTmSender, TcpTmtcError, TcpTmtcGenericServer,
|
||||
};
|
||||
use crate::ComponentId;
|
||||
|
||||
use super::tcp_server::HandledConnectionHandler;
|
||||
use super::tcp_server::HandledConnectionInfo;
|
||||
@@ -136,12 +136,12 @@ pub struct TcpTmtcInCobsServer<
|
||||
}
|
||||
|
||||
impl<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcReceiver: PacketSenderRaw<Error = TcError>,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcError: 'static,
|
||||
> TcpTmtcInCobsServer<TmSource, TcReceiver, HandledConnection, TmError, TcError>
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcReceiver: PacketSenderRaw<Error = TcError>,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcError: 'static,
|
||||
> TcpTmtcInCobsServer<TmSource, TcReceiver, HandledConnection, TmError, TcError>
|
||||
{
|
||||
/// Create a new TCP TMTC server which exchanges TMTC packets encoded with
|
||||
/// [COBS protocol](https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing).
|
||||
@@ -206,14 +206,14 @@ mod tests {
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET},
|
||||
hal::std::tcp_server::{
|
||||
ConnectionResult, ServerConfig,
|
||||
tests::{ConnectionFinishedHandler, SyncTmSource},
|
||||
ConnectionResult, ServerConfig,
|
||||
},
|
||||
queue::GenericSendError,
|
||||
tmtc::PacketAsVec,
|
||||
ComponentId,
|
||||
};
|
||||
use alloc::sync::Arc;
|
||||
use cobs::encode;
|
||||
@@ -435,19 +435,17 @@ mod tests {
|
||||
generic_tmtc_server(&auto_port_addr, tc_sender.clone(), tm_source, None);
|
||||
let start = Instant::now();
|
||||
// Call the connection handler in separate thread, does block.
|
||||
let thread_jh = thread::spawn(move || {
|
||||
loop {
|
||||
let result = tcp_server.handle_all_connections(Some(Duration::from_millis(20)));
|
||||
if result.is_err() {
|
||||
panic!("handling connection failed: {:?}", result.unwrap_err());
|
||||
}
|
||||
let result = result.unwrap();
|
||||
if result == ConnectionResult::AcceptTimeout {
|
||||
break;
|
||||
}
|
||||
if Instant::now() - start > Duration::from_millis(100) {
|
||||
panic!("regular stop signal handling failed");
|
||||
}
|
||||
let thread_jh = thread::spawn(move || loop {
|
||||
let result = tcp_server.handle_all_connections(Some(Duration::from_millis(20)));
|
||||
if result.is_err() {
|
||||
panic!("handling connection failed: {:?}", result.unwrap_err());
|
||||
}
|
||||
let result = result.unwrap();
|
||||
if result == ConnectionResult::AcceptTimeout {
|
||||
break;
|
||||
}
|
||||
if Instant::now() - start > Duration::from_millis(100) {
|
||||
panic!("regular stop signal handling failed");
|
||||
}
|
||||
});
|
||||
thread_jh.join().expect("thread join failed");
|
||||
@@ -471,22 +469,20 @@ mod tests {
|
||||
let stop_signal_copy = stop_signal.clone();
|
||||
let start = Instant::now();
|
||||
// Call the connection handler in separate thread, does block.
|
||||
let thread_jh = thread::spawn(move || {
|
||||
loop {
|
||||
let result = tcp_server.handle_all_connections(Some(Duration::from_millis(20)));
|
||||
if result.is_err() {
|
||||
panic!("handling connection failed: {:?}", result.unwrap_err());
|
||||
}
|
||||
let result = result.unwrap();
|
||||
if result == ConnectionResult::AcceptTimeout {
|
||||
panic!("unexpected accept timeout");
|
||||
}
|
||||
if stop_signal_copy.load(Ordering::Relaxed) {
|
||||
break;
|
||||
}
|
||||
if Instant::now() - start > Duration::from_millis(100) {
|
||||
panic!("regular stop signal handling failed");
|
||||
}
|
||||
let thread_jh = thread::spawn(move || loop {
|
||||
let result = tcp_server.handle_all_connections(Some(Duration::from_millis(20)));
|
||||
if result.is_err() {
|
||||
panic!("handling connection failed: {:?}", result.unwrap_err());
|
||||
}
|
||||
let result = result.unwrap();
|
||||
if result == ConnectionResult::AcceptTimeout {
|
||||
panic!("unexpected accept timeout");
|
||||
}
|
||||
if stop_signal_copy.load(Ordering::Relaxed) {
|
||||
break;
|
||||
}
|
||||
if Instant::now() - start > Duration::from_millis(100) {
|
||||
panic!("regular stop signal handling failed");
|
||||
}
|
||||
});
|
||||
// We connect but do not do anything.
|
||||
|
@@ -11,8 +11,8 @@ use std::io::{self, Read};
|
||||
use std::net::SocketAddr;
|
||||
use std::thread;
|
||||
|
||||
use crate::ComponentId;
|
||||
use crate::tmtc::{PacketSenderRaw, PacketSource};
|
||||
use crate::ComponentId;
|
||||
use thiserror::Error;
|
||||
|
||||
// Re-export the TMTC in COBS server.
|
||||
@@ -187,14 +187,14 @@ pub struct TcpTmtcGenericServer<
|
||||
}
|
||||
|
||||
impl<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = TcSendError>,
|
||||
TmSender: TcpTmSender<TmError, TcSendError>,
|
||||
TcParser: TcpTcParser<TmError, TcSendError>,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcSendError: 'static,
|
||||
>
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = TcSendError>,
|
||||
TmSender: TcpTmSender<TmError, TcSendError>,
|
||||
TcParser: TcpTcParser<TmError, TcSendError>,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcSendError: 'static,
|
||||
>
|
||||
TcpTmtcGenericServer<
|
||||
TmSource,
|
||||
TcSender,
|
||||
|
@@ -5,9 +5,9 @@ use mio::net::{TcpListener, TcpStream};
|
||||
use std::{io::Write, net::SocketAddr};
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
encoding::{ccsds::SpacePacketValidator, parse_buffer_for_ccsds_space_packets},
|
||||
tmtc::{PacketSenderRaw, PacketSource},
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
use super::tcp_server::{
|
||||
@@ -107,13 +107,13 @@ pub struct TcpSpacepacketsServer<
|
||||
}
|
||||
|
||||
impl<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = TcError>,
|
||||
Validator: SpacePacketValidator,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcError: 'static,
|
||||
> TcpSpacepacketsServer<TmSource, TcSender, Validator, HandledConnection, TmError, TcError>
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = TcError>,
|
||||
Validator: SpacePacketValidator,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcError: 'static,
|
||||
> TcpSpacepacketsServer<TmSource, TcSender, Validator, HandledConnection, TmError, TcError>
|
||||
{
|
||||
///
|
||||
/// ## Parameter
|
||||
@@ -183,30 +183,29 @@ mod tests {
|
||||
};
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use arbitrary_int::u11;
|
||||
use hashbrown::HashSet;
|
||||
use spacepackets::{
|
||||
ecss::{tc::PusTcCreator, WritablePusPacket},
|
||||
CcsdsPacket, PacketId, SpHeader,
|
||||
ecss::{CreatorConfig, WritablePusPacket, tc::PusTcCreator},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
encoding::ccsds::{SpValidity, SpacePacketValidator},
|
||||
hal::std::tcp_server::{
|
||||
ConnectionResult, ServerConfig,
|
||||
tests::{ConnectionFinishedHandler, SyncTmSource},
|
||||
ConnectionResult, ServerConfig,
|
||||
},
|
||||
queue::GenericSendError,
|
||||
tmtc::PacketAsVec,
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
use super::TcpSpacepacketsServer;
|
||||
|
||||
const TCP_SERVER_ID: ComponentId = 0x05;
|
||||
const TEST_APID_0: u11 = u11::new(0x02);
|
||||
const TEST_APID_0: u16 = 0x02;
|
||||
const TEST_PACKET_ID_0: PacketId = PacketId::new_for_tc(true, TEST_APID_0);
|
||||
const TEST_APID_1: u11 = u11::new(0x10);
|
||||
const TEST_APID_1: u16 = 0x10;
|
||||
const TEST_PACKET_ID_1: PacketId = PacketId::new_for_tc(true, TEST_APID_1);
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -284,13 +283,8 @@ mod tests {
|
||||
.check_no_connections_left();
|
||||
set_if_done.store(true, Ordering::Relaxed);
|
||||
});
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
17,
|
||||
1,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let ping_tc =
|
||||
PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 17, 1, &[], true);
|
||||
let tc_0 = ping_tc.to_vec().expect("packet generation failed");
|
||||
let mut stream = TcpStream::connect(dest_addr).expect("connecting to TCP server failed");
|
||||
stream
|
||||
@@ -320,23 +314,13 @@ mod tests {
|
||||
|
||||
// Add telemetry
|
||||
let mut total_tm_len = 0;
|
||||
let verif_tm = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
1,
|
||||
1,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let verif_tm =
|
||||
PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 1, 1, &[], true);
|
||||
let tm_0 = verif_tm.to_vec().expect("writing packet failed");
|
||||
total_tm_len += tm_0.len();
|
||||
tm_source.add_tm(&tm_0);
|
||||
let verif_tm = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_1),
|
||||
1,
|
||||
3,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let verif_tm =
|
||||
PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_1), 1, 3, &[], true);
|
||||
let tm_1 = verif_tm.to_vec().expect("writing packet failed");
|
||||
total_tm_len += tm_1.len();
|
||||
tm_source.add_tm(&tm_1);
|
||||
@@ -382,24 +366,14 @@ mod tests {
|
||||
.expect("setting reas timeout failed");
|
||||
|
||||
// Send telecommands
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
17,
|
||||
1,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let ping_tc =
|
||||
PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 17, 1, &[], true);
|
||||
let tc_0 = ping_tc.to_vec().expect("ping tc creation failed");
|
||||
stream
|
||||
.write_all(&tc_0)
|
||||
.expect("writing to TCP server failed");
|
||||
let action_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_1),
|
||||
8,
|
||||
0,
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let action_tc =
|
||||
PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_1), 8, 0, &[], true);
|
||||
let tc_1 = action_tc.to_vec().expect("action tc creation failed");
|
||||
stream
|
||||
.write_all(&tc_1)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//! Generic UDP TC server.
|
||||
use crate::ComponentId;
|
||||
use crate::tmtc::PacketSenderRaw;
|
||||
use crate::ComponentId;
|
||||
use core::fmt::Debug;
|
||||
use std::io::{self, ErrorKind};
|
||||
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
|
||||
@@ -105,7 +105,7 @@ impl<TcSender: PacketSenderRaw<Error = SendError>, SendError: Debug + 'static>
|
||||
Err(ReceiveResult::NothingReceived)
|
||||
} else {
|
||||
Err(e.into())
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
let (num_bytes, from) = res;
|
||||
@@ -123,15 +123,14 @@ impl<TcSender: PacketSenderRaw<Error = SendError>, SendError: Debug + 'static>
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ComponentId;
|
||||
use crate::hal::std::udp_server::{ReceiveResult, UdpTcServer};
|
||||
use crate::queue::GenericSendError;
|
||||
use crate::tmtc::PacketSenderRaw;
|
||||
use arbitrary_int::u11;
|
||||
use crate::ComponentId;
|
||||
use core::cell::RefCell;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::CreatorConfig;
|
||||
use spacepackets::ecss::tc::PusTcCreator;
|
||||
use spacepackets::ecss::WritablePusPacket;
|
||||
use spacepackets::SpHeader;
|
||||
use std::collections::VecDeque;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
|
||||
use std::vec::Vec;
|
||||
@@ -167,8 +166,8 @@ mod tests {
|
||||
let mut udp_tc_server = UdpTcServer::new(UDP_SERVER_ID, dest_addr, 2048, ping_receiver)
|
||||
.expect("Creating UDP TMTC server failed");
|
||||
is_send(&udp_tc_server);
|
||||
let sph = SpHeader::new_from_apid(u11::new(0x02));
|
||||
let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let sph = SpHeader::new_from_apid(0x02);
|
||||
let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
|
||||
let len = pus_tc
|
||||
.write_to_bytes(&mut buf)
|
||||
.expect("Error writing PUS TC packet");
|
||||
|
@@ -11,11 +11,11 @@ pub use alloc_mod::*;
|
||||
pub use std_mod::*;
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
queue::{GenericReceiveError, GenericSendError},
|
||||
request::{
|
||||
GenericMessage, MessageMetadata, MessageReceiverProvider, MessageReceiverWithId, RequestId,
|
||||
},
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
pub type Mode = u32;
|
||||
@@ -257,7 +257,7 @@ pub trait ModeRequestHandler: ModeProvider {
|
||||
|
||||
pub trait ModeReplyReceiver {
|
||||
fn try_recv_mode_reply(&self)
|
||||
-> Result<Option<GenericMessage<ModeReply>>, GenericReceiveError>;
|
||||
-> Result<Option<GenericMessage<ModeReply>>, GenericReceiveError>;
|
||||
}
|
||||
|
||||
impl<R: MessageReceiverProvider<ModeReply>> ModeReplyReceiver
|
||||
@@ -309,11 +309,12 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
From,
|
||||
Sender: MessageSenderProvider<ModeReply>,
|
||||
Receiver: MessageReceiverProvider<From>,
|
||||
SenderStore: MessageSenderStoreProvider<ModeReply, Sender>,
|
||||
> ModeReplySender for MessageSenderAndReceiver<ModeReply, From, Sender, Receiver, SenderStore>
|
||||
From,
|
||||
Sender: MessageSenderProvider<ModeReply>,
|
||||
Receiver: MessageReceiverProvider<From>,
|
||||
SenderStore: MessageSenderStoreProvider<ModeReply, Sender>,
|
||||
> ModeReplySender
|
||||
for MessageSenderAndReceiver<ModeReply, From, Sender, Receiver, SenderStore>
|
||||
{
|
||||
fn local_channel_id(&self) -> ComponentId {
|
||||
self.local_channel_id_generic()
|
||||
@@ -333,11 +334,12 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
To,
|
||||
Sender: MessageSenderProvider<To>,
|
||||
Receiver: MessageReceiverProvider<ModeReply>,
|
||||
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||
> ModeReplyReceiver for MessageSenderAndReceiver<To, ModeReply, Sender, Receiver, SenderStore>
|
||||
To,
|
||||
Sender: MessageSenderProvider<To>,
|
||||
Receiver: MessageReceiverProvider<ModeReply>,
|
||||
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||
> ModeReplyReceiver
|
||||
for MessageSenderAndReceiver<To, ModeReply, Sender, Receiver, SenderStore>
|
||||
{
|
||||
fn try_recv_mode_reply(
|
||||
&self,
|
||||
@@ -347,15 +349,15 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
Request,
|
||||
ReqSender: MessageSenderProvider<Request>,
|
||||
ReqReceiver: MessageReceiverProvider<Request>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
>
|
||||
Request,
|
||||
ReqSender: MessageSenderProvider<Request>,
|
||||
ReqReceiver: MessageReceiverProvider<Request>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
>
|
||||
RequestAndReplySenderAndReceiver<
|
||||
Request,
|
||||
ReqSender,
|
||||
@@ -374,14 +376,14 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
Request,
|
||||
ReqSender: MessageSenderProvider<Request>,
|
||||
ReqReceiver: MessageReceiverProvider<Request>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||
ReplySender: MessageSenderProvider<ModeReply>,
|
||||
ReplyReceiver: MessageReceiverProvider<ModeReply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<ModeReply, ReplySender>,
|
||||
> ModeReplySender
|
||||
Request,
|
||||
ReqSender: MessageSenderProvider<Request>,
|
||||
ReqReceiver: MessageReceiverProvider<Request>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||
ReplySender: MessageSenderProvider<ModeReply>,
|
||||
ReplyReceiver: MessageReceiverProvider<ModeReply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<ModeReply, ReplySender>,
|
||||
> ModeReplySender
|
||||
for RequestAndReplySenderAndReceiver<
|
||||
Request,
|
||||
ReqSender,
|
||||
@@ -411,14 +413,14 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
Request,
|
||||
ReqSender: MessageSenderProvider<Request>,
|
||||
ReqReceiver: MessageReceiverProvider<Request>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||
ReplySender: MessageSenderProvider<ModeReply>,
|
||||
ReplyReceiver: MessageReceiverProvider<ModeReply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<ModeReply, ReplySender>,
|
||||
> ModeReplyReceiver
|
||||
Request,
|
||||
ReqSender: MessageSenderProvider<Request>,
|
||||
ReqReceiver: MessageReceiverProvider<Request>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||
ReplySender: MessageSenderProvider<ModeReply>,
|
||||
ReplyReceiver: MessageReceiverProvider<ModeReply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<ModeReply, ReplySender>,
|
||||
> ModeReplyReceiver
|
||||
for RequestAndReplySenderAndReceiver<
|
||||
Request,
|
||||
ReqSender,
|
||||
@@ -442,10 +444,10 @@ pub mod alloc_mod {
|
||||
MessageSenderAndReceiver<ModeReply, ModeRequest, Sender, Receiver, ReplySenderStore>;
|
||||
|
||||
impl<
|
||||
Sender: MessageSenderProvider<ModeReply>,
|
||||
Receiver: MessageReceiverProvider<ModeRequest>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<ModeReply, Sender>,
|
||||
> ModeRequestHandlerInterface<Sender, Receiver, ReplySenderStore>
|
||||
Sender: MessageSenderProvider<ModeReply>,
|
||||
Receiver: MessageReceiverProvider<ModeRequest>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<ModeReply, Sender>,
|
||||
> ModeRequestHandlerInterface<Sender, Receiver, ReplySenderStore>
|
||||
{
|
||||
pub fn try_recv_mode_request(
|
||||
&self,
|
||||
@@ -472,10 +474,10 @@ pub mod alloc_mod {
|
||||
MessageSenderAndReceiver<ModeRequest, ModeReply, Sender, Receiver, RequestSenderStore>;
|
||||
|
||||
impl<
|
||||
Sender: MessageSenderProvider<ModeRequest>,
|
||||
Receiver: MessageReceiverProvider<ModeReply>,
|
||||
RequestSenderStore: MessageSenderStoreProvider<ModeRequest, Sender>,
|
||||
> ModeRequestorInterface<Sender, Receiver, RequestSenderStore>
|
||||
Sender: MessageSenderProvider<ModeRequest>,
|
||||
Receiver: MessageReceiverProvider<ModeReply>,
|
||||
RequestSenderStore: MessageSenderStoreProvider<ModeRequest, Sender>,
|
||||
> ModeRequestorInterface<Sender, Receiver, RequestSenderStore>
|
||||
{
|
||||
pub fn try_recv_mode_reply(
|
||||
&self,
|
||||
@@ -529,11 +531,11 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
To,
|
||||
Sender: MessageSenderProvider<To>,
|
||||
Receiver: MessageReceiverProvider<ModeRequest>,
|
||||
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||
> ModeRequestReceiver
|
||||
To,
|
||||
Sender: MessageSenderProvider<To>,
|
||||
Receiver: MessageReceiverProvider<ModeRequest>,
|
||||
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||
> ModeRequestReceiver
|
||||
for MessageSenderAndReceiver<To, ModeRequest, Sender, Receiver, SenderStore>
|
||||
{
|
||||
fn try_recv_mode_request(
|
||||
@@ -544,11 +546,11 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
From,
|
||||
Sender: MessageSenderProvider<ModeRequest>,
|
||||
Receiver: MessageReceiverProvider<From>,
|
||||
SenderStore: MessageSenderStoreProvider<ModeRequest, Sender>,
|
||||
> ModeRequestSender
|
||||
From,
|
||||
Sender: MessageSenderProvider<ModeRequest>,
|
||||
Receiver: MessageReceiverProvider<From>,
|
||||
SenderStore: MessageSenderStoreProvider<ModeRequest, Sender>,
|
||||
> ModeRequestSender
|
||||
for MessageSenderAndReceiver<ModeRequest, From, Sender, Receiver, SenderStore>
|
||||
{
|
||||
fn local_channel_id(&self) -> ComponentId {
|
||||
@@ -570,14 +572,14 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
>
|
||||
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
>
|
||||
RequestAndReplySenderAndReceiver<
|
||||
ModeRequest,
|
||||
ReqSender,
|
||||
@@ -596,14 +598,14 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
> ModeRequestSender
|
||||
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
> ModeRequestSender
|
||||
for RequestAndReplySenderAndReceiver<
|
||||
ModeRequest,
|
||||
ReqSender,
|
||||
@@ -634,14 +636,14 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
> ModeRequestReceiver
|
||||
ReqSender: MessageSenderProvider<ModeRequest>,
|
||||
ReqReceiver: MessageReceiverProvider<ModeRequest>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<ModeRequest, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
> ModeRequestReceiver
|
||||
for RequestAndReplySenderAndReceiver<
|
||||
ModeRequest,
|
||||
ReqSender,
|
||||
@@ -724,7 +726,7 @@ pub(crate) mod tests {
|
||||
use core::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use crate::{ComponentId, request::RequestId};
|
||||
use crate::{request::RequestId, ComponentId};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@@ -2,9 +2,9 @@ use alloc::vec::Vec;
|
||||
use hashbrown::HashMap;
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, Submode},
|
||||
request::MessageSenderProvider,
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
|
@@ -47,10 +47,10 @@ use crate::pool::PoolAddr;
|
||||
use core::fmt::Debug;
|
||||
use core::mem::size_of;
|
||||
use paste::paste;
|
||||
use spacepackets::ByteConversionError;
|
||||
use spacepackets::ecss::{EcssEnumU8, EcssEnumU16, EcssEnumU32, EcssEnumU64};
|
||||
use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU64, EcssEnumU8};
|
||||
pub use spacepackets::util::ToBeBytes;
|
||||
use spacepackets::util::UnsignedEnum;
|
||||
use spacepackets::ByteConversionError;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::string::{String, ToString};
|
||||
|
@@ -222,7 +222,7 @@ impl Error for PoolError {
|
||||
}
|
||||
}
|
||||
|
||||
/// Generic trait for pool providers which provide memory pools for variable sized packet data.
|
||||
/// Generic trait for pool providers which provide memory pools for variable sized data.
|
||||
///
|
||||
/// It specifies a basic API to [Self::add], [Self::modify], [Self::read] and [Self::delete] data
|
||||
/// in the store at its core. The API was designed so internal optimizations can be performed
|
||||
@@ -250,7 +250,7 @@ pub trait PoolProvider {
|
||||
/// call the user-provided closure and pass a mutable reference to the memory block
|
||||
/// to the closure. This allows the user to modify the memory block.
|
||||
fn modify<U: FnMut(&mut [u8])>(&mut self, addr: &PoolAddr, updater: U)
|
||||
-> Result<(), PoolError>;
|
||||
-> Result<(), PoolError>;
|
||||
|
||||
/// The provider should copy the data from the memory block to the user-provided buffer if
|
||||
/// it exists.
|
||||
@@ -281,7 +281,7 @@ pub trait PoolProviderWithGuards: PoolProvider {
|
||||
/// This can prevent memory leaks. Users can read the data and release the guard
|
||||
/// if the data in the store is valid for further processing. If the data is faulty, no
|
||||
/// manual deletion is necessary when returning from a processing function prematurely.
|
||||
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<'_, Self>;
|
||||
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<Self>;
|
||||
|
||||
/// This function behaves like [PoolProvider::modify], but consumes the provided
|
||||
/// address and returns a RAII conformant guard object.
|
||||
@@ -291,7 +291,7 @@ pub trait PoolProviderWithGuards: PoolProvider {
|
||||
/// This can prevent memory leaks. Users can read (and modify) the data and release the guard
|
||||
/// if the data in the store is valid for further processing. If the data is faulty, no
|
||||
/// manual deletion is necessary when returning from a processing function prematurely.
|
||||
fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<'_, Self>;
|
||||
fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<Self>;
|
||||
}
|
||||
|
||||
pub struct PoolGuard<'a, MemProvider: PoolProvider + ?Sized> {
|
||||
@@ -510,11 +510,11 @@ pub mod heapless_mod {
|
||||
///
|
||||
/// * `subpool_memory` - Static memory for a particular subpool to store the actual data.
|
||||
/// * `sizes_list` - Static sizes list structure to store the size of the data which is
|
||||
/// actually stored.
|
||||
/// actually stored.
|
||||
/// * `num_blocks ` - The number of memory blocks inside the subpool.
|
||||
/// * `set_sizes_list_to_all_free` - If this is set to true, the method will take care
|
||||
/// of setting all values in the sizes list to [super::STORE_FREE]. This does not have
|
||||
/// to be done if the user initializes the sizes list to that value themselves.
|
||||
/// of setting all values in the sizes list to [super::STORE_FREE]. This does not have
|
||||
/// to be done if the user initializes the sizes list to that value themselves.
|
||||
pub fn grow(
|
||||
&mut self,
|
||||
subpool_memory: &'static mut [u8],
|
||||
@@ -602,7 +602,7 @@ pub mod heapless_mod {
|
||||
if i < start_at_subpool as usize {
|
||||
continue;
|
||||
}
|
||||
if pool_cfg.block_size >= req_size {
|
||||
if pool_cfg.block_size as usize >= req_size {
|
||||
return Ok(i as u16);
|
||||
}
|
||||
}
|
||||
@@ -638,7 +638,7 @@ pub mod heapless_mod {
|
||||
|
||||
fn raw_pos(&self, addr: &StaticPoolAddr) -> Option<usize> {
|
||||
let (pool_cfg, _) = self.pool.get(addr.pool_idx as usize)?;
|
||||
Some(addr.packet_idx as usize * pool_cfg.block_size)
|
||||
Some(addr.packet_idx as usize * pool_cfg.block_size as usize)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -707,7 +707,7 @@ pub mod heapless_mod {
|
||||
let subpool_cfg = self.pool.get(addr.pool_idx as usize).unwrap().0;
|
||||
let raw_pos = self.raw_pos(&addr).unwrap();
|
||||
let block = &mut self.pool.get_mut(addr.pool_idx as usize).unwrap().1
|
||||
[raw_pos..raw_pos + subpool_cfg.block_size];
|
||||
[raw_pos..raw_pos + subpool_cfg.block_size as usize];
|
||||
let size_list = self.sizes_lists.get_mut(addr.pool_idx as usize).unwrap();
|
||||
size_list[addr.packet_idx as usize] = STORE_FREE;
|
||||
block.fill(0);
|
||||
@@ -742,11 +742,11 @@ pub mod heapless_mod {
|
||||
impl<const MAX_NUM_SUBPOOLS: usize> PoolProviderWithGuards
|
||||
for StaticHeaplessMemoryPool<MAX_NUM_SUBPOOLS>
|
||||
{
|
||||
fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<'_, Self> {
|
||||
fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<Self> {
|
||||
PoolRwGuard::new(self, addr)
|
||||
}
|
||||
|
||||
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<'_, Self> {
|
||||
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<Self> {
|
||||
PoolGuard::new(self, addr)
|
||||
}
|
||||
}
|
||||
@@ -1058,11 +1058,11 @@ mod alloc_mod {
|
||||
}
|
||||
|
||||
impl PoolProviderWithGuards for StaticMemoryPool {
|
||||
fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<'_, Self> {
|
||||
fn modify_with_guard(&mut self, addr: PoolAddr) -> PoolRwGuard<Self> {
|
||||
PoolRwGuard::new(self, addr)
|
||||
}
|
||||
|
||||
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<'_, Self> {
|
||||
fn read_with_guard(&mut self, addr: PoolAddr) -> PoolGuard<Self> {
|
||||
PoolGuard::new(self, addr)
|
||||
}
|
||||
}
|
||||
@@ -1307,11 +1307,9 @@ mod tests {
|
||||
let addr = pool_provider.add(&test_buf).expect("Adding data failed");
|
||||
let read_guard = PoolGuard::new(pool_provider, addr);
|
||||
drop(read_guard);
|
||||
assert!(
|
||||
!pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address")
|
||||
);
|
||||
assert!(!pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address"));
|
||||
}
|
||||
|
||||
fn generic_test_pool_guard_deletion(pool_provider: &mut impl PoolProviderWithGuards) {
|
||||
@@ -1319,11 +1317,9 @@ mod tests {
|
||||
let addr = pool_provider.add(&test_buf).expect("Adding data failed");
|
||||
let read_guard = pool_provider.read_with_guard(addr);
|
||||
drop(read_guard);
|
||||
assert!(
|
||||
!pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address")
|
||||
);
|
||||
assert!(!pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address"));
|
||||
}
|
||||
|
||||
fn generic_test_pool_guard_with_release(pool_provider: &mut impl PoolProviderWithGuards) {
|
||||
@@ -1332,11 +1328,9 @@ mod tests {
|
||||
let mut read_guard = PoolGuard::new(pool_provider, addr);
|
||||
read_guard.release();
|
||||
drop(read_guard);
|
||||
assert!(
|
||||
pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address")
|
||||
);
|
||||
assert!(pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address"));
|
||||
}
|
||||
|
||||
fn generic_test_pool_modify_guard_man_creation(
|
||||
@@ -1347,11 +1341,9 @@ mod tests {
|
||||
let mut rw_guard = PoolRwGuard::new(pool_provider, addr);
|
||||
rw_guard.update(&mut |_| {}).expect("modify failed");
|
||||
drop(rw_guard);
|
||||
assert!(
|
||||
!pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address")
|
||||
);
|
||||
assert!(!pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address"));
|
||||
}
|
||||
|
||||
fn generic_test_pool_modify_guard(pool_provider: &mut impl PoolProviderWithGuards) {
|
||||
@@ -1360,11 +1352,9 @@ mod tests {
|
||||
let mut rw_guard = pool_provider.modify_with_guard(addr);
|
||||
rw_guard.update(&mut |_| {}).expect("modify failed");
|
||||
drop(rw_guard);
|
||||
assert!(
|
||||
!pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address")
|
||||
);
|
||||
assert!(!pool_provider
|
||||
.has_element_at(&addr)
|
||||
.expect("Invalid address"));
|
||||
}
|
||||
|
||||
fn generic_modify_pool_index_above_0(pool_provider: &mut impl PoolProvider) {
|
||||
@@ -1664,36 +1654,30 @@ mod tests {
|
||||
fn small_heapless_pool() -> StaticHeaplessMemoryPool<3> {
|
||||
let mut heapless_pool: StaticHeaplessMemoryPool<3> =
|
||||
StaticHeaplessMemoryPool::new(false);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_1.take(),
|
||||
unsafe { &mut *SUBPOOL_1_SIZES.lock().unwrap().get() },
|
||||
SUBPOOL_1_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_2.take(),
|
||||
SUBPOOL_2_SIZES.take(),
|
||||
SUBPOOL_2_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_3.take(),
|
||||
SUBPOOL_3_SIZES.take(),
|
||||
SUBPOOL_3_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_1.take(),
|
||||
unsafe { &mut *SUBPOOL_1_SIZES.lock().unwrap().get() },
|
||||
SUBPOOL_1_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_2.take(),
|
||||
SUBPOOL_2_SIZES.take(),
|
||||
SUBPOOL_2_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_3.take(),
|
||||
SUBPOOL_3_SIZES.take(),
|
||||
SUBPOOL_3_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
heapless_pool
|
||||
}
|
||||
|
||||
@@ -1809,26 +1793,22 @@ mod tests {
|
||||
fn test_spills_to_higher_subpools() {
|
||||
let mut heapless_pool: StaticHeaplessMemoryPool<2> =
|
||||
StaticHeaplessMemoryPool::new(true);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_2.take(),
|
||||
SUBPOOL_2_SIZES.take(),
|
||||
SUBPOOL_2_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_4.take(),
|
||||
SUBPOOL_4_SIZES.take(),
|
||||
SUBPOOL_4_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_2.take(),
|
||||
SUBPOOL_2_SIZES.take(),
|
||||
SUBPOOL_2_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_4.take(),
|
||||
SUBPOOL_4_SIZES.take(),
|
||||
SUBPOOL_4_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
generic_test_spills_to_higher_subpools(&mut heapless_pool);
|
||||
}
|
||||
|
||||
@@ -1836,26 +1816,22 @@ mod tests {
|
||||
fn test_spillage_fails_as_well() {
|
||||
let mut heapless_pool: StaticHeaplessMemoryPool<2> =
|
||||
StaticHeaplessMemoryPool::new(true);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_5.take(),
|
||||
SUBPOOL_5_SIZES.take(),
|
||||
SUBPOOL_5_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_3.take(),
|
||||
SUBPOOL_3_SIZES.take(),
|
||||
SUBPOOL_3_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_5.take(),
|
||||
SUBPOOL_5_SIZES.take(),
|
||||
SUBPOOL_5_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_3.take(),
|
||||
SUBPOOL_3_SIZES.take(),
|
||||
SUBPOOL_3_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
generic_test_spillage_fails_as_well(&mut heapless_pool);
|
||||
}
|
||||
|
||||
@@ -1863,36 +1839,30 @@ mod tests {
|
||||
fn test_spillage_works_across_multiple_subpools() {
|
||||
let mut heapless_pool: StaticHeaplessMemoryPool<3> =
|
||||
StaticHeaplessMemoryPool::new(true);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_5.take(),
|
||||
SUBPOOL_5_SIZES.take(),
|
||||
SUBPOOL_5_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_6.take(),
|
||||
SUBPOOL_6_SIZES.take(),
|
||||
SUBPOOL_6_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_3.take(),
|
||||
SUBPOOL_3_SIZES.take(),
|
||||
SUBPOOL_3_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_5.take(),
|
||||
SUBPOOL_5_SIZES.take(),
|
||||
SUBPOOL_5_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_6.take(),
|
||||
SUBPOOL_6_SIZES.take(),
|
||||
SUBPOOL_6_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_3.take(),
|
||||
SUBPOOL_3_SIZES.take(),
|
||||
SUBPOOL_3_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
generic_test_spillage_works_across_multiple_subpools(&mut heapless_pool);
|
||||
}
|
||||
|
||||
@@ -1900,36 +1870,30 @@ mod tests {
|
||||
fn test_spillage_fails_across_multiple_subpools() {
|
||||
let mut heapless_pool: StaticHeaplessMemoryPool<3> =
|
||||
StaticHeaplessMemoryPool::new(true);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_5.take(),
|
||||
SUBPOOL_5_SIZES.take(),
|
||||
SUBPOOL_5_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_6.take(),
|
||||
SUBPOOL_6_SIZES.take(),
|
||||
SUBPOOL_6_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(
|
||||
heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_3.take(),
|
||||
SUBPOOL_3_SIZES.take(),
|
||||
SUBPOOL_3_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok()
|
||||
);
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_5.take(),
|
||||
SUBPOOL_5_SIZES.take(),
|
||||
SUBPOOL_5_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_6.take(),
|
||||
SUBPOOL_6_SIZES.take(),
|
||||
SUBPOOL_6_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
assert!(heapless_pool
|
||||
.grow(
|
||||
SUBPOOL_3.take(),
|
||||
SUBPOOL_3_SIZES.take(),
|
||||
SUBPOOL_3_NUM_ELEMENTS,
|
||||
true
|
||||
)
|
||||
.is_ok());
|
||||
generic_test_spillage_fails_across_multiple_subpools(&mut heapless_pool);
|
||||
}
|
||||
}
|
||||
|
@@ -190,7 +190,7 @@ mod tests {
|
||||
|
||||
use std::sync::mpsc::{self, TryRecvError};
|
||||
|
||||
use crate::{ComponentId, queue::GenericSendError, request::GenericMessage};
|
||||
use crate::{queue::GenericSendError, request::GenericMessage, ComponentId};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
@@ -65,13 +65,13 @@ impl GenericActionReplyPus {
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod alloc_mod {
|
||||
use crate::{
|
||||
ComponentId,
|
||||
action::ActionRequest,
|
||||
queue::{GenericReceiveError, GenericSendError},
|
||||
request::{
|
||||
GenericMessage, MessageReceiverProvider, MessageSenderAndReceiver,
|
||||
MessageSenderProvider, MessageSenderStoreProvider, RequestId,
|
||||
},
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
use super::ActionReplyPus;
|
||||
@@ -81,10 +81,10 @@ pub mod alloc_mod {
|
||||
MessageSenderAndReceiver<ActionReplyPus, ActionRequest, Sender, Receiver, ReplySenderStore>;
|
||||
|
||||
impl<
|
||||
Sender: MessageSenderProvider<ActionReplyPus>,
|
||||
Receiver: MessageReceiverProvider<ActionRequest>,
|
||||
ReplySender: MessageSenderStoreProvider<ActionReplyPus, Sender>,
|
||||
> ActionRequestHandlerInterface<Sender, Receiver, ReplySender>
|
||||
Sender: MessageSenderProvider<ActionReplyPus>,
|
||||
Receiver: MessageReceiverProvider<ActionRequest>,
|
||||
ReplySender: MessageSenderStoreProvider<ActionReplyPus, Sender>,
|
||||
> ActionRequestHandlerInterface<Sender, Receiver, ReplySender>
|
||||
{
|
||||
pub fn try_recv_action_request(
|
||||
&self,
|
||||
@@ -114,10 +114,10 @@ pub mod alloc_mod {
|
||||
>;
|
||||
|
||||
impl<
|
||||
Sender: MessageSenderProvider<ActionRequest>,
|
||||
Receiver: MessageReceiverProvider<ActionReplyPus>,
|
||||
RequestSenderStore: MessageSenderStoreProvider<ActionRequest, Sender>,
|
||||
> ActionRequestorInterface<Sender, Receiver, RequestSenderStore>
|
||||
Sender: MessageSenderProvider<ActionRequest>,
|
||||
Receiver: MessageReceiverProvider<ActionReplyPus>,
|
||||
RequestSenderStore: MessageSenderStoreProvider<ActionRequest, Sender>,
|
||||
> ActionRequestorInterface<Sender, Receiver, RequestSenderStore>
|
||||
{
|
||||
pub fn try_recv_action_reply(
|
||||
&self,
|
||||
@@ -141,12 +141,12 @@ pub mod std_mod {
|
||||
use std::sync::mpsc;
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
pus::{
|
||||
ActivePusRequestStd, ActiveRequest, DefaultActiveRequestMap,
|
||||
verification::{self, TcStateToken},
|
||||
ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap,
|
||||
},
|
||||
request::{MessageSenderMap, OneMessageSender},
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
@@ -157,7 +157,7 @@ pub mod std_mod {
|
||||
common: ActivePusRequestStd,
|
||||
}
|
||||
|
||||
impl ActiveRequest for ActivePusActionRequestStd {
|
||||
impl ActiveRequestProvider for ActivePusActionRequestStd {
|
||||
delegate::delegate! {
|
||||
to self.common {
|
||||
fn target_id(&self) -> ComponentId;
|
||||
|
@@ -1,9 +1,9 @@
|
||||
use crate::pus::source_buffer_large_enough;
|
||||
use arbitrary_int::u11;
|
||||
use spacepackets::ecss::tm::PusTmCreator;
|
||||
use spacepackets::ecss::tm::PusTmSecondaryHeader;
|
||||
use spacepackets::ecss::EcssEnumeration;
|
||||
use spacepackets::ByteConversionError;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use spacepackets::ecss::{CreatorConfig, EcssEnumeration};
|
||||
use spacepackets::{SpHeader, MAX_APID};
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub use alloc_mod::*;
|
||||
@@ -11,13 +11,16 @@ pub use alloc_mod::*;
|
||||
pub use spacepackets::ecss::event::*;
|
||||
|
||||
pub struct EventReportCreator {
|
||||
apid: u11,
|
||||
apid: u16,
|
||||
pub dest_id: u16,
|
||||
}
|
||||
|
||||
impl EventReportCreator {
|
||||
pub fn new(apid: u11, dest_id: u16) -> Self {
|
||||
Self { dest_id, apid }
|
||||
pub fn new(apid: u16, dest_id: u16) -> Option<Self> {
|
||||
if apid > MAX_APID {
|
||||
return None;
|
||||
}
|
||||
Some(Self { dest_id, apid })
|
||||
}
|
||||
|
||||
pub fn event_info<'time, 'src_data>(
|
||||
@@ -121,7 +124,7 @@ impl EventReportCreator {
|
||||
SpHeader::new_from_apid(self.apid),
|
||||
sec_header,
|
||||
&src_data_buf[0..current_idx],
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -129,41 +132,41 @@ impl EventReportCreator {
|
||||
#[cfg(feature = "alloc")]
|
||||
mod alloc_mod {
|
||||
use super::*;
|
||||
use crate::ComponentId;
|
||||
use crate::pus::{EcssTmSender, EcssTmtcError};
|
||||
use crate::ComponentId;
|
||||
use alloc::vec;
|
||||
use alloc::vec::Vec;
|
||||
use core::cell::RefCell;
|
||||
use spacepackets::ecss::PusError;
|
||||
|
||||
pub trait EventTmHook {
|
||||
pub trait EventTmHookProvider {
|
||||
fn modify_tm(&self, tm: &mut PusTmCreator);
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DummyEventHook {}
|
||||
|
||||
impl EventTmHook for DummyEventHook {
|
||||
impl EventTmHookProvider for DummyEventHook {
|
||||
fn modify_tm(&self, _tm: &mut PusTmCreator) {}
|
||||
}
|
||||
|
||||
pub struct EventReporter<EventTmHookInstance: EventTmHook = DummyEventHook> {
|
||||
pub struct EventReporter<EventTmHook: EventTmHookProvider = DummyEventHook> {
|
||||
id: ComponentId,
|
||||
// Use interior mutability pattern here. This is just an intermediate buffer to the PUS event packet
|
||||
// generation.
|
||||
source_data_buf: RefCell<Vec<u8>>,
|
||||
pub report_creator: EventReportCreator,
|
||||
pub tm_hook: EventTmHookInstance,
|
||||
pub tm_hook: EventTmHook,
|
||||
}
|
||||
|
||||
impl EventReporter<DummyEventHook> {
|
||||
pub fn new(
|
||||
id: ComponentId,
|
||||
default_apid: u11,
|
||||
default_apid: u16,
|
||||
default_dest_id: u16,
|
||||
max_event_id_and_aux_data_size: usize,
|
||||
) -> Option<Self> {
|
||||
let reporter = EventReportCreator::new(default_apid, default_dest_id);
|
||||
let reporter = EventReportCreator::new(default_apid, default_dest_id)?;
|
||||
Some(Self {
|
||||
id,
|
||||
source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]),
|
||||
@@ -172,15 +175,15 @@ mod alloc_mod {
|
||||
})
|
||||
}
|
||||
}
|
||||
impl<EventTmHookInstance: EventTmHook> EventReporter<EventTmHookInstance> {
|
||||
impl<EventTmHook: EventTmHookProvider> EventReporter<EventTmHook> {
|
||||
pub fn new_with_hook(
|
||||
id: ComponentId,
|
||||
default_apid: u11,
|
||||
default_apid: u16,
|
||||
default_dest_id: u16,
|
||||
max_event_id_and_aux_data_size: usize,
|
||||
tm_hook: EventTmHookInstance,
|
||||
tm_hook: EventTmHook,
|
||||
) -> Option<Self> {
|
||||
let reporter = EventReportCreator::new(default_apid, default_dest_id);
|
||||
let reporter = EventReportCreator::new(default_apid, default_dest_id)?;
|
||||
Some(Self {
|
||||
id,
|
||||
source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]),
|
||||
@@ -262,18 +265,18 @@ mod alloc_mod {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::ComponentId;
|
||||
use crate::events::{EventU32, Severity};
|
||||
use crate::pus::test_util::TEST_COMPONENT_ID_0;
|
||||
use crate::pus::tests::CommonTmInfo;
|
||||
use crate::pus::{ChannelWithId, EcssTmSender, EcssTmtcError, PusTmVariant};
|
||||
use spacepackets::ByteConversionError;
|
||||
use crate::ComponentId;
|
||||
use spacepackets::ecss::PusError;
|
||||
use spacepackets::ByteConversionError;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::vec::Vec;
|
||||
|
||||
const EXAMPLE_APID: u11 = u11::new(0xee);
|
||||
const EXAMPLE_APID: u16 = 0xee;
|
||||
const EXAMPLE_GROUP_ID: u16 = 2;
|
||||
const EXAMPLE_EVENT_ID_0: u16 = 1;
|
||||
#[allow(dead_code)]
|
||||
|
@@ -6,13 +6,13 @@ use core::hash::Hash;
|
||||
#[cfg(feature = "alloc")]
|
||||
use hashbrown::HashSet;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::pus::EcssTmSender;
|
||||
use crate::pus::EcssTmtcError;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub use crate::pus::event::EventReporter;
|
||||
use crate::pus::verification::TcStateToken;
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::pus::EcssTmSender;
|
||||
use crate::pus::EcssTmtcError;
|
||||
#[cfg(feature = "alloc")]
|
||||
pub use alloc_mod::*;
|
||||
#[cfg(feature = "heapless")]
|
||||
pub use heapless_mod::*;
|
||||
@@ -46,7 +46,7 @@ pub mod heapless_mod {
|
||||
// regular Event type again.
|
||||
#[derive(Default)]
|
||||
pub struct HeaplessPusMgmtBackendProvider<const N: usize, Provider: GenericEvent> {
|
||||
disabled: heapless::index_set::FnvIndexSet<LargestEventRaw, N>,
|
||||
disabled: heapless::FnvIndexSet<LargestEventRaw, N>,
|
||||
phantom: PhantomData<Provider>,
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ pub mod alloc_mod {
|
||||
use crate::{
|
||||
events::EventU16,
|
||||
params::{Params, WritableToBeBytes},
|
||||
pus::event::{DummyEventHook, EventTmHook},
|
||||
pus::event::{DummyEventHook, EventTmHookProvider},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
@@ -151,20 +151,20 @@ pub mod alloc_mod {
|
||||
pub struct PusEventTmCreatorWithMap<
|
||||
ReportingMap: PusEventReportingMapProvider<Event>,
|
||||
Event: GenericEvent,
|
||||
EventTmHookInstance: EventTmHook = DummyEventHook,
|
||||
EventTmHook: EventTmHookProvider = DummyEventHook,
|
||||
> {
|
||||
pub reporter: EventReporter<EventTmHookInstance>,
|
||||
pub reporter: EventReporter<EventTmHook>,
|
||||
reporting_map: ReportingMap,
|
||||
phantom: PhantomData<Event>,
|
||||
}
|
||||
|
||||
impl<
|
||||
ReportingMap: PusEventReportingMapProvider<Event>,
|
||||
Event: GenericEvent,
|
||||
EventTmHookInstance: EventTmHook,
|
||||
> PusEventTmCreatorWithMap<ReportingMap, Event, EventTmHookInstance>
|
||||
ReportingMap: PusEventReportingMapProvider<Event>,
|
||||
Event: GenericEvent,
|
||||
EventTmHook: EventTmHookProvider,
|
||||
> PusEventTmCreatorWithMap<ReportingMap, Event, EventTmHook>
|
||||
{
|
||||
pub fn new(reporter: EventReporter<EventTmHookInstance>, backend: ReportingMap) -> Self {
|
||||
pub fn new(reporter: EventReporter<EventTmHook>, backend: ReportingMap) -> Self {
|
||||
Self {
|
||||
reporter,
|
||||
reporting_map: backend,
|
||||
@@ -262,10 +262,10 @@ pub mod alloc_mod {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Event: GenericEvent + Copy + PartialEq + Eq + Hash, EventTmHookInstance: EventTmHook>
|
||||
PusEventTmCreatorWithMap<DefaultPusEventReportingMap<Event>, Event, EventTmHookInstance>
|
||||
impl<Event: GenericEvent + Copy + PartialEq + Eq + Hash, EventTmHook: EventTmHookProvider>
|
||||
PusEventTmCreatorWithMap<DefaultPusEventReportingMap<Event>, Event, EventTmHook>
|
||||
{
|
||||
pub fn new_with_default_backend(reporter: EventReporter<EventTmHookInstance>) -> Self {
|
||||
pub fn new_with_default_backend(reporter: EventReporter<EventTmHook>) -> Self {
|
||||
Self {
|
||||
reporter,
|
||||
reporting_map: DefaultPusEventReportingMap::default(),
|
||||
@@ -311,10 +311,9 @@ pub mod alloc_mod {
|
||||
mod tests {
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::vec;
|
||||
use arbitrary_int::u11;
|
||||
use spacepackets::ecss::PusPacket;
|
||||
use spacepackets::ecss::event::Subservice;
|
||||
use spacepackets::ecss::tm::PusTmReader;
|
||||
use spacepackets::ecss::PusPacket;
|
||||
|
||||
use super::*;
|
||||
use crate::request::UniqueApidTargetId;
|
||||
@@ -324,7 +323,7 @@ mod tests {
|
||||
const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::<SeverityInfo>::new(1, 0);
|
||||
const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5);
|
||||
const EMPTY_STAMP: [u8; 7] = [0; 7];
|
||||
const TEST_APID: u11 = u11::new(0x02);
|
||||
const TEST_APID: u16 = 0x02;
|
||||
const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
|
||||
|
||||
fn create_basic_man_1() -> DefaultPusEventU32TmCreator {
|
||||
|
@@ -3,20 +3,20 @@ use crate::pus::event_man::{EventRequest, EventRequestWithToken};
|
||||
use crate::pus::verification::TcStateToken;
|
||||
use crate::pus::{DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError};
|
||||
use crate::queue::GenericSendError;
|
||||
use spacepackets::ecss::PusPacket;
|
||||
use spacepackets::ecss::event::Subservice;
|
||||
use spacepackets::ecss::PusPacket;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use super::verification::VerificationReportingProvider;
|
||||
use super::{
|
||||
CacheAndReadRawEcssTc, EcssTcReceiver, EcssTmSender, GenericConversionError,
|
||||
EcssTcInMemConversionProvider, EcssTcReceiver, EcssTmSender, GenericConversionError,
|
||||
GenericRoutingError, HandlingStatus, PusServiceHelper,
|
||||
};
|
||||
|
||||
pub struct PusEventServiceHandler<
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: CacheAndReadRawEcssTc,
|
||||
TcInMemConverter: EcssTcInMemConversionProvider,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> {
|
||||
pub service_helper:
|
||||
@@ -25,11 +25,11 @@ pub struct PusEventServiceHandler<
|
||||
}
|
||||
|
||||
impl<
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: CacheAndReadRawEcssTc,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> PusEventServiceHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: EcssTcInMemConversionProvider,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> PusEventServiceHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||
{
|
||||
pub fn new(
|
||||
service_helper: PusServiceHelper<
|
||||
@@ -122,7 +122,7 @@ impl<
|
||||
| Subservice::TmHighSeverityReport => {
|
||||
return Err(PusPacketHandlingError::RequestConversion(
|
||||
GenericConversionError::WrongService(tc.subservice()),
|
||||
));
|
||||
))
|
||||
}
|
||||
Subservice::TcEnableEventGeneration => {
|
||||
handle_enable_disable_request(true)?;
|
||||
@@ -144,19 +144,16 @@ impl<
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use arbitrary_int::traits::Integer as _;
|
||||
use arbitrary_int::u14;
|
||||
use delegate::delegate;
|
||||
use spacepackets::ecss::CreatorConfig;
|
||||
use spacepackets::ecss::event::Subservice;
|
||||
use spacepackets::time::{TimeWriter, cds};
|
||||
use spacepackets::time::{cds, TimeWriter};
|
||||
use spacepackets::util::UnsignedEnum;
|
||||
use spacepackets::{
|
||||
SpHeader,
|
||||
ecss::{
|
||||
tc::{PusTcCreator, PusTcSecondaryHeader},
|
||||
tm::PusTmReader,
|
||||
},
|
||||
SpHeader,
|
||||
};
|
||||
use std::sync::mpsc::{self, Sender};
|
||||
|
||||
@@ -170,10 +167,10 @@ mod tests {
|
||||
use crate::{
|
||||
events::EventU32,
|
||||
pus::{
|
||||
DirectPusPacketHandlerResult, EcssTcInSharedPoolCacher, PusPacketHandlingError,
|
||||
event_man::EventRequestWithToken,
|
||||
tests::PusServiceHandlerWithSharedStoreCommon,
|
||||
verification::{TcStateAccepted, VerificationToken},
|
||||
DirectPusPacketHandlerResult, EcssTcInSharedPoolConverter, PusPacketHandlingError,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -186,7 +183,7 @@ mod tests {
|
||||
handler: PusEventServiceHandler<
|
||||
MpscTcReceiver,
|
||||
PacketSenderWithSharedPool,
|
||||
EcssTcInSharedPoolCacher,
|
||||
EcssTcInSharedPoolConverter,
|
||||
VerificationReporter,
|
||||
>,
|
||||
}
|
||||
@@ -245,13 +242,13 @@ mod tests {
|
||||
expected_event_req: EventRequest,
|
||||
event_req_receiver: mpsc::Receiver<EventRequestWithToken>,
|
||||
) {
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(5, subservice as u8);
|
||||
let mut app_data = [0; 4];
|
||||
TEST_EVENT_0
|
||||
.write_to_be_bytes(&mut app_data)
|
||||
.expect("writing test event failed");
|
||||
let ping_tc = PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new(sp_header, sec_header, &app_data, true);
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
test_harness.send_tc(&token, &ping_tc);
|
||||
let request_id = token.request_id();
|
||||
@@ -310,10 +307,9 @@ mod tests {
|
||||
fn test_sending_custom_subservice() {
|
||||
let (event_request_tx, _) = mpsc::channel();
|
||||
let mut test_harness = Pus5HandlerWithStoreTester::new(event_request_tx);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(5, 200);
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
test_harness.send_tc(&token, &ping_tc);
|
||||
let result = test_harness.handle_one_tc();
|
||||
@@ -330,11 +326,10 @@ mod tests {
|
||||
fn test_sending_invalid_app_data() {
|
||||
let (event_request_tx, _) = mpsc::channel();
|
||||
let mut test_harness = Pus5HandlerWithStoreTester::new(event_request_tx);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header =
|
||||
PusTcSecondaryHeader::new_simple(5, Subservice::TcEnableEventGeneration as u8);
|
||||
let ping_tc =
|
||||
PusTcCreator::new(sp_header, sec_header, &[0, 1, 2], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new(sp_header, sec_header, &[0, 1, 2], true);
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
test_harness.send_tc(&token, &ping_tc);
|
||||
let result = test_harness.handle_one_tc();
|
||||
|
@@ -2,7 +2,6 @@
|
||||
//!
|
||||
//! This module contains structures to make working with the PUS C standard easier.
|
||||
//! The satrs-example application contains various usage examples of these components.
|
||||
use crate::ComponentId;
|
||||
use crate::pool::{PoolAddr, PoolError};
|
||||
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
|
||||
use crate::queue::{GenericReceiveError, GenericSendError};
|
||||
@@ -10,18 +9,19 @@ use crate::request::{GenericMessage, MessageMetadata, RequestId};
|
||||
#[cfg(feature = "alloc")]
|
||||
use crate::tmtc::PacketAsVec;
|
||||
use crate::tmtc::PacketInPool;
|
||||
use crate::ComponentId;
|
||||
use core::fmt::{Display, Formatter};
|
||||
use core::time::Duration;
|
||||
#[cfg(feature = "alloc")]
|
||||
use downcast_rs::{Downcast, impl_downcast};
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
#[cfg(feature = "alloc")]
|
||||
use dyn_clone::DynClone;
|
||||
#[cfg(feature = "std")]
|
||||
use std::error::Error;
|
||||
|
||||
use spacepackets::ecss::PusError;
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader};
|
||||
use spacepackets::ecss::tm::PusTmCreator;
|
||||
use spacepackets::ecss::PusError;
|
||||
use spacepackets::{ByteConversionError, SpHeader};
|
||||
|
||||
pub mod action;
|
||||
@@ -296,7 +296,7 @@ pub trait PacketSenderPusTc: Send {
|
||||
) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
pub trait ActiveRequestStore<V>: Sized {
|
||||
pub trait ActiveRequestMapProvider<V>: Sized {
|
||||
fn insert(&mut self, request_id: &RequestId, request_info: V);
|
||||
fn get(&self, request_id: RequestId) -> Option<&V>;
|
||||
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut V>;
|
||||
@@ -309,7 +309,7 @@ pub trait ActiveRequestStore<V>: Sized {
|
||||
fn for_each_mut<F: FnMut(&RequestId, &mut V)>(&mut self, f: F);
|
||||
}
|
||||
|
||||
pub trait ActiveRequest {
|
||||
pub trait ActiveRequestProvider {
|
||||
fn target_id(&self) -> ComponentId;
|
||||
fn token(&self) -> TcStateToken;
|
||||
fn set_token(&mut self, token: TcStateToken);
|
||||
@@ -330,7 +330,7 @@ pub trait PusRequestRouter<Request> {
|
||||
) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequest, ReplyType> {
|
||||
pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequestProvider, ReplyType> {
|
||||
type Error;
|
||||
|
||||
/// This function handles a reply for a given PUS request and returns whether that request
|
||||
@@ -459,7 +459,7 @@ pub mod alloc_mod {
|
||||
///
|
||||
/// A [VerificationReportingProvider] instance is passed to the user to also allow handling
|
||||
/// of the verification process as part of the PUS standard requirements.
|
||||
pub trait PusTcToRequestConverter<ActiveRequestInfo: ActiveRequest, Request> {
|
||||
pub trait PusTcToRequestConverter<ActiveRequestInfo: ActiveRequestProvider, Request> {
|
||||
type Error;
|
||||
fn convert(
|
||||
&mut self,
|
||||
@@ -480,7 +480,7 @@ pub mod alloc_mod {
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> ActiveRequestStore<V> for DefaultActiveRequestMap<V> {
|
||||
impl<V> ActiveRequestMapProvider<V> for DefaultActiveRequestMap<V> {
|
||||
fn insert(&mut self, request_id: &RequestId, request: V) {
|
||||
self.0.insert(*request_id, request);
|
||||
}
|
||||
@@ -659,18 +659,18 @@ pub mod alloc_mod {
|
||||
#[cfg(feature = "std")]
|
||||
pub mod std_mod {
|
||||
use super::*;
|
||||
use crate::ComponentId;
|
||||
use crate::pool::{
|
||||
PoolAddr, PoolError, PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool,
|
||||
};
|
||||
use crate::pus::verification::{TcStateAccepted, VerificationToken};
|
||||
use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool};
|
||||
use crate::ComponentId;
|
||||
use alloc::vec::Vec;
|
||||
use core::time::Duration;
|
||||
use spacepackets::ByteConversionError;
|
||||
use spacepackets::ecss::WritablePusPacket;
|
||||
use spacepackets::ecss::tc::PusTcReader;
|
||||
use spacepackets::ecss::WritablePusPacket;
|
||||
use spacepackets::time::StdTimestampError;
|
||||
use spacepackets::ByteConversionError;
|
||||
use std::string::String;
|
||||
use std::sync::mpsc;
|
||||
use std::sync::mpsc::TryRecvError;
|
||||
@@ -680,7 +680,7 @@ pub mod std_mod {
|
||||
pub use cb_mod::*;
|
||||
|
||||
use super::verification::{TcStateToken, VerificationReportingProvider};
|
||||
use super::{AcceptedEcssTcAndToken, ActiveRequest, TcInMemory};
|
||||
use super::{AcceptedEcssTcAndToken, ActiveRequestProvider, TcInMemory};
|
||||
use crate::tmtc::PacketInPool;
|
||||
|
||||
impl From<mpsc::SendError<PoolAddr>> for EcssTmtcError {
|
||||
@@ -845,7 +845,7 @@ pub mod std_mod {
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveRequest for ActivePusRequestStd {
|
||||
impl ActiveRequestProvider for ActivePusRequestStd {
|
||||
fn target_id(&self) -> ComponentId {
|
||||
self.target_id
|
||||
}
|
||||
@@ -947,9 +947,7 @@ pub mod std_mod {
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait provides an abstraction for caching a raw ECSS telecommand and then
|
||||
/// providing the [PusTcReader] abstraction to read the cache raw telecommand.
|
||||
pub trait CacheAndReadRawEcssTc {
|
||||
pub trait EcssTcInMemConversionProvider {
|
||||
fn cache(&mut self, possible_packet: &TcInMemory) -> Result<(), PusTcFromMemError>;
|
||||
|
||||
fn tc_slice_raw(&self) -> &[u8];
|
||||
@@ -973,12 +971,12 @@ pub mod std_mod {
|
||||
/// Please note that this structure is not able to convert TCs which are stored inside a
|
||||
/// [SharedStaticMemoryPool].
|
||||
#[derive(Default, Clone)]
|
||||
pub struct EcssTcVecCacher {
|
||||
pub struct EcssTcInVecConverter {
|
||||
sender_id: Option<ComponentId>,
|
||||
pub pus_tc_raw: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl CacheAndReadRawEcssTc for EcssTcVecCacher {
|
||||
impl EcssTcInMemConversionProvider for EcssTcInVecConverter {
|
||||
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
||||
self.pus_tc_raw = None;
|
||||
match tc_in_memory {
|
||||
@@ -1010,13 +1008,13 @@ pub mod std_mod {
|
||||
/// packets should be avoided. Please note that this structure is not able to convert TCs which
|
||||
/// are stored as a `Vec<u8>`.
|
||||
#[derive(Clone)]
|
||||
pub struct EcssTcInSharedPoolCacher {
|
||||
pub struct EcssTcInSharedPoolConverter {
|
||||
sender_id: Option<ComponentId>,
|
||||
shared_tc_pool: SharedStaticMemoryPool,
|
||||
pus_buf: Vec<u8>,
|
||||
}
|
||||
|
||||
impl EcssTcInSharedPoolCacher {
|
||||
impl EcssTcInSharedPoolConverter {
|
||||
pub fn new(shared_tc_store: SharedStaticMemoryPool, max_expected_tc_size: usize) -> Self {
|
||||
Self {
|
||||
sender_id: None,
|
||||
@@ -1047,7 +1045,7 @@ pub mod std_mod {
|
||||
}
|
||||
}
|
||||
|
||||
impl CacheAndReadRawEcssTc for EcssTcInSharedPoolCacher {
|
||||
impl EcssTcInMemConversionProvider for EcssTcInSharedPoolConverter {
|
||||
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
||||
match tc_in_memory {
|
||||
super::TcInMemory::Pool(packet_in_pool) => {
|
||||
@@ -1072,38 +1070,38 @@ pub mod std_mod {
|
||||
|
||||
// TODO: alloc feature flag?
|
||||
#[derive(Clone)]
|
||||
pub enum EcssTcCacher {
|
||||
Static(EcssTcInSharedPoolCacher),
|
||||
Heap(EcssTcVecCacher),
|
||||
pub enum EcssTcInMemConverter {
|
||||
Static(EcssTcInSharedPoolConverter),
|
||||
Heap(EcssTcInVecConverter),
|
||||
}
|
||||
|
||||
impl EcssTcCacher {
|
||||
pub fn new_static(static_store_converter: EcssTcInSharedPoolCacher) -> Self {
|
||||
Self::Static(static_store_converter)
|
||||
impl EcssTcInMemConverter {
|
||||
pub fn new_static(static_store_converter: EcssTcInSharedPoolConverter) -> Self {
|
||||
EcssTcInMemConverter::Static(static_store_converter)
|
||||
}
|
||||
|
||||
pub fn new_heap(heap_converter: EcssTcVecCacher) -> Self {
|
||||
Self::Heap(heap_converter)
|
||||
pub fn new_heap(heap_converter: EcssTcInVecConverter) -> Self {
|
||||
EcssTcInMemConverter::Heap(heap_converter)
|
||||
}
|
||||
}
|
||||
|
||||
impl CacheAndReadRawEcssTc for EcssTcCacher {
|
||||
impl EcssTcInMemConversionProvider for EcssTcInMemConverter {
|
||||
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
|
||||
match self {
|
||||
Self::Static(converter) => converter.cache(tc_in_memory),
|
||||
Self::Heap(converter) => converter.cache(tc_in_memory),
|
||||
EcssTcInMemConverter::Static(converter) => converter.cache(tc_in_memory),
|
||||
EcssTcInMemConverter::Heap(converter) => converter.cache(tc_in_memory),
|
||||
}
|
||||
}
|
||||
fn tc_slice_raw(&self) -> &[u8] {
|
||||
match self {
|
||||
Self::Static(converter) => converter.tc_slice_raw(),
|
||||
Self::Heap(converter) => converter.tc_slice_raw(),
|
||||
EcssTcInMemConverter::Static(converter) => converter.tc_slice_raw(),
|
||||
EcssTcInMemConverter::Heap(converter) => converter.tc_slice_raw(),
|
||||
}
|
||||
}
|
||||
fn sender_id(&self) -> Option<ComponentId> {
|
||||
match self {
|
||||
Self::Static(converter) => converter.sender_id(),
|
||||
Self::Heap(converter) => converter.sender_id(),
|
||||
EcssTcInMemConverter::Static(converter) => converter.sender_id(),
|
||||
EcssTcInMemConverter::Heap(converter) => converter.sender_id(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1131,7 +1129,7 @@ pub mod std_mod {
|
||||
pub struct PusServiceHelper<
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: CacheAndReadRawEcssTc,
|
||||
TcInMemConverter: EcssTcInMemConversionProvider,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> {
|
||||
pub common: PusServiceBase<TcReceiver, TmSender, VerificationReporter>,
|
||||
@@ -1139,11 +1137,11 @@ pub mod std_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: CacheAndReadRawEcssTc,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: EcssTcInMemConversionProvider,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||
{
|
||||
pub fn new(
|
||||
id: ComponentId,
|
||||
@@ -1258,17 +1256,16 @@ pub(crate) fn source_buffer_large_enough(
|
||||
|
||||
#[cfg(any(feature = "test_util", test))]
|
||||
pub mod test_util {
|
||||
use arbitrary_int::u11;
|
||||
use spacepackets::ecss::{tc::PusTcCreator, tm::PusTmReader};
|
||||
|
||||
use crate::request::UniqueApidTargetId;
|
||||
|
||||
use super::{
|
||||
DirectPusPacketHandlerResult, PusPacketHandlingError,
|
||||
verification::{self, TcStateAccepted, VerificationToken},
|
||||
DirectPusPacketHandlerResult, PusPacketHandlingError,
|
||||
};
|
||||
|
||||
pub const TEST_APID: u11 = u11::new(0x101);
|
||||
pub const TEST_APID: u16 = 0x101;
|
||||
pub const TEST_UNIQUE_ID_0: u32 = 0x05;
|
||||
pub const TEST_UNIQUE_ID_1: u32 = 0x06;
|
||||
|
||||
@@ -1291,7 +1288,7 @@ pub mod test_util {
|
||||
|
||||
pub trait SimplePusPacketHandler {
|
||||
fn handle_one_tc(&mut self)
|
||||
-> Result<DirectPusPacketHandlerResult, PusPacketHandlingError>;
|
||||
-> Result<DirectPusPacketHandlerResult, PusPacketHandlingError>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1299,35 +1296,33 @@ pub mod test_util {
|
||||
pub mod tests {
|
||||
use core::cell::RefCell;
|
||||
use std::sync::mpsc::TryRecvError;
|
||||
use std::sync::{RwLock, mpsc};
|
||||
use std::sync::{mpsc, RwLock};
|
||||
|
||||
use alloc::collections::VecDeque;
|
||||
use alloc::vec::Vec;
|
||||
use arbitrary_int::{u11, u14};
|
||||
use satrs_shared::res_code::ResultU16;
|
||||
use spacepackets::CcsdsPacket;
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader};
|
||||
use spacepackets::ecss::tm::{GenericPusTmSecondaryHeader, PusTmCreator, PusTmReader};
|
||||
use spacepackets::ecss::{PusPacket, WritablePusPacket};
|
||||
use spacepackets::CcsdsPacket;
|
||||
use test_util::{TEST_APID, TEST_COMPONENT_ID_0};
|
||||
|
||||
use crate::ComponentId;
|
||||
use crate::pool::{PoolProvider, SharedStaticMemoryPool, StaticMemoryPool, StaticPoolConfig};
|
||||
use crate::pus::verification::{RequestId, VerificationReporter};
|
||||
use crate::tmtc::{PacketAsVec, PacketInPool, PacketSenderWithSharedPool, SharedPacketPool};
|
||||
use crate::ComponentId;
|
||||
|
||||
use super::verification::test_util::TestVerificationReporter;
|
||||
use super::verification::{
|
||||
TcStateAccepted, VerificationReporterConfig, VerificationReportingProvider,
|
||||
VerificationToken,
|
||||
TcStateAccepted, VerificationReporterCfg, VerificationReportingProvider, VerificationToken,
|
||||
};
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||
pub(crate) struct CommonTmInfo {
|
||||
pub subservice: u8,
|
||||
pub apid: u11,
|
||||
pub seq_count: u14,
|
||||
pub apid: u16,
|
||||
pub seq_count: u16,
|
||||
pub msg_counter: u16,
|
||||
pub dest_id: u16,
|
||||
pub timestamp: Vec<u8>,
|
||||
@@ -1336,8 +1331,8 @@ pub mod tests {
|
||||
impl CommonTmInfo {
|
||||
pub fn new(
|
||||
subservice: u8,
|
||||
apid: u11,
|
||||
seq_count: u14,
|
||||
apid: u16,
|
||||
seq_count: u16,
|
||||
msg_counter: u16,
|
||||
dest_id: u16,
|
||||
timestamp: &[u8],
|
||||
@@ -1353,11 +1348,11 @@ pub mod tests {
|
||||
}
|
||||
pub fn new_zero_seq_count(
|
||||
subservice: u8,
|
||||
apid: u11,
|
||||
apid: u16,
|
||||
dest_id: u16,
|
||||
timestamp: &[u8],
|
||||
) -> Self {
|
||||
Self::new(subservice, apid, u14::new(0), 0, dest_id, timestamp)
|
||||
Self::new(subservice, apid, 0, 0, dest_id, timestamp)
|
||||
}
|
||||
|
||||
pub fn new_from_tm(tm: &PusTmCreator) -> Self {
|
||||
@@ -1387,7 +1382,7 @@ pub mod tests {
|
||||
pub type PusServiceHelperStatic = PusServiceHelper<
|
||||
MpscTcReceiver,
|
||||
PacketSenderWithSharedPool,
|
||||
EcssTcInSharedPoolCacher,
|
||||
EcssTcInSharedPoolConverter,
|
||||
VerificationReporter,
|
||||
>;
|
||||
|
||||
@@ -1409,12 +1404,12 @@ pub mod tests {
|
||||
let (test_srv_tc_tx, test_srv_tc_rx) = mpsc::sync_channel(10);
|
||||
let (tm_tx, tm_rx) = mpsc::sync_channel(10);
|
||||
|
||||
let verif_cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
let verif_cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
let verification_handler =
|
||||
VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &verif_cfg);
|
||||
let test_srv_tm_sender =
|
||||
PacketSenderWithSharedPool::new(tm_tx, shared_tm_pool_wrapper.clone());
|
||||
let in_store_converter = EcssTcInSharedPoolCacher::new(shared_tc_pool.clone(), 2048);
|
||||
let in_store_converter = EcssTcInSharedPoolConverter::new(shared_tc_pool.clone(), 2048);
|
||||
(
|
||||
Self {
|
||||
pus_buf: RefCell::new([0; 2048]),
|
||||
@@ -1492,8 +1487,12 @@ pub mod tests {
|
||||
tc_sender: mpsc::Sender<EcssTcAndToken>,
|
||||
tm_receiver: mpsc::Receiver<PacketAsVec>,
|
||||
}
|
||||
pub type PusServiceHelperDynamic =
|
||||
PusServiceHelper<MpscTcReceiver, MpscTmAsVecSender, EcssTcVecCacher, VerificationReporter>;
|
||||
pub type PusServiceHelperDynamic = PusServiceHelper<
|
||||
MpscTcReceiver,
|
||||
MpscTmAsVecSender,
|
||||
EcssTcInVecConverter,
|
||||
VerificationReporter,
|
||||
>;
|
||||
|
||||
impl PusServiceHandlerWithVecCommon {
|
||||
pub fn new_with_standard_verif_reporter(
|
||||
@@ -1502,10 +1501,10 @@ pub mod tests {
|
||||
let (test_srv_tc_tx, test_srv_tc_rx) = mpsc::channel();
|
||||
let (tm_tx, tm_rx) = mpsc::channel();
|
||||
|
||||
let verif_cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
let verif_cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
let verification_handler =
|
||||
VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &verif_cfg);
|
||||
let in_store_converter = EcssTcVecCacher::default();
|
||||
let in_store_converter = EcssTcInVecConverter::default();
|
||||
(
|
||||
Self {
|
||||
current_tm: None,
|
||||
@@ -1531,14 +1530,14 @@ pub mod tests {
|
||||
PusServiceHelper<
|
||||
MpscTcReceiver,
|
||||
MpscTmAsVecSender,
|
||||
EcssTcVecCacher,
|
||||
EcssTcInVecConverter,
|
||||
TestVerificationReporter,
|
||||
>,
|
||||
) {
|
||||
let (test_srv_tc_tx, test_srv_tc_rx) = mpsc::channel();
|
||||
let (tm_tx, tm_rx) = mpsc::channel();
|
||||
|
||||
let in_store_converter = EcssTcVecCacher::default();
|
||||
let in_store_converter = EcssTcInVecConverter::default();
|
||||
let verification_handler = TestVerificationReporter::new(id);
|
||||
(
|
||||
Self {
|
||||
|
@@ -2,7 +2,6 @@
|
||||
//!
|
||||
//! The core data structure of this module is the [PusScheduler]. This structure can be used
|
||||
//! to perform the scheduling of telecommands like specified in the ECSS standard.
|
||||
use arbitrary_int::{u11, u14};
|
||||
use core::fmt::{Debug, Display, Formatter};
|
||||
use core::time::Duration;
|
||||
#[cfg(feature = "serde")]
|
||||
@@ -27,23 +26,20 @@ pub use alloc_mod::*;
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct RequestId {
|
||||
pub(crate) source_id: u16,
|
||||
pub(crate) apid: u11,
|
||||
pub(crate) seq_count: u14,
|
||||
pub(crate) apid: u16,
|
||||
pub(crate) seq_count: u16,
|
||||
}
|
||||
|
||||
impl RequestId {
|
||||
#[inline]
|
||||
pub const fn source_id(&self) -> u16 {
|
||||
pub fn source_id(&self) -> u16 {
|
||||
self.source_id
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn apid(&self) -> u11 {
|
||||
pub fn apid(&self) -> u16 {
|
||||
self.apid
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn seq_count(&self) -> u14 {
|
||||
pub fn seq_count(&self) -> u16 {
|
||||
self.seq_count
|
||||
}
|
||||
|
||||
@@ -57,11 +53,8 @@ impl RequestId {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn as_u64(&self) -> u64 {
|
||||
((self.source_id as u64) << 32)
|
||||
| ((self.apid.value() as u64) << 16)
|
||||
| self.seq_count.value() as u64
|
||||
pub fn as_u64(&self) -> u64 {
|
||||
((self.source_id as u64) << 32) | ((self.apid as u64) << 16) | self.seq_count as u64
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,8 +340,8 @@ pub fn generate_insert_telecommand_app_data(
|
||||
pub mod alloc_mod {
|
||||
use alloc::{
|
||||
collections::{
|
||||
BTreeMap,
|
||||
btree_map::{Entry, Range},
|
||||
BTreeMap,
|
||||
},
|
||||
vec::Vec,
|
||||
};
|
||||
@@ -862,83 +855,73 @@ mod tests {
|
||||
PoolAddr, PoolError, PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig,
|
||||
};
|
||||
use alloc::collections::btree_map::Range;
|
||||
use arbitrary_int::traits::Integer as _;
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
|
||||
use spacepackets::ecss::{CreatorConfig, WritablePusPacket};
|
||||
use spacepackets::time::{TimeWriter, UnixTime, cds};
|
||||
use spacepackets::{PacketId, PacketSequenceControl, PacketType, SequenceFlags, SpHeader};
|
||||
use spacepackets::ecss::WritablePusPacket;
|
||||
use spacepackets::time::{cds, TimeWriter, UnixTime};
|
||||
use spacepackets::{PacketId, PacketSequenceCtrl, PacketType, SequenceFlags, SpHeader};
|
||||
use std::time::Duration;
|
||||
use std::vec::Vec;
|
||||
#[allow(unused_imports)]
|
||||
use std::{println, vec};
|
||||
|
||||
const ZERO_SEQ: u14 = u14::ZERO;
|
||||
|
||||
fn pus_tc_base(timestamp: UnixTime, buf: &mut [u8]) -> (SpHeader, usize) {
|
||||
let cds_time =
|
||||
cds::CdsTime::from_unix_time_with_u16_days(×tamp, cds::SubmillisPrecision::Absent)
|
||||
.unwrap();
|
||||
let len_time_stamp = cds_time.write_to_bytes(buf).unwrap();
|
||||
let len_packet = base_ping_tc_simple_ctor(u14::new(0), &[])
|
||||
let len_packet = base_ping_tc_simple_ctor(0, &[])
|
||||
.write_to_bytes(&mut buf[len_time_stamp..])
|
||||
.unwrap();
|
||||
(
|
||||
SpHeader::new_for_unseg_tc(u11::new(0x02), u14::new(0x34), len_packet as u16),
|
||||
SpHeader::new_for_unseg_tc(0x02, 0x34, len_packet as u16),
|
||||
len_packet + len_time_stamp,
|
||||
)
|
||||
}
|
||||
|
||||
fn scheduled_tc(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator<'_> {
|
||||
fn scheduled_tc(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator {
|
||||
let (sph, len_app_data) = pus_tc_base(timestamp, buf);
|
||||
PusTcCreator::new_simple(sph, 11, 4, &buf[..len_app_data], CreatorConfig::default())
|
||||
PusTcCreator::new_simple(sph, 11, 4, &buf[..len_app_data], true)
|
||||
}
|
||||
|
||||
fn wrong_tc_service(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator<'_> {
|
||||
fn wrong_tc_service(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator {
|
||||
let (sph, len_app_data) = pus_tc_base(timestamp, buf);
|
||||
PusTcCreator::new_simple(sph, 12, 4, &buf[..len_app_data], CreatorConfig::default())
|
||||
PusTcCreator::new_simple(sph, 12, 4, &buf[..len_app_data], true)
|
||||
}
|
||||
|
||||
fn wrong_tc_subservice(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator<'_> {
|
||||
fn wrong_tc_subservice(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator {
|
||||
let (sph, len_app_data) = pus_tc_base(timestamp, buf);
|
||||
PusTcCreator::new_simple(sph, 11, 5, &buf[..len_app_data], CreatorConfig::default())
|
||||
PusTcCreator::new_simple(sph, 11, 5, &buf[..len_app_data], true)
|
||||
}
|
||||
|
||||
fn double_wrapped_time_tagged_tc(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator<'_> {
|
||||
fn double_wrapped_time_tagged_tc(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator {
|
||||
let cds_time =
|
||||
cds::CdsTime::from_unix_time_with_u16_days(×tamp, cds::SubmillisPrecision::Absent)
|
||||
.unwrap();
|
||||
let len_time_stamp = cds_time.write_to_bytes(buf).unwrap();
|
||||
let sph = SpHeader::new_for_unseg_tc(u11::new(0x02), u14::new(0x34), 0);
|
||||
let sph = SpHeader::new_for_unseg_tc(0x02, 0x34, 0);
|
||||
// app data should not matter, double wrapped time-tagged commands should be rejected right
|
||||
// away
|
||||
let inner_time_tagged_tc =
|
||||
PusTcCreator::new_simple(sph, 11, 4, &[], CreatorConfig::default());
|
||||
let inner_time_tagged_tc = PusTcCreator::new_simple(sph, 11, 4, &[], true);
|
||||
let packet_len = inner_time_tagged_tc
|
||||
.write_to_bytes(&mut buf[len_time_stamp..])
|
||||
.expect("writing inner time tagged tc failed");
|
||||
PusTcCreator::new_simple(
|
||||
sph,
|
||||
11,
|
||||
4,
|
||||
&buf[..len_time_stamp + packet_len],
|
||||
CreatorConfig::default(),
|
||||
)
|
||||
PusTcCreator::new_simple(sph, 11, 4, &buf[..len_time_stamp + packet_len], true)
|
||||
}
|
||||
|
||||
fn invalid_time_tagged_cmd() -> PusTcCreator<'static> {
|
||||
let sph = SpHeader::new_for_unseg_tc(u11::new(0x02), u14::new(0x34), 1);
|
||||
PusTcCreator::new_simple(sph, 11, 4, &[], CreatorConfig::default())
|
||||
let sph = SpHeader::new_for_unseg_tc(0x02, 0x34, 1);
|
||||
PusTcCreator::new_simple(sph, 11, 4, &[], true)
|
||||
}
|
||||
|
||||
fn base_ping_tc_simple_ctor(seq_count: u14, app_data: &'static [u8]) -> PusTcCreator<'static> {
|
||||
let sph = SpHeader::new_for_unseg_tc(u11::new(0x02), seq_count, 0);
|
||||
PusTcCreator::new_simple(sph, 17, 1, app_data, CreatorConfig::default())
|
||||
fn base_ping_tc_simple_ctor(seq_count: u16, app_data: &'static [u8]) -> PusTcCreator<'static> {
|
||||
let sph = SpHeader::new_for_unseg_tc(0x02, seq_count, 0);
|
||||
PusTcCreator::new_simple(sph, 17, 1, app_data, true)
|
||||
}
|
||||
|
||||
fn ping_tc_to_store(
|
||||
pool: &mut StaticMemoryPool,
|
||||
buf: &mut [u8],
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
app_data: &'static [u8],
|
||||
) -> TcInfo {
|
||||
let ping_tc = base_ping_tc_simple_ctor(seq_count, app_data);
|
||||
@@ -966,7 +949,7 @@ mod tests {
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(
|
||||
@@ -976,7 +959,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let app_data = &[0, 1, 2];
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, u14::new(1), app_data);
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, 1, app_data);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(
|
||||
UnixTime::new_only_secs(200),
|
||||
@@ -985,7 +968,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let app_data = &[0, 1, 2];
|
||||
let tc_info_2 = ping_tc_to_store(&mut pool, &mut buf, u14::new(2), app_data);
|
||||
let tc_info_2 = ping_tc_to_store(&mut pool, &mut buf, 2, app_data);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(
|
||||
UnixTime::new_only_secs(300),
|
||||
@@ -1016,8 +999,8 @@ mod tests {
|
||||
packet_idx: 1,
|
||||
}),
|
||||
RequestId {
|
||||
seq_count: u14::new(1),
|
||||
apid: u11::new(0),
|
||||
seq_count: 1,
|
||||
apid: 0,
|
||||
source_id: 0,
|
||||
},
|
||||
),
|
||||
@@ -1033,8 +1016,8 @@ mod tests {
|
||||
packet_idx: 2,
|
||||
}),
|
||||
RequestId {
|
||||
seq_count: u14::new(2),
|
||||
apid: u11::new(1),
|
||||
seq_count: 2,
|
||||
apid: 1,
|
||||
source_id: 5,
|
||||
},
|
||||
),
|
||||
@@ -1052,8 +1035,8 @@ mod tests {
|
||||
.into(),
|
||||
RequestId {
|
||||
source_id: 10,
|
||||
seq_count: u14::new(20),
|
||||
apid: u11::new(23),
|
||||
seq_count: 20,
|
||||
apid: 23,
|
||||
},
|
||||
),
|
||||
)
|
||||
@@ -1096,15 +1079,14 @@ mod tests {
|
||||
let src_id_to_set = 12;
|
||||
let apid_to_set = 0x22;
|
||||
let seq_count = 105;
|
||||
let sp_header = SpHeader::new_for_unseg_tc(u11::new(apid_to_set), u14::new(105), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(apid_to_set, 105, 0);
|
||||
let mut sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
sec_header.source_id = src_id_to_set;
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
|
||||
let req_id = RequestId::from_tc(&ping_tc);
|
||||
assert_eq!(req_id.source_id(), src_id_to_set);
|
||||
assert_eq!(req_id.apid().value(), apid_to_set);
|
||||
assert_eq!(req_id.seq_count().value(), seq_count);
|
||||
assert_eq!(req_id.apid(), apid_to_set);
|
||||
assert_eq!(req_id.seq_count(), seq_count);
|
||||
assert_eq!(
|
||||
req_id.as_u64(),
|
||||
((src_id_to_set as u64) << 32) | (apid_to_set as u64) << 16 | seq_count as u64
|
||||
@@ -1119,13 +1101,13 @@ mod tests {
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("insertion failed");
|
||||
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, u14::new(1), &[]);
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, 1, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1)
|
||||
.expect("insertion failed");
|
||||
@@ -1187,13 +1169,13 @@ mod tests {
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("insertion failed");
|
||||
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, u14::new(1), &[]);
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, 1, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_1)
|
||||
.expect("insertion failed");
|
||||
@@ -1249,13 +1231,13 @@ mod tests {
|
||||
scheduler.disable();
|
||||
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("insertion failed");
|
||||
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, u14::new(1), &[]);
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, 1, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1)
|
||||
.expect("insertion failed");
|
||||
@@ -1316,7 +1298,7 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
|
||||
let info = scheduler
|
||||
.insert_unwrapped_tc(
|
||||
@@ -1331,7 +1313,7 @@ mod tests {
|
||||
let mut read_buf: [u8; 64] = [0; 64];
|
||||
pool.read(&tc_info_0.addr(), &mut read_buf).unwrap();
|
||||
let check_tc = PusTcReader::new(&read_buf).expect("incorrect Pus tc raw data");
|
||||
assert_eq!(check_tc, base_ping_tc_simple_ctor(u14::new(0), &[]));
|
||||
assert_eq!(check_tc, base_ping_tc_simple_ctor(0, &[]));
|
||||
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 1);
|
||||
|
||||
@@ -1353,8 +1335,8 @@ mod tests {
|
||||
|
||||
let read_len = pool.read(&addr_vec[0], &mut read_buf).unwrap();
|
||||
let check_tc = PusTcReader::new(&read_buf).expect("incorrect Pus tc raw data");
|
||||
assert_eq!(read_len, check_tc.packet_len());
|
||||
assert_eq!(check_tc, base_ping_tc_simple_ctor(u14::new(0), &[]));
|
||||
assert_eq!(read_len, check_tc.total_len());
|
||||
assert_eq!(check_tc, base_ping_tc_simple_ctor(0, &[]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1380,8 +1362,8 @@ mod tests {
|
||||
|
||||
let read_len = pool.read(&info.addr, &mut buf).unwrap();
|
||||
let check_tc = PusTcReader::new(&buf).expect("incorrect Pus tc raw data");
|
||||
assert_eq!(read_len, check_tc.packet_len());
|
||||
assert_eq!(check_tc, base_ping_tc_simple_ctor(u14::new(0), &[]));
|
||||
assert_eq!(read_len, check_tc.total_len());
|
||||
assert_eq!(check_tc, base_ping_tc_simple_ctor(0, &[]));
|
||||
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 1);
|
||||
|
||||
@@ -1405,8 +1387,8 @@ mod tests {
|
||||
|
||||
let read_len = pool.read(&addr_vec[0], &mut buf).unwrap();
|
||||
let check_tc = PusTcReader::new(&buf).expect("incorrect PUS tc raw data");
|
||||
assert_eq!(read_len, check_tc.packet_len());
|
||||
assert_eq!(check_tc, base_ping_tc_simple_ctor(u14::new(0), &[]));
|
||||
assert_eq!(read_len, check_tc.total_len());
|
||||
assert_eq!(check_tc, base_ping_tc_simple_ctor(0, &[]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1549,7 +1531,7 @@ mod tests {
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("insertion failed");
|
||||
@@ -1586,7 +1568,7 @@ mod tests {
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("insertion failed");
|
||||
@@ -1612,7 +1594,7 @@ mod tests {
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("inserting tc failed");
|
||||
@@ -1633,7 +1615,7 @@ mod tests {
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("inserting tc failed");
|
||||
@@ -1654,15 +1636,15 @@ mod tests {
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("inserting tc failed");
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, u14::new(1), &[]);
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, 1, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_1)
|
||||
.expect("inserting tc failed");
|
||||
let tc_info_2 = ping_tc_to_store(&mut pool, &mut buf, u14::new(2), &[]);
|
||||
let tc_info_2 = ping_tc_to_store(&mut pool, &mut buf, 2, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_2)
|
||||
.expect("inserting tc failed");
|
||||
@@ -1721,7 +1703,7 @@ mod tests {
|
||||
fn insert_command_with_release_time(
|
||||
pool: &mut StaticMemoryPool,
|
||||
scheduler: &mut PusScheduler,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
release_secs: u64,
|
||||
) -> TcInfo {
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
@@ -1740,10 +1722,8 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let tc_info_0 =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, u14::new(0), 50);
|
||||
let tc_info_1 =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, u14::new(0), 100);
|
||||
let tc_info_0 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
let tc_info_1 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 2);
|
||||
let check_range = |range: Range<UnixTime, Vec<TcInfo>>| {
|
||||
let mut tcs_in_range = 0;
|
||||
@@ -1774,11 +1754,9 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let _ = insert_command_with_release_time(&mut pool, &mut scheduler, u14::new(0), 50);
|
||||
let tc_info_1 =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, u14::new(0), 100);
|
||||
let tc_info_2 =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, u14::new(0), 150);
|
||||
let _ = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
let tc_info_1 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
let tc_info_2 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
|
||||
let start_stamp = cds::CdsTime::from_unix_time_with_u16_days(
|
||||
&UnixTime::new_only_secs(100),
|
||||
cds::SubmillisPrecision::Absent,
|
||||
@@ -1811,11 +1789,9 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let tc_info_0 =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, u14::new(0), 50);
|
||||
let tc_info_1 =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, u14::new(0), 100);
|
||||
let _ = insert_command_with_release_time(&mut pool, &mut scheduler, u14::new(0), 150);
|
||||
let tc_info_0 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
let tc_info_1 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
let _ = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 3);
|
||||
|
||||
let end_stamp = cds::CdsTime::from_unix_time_with_u16_days(
|
||||
@@ -1848,10 +1824,10 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let _ = insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 50);
|
||||
let tc_info_1 = insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 100);
|
||||
let tc_info_2 = insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 150);
|
||||
let _ = insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 200);
|
||||
let _ = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
let tc_info_1 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
let tc_info_2 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
|
||||
let _ = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 200);
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 4);
|
||||
|
||||
let start_stamp = cds::CdsTime::from_unix_time_with_u16_days(
|
||||
@@ -1889,8 +1865,8 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 50);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 100);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 2);
|
||||
let del_res = scheduler.delete_all(&mut pool);
|
||||
assert!(del_res.is_ok());
|
||||
@@ -1899,8 +1875,8 @@ mod tests {
|
||||
// Contrary to reset, this does not disable the scheduler.
|
||||
assert!(scheduler.is_enabled());
|
||||
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 50);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 100);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 2);
|
||||
let del_res = scheduler
|
||||
.delete_by_time_filter(TimeWindow::<cds::CdsTime>::new_select_all(), &mut pool);
|
||||
@@ -1918,11 +1894,9 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 50);
|
||||
let cmd_0_to_delete =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 100);
|
||||
let cmd_1_to_delete =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 150);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
let cmd_0_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
let cmd_1_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 3);
|
||||
let start_stamp = cds::CdsTime::from_unix_time_with_u16_days(
|
||||
&UnixTime::new_only_secs(100),
|
||||
@@ -1945,11 +1919,9 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let cmd_0_to_delete =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 50);
|
||||
let cmd_1_to_delete =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 100);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 150);
|
||||
let cmd_0_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
let cmd_1_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 3);
|
||||
|
||||
let end_stamp = cds::CdsTime::from_unix_time_with_u16_days(
|
||||
@@ -1973,14 +1945,11 @@ mod tests {
|
||||
false,
|
||||
));
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
let cmd_out_of_range_0 =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 50);
|
||||
let cmd_0_to_delete =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 100);
|
||||
let cmd_1_to_delete =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 150);
|
||||
let cmd_out_of_range_0 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
|
||||
let cmd_0_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
|
||||
let cmd_1_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
|
||||
let cmd_out_of_range_1 =
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, ZERO_SEQ, 200);
|
||||
insert_command_with_release_time(&mut pool, &mut scheduler, 0, 200);
|
||||
assert_eq!(scheduler.num_scheduled_telecommands(), 4);
|
||||
|
||||
let start_stamp = cds::CdsTime::from_unix_time_with_u16_days(
|
||||
@@ -2013,13 +1982,13 @@ mod tests {
|
||||
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
|
||||
|
||||
let mut buf: [u8; 32] = [0; 32];
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::new(0), &[]);
|
||||
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
|
||||
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
|
||||
.expect("insertion failed");
|
||||
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, u14::new(1), &[]);
|
||||
let tc_info_1 = ping_tc_to_store(&mut pool, &mut buf, 1, &[]);
|
||||
scheduler
|
||||
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1)
|
||||
.expect("insertion failed");
|
||||
@@ -2048,12 +2017,12 @@ mod tests {
|
||||
fn test_generic_insert_app_data_test() {
|
||||
let time_writer = cds::CdsTime::new_with_u16_days(1, 1);
|
||||
let sph = SpHeader::new(
|
||||
PacketId::new(PacketType::Tc, true, u11::new(0x002)),
|
||||
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)),
|
||||
PacketId::new(PacketType::Tc, true, 0x002),
|
||||
PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 5),
|
||||
0,
|
||||
);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, true);
|
||||
let mut buf: [u8; 64] = [0; 64];
|
||||
let result = generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc);
|
||||
assert!(result.is_ok());
|
||||
@@ -2070,12 +2039,12 @@ mod tests {
|
||||
fn test_generic_insert_app_data_test_byte_conv_error() {
|
||||
let time_writer = cds::CdsTime::new_with_u16_days(1, 1);
|
||||
let sph = SpHeader::new(
|
||||
PacketId::new(PacketType::Tc, true, u11::new(0x002)),
|
||||
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)),
|
||||
PacketId::new(PacketType::Tc, true, 0x002),
|
||||
PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 5),
|
||||
0,
|
||||
);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, true);
|
||||
let mut buf: [u8; 16] = [0; 16];
|
||||
let result = generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc);
|
||||
assert!(result.is_err());
|
||||
@@ -2099,12 +2068,12 @@ mod tests {
|
||||
fn test_generic_insert_app_data_test_as_vec() {
|
||||
let time_writer = cds::CdsTime::new_with_u16_days(1, 1);
|
||||
let sph = SpHeader::new(
|
||||
PacketId::new(PacketType::Tc, true, u11::new(0x002)),
|
||||
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)),
|
||||
PacketId::new(PacketType::Tc, true, 0x002),
|
||||
PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 5),
|
||||
0,
|
||||
);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, true);
|
||||
let mut buf: [u8; 64] = [0; 64];
|
||||
generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc).unwrap();
|
||||
let vec = generate_insert_telecommand_app_data_as_vec(&time_writer, &ping_tc)
|
||||
|
@@ -1,15 +1,15 @@
|
||||
use super::scheduler::PusSchedulerProvider;
|
||||
use super::verification::{VerificationReporter, VerificationReportingProvider};
|
||||
use super::{
|
||||
CacheAndReadRawEcssTc, DirectPusPacketHandlerResult, EcssTcInSharedPoolCacher, EcssTcReceiver,
|
||||
EcssTcVecCacher, EcssTmSender, HandlingStatus, MpscTcReceiver, PartialPusHandlingError,
|
||||
PusServiceHelper,
|
||||
DirectPusPacketHandlerResult, EcssTcInMemConversionProvider, EcssTcInSharedPoolConverter,
|
||||
EcssTcInVecConverter, EcssTcReceiver, EcssTmSender, HandlingStatus, MpscTcReceiver,
|
||||
PartialPusHandlingError, PusServiceHelper,
|
||||
};
|
||||
use crate::pool::PoolProvider;
|
||||
use crate::pus::PusPacketHandlingError;
|
||||
use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool};
|
||||
use alloc::string::ToString;
|
||||
use spacepackets::ecss::{PusPacket, scheduling};
|
||||
use spacepackets::ecss::{scheduling, PusPacket};
|
||||
use spacepackets::time::cds::CdsTime;
|
||||
use std::sync::mpsc;
|
||||
|
||||
@@ -24,7 +24,7 @@ use std::sync::mpsc;
|
||||
pub struct PusSchedServiceHandler<
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: CacheAndReadRawEcssTc,
|
||||
TcInMemConverter: EcssTcInMemConversionProvider,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
PusScheduler: PusSchedulerProvider,
|
||||
> {
|
||||
@@ -34,12 +34,13 @@ pub struct PusSchedServiceHandler<
|
||||
}
|
||||
|
||||
impl<
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: CacheAndReadRawEcssTc,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
Scheduler: PusSchedulerProvider,
|
||||
> PusSchedServiceHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter, Scheduler>
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: EcssTcInMemConversionProvider,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
Scheduler: PusSchedulerProvider,
|
||||
>
|
||||
PusSchedServiceHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter, Scheduler>
|
||||
{
|
||||
pub fn new(
|
||||
service_helper: PusServiceHelper<
|
||||
@@ -101,12 +102,11 @@ impl<
|
||||
}
|
||||
};
|
||||
self.scheduler.enable();
|
||||
if self.scheduler.is_enabled()
|
||||
&& let Some(started_token) = opt_started_token
|
||||
{
|
||||
|
||||
if self.scheduler.is_enabled() && opt_started_token.is_some() {
|
||||
if let Err(e) = self.service_helper.verif_reporter().completion_success(
|
||||
&self.service_helper.common.tm_sender,
|
||||
started_token,
|
||||
opt_started_token.unwrap(),
|
||||
time_stamp,
|
||||
) {
|
||||
error_callback(&PartialPusHandlingError::Verification(e));
|
||||
@@ -131,12 +131,10 @@ impl<
|
||||
};
|
||||
|
||||
self.scheduler.disable();
|
||||
if !self.scheduler.is_enabled()
|
||||
&& let Some(started_token) = opt_started_token
|
||||
{
|
||||
if !self.scheduler.is_enabled() && opt_started_token.is_some() {
|
||||
if let Err(e) = self.service_helper.verif_reporter().completion_success(
|
||||
&self.service_helper.common.tm_sender,
|
||||
started_token,
|
||||
opt_started_token.unwrap(),
|
||||
time_stamp,
|
||||
) {
|
||||
error_callback(&PartialPusHandlingError::Verification(e));
|
||||
@@ -213,7 +211,7 @@ impl<
|
||||
pub type PusService11SchedHandlerDynWithMpsc<PusScheduler> = PusSchedServiceHandler<
|
||||
MpscTcReceiver,
|
||||
mpsc::Sender<PacketAsVec>,
|
||||
EcssTcVecCacher,
|
||||
EcssTcInVecConverter,
|
||||
VerificationReporter,
|
||||
PusScheduler,
|
||||
>;
|
||||
@@ -222,7 +220,7 @@ pub type PusService11SchedHandlerDynWithMpsc<PusScheduler> = PusSchedServiceHand
|
||||
pub type PusService11SchedHandlerDynWithBoundedMpsc<PusScheduler> = PusSchedServiceHandler<
|
||||
MpscTcReceiver,
|
||||
mpsc::SyncSender<PacketAsVec>,
|
||||
EcssTcVecCacher,
|
||||
EcssTcInVecConverter,
|
||||
VerificationReporter,
|
||||
PusScheduler,
|
||||
>;
|
||||
@@ -231,7 +229,7 @@ pub type PusService11SchedHandlerDynWithBoundedMpsc<PusScheduler> = PusSchedServ
|
||||
pub type PusService11SchedHandlerStaticWithMpsc<PusScheduler> = PusSchedServiceHandler<
|
||||
MpscTcReceiver,
|
||||
PacketSenderWithSharedPool,
|
||||
EcssTcInSharedPoolCacher,
|
||||
EcssTcInSharedPoolConverter,
|
||||
VerificationReporter,
|
||||
PusScheduler,
|
||||
>;
|
||||
@@ -240,7 +238,7 @@ pub type PusService11SchedHandlerStaticWithMpsc<PusScheduler> = PusSchedServiceH
|
||||
pub type PusService11SchedHandlerStaticWithBoundedMpsc<PusScheduler> = PusSchedServiceHandler<
|
||||
MpscTcReceiver,
|
||||
PacketSenderWithSharedPool,
|
||||
EcssTcInSharedPoolCacher,
|
||||
EcssTcInSharedPoolConverter,
|
||||
VerificationReporter,
|
||||
PusScheduler,
|
||||
>;
|
||||
@@ -251,23 +249,21 @@ mod tests {
|
||||
use crate::pus::test_util::{PusTestHarness, TEST_APID};
|
||||
use crate::pus::verification::{VerificationReporter, VerificationReportingProvider};
|
||||
|
||||
use crate::pus::{DirectPusPacketHandlerResult, MpscTcReceiver, PusPacketHandlingError};
|
||||
use crate::pus::{
|
||||
EcssTcInSharedPoolCacher,
|
||||
scheduler::{self, PusSchedulerProvider, TcInfo},
|
||||
tests::PusServiceHandlerWithSharedStoreCommon,
|
||||
verification::{RequestId, TcStateAccepted, VerificationToken},
|
||||
EcssTcInSharedPoolConverter,
|
||||
};
|
||||
use crate::pus::{DirectPusPacketHandlerResult, MpscTcReceiver, PusPacketHandlingError};
|
||||
use crate::tmtc::PacketSenderWithSharedPool;
|
||||
use alloc::collections::VecDeque;
|
||||
use arbitrary_int::traits::Integer;
|
||||
use arbitrary_int::u14;
|
||||
use delegate::delegate;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::scheduling::Subservice;
|
||||
use spacepackets::ecss::tc::PusTcSecondaryHeader;
|
||||
use spacepackets::ecss::{CreatorConfig, WritablePusPacket};
|
||||
use spacepackets::ecss::WritablePusPacket;
|
||||
use spacepackets::time::TimeWriter;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::{
|
||||
ecss::{tc::PusTcCreator, tm::PusTmReader},
|
||||
time::cds,
|
||||
@@ -280,7 +276,7 @@ mod tests {
|
||||
handler: PusSchedServiceHandler<
|
||||
MpscTcReceiver,
|
||||
PacketSenderWithSharedPool,
|
||||
EcssTcInSharedPoolCacher,
|
||||
EcssTcInSharedPoolConverter,
|
||||
VerificationReporter,
|
||||
TestScheduler,
|
||||
>,
|
||||
@@ -388,10 +384,9 @@ mod tests {
|
||||
test_harness: &mut Pus11HandlerWithStoreTester,
|
||||
subservice: Subservice,
|
||||
) {
|
||||
let reply_header = SpHeader::new_for_unseg_tm(TEST_APID, u14::ZERO, 0);
|
||||
let reply_header = SpHeader::new_for_unseg_tm(TEST_APID, 0, 0);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(11, subservice as u8);
|
||||
let enable_scheduling =
|
||||
PusTcCreator::new(reply_header, tc_header, &[0; 7], CreatorConfig::default());
|
||||
let enable_scheduling = PusTcCreator::new(reply_header, tc_header, &[0; 7], true);
|
||||
let token = test_harness.start_verification(&enable_scheduling);
|
||||
test_harness.send_tc(&token, &enable_scheduling);
|
||||
|
||||
@@ -436,9 +431,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_insert_activity_tc() {
|
||||
let mut test_harness = Pus11HandlerWithStoreTester::new();
|
||||
let mut reply_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let mut reply_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let mut sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let ping_tc = PusTcCreator::new(reply_header, sec_header, &[], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new(reply_header, sec_header, &[], true);
|
||||
let req_id_ping_tc = scheduler::RequestId::from_tc(&ping_tc);
|
||||
let stamper = cds::CdsTime::now_with_u16_days().expect("time provider failed");
|
||||
let mut sched_app_data: [u8; 64] = [0; 64];
|
||||
@@ -446,13 +441,13 @@ mod tests {
|
||||
let ping_raw = ping_tc.to_vec().expect("generating raw tc failed");
|
||||
sched_app_data[written_len..written_len + ping_raw.len()].copy_from_slice(&ping_raw);
|
||||
written_len += ping_raw.len();
|
||||
reply_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(1), 0);
|
||||
reply_header = SpHeader::new_for_unseg_tc(TEST_APID, 1, 0);
|
||||
sec_header = PusTcSecondaryHeader::new_simple(11, Subservice::TcInsertActivity as u8);
|
||||
let enable_scheduling = PusTcCreator::new(
|
||||
reply_header,
|
||||
sec_header,
|
||||
&sched_app_data[..written_len],
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
);
|
||||
let token = test_harness.start_verification(&enable_scheduling);
|
||||
test_harness.send_tc(&token, &enable_scheduling);
|
||||
|
@@ -2,16 +2,16 @@ use crate::pus::{
|
||||
DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError, PusTmVariant,
|
||||
};
|
||||
use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool};
|
||||
use arbitrary_int::u14;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use spacepackets::ecss::{CreatorConfig, PusPacket};
|
||||
use spacepackets::ecss::PusPacket;
|
||||
use spacepackets::SpHeader;
|
||||
use std::sync::mpsc;
|
||||
|
||||
use super::verification::{VerificationReporter, VerificationReportingProvider};
|
||||
use super::{
|
||||
CacheAndReadRawEcssTc, EcssTcInSharedPoolCacher, EcssTcReceiver, EcssTcVecCacher, EcssTmSender,
|
||||
GenericConversionError, HandlingStatus, MpscTcReceiver, PusServiceHelper,
|
||||
EcssTcInMemConversionProvider, EcssTcInSharedPoolConverter, EcssTcInVecConverter,
|
||||
EcssTcReceiver, EcssTmSender, GenericConversionError, HandlingStatus, MpscTcReceiver,
|
||||
PusServiceHelper,
|
||||
};
|
||||
|
||||
/// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets.
|
||||
@@ -19,7 +19,7 @@ use super::{
|
||||
pub struct PusService17TestHandler<
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: CacheAndReadRawEcssTc,
|
||||
TcInMemConverter: EcssTcInMemConversionProvider,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> {
|
||||
pub service_helper:
|
||||
@@ -27,11 +27,11 @@ pub struct PusService17TestHandler<
|
||||
}
|
||||
|
||||
impl<
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: CacheAndReadRawEcssTc,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> PusService17TestHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||
TcReceiver: EcssTcReceiver,
|
||||
TmSender: EcssTmSender,
|
||||
TcInMemConverter: EcssTcInMemConversionProvider,
|
||||
VerificationReporter: VerificationReportingProvider,
|
||||
> PusService17TestHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
|
||||
{
|
||||
pub fn new(
|
||||
service_helper: PusServiceHelper<
|
||||
@@ -76,14 +76,10 @@ impl<
|
||||
// Sequence count will be handled centrally in TM funnel.
|
||||
// It is assumed that the verification reporter was built with a valid APID, so we use
|
||||
// the unchecked API here.
|
||||
let reply_header = SpHeader::new_for_unseg_tm(
|
||||
self.service_helper.verif_reporter().apid(),
|
||||
u14::new(0),
|
||||
0,
|
||||
);
|
||||
let reply_header =
|
||||
SpHeader::new_for_unseg_tm(self.service_helper.verif_reporter().apid(), 0, 0);
|
||||
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, time_stamp);
|
||||
let ping_reply =
|
||||
PusTmCreator::new(reply_header, tc_header, &[], CreatorConfig::default());
|
||||
let ping_reply = PusTmCreator::new(reply_header, tc_header, &[], true);
|
||||
if let Err(e) = self
|
||||
.service_helper
|
||||
.common
|
||||
@@ -116,7 +112,7 @@ impl<
|
||||
pub type PusService17TestHandlerDynWithMpsc = PusService17TestHandler<
|
||||
MpscTcReceiver,
|
||||
mpsc::Sender<PacketAsVec>,
|
||||
EcssTcVecCacher,
|
||||
EcssTcInVecConverter,
|
||||
VerificationReporter,
|
||||
>;
|
||||
/// Helper type definition for a PUS 17 handler with a dynamic TMTC memory backend and bounded MPSC
|
||||
@@ -124,7 +120,7 @@ pub type PusService17TestHandlerDynWithMpsc = PusService17TestHandler<
|
||||
pub type PusService17TestHandlerDynWithBoundedMpsc = PusService17TestHandler<
|
||||
MpscTcReceiver,
|
||||
mpsc::SyncSender<PacketAsVec>,
|
||||
EcssTcVecCacher,
|
||||
EcssTcInVecConverter,
|
||||
VerificationReporter,
|
||||
>;
|
||||
/// Helper type definition for a PUS 17 handler with a shared store TMTC memory backend and bounded
|
||||
@@ -132,13 +128,12 @@ pub type PusService17TestHandlerDynWithBoundedMpsc = PusService17TestHandler<
|
||||
pub type PusService17TestHandlerStaticWithBoundedMpsc = PusService17TestHandler<
|
||||
MpscTcReceiver,
|
||||
PacketSenderWithSharedPool,
|
||||
EcssTcInSharedPoolCacher,
|
||||
EcssTcInSharedPoolConverter,
|
||||
VerificationReporter,
|
||||
>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ComponentId;
|
||||
use crate::pus::test_util::{PusTestHarness, SimplePusPacketHandler, TEST_APID};
|
||||
use crate::pus::tests::{
|
||||
PusServiceHandlerWithSharedStoreCommon, PusServiceHandlerWithVecCommon,
|
||||
@@ -148,18 +143,18 @@ mod tests {
|
||||
};
|
||||
use crate::pus::verification::{TcStateAccepted, VerificationToken};
|
||||
use crate::pus::{
|
||||
DirectPusPacketHandlerResult, EcssTcInSharedPoolCacher, EcssTcVecCacher,
|
||||
DirectPusPacketHandlerResult, EcssTcInSharedPoolConverter, EcssTcInVecConverter,
|
||||
GenericConversionError, HandlingStatus, MpscTcReceiver, MpscTmAsVecSender,
|
||||
PartialPusHandlingError, PusPacketHandlingError,
|
||||
};
|
||||
use crate::tmtc::PacketSenderWithSharedPool;
|
||||
use arbitrary_int::u14;
|
||||
use crate::ComponentId;
|
||||
use delegate::delegate;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
|
||||
use spacepackets::ecss::tm::PusTmReader;
|
||||
use spacepackets::ecss::{CreatorConfig, PusPacket};
|
||||
use spacepackets::time::{TimeWriter, cds};
|
||||
use spacepackets::ecss::PusPacket;
|
||||
use spacepackets::time::{cds, TimeWriter};
|
||||
use spacepackets::SpHeader;
|
||||
|
||||
use super::PusService17TestHandler;
|
||||
|
||||
@@ -168,7 +163,7 @@ mod tests {
|
||||
handler: PusService17TestHandler<
|
||||
MpscTcReceiver,
|
||||
PacketSenderWithSharedPool,
|
||||
EcssTcInSharedPoolCacher,
|
||||
EcssTcInSharedPoolConverter,
|
||||
VerificationReporter,
|
||||
>,
|
||||
}
|
||||
@@ -230,7 +225,7 @@ mod tests {
|
||||
handler: PusService17TestHandler<
|
||||
MpscTcReceiver,
|
||||
MpscTmAsVecSender,
|
||||
EcssTcVecCacher,
|
||||
EcssTcInVecConverter,
|
||||
VerificationReporter,
|
||||
>,
|
||||
}
|
||||
@@ -289,10 +284,9 @@ mod tests {
|
||||
|
||||
fn ping_test(test_harness: &mut (impl PusTestHarness + SimplePusPacketHandler)) {
|
||||
// Create a ping TC, verify acceptance.
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
test_harness.send_tc(&token, &ping_tc);
|
||||
let request_id = token.request_id();
|
||||
@@ -345,10 +339,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_sending_unsupported_service() {
|
||||
let mut test_harness = Pus17HandlerWithStoreTester::new(0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(3, 1);
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
test_harness.send_tc(&token, &ping_tc);
|
||||
let result = test_harness.handle_one_tc();
|
||||
@@ -367,10 +360,9 @@ mod tests {
|
||||
#[test]
|
||||
fn test_sending_custom_subservice() {
|
||||
let mut test_harness = Pus17HandlerWithStoreTester::new(0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 200);
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
test_harness.send_tc(&token, &ping_tc);
|
||||
let result = test_harness.handle_one_tc();
|
||||
|
@@ -17,7 +17,7 @@
|
||||
//! use std::time::Duration;
|
||||
//! use satrs::pool::{PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig};
|
||||
//! use satrs::pus::verification::{
|
||||
//! VerificationReportingProvider, VerificationReporterConfig, VerificationReporter
|
||||
//! VerificationReportingProvider, VerificationReporterCfg, VerificationReporter
|
||||
//! };
|
||||
//! use satrs::tmtc::{SharedStaticMemoryPool, PacketSenderWithSharedPool};
|
||||
//! use satrs::spacepackets::seq_count::SeqCountProviderSimple;
|
||||
@@ -38,7 +38,7 @@
|
||||
//! let shared_tm_pool = SharedStaticMemoryPool::new(RwLock::new(tm_pool));
|
||||
//! let (verif_tx, verif_rx) = mpsc::sync_channel(10);
|
||||
//! let sender = PacketSenderWithSharedPool::new_with_shared_packet_pool(verif_tx, &shared_tm_pool);
|
||||
//! let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
//! let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
//! let mut reporter = VerificationReporter::new(TEST_COMPONENT_ID.id(), &cfg);
|
||||
//!
|
||||
//! let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
@@ -81,9 +81,7 @@
|
||||
//! for the verification module contains examples how this module could be used in a more complex
|
||||
//! context involving multiple threads
|
||||
use crate::params::{Params, WritableToBeBytes};
|
||||
use crate::pus::{EcssTmSender, EcssTmtcError, source_buffer_large_enough};
|
||||
use arbitrary_int::traits::Integer as _;
|
||||
use arbitrary_int::{u3, u11, u14};
|
||||
use crate::pus::{source_buffer_large_enough, EcssTmSender, EcssTmtcError};
|
||||
use core::fmt::{Debug, Display, Formatter};
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::marker::PhantomData;
|
||||
@@ -94,17 +92,18 @@ use delegate::delegate;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use spacepackets::ecss::tc::IsPusTelecommand;
|
||||
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use spacepackets::ecss::{CreatorConfig, EcssEnumeration};
|
||||
use spacepackets::{ByteConversionError, CcsdsPacket, PacketId, PacketSequenceControl};
|
||||
use spacepackets::{MAX_APID, SpHeader};
|
||||
use spacepackets::ecss::EcssEnumeration;
|
||||
use spacepackets::{ByteConversionError, CcsdsPacket, PacketId, PacketSequenceCtrl};
|
||||
use spacepackets::{SpHeader, MAX_APID};
|
||||
|
||||
pub use spacepackets::ecss::verification::*;
|
||||
pub use spacepackets::seq_count::SeqCountProviderSimple;
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub use alloc_mod::*;
|
||||
|
||||
use crate::ComponentId;
|
||||
use crate::request::Apid;
|
||||
use crate::ComponentId;
|
||||
|
||||
/// This is a request identifier as specified in 5.4.11.2 c. of the PUS standard.
|
||||
///
|
||||
@@ -114,9 +113,9 @@ use crate::request::Apid;
|
||||
#[derive(Debug, Eq, Copy, Clone)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct RequestId {
|
||||
version_number: u3,
|
||||
version_number: u8,
|
||||
packet_id: PacketId,
|
||||
psc: PacketSequenceControl,
|
||||
psc: PacketSequenceCtrl,
|
||||
}
|
||||
|
||||
impl Display for RequestId {
|
||||
@@ -158,7 +157,7 @@ impl RequestId {
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> u32 {
|
||||
((self.version_number.as_u32()) << 29)
|
||||
((self.version_number as u32) << 29)
|
||||
| ((self.packet_id.raw() as u32) << 16)
|
||||
| self.psc.raw() as u32
|
||||
}
|
||||
@@ -167,7 +166,7 @@ impl RequestId {
|
||||
self.packet_id
|
||||
}
|
||||
|
||||
pub fn packet_sequence_control(&self) -> PacketSequenceControl {
|
||||
pub fn packet_seq_ctrl(&self) -> PacketSequenceCtrl {
|
||||
self.psc
|
||||
}
|
||||
|
||||
@@ -182,9 +181,9 @@ impl RequestId {
|
||||
}
|
||||
let raw = u32::from_be_bytes(buf[0..Self::SIZE_AS_BYTES].try_into().unwrap());
|
||||
Some(Self {
|
||||
version_number: u3::new(((raw >> 29) & 0b111) as u8),
|
||||
version_number: ((raw >> 29) & 0b111) as u8,
|
||||
packet_id: PacketId::from(((raw >> 16) & 0xffff) as u16),
|
||||
psc: PacketSequenceControl::from((raw & 0xffff) as u16),
|
||||
psc: PacketSequenceCtrl::from((raw & 0xffff) as u16),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -192,9 +191,9 @@ impl RequestId {
|
||||
impl From<u32> for RequestId {
|
||||
fn from(value: u32) -> Self {
|
||||
Self {
|
||||
version_number: u3::new(((value >> 29) & 0b111) as u8),
|
||||
version_number: ((value >> 29) & 0b111) as u8,
|
||||
packet_id: PacketId::from(((value >> 16) & 0xffff) as u16),
|
||||
psc: PacketSequenceControl::from((value & 0xffff) as u16),
|
||||
psc: PacketSequenceCtrl::from((value & 0xffff) as u16),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -481,19 +480,26 @@ pub trait VerificationReportingProvider {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VerificationReportCreator {
|
||||
pub dest_id: u16,
|
||||
apid: u11,
|
||||
apid: u16,
|
||||
}
|
||||
|
||||
impl VerificationReportCreator {
|
||||
pub fn new(apid: u11) -> Self {
|
||||
Self { apid, dest_id: 0 }
|
||||
pub fn new(apid: u16) -> Option<Self> {
|
||||
if apid > MAX_APID {
|
||||
return None;
|
||||
}
|
||||
Some(Self { apid, dest_id: 0 })
|
||||
}
|
||||
|
||||
pub fn set_apid(&mut self, apid: u11) {
|
||||
pub fn set_apid(&mut self, apid: u16) -> bool {
|
||||
if apid > MAX_APID {
|
||||
return false;
|
||||
}
|
||||
self.apid = apid;
|
||||
true
|
||||
}
|
||||
|
||||
pub fn apid(&self) -> u11 {
|
||||
pub fn apid(&self) -> u16 {
|
||||
self.apid
|
||||
}
|
||||
|
||||
@@ -516,7 +522,7 @@ impl VerificationReportCreator {
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
subservice: u8,
|
||||
request_id: &RequestId,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
time_stamp: &'time [u8],
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
@@ -539,7 +545,7 @@ impl VerificationReportCreator {
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
subservice: u8,
|
||||
request_id: &RequestId,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
step: Option<&(impl EcssEnumeration + ?Sized)>,
|
||||
params: &FailParams<'time, '_>,
|
||||
@@ -561,7 +567,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
request_id: &RequestId,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
time_stamp: &'time [u8],
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
@@ -581,7 +587,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
request_id: &RequestId,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
params: FailParams<'time, '_>,
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
@@ -603,7 +609,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
request_id: &RequestId,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
time_stamp: &'time [u8],
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
@@ -626,7 +632,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
request_id: &RequestId,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
params: FailParams<'time, '_>,
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
@@ -648,7 +654,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
request_id: &RequestId,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
time_stamp: &'time [u8],
|
||||
step: impl EcssEnumeration,
|
||||
@@ -672,7 +678,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
token: VerificationToken<TcStateStarted>,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
params: FailParamsWithStep<'time, '_>,
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
@@ -695,7 +701,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
request_id: &RequestId,
|
||||
seq_counter: u14,
|
||||
seq_counter: u16,
|
||||
msg_counter: u16,
|
||||
time_stamp: &'time [u8],
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
@@ -717,7 +723,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
request_id: &RequestId,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_count: u16,
|
||||
params: FailParams<'time, '_>,
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
@@ -738,7 +744,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
subservice: u8,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_counter: u16,
|
||||
req_id: &RequestId,
|
||||
time_stamp: &'time [u8],
|
||||
@@ -774,7 +780,7 @@ impl VerificationReportCreator {
|
||||
&self,
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
subservice: u8,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
msg_counter: u16,
|
||||
req_id: &RequestId,
|
||||
step: Option<&(impl EcssEnumeration + ?Sized)>,
|
||||
@@ -826,14 +832,13 @@ impl VerificationReportCreator {
|
||||
sp_header,
|
||||
tm_sec_header,
|
||||
&src_data_buf[0..source_data_len],
|
||||
CreatorConfig::default(),
|
||||
true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
pub mod alloc_mod {
|
||||
use arbitrary_int::u11;
|
||||
use spacepackets::ecss::PusError;
|
||||
|
||||
use super::*;
|
||||
@@ -841,16 +846,16 @@ pub mod alloc_mod {
|
||||
use core::cell::RefCell;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct VerificationReporterConfig {
|
||||
apid: u11,
|
||||
pub struct VerificationReporterCfg {
|
||||
apid: u16,
|
||||
pub step_field_width: usize,
|
||||
pub fail_code_field_width: usize,
|
||||
pub max_fail_data_len: usize,
|
||||
}
|
||||
|
||||
impl VerificationReporterConfig {
|
||||
impl VerificationReporterCfg {
|
||||
pub fn new(
|
||||
apid: u11,
|
||||
apid: u16,
|
||||
step_field_width: usize,
|
||||
fail_code_field_width: usize,
|
||||
max_fail_data_len: usize,
|
||||
@@ -871,7 +876,7 @@ pub mod alloc_mod {
|
||||
///
|
||||
/// The [Self::modify_tm] function is called before the TM is sent. This allows users to change
|
||||
/// fields like the message count or sequence counter before the TM is sent.
|
||||
pub trait VerificationHook {
|
||||
pub trait VerificationHookProvider {
|
||||
fn modify_tm(&self, tm: &mut PusTmCreator);
|
||||
}
|
||||
|
||||
@@ -881,7 +886,7 @@ pub mod alloc_mod {
|
||||
#[derive(Default, Copy, Clone)]
|
||||
pub struct DummyVerificationHook {}
|
||||
|
||||
impl VerificationHook for DummyVerificationHook {
|
||||
impl VerificationHookProvider for DummyVerificationHook {
|
||||
fn modify_tm(&self, _tm: &mut PusTmCreator) {}
|
||||
}
|
||||
|
||||
@@ -894,17 +899,17 @@ pub mod alloc_mod {
|
||||
/// destination fields are assumed to be constant for a given repoter instance.
|
||||
#[derive(Clone)]
|
||||
pub struct VerificationReporter<
|
||||
VerificationHookInstance: VerificationHook = DummyVerificationHook,
|
||||
VerificationHook: VerificationHookProvider = DummyVerificationHook,
|
||||
> {
|
||||
owner_id: ComponentId,
|
||||
source_data_buf: RefCell<alloc::vec::Vec<u8>>,
|
||||
pub reporter_creator: VerificationReportCreator,
|
||||
pub tm_hook: VerificationHookInstance,
|
||||
pub tm_hook: VerificationHook,
|
||||
}
|
||||
|
||||
impl VerificationReporter<DummyVerificationHook> {
|
||||
pub fn new(owner_id: ComponentId, cfg: &VerificationReporterConfig) -> Self {
|
||||
let reporter = VerificationReportCreator::new(cfg.apid);
|
||||
pub fn new(owner_id: ComponentId, cfg: &VerificationReporterCfg) -> Self {
|
||||
let reporter = VerificationReportCreator::new(cfg.apid).unwrap();
|
||||
Self {
|
||||
owner_id,
|
||||
source_data_buf: RefCell::new(alloc::vec![
|
||||
@@ -920,15 +925,15 @@ pub mod alloc_mod {
|
||||
}
|
||||
}
|
||||
|
||||
impl<VerificationHookInstance: VerificationHook> VerificationReporter<VerificationHookInstance> {
|
||||
impl<VerificationHook: VerificationHookProvider> VerificationReporter<VerificationHook> {
|
||||
/// The provided [VerificationHookProvider] can be used to modify a verification packet
|
||||
/// before it is sent.
|
||||
pub fn new_with_hook(
|
||||
owner_id: ComponentId,
|
||||
cfg: &VerificationReporterConfig,
|
||||
tm_hook: VerificationHookInstance,
|
||||
cfg: &VerificationReporterCfg,
|
||||
tm_hook: VerificationHook,
|
||||
) -> Self {
|
||||
let reporter = VerificationReportCreator::new(cfg.apid);
|
||||
let reporter = VerificationReportCreator::new(cfg.apid).unwrap();
|
||||
Self {
|
||||
owner_id,
|
||||
source_data_buf: RefCell::new(alloc::vec![
|
||||
@@ -961,8 +966,8 @@ pub mod alloc_mod {
|
||||
|
||||
delegate!(
|
||||
to self.reporter_creator {
|
||||
pub fn set_apid(&mut self, apid: u11);
|
||||
pub fn apid(&self) -> u11;
|
||||
pub fn set_apid(&mut self, apid: u16) -> bool;
|
||||
pub fn apid(&self) -> u16;
|
||||
pub fn dest_id(&self) -> u16;
|
||||
pub fn set_dest_id(&mut self, dest_id: u16);
|
||||
}
|
||||
@@ -973,8 +978,8 @@ pub mod alloc_mod {
|
||||
}
|
||||
}
|
||||
|
||||
impl<VerificationHookInstance: VerificationHook> VerificationReportingProvider
|
||||
for VerificationReporter<VerificationHookInstance>
|
||||
impl<VerificationHook: VerificationHookProvider> VerificationReportingProvider
|
||||
for VerificationReporter<VerificationHook>
|
||||
{
|
||||
delegate!(
|
||||
to self.reporter_creator {
|
||||
@@ -1007,7 +1012,7 @@ pub mod alloc_mod {
|
||||
.acceptance_success(
|
||||
source_data_buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
u14::new(0),
|
||||
0,
|
||||
0,
|
||||
time_stamp,
|
||||
)
|
||||
@@ -1027,13 +1032,7 @@ pub mod alloc_mod {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.acceptance_failure(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
u14::new(0),
|
||||
0,
|
||||
params,
|
||||
)
|
||||
.acceptance_failure(buf.as_mut_slice(), &token.request_id(), 0, 0, params)
|
||||
.map_err(PusError::ByteConversion)?;
|
||||
self.tm_hook.modify_tm(&mut tm_creator);
|
||||
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
|
||||
@@ -1052,13 +1051,7 @@ pub mod alloc_mod {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.start_success(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
u14::new(0),
|
||||
0,
|
||||
time_stamp,
|
||||
)
|
||||
.start_success(buf.as_mut_slice(), &token.request_id(), 0, 0, time_stamp)
|
||||
.map_err(PusError::ByteConversion)?;
|
||||
self.tm_hook.modify_tm(&mut tm_creator);
|
||||
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
|
||||
@@ -1078,13 +1071,7 @@ pub mod alloc_mod {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.start_failure(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
u14::new(0),
|
||||
0,
|
||||
params,
|
||||
)
|
||||
.start_failure(buf.as_mut_slice(), &token.request_id(), 0, 0, params)
|
||||
.map_err(PusError::ByteConversion)?;
|
||||
self.tm_hook.modify_tm(&mut tm_creator);
|
||||
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
|
||||
@@ -1107,7 +1094,7 @@ pub mod alloc_mod {
|
||||
.step_success(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
u14::new(0),
|
||||
0,
|
||||
0,
|
||||
time_stamp,
|
||||
step,
|
||||
@@ -1131,7 +1118,7 @@ pub mod alloc_mod {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.step_failure(buf.as_mut_slice(), token, u14::new(0), 0, params)
|
||||
.step_failure(buf.as_mut_slice(), token, 0, 0, params)
|
||||
.map_err(PusError::ByteConversion)?;
|
||||
self.tm_hook.modify_tm(&mut tm_creator);
|
||||
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
|
||||
@@ -1152,13 +1139,7 @@ pub mod alloc_mod {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.completion_success(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
u14::new(0),
|
||||
0,
|
||||
time_stamp,
|
||||
)
|
||||
.completion_success(buf.as_mut_slice(), &token.request_id(), 0, 0, time_stamp)
|
||||
.map_err(PusError::ByteConversion)?;
|
||||
self.tm_hook.modify_tm(&mut tm_creator);
|
||||
sender.send_tm(self.owner_id, PusTmVariant::Direct(tm_creator))?;
|
||||
@@ -1178,13 +1159,7 @@ pub mod alloc_mod {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.completion_failure(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
u14::new(0),
|
||||
0,
|
||||
params,
|
||||
)
|
||||
.completion_failure(buf.as_mut_slice(), &token.request_id(), 0, 00, params)
|
||||
.map_err(PusError::ByteConversion)?;
|
||||
self.tm_hook.modify_tm(&mut tm_creator);
|
||||
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
|
||||
@@ -1334,7 +1309,6 @@ pub fn handle_step_failure_with_generic_params(
|
||||
#[cfg(any(feature = "test_util", test))]
|
||||
pub mod test_util {
|
||||
use alloc::vec::Vec;
|
||||
use arbitrary_int::u11;
|
||||
use core::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
@@ -1396,7 +1370,7 @@ pub mod test_util {
|
||||
fn set_apid(&mut self, _apid: Apid) {}
|
||||
|
||||
fn apid(&self) -> Apid {
|
||||
u11::new(0)
|
||||
0
|
||||
}
|
||||
|
||||
fn acceptance_success(
|
||||
@@ -1712,41 +1686,39 @@ pub mod test_util {
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod tests {
|
||||
use crate::ComponentId;
|
||||
use crate::params::Params;
|
||||
use crate::pool::{SharedStaticMemoryPool, StaticMemoryPool, StaticPoolConfig};
|
||||
use crate::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0};
|
||||
use crate::pus::tests::CommonTmInfo;
|
||||
use crate::pus::verification::{
|
||||
EcssTmSender, EcssTmtcError, FailParams, FailParamsWithStep, RequestId, TcStateNone,
|
||||
VerificationReporter, VerificationReporterConfig, VerificationToken,
|
||||
handle_step_failure_with_generic_params,
|
||||
handle_step_failure_with_generic_params, EcssTmSender, EcssTmtcError, FailParams,
|
||||
FailParamsWithStep, RequestId, TcStateNone, VerificationReporter, VerificationReporterCfg,
|
||||
VerificationToken,
|
||||
};
|
||||
use crate::pus::{ChannelWithId, PusTmVariant};
|
||||
use crate::request::MessageMetadata;
|
||||
use crate::spacepackets::seq_count::{SequenceCounter, SequenceCounterCcsdsSimple};
|
||||
use crate::spacepackets::seq_count::{CcsdsSimpleSeqCountProvider, SequenceCountProvider};
|
||||
use crate::tmtc::{PacketSenderWithSharedPool, SharedPacketPool};
|
||||
use crate::ComponentId;
|
||||
use alloc::format;
|
||||
use alloc::string::ToString;
|
||||
use arbitrary_int::{u11, u14};
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
|
||||
use spacepackets::ecss::{
|
||||
CreatorConfig, EcssEnumU8, EcssEnumU16, EcssEnumU32, EcssEnumeration, PusError, PusPacket,
|
||||
EcssEnumU16, EcssEnumU32, EcssEnumU8, EcssEnumeration, PusError, PusPacket,
|
||||
WritablePusPacket,
|
||||
};
|
||||
use spacepackets::seq_count::SequenceCounterSimple;
|
||||
use spacepackets::util::UnsignedEnum;
|
||||
use spacepackets::{ByteConversionError, SpHeader};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::sync::{RwLock, mpsc};
|
||||
use std::sync::{mpsc, RwLock};
|
||||
use std::vec;
|
||||
use std::vec::Vec;
|
||||
|
||||
use super::{
|
||||
DummyVerificationHook, FailParamHelper, TcStateAccepted, TcStateStarted, VerificationHook,
|
||||
handle_completion_failure_with_generic_params, DummyVerificationHook, FailParamHelper,
|
||||
SeqCountProviderSimple, TcStateAccepted, TcStateStarted, VerificationHookProvider,
|
||||
VerificationReportingProvider, WasAtLeastAccepted,
|
||||
handle_completion_failure_with_generic_params,
|
||||
};
|
||||
|
||||
fn is_send<T: Send>(_: &T) {}
|
||||
@@ -1811,41 +1783,41 @@ pub mod tests {
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SequenceCounterHook {
|
||||
pub seq_counter: SequenceCounterCcsdsSimple,
|
||||
pub msg_counter: SequenceCounterSimple<u16>,
|
||||
pub seq_counter: CcsdsSimpleSeqCountProvider,
|
||||
pub msg_counter: SeqCountProviderSimple<u16>,
|
||||
}
|
||||
|
||||
impl VerificationHook for SequenceCounterHook {
|
||||
impl VerificationHookProvider for SequenceCounterHook {
|
||||
fn modify_tm(&self, tm: &mut spacepackets::ecss::tm::PusTmCreator) {
|
||||
tm.set_seq_count(u14::new(self.seq_counter.get_and_increment()));
|
||||
tm.set_seq_count(self.seq_counter.get_and_increment());
|
||||
tm.set_msg_counter(self.msg_counter.get_and_increment());
|
||||
}
|
||||
}
|
||||
|
||||
struct VerificationReporterTestbench<
|
||||
VerificationHookInstance: VerificationHook = DummyVerificationHook,
|
||||
VerificationHook: VerificationHookProvider = DummyVerificationHook,
|
||||
> {
|
||||
pub id: ComponentId,
|
||||
sender: TestSender,
|
||||
reporter: VerificationReporter<VerificationHookInstance>,
|
||||
reporter: VerificationReporter<VerificationHook>,
|
||||
pub request_id: RequestId,
|
||||
tc: Vec<u8>,
|
||||
}
|
||||
|
||||
fn base_reporter(id: ComponentId, max_fail_data_len: usize) -> VerificationReporter {
|
||||
let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, max_fail_data_len).unwrap();
|
||||
let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, max_fail_data_len).unwrap();
|
||||
VerificationReporter::new(id, &cfg)
|
||||
}
|
||||
|
||||
fn reporter_with_hook<VerificationHookInstance: VerificationHook>(
|
||||
fn reporter_with_hook<VerificationHook: VerificationHookProvider>(
|
||||
id: ComponentId,
|
||||
hook: VerificationHookInstance,
|
||||
) -> VerificationReporter<VerificationHookInstance> {
|
||||
let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
hook: VerificationHook,
|
||||
) -> VerificationReporter<VerificationHook> {
|
||||
let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
VerificationReporter::new_with_hook(id, &cfg, hook)
|
||||
}
|
||||
|
||||
impl<VerificiationHook: VerificationHook> VerificationReporterTestbench<VerificiationHook> {
|
||||
impl<VerificiationHook: VerificationHookProvider> VerificationReporterTestbench<VerificiationHook> {
|
||||
fn new_with_hook(id: ComponentId, tc: PusTcCreator, tm_hook: VerificiationHook) -> Self {
|
||||
let reporter = reporter_with_hook(id, tm_hook);
|
||||
Self {
|
||||
@@ -1940,14 +1912,7 @@ pub mod tests {
|
||||
fn check_acceptance_success(&self, timestamp: &[u8; 7]) {
|
||||
let cmp_info = TmInfo {
|
||||
requestor: MessageMetadata::new(self.request_id.into(), self.id),
|
||||
common: CommonTmInfo::new(
|
||||
1,
|
||||
TEST_APID,
|
||||
u14::new(0),
|
||||
0,
|
||||
self.reporter.dest_id(),
|
||||
timestamp,
|
||||
),
|
||||
common: CommonTmInfo::new(1, TEST_APID, 0, 0, self.reporter.dest_id(), timestamp),
|
||||
additional_data: None,
|
||||
};
|
||||
let mut service_queue = self.sender.service_queue.borrow_mut();
|
||||
@@ -1956,7 +1921,7 @@ pub mod tests {
|
||||
assert_eq!(info, cmp_info);
|
||||
}
|
||||
|
||||
fn check_start_success(&mut self, seq_count: u14, msg_counter: u16, timestamp: &[u8]) {
|
||||
fn check_start_success(&mut self, seq_count: u16, msg_counter: u16, timestamp: &[u8]) {
|
||||
let mut srv_queue = self.sender.service_queue.borrow_mut();
|
||||
let cmp_info = TmInfo {
|
||||
requestor: MessageMetadata::new(self.request_id.into(), self.id),
|
||||
@@ -1974,7 +1939,7 @@ pub mod tests {
|
||||
assert_eq!(info, cmp_info);
|
||||
}
|
||||
|
||||
fn check_completion_success(&mut self, seq_count: u14, msg_counter: u16) {
|
||||
fn check_completion_success(&mut self, seq_count: u16, msg_counter: u16) {
|
||||
let cmp_info = TmInfo {
|
||||
requestor: MessageMetadata::new(self.request_id.into(), self.id),
|
||||
common: CommonTmInfo::new(
|
||||
@@ -2007,14 +1972,7 @@ pub mod tests {
|
||||
fn check_acceptance_failure(&mut self, timestamp: &[u8; 7]) {
|
||||
let cmp_info = TmInfo {
|
||||
requestor: MessageMetadata::new(self.request_id.into(), self.id),
|
||||
common: CommonTmInfo::new(
|
||||
2,
|
||||
TEST_APID,
|
||||
u14::new(0),
|
||||
0,
|
||||
self.reporter.dest_id(),
|
||||
timestamp,
|
||||
),
|
||||
common: CommonTmInfo::new(2, TEST_APID, 0, 0, self.reporter.dest_id(), timestamp),
|
||||
additional_data: Some([0, 2].to_vec()),
|
||||
};
|
||||
let service_queue = self.sender.service_queue.get_mut();
|
||||
@@ -2102,9 +2060,9 @@ pub mod tests {
|
||||
}
|
||||
|
||||
fn create_generic_ping() -> PusTcCreator<'static> {
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0x34), 0);
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, 0x34, 0);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
PusTcCreator::new(sph, tc_header, &[], CreatorConfig::default())
|
||||
PusTcCreator::new(sph, tc_header, &[], true)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2124,8 +2082,8 @@ pub mod tests {
|
||||
fn test_state() {
|
||||
let mut testbench = VerificationReporterTestbench::new(0, create_generic_ping(), 16);
|
||||
assert_eq!(testbench.reporter.apid(), TEST_APID);
|
||||
testbench.reporter.set_apid(u11::new(TEST_APID.value() + 1));
|
||||
assert_eq!(testbench.reporter.apid().value(), TEST_APID.value() + 1);
|
||||
testbench.reporter.set_apid(TEST_APID + 1);
|
||||
assert_eq!(testbench.reporter.apid(), TEST_APID + 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2275,7 +2233,7 @@ pub mod tests {
|
||||
.expect("step 1 failed");
|
||||
assert_eq!(testbench.sender.service_queue.borrow().len(), 4);
|
||||
testbench.check_acceptance_success(&EMPTY_STAMP);
|
||||
testbench.check_start_success(u14::new(0), 0, &EMPTY_STAMP);
|
||||
testbench.check_start_success(0, 0, &EMPTY_STAMP);
|
||||
testbench.check_step_success(0, &EMPTY_STAMP);
|
||||
testbench.check_step_success(1, &EMPTY_STAMP);
|
||||
}
|
||||
@@ -2309,7 +2267,7 @@ pub mod tests {
|
||||
.step_failure(started_token, fail_params)
|
||||
.expect("Step failure failed");
|
||||
testbench.check_acceptance_success(&EMPTY_STAMP);
|
||||
testbench.check_start_success(u14::new(0), 0, DUMMY_STAMP);
|
||||
testbench.check_start_success(0, 0, DUMMY_STAMP);
|
||||
testbench.check_step_success(0, &EMPTY_STAMP);
|
||||
testbench.check_step_failure(&fail_step, &fail_code, &fail_data_raw);
|
||||
}
|
||||
@@ -2331,7 +2289,7 @@ pub mod tests {
|
||||
.completion_failure(started_token, fail_params)
|
||||
.expect("Completion failure");
|
||||
testbench.check_acceptance_success(&EMPTY_STAMP);
|
||||
testbench.check_start_success(u14::new(0), 0, DUMMY_STAMP);
|
||||
testbench.check_start_success(0, 0, DUMMY_STAMP);
|
||||
|
||||
testbench.check_completion_failure(&fail_code, &[]);
|
||||
}
|
||||
@@ -2351,8 +2309,8 @@ pub mod tests {
|
||||
.completion_success(started_token, &EMPTY_STAMP)
|
||||
.expect("Sending completion success failed");
|
||||
testbench.check_acceptance_success(&EMPTY_STAMP);
|
||||
testbench.check_start_success(u14::new(0), 0, DUMMY_STAMP);
|
||||
testbench.check_completion_success(u14::new(0), 0);
|
||||
testbench.check_start_success(0, 0, DUMMY_STAMP);
|
||||
testbench.check_completion_success(0, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2373,8 +2331,8 @@ pub mod tests {
|
||||
.completion_success(started_token, &EMPTY_STAMP)
|
||||
.expect("Sending completion success failed");
|
||||
testbench.check_acceptance_success(&EMPTY_STAMP);
|
||||
testbench.check_start_success(u14::new(1), 1, DUMMY_STAMP);
|
||||
testbench.check_completion_success(u14::new(2), 2);
|
||||
testbench.check_start_success(1, 1, DUMMY_STAMP);
|
||||
testbench.check_completion_success(2, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2433,7 +2391,7 @@ pub mod tests {
|
||||
);
|
||||
assert!(result.unwrap());
|
||||
testbench.check_acceptance_success(&EMPTY_STAMP);
|
||||
testbench.check_start_success(u14::new(0), 0, &EMPTY_STAMP);
|
||||
testbench.check_start_success(0, 0, &EMPTY_STAMP);
|
||||
testbench.check_step_failure(&step, &fail_code, fail_data.as_bytes());
|
||||
}
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
use arbitrary_int::{traits::Integer as _, u11};
|
||||
use core::{fmt, marker::PhantomData};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -10,21 +9,21 @@ pub use alloc_mod::*;
|
||||
pub use std_mod::*;
|
||||
|
||||
use spacepackets::{
|
||||
ecss::{tc::IsPusTelecommand, PusPacket},
|
||||
ByteConversionError,
|
||||
ecss::{PusPacket, tc::IsPusTelecommand},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
queue::{GenericReceiveError, GenericSendError},
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
/// Generic request ID type. Requests can be associated with an ID to have a unique identifier
|
||||
/// for them. This can be useful for tasks like tracking their progress.
|
||||
pub type RequestId = u32;
|
||||
|
||||
/// CCSDS APID type definition. Please note that the APID is a 11 bit value.
|
||||
pub type Apid = u11;
|
||||
/// CCSDS APID type definition. Please note that the APID is a 14 bit value.
|
||||
pub type Apid = u16;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct UniqueApidTargetId {
|
||||
@@ -40,8 +39,8 @@ impl UniqueApidTargetId {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> ComponentId {
|
||||
((self.apid.as_u64()) << 32) | (self.unique_id as u64)
|
||||
pub const fn raw(&self) -> ComponentId {
|
||||
((self.apid as u64) << 32) | (self.unique_id as u64)
|
||||
}
|
||||
|
||||
pub fn id(&self) -> ComponentId {
|
||||
@@ -69,7 +68,7 @@ impl UniqueApidTargetId {
|
||||
impl From<u64> for UniqueApidTargetId {
|
||||
fn from(raw: u64) -> Self {
|
||||
Self {
|
||||
apid: u11::new((raw >> 32) as u16),
|
||||
apid: (raw >> 32) as u16,
|
||||
unique_id: raw as u32,
|
||||
}
|
||||
}
|
||||
@@ -336,12 +335,12 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
To,
|
||||
From,
|
||||
Sender: MessageSenderProvider<To>,
|
||||
Receiver: MessageReceiverProvider<From>,
|
||||
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||
> MessageSenderAndReceiver<To, From, Sender, Receiver, SenderStore>
|
||||
To,
|
||||
From,
|
||||
Sender: MessageSenderProvider<To>,
|
||||
Receiver: MessageReceiverProvider<From>,
|
||||
SenderStore: MessageSenderStoreProvider<To, Sender>,
|
||||
> MessageSenderAndReceiver<To, From, Sender, Receiver, SenderStore>
|
||||
{
|
||||
pub fn new(local_channel_id: ComponentId, message_receiver: Receiver) -> Self {
|
||||
Self {
|
||||
@@ -404,15 +403,15 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
impl<
|
||||
Request,
|
||||
ReqSender: MessageSenderProvider<Request>,
|
||||
ReqReceiver: MessageReceiverProvider<Request>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
>
|
||||
Request,
|
||||
ReqSender: MessageSenderProvider<Request>,
|
||||
ReqReceiver: MessageReceiverProvider<Request>,
|
||||
ReqSenderStore: MessageSenderStoreProvider<Request, ReqSender>,
|
||||
Reply,
|
||||
ReplySender: MessageSenderProvider<Reply>,
|
||||
ReplyReceiver: MessageReceiverProvider<Reply>,
|
||||
ReplySenderStore: MessageSenderStoreProvider<Reply, ReplySender>,
|
||||
>
|
||||
RequestAndReplySenderAndReceiver<
|
||||
Request,
|
||||
ReqSender,
|
||||
@@ -496,19 +495,16 @@ pub mod std_mod {
|
||||
mod tests {
|
||||
use std::sync::mpsc;
|
||||
|
||||
use alloc::string::ToString;
|
||||
use spacepackets::{
|
||||
ecss::tc::{PusTcCreator, PusTcSecondaryHeader},
|
||||
ByteConversionError, SpHeader,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
queue::{GenericReceiveError, GenericSendError},
|
||||
request::{MessageMetadata, MessageSenderMap, MessageSenderStoreProvider},
|
||||
};
|
||||
use alloc::string::ToString;
|
||||
use arbitrary_int::{u11, u14};
|
||||
use spacepackets::{
|
||||
ByteConversionError, SpHeader,
|
||||
ecss::{
|
||||
CreatorConfig,
|
||||
tc::{PusTcCreator, PusTcSecondaryHeader},
|
||||
},
|
||||
};
|
||||
|
||||
use super::{GenericMessage, MessageReceiverWithId, UniqueApidTargetId};
|
||||
|
||||
@@ -518,8 +514,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_basic_target_id_with_apid() {
|
||||
let id = UniqueApidTargetId::new(u11::new(0x111), 0x01);
|
||||
assert_eq!(id.apid.value(), 0x111);
|
||||
let id = UniqueApidTargetId::new(0x111, 0x01);
|
||||
assert_eq!(id.apid, 0x111);
|
||||
assert_eq!(id.unique_id, 0x01);
|
||||
assert_eq!(id.id(), id.raw());
|
||||
assert_eq!(u64::from(id), id.raw());
|
||||
@@ -536,20 +532,19 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_basic_target_id_with_apid_from_pus_tc() {
|
||||
let sp_header = SpHeader::new_for_unseg_tc(u11::new(0x111), u14::new(5), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(0x111, 5, 0);
|
||||
let app_data = 1_u32.to_be_bytes();
|
||||
let pus_tc =
|
||||
PusTcCreator::new_simple(sp_header, 17, 1, &app_data, CreatorConfig::default());
|
||||
let pus_tc = PusTcCreator::new_simple(sp_header, 17, 1, &app_data, true);
|
||||
let id = UniqueApidTargetId::from_pus_tc(&pus_tc).unwrap();
|
||||
assert_eq!(id.apid.value(), 0x111);
|
||||
assert_eq!(id.apid, 0x111);
|
||||
assert_eq!(id.unique_id, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_target_id_with_apid_from_pus_tc_invalid_app_data() {
|
||||
let sp_header = SpHeader::new_for_unseg_tc(u11::new(0x111), u14::new(5), 0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(0x111, 5, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let pus_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let pus_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
|
||||
let error = UniqueApidTargetId::from_pus_tc(&pus_tc);
|
||||
assert!(error.is_err());
|
||||
let error = error.unwrap_err();
|
||||
|
@@ -211,8 +211,8 @@ mod tests {
|
||||
println,
|
||||
rc::Rc,
|
||||
sync::{
|
||||
Arc, Mutex,
|
||||
mpsc::{self, TryRecvError},
|
||||
Arc, Mutex,
|
||||
},
|
||||
time::Instant,
|
||||
};
|
||||
|
@@ -1,5 +1,4 @@
|
||||
use crate::{
|
||||
ComponentId,
|
||||
health::{HealthState, HealthTableProvider},
|
||||
mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, ModeRequestSender, UNKNOWN_MODE_VAL},
|
||||
mode_tree::{
|
||||
@@ -8,6 +7,7 @@ use crate::{
|
||||
},
|
||||
queue::GenericTargetedMessagingError,
|
||||
request::{GenericMessage, RequestId},
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
@@ -252,10 +252,10 @@ impl SequenceExecutionHelper {
|
||||
Ok(ModeCommandingResult::AwaitingSuccessCheck)
|
||||
} else if seq_table_value.entries.len() - 1 == sequence_idx {
|
||||
self.state = SequenceExecutionHelperState::Idle;
|
||||
Ok(ModeCommandingResult::Done)
|
||||
return Ok(ModeCommandingResult::Done);
|
||||
} else {
|
||||
self.current_sequence_index = Some(sequence_idx + 1);
|
||||
Ok(ModeCommandingResult::StepDone)
|
||||
return Ok(ModeCommandingResult::StepDone);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -682,10 +682,9 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
mode::{
|
||||
Mode, ModeAndSubmode, ModeReply, ModeRequest, UNKNOWN_MODE,
|
||||
tests::{ModeReqSenderMock, ModeReqWrapper},
|
||||
Mode, ModeAndSubmode, ModeReply, ModeRequest, UNKNOWN_MODE,
|
||||
},
|
||||
mode_tree::{
|
||||
ModeStoreProvider, ModeStoreVec, SequenceModeTables, SequenceTableEntry,
|
||||
@@ -694,6 +693,7 @@ mod tests {
|
||||
queue::GenericTargetedMessagingError,
|
||||
request::{GenericMessage, MessageMetadata, RequestId},
|
||||
subsystem::{ModeCommandingResult, ModeTreeHelperState, SequenceExecutionHelperState},
|
||||
ComponentId,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@@ -1,7 +1,7 @@
|
||||
use core::fmt::Debug;
|
||||
|
||||
/// Generic abstraction for a check/countdown timer.
|
||||
pub trait Countdown: Debug {
|
||||
pub trait CountdownProvider: Debug {
|
||||
fn has_expired(&self) -> bool;
|
||||
fn reset(&mut self);
|
||||
}
|
||||
|
@@ -9,20 +9,20 @@
|
||||
//! They only need to send the received and generated data to these objects.
|
||||
use crate::queue::GenericSendError;
|
||||
use crate::{
|
||||
ComponentId,
|
||||
pool::{PoolAddr, PoolError},
|
||||
ComponentId,
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
pub use alloc_mod::*;
|
||||
use core::fmt::Debug;
|
||||
#[cfg(feature = "alloc")]
|
||||
use downcast_rs::{Downcast, impl_downcast};
|
||||
use downcast_rs::{impl_downcast, Downcast};
|
||||
use spacepackets::{
|
||||
SpHeader,
|
||||
ecss::{
|
||||
tc::PusTcReader,
|
||||
tm::{PusTmCreator, PusTmReader},
|
||||
},
|
||||
SpHeader,
|
||||
};
|
||||
#[cfg(feature = "std")]
|
||||
use std::sync::mpsc;
|
||||
|
@@ -1,16 +1,15 @@
|
||||
use arbitrary_int::{u11, u14};
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::CreatorConfig;
|
||||
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use spacepackets::time::cds::CdsTime;
|
||||
use spacepackets::time::TimeWriter;
|
||||
use spacepackets::SpHeader;
|
||||
|
||||
pub struct PusTmWithCdsShortHelper {
|
||||
apid: u11,
|
||||
apid: u16,
|
||||
cds_short_buf: [u8; 7],
|
||||
}
|
||||
|
||||
impl PusTmWithCdsShortHelper {
|
||||
pub fn new(apid: u11) -> Self {
|
||||
pub fn new(apid: u16) -> Self {
|
||||
Self {
|
||||
apid,
|
||||
cds_short_buf: [0; 7],
|
||||
@@ -23,7 +22,7 @@ impl PusTmWithCdsShortHelper {
|
||||
service: u8,
|
||||
subservice: u8,
|
||||
source_data: &'data [u8],
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
) -> PusTmCreator<'_, 'data> {
|
||||
let time_stamp = CdsTime::now_with_u16_days().unwrap();
|
||||
time_stamp.write_to_bytes(&mut self.cds_short_buf).unwrap();
|
||||
@@ -36,7 +35,7 @@ impl PusTmWithCdsShortHelper {
|
||||
subservice: u8,
|
||||
source_data: &'data [u8],
|
||||
stamper: &CdsTime,
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
) -> PusTmCreator<'_, 'data> {
|
||||
stamper.write_to_bytes(&mut self.cds_short_buf).unwrap();
|
||||
self.create_pus_tm_common(service, subservice, source_data, seq_count)
|
||||
@@ -47,46 +46,40 @@ impl PusTmWithCdsShortHelper {
|
||||
service: u8,
|
||||
subservice: u8,
|
||||
source_data: &'data [u8],
|
||||
seq_count: u14,
|
||||
seq_count: u16,
|
||||
) -> PusTmCreator<'_, 'data> {
|
||||
let reply_header = SpHeader::new_for_unseg_tm(self.apid, seq_count, 0);
|
||||
let tc_header = PusTmSecondaryHeader::new_simple(service, subservice, &self.cds_short_buf);
|
||||
PusTmCreator::new(
|
||||
reply_header,
|
||||
tc_header,
|
||||
source_data,
|
||||
CreatorConfig::default(),
|
||||
)
|
||||
PusTmCreator::new(reply_header, tc_header, source_data, true)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use spacepackets::{CcsdsPacket, ecss::PusPacket, time::cds::CdsTime};
|
||||
use spacepackets::{ecss::PusPacket, time::cds::CdsTime, CcsdsPacket};
|
||||
|
||||
use super::*;
|
||||
use super::PusTmWithCdsShortHelper;
|
||||
|
||||
#[test]
|
||||
fn test_helper_with_stamper() {
|
||||
let mut pus_tm_helper = PusTmWithCdsShortHelper::new(u11::new(0x123));
|
||||
let mut pus_tm_helper = PusTmWithCdsShortHelper::new(0x123);
|
||||
let stamper = CdsTime::new_with_u16_days(0, 0);
|
||||
let tm =
|
||||
pus_tm_helper.create_pus_tm_with_stamper(17, 1, &[1, 2, 3, 4], &stamper, u14::new(25));
|
||||
let tm = pus_tm_helper.create_pus_tm_with_stamper(17, 1, &[1, 2, 3, 4], &stamper, 25);
|
||||
assert_eq!(tm.service(), 17);
|
||||
assert_eq!(tm.subservice(), 1);
|
||||
assert_eq!(tm.user_data(), &[1, 2, 3, 4]);
|
||||
assert_eq!(tm.seq_count().value(), 25);
|
||||
assert_eq!(tm.seq_count(), 25);
|
||||
assert_eq!(tm.timestamp(), [64, 0, 0, 0, 0, 0, 0])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_helper_from_now() {
|
||||
let mut pus_tm_helper = PusTmWithCdsShortHelper::new(u11::new(0x123));
|
||||
let tm = pus_tm_helper.create_pus_tm_timestamp_now(17, 1, &[1, 2, 3, 4], u14::new(25));
|
||||
let mut pus_tm_helper = PusTmWithCdsShortHelper::new(0x123);
|
||||
let tm = pus_tm_helper.create_pus_tm_timestamp_now(17, 1, &[1, 2, 3, 4], 25);
|
||||
assert_eq!(tm.service(), 17);
|
||||
assert_eq!(tm.subservice(), 1);
|
||||
assert_eq!(tm.user_data(), &[1, 2, 3, 4]);
|
||||
assert_eq!(tm.seq_count().value(), 25);
|
||||
assert_eq!(tm.seq_count(), 25);
|
||||
assert_eq!(tm.timestamp().len(), 7);
|
||||
}
|
||||
}
|
||||
|
@@ -2,8 +2,8 @@
|
||||
use core::mem::size_of;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use spacepackets::ecss::{PfcReal, PfcUnsigned, Ptc};
|
||||
use spacepackets::time::CcsdsTimeProvider;
|
||||
use spacepackets::time::cds::CdsTime;
|
||||
use spacepackets::time::{CcsdsTimeProvider, TimeWriter};
|
||||
|
||||
enum NumOfParamsInfo {
|
||||
/// The parameter entry is a scalar field
|
||||
|
@@ -4,13 +4,13 @@ use satrs::dev_mgmt::{
|
||||
DevManagerCommandingHelper, DevManagerHelperResult, TransparentDevManagerHook,
|
||||
};
|
||||
use satrs::mode::{
|
||||
INVALID_MODE, Mode, ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender,
|
||||
ModeRequestHandler, ModeRequestHandlerMpscBounded, ModeRequestReceiver,
|
||||
ModeRequestorAndHandlerMpscBounded, ModeRequestorOneChildBoundedMpsc, UNKNOWN_MODE,
|
||||
Mode, ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, ModeRequestHandler,
|
||||
ModeRequestHandlerMpscBounded, ModeRequestReceiver, ModeRequestorAndHandlerMpscBounded,
|
||||
ModeRequestorOneChildBoundedMpsc, INVALID_MODE, UNKNOWN_MODE,
|
||||
};
|
||||
use satrs::mode_tree::{
|
||||
ModeChild, ModeNode, ModeParent, ModeStoreProvider, SequenceTableEntry, SequenceTableMapTable,
|
||||
TargetTableEntry, connect_mode_nodes,
|
||||
connect_mode_nodes, ModeChild, ModeNode, ModeParent, ModeStoreProvider, SequenceTableEntry,
|
||||
SequenceTableMapTable, TargetTableEntry,
|
||||
};
|
||||
use satrs::mode_tree::{SequenceTablesMapValue, TargetTablesMapValue};
|
||||
use satrs::request::{MessageMetadata, RequestId};
|
||||
@@ -20,10 +20,10 @@ use satrs::subsystem::{
|
||||
StartSequenceError, SubsystemCommandingHelper, SubsystemHelperResult,
|
||||
};
|
||||
use satrs::{
|
||||
ComponentId,
|
||||
mode::{ModeAndSubmode, ModeReply, ModeRequest},
|
||||
queue::GenericTargetedMessagingError,
|
||||
request::GenericMessage,
|
||||
ComponentId,
|
||||
};
|
||||
use std::borrow::{Borrow, BorrowMut};
|
||||
use std::cell::RefCell;
|
||||
|
@@ -1,4 +1,3 @@
|
||||
use arbitrary_int::u11;
|
||||
use satrs::event_man::{
|
||||
EventManagerWithMpsc, EventMessage, EventMessageU32, EventRoutingError, EventSendProvider,
|
||||
EventU32SenderMpsc,
|
||||
@@ -9,15 +8,15 @@ use satrs::params::{Params, ParamsHeapless, WritableToBeBytes};
|
||||
use satrs::pus::event_man::{DefaultPusEventReportingMap, EventReporter, PusEventTmCreatorWithMap};
|
||||
use satrs::request::UniqueApidTargetId;
|
||||
use satrs::tmtc::PacketAsVec;
|
||||
use spacepackets::ecss::PusError;
|
||||
use spacepackets::ecss::tm::PusTmReader;
|
||||
use spacepackets::ecss::{PusError, PusPacket};
|
||||
use std::sync::mpsc::{self, SendError, TryRecvError};
|
||||
use std::thread;
|
||||
|
||||
const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::<SeverityInfo>::new(1, 0);
|
||||
const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5);
|
||||
const EMPTY_STAMP: [u8; 7] = [0; 7];
|
||||
const TEST_APID: u11 = u11::new(0x02);
|
||||
const TEST_APID: u16 = 0x02;
|
||||
const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -36,8 +35,8 @@ fn test_threaded_usage() {
|
||||
event_man.subscribe_all(pus_event_man_send_provider.target_id());
|
||||
event_man.add_sender(pus_event_man_send_provider);
|
||||
let (event_packet_tx, event_packet_rx) = mpsc::channel::<PacketAsVec>();
|
||||
let reporter = EventReporter::new(TEST_ID.raw(), u11::new(0x02), 0, 128)
|
||||
.expect("Creating event reporter failed");
|
||||
let reporter =
|
||||
EventReporter::new(TEST_ID.raw(), 0x02, 0, 128).expect("Creating event reporter failed");
|
||||
let pus_event_man =
|
||||
PusEventTmCreatorWithMap::new(reporter, DefaultPusEventReportingMap::default());
|
||||
let error_handler = |event_msg: &EventMessageU32, error: EventRoutingError| {
|
||||
|
@@ -1,19 +1,17 @@
|
||||
#[cfg(feature = "crossbeam")]
|
||||
pub mod crossbeam_test {
|
||||
use arbitrary_int::traits::Integer as _;
|
||||
use arbitrary_int::u14;
|
||||
use hashbrown::HashMap;
|
||||
use satrs::pool::{PoolProvider, PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig};
|
||||
use satrs::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0};
|
||||
use satrs::pus::verification::{
|
||||
FailParams, RequestId, VerificationReporter, VerificationReporterConfig,
|
||||
FailParams, RequestId, VerificationReporter, VerificationReporterCfg,
|
||||
VerificationReportingProvider,
|
||||
};
|
||||
use satrs::tmtc::{PacketSenderWithSharedPool, SharedStaticMemoryPool};
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
|
||||
use spacepackets::ecss::tm::PusTmReader;
|
||||
use spacepackets::ecss::{CreatorConfig, EcssEnumU8, EcssEnumU16, WritablePusPacket};
|
||||
use spacepackets::ecss::{EcssEnumU16, EcssEnumU8, PusPacket, WritablePusPacket};
|
||||
use spacepackets::SpHeader;
|
||||
use std::sync::RwLock;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
@@ -33,7 +31,7 @@ pub mod crossbeam_test {
|
||||
// We use a synced sequence count provider here because both verification reporters have the
|
||||
// the same APID. If they had distinct APIDs, the more correct approach would be to have
|
||||
// each reporter have an own sequence count provider.
|
||||
let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
|
||||
// Shared pool object to store the verification PUS telemetry
|
||||
let pool_cfg = StaticPoolConfig::new_from_subpool_cfg_tuples(
|
||||
vec![(10, 32), (10, 64), (10, 128), (10, 1024)],
|
||||
@@ -48,8 +46,8 @@ pub mod crossbeam_test {
|
||||
let sender =
|
||||
PacketSenderWithSharedPool::new_with_shared_packet_pool(tx.clone(), &shared_tm_pool);
|
||||
let sender_1 = sender.clone();
|
||||
let reporter_with_sender_0 = VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &cfg);
|
||||
let reporter_with_sender_1 = reporter_with_sender_0.clone();
|
||||
let mut reporter_with_sender_0 = VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &cfg);
|
||||
let mut reporter_with_sender_1 = reporter_with_sender_0.clone();
|
||||
// For test purposes, we retrieve the request ID from the TCs and pass them to the receiver
|
||||
// tread.
|
||||
let req_id_0;
|
||||
@@ -59,9 +57,9 @@ pub mod crossbeam_test {
|
||||
let (tx_tc_1, rx_tc_1) = crossbeam_channel::bounded(3);
|
||||
{
|
||||
let mut tc_guard = shared_tc_pool.write().unwrap();
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, 0, 0);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let pus_tc_0 = PusTcCreator::new_no_app_data(sph, tc_header, CreatorConfig::default());
|
||||
let pus_tc_0 = PusTcCreator::new_no_app_data(sph, tc_header, true);
|
||||
req_id_0 = RequestId::new(&pus_tc_0);
|
||||
let addr = tc_guard
|
||||
.free_element(pus_tc_0.len_written(), |buf| {
|
||||
@@ -69,9 +67,9 @@ pub mod crossbeam_test {
|
||||
})
|
||||
.unwrap();
|
||||
tx_tc_0.send(addr).unwrap();
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(1), 0);
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, 1, 0);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(5, 1);
|
||||
let pus_tc_1 = PusTcCreator::new_no_app_data(sph, tc_header, CreatorConfig::default());
|
||||
let pus_tc_1 = PusTcCreator::new_no_app_data(sph, tc_header, true);
|
||||
req_id_1 = RequestId::new(&pus_tc_1);
|
||||
let addr = tc_guard
|
||||
.free_element(pus_tc_0.len_written(), |buf| {
|
||||
|
@@ -17,14 +17,12 @@ use core::{
|
||||
use std::{
|
||||
io::{Read, Write},
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream},
|
||||
sync::{Mutex, mpsc},
|
||||
sync::{mpsc, Mutex},
|
||||
thread,
|
||||
};
|
||||
|
||||
use arbitrary_int::{traits::Integer, u11, u14};
|
||||
use hashbrown::HashSet;
|
||||
use satrs::{
|
||||
ComponentId,
|
||||
encoding::{
|
||||
ccsds::{SpValidity, SpacePacketValidator},
|
||||
cobs::encode_packet_with_cobs,
|
||||
@@ -34,10 +32,11 @@ use satrs::{
|
||||
TcpSpacepacketsServer, TcpTmtcInCobsServer,
|
||||
},
|
||||
tmtc::PacketSource,
|
||||
ComponentId,
|
||||
};
|
||||
use spacepackets::{
|
||||
ecss::{tc::PusTcCreator, WritablePusPacket},
|
||||
CcsdsPacket, PacketId, SpHeader,
|
||||
ecss::{CreatorConfig, WritablePusPacket, tc::PusTcCreator},
|
||||
};
|
||||
use std::{collections::VecDeque, sync::Arc, vec::Vec};
|
||||
|
||||
@@ -193,7 +192,7 @@ fn test_cobs_server() {
|
||||
matches!(tc_receiver.try_recv(), Err(mpsc::TryRecvError::Empty));
|
||||
}
|
||||
|
||||
const TEST_APID_0: u11 = u11::new(0x02);
|
||||
const TEST_APID_0: u16 = 0x02;
|
||||
const TEST_PACKET_ID_0: PacketId = PacketId::new_for_tc(true, TEST_APID_0);
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -218,8 +217,8 @@ impl SpacePacketValidator for SimpleVerificator {
|
||||
fn test_ccsds_server() {
|
||||
let (tc_sender, tc_receiver) = mpsc::channel();
|
||||
let mut tm_source = SyncTmSource::default();
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, u14::new(0), 0);
|
||||
let verif_tm = PusTcCreator::new_simple(sph, 1, 1, &[], CreatorConfig::default());
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, 0, 0);
|
||||
let verif_tm = PusTcCreator::new_simple(sph, 1, 1, &[], true);
|
||||
let tm_0 = verif_tm.to_vec().expect("tm generation failed");
|
||||
tm_source.add_tm(&tm_0);
|
||||
let mut packet_id_lookup = SimpleVerificator::default();
|
||||
@@ -268,8 +267,8 @@ fn test_ccsds_server() {
|
||||
.expect("setting reas timeout failed");
|
||||
|
||||
// Send ping telecommand.
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, u14::ZERO, 0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, 0, 0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
|
||||
let tc_0 = ping_tc.to_vec().expect("packet creation failed");
|
||||
stream
|
||||
.write_all(&tc_0)
|
||||
|
Reference in New Issue
Block a user