Compare commits

..

1 Commits

Author SHA1 Message Date
6a4417c954 added and scheduled MGM assembly 2025-05-19 16:18:31 +02:00
72 changed files with 1339 additions and 1413 deletions

View File

@@ -47,8 +47,6 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- run: cargo fmt --all -- --check - run: cargo fmt --all -- --check
docs: docs:
@@ -65,6 +63,4 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- run: cargo clippy -- -D warnings - run: cargo clippy -- -D warnings

View File

@@ -4,7 +4,6 @@
[![sat-rs book](https://img.shields.io/badge/sat--rs-book-darkgreen?style=flat)](https://robamu.github.io/sat-rs/book/) [![sat-rs book](https://img.shields.io/badge/sat--rs-book-darkgreen?style=flat)](https://robamu.github.io/sat-rs/book/)
[![Crates.io](https://img.shields.io/crates/v/satrs)](https://crates.io/crates/satrs) [![Crates.io](https://img.shields.io/crates/v/satrs)](https://crates.io/crates/satrs)
[![docs.rs](https://img.shields.io/docsrs/satrs)](https://docs.rs/satrs) [![docs.rs](https://img.shields.io/docsrs/satrs)](https://docs.rs/satrs)
[![matrix chat](https://img.shields.io/matrix/sat-rs%3Amatrix.org)](https://matrix.to/#/#sat-rs:matrix.org)
sat-rs sat-rs
========= =========
@@ -62,8 +61,6 @@ Each project has its own `CHANGELOG.md`.
packet protocol implementations. This repository is re-exported in the packet protocol implementations. This repository is re-exported in the
[`satrs`](https://egit.irs.uni-stuttgart.de/rust/satrs/src/branch/main/satrs) [`satrs`](https://egit.irs.uni-stuttgart.de/rust/satrs/src/branch/main/satrs)
crate. crate.
* [`cfdp`](https://egit.irs.uni-stuttgart.de/rust/cfdp): CCSDS File Delivery Protocol
(CFDP) high-level library components.
# Flight Heritage # Flight Heritage

View File

@@ -1,21 +0,0 @@
all: check embedded test fmt clippy docs
check:
cargo check
cargo check -p satrs-example --no-default-features
test:
cargo nextest run --all-features
cargo test --doc --all-features
embedded:
cargo check -p satrs --target=thumbv7em-none-eabihf --no-default-features
fmt:
cargo fmt --all -- --check
clippy:
cargo clippy -- -D warnings
docs:
cargo +nightly doc --all-features --config 'build.rustdocflags=["--cfg", "docs_rs"]'

View File

@@ -18,11 +18,9 @@ csv = "1"
num_enum = "0.7" num_enum = "0.7"
thiserror = "2" thiserror = "2"
lazy_static = "1" lazy_static = "1"
strum = { version = "0.27", features = ["derive"] } strum = { version = "0.26", features = ["derive"] }
derive-new = "0.7" derive-new = "0.7"
cfg-if = "1" cfg-if = "1"
arbitrary-int = "2"
bitbybit = "1.4"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
@@ -38,8 +36,8 @@ version = "0.1.1"
path = "../satrs-mib" path = "../satrs-mib"
[features] [features]
default = ["heap_tmtc"]
heap_tmtc = [] heap_tmtc = []
default = ["heap_tmtc"]
[dev-dependencies] [dev-dependencies]
env_logger = "0.11" env_logger = "0.11"

View File

@@ -1 +1,175 @@
// TODO: Write the assembly // 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(())
}
}

View File

@@ -83,7 +83,7 @@ impl SpiInterface for SpiSimInterface {
.sim_request_tx .sim_request_tx
.send(SimRequest::new_with_epoch_time(mgm_sensor_request)) .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)) { match self.sim_reply_rx.recv_timeout(Duration::from_millis(50)) {
Ok(sim_reply) => { Ok(sim_reply) => {
@@ -97,7 +97,7 @@ impl SpiInterface for SpiSimInterface {
.copy_from_slice(&sim_reply_lis3.raw.z.to_le_bytes()); .copy_from_slice(&sim_reply_lis3.raw.z.to_le_bytes());
} }
Err(e) => { Err(e) => {
log::warn!("MGM LIS3 SIM reply timeout: {e}"); log::warn!("MGM LIS3 SIM reply timeout: {}", e);
} }
} }
Ok(()) Ok(())
@@ -400,6 +400,7 @@ impl<
} }
fn announce_mode(&self, _requestor_info: Option<MessageMetadata>, _recursive: bool) { fn announce_mode(&self, _requestor_info: Option<MessageMetadata>, _recursive: bool) {
// TODO: Event
log::info!( log::info!(
"{} announcing mode: {:?}", "{} announcing mode: {:?}",
self.dev_str, self.dev_str,
@@ -492,7 +493,7 @@ mod tests {
tmtc::PacketAsVec, tmtc::PacketAsVec,
ComponentId, ComponentId,
}; };
use satrs_example::ids::{acs::ASSEMBLY, Apid}; use satrs_example::ids::{acs::MGM_ASSEMBLY, Apid};
use satrs_minisim::acs::lis3mdl::MgmLis3RawValues; use satrs_minisim::acs::lis3mdl::MgmLis3RawValues;
use crate::{eps::TestSwitchHelper, pus::hk::HkReply, requests::CompositeRequest}; 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 (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_pus, reply_rx_to_pus) = mpsc::sync_channel(5);
let (reply_tx_to_parent, reply_rx_to_parent) = 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 mode_node = ModeRequestHandlerMpscBounded::new(id.into(), request_rx);
let (composite_request_tx, composite_request_rx) = mpsc::channel(); let (composite_request_tx, composite_request_rx) = mpsc::channel();
let (hk_reply_tx, hk_reply_rx) = mpsc::sync_channel(10); let (hk_reply_tx, hk_reply_rx) = mpsc::sync_channel(10);
@@ -593,7 +594,7 @@ mod tests {
shared_mgm_set, shared_mgm_set,
); );
handler.add_mode_parent(PUS_MODE.into(), reply_tx_to_pus); 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 { Self {
mode_request_tx: request_tx, mode_request_tx: request_tx,
mode_reply_rx_to_pus: reply_rx_to_pus, mode_reply_rx_to_pus: reply_rx_to_pus,

View File

@@ -1,9 +1,7 @@
use arbitrary_int::u11;
use satrs::pus::verification::RequestId; use satrs::pus::verification::RequestId;
use satrs::spacepackets::ecss::tc::PusTcCreator; use satrs::spacepackets::ecss::tc::PusTcCreator;
use satrs::spacepackets::ecss::tm::PusTmReader; use satrs::spacepackets::ecss::tm::PusTmReader;
use satrs::spacepackets::ecss::CreatorConfig; use satrs::{spacepackets::ecss::PusPacket, spacepackets::SpHeader};
use satrs::spacepackets::SpHeader;
use satrs_example::config::{OBSW_SERVER_ADDR, SERVER_PORT}; use satrs_example::config::{OBSW_SERVER_ADDR, SERVER_PORT};
use std::net::{IpAddr, SocketAddr, UdpSocket}; use std::net::{IpAddr, SocketAddr, UdpSocket};
use std::time::Duration; use std::time::Duration;
@@ -11,13 +9,7 @@ use std::time::Duration;
fn main() { fn main() {
let mut buf = [0; 32]; let mut buf = [0; 32];
let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT); let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT);
let pus_tc = PusTcCreator::new_simple( let pus_tc = PusTcCreator::new_simple(SpHeader::new_from_apid(0x02), 17, 1, &[], true);
SpHeader::new_from_apid(u11::new(0x02)),
17,
1,
&[],
CreatorConfig::default(),
);
let client = UdpSocket::bind("127.0.0.1:7302").expect("Connecting to UDP server failed"); let client = UdpSocket::bind("127.0.0.1:7302").expect("Connecting to UDP server failed");
let tc_req_id = RequestId::new(&pus_tc); let tc_req_id = RequestId::new(&pus_tc);
println!("Packing and sending PUS ping command TC[17,1] with request ID {tc_req_id}"); println!("Packing and sending PUS ping command TC[17,1] with request ID {tc_req_id}");

View File

@@ -1,4 +1,3 @@
use arbitrary_int::u11;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use satrs::{ use satrs::{
res_code::ResultU16, res_code::ResultU16,
@@ -45,7 +44,7 @@ lazy_static! {
pub static ref PACKET_ID_VALIDATOR: HashSet<PacketId> = { pub static ref PACKET_ID_VALIDATOR: HashSet<PacketId> = {
let mut set = HashSet::new(); let mut set = HashSet::new();
for id in crate::ids::Apid::iter() { for id in crate::ids::Apid::iter() {
set.insert(PacketId::new(PacketType::Tc, true, u11::new(id as u16))); set.insert(PacketId::new(PacketType::Tc, true, id as u16));
} }
set set
}; };

View File

@@ -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 (switch_request_tx, switch_reqest_rx) = mpsc::channel();
let shared_switch_map = Arc::new(Mutex::new(SwitchSet::default())); let shared_switch_map = Arc::new(Mutex::new(SwitchSet::default()));
let mut handler = PcduHandler::new( let mut handler = PcduHandler::new(
UniqueApidTargetId::new(Apid::Eps.raw_value(), 0), UniqueApidTargetId::new(Apid::Eps as u16, 0),
"TEST_PCDU", "TEST_PCDU",
mode_node, mode_node,
composite_request_rx, composite_request_rx,

View File

@@ -1,10 +1,8 @@
use std::sync::mpsc::{self}; use std::sync::mpsc::{self};
use crate::pus::create_verification_reporter; use crate::pus::create_verification_reporter;
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u11;
use satrs::event_man::{EventMessageU32, EventRoutingError}; use satrs::event_man::{EventMessageU32, EventRoutingError};
use satrs::pus::event::EventTmHook; use satrs::pus::event::EventTmHookProvider;
use satrs::pus::verification::VerificationReporter; use satrs::pus::verification::VerificationReporter;
use satrs::pus::EcssTmSender; use satrs::pus::EcssTmSender;
use satrs::request::UniqueApidTargetId; use satrs::request::UniqueApidTargetId;
@@ -25,10 +23,10 @@ use crate::update_time;
// This helper sets the APID of the event sender for the PUS telemetry. // This helper sets the APID of the event sender for the PUS telemetry.
#[derive(Default)] #[derive(Default)]
pub struct EventApidSetter { 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) { fn modify_tm(&self, tm: &mut satrs::spacepackets::ecss::tm::PusTmCreator) {
tm.set_apid(self.next_apid); tm.set_apid(self.next_apid);
} }
@@ -61,11 +59,12 @@ impl<TmSender: EcssTmSender> PusEventHandler<TmSender> {
// telemetry for each event. // telemetry for each event.
let event_reporter = EventReporter::new_with_hook( let event_reporter = EventReporter::new_with_hook(
PUS_EVENT_MANAGEMENT.raw(), PUS_EVENT_MANAGEMENT.raw(),
u11::ZERO, 0,
0, 0,
128, 128,
EventApidSetter::default(), EventApidSetter::default(),
); )
.unwrap();
let pus_event_dispatcher = let pus_event_dispatcher =
DefaultPusEventU32TmCreator::new_with_default_backend(event_reporter); DefaultPusEventU32TmCreator::new_with_default_backend(event_reporter);
let pus_event_man_send_provider = EventU32SenderMpscBounded::new( let pus_event_man_send_provider = EventU32SenderMpscBounded::new(
@@ -220,14 +219,17 @@ impl<TmSender: EcssTmSender> EventHandler<TmSender> {
mod tests { mod tests {
use satrs::{ use satrs::{
events::EventU32, events::EventU32,
pus::verification::VerificationReporterConfig, pus::verification::VerificationReporterCfg,
spacepackets::ecss::{tm::PusTmReader, PusPacket}, spacepackets::{
ecss::{tm::PusTmReader, PusPacket},
CcsdsPacket,
},
tmtc::PacketAsVec, tmtc::PacketAsVec,
}; };
use super::*; 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); const TEST_EVENT: EventU32 = EventU32::new(satrs::events::Severity::Info, 1, 1);
pub struct EventManagementTestbench { pub struct EventManagementTestbench {
@@ -242,7 +244,7 @@ mod tests {
let (event_tx, event_rx) = mpsc::sync_channel(10); let (event_tx, event_rx) = mpsc::sync_channel(10);
let (_event_req_tx, event_req_rx) = mpsc::sync_channel(10); let (_event_req_tx, event_req_rx) = mpsc::sync_channel(10);
let (tm_sender, tm_receiver) = mpsc::channel(); let (tm_sender, tm_receiver) = mpsc::channel();
let verif_reporter_cfg = VerificationReporterConfig::new(u11::new(0x05), 2, 2, 128); let verif_reporter_cfg = VerificationReporterCfg::new(0x05, 2, 2, 128).unwrap();
let verif_reporter = let verif_reporter =
VerificationReporter::new(PUS_EVENT_MANAGEMENT.id(), &verif_reporter_cfg); VerificationReporter::new(PUS_EVENT_MANAGEMENT.id(), &verif_reporter_cfg);
let mut event_manager = EventManagerWithBoundedMpsc::new(event_rx); let mut event_manager = EventManagerWithBoundedMpsc::new(event_rx);

View File

@@ -1,8 +1,8 @@
use derive_new::new; use derive_new::new;
use satrs::hk::UniqueId; use satrs::hk::UniqueId;
use satrs::request::UniqueApidTargetId; use satrs::request::UniqueApidTargetId;
use satrs::spacepackets::ecss::hk;
use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader}; use satrs::spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
use satrs::spacepackets::ecss::{hk, CreatorConfig};
use satrs::spacepackets::{ByteConversionError, SpHeader}; use satrs::spacepackets::{ByteConversionError, SpHeader};
#[derive(Debug, new, Copy, Clone)] #[derive(Debug, new, Copy, Clone)]
@@ -63,7 +63,7 @@ impl PusHkHelper {
SpHeader::new_from_apid(self.component_id.apid), SpHeader::new_from_apid(self.component_id.apid),
sec_header, sec_header,
&buf[0..8 + hk_data_len], &buf[0..8 + hk_data_len],
CreatorConfig::default(), true,
)) ))
} }
} }

View File

@@ -1,8 +1,7 @@
//! This is an auto-generated configuration module. //! This is an auto-generated configuration module.
use satrs::request::UniqueApidTargetId; use satrs::request::UniqueApidTargetId;
#[derive(Debug, PartialEq, Eq, strum::EnumIter)] #[derive(Debug, Copy, Clone, PartialEq, Eq, strum::EnumIter)]
#[bitbybit::bitenum(u11)]
pub enum Apid { pub enum Apid {
Sched = 1, Sched = 1,
GenericPus = 2, GenericPus = 2,
@@ -13,23 +12,22 @@ pub enum Apid {
} }
pub mod acs { pub mod acs {
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Id { pub enum Id {
Subsystem = 1, Subsystem = 1,
Assembly = 2, MgmAssembly = 2,
Mgm0 = 3, Mgm0 = 3,
Mgm1 = 4, Mgm1 = 4,
} }
pub const SUBSYSTEM: super::UniqueApidTargetId = pub const SUBSYSTEM: super::UniqueApidTargetId =
super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Subsystem as u32); super::UniqueApidTargetId::new(super::Apid::Acs as u16, Id::Subsystem as u32);
pub const ASSEMBLY: super::UniqueApidTargetId = pub const MGM_ASSEMBLY: super::UniqueApidTargetId =
super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Assembly as u32); super::UniqueApidTargetId::new(super::Apid::Acs as u16, Id::MgmAssembly as u32);
pub const MGM0: super::UniqueApidTargetId = 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 = 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 { pub mod eps {
@@ -40,9 +38,9 @@ pub mod eps {
} }
pub const PCDU: super::UniqueApidTargetId = 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 = 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 { pub mod generic_pus {
@@ -57,19 +55,19 @@ pub mod generic_pus {
} }
pub const PUS_EVENT_MANAGEMENT: super::UniqueApidTargetId = super::UniqueApidTargetId::new( pub const PUS_EVENT_MANAGEMENT: super::UniqueApidTargetId = super::UniqueApidTargetId::new(
super::Apid::GenericPus.raw_value(), super::Apid::GenericPus as u16,
Id::PusEventManagement as u32, Id::PusEventManagement as u32,
); );
pub const PUS_ROUTING: super::UniqueApidTargetId = 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 = 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 = 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 = 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 = 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 { pub mod sched {
@@ -79,7 +77,7 @@ pub mod sched {
} }
pub const PUS_SCHED: super::UniqueApidTargetId = 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 { pub mod tmtc {
@@ -90,7 +88,7 @@ pub mod tmtc {
} }
pub const UDP_SERVER: super::UniqueApidTargetId = 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 = 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);
} }

View File

@@ -24,7 +24,7 @@ pub fn create_sim_client(sim_request_rx: mpsc::Receiver<SimRequest>) -> Option<S
return Some(sim_client); return Some(sim_client);
} }
Err(e) => { Err(e) => {
log::warn!("sim client creation error: {e}"); log::warn!("sim client creation error: {}", e);
} }
} }
None None
@@ -116,7 +116,7 @@ impl SimClientUdp {
.udp_client .udp_client
.send_to(request_json.as_bytes(), self.simulator_addr) .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; break;
} else { } else {
no_sim_requests_handled = false; no_sim_requests_handled = false;
@@ -151,7 +151,7 @@ impl SimClientUdp {
} }
} }
Err(e) => { 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; break;
} }
log::error!("error receiving data from UDP SIM server: {e}"); log::error!("error receiving data from UDP SIM server: {}", e);
break; break;
} }
} }

View File

@@ -31,7 +31,7 @@ impl SpacePacketValidator for SimplePacketValidator {
if self.valid_ids.contains(&sp_header.packet_id()) { if self.valid_ids.contains(&sp_header.packet_id()) {
return SpValidity::Valid; 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 // We could perform a CRC check.. but lets keep this simple and assume that TCP ensures
// data integrity. // data integrity.
SpValidity::Skip SpValidity::Skip

View File

@@ -1,14 +1,13 @@
#![allow(dead_code)]
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
use std::sync::mpsc; use std::sync::mpsc;
use log::{info, warn}; use log::{info, warn};
use satrs::hal::std::udp_server::{ReceiveResult, UdpTcServer};
use satrs::pus::HandlingStatus; use satrs::pus::HandlingStatus;
use satrs::tmtc::{PacketAsVec, StoreAndSendError}; use satrs::tmtc::{PacketAsVec, PacketInPool, StoreAndSendError};
use satrs::{
use satrs::pool::{PoolProviderWithGuards, SharedStaticMemoryPool}; hal::std::udp_server::{ReceiveResult, UdpTcServer},
use satrs::tmtc::PacketInPool; pool::{PoolProviderWithGuards, SharedStaticMemoryPool},
};
use crate::tmtc::sender::TmTcSender; use crate::tmtc::sender::TmTcSender;
@@ -113,9 +112,6 @@ mod tests {
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u14;
use satrs::spacepackets::ecss::CreatorConfig;
use satrs::{ use satrs::{
spacepackets::{ spacepackets::{
ecss::{tc::PusTcCreator, WritablePusPacket}, ecss::{tc::PusTcCreator, WritablePusPacket},
@@ -180,8 +176,8 @@ mod tests {
udp_tc_server, udp_tc_server,
tm_handler, tm_handler,
}; };
let sph = SpHeader::new_for_unseg_tc(ids::Apid::GenericPus.raw_value(), u14::ZERO, 0); let sph = SpHeader::new_for_unseg_tc(ids::Apid::GenericPus as u16, 0, 0);
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default()) let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true)
.to_vec() .to_vec()
.unwrap(); .unwrap();
let client = UdpSocket::bind("127.0.0.1:0").expect("Connecting to UDP server failed"); let client = UdpSocket::bind("127.0.0.1:0").expect("Connecting to UDP server failed");

View File

@@ -1,4 +1,4 @@
use satrs::spacepackets::time::cds::CdsTime; use satrs::spacepackets::time::{cds::CdsTime, TimeWriter};
pub mod config; pub mod config;
pub mod ids; pub mod ids;

View File

@@ -5,7 +5,10 @@ use std::{
time::Duration, time::Duration,
}; };
use acs::mgm::{MgmHandlerLis3Mdl, SpiDummyInterface, SpiSimInterface, SpiSimInterfaceWrapper}; use acs::{
assembly::MgmAssembly,
mgm::{MgmHandlerLis3Mdl, SpiDummyInterface, SpiSimInterface, SpiSimInterfaceWrapper},
};
use eps::{ use eps::{
pcdu::{PcduHandler, SerialInterfaceDummy, SerialInterfaceToSim, SerialSimInterfaceWrapper}, pcdu::{PcduHandler, SerialInterfaceDummy, SerialInterfaceToSim, SerialSimInterfaceWrapper},
PowerSwitchHelper, PowerSwitchHelper,
@@ -31,11 +34,14 @@ use pus::{
use requests::GenericRequestRouter; use requests::GenericRequestRouter;
use satrs::{ use satrs::{
hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer}, hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer},
mode::{Mode, ModeAndSubmode, ModeRequest, ModeRequestHandlerMpscBounded}, mode::{
Mode, ModeAndSubmode, ModeRequest, ModeRequestHandlerMpscBounded,
ModeRequestorAndHandlerMpscBounded,
},
mode_tree::connect_mode_nodes, mode_tree::connect_mode_nodes,
pus::{event_man::EventRequestWithToken, EcssTcCacher, HandlingStatus}, pus::{event_man::EventRequestWithToken, EcssTcInMemConverter, HandlingStatus},
request::{GenericMessage, MessageMetadata}, request::{GenericMessage, MessageMetadata},
spacepackets::time::cds::CdsTime, spacepackets::time::{cds::CdsTime, TimeWriter},
}; };
use satrs_example::{ use satrs_example::{
config::{ config::{
@@ -57,12 +63,12 @@ use tmtc::{tc_source::TcSourceTask, tm_sink::TmSink};
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(feature = "heap_tmtc")] { if #[cfg(feature = "heap_tmtc")] {
use interface::udp::DynamicUdpTmHandler; use interface::udp::DynamicUdpTmHandler;
use satrs::pus::EcssTcVecCacher; use satrs::pus::EcssTcInVecConverter;
use tmtc::{tc_source::TcSourceTaskDynamic, tm_sink::TmSinkDynamic}; use tmtc::{tc_source::TcSourceTaskDynamic, tm_sink::TmSinkDynamic};
} else { } else {
use std::sync::RwLock; use std::sync::RwLock;
use interface::udp::StaticUdpTmHandler; use interface::udp::StaticUdpTmHandler;
use satrs::pus::EcssTcInSharedPoolCacher; use satrs::pus::EcssTcInSharedPoolConverter;
use satrs::tmtc::{PacketSenderWithSharedPool, SharedPacketPool}; use satrs::tmtc::{PacketSenderWithSharedPool, SharedPacketPool};
use satrs_example::config::pool::create_static_pools; use satrs_example::config::pool::create_static_pools;
use tmtc::{ use tmtc::{
@@ -143,9 +149,9 @@ fn main() {
let tc_sender_with_shared_pool = let tc_sender_with_shared_pool =
PacketSenderWithSharedPool::new(tc_source_tx, shared_tc_pool_wrapper.clone()); PacketSenderWithSharedPool::new(tc_source_tx, shared_tc_pool_wrapper.clone());
let tc_in_mem_converter = 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")] { } 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_request_tx, switch_request_rx) = mpsc::sync_channel(20);
let switch_helper = PowerSwitchHelper::new(switch_request_tx, shared_switch_set.clone()); 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_0_set = Arc::default();
let shared_mgm_1_set = Arc::default(); let shared_mgm_1_set = Arc::default();
let mgm_0_mode_node = ModeRequestHandlerMpscBounded::new(MGM0.into(), mgm_0_handler_mode_rx); let mgm_0_mode_node = ModeRequestHandlerMpscBounded::new(MGM0.into(), mgm_0_handler_mode_rx);
@@ -364,6 +379,19 @@ fn main() {
&mut mgm_1_handler, &mut mgm_1_handler,
pus_mode_reply_tx.clone(), 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() { 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); 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() let jh_aocs = thread::Builder::new()
.name("sat-rs aocs".to_string()) .name("sat-rs aocs".to_string())
.spawn(move || loop { .spawn(move || loop {
mgm_assembly.periodic_operation();
mgm_0_handler.periodic_operation(); mgm_0_handler.periodic_operation();
mgm_1_handler.periodic_operation(); mgm_1_handler.periodic_operation();
thread::sleep(Duration::from_millis(FREQ_MS_AOCS)); thread::sleep(Duration::from_millis(FREQ_MS_AOCS));

View File

@@ -9,7 +9,7 @@ use satrs::pus::verification::{
VerificationReportingProvider, VerificationToken, VerificationReportingProvider, VerificationToken,
}; };
use satrs::pus::{ use satrs::pus::{
ActiveRequest, EcssTcAndToken, EcssTcCacher, EcssTmSender, EcssTmtcError, ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConverter, EcssTmSender, EcssTmtcError,
GenericConversionError, MpscTcReceiver, PusPacketHandlingError, PusReplyHandler, GenericConversionError, MpscTcReceiver, PusPacketHandlingError, PusReplyHandler,
PusServiceHelper, PusTcToRequestConverter, PusServiceHelper, PusTcToRequestConverter,
}; };
@@ -208,7 +208,7 @@ impl PusTcToRequestConverter<ActivePusActionRequestStd, ActionRequest> for Actio
pub fn create_action_service( pub fn create_action_service(
tm_sender: TmTcSender, tm_sender: TmTcSender,
tc_in_mem_converter: EcssTcCacher, tc_in_mem_converter: EcssTcInMemConverter,
pus_action_rx: mpsc::Receiver<EcssTcAndToken>, pus_action_rx: mpsc::Receiver<EcssTcAndToken>,
action_router: GenericRequestRouter, action_router: GenericRequestRouter,
reply_receiver: mpsc::Receiver<GenericMessage<ActionReplyPus>>, 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, 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::test_util::TestVerificationReporter;
use satrs::pus::{verification, EcssTcVecCacher}; use satrs::pus::{verification, EcssTcInVecConverter};
use satrs::request::MessageMetadata; use satrs::request::MessageMetadata;
use satrs::spacepackets::ecss::CreatorConfig;
use satrs::tmtc::PacketAsVec; use satrs::tmtc::PacketAsVec;
use satrs::ComponentId; use satrs::ComponentId;
use satrs::{ use satrs::{
@@ -326,7 +325,7 @@ mod tests {
pus_action_rx, pus_action_rx,
TmTcSender::Heap(tm_funnel_tx.clone()), TmTcSender::Heap(tm_funnel_tx.clone()),
verif_reporter, verif_reporter,
EcssTcCacher::Heap(EcssTcVecCacher::default()), EcssTcInMemConverter::Heap(EcssTcInVecConverter::default()),
), ),
ActionRequestConverter::default(), ActionRequestConverter::default(),
DefaultActiveActionRequestMap::default(), DefaultActiveActionRequestMap::default(),
@@ -454,8 +453,7 @@ mod tests {
let mut app_data: [u8; 8] = [0; 8]; let mut app_data: [u8; 8] = [0; 8];
app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_1.to_be_bytes()); 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()); app_data[4..8].copy_from_slice(&action_id.to_be_bytes());
let pus8_packet = let pus8_packet = PusTcCreator::new(sp_header, sec_header, &app_data, true);
PusTcCreator::new(sp_header, sec_header, &app_data, CreatorConfig::default());
testbench.add_tc(&pus8_packet); testbench.add_tc(&pus8_packet);
let time_stamp: [u8; 7] = [0; 7]; let time_stamp: [u8; 7] = [0; 7];
testbench.verify_next_tc_is_handled_properly(&time_stamp); testbench.verify_next_tc_is_handled_properly(&time_stamp);
@@ -501,7 +499,7 @@ mod tests {
SpHeader::new_from_apid(TEST_APID), SpHeader::new_from_apid(TEST_APID),
sec_header, sec_header,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
testbench.add_tc(&pus8_packet); testbench.add_tc(&pus8_packet);
let time_stamp: [u8; 7] = [0; 7]; let time_stamp: [u8; 7] = [0; 7];
@@ -527,7 +525,7 @@ mod tests {
SpHeader::new_from_apid(TEST_APID), SpHeader::new_from_apid(TEST_APID),
sec_header, sec_header,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
let token = testbench.add_tc(&pus8_packet); let token = testbench.add_tc(&pus8_packet);
let result = testbench.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0); let result = testbench.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0);
@@ -566,7 +564,7 @@ mod tests {
SpHeader::new_from_apid(TEST_APID), SpHeader::new_from_apid(TEST_APID),
sec_header, sec_header,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
let token = testbench.add_tc(&pus8_packet); let token = testbench.add_tc(&pus8_packet);
let result = testbench.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0); let result = testbench.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0);

View File

@@ -6,7 +6,7 @@ use satrs::pus::event_man::EventRequestWithToken;
use satrs::pus::event_srv::PusEventServiceHandler; use satrs::pus::event_srv::PusEventServiceHandler;
use satrs::pus::verification::VerificationReporter; use satrs::pus::verification::VerificationReporter;
use satrs::pus::{ use satrs::pus::{
DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcCacher, MpscTcReceiver, DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConverter, MpscTcReceiver,
PartialPusHandlingError, PusServiceHelper, PartialPusHandlingError, PusServiceHelper,
}; };
use satrs::spacepackets::ecss::PusServiceId; use satrs::spacepackets::ecss::PusServiceId;
@@ -16,7 +16,7 @@ use super::{DirectPusService, HandlingStatus};
pub fn create_event_service( pub fn create_event_service(
tm_sender: TmTcSender, tm_sender: TmTcSender,
tm_in_pool_converter: EcssTcCacher, tm_in_pool_converter: EcssTcInMemConverter,
pus_event_rx: mpsc::Receiver<EcssTcAndToken>, pus_event_rx: mpsc::Receiver<EcssTcAndToken>,
event_request_tx: mpsc::Sender<EventRequestWithToken>, event_request_tx: mpsc::Sender<EventRequestWithToken>,
) -> EventServiceWrapper { ) -> EventServiceWrapper {
@@ -36,8 +36,12 @@ pub fn create_event_service(
} }
pub struct EventServiceWrapper { pub struct EventServiceWrapper {
pub handler: pub handler: PusEventServiceHandler<
PusEventServiceHandler<MpscTcReceiver, TmTcSender, EcssTcCacher, VerificationReporter>, MpscTcReceiver,
TmTcSender,
EcssTcInMemConverter,
VerificationReporter,
>,
} }
impl DirectPusService for EventServiceWrapper { impl DirectPusService for EventServiceWrapper {

View File

@@ -5,9 +5,9 @@ use satrs::pus::verification::{
VerificationReportingProvider, VerificationToken, VerificationReportingProvider, VerificationToken,
}; };
use satrs::pus::{ use satrs::pus::{
ActivePusRequestStd, ActiveRequest, DefaultActiveRequestMap, EcssTcAndToken, EcssTcCacher, ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap, EcssTcAndToken,
EcssTmSender, EcssTmtcError, GenericConversionError, MpscTcReceiver, PusPacketHandlingError, EcssTcInMemConverter, EcssTmSender, EcssTmtcError, GenericConversionError, MpscTcReceiver,
PusReplyHandler, PusServiceHelper, PusTcToRequestConverter, PusPacketHandlingError, PusReplyHandler, PusServiceHelper, PusTcToRequestConverter,
}; };
use satrs::request::{GenericMessage, UniqueApidTargetId}; use satrs::request::{GenericMessage, UniqueApidTargetId};
use satrs::res_code::ResultU16; use satrs::res_code::ResultU16;
@@ -242,7 +242,7 @@ impl PusTcToRequestConverter<ActivePusRequestStd, HkRequest> for HkRequestConver
pub fn create_hk_service( pub fn create_hk_service(
tm_sender: TmTcSender, tm_sender: TmTcSender,
tc_in_mem_converter: EcssTcCacher, tc_in_mem_converter: EcssTcInMemConverter,
pus_hk_rx: mpsc::Receiver<EcssTcAndToken>, pus_hk_rx: mpsc::Receiver<EcssTcAndToken>,
request_router: GenericRequestRouter, request_router: GenericRequestRouter,
reply_receiver: mpsc::Receiver<GenericMessage<HkReply>>, reply_receiver: mpsc::Receiver<GenericMessage<HkReply>>,
@@ -302,13 +302,10 @@ impl TargetedPusService for HkServiceWrapper {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u14;
use satrs::pus::test_util::{ use satrs::pus::test_util::{
TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1, TEST_UNIQUE_ID_0, TEST_UNIQUE_ID_1, TEST_COMPONENT_ID_0, TEST_COMPONENT_ID_1, TEST_UNIQUE_ID_0, TEST_UNIQUE_ID_1,
}; };
use satrs::request::MessageMetadata; use satrs::request::MessageMetadata;
use satrs::spacepackets::ecss::CreatorConfig;
use satrs::{ use satrs::{
hk::HkRequestVariant, hk::HkRequestVariant,
pus::test_util::TEST_APID, pus::test_util::TEST_APID,
@@ -331,7 +328,7 @@ mod tests {
fn hk_converter_one_shot_req() { fn hk_converter_one_shot_req() {
let mut hk_bench = let mut hk_bench =
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default()); PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default());
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 target_id = TEST_UNIQUE_ID_0; let target_id = TEST_UNIQUE_ID_0;
let unique_id = 5_u32; let unique_id = 5_u32;
let mut app_data: [u8; 8] = [0; 8]; let mut app_data: [u8; 8] = [0; 8];
@@ -343,7 +340,7 @@ mod tests {
3, 3,
Subservice::TcGenerateOneShotHk as u8, Subservice::TcGenerateOneShotHk as u8,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
let accepted_token = hk_bench.add_tc(&hk_req); let accepted_token = hk_bench.add_tc(&hk_req);
let (_active_req, req) = hk_bench let (_active_req, req) = hk_bench
@@ -361,7 +358,7 @@ mod tests {
fn hk_converter_enable_periodic_generation() { fn hk_converter_enable_periodic_generation() {
let mut hk_bench = let mut hk_bench =
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default()); PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default());
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 target_id = TEST_UNIQUE_ID_0; let target_id = TEST_UNIQUE_ID_0;
let unique_id = 5_u32; let unique_id = 5_u32;
let mut app_data: [u8; 8] = [0; 8]; let mut app_data: [u8; 8] = [0; 8];
@@ -383,7 +380,7 @@ mod tests {
3, 3,
Subservice::TcEnableHkGeneration as u8, Subservice::TcEnableHkGeneration as u8,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
generic_check(&tc0); generic_check(&tc0);
let tc1 = PusTcCreator::new_simple( let tc1 = PusTcCreator::new_simple(
@@ -391,7 +388,7 @@ mod tests {
3, 3,
Subservice::TcEnableDiagGeneration as u8, Subservice::TcEnableDiagGeneration as u8,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
generic_check(&tc1); generic_check(&tc1);
} }
@@ -400,7 +397,7 @@ mod tests {
fn hk_conversion_disable_periodic_generation() { fn hk_conversion_disable_periodic_generation() {
let mut hk_bench = let mut hk_bench =
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default()); PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default());
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 target_id = TEST_UNIQUE_ID_0; let target_id = TEST_UNIQUE_ID_0;
let unique_id = 5_u32; let unique_id = 5_u32;
let mut app_data: [u8; 8] = [0; 8]; let mut app_data: [u8; 8] = [0; 8];
@@ -422,7 +419,7 @@ mod tests {
3, 3,
Subservice::TcDisableHkGeneration as u8, Subservice::TcDisableHkGeneration as u8,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
generic_check(&tc0); generic_check(&tc0);
let tc1 = PusTcCreator::new_simple( let tc1 = PusTcCreator::new_simple(
@@ -430,7 +427,7 @@ mod tests {
3, 3,
Subservice::TcDisableDiagGeneration as u8, Subservice::TcDisableDiagGeneration as u8,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
generic_check(&tc1); generic_check(&tc1);
} }
@@ -439,7 +436,7 @@ mod tests {
fn hk_conversion_modify_interval() { fn hk_conversion_modify_interval() {
let mut hk_bench = let mut hk_bench =
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default()); PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), HkRequestConverter::default());
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 target_id = TEST_UNIQUE_ID_0; let target_id = TEST_UNIQUE_ID_0;
let unique_id = 5_u32; let unique_id = 5_u32;
let mut app_data: [u8; 12] = [0; 12]; let mut app_data: [u8; 12] = [0; 12];
@@ -465,7 +462,7 @@ mod tests {
3, 3,
Subservice::TcModifyHkCollectionInterval as u8, Subservice::TcModifyHkCollectionInterval as u8,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
generic_check(&tc0); generic_check(&tc0);
let tc1 = PusTcCreator::new_simple( let tc1 = PusTcCreator::new_simple(
@@ -473,7 +470,7 @@ mod tests {
3, 3,
Subservice::TcModifyDiagCollectionInterval as u8, Subservice::TcModifyDiagCollectionInterval as u8,
&app_data, &app_data,
CreatorConfig::default(), true,
); );
generic_check(&tc1); generic_check(&tc1);
} }

View File

@@ -4,13 +4,13 @@ use log::warn;
use satrs::pool::PoolAddr; use satrs::pool::PoolAddr;
use satrs::pus::verification::{ use satrs::pus::verification::{
self, FailParams, TcStateAccepted, TcStateStarted, VerificationReporter, self, FailParams, TcStateAccepted, TcStateStarted, VerificationReporter,
VerificationReporterConfig, VerificationReportingProvider, VerificationToken, VerificationReporterCfg, VerificationReportingProvider, VerificationToken,
}; };
use satrs::pus::{ use satrs::pus::{
ActiveRequest, ActiveRequestStore, CacheAndReadRawEcssTc, EcssTcAndToken, EcssTcCacher, ActiveRequestMapProvider, ActiveRequestProvider, EcssTcAndToken, EcssTcInMemConversionProvider,
EcssTcReceiver, EcssTmSender, EcssTmtcError, GenericConversionError, GenericRoutingError, EcssTcInMemConverter, EcssTcReceiver, EcssTmSender, EcssTmtcError, GenericConversionError,
HandlingStatus, PusPacketHandlingError, PusReplyHandler, PusRequestRouter, PusServiceHelper, GenericRoutingError, HandlingStatus, PusPacketHandlingError, PusReplyHandler, PusRequestRouter,
PusTcToRequestConverter, TcInMemory, PusServiceHelper, PusTcToRequestConverter, TcInMemory,
}; };
use satrs::queue::{GenericReceiveError, GenericSendError}; use satrs::queue::{GenericReceiveError, GenericSendError};
use satrs::request::{Apid, GenericMessage, MessageMetadata}; use satrs::request::{Apid, GenericMessage, MessageMetadata};
@@ -33,7 +33,7 @@ pub mod stack;
pub mod test; pub mod test;
pub fn create_verification_reporter(owner_id: ComponentId, apid: Apid) -> VerificationReporter { pub fn create_verification_reporter(owner_id: ComponentId, apid: Apid) -> VerificationReporter {
let verif_cfg = VerificationReporterConfig::new(apid, 1, 2, 8); let verif_cfg = VerificationReporterCfg::new(apid, 1, 2, 8).unwrap();
// Every software component which needs to generate verification telemetry, gets a cloned // Every software component which needs to generate verification telemetry, gets a cloned
// verification reporter. // verification reporter.
VerificationReporter::new(owner_id, &verif_cfg) VerificationReporter::new(owner_id, &verif_cfg)
@@ -102,7 +102,7 @@ impl PusTcDistributor {
sender_id, sender_id,
pus_tc_result.unwrap_err() 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? // TODO: Shouldn't this be an error?
return Ok(HandlingStatus::HandledOne); return Ok(HandlingStatus::HandledOne);
} }
@@ -269,16 +269,16 @@ pub struct PusTargetedRequestService<
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>, RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>,
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>, ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
ActiveRequestMapInstance: ActiveRequestStore<ActiveRequestInfo>, ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
ActiveRequestInfo: ActiveRequest, ActiveRequestInfo: ActiveRequestProvider,
RequestType, RequestType,
ReplyType, ReplyType,
> { > {
pub service_helper: pub service_helper:
PusServiceHelper<TcReceiver, TmTcSender, EcssTcCacher, VerificationReporter>, PusServiceHelper<TcReceiver, TmTcSender, EcssTcInMemConverter, VerificationReporter>,
pub request_router: GenericRequestRouter, pub request_router: GenericRequestRouter,
pub request_converter: RequestConverter, pub request_converter: RequestConverter,
pub active_request_map: ActiveRequestMapInstance, pub active_request_map: ActiveRequestMap,
pub reply_handler: ReplyHandler, pub reply_handler: ReplyHandler,
pub reply_receiver: mpsc::Receiver<GenericMessage<ReplyType>>, pub reply_receiver: mpsc::Receiver<GenericMessage<ReplyType>>,
phantom: std::marker::PhantomData<(RequestType, ActiveRequestInfo, ReplyType)>, phantom: std::marker::PhantomData<(RequestType, ActiveRequestInfo, ReplyType)>,
@@ -289,8 +289,8 @@ impl<
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>, RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>,
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>, ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
ActiveRequestMapInstance: ActiveRequestStore<ActiveRequestInfo>, ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
ActiveRequestInfo: ActiveRequest, ActiveRequestInfo: ActiveRequestProvider,
RequestType, RequestType,
ReplyType, ReplyType,
> >
@@ -299,7 +299,7 @@ impl<
VerificationReporter, VerificationReporter,
RequestConverter, RequestConverter,
ReplyHandler, ReplyHandler,
ActiveRequestMapInstance, ActiveRequestMap,
ActiveRequestInfo, ActiveRequestInfo,
RequestType, RequestType,
ReplyType, ReplyType,
@@ -311,11 +311,11 @@ where
service_helper: PusServiceHelper< service_helper: PusServiceHelper<
TcReceiver, TcReceiver,
TmTcSender, TmTcSender,
EcssTcCacher, EcssTcInMemConverter,
VerificationReporter, VerificationReporter,
>, >,
request_converter: RequestConverter, request_converter: RequestConverter,
active_request_map: ActiveRequestMapInstance, active_request_map: ActiveRequestMap,
reply_hook: ReplyHandler, reply_hook: ReplyHandler,
request_router: GenericRequestRouter, request_router: GenericRequestRouter,
reply_receiver: mpsc::Receiver<GenericMessage<ReplyType>>, reply_receiver: mpsc::Receiver<GenericMessage<ReplyType>>,
@@ -509,7 +509,7 @@ where
/// and also log the error. /// and also log the error.
pub fn generic_pus_request_timeout_handler( pub fn generic_pus_request_timeout_handler(
sender: &(impl EcssTmSender + ?Sized), sender: &(impl EcssTmSender + ?Sized),
active_request: &(impl ActiveRequest + Debug), active_request: &(impl ActiveRequestProvider + Debug),
verification_handler: &impl VerificationReportingProvider, verification_handler: &impl VerificationReportingProvider,
time_stamp: &[u8], time_stamp: &[u8],
service_str: &'static str, service_str: &'static str,
@@ -531,15 +531,13 @@ pub fn generic_pus_request_timeout_handler(
pub(crate) mod tests { pub(crate) mod tests {
use std::time::Duration; use std::time::Duration;
use arbitrary_int::u11;
use satrs::pus::test_util::TEST_COMPONENT_ID_0; use satrs::pus::test_util::TEST_COMPONENT_ID_0;
use satrs::pus::{MpscTmAsVecSender, PusTmVariant}; use satrs::pus::{MpscTmAsVecSender, PusTmVariant};
use satrs::request::RequestId; use satrs::request::RequestId;
use satrs::spacepackets::ecss::CreatorConfig;
use satrs::{ use satrs::{
pus::{ pus::{
verification::test_util::TestVerificationReporter, ActivePusRequestStd, verification::test_util::TestVerificationReporter, ActivePusRequestStd,
ActiveRequestStore, MpscTcReceiver, ActiveRequestMapProvider, MpscTcReceiver,
}, },
request::UniqueApidTargetId, request::UniqueApidTargetId,
spacepackets::{ spacepackets::{
@@ -558,7 +556,7 @@ pub(crate) mod tests {
// Testbench dedicated to the testing of [PusReplyHandler]s // Testbench dedicated to the testing of [PusReplyHandler]s
pub struct ReplyHandlerTestbench< pub struct ReplyHandlerTestbench<
ReplyHandler: PusReplyHandler<ActiveRequestInfo, Reply, Error = EcssTmtcError>, ReplyHandler: PusReplyHandler<ActiveRequestInfo, Reply, Error = EcssTmtcError>,
ActiveRequestInfo: ActiveRequest, ActiveRequestInfo: ActiveRequestProvider,
Reply, Reply,
> { > {
pub id: ComponentId, pub id: ComponentId,
@@ -572,7 +570,7 @@ pub(crate) mod tests {
impl< impl<
ReplyHandler: PusReplyHandler<ActiveRequestInfo, Reply, Error = EcssTmtcError>, ReplyHandler: PusReplyHandler<ActiveRequestInfo, Reply, Error = EcssTmtcError>,
ActiveRequestInfo: ActiveRequest, ActiveRequestInfo: ActiveRequestProvider,
Reply, Reply,
> ReplyHandlerTestbench<ReplyHandler, ActiveRequestInfo, Reply> > ReplyHandlerTestbench<ReplyHandler, ActiveRequestInfo, Reply>
{ {
@@ -592,7 +590,7 @@ pub(crate) mod tests {
pub fn add_tc( pub fn add_tc(
&mut self, &mut self,
apid: u11, apid: u16,
apid_target: u32, apid_target: u32,
time_stamp: &[u8], time_stamp: &[u8],
) -> (verification::RequestId, ActivePusRequestStd) { ) -> (verification::RequestId, ActivePusRequestStd) {
@@ -602,7 +600,7 @@ pub(crate) mod tests {
sp_header, sp_header,
sec_header_dummy, sec_header_dummy,
&[], &[],
CreatorConfig::default(), true,
)); ));
let accepted = self let accepted = self
.verif_reporter .verif_reporter
@@ -673,7 +671,7 @@ pub(crate) mod tests {
// Testbench dedicated to the testing of [PusTcToRequestConverter]s // Testbench dedicated to the testing of [PusTcToRequestConverter]s
pub struct PusConverterTestbench< pub struct PusConverterTestbench<
Converter: PusTcToRequestConverter<ActiveRequestInfo, Request, Error = GenericConversionError>, Converter: PusTcToRequestConverter<ActiveRequestInfo, Request, Error = GenericConversionError>,
ActiveRequestInfo: ActiveRequest, ActiveRequestInfo: ActiveRequestProvider,
Request, Request,
> { > {
pub id: ComponentId, pub id: ComponentId,
@@ -687,7 +685,7 @@ pub(crate) mod tests {
impl< impl<
Converter: PusTcToRequestConverter<ActiveRequestInfo, Request, Error = GenericConversionError>, Converter: PusTcToRequestConverter<ActiveRequestInfo, Request, Error = GenericConversionError>,
ActiveRequestInfo: ActiveRequest, ActiveRequestInfo: ActiveRequestProvider,
Request, Request,
> PusConverterTestbench<Converter, ActiveRequestInfo, Request> > PusConverterTestbench<Converter, ActiveRequestInfo, Request>
{ {
@@ -721,7 +719,7 @@ pub(crate) mod tests {
&mut self, &mut self,
token: VerificationToken<TcStateAccepted>, token: VerificationToken<TcStateAccepted>,
time_stamp: &[u8], time_stamp: &[u8],
expected_apid: u11, expected_apid: u16,
expected_apid_target: u32, expected_apid_target: u32,
) -> Result<(ActiveRequestInfo, Request), Converter::Error> { ) -> Result<(ActiveRequestInfo, Request), Converter::Error> {
if self.current_packet.is_none() { if self.current_packet.is_none() {
@@ -753,8 +751,8 @@ pub(crate) mod tests {
pub struct TargetedPusRequestTestbench< pub struct TargetedPusRequestTestbench<
RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>, RequestConverter: PusTcToRequestConverter<ActiveRequestInfo, RequestType, Error = GenericConversionError>,
ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>, ReplyHandler: PusReplyHandler<ActiveRequestInfo, ReplyType, Error = EcssTmtcError>,
ActiveRequestMapInstance: ActiveRequestStore<ActiveRequestInfo>, ActiveRequestMap: ActiveRequestMapProvider<ActiveRequestInfo>,
ActiveRequestInfo: ActiveRequest, ActiveRequestInfo: ActiveRequestProvider,
RequestType, RequestType,
ReplyType, ReplyType,
> { > {
@@ -763,7 +761,7 @@ pub(crate) mod tests {
TestVerificationReporter, TestVerificationReporter,
RequestConverter, RequestConverter,
ReplyHandler, ReplyHandler,
ActiveRequestMapInstance, ActiveRequestMap,
ActiveRequestInfo, ActiveRequestInfo,
RequestType, RequestType,
ReplyType, ReplyType,

View File

@@ -1,8 +1,5 @@
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u14;
use derive_new::new; use derive_new::new;
use satrs::mode_tree::{ModeNode, ModeParent}; use satrs::mode_tree::{ModeNode, ModeParent};
use satrs::spacepackets::ecss::CreatorConfig;
use satrs_example::ids; use satrs_example::ids;
use std::sync::mpsc; use std::sync::mpsc;
use std::time::Duration; use std::time::Duration;
@@ -11,8 +8,8 @@ use crate::requests::GenericRequestRouter;
use crate::tmtc::sender::TmTcSender; use crate::tmtc::sender::TmTcSender;
use satrs::pus::verification::VerificationReporter; use satrs::pus::verification::VerificationReporter;
use satrs::pus::{ use satrs::pus::{
DefaultActiveRequestMap, EcssTcAndToken, EcssTcCacher, MpscTcReceiver, PusPacketHandlingError, DefaultActiveRequestMap, EcssTcAndToken, EcssTcInMemConverter, MpscTcReceiver,
PusServiceHelper, PusPacketHandlingError, PusServiceHelper,
}; };
use satrs::request::GenericMessage; use satrs::request::GenericMessage;
use satrs::{ use satrs::{
@@ -23,8 +20,8 @@ use satrs::{
self, FailParams, TcStateAccepted, TcStateStarted, VerificationReportingProvider, self, FailParams, TcStateAccepted, TcStateStarted, VerificationReportingProvider,
VerificationToken, VerificationToken,
}, },
ActivePusRequestStd, ActiveRequest, EcssTmSender, EcssTmtcError, GenericConversionError, ActivePusRequestStd, ActiveRequestProvider, EcssTmSender, EcssTmtcError,
PusReplyHandler, PusTcToRequestConverter, PusTmVariant, GenericConversionError, PusReplyHandler, PusTcToRequestConverter, PusTmVariant,
}, },
request::UniqueApidTargetId, request::UniqueApidTargetId,
spacepackets::{ spacepackets::{
@@ -80,15 +77,10 @@ impl PusReplyHandler<ActivePusRequestStd, ModeReply> for ModeReplyHandler {
.write_to_be_bytes(&mut source_data) .write_to_be_bytes(&mut source_data)
.expect("writing mode reply failed"); .expect("writing mode reply failed");
let req_id = verification::RequestId::from(reply.request_id()); let req_id = verification::RequestId::from(reply.request_id());
let sp_header = SpHeader::new_for_unseg_tm(req_id.packet_id().apid(), u14::ZERO, 0); let sp_header = SpHeader::new_for_unseg_tm(req_id.packet_id().apid(), 0, 0);
let sec_header = let sec_header =
PusTmSecondaryHeader::new(200, Subservice::TmModeReply as u8, 0, 0, time_stamp); PusTmSecondaryHeader::new(200, Subservice::TmModeReply as u8, 0, 0, time_stamp);
let pus_tm = PusTmCreator::new( let pus_tm = PusTmCreator::new(sp_header, sec_header, &source_data, true);
sp_header,
sec_header,
&source_data,
CreatorConfig::default(),
);
tm_sender.send_tm(self.owner_id, PusTmVariant::Direct(pus_tm))?; tm_sender.send_tm(self.owner_id, PusTmVariant::Direct(pus_tm))?;
verification_handler.completion_success(tm_sender, started_token, time_stamp)?; 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( pub fn create_mode_service(
tm_sender: TmTcSender, tm_sender: TmTcSender,
tc_in_mem_converter: EcssTcCacher, tc_in_mem_converter: EcssTcInMemConverter,
pus_action_rx: mpsc::Receiver<EcssTcAndToken>, pus_action_rx: mpsc::Receiver<EcssTcAndToken>,
mode_router: GenericRequestRouter, mode_router: GenericRequestRouter,
reply_receiver: mpsc::Receiver<GenericMessage<ModeReply>>, reply_receiver: mpsc::Receiver<GenericMessage<ModeReply>>,
@@ -298,11 +290,8 @@ impl TargetedPusService for ModeServiceWrapper {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use arbitrary_int::traits::Integer;
use arbitrary_int::u14;
use satrs::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0, TEST_UNIQUE_ID_0}; use satrs::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0, TEST_UNIQUE_ID_0};
use satrs::request::MessageMetadata; use satrs::request::MessageMetadata;
use satrs::spacepackets::ecss::CreatorConfig;
use satrs::{ use satrs::{
mode::{ModeAndSubmode, ModeReply, ModeRequest}, mode::{ModeAndSubmode, ModeReply, ModeRequest},
pus::mode::Subservice, pus::mode::Subservice,
@@ -325,11 +314,11 @@ mod tests {
fn mode_converter_read_mode_request() { fn mode_converter_read_mode_request() {
let mut testbench = let mut testbench =
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default()); PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default());
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(200, Subservice::TcReadMode as u8); let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcReadMode as u8);
let mut app_data: [u8; 4] = [0; 4]; let mut app_data: [u8; 4] = [0; 4];
app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); 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 token = testbench.add_tc(&tc);
let (_active_req, req) = testbench let (_active_req, req) = testbench
.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0) .convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0)
@@ -341,7 +330,7 @@ mod tests {
fn mode_converter_set_mode_request() { fn mode_converter_set_mode_request() {
let mut testbench = let mut testbench =
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default()); PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default());
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(200, Subservice::TcSetMode as u8); 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 mut app_data: [u8; 4 + ModeAndSubmode::RAW_LEN] = [0; 4 + ModeAndSubmode::RAW_LEN];
let mode_and_submode = ModeAndSubmode::new(2, 1); let mode_and_submode = ModeAndSubmode::new(2, 1);
@@ -349,7 +338,7 @@ mod tests {
mode_and_submode mode_and_submode
.write_to_be_bytes(&mut app_data[4..]) .write_to_be_bytes(&mut app_data[4..])
.unwrap(); .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 token = testbench.add_tc(&tc);
let (_active_req, req) = testbench let (_active_req, req) = testbench
.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0) .convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0)
@@ -367,11 +356,11 @@ mod tests {
fn mode_converter_announce_mode() { fn mode_converter_announce_mode() {
let mut testbench = let mut testbench =
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default()); PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default());
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(200, Subservice::TcAnnounceMode as u8); let sec_header = PusTcSecondaryHeader::new_simple(200, Subservice::TcAnnounceMode as u8);
let mut app_data: [u8; 4] = [0; 4]; let mut app_data: [u8; 4] = [0; 4];
app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); 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 token = testbench.add_tc(&tc);
let (_active_req, req) = testbench let (_active_req, req) = testbench
.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0) .convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0)
@@ -383,12 +372,12 @@ mod tests {
fn mode_converter_announce_mode_recursively() { fn mode_converter_announce_mode_recursively() {
let mut testbench = let mut testbench =
PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default()); PusConverterTestbench::new(TEST_COMPONENT_ID_0.id(), ModeRequestConverter::default());
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 = let sec_header =
PusTcSecondaryHeader::new_simple(200, Subservice::TcAnnounceModeRecursive as u8); PusTcSecondaryHeader::new_simple(200, Subservice::TcAnnounceModeRecursive as u8);
let mut app_data: [u8; 4] = [0; 4]; let mut app_data: [u8; 4] = [0; 4];
app_data[0..4].copy_from_slice(&TEST_UNIQUE_ID_0.to_be_bytes()); 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 token = testbench.add_tc(&tc);
let (_active_req, req) = testbench let (_active_req, req) = testbench
.convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0) .convert(token, &[], TEST_APID, TEST_UNIQUE_ID_0)

View File

@@ -9,7 +9,7 @@ use satrs::pus::scheduler::{PusScheduler, TcInfo};
use satrs::pus::scheduler_srv::PusSchedServiceHandler; use satrs::pus::scheduler_srv::PusSchedServiceHandler;
use satrs::pus::verification::VerificationReporter; use satrs::pus::verification::VerificationReporter;
use satrs::pus::{ use satrs::pus::{
DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcCacher, MpscTcReceiver, DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConverter, MpscTcReceiver,
PartialPusHandlingError, PusServiceHelper, PartialPusHandlingError, PusServiceHelper,
}; };
use satrs::spacepackets::ecss::PusServiceId; use satrs::spacepackets::ecss::PusServiceId;
@@ -84,7 +84,7 @@ pub struct SchedulingServiceWrapper {
pub pus_11_handler: PusSchedServiceHandler< pub pus_11_handler: PusSchedServiceHandler<
MpscTcReceiver, MpscTcReceiver,
TmTcSender, TmTcSender,
EcssTcCacher, EcssTcInMemConverter,
VerificationReporter, VerificationReporter,
PusScheduler, PusScheduler,
>, >,
@@ -174,7 +174,7 @@ impl SchedulingServiceWrapper {
pub fn create_scheduler_service( pub fn create_scheduler_service(
tm_sender: TmTcSender, tm_sender: TmTcSender,
tc_in_mem_converter: EcssTcCacher, tc_in_mem_converter: EcssTcInMemConverter,
tc_releaser: TcReleaser, tc_releaser: TcReleaser,
pus_sched_rx: mpsc::Receiver<EcssTcAndToken>, pus_sched_rx: mpsc::Receiver<EcssTcAndToken>,
sched_tc_pool: StaticMemoryPool, sched_tc_pool: StaticMemoryPool,

View File

@@ -6,8 +6,8 @@ use satrs::pus::test::PusService17TestHandler;
use satrs::pus::verification::{FailParams, VerificationReporter, VerificationReportingProvider}; use satrs::pus::verification::{FailParams, VerificationReporter, VerificationReportingProvider};
use satrs::pus::PartialPusHandlingError; use satrs::pus::PartialPusHandlingError;
use satrs::pus::{ use satrs::pus::{
CacheAndReadRawEcssTc, DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcCacher, DirectPusPacketHandlerResult, EcssTcAndToken, EcssTcInMemConversionProvider,
MpscTcReceiver, PusServiceHelper, EcssTcInMemConverter, MpscTcReceiver, PusServiceHelper,
}; };
use satrs::spacepackets::ecss::tc::PusTcReader; use satrs::spacepackets::ecss::tc::PusTcReader;
use satrs::spacepackets::ecss::{PusPacket, PusServiceId}; use satrs::spacepackets::ecss::{PusPacket, PusServiceId};
@@ -19,7 +19,7 @@ use super::{DirectPusService, HandlingStatus};
pub fn create_test_service( pub fn create_test_service(
tm_sender: TmTcSender, tm_sender: TmTcSender,
tc_in_mem_converter: EcssTcCacher, tc_in_mem_converter: EcssTcInMemConverter,
event_sender: mpsc::SyncSender<EventMessageU32>, event_sender: mpsc::SyncSender<EventMessageU32>,
pus_test_rx: mpsc::Receiver<EcssTcAndToken>, pus_test_rx: mpsc::Receiver<EcssTcAndToken>,
) -> TestCustomServiceWrapper { ) -> TestCustomServiceWrapper {
@@ -37,8 +37,12 @@ pub fn create_test_service(
} }
pub struct TestCustomServiceWrapper { pub struct TestCustomServiceWrapper {
pub handler: pub handler: PusService17TestHandler<
PusService17TestHandler<MpscTcReceiver, TmTcSender, EcssTcCacher, VerificationReporter>, MpscTcReceiver,
TmTcSender,
EcssTcInMemConverter,
VerificationReporter,
>,
pub event_tx: mpsc::SyncSender<EventMessageU32>, pub event_tx: mpsc::SyncSender<EventMessageU32>,
} }

View File

@@ -8,7 +8,7 @@ use satrs::mode::ModeRequest;
use satrs::pus::verification::{ use satrs::pus::verification::{
FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken, FailParams, TcStateAccepted, VerificationReportingProvider, VerificationToken,
}; };
use satrs::pus::{ActiveRequest, EcssTmSender, GenericRoutingError, PusRequestRouter}; use satrs::pus::{ActiveRequestProvider, EcssTmSender, GenericRoutingError, PusRequestRouter};
use satrs::queue::GenericSendError; use satrs::queue::GenericSendError;
use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId}; use satrs::request::{GenericMessage, MessageMetadata, UniqueApidTargetId};
use satrs::spacepackets::ecss::tc::PusTcReader; use satrs::spacepackets::ecss::tc::PusTcReader;
@@ -46,7 +46,7 @@ impl Default for GenericRequestRouter {
impl GenericRequestRouter { impl GenericRequestRouter {
pub(crate) fn handle_error_generic( pub(crate) fn handle_error_generic(
&self, &self,
active_request: &impl ActiveRequest, active_request: &impl ActiveRequestProvider,
tc: &PusTcReader, tc: &PusTcReader,
error: GenericRoutingError, error: GenericRoutingError,
tm_sender: &(impl EcssTmSender + ?Sized), tm_sender: &(impl EcssTmSender + ?Sized),

View File

@@ -3,17 +3,18 @@ use std::{
sync::mpsc::{self}, sync::mpsc::{self},
}; };
use arbitrary_int::{u11, u14};
use log::info; use log::info;
use satrs::{ use satrs::{
pool::PoolProvider, pool::PoolProvider,
spacepackets::{ spacepackets::{
ecss::{tm::PusTmZeroCopyWriter, PusPacket}, ecss::{tm::PusTmZeroCopyWriter, PusPacket},
seq_count::SequenceCounter, seq_count::CcsdsSimpleSeqCountProvider,
seq_count::SequenceCounterCcsdsSimple,
time::cds::MIN_CDS_FIELD_LEN, time::cds::MIN_CDS_FIELD_LEN,
CcsdsPacket, CcsdsPacket,
}, },
};
use satrs::{
spacepackets::seq_count::SequenceCountProvider,
tmtc::{PacketAsVec, PacketInPool, SharedPacketPool}, tmtc::{PacketAsVec, PacketInPool, SharedPacketPool},
}; };
@@ -21,16 +22,14 @@ use crate::interface::tcp::SyncTcpTmSource;
#[derive(Default)] #[derive(Default)]
pub struct CcsdsSeqCounterMap { pub struct CcsdsSeqCounterMap {
apid_seq_counter_map: HashMap<u11, SequenceCounterCcsdsSimple>, apid_seq_counter_map: HashMap<u16, CcsdsSimpleSeqCountProvider>,
} }
impl CcsdsSeqCounterMap { impl CcsdsSeqCounterMap {
pub fn get_and_increment(&mut self, apid: u11) -> u14 { pub fn get_and_increment(&mut self, apid: u16) -> u16 {
u14::new(
self.apid_seq_counter_map self.apid_seq_counter_map
.entry(apid) .entry(apid)
.or_default() .or_default()
.get_and_increment(), .get_and_increment()
)
} }
} }
@@ -115,7 +114,7 @@ impl TmSinkStatic {
let mut tm_copy = Vec::new(); let mut tm_copy = Vec::new();
pool_guard pool_guard
.modify(&pus_tm_in_pool.store_addr, |buf| { .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"); .expect("Creating TM zero copy writer failed");
self.common.apply_packet_processing(zero_copy_writer); self.common.apply_packet_processing(zero_copy_writer);
tm_copy = buf.to_vec() tm_copy = buf.to_vec()
@@ -155,8 +154,7 @@ impl TmSinkDynamic {
if let Ok(mut tm) = self.tm_funnel_rx.recv() { if let Ok(mut tm) = self.tm_funnel_rx.recv() {
// Read the TM, set sequence counter and message counter, and finally update // Read the TM, set sequence counter and message counter, and finally update
// the CRC. // the CRC.
let zero_copy_writer = let zero_copy_writer = PusTmZeroCopyWriter::new(&mut tm.packet, MIN_CDS_FIELD_LEN)
PusTmZeroCopyWriter::new(&mut tm.packet, MIN_CDS_FIELD_LEN, true)
.expect("Creating TM zero copy writer failed"); .expect("Creating TM zero copy writer failed");
self.common.apply_packet_processing(zero_copy_writer); self.common.apply_packet_processing(zero_copy_writer);
self.common.sync_tm_tcp_source.add_tm(&tm.packet); self.common.sync_tm_tcp_source.add_tm(&tm.packet);

View File

@@ -8,10 +8,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased] # [unreleased]
# [v0.1.3] 2024-08-26
Bump `satrs-shared`.
# [v0.1.2] 2024-04-17 # [v0.1.2] 2024-04-17
Allow `satrs-shared` from `v0.1.3` to `<v0.2`. 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 # [v0.1.0] 2024-02-12
Initial release containing the `resultcode` macro. 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

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "satrs-mib" name = "satrs-mib"
version = "0.1.3" version = "0.1.2"
edition = "2021" edition = "2021"
rust-version = "1.61" rust-version = "1.61"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"] authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
@@ -23,7 +23,7 @@ version = "1"
optional = true optional = true
[dependencies.satrs-shared] [dependencies.satrs-shared]
version = "0.2" version = "0.2.2"
path = "../satrs-shared" path = "../satrs-shared"
features = ["serde"] features = ["serde"]

View File

@@ -28,7 +28,7 @@ features = ["full"]
trybuild = { version = "1", features = ["diff"] } trybuild = { version = "1", features = ["diff"] }
[dev-dependencies.satrs-shared] [dev-dependencies.satrs-shared]
version = "0.2" version = "0.2.2"
path = "../../satrs-shared" path = "../../satrs-shared"
[dev-dependencies.satrs-mib] [dev-dependencies.satrs-mib]

View File

@@ -11,7 +11,7 @@ serde_json = "1"
log = "0.4" log = "0.4"
thiserror = "2" thiserror = "2"
fern = "0.7" fern = "0.7"
strum = { version = "0.27", features = ["derive"] } strum = { version = "0.26", features = ["derive"] }
num_enum = "0.7" num_enum = "0.7"
humantime = "2" humantime = "2"
tai-time = { version = "0.3", features = ["serde"] } tai-time = { version = "0.3", features = ["serde"] }

View File

@@ -120,7 +120,7 @@ impl SimController {
fn handle_ctrl_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> { fn handle_ctrl_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> {
let sim_ctrl_request = SimCtrlRequest::from_sim_message(request)?; let sim_ctrl_request = SimCtrlRequest::from_sim_message(request)?;
if SIM_CTRL_REQ_WIRETAPPING { 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 { match sim_ctrl_request {
SimCtrlRequest::Ping => { SimCtrlRequest::Ping => {
@@ -139,7 +139,7 @@ impl SimController {
) -> Result<(), SimRequestError> { ) -> Result<(), SimRequestError> {
let mgm_request = MgmRequestLis3Mdl::from_sim_message(request)?; let mgm_request = MgmRequestLis3Mdl::from_sim_message(request)?;
if MGM_REQ_WIRETAPPING { if MGM_REQ_WIRETAPPING {
log::info!("received MGM request: {mgm_request:?}"); log::info!("received MGM request: {:?}", mgm_request);
} }
match mgm_request { match mgm_request {
MgmRequestLis3Mdl::RequestSensorData => { MgmRequestLis3Mdl::RequestSensorData => {
@@ -160,7 +160,7 @@ impl SimController {
fn handle_pcdu_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> { fn handle_pcdu_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> {
let pcdu_request = PcduRequest::from_sim_message(request)?; let pcdu_request = PcduRequest::from_sim_message(request)?;
if PCDU_REQ_WIRETAPPING { if PCDU_REQ_WIRETAPPING {
log::info!("received PCDU request: {pcdu_request:?}"); log::info!("received PCDU request: {:?}", pcdu_request);
} }
match pcdu_request { match pcdu_request {
PcduRequest::RequestSwitchInfo => { PcduRequest::RequestSwitchInfo => {
@@ -188,7 +188,7 @@ impl SimController {
fn handle_mgt_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> { fn handle_mgt_request(&mut self, request: &SimRequest) -> Result<(), SimRequestError> {
let mgt_request = MgtRequest::from_sim_message(request)?; let mgt_request = MgtRequest::from_sim_message(request)?;
if MGT_REQ_WIRETAPPING { if MGT_REQ_WIRETAPPING {
log::info!("received MGT request: {mgt_request:?}"); log::info!("received MGT request: {:?}", mgt_request);
} }
match mgt_request { match mgt_request {
MgtRequest::ApplyTorque { duration, dipole } => self MgtRequest::ApplyTorque { duration, dipole } => self

View File

@@ -130,7 +130,7 @@ fn main() {
let mut udp_server = let mut udp_server =
SimUdpServer::new(SIM_CTRL_PORT, request_sender, reply_receiver, 200, None) SimUdpServer::new(SIM_CTRL_PORT, request_sender, reply_receiver, 200, None)
.expect("could not create UDP request server"); .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. // This thread manages the simulator UDP server.
let udp_tc_thread = thread::spawn(move || { let udp_tc_thread = thread::spawn(move || {
udp_server.run(); udp_server.run();

View File

@@ -8,10 +8,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased] # [unreleased]
# [v0.2.3] 2025-07-22
`spacepackets` range v0.14 to v0.15
# [v0.2.2] 2025-05-10 # [v0.2.2] 2025-05-10
- Bump to `spacepackests` v0.14 - Bump to `spacepackests` v0.14
@@ -50,6 +46,5 @@ Allow `spacepackets` range starting with v0.10 and v0.11.
Initial release. Initial release.
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.3...HEAD [unreleased]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.2...HEAD
[v0.2.3]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.1...satrs-shared-v0.2.3
[v0.2.2]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.1...satrs-shared-v0.2.2 [v0.2.2]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-shared-v0.2.1...satrs-shared-v0.2.2

View File

@@ -1,7 +1,7 @@
[package] [package]
name = "satrs-shared" name = "satrs-shared"
description = "Components shared by multiple sat-rs crates" description = "Components shared by multiple sat-rs crates"
version = "0.2.3" version = "0.2.2"
edition = "2021" edition = "2021"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"] authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
homepage = "https://absatsw.irs.uni-stuttgart.de/projects/sat-rs/" 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 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
spacepackets = { 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] [dependencies.serde]
version = "1" version = "1"

View File

@@ -8,29 +8,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
# [unreleased] # [unreleased]
# [v0.3.0-alpha.3] 2025-09-??
- Bump `sat-rs` edition to 2024.
- Bumped `spacepackets` to v0.16
## 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 # [v0.3.0-alpha.0] 2025-02-18
`spacepackets` v0.13 `spacepackets` v0.13
@@ -221,9 +198,3 @@ docs-rs hotfix
# [v0.1.0] 2024-02-12 # [v0.1.0] 2024-02-12
Initial release. Initial release.
[unreleased]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-v0.3.0-alpha.3...HEAD
[v0.3.0-alpha.3]: https://egit.irs.uni-stuttgart.de/rust/sat-rs/compare/satrs-v0.3.0-alpha.2...satrs-v0.3.0-alpha.3
[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

View File

@@ -1,8 +1,8 @@
[package] [package]
name = "satrs" name = "satrs"
version = "0.3.0-alpha.2" version = "0.3.0-alpha.0"
edition = "2024" edition = "2021"
rust-version = "1.85.0" rust-version = "1.82.0"
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"] authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
description = "A library collection to build software for remote systems" description = "A library collection to build software for remote systems"
homepage = "https://github.com/us-irs/sat-rs" 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"] categories = ["aerospace", "aerospace::space-protocols", "no-std", "hardware-support", "embedded"]
[dependencies] [dependencies]
satrs-shared = { version = "0.2", path = "../satrs-shared" } satrs-shared = { version = "0.2.2", path = "../satrs-shared" }
spacepackets = { version = "0.16", default-features = false } spacepackets = { version = ">=0.14, <=0.15", git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", default-features = false }
delegate = ">0.7, <=0.13" delegate = ">0.7, <=0.13"
paste = "1" paste = "1"
derive-new = ">=0.6, <=0.7" derive-new = ">=0.6, <=0.7"
num_enum = { version = ">0.5, <=0.7", default-features = false } 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 } thiserror = { version = "2", default-features = false }
hashbrown = { version = ">=0.14, <=0.15", optional = true } hashbrown = { version = ">=0.14, <=0.15", optional = true }
static_cell = { version = "2", optional = true } static_cell = { version = "2", optional = true }
dyn-clone = { version = "1", 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 } downcast-rs = { version = "2", default-features = false, optional = true }
bus = { version = "2.2", optional = true } bus = { version = "2.2", optional = true }
crossbeam-channel = { version = "0.5", default-features = false, optional = true } crossbeam-channel = { version = "0.5", default-features = false, optional = true }
serde = { version = "1", 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 }
arbitrary-int = "2"
mio = { version = "1", features = ["os-poll", "net"], optional = true } mio = { version = "1", features = ["os-poll", "net"], optional = true }
defmt = { version = "1", optional = true } defmt = { version = "0.3", optional = true }
[dev-dependencies] [dev-dependencies]
serde = "1" serde = "1"

View File

@@ -1,9 +1,9 @@
use crate::{ use crate::{
ComponentId,
mode::{ModeAndSubmode, ModeReply, ModeRequest, ModeRequestSender}, mode::{ModeAndSubmode, ModeReply, ModeRequest, ModeRequestSender},
mode_tree::{ModeStoreProvider, ModeStoreVec}, mode_tree::{ModeStoreProvider, ModeStoreVec},
queue::{GenericSendError, GenericTargetedMessagingError}, queue::{GenericSendError, GenericTargetedMessagingError},
request::{GenericMessage, RequestId}, request::{GenericMessage, RequestId},
ComponentId,
}; };
use core::fmt::Debug; use core::fmt::Debug;
@@ -270,7 +270,7 @@ impl<UserHook: DevManagerUserHook> DevManagerCommandingHelper<UserHook> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{ use crate::{
mode::{UNKNOWN_MODE, tests::ModeReqSenderMock}, mode::{tests::ModeReqSenderMock, UNKNOWN_MODE},
request::MessageMetadata, request::MessageMetadata,
}; };

View File

@@ -1,6 +1,6 @@
use spacepackets::SpHeader; use spacepackets::{CcsdsPacket, SpHeader};
use crate::{ComponentId, tmtc::PacketSenderRaw}; use crate::{tmtc::PacketSenderRaw, ComponentId};
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SpValidity { 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; let sp_header = SpHeader::from_be_bytes(&buf[current_idx..]).unwrap().0;
match packet_validator.validate(&sp_header, &buf[current_idx..]) { match packet_validator.validate(&sp_header, &buf[current_idx..]) {
SpValidity::Valid => { SpValidity::Valid => {
let packet_size = sp_header.packet_len(); let packet_size = sp_header.total_len();
if (current_idx + packet_size) <= buf_len { if (current_idx + packet_size) <= buf_len {
packet_sender packet_sender
.send_packet(sender_id, &buf[current_idx..current_idx + packet_size])?; .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; continue;
} }
SpValidity::Skip => { 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. // We might have lost sync. Try to find the start of a new space packet header.
SpValidity::Invalid => { SpValidity::Invalid => {
@@ -89,19 +89,18 @@ pub fn parse_buffer_for_ccsds_space_packets<SendError>(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use arbitrary_int::{u11, u14};
use spacepackets::{ use spacepackets::{
CcsdsPacket, PacketId, PacketSequenceControl, PacketType, SequenceFlags, SpHeader, ecss::{tc::PusTcCreator, WritablePusPacket},
ecss::{CreatorConfig, tc::PusTcCreator}, 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 PARSER_ID: ComponentId = 0x05;
const TEST_APID_0: u11 = u11::new(0x02); const TEST_APID_0: u16 = 0x02;
const TEST_APID_1: u11 = u11::new(0x10); const TEST_APID_1: u16 = 0x10;
const TEST_PACKET_ID_0: PacketId = PacketId::new_for_tc(true, TEST_APID_0); 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); const TEST_PACKET_ID_1: PacketId = PacketId::new_for_tc(true, TEST_APID_1);
@@ -132,7 +131,7 @@ mod tests {
#[test] #[test]
fn test_basic() { fn test_basic() {
let sph = SpHeader::new_from_apid(TEST_APID_0); 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 mut buffer: [u8; 32] = [0; 32];
let packet_len = ping_tc let packet_len = ping_tc
.write_to_bytes(&mut buffer) .write_to_bytes(&mut buffer)
@@ -157,8 +156,8 @@ mod tests {
#[test] #[test]
fn test_multi_packet() { fn test_multi_packet() {
let sph = SpHeader::new_from_apid(TEST_APID_0); 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 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 mut buffer: [u8; 32] = [0; 32];
let packet_len_ping = ping_tc let packet_len_ping = ping_tc
.write_to_bytes(&mut buffer) .write_to_bytes(&mut buffer)
@@ -192,9 +191,9 @@ mod tests {
#[test] #[test]
fn test_multi_apid() { fn test_multi_apid() {
let sph = SpHeader::new_from_apid(TEST_APID_0); 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 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 mut buffer: [u8; 32] = [0; 32];
let packet_len_ping = ping_tc let packet_len_ping = ping_tc
.write_to_bytes(&mut buffer) .write_to_bytes(&mut buffer)
@@ -222,20 +221,10 @@ mod tests {
#[test] #[test]
fn test_split_packet_multi() { fn test_split_packet_multi() {
let ping_tc = PusTcCreator::new_simple( let ping_tc =
SpHeader::new_from_apid(TEST_APID_0), PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 17, 1, &[], true);
17, let action_tc =
1, PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_1), 8, 0, &[], true);
&[],
CreatorConfig::default(),
);
let action_tc = PusTcCreator::new_simple(
SpHeader::new_from_apid(TEST_APID_1),
8,
0,
&[],
CreatorConfig::default(),
);
let mut buffer: [u8; 32] = [0; 32]; let mut buffer: [u8; 32] = [0; 32];
let packet_len_ping = ping_tc let packet_len_ping = ping_tc
.write_to_bytes(&mut buffer) .write_to_bytes(&mut buffer)
@@ -266,13 +255,8 @@ mod tests {
#[test] #[test]
fn test_one_split_packet() { fn test_one_split_packet() {
let ping_tc = PusTcCreator::new_simple( let ping_tc =
SpHeader::new_from_apid(TEST_APID_0), PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 17, 1, &[], true);
17,
1,
&[],
CreatorConfig::default(),
);
let mut buffer: [u8; 32] = [0; 32]; let mut buffer: [u8; 32] = [0; 32];
let packet_len_ping = ping_tc let packet_len_ping = ping_tc
.write_to_bytes(&mut buffer) .write_to_bytes(&mut buffer)
@@ -297,7 +281,7 @@ mod tests {
fn test_smallest_packet() { fn test_smallest_packet() {
let ccsds_header_only = SpHeader::new( let ccsds_header_only = SpHeader::new(
PacketId::new(PacketType::Tc, true, TEST_APID_0), PacketId::new(PacketType::Tc, true, TEST_APID_0),
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(0)), PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 0),
0, 0,
); );
let mut buf: [u8; 7] = [0; 7]; let mut buf: [u8; 7] = [0; 7];

View File

@@ -1,4 +1,4 @@
use crate::{ComponentId, tmtc::PacketSenderRaw}; use crate::{tmtc::PacketSenderRaw, ComponentId};
use cobs::{decode_in_place, encode, max_encoding_length}; use cobs::{decode_in_place, encode, max_encoding_length};
/// This function encodes the given packet with COBS and also wraps the encoded packet with /// 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 cobs::encode;
use crate::{ use crate::{
encoding::tests::{encode_simple_packet, TcCacher, INVERTED_PACKET, SIMPLE_PACKET},
ComponentId, ComponentId,
encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET, TcCacher, encode_simple_packet},
}; };
use super::parse_buffer_for_cobs_encoded_packets; use super::parse_buffer_for_cobs_encoded_packets;

View File

@@ -11,8 +11,8 @@ pub(crate) mod tests {
use alloc::collections::VecDeque; use alloc::collections::VecDeque;
use crate::{ use crate::{
ComponentId,
tmtc::{PacketAsVec, PacketSenderRaw}, tmtc::{PacketAsVec, PacketSenderRaw},
ComponentId,
}; };
use super::cobs::encode_packet_with_cobs; use super::cobs::encode_packet_with_cobs;

View File

@@ -71,14 +71,18 @@ pub enum ListenerKey {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct EventMessage<Event: GenericEvent, Parameters: Debug = Params> { pub struct EventMessage<Event: GenericEvent, ParamProvider: Debug = Params> {
sender_id: ComponentId, sender_id: ComponentId,
event: Event, event: Event,
params: Option<Parameters>, params: Option<ParamProvider>,
} }
impl<Event: GenericEvent, Parameters: Debug + Clone> EventMessage<Event, Parameters> { impl<Event: GenericEvent, ParamProvider: Debug + Clone> EventMessage<Event, ParamProvider> {
pub fn new_generic(sender_id: ComponentId, event: Event, params: Option<&Parameters>) -> Self { pub fn new_generic(
sender_id: ComponentId,
event: Event,
params: Option<&ParamProvider>,
) -> Self {
Self { Self {
sender_id, sender_id,
event, event,
@@ -94,7 +98,7 @@ impl<Event: GenericEvent, Parameters: Debug + Clone> EventMessage<Event, Paramet
self.event self.event
} }
pub fn params(&self) -> Option<&Parameters> { pub fn params(&self) -> Option<&ParamProvider> {
self.params.as_ref() self.params.as_ref()
} }
@@ -102,7 +106,7 @@ impl<Event: GenericEvent, Parameters: Debug + Clone> EventMessage<Event, Paramet
Self::new_generic(sender_id, event, None) 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)) Self::new_generic(sender_id, event, Some(params))
} }
} }
@@ -132,7 +136,7 @@ pub trait ListenerMapProvider {
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
fn get_listeners(&self) -> alloc::vec::Vec<ListenerKey>; fn get_listeners(&self) -> alloc::vec::Vec<ListenerKey>;
fn contains_listener(&self, key: &ListenerKey) -> bool; 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 add_listener(&mut self, key: ListenerKey, listener_id: ComponentId) -> bool;
fn remove_duplicates(&mut self, key: &ListenerKey); fn remove_duplicates(&mut self, key: &ListenerKey);
} }
@@ -398,7 +402,7 @@ pub mod alloc_mod {
self.listeners.contains_key(key) 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()) self.listeners.get(key).map(|vec| vec.iter())
} }

View File

@@ -31,9 +31,9 @@ use core::fmt::Debug;
use core::hash::Hash; use core::hash::Hash;
use core::marker::PhantomData; use core::marker::PhantomData;
use delegate::delegate; use delegate::delegate;
use spacepackets::ByteConversionError;
use spacepackets::ecss::EcssEnumeration; use spacepackets::ecss::EcssEnumeration;
use spacepackets::util::{ToBeBytes, UnsignedEnum}; use spacepackets::util::{ToBeBytes, UnsignedEnum};
use spacepackets::ByteConversionError;
/// Using a type definition allows to change this to u64 in the future more easily /// Using a type definition allows to change this to u64 in the future more easily
pub type LargestEventRaw = u32; pub type LargestEventRaw = u32;

View File

@@ -55,8 +55,7 @@ pub fn exec_sched_single<
let mut cycle_count = 0; let mut cycle_count = 0;
thread::Builder::new() thread::Builder::new()
.name(String::from(executable.task_name())) .name(String::from(executable.task_name()))
.spawn(move || { .spawn(move || loop {
loop {
if let Some(ref mut terminator) = termination { if let Some(ref mut terminator) = termination {
match terminator.try_recv() { match terminator.try_recv() {
Ok(_) | Err(TryRecvError::Disconnected) => { Ok(_) | Err(TryRecvError::Disconnected) => {
@@ -84,7 +83,6 @@ pub fn exec_sched_single<
if let Some(freq) = task_freq { if let Some(freq) = task_freq {
thread::sleep(freq); thread::sleep(freq);
} }
}
}) })
} }
@@ -112,8 +110,7 @@ pub fn exec_sched_multi<
thread::Builder::new() thread::Builder::new()
.name(String::from(task_name)) .name(String::from(task_name))
.spawn(move || { .spawn(move || loop {
loop {
if let Some(ref mut terminator) = termination { if let Some(ref mut terminator) = termination {
match terminator.try_recv() { match terminator.try_recv() {
Ok(_) | Err(TryRecvError::Disconnected) => { Ok(_) | Err(TryRecvError::Disconnected) => {
@@ -150,15 +147,14 @@ pub fn exec_sched_multi<
} }
let freq = task_freq.unwrap_or_else(|| panic!("No task frequency specified")); let freq = task_freq.unwrap_or_else(|| panic!("No task frequency specified"));
thread::sleep(freq); thread::sleep(freq);
}
}) })
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{ use super::{
Executable, ExecutableWithType, ExecutionType, OpResult, exec_sched_multi, exec_sched_multi, exec_sched_single, Executable, ExecutableWithType, ExecutionType,
exec_sched_single, OpResult,
}; };
use bus::Bus; use bus::Bus;
use std::boxed::Box; use std::boxed::Box;

View File

@@ -13,10 +13,10 @@ use crate::encoding::parse_buffer_for_cobs_encoded_packets;
use crate::tmtc::PacketSenderRaw; use crate::tmtc::PacketSenderRaw;
use crate::tmtc::PacketSource; use crate::tmtc::PacketSource;
use crate::ComponentId;
use crate::hal::std::tcp_server::{ use crate::hal::std::tcp_server::{
ConnectionResult, ServerConfig, TcpTcParser, TcpTmSender, TcpTmtcError, TcpTmtcGenericServer, ConnectionResult, ServerConfig, TcpTcParser, TcpTmSender, TcpTmtcError, TcpTmtcGenericServer,
}; };
use crate::ComponentId;
use super::tcp_server::HandledConnectionHandler; use super::tcp_server::HandledConnectionHandler;
use super::tcp_server::HandledConnectionInfo; use super::tcp_server::HandledConnectionInfo;
@@ -206,14 +206,14 @@ mod tests {
}; };
use crate::{ use crate::{
ComponentId,
encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET}, encoding::tests::{INVERTED_PACKET, SIMPLE_PACKET},
hal::std::tcp_server::{ hal::std::tcp_server::{
ConnectionResult, ServerConfig,
tests::{ConnectionFinishedHandler, SyncTmSource}, tests::{ConnectionFinishedHandler, SyncTmSource},
ConnectionResult, ServerConfig,
}, },
queue::GenericSendError, queue::GenericSendError,
tmtc::PacketAsVec, tmtc::PacketAsVec,
ComponentId,
}; };
use alloc::sync::Arc; use alloc::sync::Arc;
use cobs::encode; use cobs::encode;
@@ -435,8 +435,7 @@ mod tests {
generic_tmtc_server(&auto_port_addr, tc_sender.clone(), tm_source, None); generic_tmtc_server(&auto_port_addr, tc_sender.clone(), tm_source, None);
let start = Instant::now(); let start = Instant::now();
// Call the connection handler in separate thread, does block. // Call the connection handler in separate thread, does block.
let thread_jh = thread::spawn(move || { let thread_jh = thread::spawn(move || loop {
loop {
let result = tcp_server.handle_all_connections(Some(Duration::from_millis(20))); let result = tcp_server.handle_all_connections(Some(Duration::from_millis(20)));
if result.is_err() { if result.is_err() {
panic!("handling connection failed: {:?}", result.unwrap_err()); panic!("handling connection failed: {:?}", result.unwrap_err());
@@ -448,7 +447,6 @@ mod tests {
if Instant::now() - start > Duration::from_millis(100) { if Instant::now() - start > Duration::from_millis(100) {
panic!("regular stop signal handling failed"); panic!("regular stop signal handling failed");
} }
}
}); });
thread_jh.join().expect("thread join failed"); thread_jh.join().expect("thread join failed");
} }
@@ -471,8 +469,7 @@ mod tests {
let stop_signal_copy = stop_signal.clone(); let stop_signal_copy = stop_signal.clone();
let start = Instant::now(); let start = Instant::now();
// Call the connection handler in separate thread, does block. // Call the connection handler in separate thread, does block.
let thread_jh = thread::spawn(move || { let thread_jh = thread::spawn(move || loop {
loop {
let result = tcp_server.handle_all_connections(Some(Duration::from_millis(20))); let result = tcp_server.handle_all_connections(Some(Duration::from_millis(20)));
if result.is_err() { if result.is_err() {
panic!("handling connection failed: {:?}", result.unwrap_err()); panic!("handling connection failed: {:?}", result.unwrap_err());
@@ -487,7 +484,6 @@ mod tests {
if Instant::now() - start > Duration::from_millis(100) { if Instant::now() - start > Duration::from_millis(100) {
panic!("regular stop signal handling failed"); panic!("regular stop signal handling failed");
} }
}
}); });
// We connect but do not do anything. // We connect but do not do anything.
let _stream = TcpStream::connect(dest_addr).expect("connecting to TCP server failed"); let _stream = TcpStream::connect(dest_addr).expect("connecting to TCP server failed");

View File

@@ -11,8 +11,8 @@ use std::io::{self, Read};
use std::net::SocketAddr; use std::net::SocketAddr;
use std::thread; use std::thread;
use crate::ComponentId;
use crate::tmtc::{PacketSenderRaw, PacketSource}; use crate::tmtc::{PacketSenderRaw, PacketSource};
use crate::ComponentId;
use thiserror::Error; use thiserror::Error;
// Re-export the TMTC in COBS server. // Re-export the TMTC in COBS server.

View File

@@ -5,9 +5,9 @@ use mio::net::{TcpListener, TcpStream};
use std::{io::Write, net::SocketAddr}; use std::{io::Write, net::SocketAddr};
use crate::{ use crate::{
ComponentId,
encoding::{ccsds::SpacePacketValidator, parse_buffer_for_ccsds_space_packets}, encoding::{ccsds::SpacePacketValidator, parse_buffer_for_ccsds_space_packets},
tmtc::{PacketSenderRaw, PacketSource}, tmtc::{PacketSenderRaw, PacketSource},
ComponentId,
}; };
use super::tcp_server::{ use super::tcp_server::{
@@ -183,30 +183,29 @@ mod tests {
}; };
use alloc::sync::Arc; use alloc::sync::Arc;
use arbitrary_int::u11;
use hashbrown::HashSet; use hashbrown::HashSet;
use spacepackets::{ use spacepackets::{
ecss::{tc::PusTcCreator, WritablePusPacket},
CcsdsPacket, PacketId, SpHeader, CcsdsPacket, PacketId, SpHeader,
ecss::{CreatorConfig, WritablePusPacket, tc::PusTcCreator},
}; };
use crate::{ use crate::{
ComponentId,
encoding::ccsds::{SpValidity, SpacePacketValidator}, encoding::ccsds::{SpValidity, SpacePacketValidator},
hal::std::tcp_server::{ hal::std::tcp_server::{
ConnectionResult, ServerConfig,
tests::{ConnectionFinishedHandler, SyncTmSource}, tests::{ConnectionFinishedHandler, SyncTmSource},
ConnectionResult, ServerConfig,
}, },
queue::GenericSendError, queue::GenericSendError,
tmtc::PacketAsVec, tmtc::PacketAsVec,
ComponentId,
}; };
use super::TcpSpacepacketsServer; use super::TcpSpacepacketsServer;
const TCP_SERVER_ID: ComponentId = 0x05; 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_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); const TEST_PACKET_ID_1: PacketId = PacketId::new_for_tc(true, TEST_APID_1);
#[derive(Default)] #[derive(Default)]
@@ -284,13 +283,8 @@ mod tests {
.check_no_connections_left(); .check_no_connections_left();
set_if_done.store(true, Ordering::Relaxed); set_if_done.store(true, Ordering::Relaxed);
}); });
let ping_tc = PusTcCreator::new_simple( let ping_tc =
SpHeader::new_from_apid(TEST_APID_0), PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 17, 1, &[], true);
17,
1,
&[],
CreatorConfig::default(),
);
let tc_0 = ping_tc.to_vec().expect("packet generation failed"); let tc_0 = ping_tc.to_vec().expect("packet generation failed");
let mut stream = TcpStream::connect(dest_addr).expect("connecting to TCP server failed"); let mut stream = TcpStream::connect(dest_addr).expect("connecting to TCP server failed");
stream stream
@@ -320,23 +314,13 @@ mod tests {
// Add telemetry // Add telemetry
let mut total_tm_len = 0; let mut total_tm_len = 0;
let verif_tm = PusTcCreator::new_simple( let verif_tm =
SpHeader::new_from_apid(TEST_APID_0), PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 1, 1, &[], true);
1,
1,
&[],
CreatorConfig::default(),
);
let tm_0 = verif_tm.to_vec().expect("writing packet failed"); let tm_0 = verif_tm.to_vec().expect("writing packet failed");
total_tm_len += tm_0.len(); total_tm_len += tm_0.len();
tm_source.add_tm(&tm_0); tm_source.add_tm(&tm_0);
let verif_tm = PusTcCreator::new_simple( let verif_tm =
SpHeader::new_from_apid(TEST_APID_1), PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_1), 1, 3, &[], true);
1,
3,
&[],
CreatorConfig::default(),
);
let tm_1 = verif_tm.to_vec().expect("writing packet failed"); let tm_1 = verif_tm.to_vec().expect("writing packet failed");
total_tm_len += tm_1.len(); total_tm_len += tm_1.len();
tm_source.add_tm(&tm_1); tm_source.add_tm(&tm_1);
@@ -382,24 +366,14 @@ mod tests {
.expect("setting reas timeout failed"); .expect("setting reas timeout failed");
// Send telecommands // Send telecommands
let ping_tc = PusTcCreator::new_simple( let ping_tc =
SpHeader::new_from_apid(TEST_APID_0), PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_0), 17, 1, &[], true);
17,
1,
&[],
CreatorConfig::default(),
);
let tc_0 = ping_tc.to_vec().expect("ping tc creation failed"); let tc_0 = ping_tc.to_vec().expect("ping tc creation failed");
stream stream
.write_all(&tc_0) .write_all(&tc_0)
.expect("writing to TCP server failed"); .expect("writing to TCP server failed");
let action_tc = PusTcCreator::new_simple( let action_tc =
SpHeader::new_from_apid(TEST_APID_1), PusTcCreator::new_simple(SpHeader::new_from_apid(TEST_APID_1), 8, 0, &[], true);
8,
0,
&[],
CreatorConfig::default(),
);
let tc_1 = action_tc.to_vec().expect("action tc creation failed"); let tc_1 = action_tc.to_vec().expect("action tc creation failed");
stream stream
.write_all(&tc_1) .write_all(&tc_1)

View File

@@ -1,6 +1,6 @@
//! Generic UDP TC server. //! Generic UDP TC server.
use crate::ComponentId;
use crate::tmtc::PacketSenderRaw; use crate::tmtc::PacketSenderRaw;
use crate::ComponentId;
use core::fmt::Debug; use core::fmt::Debug;
use std::io::{self, ErrorKind}; use std::io::{self, ErrorKind};
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
@@ -26,8 +26,7 @@ use std::vec::Vec;
/// use satrs::ComponentId; /// use satrs::ComponentId;
/// use satrs::tmtc::PacketSenderRaw; /// use satrs::tmtc::PacketSenderRaw;
/// use spacepackets::SpHeader; /// use spacepackets::SpHeader;
/// use spacepackets::ecss::tc::{PusTcCreator, CreatorConfig}; /// use spacepackets::ecss::tc::PusTcCreator;
/// use arbitrary_int::u11;
/// ///
/// const UDP_SERVER_ID: ComponentId = 0x05; /// const UDP_SERVER_ID: ComponentId = 0x05;
/// ///
@@ -35,8 +34,8 @@ use std::vec::Vec;
/// let dest_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7777); /// let dest_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7777);
/// let mut udp_tc_server = UdpTcServer::new(UDP_SERVER_ID, dest_addr, 2048, packet_sender) /// let mut udp_tc_server = UdpTcServer::new(UDP_SERVER_ID, dest_addr, 2048, packet_sender)
/// .expect("Creating UDP TMTC server failed"); /// .expect("Creating UDP TMTC server failed");
/// let sph = SpHeader::new_from_apid(u11::new(0x02)); /// let sph = SpHeader::new_from_apid(0x02);
/// let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default()); /// let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
/// // Can not fail. /// // Can not fail.
/// let ping_tc_raw = pus_tc.to_vec().unwrap(); /// let ping_tc_raw = pus_tc.to_vec().unwrap();
/// ///
@@ -106,7 +105,7 @@ impl<TcSender: PacketSenderRaw<Error = SendError>, SendError: Debug + 'static>
Err(ReceiveResult::NothingReceived) Err(ReceiveResult::NothingReceived)
} else { } else {
Err(e.into()) Err(e.into())
}; }
} }
}; };
let (num_bytes, from) = res; let (num_bytes, from) = res;
@@ -124,15 +123,14 @@ impl<TcSender: PacketSenderRaw<Error = SendError>, SendError: Debug + 'static>
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::ComponentId;
use crate::hal::std::udp_server::{ReceiveResult, UdpTcServer}; use crate::hal::std::udp_server::{ReceiveResult, UdpTcServer};
use crate::queue::GenericSendError; use crate::queue::GenericSendError;
use crate::tmtc::PacketSenderRaw; use crate::tmtc::PacketSenderRaw;
use arbitrary_int::u11; use crate::ComponentId;
use core::cell::RefCell; use core::cell::RefCell;
use spacepackets::SpHeader;
use spacepackets::ecss::CreatorConfig;
use spacepackets::ecss::tc::PusTcCreator; use spacepackets::ecss::tc::PusTcCreator;
use spacepackets::ecss::WritablePusPacket;
use spacepackets::SpHeader;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket}; use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
use std::vec::Vec; use std::vec::Vec;
@@ -168,8 +166,8 @@ mod tests {
let mut udp_tc_server = UdpTcServer::new(UDP_SERVER_ID, dest_addr, 2048, ping_receiver) let mut udp_tc_server = UdpTcServer::new(UDP_SERVER_ID, dest_addr, 2048, ping_receiver)
.expect("Creating UDP TMTC server failed"); .expect("Creating UDP TMTC server failed");
is_send(&udp_tc_server); is_send(&udp_tc_server);
let sph = SpHeader::new_from_apid(u11::new(0x02)); let sph = SpHeader::new_from_apid(0x02);
let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default()); let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
let len = pus_tc let len = pus_tc
.write_to_bytes(&mut buf) .write_to_bytes(&mut buf)
.expect("Error writing PUS TC packet"); .expect("Error writing PUS TC packet");

View File

@@ -11,11 +11,11 @@ pub use alloc_mod::*;
pub use std_mod::*; pub use std_mod::*;
use crate::{ use crate::{
ComponentId,
queue::{GenericReceiveError, GenericSendError}, queue::{GenericReceiveError, GenericSendError},
request::{ request::{
GenericMessage, MessageMetadata, MessageReceiverProvider, MessageReceiverWithId, RequestId, GenericMessage, MessageMetadata, MessageReceiverProvider, MessageReceiverWithId, RequestId,
}, },
ComponentId,
}; };
pub type Mode = u32; pub type Mode = u32;
@@ -313,7 +313,8 @@ pub mod alloc_mod {
Sender: MessageSenderProvider<ModeReply>, Sender: MessageSenderProvider<ModeReply>,
Receiver: MessageReceiverProvider<From>, Receiver: MessageReceiverProvider<From>,
SenderStore: MessageSenderStoreProvider<ModeReply, Sender>, SenderStore: MessageSenderStoreProvider<ModeReply, Sender>,
> ModeReplySender for MessageSenderAndReceiver<ModeReply, From, Sender, Receiver, SenderStore> > ModeReplySender
for MessageSenderAndReceiver<ModeReply, From, Sender, Receiver, SenderStore>
{ {
fn local_channel_id(&self) -> ComponentId { fn local_channel_id(&self) -> ComponentId {
self.local_channel_id_generic() self.local_channel_id_generic()
@@ -337,7 +338,8 @@ pub mod alloc_mod {
Sender: MessageSenderProvider<To>, Sender: MessageSenderProvider<To>,
Receiver: MessageReceiverProvider<ModeReply>, Receiver: MessageReceiverProvider<ModeReply>,
SenderStore: MessageSenderStoreProvider<To, Sender>, SenderStore: MessageSenderStoreProvider<To, Sender>,
> ModeReplyReceiver for MessageSenderAndReceiver<To, ModeReply, Sender, Receiver, SenderStore> > ModeReplyReceiver
for MessageSenderAndReceiver<To, ModeReply, Sender, Receiver, SenderStore>
{ {
fn try_recv_mode_reply( fn try_recv_mode_reply(
&self, &self,
@@ -724,7 +726,7 @@ pub(crate) mod tests {
use core::cell::RefCell; use core::cell::RefCell;
use std::collections::VecDeque; use std::collections::VecDeque;
use crate::{ComponentId, request::RequestId}; use crate::{request::RequestId, ComponentId};
use super::*; use super::*;

View File

@@ -2,9 +2,9 @@ use alloc::vec::Vec;
use hashbrown::HashMap; use hashbrown::HashMap;
use crate::{ use crate::{
ComponentId,
mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, Submode}, mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, Submode},
request::MessageSenderProvider, request::MessageSenderProvider,
ComponentId,
}; };
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]

View File

@@ -47,10 +47,10 @@ use crate::pool::PoolAddr;
use core::fmt::Debug; use core::fmt::Debug;
use core::mem::size_of; use core::mem::size_of;
use paste::paste; use paste::paste;
use spacepackets::ByteConversionError; use spacepackets::ecss::{EcssEnumU16, EcssEnumU32, EcssEnumU64, EcssEnumU8};
use spacepackets::ecss::{EcssEnumU8, EcssEnumU16, EcssEnumU32, EcssEnumU64};
pub use spacepackets::util::ToBeBytes; pub use spacepackets::util::ToBeBytes;
use spacepackets::util::UnsignedEnum; use spacepackets::util::UnsignedEnum;
use spacepackets::ByteConversionError;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};

View File

@@ -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 /// 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 /// in the store at its core. The API was designed so internal optimizations can be performed
@@ -281,7 +281,7 @@ pub trait PoolProviderWithGuards: PoolProvider {
/// This can prevent memory leaks. Users can read the data and release the guard /// 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 /// 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. /// 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 /// This function behaves like [PoolProvider::modify], but consumes the provided
/// address and returns a RAII conformant guard object. /// 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 /// 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 /// 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. /// 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> { pub struct PoolGuard<'a, MemProvider: PoolProvider + ?Sized> {
@@ -602,7 +602,7 @@ pub mod heapless_mod {
if i < start_at_subpool as usize { if i < start_at_subpool as usize {
continue; continue;
} }
if pool_cfg.block_size >= req_size { if pool_cfg.block_size as usize >= req_size {
return Ok(i as u16); return Ok(i as u16);
} }
} }
@@ -638,7 +638,7 @@ pub mod heapless_mod {
fn raw_pos(&self, addr: &StaticPoolAddr) -> Option<usize> { fn raw_pos(&self, addr: &StaticPoolAddr) -> Option<usize> {
let (pool_cfg, _) = self.pool.get(addr.pool_idx as 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 subpool_cfg = self.pool.get(addr.pool_idx as usize).unwrap().0;
let raw_pos = self.raw_pos(&addr).unwrap(); let raw_pos = self.raw_pos(&addr).unwrap();
let block = &mut self.pool.get_mut(addr.pool_idx as usize).unwrap().1 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(); let size_list = self.sizes_lists.get_mut(addr.pool_idx as usize).unwrap();
size_list[addr.packet_idx as usize] = STORE_FREE; size_list[addr.packet_idx as usize] = STORE_FREE;
block.fill(0); block.fill(0);
@@ -742,11 +742,11 @@ pub mod heapless_mod {
impl<const MAX_NUM_SUBPOOLS: usize> PoolProviderWithGuards impl<const MAX_NUM_SUBPOOLS: usize> PoolProviderWithGuards
for StaticHeaplessMemoryPool<MAX_NUM_SUBPOOLS> 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) 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) PoolGuard::new(self, addr)
} }
} }
@@ -1058,11 +1058,11 @@ mod alloc_mod {
} }
impl PoolProviderWithGuards for StaticMemoryPool { 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) 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) PoolGuard::new(self, addr)
} }
} }
@@ -1307,11 +1307,9 @@ mod tests {
let addr = pool_provider.add(&test_buf).expect("Adding data failed"); let addr = pool_provider.add(&test_buf).expect("Adding data failed");
let read_guard = PoolGuard::new(pool_provider, addr); let read_guard = PoolGuard::new(pool_provider, addr);
drop(read_guard); drop(read_guard);
assert!( assert!(!pool_provider
!pool_provider
.has_element_at(&addr) .has_element_at(&addr)
.expect("Invalid address") .expect("Invalid address"));
);
} }
fn generic_test_pool_guard_deletion(pool_provider: &mut impl PoolProviderWithGuards) { 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 addr = pool_provider.add(&test_buf).expect("Adding data failed");
let read_guard = pool_provider.read_with_guard(addr); let read_guard = pool_provider.read_with_guard(addr);
drop(read_guard); drop(read_guard);
assert!( assert!(!pool_provider
!pool_provider
.has_element_at(&addr) .has_element_at(&addr)
.expect("Invalid address") .expect("Invalid address"));
);
} }
fn generic_test_pool_guard_with_release(pool_provider: &mut impl PoolProviderWithGuards) { 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); let mut read_guard = PoolGuard::new(pool_provider, addr);
read_guard.release(); read_guard.release();
drop(read_guard); drop(read_guard);
assert!( assert!(pool_provider
pool_provider
.has_element_at(&addr) .has_element_at(&addr)
.expect("Invalid address") .expect("Invalid address"));
);
} }
fn generic_test_pool_modify_guard_man_creation( fn generic_test_pool_modify_guard_man_creation(
@@ -1347,11 +1341,9 @@ mod tests {
let mut rw_guard = PoolRwGuard::new(pool_provider, addr); let mut rw_guard = PoolRwGuard::new(pool_provider, addr);
rw_guard.update(&mut |_| {}).expect("modify failed"); rw_guard.update(&mut |_| {}).expect("modify failed");
drop(rw_guard); drop(rw_guard);
assert!( assert!(!pool_provider
!pool_provider
.has_element_at(&addr) .has_element_at(&addr)
.expect("Invalid address") .expect("Invalid address"));
);
} }
fn generic_test_pool_modify_guard(pool_provider: &mut impl PoolProviderWithGuards) { 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); let mut rw_guard = pool_provider.modify_with_guard(addr);
rw_guard.update(&mut |_| {}).expect("modify failed"); rw_guard.update(&mut |_| {}).expect("modify failed");
drop(rw_guard); drop(rw_guard);
assert!( assert!(!pool_provider
!pool_provider
.has_element_at(&addr) .has_element_at(&addr)
.expect("Invalid address") .expect("Invalid address"));
);
} }
fn generic_modify_pool_index_above_0(pool_provider: &mut impl PoolProvider) { fn generic_modify_pool_index_above_0(pool_provider: &mut impl PoolProvider) {
@@ -1664,36 +1654,30 @@ mod tests {
fn small_heapless_pool() -> StaticHeaplessMemoryPool<3> { fn small_heapless_pool() -> StaticHeaplessMemoryPool<3> {
let mut heapless_pool: StaticHeaplessMemoryPool<3> = let mut heapless_pool: StaticHeaplessMemoryPool<3> =
StaticHeaplessMemoryPool::new(false); StaticHeaplessMemoryPool::new(false);
assert!( assert!(heapless_pool
heapless_pool
.grow( .grow(
SUBPOOL_1.take(), SUBPOOL_1.take(),
unsafe { &mut *SUBPOOL_1_SIZES.lock().unwrap().get() }, unsafe { &mut *SUBPOOL_1_SIZES.lock().unwrap().get() },
SUBPOOL_1_NUM_ELEMENTS, SUBPOOL_1_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
); assert!(heapless_pool
assert!(
heapless_pool
.grow( .grow(
SUBPOOL_2.take(), SUBPOOL_2.take(),
SUBPOOL_2_SIZES.take(), SUBPOOL_2_SIZES.take(),
SUBPOOL_2_NUM_ELEMENTS, SUBPOOL_2_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
); assert!(heapless_pool
assert!(
heapless_pool
.grow( .grow(
SUBPOOL_3.take(), SUBPOOL_3.take(),
SUBPOOL_3_SIZES.take(), SUBPOOL_3_SIZES.take(),
SUBPOOL_3_NUM_ELEMENTS, SUBPOOL_3_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
);
heapless_pool heapless_pool
} }
@@ -1809,26 +1793,22 @@ mod tests {
fn test_spills_to_higher_subpools() { fn test_spills_to_higher_subpools() {
let mut heapless_pool: StaticHeaplessMemoryPool<2> = let mut heapless_pool: StaticHeaplessMemoryPool<2> =
StaticHeaplessMemoryPool::new(true); StaticHeaplessMemoryPool::new(true);
assert!( assert!(heapless_pool
heapless_pool
.grow( .grow(
SUBPOOL_2.take(), SUBPOOL_2.take(),
SUBPOOL_2_SIZES.take(), SUBPOOL_2_SIZES.take(),
SUBPOOL_2_NUM_ELEMENTS, SUBPOOL_2_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
); assert!(heapless_pool
assert!(
heapless_pool
.grow( .grow(
SUBPOOL_4.take(), SUBPOOL_4.take(),
SUBPOOL_4_SIZES.take(), SUBPOOL_4_SIZES.take(),
SUBPOOL_4_NUM_ELEMENTS, SUBPOOL_4_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
);
generic_test_spills_to_higher_subpools(&mut heapless_pool); generic_test_spills_to_higher_subpools(&mut heapless_pool);
} }
@@ -1836,26 +1816,22 @@ mod tests {
fn test_spillage_fails_as_well() { fn test_spillage_fails_as_well() {
let mut heapless_pool: StaticHeaplessMemoryPool<2> = let mut heapless_pool: StaticHeaplessMemoryPool<2> =
StaticHeaplessMemoryPool::new(true); StaticHeaplessMemoryPool::new(true);
assert!( assert!(heapless_pool
heapless_pool
.grow( .grow(
SUBPOOL_5.take(), SUBPOOL_5.take(),
SUBPOOL_5_SIZES.take(), SUBPOOL_5_SIZES.take(),
SUBPOOL_5_NUM_ELEMENTS, SUBPOOL_5_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
); assert!(heapless_pool
assert!(
heapless_pool
.grow( .grow(
SUBPOOL_3.take(), SUBPOOL_3.take(),
SUBPOOL_3_SIZES.take(), SUBPOOL_3_SIZES.take(),
SUBPOOL_3_NUM_ELEMENTS, SUBPOOL_3_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
);
generic_test_spillage_fails_as_well(&mut heapless_pool); generic_test_spillage_fails_as_well(&mut heapless_pool);
} }
@@ -1863,36 +1839,30 @@ mod tests {
fn test_spillage_works_across_multiple_subpools() { fn test_spillage_works_across_multiple_subpools() {
let mut heapless_pool: StaticHeaplessMemoryPool<3> = let mut heapless_pool: StaticHeaplessMemoryPool<3> =
StaticHeaplessMemoryPool::new(true); StaticHeaplessMemoryPool::new(true);
assert!( assert!(heapless_pool
heapless_pool
.grow( .grow(
SUBPOOL_5.take(), SUBPOOL_5.take(),
SUBPOOL_5_SIZES.take(), SUBPOOL_5_SIZES.take(),
SUBPOOL_5_NUM_ELEMENTS, SUBPOOL_5_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
); assert!(heapless_pool
assert!(
heapless_pool
.grow( .grow(
SUBPOOL_6.take(), SUBPOOL_6.take(),
SUBPOOL_6_SIZES.take(), SUBPOOL_6_SIZES.take(),
SUBPOOL_6_NUM_ELEMENTS, SUBPOOL_6_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
); assert!(heapless_pool
assert!(
heapless_pool
.grow( .grow(
SUBPOOL_3.take(), SUBPOOL_3.take(),
SUBPOOL_3_SIZES.take(), SUBPOOL_3_SIZES.take(),
SUBPOOL_3_NUM_ELEMENTS, SUBPOOL_3_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
);
generic_test_spillage_works_across_multiple_subpools(&mut heapless_pool); generic_test_spillage_works_across_multiple_subpools(&mut heapless_pool);
} }
@@ -1900,36 +1870,30 @@ mod tests {
fn test_spillage_fails_across_multiple_subpools() { fn test_spillage_fails_across_multiple_subpools() {
let mut heapless_pool: StaticHeaplessMemoryPool<3> = let mut heapless_pool: StaticHeaplessMemoryPool<3> =
StaticHeaplessMemoryPool::new(true); StaticHeaplessMemoryPool::new(true);
assert!( assert!(heapless_pool
heapless_pool
.grow( .grow(
SUBPOOL_5.take(), SUBPOOL_5.take(),
SUBPOOL_5_SIZES.take(), SUBPOOL_5_SIZES.take(),
SUBPOOL_5_NUM_ELEMENTS, SUBPOOL_5_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
); assert!(heapless_pool
assert!(
heapless_pool
.grow( .grow(
SUBPOOL_6.take(), SUBPOOL_6.take(),
SUBPOOL_6_SIZES.take(), SUBPOOL_6_SIZES.take(),
SUBPOOL_6_NUM_ELEMENTS, SUBPOOL_6_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
); assert!(heapless_pool
assert!(
heapless_pool
.grow( .grow(
SUBPOOL_3.take(), SUBPOOL_3.take(),
SUBPOOL_3_SIZES.take(), SUBPOOL_3_SIZES.take(),
SUBPOOL_3_NUM_ELEMENTS, SUBPOOL_3_NUM_ELEMENTS,
true true
) )
.is_ok() .is_ok());
);
generic_test_spillage_fails_across_multiple_subpools(&mut heapless_pool); generic_test_spillage_fails_across_multiple_subpools(&mut heapless_pool);
} }
} }

View File

@@ -190,7 +190,7 @@ mod tests {
use std::sync::mpsc::{self, TryRecvError}; use std::sync::mpsc::{self, TryRecvError};
use crate::{ComponentId, queue::GenericSendError, request::GenericMessage}; use crate::{queue::GenericSendError, request::GenericMessage, ComponentId};
use super::*; use super::*;

View File

@@ -65,13 +65,13 @@ impl GenericActionReplyPus {
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub mod alloc_mod { pub mod alloc_mod {
use crate::{ use crate::{
ComponentId,
action::ActionRequest, action::ActionRequest,
queue::{GenericReceiveError, GenericSendError}, queue::{GenericReceiveError, GenericSendError},
request::{ request::{
GenericMessage, MessageReceiverProvider, MessageSenderAndReceiver, GenericMessage, MessageReceiverProvider, MessageSenderAndReceiver,
MessageSenderProvider, MessageSenderStoreProvider, RequestId, MessageSenderProvider, MessageSenderStoreProvider, RequestId,
}, },
ComponentId,
}; };
use super::ActionReplyPus; use super::ActionReplyPus;
@@ -141,12 +141,12 @@ pub mod std_mod {
use std::sync::mpsc; use std::sync::mpsc;
use crate::{ use crate::{
ComponentId,
pus::{ pus::{
ActivePusRequestStd, ActiveRequest, DefaultActiveRequestMap,
verification::{self, TcStateToken}, verification::{self, TcStateToken},
ActivePusRequestStd, ActiveRequestProvider, DefaultActiveRequestMap,
}, },
request::{MessageSenderMap, OneMessageSender}, request::{MessageSenderMap, OneMessageSender},
ComponentId,
}; };
use super::*; use super::*;
@@ -157,7 +157,7 @@ pub mod std_mod {
common: ActivePusRequestStd, common: ActivePusRequestStd,
} }
impl ActiveRequest for ActivePusActionRequestStd { impl ActiveRequestProvider for ActivePusActionRequestStd {
delegate::delegate! { delegate::delegate! {
to self.common { to self.common {
fn target_id(&self) -> ComponentId; fn target_id(&self) -> ComponentId;

View File

@@ -1,11 +1,9 @@
use crate::pus::source_buffer_large_enough; use crate::pus::source_buffer_large_enough;
use arbitrary_int::u11;
use spacepackets::ByteConversionError;
use spacepackets::SpHeader;
use spacepackets::ecss::CreatorConfig;
use spacepackets::ecss::EcssEnumeration;
use spacepackets::ecss::tm::PusTmCreator; use spacepackets::ecss::tm::PusTmCreator;
use spacepackets::ecss::tm::PusTmSecondaryHeader; use spacepackets::ecss::tm::PusTmSecondaryHeader;
use spacepackets::ecss::EcssEnumeration;
use spacepackets::ByteConversionError;
use spacepackets::{SpHeader, MAX_APID};
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub use alloc_mod::*; pub use alloc_mod::*;
@@ -13,13 +11,16 @@ pub use alloc_mod::*;
pub use spacepackets::ecss::event::*; pub use spacepackets::ecss::event::*;
pub struct EventReportCreator { pub struct EventReportCreator {
apid: u11, apid: u16,
pub dest_id: u16, pub dest_id: u16,
} }
impl EventReportCreator { impl EventReportCreator {
pub fn new(apid: u11, dest_id: u16) -> Self { pub fn new(apid: u16, dest_id: u16) -> Option<Self> {
Self { dest_id, apid } if apid > MAX_APID {
return None;
}
Some(Self { dest_id, apid })
} }
pub fn event_info<'time, 'src_data>( pub fn event_info<'time, 'src_data>(
@@ -123,7 +124,7 @@ impl EventReportCreator {
SpHeader::new_from_apid(self.apid), SpHeader::new_from_apid(self.apid),
sec_header, sec_header,
&src_data_buf[0..current_idx], &src_data_buf[0..current_idx],
CreatorConfig::default(), true,
)) ))
} }
} }
@@ -131,64 +132,64 @@ impl EventReportCreator {
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
mod alloc_mod { mod alloc_mod {
use super::*; use super::*;
use crate::ComponentId;
use crate::pus::{EcssTmSender, EcssTmtcError}; use crate::pus::{EcssTmSender, EcssTmtcError};
use crate::ComponentId;
use alloc::vec; use alloc::vec;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::cell::RefCell; use core::cell::RefCell;
use spacepackets::ecss::PusError; use spacepackets::ecss::PusError;
pub trait EventTmHook { pub trait EventTmHookProvider {
fn modify_tm(&self, tm: &mut PusTmCreator); fn modify_tm(&self, tm: &mut PusTmCreator);
} }
#[derive(Default)] #[derive(Default)]
pub struct DummyEventHook {} pub struct DummyEventHook {}
impl EventTmHook for DummyEventHook { impl EventTmHookProvider for DummyEventHook {
fn modify_tm(&self, _tm: &mut PusTmCreator) {} fn modify_tm(&self, _tm: &mut PusTmCreator) {}
} }
pub struct EventReporter<EventTmHookInstance: EventTmHook = DummyEventHook> { pub struct EventReporter<EventTmHook: EventTmHookProvider = DummyEventHook> {
id: ComponentId, id: ComponentId,
// Use interior mutability pattern here. This is just an intermediate buffer to the PUS event packet // Use interior mutability pattern here. This is just an intermediate buffer to the PUS event packet
// generation. // generation.
source_data_buf: RefCell<Vec<u8>>, source_data_buf: RefCell<Vec<u8>>,
pub report_creator: EventReportCreator, pub report_creator: EventReportCreator,
pub tm_hook: EventTmHookInstance, pub tm_hook: EventTmHook,
} }
impl EventReporter<DummyEventHook> { impl EventReporter<DummyEventHook> {
pub fn new( pub fn new(
id: ComponentId, id: ComponentId,
default_apid: u11, default_apid: u16,
default_dest_id: u16, default_dest_id: u16,
max_event_id_and_aux_data_size: usize, max_event_id_and_aux_data_size: usize,
) -> Self { ) -> Option<Self> {
let reporter = EventReportCreator::new(default_apid, default_dest_id); let reporter = EventReportCreator::new(default_apid, default_dest_id)?;
Self { Some(Self {
id, id,
source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]), source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]),
report_creator: reporter, report_creator: reporter,
tm_hook: DummyEventHook::default(), tm_hook: DummyEventHook::default(),
})
} }
} }
} impl<EventTmHook: EventTmHookProvider> EventReporter<EventTmHook> {
impl<EventTmHookInstance: EventTmHook> EventReporter<EventTmHookInstance> {
pub fn new_with_hook( pub fn new_with_hook(
id: ComponentId, id: ComponentId,
default_apid: u11, default_apid: u16,
default_dest_id: u16, default_dest_id: u16,
max_event_id_and_aux_data_size: usize, max_event_id_and_aux_data_size: usize,
tm_hook: EventTmHookInstance, tm_hook: EventTmHook,
) -> Self { ) -> Option<Self> {
let reporter = EventReportCreator::new(default_apid, default_dest_id); let reporter = EventReportCreator::new(default_apid, default_dest_id)?;
Self { Some(Self {
id, id,
source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]), source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]),
report_creator: reporter, report_creator: reporter,
tm_hook, tm_hook,
} })
} }
pub fn event_info( pub fn event_info(
@@ -264,18 +265,18 @@ mod alloc_mod {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::ComponentId;
use crate::events::{EventU32, Severity}; use crate::events::{EventU32, Severity};
use crate::pus::test_util::TEST_COMPONENT_ID_0; use crate::pus::test_util::TEST_COMPONENT_ID_0;
use crate::pus::tests::CommonTmInfo; use crate::pus::tests::CommonTmInfo;
use crate::pus::{ChannelWithId, EcssTmSender, EcssTmtcError, PusTmVariant}; use crate::pus::{ChannelWithId, EcssTmSender, EcssTmtcError, PusTmVariant};
use spacepackets::ByteConversionError; use crate::ComponentId;
use spacepackets::ecss::PusError; use spacepackets::ecss::PusError;
use spacepackets::ByteConversionError;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::vec::Vec; use std::vec::Vec;
const EXAMPLE_APID: u11 = u11::new(0xee); const EXAMPLE_APID: u16 = 0xee;
const EXAMPLE_GROUP_ID: u16 = 2; const EXAMPLE_GROUP_ID: u16 = 2;
const EXAMPLE_EVENT_ID_0: u16 = 1; const EXAMPLE_EVENT_ID_0: u16 = 1;
#[allow(dead_code)] #[allow(dead_code)]
@@ -375,12 +376,14 @@ mod tests {
error_data: Option<&[u8]>, error_data: Option<&[u8]>,
) { ) {
let mut sender = TestSender::default(); let mut sender = TestSender::default();
let mut reporter = EventReporter::new( let reporter = EventReporter::new(
TEST_COMPONENT_ID_0.id(), TEST_COMPONENT_ID_0.id(),
EXAMPLE_APID, EXAMPLE_APID,
0, 0,
max_event_aux_data_buf, max_event_aux_data_buf,
); );
assert!(reporter.is_some());
let mut reporter = reporter.unwrap();
let time_stamp_empty: [u8; 7] = [0; 7]; let time_stamp_empty: [u8; 7] = [0; 7];
let mut error_copy = Vec::new(); let mut error_copy = Vec::new();
if let Some(err_data) = error_data { if let Some(err_data) = error_data {
@@ -471,7 +474,9 @@ mod tests {
fn insufficient_buffer() { fn insufficient_buffer() {
let mut sender = TestSender::default(); let mut sender = TestSender::default();
for i in 0..3 { for i in 0..3 {
let mut reporter = EventReporter::new(0, EXAMPLE_APID, 0, i); let reporter = EventReporter::new(0, EXAMPLE_APID, 0, i);
assert!(reporter.is_some());
let mut reporter = reporter.unwrap();
check_buf_too_small(&mut reporter, &mut sender, i); check_buf_too_small(&mut reporter, &mut sender, i);
} }
} }

View File

@@ -6,13 +6,13 @@ use core::hash::Hash;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use hashbrown::HashSet; use hashbrown::HashSet;
#[cfg(feature = "alloc")]
use crate::pus::EcssTmSender;
use crate::pus::EcssTmtcError;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub use crate::pus::event::EventReporter; pub use crate::pus::event::EventReporter;
use crate::pus::verification::TcStateToken; use crate::pus::verification::TcStateToken;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use crate::pus::EcssTmSender;
use crate::pus::EcssTmtcError;
#[cfg(feature = "alloc")]
pub use alloc_mod::*; pub use alloc_mod::*;
#[cfg(feature = "heapless")] #[cfg(feature = "heapless")]
pub use heapless_mod::*; pub use heapless_mod::*;
@@ -46,7 +46,7 @@ pub mod heapless_mod {
// regular Event type again. // regular Event type again.
#[derive(Default)] #[derive(Default)]
pub struct HeaplessPusMgmtBackendProvider<const N: usize, Provider: GenericEvent> { pub struct HeaplessPusMgmtBackendProvider<const N: usize, Provider: GenericEvent> {
disabled: heapless::index_set::FnvIndexSet<LargestEventRaw, N>, disabled: heapless::FnvIndexSet<LargestEventRaw, N>,
phantom: PhantomData<Provider>, phantom: PhantomData<Provider>,
} }
@@ -102,7 +102,7 @@ pub mod alloc_mod {
use crate::{ use crate::{
events::EventU16, events::EventU16,
params::{Params, WritableToBeBytes}, params::{Params, WritableToBeBytes},
pus::event::{DummyEventHook, EventTmHook}, pus::event::{DummyEventHook, EventTmHookProvider},
}; };
use super::*; use super::*;
@@ -151,9 +151,9 @@ pub mod alloc_mod {
pub struct PusEventTmCreatorWithMap< pub struct PusEventTmCreatorWithMap<
ReportingMap: PusEventReportingMapProvider<Event>, ReportingMap: PusEventReportingMapProvider<Event>,
Event: GenericEvent, Event: GenericEvent,
EventTmHookInstance: EventTmHook = DummyEventHook, EventTmHook: EventTmHookProvider = DummyEventHook,
> { > {
pub reporter: EventReporter<EventTmHookInstance>, pub reporter: EventReporter<EventTmHook>,
reporting_map: ReportingMap, reporting_map: ReportingMap,
phantom: PhantomData<Event>, phantom: PhantomData<Event>,
} }
@@ -161,10 +161,10 @@ pub mod alloc_mod {
impl< impl<
ReportingMap: PusEventReportingMapProvider<Event>, ReportingMap: PusEventReportingMapProvider<Event>,
Event: GenericEvent, Event: GenericEvent,
EventTmHookInstance: EventTmHook, EventTmHook: EventTmHookProvider,
> PusEventTmCreatorWithMap<ReportingMap, Event, EventTmHookInstance> > PusEventTmCreatorWithMap<ReportingMap, Event, EventTmHook>
{ {
pub fn new(reporter: EventReporter<EventTmHookInstance>, backend: ReportingMap) -> Self { pub fn new(reporter: EventReporter<EventTmHook>, backend: ReportingMap) -> Self {
Self { Self {
reporter, reporter,
reporting_map: backend, reporting_map: backend,
@@ -262,10 +262,10 @@ pub mod alloc_mod {
} }
} }
impl<Event: GenericEvent + Copy + PartialEq + Eq + Hash, EventTmHookInstance: EventTmHook> impl<Event: GenericEvent + Copy + PartialEq + Eq + Hash, EventTmHook: EventTmHookProvider>
PusEventTmCreatorWithMap<DefaultPusEventReportingMap<Event>, Event, EventTmHookInstance> 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 { Self {
reporter, reporter,
reporting_map: DefaultPusEventReportingMap::default(), reporting_map: DefaultPusEventReportingMap::default(),
@@ -311,10 +311,9 @@ pub mod alloc_mod {
mod tests { mod tests {
use alloc::string::{String, ToString}; use alloc::string::{String, ToString};
use alloc::vec; use alloc::vec;
use arbitrary_int::u11;
use spacepackets::ecss::PusPacket;
use spacepackets::ecss::event::Subservice; use spacepackets::ecss::event::Subservice;
use spacepackets::ecss::tm::PusTmReader; use spacepackets::ecss::tm::PusTmReader;
use spacepackets::ecss::PusPacket;
use super::*; use super::*;
use crate::request::UniqueApidTargetId; use crate::request::UniqueApidTargetId;
@@ -324,15 +323,17 @@ mod tests {
const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::<SeverityInfo>::new(1, 0); const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::<SeverityInfo>::new(1, 0);
const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5); const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5);
const EMPTY_STAMP: [u8; 7] = [0; 7]; 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); const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
fn create_basic_man_1() -> DefaultPusEventU32TmCreator { fn create_basic_man_1() -> DefaultPusEventU32TmCreator {
let reporter = EventReporter::new(TEST_ID.raw(), TEST_APID, 0, 128); let reporter = EventReporter::new(TEST_ID.raw(), TEST_APID, 0, 128)
.expect("Creating event repoter failed");
PusEventTmCreatorWithMap::new_with_default_backend(reporter) PusEventTmCreatorWithMap::new_with_default_backend(reporter)
} }
fn create_basic_man_2() -> DefaultPusEventU32TmCreator { fn create_basic_man_2() -> DefaultPusEventU32TmCreator {
let reporter = EventReporter::new(TEST_ID.raw(), TEST_APID, 0, 128); let reporter = EventReporter::new(TEST_ID.raw(), TEST_APID, 0, 128)
.expect("Creating event repoter failed");
let backend = DefaultPusEventReportingMap::default(); let backend = DefaultPusEventReportingMap::default();
PusEventTmCreatorWithMap::new(reporter, backend) PusEventTmCreatorWithMap::new(reporter, backend)
} }

View File

@@ -3,20 +3,20 @@ use crate::pus::event_man::{EventRequest, EventRequestWithToken};
use crate::pus::verification::TcStateToken; use crate::pus::verification::TcStateToken;
use crate::pus::{DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError}; use crate::pus::{DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError};
use crate::queue::GenericSendError; use crate::queue::GenericSendError;
use spacepackets::ecss::PusPacket;
use spacepackets::ecss::event::Subservice; use spacepackets::ecss::event::Subservice;
use spacepackets::ecss::PusPacket;
use std::sync::mpsc::Sender; use std::sync::mpsc::Sender;
use super::verification::VerificationReportingProvider; use super::verification::VerificationReportingProvider;
use super::{ use super::{
CacheAndReadRawEcssTc, EcssTcReceiver, EcssTmSender, GenericConversionError, EcssTcInMemConversionProvider, EcssTcReceiver, EcssTmSender, GenericConversionError,
GenericRoutingError, HandlingStatus, PusServiceHelper, GenericRoutingError, HandlingStatus, PusServiceHelper,
}; };
pub struct PusEventServiceHandler< pub struct PusEventServiceHandler<
TcReceiver: EcssTcReceiver, TcReceiver: EcssTcReceiver,
TmSender: EcssTmSender, TmSender: EcssTmSender,
TcInMemConverter: CacheAndReadRawEcssTc, TcInMemConverter: EcssTcInMemConversionProvider,
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
> { > {
pub service_helper: pub service_helper:
@@ -27,7 +27,7 @@ pub struct PusEventServiceHandler<
impl< impl<
TcReceiver: EcssTcReceiver, TcReceiver: EcssTcReceiver,
TmSender: EcssTmSender, TmSender: EcssTmSender,
TcInMemConverter: CacheAndReadRawEcssTc, TcInMemConverter: EcssTcInMemConversionProvider,
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
> PusEventServiceHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter> > PusEventServiceHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
{ {
@@ -122,7 +122,7 @@ impl<
| Subservice::TmHighSeverityReport => { | Subservice::TmHighSeverityReport => {
return Err(PusPacketHandlingError::RequestConversion( return Err(PusPacketHandlingError::RequestConversion(
GenericConversionError::WrongService(tc.subservice()), GenericConversionError::WrongService(tc.subservice()),
)); ))
} }
Subservice::TcEnableEventGeneration => { Subservice::TcEnableEventGeneration => {
handle_enable_disable_request(true)?; handle_enable_disable_request(true)?;
@@ -144,19 +144,16 @@ impl<
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u14;
use delegate::delegate; use delegate::delegate;
use spacepackets::ecss::CreatorConfig;
use spacepackets::ecss::event::Subservice; use spacepackets::ecss::event::Subservice;
use spacepackets::time::{TimeWriter, cds}; use spacepackets::time::{cds, TimeWriter};
use spacepackets::util::UnsignedEnum; use spacepackets::util::UnsignedEnum;
use spacepackets::{ use spacepackets::{
SpHeader,
ecss::{ ecss::{
tc::{PusTcCreator, PusTcSecondaryHeader}, tc::{PusTcCreator, PusTcSecondaryHeader},
tm::PusTmReader, tm::PusTmReader,
}, },
SpHeader,
}; };
use std::sync::mpsc::{self, Sender}; use std::sync::mpsc::{self, Sender};
@@ -170,10 +167,10 @@ mod tests {
use crate::{ use crate::{
events::EventU32, events::EventU32,
pus::{ pus::{
DirectPusPacketHandlerResult, EcssTcInSharedPoolCacher, PusPacketHandlingError,
event_man::EventRequestWithToken, event_man::EventRequestWithToken,
tests::PusServiceHandlerWithSharedStoreCommon, tests::PusServiceHandlerWithSharedStoreCommon,
verification::{TcStateAccepted, VerificationToken}, verification::{TcStateAccepted, VerificationToken},
DirectPusPacketHandlerResult, EcssTcInSharedPoolConverter, PusPacketHandlingError,
}, },
}; };
@@ -186,7 +183,7 @@ mod tests {
handler: PusEventServiceHandler< handler: PusEventServiceHandler<
MpscTcReceiver, MpscTcReceiver,
PacketSenderWithSharedPool, PacketSenderWithSharedPool,
EcssTcInSharedPoolCacher, EcssTcInSharedPoolConverter,
VerificationReporter, VerificationReporter,
>, >,
} }
@@ -245,13 +242,13 @@ mod tests {
expected_event_req: EventRequest, expected_event_req: EventRequest,
event_req_receiver: mpsc::Receiver<EventRequestWithToken>, 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 sec_header = PusTcSecondaryHeader::new_simple(5, subservice as u8);
let mut app_data = [0; 4]; let mut app_data = [0; 4];
TEST_EVENT_0 TEST_EVENT_0
.write_to_be_bytes(&mut app_data) .write_to_be_bytes(&mut app_data)
.expect("writing test event failed"); .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); let token = test_harness.start_verification(&ping_tc);
test_harness.send_tc(&token, &ping_tc); test_harness.send_tc(&token, &ping_tc);
let request_id = token.request_id(); let request_id = token.request_id();
@@ -310,10 +307,9 @@ mod tests {
fn test_sending_custom_subservice() { fn test_sending_custom_subservice() {
let (event_request_tx, _) = mpsc::channel(); let (event_request_tx, _) = mpsc::channel();
let mut test_harness = Pus5HandlerWithStoreTester::new(event_request_tx); 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 sec_header = PusTcSecondaryHeader::new_simple(5, 200);
let ping_tc = let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
let token = test_harness.start_verification(&ping_tc); let token = test_harness.start_verification(&ping_tc);
test_harness.send_tc(&token, &ping_tc); test_harness.send_tc(&token, &ping_tc);
let result = test_harness.handle_one_tc(); let result = test_harness.handle_one_tc();
@@ -330,11 +326,10 @@ mod tests {
fn test_sending_invalid_app_data() { fn test_sending_invalid_app_data() {
let (event_request_tx, _) = mpsc::channel(); let (event_request_tx, _) = mpsc::channel();
let mut test_harness = Pus5HandlerWithStoreTester::new(event_request_tx); 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 = let sec_header =
PusTcSecondaryHeader::new_simple(5, Subservice::TcEnableEventGeneration as u8); PusTcSecondaryHeader::new_simple(5, Subservice::TcEnableEventGeneration as u8);
let ping_tc = let ping_tc = PusTcCreator::new(sp_header, sec_header, &[0, 1, 2], true);
PusTcCreator::new(sp_header, sec_header, &[0, 1, 2], CreatorConfig::default());
let token = test_harness.start_verification(&ping_tc); let token = test_harness.start_verification(&ping_tc);
test_harness.send_tc(&token, &ping_tc); test_harness.send_tc(&token, &ping_tc);
let result = test_harness.handle_one_tc(); let result = test_harness.handle_one_tc();

View File

@@ -2,7 +2,6 @@
//! //!
//! This module contains structures to make working with the PUS C standard easier. //! This module contains structures to make working with the PUS C standard easier.
//! The satrs-example application contains various usage examples of these components. //! The satrs-example application contains various usage examples of these components.
use crate::ComponentId;
use crate::pool::{PoolAddr, PoolError}; use crate::pool::{PoolAddr, PoolError};
use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken}; use crate::pus::verification::{TcStateAccepted, TcStateToken, VerificationToken};
use crate::queue::{GenericReceiveError, GenericSendError}; use crate::queue::{GenericReceiveError, GenericSendError};
@@ -10,18 +9,19 @@ use crate::request::{GenericMessage, MessageMetadata, RequestId};
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use crate::tmtc::PacketAsVec; use crate::tmtc::PacketAsVec;
use crate::tmtc::PacketInPool; use crate::tmtc::PacketInPool;
use crate::ComponentId;
use core::fmt::{Display, Formatter}; use core::fmt::{Display, Formatter};
use core::time::Duration; use core::time::Duration;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use downcast_rs::{Downcast, impl_downcast}; use downcast_rs::{impl_downcast, Downcast};
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use dyn_clone::DynClone; use dyn_clone::DynClone;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::error::Error; use std::error::Error;
use spacepackets::ecss::PusError;
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader}; use spacepackets::ecss::tc::{PusTcCreator, PusTcReader};
use spacepackets::ecss::tm::PusTmCreator; use spacepackets::ecss::tm::PusTmCreator;
use spacepackets::ecss::PusError;
use spacepackets::{ByteConversionError, SpHeader}; use spacepackets::{ByteConversionError, SpHeader};
pub mod action; pub mod action;
@@ -296,7 +296,7 @@ pub trait PacketSenderPusTc: Send {
) -> Result<(), Self::Error>; ) -> Result<(), Self::Error>;
} }
pub trait ActiveRequestStore<V>: Sized { pub trait ActiveRequestMapProvider<V>: Sized {
fn insert(&mut self, request_id: &RequestId, request_info: V); fn insert(&mut self, request_id: &RequestId, request_info: V);
fn get(&self, request_id: RequestId) -> Option<&V>; fn get(&self, request_id: RequestId) -> Option<&V>;
fn get_mut(&mut self, request_id: RequestId) -> Option<&mut 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); 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 target_id(&self) -> ComponentId;
fn token(&self) -> TcStateToken; fn token(&self) -> TcStateToken;
fn set_token(&mut self, token: TcStateToken); fn set_token(&mut self, token: TcStateToken);
@@ -330,7 +330,7 @@ pub trait PusRequestRouter<Request> {
) -> Result<(), Self::Error>; ) -> Result<(), Self::Error>;
} }
pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequest, ReplyType> { pub trait PusReplyHandler<ActiveRequestInfo: ActiveRequestProvider, ReplyType> {
type Error; type Error;
/// This function handles a reply for a given PUS request and returns whether that request /// This function handles a reply for a given PUS request and returns whether that request
@@ -449,7 +449,7 @@ pub mod alloc_mod {
/// Having a dedicated trait for this allows maximum flexiblity and tailoring of the standard. /// Having a dedicated trait for this allows maximum flexiblity and tailoring of the standard.
/// The only requirement is that a valid active request information instance and a request /// The only requirement is that a valid active request information instance and a request
/// are returned by the core conversion function. The active request type needs to fulfill /// are returned by the core conversion function. The active request type needs to fulfill
/// the [ActiveRequest] trait bound. /// the [ActiveRequestProvider] trait bound.
/// ///
/// The user should take care of performing the error handling as well. Some of the following /// The user should take care of performing the error handling as well. Some of the following
/// aspects might be relevant: /// aspects might be relevant:
@@ -459,7 +459,7 @@ pub mod alloc_mod {
/// ///
/// A [VerificationReportingProvider] instance is passed to the user to also allow handling /// A [VerificationReportingProvider] instance is passed to the user to also allow handling
/// of the verification process as part of the PUS standard requirements. /// 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; type Error;
fn convert( fn convert(
&mut self, &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) { fn insert(&mut self, request_id: &RequestId, request: V) {
self.0.insert(*request_id, request); self.0.insert(*request_id, request);
} }
@@ -659,18 +659,18 @@ pub mod alloc_mod {
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub mod std_mod { pub mod std_mod {
use super::*; use super::*;
use crate::ComponentId;
use crate::pool::{ use crate::pool::{
PoolAddr, PoolError, PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool, PoolAddr, PoolError, PoolProvider, PoolProviderWithGuards, SharedStaticMemoryPool,
}; };
use crate::pus::verification::{TcStateAccepted, VerificationToken}; use crate::pus::verification::{TcStateAccepted, VerificationToken};
use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool}; use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool};
use crate::ComponentId;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::time::Duration; use core::time::Duration;
use spacepackets::ByteConversionError;
use spacepackets::ecss::WritablePusPacket;
use spacepackets::ecss::tc::PusTcReader; use spacepackets::ecss::tc::PusTcReader;
use spacepackets::ecss::WritablePusPacket;
use spacepackets::time::StdTimestampError; use spacepackets::time::StdTimestampError;
use spacepackets::ByteConversionError;
use std::string::String; use std::string::String;
use std::sync::mpsc; use std::sync::mpsc;
use std::sync::mpsc::TryRecvError; use std::sync::mpsc::TryRecvError;
@@ -680,7 +680,7 @@ pub mod std_mod {
pub use cb_mod::*; pub use cb_mod::*;
use super::verification::{TcStateToken, VerificationReportingProvider}; use super::verification::{TcStateToken, VerificationReportingProvider};
use super::{AcceptedEcssTcAndToken, ActiveRequest, TcInMemory}; use super::{AcceptedEcssTcAndToken, ActiveRequestProvider, TcInMemory};
use crate::tmtc::PacketInPool; use crate::tmtc::PacketInPool;
impl From<mpsc::SendError<PoolAddr>> for EcssTmtcError { 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 { fn target_id(&self) -> ComponentId {
self.target_id self.target_id
} }
@@ -947,9 +947,7 @@ pub mod std_mod {
} }
} }
/// This trait provides an abstraction for caching a raw ECSS telecommand and then pub trait EcssTcInMemConversionProvider {
/// providing the [PusTcReader] abstraction to read the cache raw telecommand.
pub trait CacheAndReadRawEcssTc {
fn cache(&mut self, possible_packet: &TcInMemory) -> Result<(), PusTcFromMemError>; fn cache(&mut self, possible_packet: &TcInMemory) -> Result<(), PusTcFromMemError>;
fn tc_slice_raw(&self) -> &[u8]; 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 /// Please note that this structure is not able to convert TCs which are stored inside a
/// [SharedStaticMemoryPool]. /// [SharedStaticMemoryPool].
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct EcssTcVecCacher { pub struct EcssTcInVecConverter {
sender_id: Option<ComponentId>, sender_id: Option<ComponentId>,
pub pus_tc_raw: Option<Vec<u8>>, 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> { fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
self.pus_tc_raw = None; self.pus_tc_raw = None;
match tc_in_memory { 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 /// packets should be avoided. Please note that this structure is not able to convert TCs which
/// are stored as a `Vec<u8>`. /// are stored as a `Vec<u8>`.
#[derive(Clone)] #[derive(Clone)]
pub struct EcssTcInSharedPoolCacher { pub struct EcssTcInSharedPoolConverter {
sender_id: Option<ComponentId>, sender_id: Option<ComponentId>,
shared_tc_pool: SharedStaticMemoryPool, shared_tc_pool: SharedStaticMemoryPool,
pus_buf: Vec<u8>, pus_buf: Vec<u8>,
} }
impl EcssTcInSharedPoolCacher { impl EcssTcInSharedPoolConverter {
pub fn new(shared_tc_store: SharedStaticMemoryPool, max_expected_tc_size: usize) -> Self { pub fn new(shared_tc_store: SharedStaticMemoryPool, max_expected_tc_size: usize) -> Self {
Self { Self {
sender_id: None, 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> { fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
match tc_in_memory { match tc_in_memory {
super::TcInMemory::Pool(packet_in_pool) => { super::TcInMemory::Pool(packet_in_pool) => {
@@ -1072,38 +1070,38 @@ pub mod std_mod {
// TODO: alloc feature flag? // TODO: alloc feature flag?
#[derive(Clone)] #[derive(Clone)]
pub enum EcssTcCacher { pub enum EcssTcInMemConverter {
Static(EcssTcInSharedPoolCacher), Static(EcssTcInSharedPoolConverter),
Heap(EcssTcVecCacher), Heap(EcssTcInVecConverter),
} }
impl EcssTcCacher { impl EcssTcInMemConverter {
pub fn new_static(static_store_converter: EcssTcInSharedPoolCacher) -> Self { pub fn new_static(static_store_converter: EcssTcInSharedPoolConverter) -> Self {
Self::Static(static_store_converter) EcssTcInMemConverter::Static(static_store_converter)
} }
pub fn new_heap(heap_converter: EcssTcVecCacher) -> Self { pub fn new_heap(heap_converter: EcssTcInVecConverter) -> Self {
Self::Heap(heap_converter) EcssTcInMemConverter::Heap(heap_converter)
} }
} }
impl CacheAndReadRawEcssTc for EcssTcCacher { impl EcssTcInMemConversionProvider for EcssTcInMemConverter {
fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> { fn cache(&mut self, tc_in_memory: &TcInMemory) -> Result<(), PusTcFromMemError> {
match self { match self {
Self::Static(converter) => converter.cache(tc_in_memory), EcssTcInMemConverter::Static(converter) => converter.cache(tc_in_memory),
Self::Heap(converter) => converter.cache(tc_in_memory), EcssTcInMemConverter::Heap(converter) => converter.cache(tc_in_memory),
} }
} }
fn tc_slice_raw(&self) -> &[u8] { fn tc_slice_raw(&self) -> &[u8] {
match self { match self {
Self::Static(converter) => converter.tc_slice_raw(), EcssTcInMemConverter::Static(converter) => converter.tc_slice_raw(),
Self::Heap(converter) => converter.tc_slice_raw(), EcssTcInMemConverter::Heap(converter) => converter.tc_slice_raw(),
} }
} }
fn sender_id(&self) -> Option<ComponentId> { fn sender_id(&self) -> Option<ComponentId> {
match self { match self {
Self::Static(converter) => converter.sender_id(), EcssTcInMemConverter::Static(converter) => converter.sender_id(),
Self::Heap(converter) => converter.sender_id(), EcssTcInMemConverter::Heap(converter) => converter.sender_id(),
} }
} }
} }
@@ -1126,12 +1124,12 @@ pub mod std_mod {
/// groups (for example individual services). /// groups (for example individual services).
/// ///
/// This base class can handle PUS telecommands backed by different memory storage machanisms /// This base class can handle PUS telecommands backed by different memory storage machanisms
/// by using the [CacheAndReadRawEcssTc] abstraction. This object provides some convenience /// by using the [EcssTcInMemConverter] abstraction. This object provides some convenience
/// methods to make the generic parts of TC handling easier. /// methods to make the generic parts of TC handling easier.
pub struct PusServiceHelper< pub struct PusServiceHelper<
TcReceiver: EcssTcReceiver, TcReceiver: EcssTcReceiver,
TmSender: EcssTmSender, TmSender: EcssTmSender,
TcInMemConverter: CacheAndReadRawEcssTc, TcInMemConverter: EcssTcInMemConversionProvider,
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
> { > {
pub common: PusServiceBase<TcReceiver, TmSender, VerificationReporter>, pub common: PusServiceBase<TcReceiver, TmSender, VerificationReporter>,
@@ -1141,7 +1139,7 @@ pub mod std_mod {
impl< impl<
TcReceiver: EcssTcReceiver, TcReceiver: EcssTcReceiver,
TmSender: EcssTmSender, TmSender: EcssTmSender,
TcInMemConverter: CacheAndReadRawEcssTc, TcInMemConverter: EcssTcInMemConversionProvider,
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
> PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter> > PusServiceHelper<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
{ {
@@ -1258,17 +1256,16 @@ pub(crate) fn source_buffer_large_enough(
#[cfg(any(feature = "test_util", test))] #[cfg(any(feature = "test_util", test))]
pub mod test_util { pub mod test_util {
use arbitrary_int::u11;
use spacepackets::ecss::{tc::PusTcCreator, tm::PusTmReader}; use spacepackets::ecss::{tc::PusTcCreator, tm::PusTmReader};
use crate::request::UniqueApidTargetId; use crate::request::UniqueApidTargetId;
use super::{ use super::{
DirectPusPacketHandlerResult, PusPacketHandlingError,
verification::{self, TcStateAccepted, VerificationToken}, 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_0: u32 = 0x05;
pub const TEST_UNIQUE_ID_1: u32 = 0x06; pub const TEST_UNIQUE_ID_1: u32 = 0x06;
@@ -1299,35 +1296,33 @@ pub mod test_util {
pub mod tests { pub mod tests {
use core::cell::RefCell; use core::cell::RefCell;
use std::sync::mpsc::TryRecvError; use std::sync::mpsc::TryRecvError;
use std::sync::{RwLock, mpsc}; use std::sync::{mpsc, RwLock};
use alloc::collections::VecDeque; use alloc::collections::VecDeque;
use alloc::vec::Vec; use alloc::vec::Vec;
use arbitrary_int::{u11, u14};
use satrs_shared::res_code::ResultU16; use satrs_shared::res_code::ResultU16;
use spacepackets::CcsdsPacket;
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader}; use spacepackets::ecss::tc::{PusTcCreator, PusTcReader};
use spacepackets::ecss::tm::{GenericPusTmSecondaryHeader, PusTmCreator, PusTmReader}; use spacepackets::ecss::tm::{GenericPusTmSecondaryHeader, PusTmCreator, PusTmReader};
use spacepackets::ecss::{PusPacket, WritablePusPacket}; use spacepackets::ecss::{PusPacket, WritablePusPacket};
use spacepackets::CcsdsPacket;
use test_util::{TEST_APID, TEST_COMPONENT_ID_0}; use test_util::{TEST_APID, TEST_COMPONENT_ID_0};
use crate::ComponentId;
use crate::pool::{PoolProvider, SharedStaticMemoryPool, StaticMemoryPool, StaticPoolConfig}; use crate::pool::{PoolProvider, SharedStaticMemoryPool, StaticMemoryPool, StaticPoolConfig};
use crate::pus::verification::{RequestId, VerificationReporter}; use crate::pus::verification::{RequestId, VerificationReporter};
use crate::tmtc::{PacketAsVec, PacketInPool, PacketSenderWithSharedPool, SharedPacketPool}; use crate::tmtc::{PacketAsVec, PacketInPool, PacketSenderWithSharedPool, SharedPacketPool};
use crate::ComponentId;
use super::verification::test_util::TestVerificationReporter; use super::verification::test_util::TestVerificationReporter;
use super::verification::{ use super::verification::{
TcStateAccepted, VerificationReporterConfig, VerificationReportingProvider, TcStateAccepted, VerificationReporterCfg, VerificationReportingProvider, VerificationToken,
VerificationToken,
}; };
use super::*; use super::*;
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
pub(crate) struct CommonTmInfo { pub(crate) struct CommonTmInfo {
pub subservice: u8, pub subservice: u8,
pub apid: u11, pub apid: u16,
pub seq_count: u14, pub seq_count: u16,
pub msg_counter: u16, pub msg_counter: u16,
pub dest_id: u16, pub dest_id: u16,
pub timestamp: Vec<u8>, pub timestamp: Vec<u8>,
@@ -1336,8 +1331,8 @@ pub mod tests {
impl CommonTmInfo { impl CommonTmInfo {
pub fn new( pub fn new(
subservice: u8, subservice: u8,
apid: u11, apid: u16,
seq_count: u14, seq_count: u16,
msg_counter: u16, msg_counter: u16,
dest_id: u16, dest_id: u16,
timestamp: &[u8], timestamp: &[u8],
@@ -1353,11 +1348,11 @@ pub mod tests {
} }
pub fn new_zero_seq_count( pub fn new_zero_seq_count(
subservice: u8, subservice: u8,
apid: u11, apid: u16,
dest_id: u16, dest_id: u16,
timestamp: &[u8], timestamp: &[u8],
) -> Self { ) -> 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 { pub fn new_from_tm(tm: &PusTmCreator) -> Self {
@@ -1387,7 +1382,7 @@ pub mod tests {
pub type PusServiceHelperStatic = PusServiceHelper< pub type PusServiceHelperStatic = PusServiceHelper<
MpscTcReceiver, MpscTcReceiver,
PacketSenderWithSharedPool, PacketSenderWithSharedPool,
EcssTcInSharedPoolCacher, EcssTcInSharedPoolConverter,
VerificationReporter, VerificationReporter,
>; >;
@@ -1409,12 +1404,12 @@ pub mod tests {
let (test_srv_tc_tx, test_srv_tc_rx) = mpsc::sync_channel(10); let (test_srv_tc_tx, test_srv_tc_rx) = mpsc::sync_channel(10);
let (tm_tx, tm_rx) = mpsc::sync_channel(10); let (tm_tx, tm_rx) = mpsc::sync_channel(10);
let verif_cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8); let verif_cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
let verification_handler = let verification_handler =
VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &verif_cfg); VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &verif_cfg);
let test_srv_tm_sender = let test_srv_tm_sender =
PacketSenderWithSharedPool::new(tm_tx, shared_tm_pool_wrapper.clone()); 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 { Self {
pus_buf: RefCell::new([0; 2048]), pus_buf: RefCell::new([0; 2048]),
@@ -1492,8 +1487,12 @@ pub mod tests {
tc_sender: mpsc::Sender<EcssTcAndToken>, tc_sender: mpsc::Sender<EcssTcAndToken>,
tm_receiver: mpsc::Receiver<PacketAsVec>, tm_receiver: mpsc::Receiver<PacketAsVec>,
} }
pub type PusServiceHelperDynamic = pub type PusServiceHelperDynamic = PusServiceHelper<
PusServiceHelper<MpscTcReceiver, MpscTmAsVecSender, EcssTcVecCacher, VerificationReporter>; MpscTcReceiver,
MpscTmAsVecSender,
EcssTcInVecConverter,
VerificationReporter,
>;
impl PusServiceHandlerWithVecCommon { impl PusServiceHandlerWithVecCommon {
pub fn new_with_standard_verif_reporter( 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 (test_srv_tc_tx, test_srv_tc_rx) = mpsc::channel();
let (tm_tx, tm_rx) = mpsc::channel(); let (tm_tx, tm_rx) = mpsc::channel();
let verif_cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8); let verif_cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
let verification_handler = let verification_handler =
VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &verif_cfg); VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &verif_cfg);
let in_store_converter = EcssTcVecCacher::default(); let in_store_converter = EcssTcInVecConverter::default();
( (
Self { Self {
current_tm: None, current_tm: None,
@@ -1531,14 +1530,14 @@ pub mod tests {
PusServiceHelper< PusServiceHelper<
MpscTcReceiver, MpscTcReceiver,
MpscTmAsVecSender, MpscTmAsVecSender,
EcssTcVecCacher, EcssTcInVecConverter,
TestVerificationReporter, TestVerificationReporter,
>, >,
) { ) {
let (test_srv_tc_tx, test_srv_tc_rx) = mpsc::channel(); let (test_srv_tc_tx, test_srv_tc_rx) = mpsc::channel();
let (tm_tx, tm_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); let verification_handler = TestVerificationReporter::new(id);
( (
Self { Self {

View File

@@ -2,7 +2,6 @@
//! //!
//! The core data structure of this module is the [PusScheduler]. This structure can be used //! 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. //! 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::fmt::{Debug, Display, Formatter};
use core::time::Duration; use core::time::Duration;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
@@ -25,26 +24,22 @@ pub use alloc_mod::*;
/// the source ID found in the secondary header of PUS telecommands. /// the source ID found in the secondary header of PUS telecommands.
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct RequestId { pub struct RequestId {
pub(crate) source_id: u16, pub(crate) source_id: u16,
pub(crate) apid: u11, pub(crate) apid: u16,
pub(crate) seq_count: u14, pub(crate) seq_count: u16,
} }
impl RequestId { impl RequestId {
#[inline] pub fn source_id(&self) -> u16 {
pub const fn source_id(&self) -> u16 {
self.source_id self.source_id
} }
#[inline] pub fn apid(&self) -> u16 {
pub const fn apid(&self) -> u11 {
self.apid self.apid
} }
#[inline] pub fn seq_count(&self) -> u16 {
pub const fn seq_count(&self) -> u14 {
self.seq_count self.seq_count
} }
@@ -58,10 +53,8 @@ impl RequestId {
} }
} }
pub const fn as_u64(&self) -> u64 { pub fn as_u64(&self) -> u64 {
((self.source_id as u64) << 32) ((self.source_id as u64) << 32) | ((self.apid as u64) << 16) | self.seq_count as u64
| ((self.apid.value() as u64) << 16)
| self.seq_count.value() as u64
} }
} }
@@ -347,8 +340,8 @@ pub fn generate_insert_telecommand_app_data(
pub mod alloc_mod { pub mod alloc_mod {
use alloc::{ use alloc::{
collections::{ collections::{
BTreeMap,
btree_map::{Entry, Range}, btree_map::{Entry, Range},
BTreeMap,
}, },
vec::Vec, vec::Vec,
}; };
@@ -862,12 +855,10 @@ mod tests {
PoolAddr, PoolError, PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig, PoolAddr, PoolError, PoolProvider, StaticMemoryPool, StaticPoolAddr, StaticPoolConfig,
}; };
use alloc::collections::btree_map::Range; use alloc::collections::btree_map::Range;
use arbitrary_int::traits::Integer;
use arbitrary_int::{u11, u14};
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader}; use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
use spacepackets::ecss::{CreatorConfig, WritablePusPacket}; use spacepackets::ecss::WritablePusPacket;
use spacepackets::time::{TimeWriter, UnixTime, cds}; use spacepackets::time::{cds, TimeWriter, UnixTime};
use spacepackets::{PacketId, PacketSequenceControl, PacketType, SequenceFlags, SpHeader}; use spacepackets::{PacketId, PacketSequenceCtrl, PacketType, SequenceFlags, SpHeader};
use std::time::Duration; use std::time::Duration;
use std::vec::Vec; use std::vec::Vec;
#[allow(unused_imports)] #[allow(unused_imports)]
@@ -878,66 +869,59 @@ mod tests {
cds::CdsTime::from_unix_time_with_u16_days(&timestamp, cds::SubmillisPrecision::Absent) cds::CdsTime::from_unix_time_with_u16_days(&timestamp, cds::SubmillisPrecision::Absent)
.unwrap(); .unwrap();
let len_time_stamp = cds_time.write_to_bytes(buf).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..]) .write_to_bytes(&mut buf[len_time_stamp..])
.unwrap(); .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, 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); 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); 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); 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 = let cds_time =
cds::CdsTime::from_unix_time_with_u16_days(&timestamp, cds::SubmillisPrecision::Absent) cds::CdsTime::from_unix_time_with_u16_days(&timestamp, cds::SubmillisPrecision::Absent)
.unwrap(); .unwrap();
let len_time_stamp = cds_time.write_to_bytes(buf).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 // app data should not matter, double wrapped time-tagged commands should be rejected right
// away // away
let inner_time_tagged_tc = let inner_time_tagged_tc = PusTcCreator::new_simple(sph, 11, 4, &[], true);
PusTcCreator::new_simple(sph, 11, 4, &[], CreatorConfig::default());
let packet_len = inner_time_tagged_tc let packet_len = inner_time_tagged_tc
.write_to_bytes(&mut buf[len_time_stamp..]) .write_to_bytes(&mut buf[len_time_stamp..])
.expect("writing inner time tagged tc failed"); .expect("writing inner time tagged tc failed");
PusTcCreator::new_simple( PusTcCreator::new_simple(sph, 11, 4, &buf[..len_time_stamp + packet_len], true)
sph,
11,
4,
&buf[..len_time_stamp + packet_len],
CreatorConfig::default(),
)
} }
fn invalid_time_tagged_cmd() -> PusTcCreator<'static> { fn invalid_time_tagged_cmd() -> PusTcCreator<'static> {
let sph = SpHeader::new_for_unseg_tc(u11::new(0x02), u14::new(0x34), 1); let sph = SpHeader::new_for_unseg_tc(0x02, 0x34, 1);
PusTcCreator::new_simple(sph, 11, 4, &[], CreatorConfig::default()) PusTcCreator::new_simple(sph, 11, 4, &[], true)
} }
fn base_ping_tc_simple_ctor(seq_count: u14, app_data: &'static [u8]) -> PusTcCreator<'static> { fn base_ping_tc_simple_ctor(seq_count: u16, app_data: &'static [u8]) -> PusTcCreator<'static> {
let sph = SpHeader::new_for_unseg_tc(u11::new(0x02), seq_count, 0); let sph = SpHeader::new_for_unseg_tc(0x02, seq_count, 0);
PusTcCreator::new_simple(sph, 17, 1, app_data, CreatorConfig::default()) PusTcCreator::new_simple(sph, 17, 1, app_data, true)
} }
fn ping_tc_to_store( fn ping_tc_to_store(
pool: &mut StaticMemoryPool, pool: &mut StaticMemoryPool,
buf: &mut [u8], buf: &mut [u8],
seq_count: u14, seq_count: u16,
app_data: &'static [u8], app_data: &'static [u8],
) -> TcInfo { ) -> TcInfo {
let ping_tc = base_ping_tc_simple_ctor(seq_count, app_data); let ping_tc = base_ping_tc_simple_ctor(seq_count, app_data);
@@ -965,7 +949,7 @@ mod tests {
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; 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 scheduler
.insert_unwrapped_and_stored_tc( .insert_unwrapped_and_stored_tc(
@@ -975,7 +959,7 @@ mod tests {
.unwrap(); .unwrap();
let app_data = &[0, 1, 2]; 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 scheduler
.insert_unwrapped_and_stored_tc( .insert_unwrapped_and_stored_tc(
UnixTime::new_only_secs(200), UnixTime::new_only_secs(200),
@@ -984,7 +968,7 @@ mod tests {
.unwrap(); .unwrap();
let app_data = &[0, 1, 2]; 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 scheduler
.insert_unwrapped_and_stored_tc( .insert_unwrapped_and_stored_tc(
UnixTime::new_only_secs(300), UnixTime::new_only_secs(300),
@@ -1015,8 +999,8 @@ mod tests {
packet_idx: 1, packet_idx: 1,
}), }),
RequestId { RequestId {
seq_count: u14::new(1), seq_count: 1,
apid: u11::ZERO, apid: 0,
source_id: 0, source_id: 0,
}, },
), ),
@@ -1032,8 +1016,8 @@ mod tests {
packet_idx: 2, packet_idx: 2,
}), }),
RequestId { RequestId {
seq_count: u14::new(2), seq_count: 2,
apid: u11::new(1), apid: 1,
source_id: 5, source_id: 5,
}, },
), ),
@@ -1051,8 +1035,8 @@ mod tests {
.into(), .into(),
RequestId { RequestId {
source_id: 10, source_id: 10,
seq_count: u14::new(20), seq_count: 20,
apid: u11::new(23), apid: 23,
}, },
), ),
) )
@@ -1093,22 +1077,19 @@ mod tests {
#[test] #[test]
fn test_request_id() { fn test_request_id() {
let src_id_to_set = 12; let src_id_to_set = 12;
let apid_to_set = u11::new(0x22); let apid_to_set = 0x22;
let seq_count = u14::new(105); let seq_count = 105;
let sp_header = SpHeader::new_for_unseg_tc(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); let mut sec_header = PusTcSecondaryHeader::new_simple(17, 1);
sec_header.source_id = src_id_to_set; sec_header.source_id = src_id_to_set;
let ping_tc = let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
let req_id = RequestId::from_tc(&ping_tc); let req_id = RequestId::from_tc(&ping_tc);
assert_eq!(req_id.source_id(), src_id_to_set); assert_eq!(req_id.source_id(), src_id_to_set);
assert_eq!(req_id.apid(), apid_to_set); assert_eq!(req_id.apid(), apid_to_set);
assert_eq!(req_id.seq_count(), seq_count); assert_eq!(req_id.seq_count(), seq_count);
assert_eq!( assert_eq!(
req_id.as_u64(), req_id.as_u64(),
((src_id_to_set as u64) << 32) ((src_id_to_set as u64) << 32) | (apid_to_set as u64) << 16 | seq_count as u64
| (apid_to_set.value() as u64) << 16
| seq_count.value() as u64
); );
} }
#[test] #[test]
@@ -1120,13 +1101,13 @@ mod tests {
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("insertion failed"); .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 scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1)
.expect("insertion failed"); .expect("insertion failed");
@@ -1188,13 +1169,13 @@ mod tests {
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("insertion failed"); .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 scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_1) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_1)
.expect("insertion failed"); .expect("insertion failed");
@@ -1250,13 +1231,13 @@ mod tests {
scheduler.disable(); scheduler.disable();
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("insertion failed"); .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 scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1)
.expect("insertion failed"); .expect("insertion failed");
@@ -1317,7 +1298,7 @@ mod tests {
false, false,
)); ));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
let info = scheduler let info = scheduler
.insert_unwrapped_tc( .insert_unwrapped_tc(
@@ -1332,7 +1313,7 @@ mod tests {
let mut read_buf: [u8; 64] = [0; 64]; let mut read_buf: [u8; 64] = [0; 64];
pool.read(&tc_info_0.addr(), &mut read_buf).unwrap(); pool.read(&tc_info_0.addr(), &mut read_buf).unwrap();
let check_tc = PusTcReader::new(&read_buf).expect("incorrect Pus tc raw data"); let check_tc = PusTcReader::new(&read_buf).expect("incorrect Pus tc raw data");
assert_eq!(check_tc, base_ping_tc_simple_ctor(u14::ZERO, &[])); assert_eq!(check_tc, base_ping_tc_simple_ctor(0, &[]));
assert_eq!(scheduler.num_scheduled_telecommands(), 1); assert_eq!(scheduler.num_scheduled_telecommands(), 1);
@@ -1354,8 +1335,8 @@ mod tests {
let read_len = pool.read(&addr_vec[0], &mut read_buf).unwrap(); 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"); let check_tc = PusTcReader::new(&read_buf).expect("incorrect Pus tc raw data");
assert_eq!(read_len, check_tc.packet_len()); assert_eq!(read_len, check_tc.total_len());
assert_eq!(check_tc, base_ping_tc_simple_ctor(u14::new(0), &[])); assert_eq!(check_tc, base_ping_tc_simple_ctor(0, &[]));
} }
#[test] #[test]
@@ -1381,8 +1362,8 @@ mod tests {
let read_len = pool.read(&info.addr, &mut buf).unwrap(); let read_len = pool.read(&info.addr, &mut buf).unwrap();
let check_tc = PusTcReader::new(&buf).expect("incorrect Pus tc raw data"); let check_tc = PusTcReader::new(&buf).expect("incorrect Pus tc raw data");
assert_eq!(read_len, check_tc.packet_len()); assert_eq!(read_len, check_tc.total_len());
assert_eq!(check_tc, base_ping_tc_simple_ctor(u14::ZERO, &[])); assert_eq!(check_tc, base_ping_tc_simple_ctor(0, &[]));
assert_eq!(scheduler.num_scheduled_telecommands(), 1); assert_eq!(scheduler.num_scheduled_telecommands(), 1);
@@ -1406,8 +1387,8 @@ mod tests {
let read_len = pool.read(&addr_vec[0], &mut buf).unwrap(); let read_len = pool.read(&addr_vec[0], &mut buf).unwrap();
let check_tc = PusTcReader::new(&buf).expect("incorrect PUS tc raw data"); let check_tc = PusTcReader::new(&buf).expect("incorrect PUS tc raw data");
assert_eq!(read_len, check_tc.packet_len()); assert_eq!(read_len, check_tc.total_len());
assert_eq!(check_tc, base_ping_tc_simple_ctor(u14::new(0), &[])); assert_eq!(check_tc, base_ping_tc_simple_ctor(0, &[]));
} }
#[test] #[test]
@@ -1550,7 +1531,7 @@ mod tests {
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("insertion failed"); .expect("insertion failed");
@@ -1587,7 +1568,7 @@ mod tests {
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("insertion failed"); .expect("insertion failed");
@@ -1613,7 +1594,7 @@ mod tests {
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("inserting tc failed"); .expect("inserting tc failed");
@@ -1634,7 +1615,7 @@ mod tests {
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("inserting tc failed"); .expect("inserting tc failed");
@@ -1655,15 +1636,15 @@ mod tests {
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("inserting tc failed"); .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 scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_1) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_1)
.expect("inserting tc failed"); .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 scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_2) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_2)
.expect("inserting tc failed"); .expect("inserting tc failed");
@@ -1722,7 +1703,7 @@ mod tests {
fn insert_command_with_release_time( fn insert_command_with_release_time(
pool: &mut StaticMemoryPool, pool: &mut StaticMemoryPool,
scheduler: &mut PusScheduler, scheduler: &mut PusScheduler,
seq_count: u14, seq_count: u16,
release_secs: u64, release_secs: u64,
) -> TcInfo { ) -> TcInfo {
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
@@ -1741,8 +1722,8 @@ mod tests {
false, false,
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); 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::ZERO, 50); 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, u14::ZERO, 100); let tc_info_1 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
assert_eq!(scheduler.num_scheduled_telecommands(), 2); assert_eq!(scheduler.num_scheduled_telecommands(), 2);
let check_range = |range: Range<UnixTime, Vec<TcInfo>>| { let check_range = |range: Range<UnixTime, Vec<TcInfo>>| {
let mut tcs_in_range = 0; let mut tcs_in_range = 0;
@@ -1773,9 +1754,9 @@ mod tests {
false, false,
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); 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::ZERO, 50); 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, u14::ZERO, 100); 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, u14::ZERO, 150); 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( let start_stamp = cds::CdsTime::from_unix_time_with_u16_days(
&UnixTime::new_only_secs(100), &UnixTime::new_only_secs(100),
cds::SubmillisPrecision::Absent, cds::SubmillisPrecision::Absent,
@@ -1808,9 +1789,9 @@ mod tests {
false, false,
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); 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::ZERO, 50); 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, u14::ZERO, 100); 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, u14::ZERO, 150); let _ = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
assert_eq!(scheduler.num_scheduled_telecommands(), 3); assert_eq!(scheduler.num_scheduled_telecommands(), 3);
let end_stamp = cds::CdsTime::from_unix_time_with_u16_days( let end_stamp = cds::CdsTime::from_unix_time_with_u16_days(
@@ -1843,10 +1824,10 @@ mod tests {
false, false,
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); 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::ZERO, 50); 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, u14::ZERO, 100); 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, u14::ZERO, 150); 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, u14::ZERO, 200); let _ = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 200);
assert_eq!(scheduler.num_scheduled_telecommands(), 4); assert_eq!(scheduler.num_scheduled_telecommands(), 4);
let start_stamp = cds::CdsTime::from_unix_time_with_u16_days( let start_stamp = cds::CdsTime::from_unix_time_with_u16_days(
@@ -1884,8 +1865,8 @@ mod tests {
false, false,
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 50); insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 100); insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
assert_eq!(scheduler.num_scheduled_telecommands(), 2); assert_eq!(scheduler.num_scheduled_telecommands(), 2);
let del_res = scheduler.delete_all(&mut pool); let del_res = scheduler.delete_all(&mut pool);
assert!(del_res.is_ok()); assert!(del_res.is_ok());
@@ -1894,8 +1875,8 @@ mod tests {
// Contrary to reset, this does not disable the scheduler. // Contrary to reset, this does not disable the scheduler.
assert!(scheduler.is_enabled()); assert!(scheduler.is_enabled());
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 50); insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 100); insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
assert_eq!(scheduler.num_scheduled_telecommands(), 2); assert_eq!(scheduler.num_scheduled_telecommands(), 2);
let del_res = scheduler let del_res = scheduler
.delete_by_time_filter(TimeWindow::<cds::CdsTime>::new_select_all(), &mut pool); .delete_by_time_filter(TimeWindow::<cds::CdsTime>::new_select_all(), &mut pool);
@@ -1913,11 +1894,9 @@ mod tests {
false, false,
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 50); insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
let cmd_0_to_delete = let cmd_0_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 100); let cmd_1_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
let cmd_1_to_delete =
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 150);
assert_eq!(scheduler.num_scheduled_telecommands(), 3); assert_eq!(scheduler.num_scheduled_telecommands(), 3);
let start_stamp = cds::CdsTime::from_unix_time_with_u16_days( let start_stamp = cds::CdsTime::from_unix_time_with_u16_days(
&UnixTime::new_only_secs(100), &UnixTime::new_only_secs(100),
@@ -1940,11 +1919,9 @@ mod tests {
false, false,
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let cmd_0_to_delete = let cmd_0_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 50); let cmd_1_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);
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 100);
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 150);
assert_eq!(scheduler.num_scheduled_telecommands(), 3); assert_eq!(scheduler.num_scheduled_telecommands(), 3);
let end_stamp = cds::CdsTime::from_unix_time_with_u16_days( let end_stamp = cds::CdsTime::from_unix_time_with_u16_days(
@@ -1968,14 +1945,11 @@ mod tests {
false, false,
)); ));
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let cmd_out_of_range_0 = let cmd_out_of_range_0 = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 50);
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 50); let cmd_0_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 100);
let cmd_0_to_delete = let cmd_1_to_delete = insert_command_with_release_time(&mut pool, &mut scheduler, 0, 150);
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 100);
let cmd_1_to_delete =
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 150);
let cmd_out_of_range_1 = let cmd_out_of_range_1 =
insert_command_with_release_time(&mut pool, &mut scheduler, u14::ZERO, 200); insert_command_with_release_time(&mut pool, &mut scheduler, 0, 200);
assert_eq!(scheduler.num_scheduled_telecommands(), 4); assert_eq!(scheduler.num_scheduled_telecommands(), 4);
let start_stamp = cds::CdsTime::from_unix_time_with_u16_days( let start_stamp = cds::CdsTime::from_unix_time_with_u16_days(
@@ -2008,13 +1982,13 @@ mod tests {
let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5)); let mut scheduler = PusScheduler::new(UnixTime::new_only_secs(0), Duration::from_secs(5));
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, u14::ZERO, &[]); let tc_info_0 = ping_tc_to_store(&mut pool, &mut buf, 0, &[]);
scheduler scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(100), tc_info_0)
.expect("insertion failed"); .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 scheduler
.insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1) .insert_unwrapped_and_stored_tc(UnixTime::new_only_secs(200), tc_info_1)
.expect("insertion failed"); .expect("insertion failed");
@@ -2043,12 +2017,12 @@ mod tests {
fn test_generic_insert_app_data_test() { fn test_generic_insert_app_data_test() {
let time_writer = cds::CdsTime::new_with_u16_days(1, 1); let time_writer = cds::CdsTime::new_with_u16_days(1, 1);
let sph = SpHeader::new( let sph = SpHeader::new(
PacketId::new(PacketType::Tc, true, u11::new(0x002)), PacketId::new(PacketType::Tc, true, 0x002),
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)), PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 5),
0, 0,
); );
let sec_header = PusTcSecondaryHeader::new_simple(17, 1); 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 mut buf: [u8; 64] = [0; 64];
let result = generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc); let result = generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc);
assert!(result.is_ok()); assert!(result.is_ok());
@@ -2065,12 +2039,12 @@ mod tests {
fn test_generic_insert_app_data_test_byte_conv_error() { fn test_generic_insert_app_data_test_byte_conv_error() {
let time_writer = cds::CdsTime::new_with_u16_days(1, 1); let time_writer = cds::CdsTime::new_with_u16_days(1, 1);
let sph = SpHeader::new( let sph = SpHeader::new(
PacketId::new(PacketType::Tc, true, u11::new(0x002)), PacketId::new(PacketType::Tc, true, 0x002),
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)), PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 5),
0, 0,
); );
let sec_header = PusTcSecondaryHeader::new_simple(17, 1); 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 mut buf: [u8; 16] = [0; 16];
let result = generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc); let result = generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc);
assert!(result.is_err()); assert!(result.is_err());
@@ -2094,12 +2068,12 @@ mod tests {
fn test_generic_insert_app_data_test_as_vec() { fn test_generic_insert_app_data_test_as_vec() {
let time_writer = cds::CdsTime::new_with_u16_days(1, 1); let time_writer = cds::CdsTime::new_with_u16_days(1, 1);
let sph = SpHeader::new( let sph = SpHeader::new(
PacketId::new(PacketType::Tc, true, u11::new(0x002)), PacketId::new(PacketType::Tc, true, 0x002),
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)), PacketSequenceCtrl::new(SequenceFlags::Unsegmented, 5),
0, 0,
); );
let sec_header = PusTcSecondaryHeader::new_simple(17, 1); 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 mut buf: [u8; 64] = [0; 64];
generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc).unwrap(); 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) let vec = generate_insert_telecommand_app_data_as_vec(&time_writer, &ping_tc)

View File

@@ -1,15 +1,15 @@
use super::scheduler::PusSchedulerProvider; use super::scheduler::PusSchedulerProvider;
use super::verification::{VerificationReporter, VerificationReportingProvider}; use super::verification::{VerificationReporter, VerificationReportingProvider};
use super::{ use super::{
CacheAndReadRawEcssTc, DirectPusPacketHandlerResult, EcssTcInSharedPoolCacher, EcssTcReceiver, DirectPusPacketHandlerResult, EcssTcInMemConversionProvider, EcssTcInSharedPoolConverter,
EcssTcVecCacher, EcssTmSender, HandlingStatus, MpscTcReceiver, PartialPusHandlingError, EcssTcInVecConverter, EcssTcReceiver, EcssTmSender, HandlingStatus, MpscTcReceiver,
PusServiceHelper, PartialPusHandlingError, PusServiceHelper,
}; };
use crate::pool::PoolProvider; use crate::pool::PoolProvider;
use crate::pus::PusPacketHandlingError; use crate::pus::PusPacketHandlingError;
use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool}; use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool};
use alloc::string::ToString; use alloc::string::ToString;
use spacepackets::ecss::{PusPacket, scheduling}; use spacepackets::ecss::{scheduling, PusPacket};
use spacepackets::time::cds::CdsTime; use spacepackets::time::cds::CdsTime;
use std::sync::mpsc; use std::sync::mpsc;
@@ -24,7 +24,7 @@ use std::sync::mpsc;
pub struct PusSchedServiceHandler< pub struct PusSchedServiceHandler<
TcReceiver: EcssTcReceiver, TcReceiver: EcssTcReceiver,
TmSender: EcssTmSender, TmSender: EcssTmSender,
TcInMemConverter: CacheAndReadRawEcssTc, TcInMemConverter: EcssTcInMemConversionProvider,
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
PusScheduler: PusSchedulerProvider, PusScheduler: PusSchedulerProvider,
> { > {
@@ -36,10 +36,11 @@ pub struct PusSchedServiceHandler<
impl< impl<
TcReceiver: EcssTcReceiver, TcReceiver: EcssTcReceiver,
TmSender: EcssTmSender, TmSender: EcssTmSender,
TcInMemConverter: CacheAndReadRawEcssTc, TcInMemConverter: EcssTcInMemConversionProvider,
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
Scheduler: PusSchedulerProvider, Scheduler: PusSchedulerProvider,
> PusSchedServiceHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter, Scheduler> >
PusSchedServiceHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter, Scheduler>
{ {
pub fn new( pub fn new(
service_helper: PusServiceHelper< service_helper: PusServiceHelper<
@@ -101,12 +102,11 @@ impl<
} }
}; };
self.scheduler.enable(); 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( if let Err(e) = self.service_helper.verif_reporter().completion_success(
&self.service_helper.common.tm_sender, &self.service_helper.common.tm_sender,
started_token, opt_started_token.unwrap(),
time_stamp, time_stamp,
) { ) {
error_callback(&PartialPusHandlingError::Verification(e)); error_callback(&PartialPusHandlingError::Verification(e));
@@ -131,12 +131,10 @@ impl<
}; };
self.scheduler.disable(); self.scheduler.disable();
if !self.scheduler.is_enabled() if !self.scheduler.is_enabled() && opt_started_token.is_some() {
&& let Some(started_token) = opt_started_token
{
if let Err(e) = self.service_helper.verif_reporter().completion_success( if let Err(e) = self.service_helper.verif_reporter().completion_success(
&self.service_helper.common.tm_sender, &self.service_helper.common.tm_sender,
started_token, opt_started_token.unwrap(),
time_stamp, time_stamp,
) { ) {
error_callback(&PartialPusHandlingError::Verification(e)); error_callback(&PartialPusHandlingError::Verification(e));
@@ -213,7 +211,7 @@ impl<
pub type PusService11SchedHandlerDynWithMpsc<PusScheduler> = PusSchedServiceHandler< pub type PusService11SchedHandlerDynWithMpsc<PusScheduler> = PusSchedServiceHandler<
MpscTcReceiver, MpscTcReceiver,
mpsc::Sender<PacketAsVec>, mpsc::Sender<PacketAsVec>,
EcssTcVecCacher, EcssTcInVecConverter,
VerificationReporter, VerificationReporter,
PusScheduler, PusScheduler,
>; >;
@@ -222,7 +220,7 @@ pub type PusService11SchedHandlerDynWithMpsc<PusScheduler> = PusSchedServiceHand
pub type PusService11SchedHandlerDynWithBoundedMpsc<PusScheduler> = PusSchedServiceHandler< pub type PusService11SchedHandlerDynWithBoundedMpsc<PusScheduler> = PusSchedServiceHandler<
MpscTcReceiver, MpscTcReceiver,
mpsc::SyncSender<PacketAsVec>, mpsc::SyncSender<PacketAsVec>,
EcssTcVecCacher, EcssTcInVecConverter,
VerificationReporter, VerificationReporter,
PusScheduler, PusScheduler,
>; >;
@@ -231,7 +229,7 @@ pub type PusService11SchedHandlerDynWithBoundedMpsc<PusScheduler> = PusSchedServ
pub type PusService11SchedHandlerStaticWithMpsc<PusScheduler> = PusSchedServiceHandler< pub type PusService11SchedHandlerStaticWithMpsc<PusScheduler> = PusSchedServiceHandler<
MpscTcReceiver, MpscTcReceiver,
PacketSenderWithSharedPool, PacketSenderWithSharedPool,
EcssTcInSharedPoolCacher, EcssTcInSharedPoolConverter,
VerificationReporter, VerificationReporter,
PusScheduler, PusScheduler,
>; >;
@@ -240,7 +238,7 @@ pub type PusService11SchedHandlerStaticWithMpsc<PusScheduler> = PusSchedServiceH
pub type PusService11SchedHandlerStaticWithBoundedMpsc<PusScheduler> = PusSchedServiceHandler< pub type PusService11SchedHandlerStaticWithBoundedMpsc<PusScheduler> = PusSchedServiceHandler<
MpscTcReceiver, MpscTcReceiver,
PacketSenderWithSharedPool, PacketSenderWithSharedPool,
EcssTcInSharedPoolCacher, EcssTcInSharedPoolConverter,
VerificationReporter, VerificationReporter,
PusScheduler, PusScheduler,
>; >;
@@ -251,23 +249,21 @@ mod tests {
use crate::pus::test_util::{PusTestHarness, TEST_APID}; use crate::pus::test_util::{PusTestHarness, TEST_APID};
use crate::pus::verification::{VerificationReporter, VerificationReportingProvider}; use crate::pus::verification::{VerificationReporter, VerificationReportingProvider};
use crate::pus::{DirectPusPacketHandlerResult, MpscTcReceiver, PusPacketHandlingError};
use crate::pus::{ use crate::pus::{
EcssTcInSharedPoolCacher,
scheduler::{self, PusSchedulerProvider, TcInfo}, scheduler::{self, PusSchedulerProvider, TcInfo},
tests::PusServiceHandlerWithSharedStoreCommon, tests::PusServiceHandlerWithSharedStoreCommon,
verification::{RequestId, TcStateAccepted, VerificationToken}, verification::{RequestId, TcStateAccepted, VerificationToken},
EcssTcInSharedPoolConverter,
}; };
use crate::pus::{DirectPusPacketHandlerResult, MpscTcReceiver, PusPacketHandlingError};
use crate::tmtc::PacketSenderWithSharedPool; use crate::tmtc::PacketSenderWithSharedPool;
use alloc::collections::VecDeque; use alloc::collections::VecDeque;
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u14;
use delegate::delegate; use delegate::delegate;
use spacepackets::SpHeader;
use spacepackets::ecss::scheduling::Subservice; use spacepackets::ecss::scheduling::Subservice;
use spacepackets::ecss::tc::PusTcSecondaryHeader; use spacepackets::ecss::tc::PusTcSecondaryHeader;
use spacepackets::ecss::{CreatorConfig, WritablePusPacket}; use spacepackets::ecss::WritablePusPacket;
use spacepackets::time::TimeWriter; use spacepackets::time::TimeWriter;
use spacepackets::SpHeader;
use spacepackets::{ use spacepackets::{
ecss::{tc::PusTcCreator, tm::PusTmReader}, ecss::{tc::PusTcCreator, tm::PusTmReader},
time::cds, time::cds,
@@ -280,7 +276,7 @@ mod tests {
handler: PusSchedServiceHandler< handler: PusSchedServiceHandler<
MpscTcReceiver, MpscTcReceiver,
PacketSenderWithSharedPool, PacketSenderWithSharedPool,
EcssTcInSharedPoolCacher, EcssTcInSharedPoolConverter,
VerificationReporter, VerificationReporter,
TestScheduler, TestScheduler,
>, >,
@@ -388,10 +384,9 @@ mod tests {
test_harness: &mut Pus11HandlerWithStoreTester, test_harness: &mut Pus11HandlerWithStoreTester,
subservice: Subservice, 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 tc_header = PusTcSecondaryHeader::new_simple(11, subservice as u8);
let enable_scheduling = let enable_scheduling = PusTcCreator::new(reply_header, tc_header, &[0; 7], true);
PusTcCreator::new(reply_header, tc_header, &[0; 7], CreatorConfig::default());
let token = test_harness.start_verification(&enable_scheduling); let token = test_harness.start_verification(&enable_scheduling);
test_harness.send_tc(&token, &enable_scheduling); test_harness.send_tc(&token, &enable_scheduling);
@@ -436,9 +431,9 @@ mod tests {
#[test] #[test]
fn test_insert_activity_tc() { fn test_insert_activity_tc() {
let mut test_harness = Pus11HandlerWithStoreTester::new(); 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 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 req_id_ping_tc = scheduler::RequestId::from_tc(&ping_tc);
let stamper = cds::CdsTime::now_with_u16_days().expect("time provider failed"); let stamper = cds::CdsTime::now_with_u16_days().expect("time provider failed");
let mut sched_app_data: [u8; 64] = [0; 64]; 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"); 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); sched_app_data[written_len..written_len + ping_raw.len()].copy_from_slice(&ping_raw);
written_len += ping_raw.len(); written_len += ping_raw.len();
reply_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0); reply_header = SpHeader::new_for_unseg_tc(TEST_APID, 1, 0);
sec_header = PusTcSecondaryHeader::new_simple(11, Subservice::TcInsertActivity as u8); sec_header = PusTcSecondaryHeader::new_simple(11, Subservice::TcInsertActivity as u8);
let enable_scheduling = PusTcCreator::new( let enable_scheduling = PusTcCreator::new(
reply_header, reply_header,
sec_header, sec_header,
&sched_app_data[..written_len], &sched_app_data[..written_len],
CreatorConfig::default(), true,
); );
let token = test_harness.start_verification(&enable_scheduling); let token = test_harness.start_verification(&enable_scheduling);
test_harness.send_tc(&token, &enable_scheduling); test_harness.send_tc(&token, &enable_scheduling);

View File

@@ -2,17 +2,16 @@ use crate::pus::{
DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError, PusTmVariant, DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError, PusTmVariant,
}; };
use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool}; use crate::tmtc::{PacketAsVec, PacketSenderWithSharedPool};
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u14;
use spacepackets::SpHeader;
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader}; use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
use spacepackets::ecss::{CreatorConfig, PusPacket}; use spacepackets::ecss::PusPacket;
use spacepackets::SpHeader;
use std::sync::mpsc; use std::sync::mpsc;
use super::verification::{VerificationReporter, VerificationReportingProvider}; use super::verification::{VerificationReporter, VerificationReportingProvider};
use super::{ use super::{
CacheAndReadRawEcssTc, EcssTcInSharedPoolCacher, EcssTcReceiver, EcssTcVecCacher, EcssTmSender, EcssTcInMemConversionProvider, EcssTcInSharedPoolConverter, EcssTcInVecConverter,
GenericConversionError, HandlingStatus, MpscTcReceiver, PusServiceHelper, EcssTcReceiver, EcssTmSender, GenericConversionError, HandlingStatus, MpscTcReceiver,
PusServiceHelper,
}; };
/// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets. /// This is a helper class for [std] environments to handle generic PUS 17 (test service) packets.
@@ -20,7 +19,7 @@ use super::{
pub struct PusService17TestHandler< pub struct PusService17TestHandler<
TcReceiver: EcssTcReceiver, TcReceiver: EcssTcReceiver,
TmSender: EcssTmSender, TmSender: EcssTmSender,
TcInMemConverter: CacheAndReadRawEcssTc, TcInMemConverter: EcssTcInMemConversionProvider,
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
> { > {
pub service_helper: pub service_helper:
@@ -30,7 +29,7 @@ pub struct PusService17TestHandler<
impl< impl<
TcReceiver: EcssTcReceiver, TcReceiver: EcssTcReceiver,
TmSender: EcssTmSender, TmSender: EcssTmSender,
TcInMemConverter: CacheAndReadRawEcssTc, TcInMemConverter: EcssTcInMemConversionProvider,
VerificationReporter: VerificationReportingProvider, VerificationReporter: VerificationReportingProvider,
> PusService17TestHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter> > PusService17TestHandler<TcReceiver, TmSender, TcInMemConverter, VerificationReporter>
{ {
@@ -77,14 +76,10 @@ impl<
// Sequence count will be handled centrally in TM funnel. // 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 // It is assumed that the verification reporter was built with a valid APID, so we use
// the unchecked API here. // the unchecked API here.
let reply_header = SpHeader::new_for_unseg_tm( let reply_header =
self.service_helper.verif_reporter().apid(), SpHeader::new_for_unseg_tm(self.service_helper.verif_reporter().apid(), 0, 0);
u14::ZERO,
0,
);
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, time_stamp); let tc_header = PusTmSecondaryHeader::new_simple(17, 2, time_stamp);
let ping_reply = let ping_reply = PusTmCreator::new(reply_header, tc_header, &[], true);
PusTmCreator::new(reply_header, tc_header, &[], CreatorConfig::default());
if let Err(e) = self if let Err(e) = self
.service_helper .service_helper
.common .common
@@ -117,7 +112,7 @@ impl<
pub type PusService17TestHandlerDynWithMpsc = PusService17TestHandler< pub type PusService17TestHandlerDynWithMpsc = PusService17TestHandler<
MpscTcReceiver, MpscTcReceiver,
mpsc::Sender<PacketAsVec>, mpsc::Sender<PacketAsVec>,
EcssTcVecCacher, EcssTcInVecConverter,
VerificationReporter, VerificationReporter,
>; >;
/// Helper type definition for a PUS 17 handler with a dynamic TMTC memory backend and bounded MPSC /// Helper type definition for a PUS 17 handler with a dynamic TMTC memory backend and bounded MPSC
@@ -125,7 +120,7 @@ pub type PusService17TestHandlerDynWithMpsc = PusService17TestHandler<
pub type PusService17TestHandlerDynWithBoundedMpsc = PusService17TestHandler< pub type PusService17TestHandlerDynWithBoundedMpsc = PusService17TestHandler<
MpscTcReceiver, MpscTcReceiver,
mpsc::SyncSender<PacketAsVec>, mpsc::SyncSender<PacketAsVec>,
EcssTcVecCacher, EcssTcInVecConverter,
VerificationReporter, VerificationReporter,
>; >;
/// Helper type definition for a PUS 17 handler with a shared store TMTC memory backend and bounded /// Helper type definition for a PUS 17 handler with a shared store TMTC memory backend and bounded
@@ -133,13 +128,12 @@ pub type PusService17TestHandlerDynWithBoundedMpsc = PusService17TestHandler<
pub type PusService17TestHandlerStaticWithBoundedMpsc = PusService17TestHandler< pub type PusService17TestHandlerStaticWithBoundedMpsc = PusService17TestHandler<
MpscTcReceiver, MpscTcReceiver,
PacketSenderWithSharedPool, PacketSenderWithSharedPool,
EcssTcInSharedPoolCacher, EcssTcInSharedPoolConverter,
VerificationReporter, VerificationReporter,
>; >;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::ComponentId;
use crate::pus::test_util::{PusTestHarness, SimplePusPacketHandler, TEST_APID}; use crate::pus::test_util::{PusTestHarness, SimplePusPacketHandler, TEST_APID};
use crate::pus::tests::{ use crate::pus::tests::{
PusServiceHandlerWithSharedStoreCommon, PusServiceHandlerWithVecCommon, PusServiceHandlerWithSharedStoreCommon, PusServiceHandlerWithVecCommon,
@@ -149,19 +143,18 @@ mod tests {
}; };
use crate::pus::verification::{TcStateAccepted, VerificationToken}; use crate::pus::verification::{TcStateAccepted, VerificationToken};
use crate::pus::{ use crate::pus::{
DirectPusPacketHandlerResult, EcssTcInSharedPoolCacher, EcssTcVecCacher, DirectPusPacketHandlerResult, EcssTcInSharedPoolConverter, EcssTcInVecConverter,
GenericConversionError, HandlingStatus, MpscTcReceiver, MpscTmAsVecSender, GenericConversionError, HandlingStatus, MpscTcReceiver, MpscTmAsVecSender,
PartialPusHandlingError, PusPacketHandlingError, PartialPusHandlingError, PusPacketHandlingError,
}; };
use crate::tmtc::PacketSenderWithSharedPool; use crate::tmtc::PacketSenderWithSharedPool;
use arbitrary_int::traits::Integer as _; use crate::ComponentId;
use arbitrary_int::u14;
use delegate::delegate; use delegate::delegate;
use spacepackets::SpHeader;
use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader}; use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
use spacepackets::ecss::tm::PusTmReader; use spacepackets::ecss::tm::PusTmReader;
use spacepackets::ecss::{CreatorConfig, PusPacket}; use spacepackets::ecss::PusPacket;
use spacepackets::time::{TimeWriter, cds}; use spacepackets::time::{cds, TimeWriter};
use spacepackets::SpHeader;
use super::PusService17TestHandler; use super::PusService17TestHandler;
@@ -170,7 +163,7 @@ mod tests {
handler: PusService17TestHandler< handler: PusService17TestHandler<
MpscTcReceiver, MpscTcReceiver,
PacketSenderWithSharedPool, PacketSenderWithSharedPool,
EcssTcInSharedPoolCacher, EcssTcInSharedPoolConverter,
VerificationReporter, VerificationReporter,
>, >,
} }
@@ -232,7 +225,7 @@ mod tests {
handler: PusService17TestHandler< handler: PusService17TestHandler<
MpscTcReceiver, MpscTcReceiver,
MpscTmAsVecSender, MpscTmAsVecSender,
EcssTcVecCacher, EcssTcInVecConverter,
VerificationReporter, VerificationReporter,
>, >,
} }
@@ -291,10 +284,9 @@ mod tests {
fn ping_test(test_harness: &mut (impl PusTestHarness + SimplePusPacketHandler)) { fn ping_test(test_harness: &mut (impl PusTestHarness + SimplePusPacketHandler)) {
// Create a ping TC, verify acceptance. // Create a ping TC, verify acceptance.
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(17, 1); let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
let ping_tc = let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
let token = test_harness.start_verification(&ping_tc); let token = test_harness.start_verification(&ping_tc);
test_harness.send_tc(&token, &ping_tc); test_harness.send_tc(&token, &ping_tc);
let request_id = token.request_id(); let request_id = token.request_id();
@@ -347,10 +339,9 @@ mod tests {
#[test] #[test]
fn test_sending_unsupported_service() { fn test_sending_unsupported_service() {
let mut test_harness = Pus17HandlerWithStoreTester::new(0); let mut test_harness = Pus17HandlerWithStoreTester::new(0);
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(3, 1); let sec_header = PusTcSecondaryHeader::new_simple(3, 1);
let ping_tc = let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
let token = test_harness.start_verification(&ping_tc); let token = test_harness.start_verification(&ping_tc);
test_harness.send_tc(&token, &ping_tc); test_harness.send_tc(&token, &ping_tc);
let result = test_harness.handle_one_tc(); let result = test_harness.handle_one_tc();
@@ -369,10 +360,9 @@ mod tests {
#[test] #[test]
fn test_sending_custom_subservice() { fn test_sending_custom_subservice() {
let mut test_harness = Pus17HandlerWithStoreTester::new(0); let mut test_harness = Pus17HandlerWithStoreTester::new(0);
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(17, 200); let sec_header = PusTcSecondaryHeader::new_simple(17, 200);
let ping_tc = let ping_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, true);
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
let token = test_harness.start_verification(&ping_tc); let token = test_harness.start_verification(&ping_tc);
test_harness.send_tc(&token, &ping_tc); test_harness.send_tc(&token, &ping_tc);
let result = test_harness.handle_one_tc(); let result = test_harness.handle_one_tc();

View File

@@ -17,18 +17,18 @@
//! use std::time::Duration; //! use std::time::Duration;
//! use satrs::pool::{PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig}; //! use satrs::pool::{PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig};
//! use satrs::pus::verification::{ //! use satrs::pus::verification::{
//! VerificationReportingProvider, VerificationReporterConfig, VerificationReporter //! VerificationReportingProvider, VerificationReporterCfg, VerificationReporter
//! }; //! };
//! use satrs::tmtc::{SharedStaticMemoryPool, PacketSenderWithSharedPool}; //! use satrs::tmtc::{SharedStaticMemoryPool, PacketSenderWithSharedPool};
//! use satrs::spacepackets::seq_count::SeqCountProviderSimple;
//! use satrs::request::UniqueApidTargetId; //! use satrs::request::UniqueApidTargetId;
//! use spacepackets::ecss::PusPacket; //! use spacepackets::ecss::PusPacket;
//! use spacepackets::SpHeader; //! use spacepackets::SpHeader;
//! use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader, CreatorConfig}; //! use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
//! use spacepackets::ecss::tm::PusTmReader; //! use spacepackets::ecss::tm::PusTmReader;
//! use arbitrary_int::u11;
//! //!
//! const EMPTY_STAMP: [u8; 7] = [0; 7]; //! const EMPTY_STAMP: [u8; 7] = [0; 7];
//! const TEST_APID: u11 = u11::new(0x02); //! const TEST_APID: u16 = 0x02;
//! const TEST_COMPONENT_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05); //! const TEST_COMPONENT_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
//! //!
//! let pool_cfg = StaticPoolConfig::new_from_subpool_cfg_tuples( //! let pool_cfg = StaticPoolConfig::new_from_subpool_cfg_tuples(
@@ -38,14 +38,14 @@
//! let shared_tm_pool = SharedStaticMemoryPool::new(RwLock::new(tm_pool)); //! let shared_tm_pool = SharedStaticMemoryPool::new(RwLock::new(tm_pool));
//! let (verif_tx, verif_rx) = mpsc::sync_channel(10); //! let (verif_tx, verif_rx) = mpsc::sync_channel(10);
//! let sender = PacketSenderWithSharedPool::new_with_shared_packet_pool(verif_tx, &shared_tm_pool); //! let sender = PacketSenderWithSharedPool::new_with_shared_packet_pool(verif_tx, &shared_tm_pool);
//! let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8); //! let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
//! let mut reporter = VerificationReporter::new(TEST_COMPONENT_ID.id(), &cfg); //! let mut reporter = VerificationReporter::new(TEST_COMPONENT_ID.id(), &cfg);
//! //!
//! let tc_header = PusTcSecondaryHeader::new_simple(17, 1); //! let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
//! let pus_tc_0 = PusTcCreator::new_no_app_data( //! let pus_tc_0 = PusTcCreator::new_no_app_data(
//! SpHeader::new_from_apid(TEST_APID), //! SpHeader::new_from_apid(TEST_APID),
//! tc_header, //! tc_header,
//! CreatorConfig::default() //! true
//! ); //! );
//! let init_token = reporter.start_verification(&pus_tc_0); //! let init_token = reporter.start_verification(&pus_tc_0);
//! //!
@@ -81,8 +81,7 @@
//! for the verification module contains examples how this module could be used in a more complex //! for the verification module contains examples how this module could be used in a more complex
//! context involving multiple threads //! context involving multiple threads
use crate::params::{Params, WritableToBeBytes}; use crate::params::{Params, WritableToBeBytes};
use crate::pus::{EcssTmSender, EcssTmtcError, source_buffer_large_enough}; use crate::pus::{source_buffer_large_enough, EcssTmSender, EcssTmtcError};
use arbitrary_int::{u3, u11, u14};
use core::fmt::{Debug, Display, Formatter}; use core::fmt::{Debug, Display, Formatter};
use core::hash::{Hash, Hasher}; use core::hash::{Hash, Hasher};
use core::marker::PhantomData; use core::marker::PhantomData;
@@ -91,20 +90,20 @@ use core::mem::size_of;
use delegate::delegate; use delegate::delegate;
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use spacepackets::SpHeader;
use spacepackets::ecss::tc::IsPusTelecommand; use spacepackets::ecss::tc::IsPusTelecommand;
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader}; use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
use spacepackets::ecss::{CreatorConfig, EcssEnumeration}; use spacepackets::ecss::EcssEnumeration;
use spacepackets::{ByteConversionError, CcsdsPacket, PacketId, PacketSequenceControl}; use spacepackets::{ByteConversionError, CcsdsPacket, PacketId, PacketSequenceCtrl};
use spacepackets::{SpHeader, MAX_APID};
pub use spacepackets::ecss::verification::*; pub use spacepackets::ecss::verification::*;
pub use spacepackets::seq_count::SequenceCounterSimple; pub use spacepackets::seq_count::SeqCountProviderSimple;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub use alloc_mod::*; pub use alloc_mod::*;
use crate::ComponentId;
use crate::request::Apid; use crate::request::Apid;
use crate::ComponentId;
/// This is a request identifier as specified in 5.4.11.2 c. of the PUS standard. /// 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)] #[derive(Debug, Eq, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct RequestId { pub struct RequestId {
version_number: u3, version_number: u8,
packet_id: PacketId, packet_id: PacketId,
psc: PacketSequenceControl, psc: PacketSequenceCtrl,
} }
impl Display for RequestId { impl Display for RequestId {
@@ -158,18 +157,16 @@ impl RequestId {
} }
pub fn raw(&self) -> u32 { pub fn raw(&self) -> u32 {
((self.version_number.value() as u32) << 29) ((self.version_number as u32) << 29)
| ((self.packet_id.raw() as u32) << 16) | ((self.packet_id.raw() as u32) << 16)
| self.psc.raw() as u32 | self.psc.raw() as u32
} }
#[inline] pub fn packet_id(&self) -> PacketId {
pub const fn packet_id(&self) -> PacketId {
self.packet_id self.packet_id
} }
#[inline] pub fn packet_seq_ctrl(&self) -> PacketSequenceCtrl {
pub const fn packet_seq_ctrl(&self) -> PacketSequenceControl {
self.psc self.psc
} }
@@ -184,9 +181,9 @@ impl RequestId {
} }
let raw = u32::from_be_bytes(buf[0..Self::SIZE_AS_BYTES].try_into().unwrap()); let raw = u32::from_be_bytes(buf[0..Self::SIZE_AS_BYTES].try_into().unwrap());
Some(Self { 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), packet_id: PacketId::from(((raw >> 16) & 0xffff) as u16),
psc: PacketSequenceControl::from((raw & 0xffff) as u16), psc: PacketSequenceCtrl::from((raw & 0xffff) as u16),
}) })
} }
} }
@@ -194,9 +191,9 @@ impl RequestId {
impl From<u32> for RequestId { impl From<u32> for RequestId {
fn from(value: u32) -> Self { fn from(value: u32) -> Self {
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), packet_id: PacketId::from(((value >> 16) & 0xffff) as u16),
psc: PacketSequenceControl::from((value & 0xffff) as u16), psc: PacketSequenceCtrl::from((value & 0xffff) as u16),
} }
} }
} }
@@ -483,19 +480,26 @@ pub trait VerificationReportingProvider {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct VerificationReportCreator { pub struct VerificationReportCreator {
pub dest_id: u16, pub dest_id: u16,
apid: u11, apid: u16,
} }
impl VerificationReportCreator { impl VerificationReportCreator {
pub fn new(apid: u11) -> Self { pub fn new(apid: u16) -> Option<Self> {
Self { apid, dest_id: 0 } 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; self.apid = apid;
true
} }
pub fn apid(&self) -> u11 { pub fn apid(&self) -> u16 {
self.apid self.apid
} }
@@ -518,7 +522,7 @@ impl VerificationReportCreator {
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
subservice: u8, subservice: u8,
request_id: &RequestId, request_id: &RequestId,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
time_stamp: &'time [u8], time_stamp: &'time [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
@@ -541,7 +545,7 @@ impl VerificationReportCreator {
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
subservice: u8, subservice: u8,
request_id: &RequestId, request_id: &RequestId,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
step: Option<&(impl EcssEnumeration + ?Sized)>, step: Option<&(impl EcssEnumeration + ?Sized)>,
params: &FailParams<'time, '_>, params: &FailParams<'time, '_>,
@@ -563,7 +567,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
request_id: &RequestId, request_id: &RequestId,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
time_stamp: &'time [u8], time_stamp: &'time [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
@@ -583,7 +587,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
request_id: &RequestId, request_id: &RequestId,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
params: FailParams<'time, '_>, params: FailParams<'time, '_>,
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
@@ -605,7 +609,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
request_id: &RequestId, request_id: &RequestId,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
time_stamp: &'time [u8], time_stamp: &'time [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
@@ -628,7 +632,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
request_id: &RequestId, request_id: &RequestId,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
params: FailParams<'time, '_>, params: FailParams<'time, '_>,
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
@@ -650,7 +654,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
request_id: &RequestId, request_id: &RequestId,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
time_stamp: &'time [u8], time_stamp: &'time [u8],
step: impl EcssEnumeration, step: impl EcssEnumeration,
@@ -674,7 +678,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
token: VerificationToken<TcStateStarted>, token: VerificationToken<TcStateStarted>,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
params: FailParamsWithStep<'time, '_>, params: FailParamsWithStep<'time, '_>,
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
@@ -697,7 +701,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
request_id: &RequestId, request_id: &RequestId,
seq_counter: u14, seq_counter: u16,
msg_counter: u16, msg_counter: u16,
time_stamp: &'time [u8], time_stamp: &'time [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
@@ -719,7 +723,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
request_id: &RequestId, request_id: &RequestId,
seq_count: u14, seq_count: u16,
msg_count: u16, msg_count: u16,
params: FailParams<'time, '_>, params: FailParams<'time, '_>,
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
@@ -740,7 +744,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
subservice: u8, subservice: u8,
seq_count: u14, seq_count: u16,
msg_counter: u16, msg_counter: u16,
req_id: &RequestId, req_id: &RequestId,
time_stamp: &'time [u8], time_stamp: &'time [u8],
@@ -776,7 +780,7 @@ impl VerificationReportCreator {
&self, &self,
src_data_buf: &'src_data mut [u8], src_data_buf: &'src_data mut [u8],
subservice: u8, subservice: u8,
seq_count: u14, seq_count: u16,
msg_counter: u16, msg_counter: u16,
req_id: &RequestId, req_id: &RequestId,
step: Option<&(impl EcssEnumeration + ?Sized)>, step: Option<&(impl EcssEnumeration + ?Sized)>,
@@ -828,14 +832,13 @@ impl VerificationReportCreator {
sp_header, sp_header,
tm_sec_header, tm_sec_header,
&src_data_buf[0..source_data_len], &src_data_buf[0..source_data_len],
CreatorConfig::default(), true,
) )
} }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub mod alloc_mod { pub mod alloc_mod {
use arbitrary_int::traits::Integer as _;
use spacepackets::ecss::PusError; use spacepackets::ecss::PusError;
use super::*; use super::*;
@@ -843,26 +846,29 @@ pub mod alloc_mod {
use core::cell::RefCell; use core::cell::RefCell;
#[derive(Clone)] #[derive(Clone)]
pub struct VerificationReporterConfig { pub struct VerificationReporterCfg {
apid: u11, apid: u16,
pub step_field_width: usize, pub step_field_width: usize,
pub fail_code_field_width: usize, pub fail_code_field_width: usize,
pub max_fail_data_len: usize, pub max_fail_data_len: usize,
} }
impl VerificationReporterConfig { impl VerificationReporterCfg {
pub fn new( pub fn new(
apid: u11, apid: u16,
step_field_width: usize, step_field_width: usize,
fail_code_field_width: usize, fail_code_field_width: usize,
max_fail_data_len: usize, max_fail_data_len: usize,
) -> Self { ) -> Option<Self> {
Self { if apid > MAX_APID {
return None;
}
Some(Self {
apid, apid,
step_field_width, step_field_width,
fail_code_field_width, fail_code_field_width,
max_fail_data_len, max_fail_data_len,
} })
} }
} }
@@ -870,17 +876,17 @@ pub mod alloc_mod {
/// ///
/// The [Self::modify_tm] function is called before the TM is sent. This allows users to change /// 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. /// 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); fn modify_tm(&self, tm: &mut PusTmCreator);
} }
/// [VerificationHook] which does nothing. This is the default hook variant for /// [VerificationHookProvider] which does nothing. This is the default hook variant for
/// the [VerificationReporter], assuming that any necessary packet manipulation is performed by /// the [VerificationReporter], assuming that any necessary packet manipulation is performed by
/// a centralized TM funnel or inlet. /// a centralized TM funnel or inlet.
#[derive(Default, Copy, Clone)] #[derive(Default, Copy, Clone)]
pub struct DummyVerificationHook {} pub struct DummyVerificationHook {}
impl VerificationHook for DummyVerificationHook { impl VerificationHookProvider for DummyVerificationHook {
fn modify_tm(&self, _tm: &mut PusTmCreator) {} fn modify_tm(&self, _tm: &mut PusTmCreator) {}
} }
@@ -893,17 +899,17 @@ pub mod alloc_mod {
/// destination fields are assumed to be constant for a given repoter instance. /// destination fields are assumed to be constant for a given repoter instance.
#[derive(Clone)] #[derive(Clone)]
pub struct VerificationReporter< pub struct VerificationReporter<
VerificationHookInstance: VerificationHook = DummyVerificationHook, VerificationHook: VerificationHookProvider = DummyVerificationHook,
> { > {
owner_id: ComponentId, owner_id: ComponentId,
source_data_buf: RefCell<alloc::vec::Vec<u8>>, source_data_buf: RefCell<alloc::vec::Vec<u8>>,
pub reporter_creator: VerificationReportCreator, pub reporter_creator: VerificationReportCreator,
pub tm_hook: VerificationHookInstance, pub tm_hook: VerificationHook,
} }
impl VerificationReporter<DummyVerificationHook> { impl VerificationReporter<DummyVerificationHook> {
pub fn new(owner_id: ComponentId, cfg: &VerificationReporterConfig) -> Self { pub fn new(owner_id: ComponentId, cfg: &VerificationReporterCfg) -> Self {
let reporter = VerificationReportCreator::new(cfg.apid); let reporter = VerificationReportCreator::new(cfg.apid).unwrap();
Self { Self {
owner_id, owner_id,
source_data_buf: RefCell::new(alloc::vec![ source_data_buf: RefCell::new(alloc::vec![
@@ -919,15 +925,15 @@ pub mod alloc_mod {
} }
} }
impl<VerificationHookInstance: VerificationHook> VerificationReporter<VerificationHookInstance> { impl<VerificationHook: VerificationHookProvider> VerificationReporter<VerificationHook> {
/// The provided [VerificationHook] can be used to modify a verification packet /// The provided [VerificationHookProvider] can be used to modify a verification packet
/// before it is sent. /// before it is sent.
pub fn new_with_hook( pub fn new_with_hook(
owner_id: ComponentId, owner_id: ComponentId,
cfg: &VerificationReporterConfig, cfg: &VerificationReporterCfg,
tm_hook: VerificationHookInstance, tm_hook: VerificationHook,
) -> Self { ) -> Self {
let reporter = VerificationReportCreator::new(cfg.apid); let reporter = VerificationReportCreator::new(cfg.apid).unwrap();
Self { Self {
owner_id, owner_id,
source_data_buf: RefCell::new(alloc::vec![ source_data_buf: RefCell::new(alloc::vec![
@@ -960,8 +966,8 @@ pub mod alloc_mod {
delegate!( delegate!(
to self.reporter_creator { to self.reporter_creator {
pub fn set_apid(&mut self, apid: u11); pub fn set_apid(&mut self, apid: u16) -> bool;
pub fn apid(&self) -> u11; pub fn apid(&self) -> u16;
pub fn dest_id(&self) -> u16; pub fn dest_id(&self) -> u16;
pub fn set_dest_id(&mut self, dest_id: u16); pub fn set_dest_id(&mut self, dest_id: u16);
} }
@@ -972,8 +978,8 @@ pub mod alloc_mod {
} }
} }
impl<VerificationHookInstance: VerificationHook> VerificationReportingProvider impl<VerificationHook: VerificationHookProvider> VerificationReportingProvider
for VerificationReporter<VerificationHookInstance> for VerificationReporter<VerificationHook>
{ {
delegate!( delegate!(
to self.reporter_creator { to self.reporter_creator {
@@ -1006,7 +1012,7 @@ pub mod alloc_mod {
.acceptance_success( .acceptance_success(
source_data_buf.as_mut_slice(), source_data_buf.as_mut_slice(),
&token.request_id(), &token.request_id(),
u14::ZERO, 0,
0, 0,
time_stamp, time_stamp,
) )
@@ -1026,13 +1032,7 @@ pub mod alloc_mod {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let mut tm_creator = self let mut tm_creator = self
.reporter_creator .reporter_creator
.acceptance_failure( .acceptance_failure(buf.as_mut_slice(), &token.request_id(), 0, 0, params)
buf.as_mut_slice(),
&token.request_id(),
u14::ZERO,
0,
params,
)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator); self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?; sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
@@ -1051,13 +1051,7 @@ pub mod alloc_mod {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let mut tm_creator = self let mut tm_creator = self
.reporter_creator .reporter_creator
.start_success( .start_success(buf.as_mut_slice(), &token.request_id(), 0, 0, time_stamp)
buf.as_mut_slice(),
&token.request_id(),
u14::ZERO,
0,
time_stamp,
)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator); self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?; sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
@@ -1077,13 +1071,7 @@ pub mod alloc_mod {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let mut tm_creator = self let mut tm_creator = self
.reporter_creator .reporter_creator
.start_failure( .start_failure(buf.as_mut_slice(), &token.request_id(), 0, 0, params)
buf.as_mut_slice(),
&token.request_id(),
u14::ZERO,
0,
params,
)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator); self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?; sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
@@ -1106,7 +1094,7 @@ pub mod alloc_mod {
.step_success( .step_success(
buf.as_mut_slice(), buf.as_mut_slice(),
&token.request_id(), &token.request_id(),
u14::ZERO, 0,
0, 0,
time_stamp, time_stamp,
step, step,
@@ -1130,7 +1118,7 @@ pub mod alloc_mod {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let mut tm_creator = self let mut tm_creator = self
.reporter_creator .reporter_creator
.step_failure(buf.as_mut_slice(), token, u14::ZERO, 0, params) .step_failure(buf.as_mut_slice(), token, 0, 0, params)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator); self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?; sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
@@ -1151,13 +1139,7 @@ pub mod alloc_mod {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let mut tm_creator = self let mut tm_creator = self
.reporter_creator .reporter_creator
.completion_success( .completion_success(buf.as_mut_slice(), &token.request_id(), 0, 0, time_stamp)
buf.as_mut_slice(),
&token.request_id(),
u14::ZERO,
0,
time_stamp,
)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator); self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.owner_id, PusTmVariant::Direct(tm_creator))?; sender.send_tm(self.owner_id, PusTmVariant::Direct(tm_creator))?;
@@ -1177,13 +1159,7 @@ pub mod alloc_mod {
let mut buf = self.source_data_buf.borrow_mut(); let mut buf = self.source_data_buf.borrow_mut();
let mut tm_creator = self let mut tm_creator = self
.reporter_creator .reporter_creator
.completion_failure( .completion_failure(buf.as_mut_slice(), &token.request_id(), 0, 00, params)
buf.as_mut_slice(),
&token.request_id(),
u14::ZERO,
0,
params,
)
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator); self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?; sender.send_tm(self.owner_id(), PusTmVariant::Direct(tm_creator))?;
@@ -1333,7 +1309,6 @@ pub fn handle_step_failure_with_generic_params(
#[cfg(any(feature = "test_util", test))] #[cfg(any(feature = "test_util", test))]
pub mod test_util { pub mod test_util {
use alloc::vec::Vec; use alloc::vec::Vec;
use arbitrary_int::traits::Integer;
use core::cell::RefCell; use core::cell::RefCell;
use std::collections::VecDeque; use std::collections::VecDeque;
@@ -1395,7 +1370,7 @@ pub mod test_util {
fn set_apid(&mut self, _apid: Apid) {} fn set_apid(&mut self, _apid: Apid) {}
fn apid(&self) -> Apid { fn apid(&self) -> Apid {
Apid::ZERO 0
} }
fn acceptance_success( fn acceptance_success(
@@ -1711,41 +1686,39 @@ pub mod test_util {
#[cfg(test)] #[cfg(test)]
pub mod tests { pub mod tests {
use crate::ComponentId;
use crate::params::Params; use crate::params::Params;
use crate::pool::{SharedStaticMemoryPool, StaticMemoryPool, StaticPoolConfig}; use crate::pool::{SharedStaticMemoryPool, StaticMemoryPool, StaticPoolConfig};
use crate::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0}; use crate::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0};
use crate::pus::tests::CommonTmInfo; use crate::pus::tests::CommonTmInfo;
use crate::pus::verification::{ use crate::pus::verification::{
EcssTmSender, EcssTmtcError, FailParams, FailParamsWithStep, RequestId, TcStateNone, handle_step_failure_with_generic_params, EcssTmSender, EcssTmtcError, FailParams,
VerificationReporter, VerificationReporterConfig, VerificationToken, FailParamsWithStep, RequestId, TcStateNone, VerificationReporter, VerificationReporterCfg,
handle_step_failure_with_generic_params, VerificationToken,
}; };
use crate::pus::{ChannelWithId, PusTmVariant}; use crate::pus::{ChannelWithId, PusTmVariant};
use crate::request::MessageMetadata; 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::tmtc::{PacketSenderWithSharedPool, SharedPacketPool};
use crate::ComponentId;
use alloc::format; use alloc::format;
use alloc::string::ToString; use alloc::string::ToString;
use arbitrary_int::traits::Integer;
use arbitrary_int::{u11, u14};
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader}; use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
use spacepackets::ecss::{ use spacepackets::ecss::{
CreatorConfig, EcssEnumU8, EcssEnumU16, EcssEnumU32, EcssEnumeration, PusError, PusPacket, EcssEnumU16, EcssEnumU32, EcssEnumU8, EcssEnumeration, PusError, PusPacket,
WritablePusPacket, WritablePusPacket,
}; };
use spacepackets::util::UnsignedEnum; use spacepackets::util::UnsignedEnum;
use spacepackets::{ByteConversionError, SpHeader}; use spacepackets::{ByteConversionError, SpHeader};
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::sync::{RwLock, mpsc}; use std::sync::{mpsc, RwLock};
use std::vec; use std::vec;
use std::vec::Vec; use std::vec::Vec;
use super::{ use super::{
DummyVerificationHook, FailParamHelper, SequenceCounterSimple, TcStateAccepted, handle_completion_failure_with_generic_params, DummyVerificationHook, FailParamHelper,
TcStateStarted, VerificationHook, VerificationReportingProvider, WasAtLeastAccepted, SeqCountProviderSimple, TcStateAccepted, TcStateStarted, VerificationHookProvider,
handle_completion_failure_with_generic_params, VerificationReportingProvider, WasAtLeastAccepted,
}; };
fn is_send<T: Send>(_: &T) {} fn is_send<T: Send>(_: &T) {}
@@ -1810,41 +1783,41 @@ pub mod tests {
#[derive(Default)] #[derive(Default)]
pub struct SequenceCounterHook { pub struct SequenceCounterHook {
pub seq_counter: SequenceCounterCcsdsSimple, pub seq_counter: CcsdsSimpleSeqCountProvider,
pub msg_counter: SequenceCounterSimple<u16>, pub msg_counter: SeqCountProviderSimple<u16>,
} }
impl VerificationHook for SequenceCounterHook { impl VerificationHookProvider for SequenceCounterHook {
fn modify_tm(&self, tm: &mut spacepackets::ecss::tm::PusTmCreator) { 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()); tm.set_msg_counter(self.msg_counter.get_and_increment());
} }
} }
struct VerificationReporterTestbench< struct VerificationReporterTestbench<
VerificationHookInstance: VerificationHook = DummyVerificationHook, VerificationHook: VerificationHookProvider = DummyVerificationHook,
> { > {
pub id: ComponentId, pub id: ComponentId,
sender: TestSender, sender: TestSender,
reporter: VerificationReporter<VerificationHookInstance>, reporter: VerificationReporter<VerificationHook>,
pub request_id: RequestId, pub request_id: RequestId,
tc: Vec<u8>, tc: Vec<u8>,
} }
fn base_reporter(id: ComponentId, max_fail_data_len: usize) -> VerificationReporter { fn base_reporter(id: ComponentId, max_fail_data_len: usize) -> VerificationReporter {
let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, max_fail_data_len); let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, max_fail_data_len).unwrap();
VerificationReporter::new(id, &cfg) VerificationReporter::new(id, &cfg)
} }
fn reporter_with_hook<VerificationHookInstance: VerificationHook>( fn reporter_with_hook<VerificationHook: VerificationHookProvider>(
id: ComponentId, id: ComponentId,
hook: VerificationHookInstance, hook: VerificationHook,
) -> VerificationReporter<VerificationHookInstance> { ) -> VerificationReporter<VerificationHook> {
let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8); let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
VerificationReporter::new_with_hook(id, &cfg, hook) 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 { fn new_with_hook(id: ComponentId, tc: PusTcCreator, tm_hook: VerificiationHook) -> Self {
let reporter = reporter_with_hook(id, tm_hook); let reporter = reporter_with_hook(id, tm_hook);
Self { Self {
@@ -1939,14 +1912,7 @@ pub mod tests {
fn check_acceptance_success(&self, timestamp: &[u8; 7]) { fn check_acceptance_success(&self, timestamp: &[u8; 7]) {
let cmp_info = TmInfo { let cmp_info = TmInfo {
requestor: MessageMetadata::new(self.request_id.into(), self.id), requestor: MessageMetadata::new(self.request_id.into(), self.id),
common: CommonTmInfo::new( common: CommonTmInfo::new(1, TEST_APID, 0, 0, self.reporter.dest_id(), timestamp),
1,
TEST_APID,
u14::ZERO,
0,
self.reporter.dest_id(),
timestamp,
),
additional_data: None, additional_data: None,
}; };
let mut service_queue = self.sender.service_queue.borrow_mut(); let mut service_queue = self.sender.service_queue.borrow_mut();
@@ -1955,7 +1921,7 @@ pub mod tests {
assert_eq!(info, cmp_info); 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 mut srv_queue = self.sender.service_queue.borrow_mut();
let cmp_info = TmInfo { let cmp_info = TmInfo {
requestor: MessageMetadata::new(self.request_id.into(), self.id), requestor: MessageMetadata::new(self.request_id.into(), self.id),
@@ -1973,7 +1939,7 @@ pub mod tests {
assert_eq!(info, cmp_info); 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 { let cmp_info = TmInfo {
requestor: MessageMetadata::new(self.request_id.into(), self.id), requestor: MessageMetadata::new(self.request_id.into(), self.id),
common: CommonTmInfo::new( common: CommonTmInfo::new(
@@ -2006,14 +1972,7 @@ pub mod tests {
fn check_acceptance_failure(&mut self, timestamp: &[u8; 7]) { fn check_acceptance_failure(&mut self, timestamp: &[u8; 7]) {
let cmp_info = TmInfo { let cmp_info = TmInfo {
requestor: MessageMetadata::new(self.request_id.into(), self.id), requestor: MessageMetadata::new(self.request_id.into(), self.id),
common: CommonTmInfo::new( common: CommonTmInfo::new(2, TEST_APID, 0, 0, self.reporter.dest_id(), timestamp),
2,
TEST_APID,
u14::ZERO,
0,
self.reporter.dest_id(),
timestamp,
),
additional_data: Some([0, 2].to_vec()), additional_data: Some([0, 2].to_vec()),
}; };
let service_queue = self.sender.service_queue.get_mut(); let service_queue = self.sender.service_queue.get_mut();
@@ -2101,9 +2060,9 @@ pub mod tests {
} }
fn create_generic_ping() -> PusTcCreator<'static> { 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); let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
PusTcCreator::new(sph, tc_header, &[], CreatorConfig::default()) PusTcCreator::new(sph, tc_header, &[], true)
} }
#[test] #[test]
@@ -2123,8 +2082,8 @@ pub mod tests {
fn test_state() { fn test_state() {
let mut testbench = VerificationReporterTestbench::new(0, create_generic_ping(), 16); let mut testbench = VerificationReporterTestbench::new(0, create_generic_ping(), 16);
assert_eq!(testbench.reporter.apid(), TEST_APID); assert_eq!(testbench.reporter.apid(), TEST_APID);
testbench.reporter.set_apid(u11::new(TEST_APID.value() + 1)); testbench.reporter.set_apid(TEST_APID + 1);
assert_eq!(testbench.reporter.apid().value(), TEST_APID.value() + 1); assert_eq!(testbench.reporter.apid(), TEST_APID + 1);
} }
#[test] #[test]
@@ -2274,7 +2233,7 @@ pub mod tests {
.expect("step 1 failed"); .expect("step 1 failed");
assert_eq!(testbench.sender.service_queue.borrow().len(), 4); assert_eq!(testbench.sender.service_queue.borrow().len(), 4);
testbench.check_acceptance_success(&EMPTY_STAMP); testbench.check_acceptance_success(&EMPTY_STAMP);
testbench.check_start_success(u14::ZERO, 0, &EMPTY_STAMP); testbench.check_start_success(0, 0, &EMPTY_STAMP);
testbench.check_step_success(0, &EMPTY_STAMP); testbench.check_step_success(0, &EMPTY_STAMP);
testbench.check_step_success(1, &EMPTY_STAMP); testbench.check_step_success(1, &EMPTY_STAMP);
} }
@@ -2308,7 +2267,7 @@ pub mod tests {
.step_failure(started_token, fail_params) .step_failure(started_token, fail_params)
.expect("Step failure failed"); .expect("Step failure failed");
testbench.check_acceptance_success(&EMPTY_STAMP); testbench.check_acceptance_success(&EMPTY_STAMP);
testbench.check_start_success(u14::ZERO, 0, DUMMY_STAMP); testbench.check_start_success(0, 0, DUMMY_STAMP);
testbench.check_step_success(0, &EMPTY_STAMP); testbench.check_step_success(0, &EMPTY_STAMP);
testbench.check_step_failure(&fail_step, &fail_code, &fail_data_raw); testbench.check_step_failure(&fail_step, &fail_code, &fail_data_raw);
} }
@@ -2330,7 +2289,7 @@ pub mod tests {
.completion_failure(started_token, fail_params) .completion_failure(started_token, fail_params)
.expect("Completion failure"); .expect("Completion failure");
testbench.check_acceptance_success(&EMPTY_STAMP); testbench.check_acceptance_success(&EMPTY_STAMP);
testbench.check_start_success(u14::ZERO, 0, DUMMY_STAMP); testbench.check_start_success(0, 0, DUMMY_STAMP);
testbench.check_completion_failure(&fail_code, &[]); testbench.check_completion_failure(&fail_code, &[]);
} }
@@ -2350,8 +2309,8 @@ pub mod tests {
.completion_success(started_token, &EMPTY_STAMP) .completion_success(started_token, &EMPTY_STAMP)
.expect("Sending completion success failed"); .expect("Sending completion success failed");
testbench.check_acceptance_success(&EMPTY_STAMP); testbench.check_acceptance_success(&EMPTY_STAMP);
testbench.check_start_success(u14::ZERO, 0, DUMMY_STAMP); testbench.check_start_success(0, 0, DUMMY_STAMP);
testbench.check_completion_success(u14::ZERO, 0); testbench.check_completion_success(0, 0);
} }
#[test] #[test]
@@ -2372,8 +2331,8 @@ pub mod tests {
.completion_success(started_token, &EMPTY_STAMP) .completion_success(started_token, &EMPTY_STAMP)
.expect("Sending completion success failed"); .expect("Sending completion success failed");
testbench.check_acceptance_success(&EMPTY_STAMP); testbench.check_acceptance_success(&EMPTY_STAMP);
testbench.check_start_success(u14::new(1), 1, DUMMY_STAMP); testbench.check_start_success(1, 1, DUMMY_STAMP);
testbench.check_completion_success(u14::new(2), 2); testbench.check_completion_success(2, 2);
} }
#[test] #[test]
@@ -2432,7 +2391,7 @@ pub mod tests {
); );
assert!(result.unwrap()); assert!(result.unwrap());
testbench.check_acceptance_success(&EMPTY_STAMP); testbench.check_acceptance_success(&EMPTY_STAMP);
testbench.check_start_success(u14::ZERO, 0, &EMPTY_STAMP); testbench.check_start_success(0, 0, &EMPTY_STAMP);
testbench.check_step_failure(&step, &fail_code, fail_data.as_bytes()); testbench.check_step_failure(&step, &fail_code, fail_data.as_bytes());
} }

View File

@@ -1,4 +1,3 @@
use arbitrary_int::u11;
use core::{fmt, marker::PhantomData}; use core::{fmt, marker::PhantomData};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -10,13 +9,13 @@ pub use alloc_mod::*;
pub use std_mod::*; pub use std_mod::*;
use spacepackets::{ use spacepackets::{
ecss::{tc::IsPusTelecommand, PusPacket},
ByteConversionError, ByteConversionError,
ecss::{PusPacket, tc::IsPusTelecommand},
}; };
use crate::{ use crate::{
ComponentId,
queue::{GenericReceiveError, GenericSendError}, queue::{GenericReceiveError, GenericSendError},
ComponentId,
}; };
/// Generic request ID type. Requests can be associated with an ID to have a unique identifier /// Generic request ID type. Requests can be associated with an ID to have a unique identifier
@@ -24,7 +23,7 @@ use crate::{
pub type RequestId = u32; pub type RequestId = u32;
/// CCSDS APID type definition. Please note that the APID is a 14 bit value. /// CCSDS APID type definition. Please note that the APID is a 14 bit value.
pub type Apid = u11; pub type Apid = u16;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct UniqueApidTargetId { pub struct UniqueApidTargetId {
@@ -40,8 +39,8 @@ impl UniqueApidTargetId {
} }
} }
pub fn raw(&self) -> ComponentId { pub const fn raw(&self) -> ComponentId {
((self.apid.value() as u64) << 32) | (self.unique_id as u64) ((self.apid as u64) << 32) | (self.unique_id as u64)
} }
pub fn id(&self) -> ComponentId { pub fn id(&self) -> ComponentId {
@@ -69,7 +68,7 @@ impl UniqueApidTargetId {
impl From<u64> for UniqueApidTargetId { impl From<u64> for UniqueApidTargetId {
fn from(raw: u64) -> Self { fn from(raw: u64) -> Self {
Self { Self {
apid: u11::new((raw >> 32) as u16), apid: (raw >> 32) as u16,
unique_id: raw as u32, unique_id: raw as u32,
} }
} }
@@ -497,18 +496,14 @@ mod tests {
use std::sync::mpsc; use std::sync::mpsc;
use alloc::string::ToString; use alloc::string::ToString;
use arbitrary_int::{u11, u14};
use spacepackets::{ use spacepackets::{
ecss::tc::{PusTcCreator, PusTcSecondaryHeader},
ByteConversionError, SpHeader, ByteConversionError, SpHeader,
ecss::{
CreatorConfig,
tc::{PusTcCreator, PusTcSecondaryHeader},
},
}; };
use crate::{ use crate::{
queue::{GenericReceiveError, GenericSendError}, queue::{GenericReceiveError, GenericSendError},
request::{Apid, MessageMetadata, MessageSenderMap, MessageSenderStoreProvider}, request::{MessageMetadata, MessageSenderMap, MessageSenderStoreProvider},
}; };
use super::{GenericMessage, MessageReceiverWithId, UniqueApidTargetId}; use super::{GenericMessage, MessageReceiverWithId, UniqueApidTargetId};
@@ -519,8 +514,8 @@ mod tests {
#[test] #[test]
fn test_basic_target_id_with_apid() { fn test_basic_target_id_with_apid() {
let id = UniqueApidTargetId::new(Apid::new(0x111), 0x01); let id = UniqueApidTargetId::new(0x111, 0x01);
assert_eq!(id.apid.value(), 0x111); assert_eq!(id.apid, 0x111);
assert_eq!(id.unique_id, 0x01); assert_eq!(id.unique_id, 0x01);
assert_eq!(id.id(), id.raw()); assert_eq!(id.id(), id.raw());
assert_eq!(u64::from(id), id.raw()); assert_eq!(u64::from(id), id.raw());
@@ -537,20 +532,19 @@ mod tests {
#[test] #[test]
fn test_basic_target_id_with_apid_from_pus_tc() { 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 app_data = 1_u32.to_be_bytes();
let pus_tc = let pus_tc = PusTcCreator::new_simple(sp_header, 17, 1, &app_data, true);
PusTcCreator::new_simple(sp_header, 17, 1, &app_data, CreatorConfig::default());
let id = UniqueApidTargetId::from_pus_tc(&pus_tc).unwrap(); 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); assert_eq!(id.unique_id, 1);
} }
#[test] #[test]
fn test_basic_target_id_with_apid_from_pus_tc_invalid_app_data() { 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 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); let error = UniqueApidTargetId::from_pus_tc(&pus_tc);
assert!(error.is_err()); assert!(error.is_err());
let error = error.unwrap_err(); let error = error.unwrap_err();

View File

@@ -211,8 +211,8 @@ mod tests {
println, println,
rc::Rc, rc::Rc,
sync::{ sync::{
Arc, Mutex,
mpsc::{self, TryRecvError}, mpsc::{self, TryRecvError},
Arc, Mutex,
}, },
time::Instant, time::Instant,
}; };

View File

@@ -1,5 +1,4 @@
use crate::{ use crate::{
ComponentId,
health::{HealthState, HealthTableProvider}, health::{HealthState, HealthTableProvider},
mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, ModeRequestSender, UNKNOWN_MODE_VAL}, mode::{Mode, ModeAndSubmode, ModeReply, ModeRequest, ModeRequestSender, UNKNOWN_MODE_VAL},
mode_tree::{ mode_tree::{
@@ -8,6 +7,7 @@ use crate::{
}, },
queue::GenericTargetedMessagingError, queue::GenericTargetedMessagingError,
request::{GenericMessage, RequestId}, request::{GenericMessage, RequestId},
ComponentId,
}; };
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
@@ -252,10 +252,10 @@ impl SequenceExecutionHelper {
Ok(ModeCommandingResult::AwaitingSuccessCheck) Ok(ModeCommandingResult::AwaitingSuccessCheck)
} else if seq_table_value.entries.len() - 1 == sequence_idx { } else if seq_table_value.entries.len() - 1 == sequence_idx {
self.state = SequenceExecutionHelperState::Idle; self.state = SequenceExecutionHelperState::Idle;
Ok(ModeCommandingResult::Done) return Ok(ModeCommandingResult::Done);
} else { } else {
self.current_sequence_index = Some(sequence_idx + 1); self.current_sequence_index = Some(sequence_idx + 1);
Ok(ModeCommandingResult::StepDone) return Ok(ModeCommandingResult::StepDone);
} }
} }
@@ -682,10 +682,9 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
ComponentId,
mode::{ mode::{
Mode, ModeAndSubmode, ModeReply, ModeRequest, UNKNOWN_MODE,
tests::{ModeReqSenderMock, ModeReqWrapper}, tests::{ModeReqSenderMock, ModeReqWrapper},
Mode, ModeAndSubmode, ModeReply, ModeRequest, UNKNOWN_MODE,
}, },
mode_tree::{ mode_tree::{
ModeStoreProvider, ModeStoreVec, SequenceModeTables, SequenceTableEntry, ModeStoreProvider, ModeStoreVec, SequenceModeTables, SequenceTableEntry,
@@ -694,6 +693,7 @@ mod tests {
queue::GenericTargetedMessagingError, queue::GenericTargetedMessagingError,
request::{GenericMessage, MessageMetadata, RequestId}, request::{GenericMessage, MessageMetadata, RequestId},
subsystem::{ModeCommandingResult, ModeTreeHelperState, SequenceExecutionHelperState}, subsystem::{ModeCommandingResult, ModeTreeHelperState, SequenceExecutionHelperState},
ComponentId,
}; };
#[derive(Debug)] #[derive(Debug)]

View File

@@ -1,7 +1,7 @@
use core::fmt::Debug; use core::fmt::Debug;
/// Generic abstraction for a check/countdown timer. /// Generic abstraction for a check/countdown timer.
pub trait Countdown: Debug { pub trait CountdownProvider: Debug {
fn has_expired(&self) -> bool; fn has_expired(&self) -> bool;
fn reset(&mut self); fn reset(&mut self);
} }

View File

@@ -9,20 +9,20 @@
//! They only need to send the received and generated data to these objects. //! They only need to send the received and generated data to these objects.
use crate::queue::GenericSendError; use crate::queue::GenericSendError;
use crate::{ use crate::{
ComponentId,
pool::{PoolAddr, PoolError}, pool::{PoolAddr, PoolError},
ComponentId,
}; };
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use alloc_mod::*; pub use alloc_mod::*;
use core::fmt::Debug; use core::fmt::Debug;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use downcast_rs::{Downcast, impl_downcast}; use downcast_rs::{impl_downcast, Downcast};
use spacepackets::{ use spacepackets::{
SpHeader,
ecss::{ ecss::{
tc::PusTcReader, tc::PusTcReader,
tm::{PusTmCreator, PusTmReader}, tm::{PusTmCreator, PusTmReader},
}, },
SpHeader,
}; };
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::sync::mpsc; use std::sync::mpsc;

View File

@@ -1,16 +1,15 @@
use arbitrary_int::{u11, u14};
use spacepackets::SpHeader;
use spacepackets::ecss::CreatorConfig;
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader}; use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
use spacepackets::time::cds::CdsTime; use spacepackets::time::cds::CdsTime;
use spacepackets::time::TimeWriter;
use spacepackets::SpHeader;
pub struct PusTmWithCdsShortHelper { pub struct PusTmWithCdsShortHelper {
apid: u11, apid: u16,
cds_short_buf: [u8; 7], cds_short_buf: [u8; 7],
} }
impl PusTmWithCdsShortHelper { impl PusTmWithCdsShortHelper {
pub fn new(apid: u11) -> Self { pub fn new(apid: u16) -> Self {
Self { Self {
apid, apid,
cds_short_buf: [0; 7], cds_short_buf: [0; 7],
@@ -23,7 +22,7 @@ impl PusTmWithCdsShortHelper {
service: u8, service: u8,
subservice: u8, subservice: u8,
source_data: &'data [u8], source_data: &'data [u8],
seq_count: u14, seq_count: u16,
) -> PusTmCreator<'_, 'data> { ) -> PusTmCreator<'_, 'data> {
let time_stamp = CdsTime::now_with_u16_days().unwrap(); let time_stamp = CdsTime::now_with_u16_days().unwrap();
time_stamp.write_to_bytes(&mut self.cds_short_buf).unwrap(); time_stamp.write_to_bytes(&mut self.cds_short_buf).unwrap();
@@ -36,7 +35,7 @@ impl PusTmWithCdsShortHelper {
subservice: u8, subservice: u8,
source_data: &'data [u8], source_data: &'data [u8],
stamper: &CdsTime, stamper: &CdsTime,
seq_count: u14, seq_count: u16,
) -> PusTmCreator<'_, 'data> { ) -> PusTmCreator<'_, 'data> {
stamper.write_to_bytes(&mut self.cds_short_buf).unwrap(); stamper.write_to_bytes(&mut self.cds_short_buf).unwrap();
self.create_pus_tm_common(service, subservice, source_data, seq_count) self.create_pus_tm_common(service, subservice, source_data, seq_count)
@@ -47,47 +46,40 @@ impl PusTmWithCdsShortHelper {
service: u8, service: u8,
subservice: u8, subservice: u8,
source_data: &'data [u8], source_data: &'data [u8],
seq_count: u14, seq_count: u16,
) -> PusTmCreator<'_, 'data> { ) -> PusTmCreator<'_, 'data> {
let reply_header = SpHeader::new_for_unseg_tm(self.apid, seq_count, 0); 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); let tc_header = PusTmSecondaryHeader::new_simple(service, subservice, &self.cds_short_buf);
PusTmCreator::new( PusTmCreator::new(reply_header, tc_header, source_data, true)
reply_header,
tc_header,
source_data,
CreatorConfig::default(),
)
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use arbitrary_int::{u11, u14}; use spacepackets::{ecss::PusPacket, time::cds::CdsTime, CcsdsPacket};
use spacepackets::{CcsdsPacket, ecss::PusPacket, time::cds::CdsTime};
use super::PusTmWithCdsShortHelper; use super::PusTmWithCdsShortHelper;
#[test] #[test]
fn test_helper_with_stamper() { 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 stamper = CdsTime::new_with_u16_days(0, 0);
let tm = let tm = pus_tm_helper.create_pus_tm_with_stamper(17, 1, &[1, 2, 3, 4], &stamper, 25);
pus_tm_helper.create_pus_tm_with_stamper(17, 1, &[1, 2, 3, 4], &stamper, u14::new(25));
assert_eq!(tm.service(), 17); assert_eq!(tm.service(), 17);
assert_eq!(tm.subservice(), 1); assert_eq!(tm.subservice(), 1);
assert_eq!(tm.user_data(), &[1, 2, 3, 4]); 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]) assert_eq!(tm.timestamp(), [64, 0, 0, 0, 0, 0, 0])
} }
#[test] #[test]
fn test_helper_from_now() { fn test_helper_from_now() {
let mut pus_tm_helper = PusTmWithCdsShortHelper::new(u11::new(0x123)); let mut pus_tm_helper = PusTmWithCdsShortHelper::new(0x123);
let tm = pus_tm_helper.create_pus_tm_timestamp_now(17, 1, &[1, 2, 3, 4], u14::new(25)); 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.service(), 17);
assert_eq!(tm.subservice(), 1); assert_eq!(tm.subservice(), 1);
assert_eq!(tm.user_data(), &[1, 2, 3, 4]); 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); assert_eq!(tm.timestamp().len(), 7);
} }
} }

View File

@@ -2,8 +2,8 @@
use core::mem::size_of; use core::mem::size_of;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use spacepackets::ecss::{PfcReal, PfcUnsigned, Ptc}; use spacepackets::ecss::{PfcReal, PfcUnsigned, Ptc};
use spacepackets::time::CcsdsTimeProvider;
use spacepackets::time::cds::CdsTime; use spacepackets::time::cds::CdsTime;
use spacepackets::time::{CcsdsTimeProvider, TimeWriter};
enum NumOfParamsInfo { enum NumOfParamsInfo {
/// The parameter entry is a scalar field /// The parameter entry is a scalar field

View File

@@ -4,13 +4,13 @@ use satrs::dev_mgmt::{
DevManagerCommandingHelper, DevManagerHelperResult, TransparentDevManagerHook, DevManagerCommandingHelper, DevManagerHelperResult, TransparentDevManagerHook,
}; };
use satrs::mode::{ use satrs::mode::{
INVALID_MODE, Mode, ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, Mode, ModeError, ModeProvider, ModeReplyReceiver, ModeReplySender, ModeRequestHandler,
ModeRequestHandler, ModeRequestHandlerMpscBounded, ModeRequestReceiver, ModeRequestHandlerMpscBounded, ModeRequestReceiver, ModeRequestorAndHandlerMpscBounded,
ModeRequestorAndHandlerMpscBounded, ModeRequestorOneChildBoundedMpsc, UNKNOWN_MODE, ModeRequestorOneChildBoundedMpsc, INVALID_MODE, UNKNOWN_MODE,
}; };
use satrs::mode_tree::{ use satrs::mode_tree::{
ModeChild, ModeNode, ModeParent, ModeStoreProvider, SequenceTableEntry, SequenceTableMapTable, connect_mode_nodes, ModeChild, ModeNode, ModeParent, ModeStoreProvider, SequenceTableEntry,
TargetTableEntry, connect_mode_nodes, SequenceTableMapTable, TargetTableEntry,
}; };
use satrs::mode_tree::{SequenceTablesMapValue, TargetTablesMapValue}; use satrs::mode_tree::{SequenceTablesMapValue, TargetTablesMapValue};
use satrs::request::{MessageMetadata, RequestId}; use satrs::request::{MessageMetadata, RequestId};
@@ -20,10 +20,10 @@ use satrs::subsystem::{
StartSequenceError, SubsystemCommandingHelper, SubsystemHelperResult, StartSequenceError, SubsystemCommandingHelper, SubsystemHelperResult,
}; };
use satrs::{ use satrs::{
ComponentId,
mode::{ModeAndSubmode, ModeReply, ModeRequest}, mode::{ModeAndSubmode, ModeReply, ModeRequest},
queue::GenericTargetedMessagingError, queue::GenericTargetedMessagingError,
request::GenericMessage, request::GenericMessage,
ComponentId,
}; };
use std::borrow::{Borrow, BorrowMut}; use std::borrow::{Borrow, BorrowMut};
use std::cell::RefCell; use std::cell::RefCell;

View File

@@ -1,4 +1,3 @@
use arbitrary_int::u11;
use satrs::event_man::{ use satrs::event_man::{
EventManagerWithMpsc, EventMessage, EventMessageU32, EventRoutingError, EventSendProvider, EventManagerWithMpsc, EventMessage, EventMessageU32, EventRoutingError, EventSendProvider,
EventU32SenderMpsc, EventU32SenderMpsc,
@@ -9,15 +8,15 @@ use satrs::params::{Params, ParamsHeapless, WritableToBeBytes};
use satrs::pus::event_man::{DefaultPusEventReportingMap, EventReporter, PusEventTmCreatorWithMap}; use satrs::pus::event_man::{DefaultPusEventReportingMap, EventReporter, PusEventTmCreatorWithMap};
use satrs::request::UniqueApidTargetId; use satrs::request::UniqueApidTargetId;
use satrs::tmtc::PacketAsVec; use satrs::tmtc::PacketAsVec;
use spacepackets::ecss::PusError;
use spacepackets::ecss::tm::PusTmReader; use spacepackets::ecss::tm::PusTmReader;
use spacepackets::ecss::{PusError, PusPacket};
use std::sync::mpsc::{self, SendError, TryRecvError}; use std::sync::mpsc::{self, SendError, TryRecvError};
use std::thread; use std::thread;
const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::<SeverityInfo>::new(1, 0); const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::<SeverityInfo>::new(1, 0);
const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5); const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5);
const EMPTY_STAMP: [u8; 7] = [0; 7]; 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); const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -36,7 +35,8 @@ fn test_threaded_usage() {
event_man.subscribe_all(pus_event_man_send_provider.target_id()); event_man.subscribe_all(pus_event_man_send_provider.target_id());
event_man.add_sender(pus_event_man_send_provider); event_man.add_sender(pus_event_man_send_provider);
let (event_packet_tx, event_packet_rx) = mpsc::channel::<PacketAsVec>(); let (event_packet_tx, event_packet_rx) = mpsc::channel::<PacketAsVec>();
let reporter = EventReporter::new(TEST_ID.raw(), u11::new(0x02), 0, 128); let reporter =
EventReporter::new(TEST_ID.raw(), 0x02, 0, 128).expect("Creating event reporter failed");
let pus_event_man = let pus_event_man =
PusEventTmCreatorWithMap::new(reporter, DefaultPusEventReportingMap::default()); PusEventTmCreatorWithMap::new(reporter, DefaultPusEventReportingMap::default());
let error_handler = |event_msg: &EventMessageU32, error: EventRoutingError| { let error_handler = |event_msg: &EventMessageU32, error: EventRoutingError| {

View File

@@ -1,19 +1,17 @@
#[cfg(feature = "crossbeam")] #[cfg(feature = "crossbeam")]
pub mod crossbeam_test { pub mod crossbeam_test {
use arbitrary_int::traits::Integer as _;
use arbitrary_int::u14;
use hashbrown::HashMap; use hashbrown::HashMap;
use satrs::pool::{PoolProvider, PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig}; use satrs::pool::{PoolProvider, PoolProviderWithGuards, StaticMemoryPool, StaticPoolConfig};
use satrs::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0}; use satrs::pus::test_util::{TEST_APID, TEST_COMPONENT_ID_0};
use satrs::pus::verification::{ use satrs::pus::verification::{
FailParams, RequestId, VerificationReporter, VerificationReporterConfig, FailParams, RequestId, VerificationReporter, VerificationReporterCfg,
VerificationReportingProvider, VerificationReportingProvider,
}; };
use satrs::tmtc::{PacketSenderWithSharedPool, SharedStaticMemoryPool}; use satrs::tmtc::{PacketSenderWithSharedPool, SharedStaticMemoryPool};
use spacepackets::SpHeader;
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader}; use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
use spacepackets::ecss::tm::PusTmReader; 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::sync::RwLock;
use std::thread; use std::thread;
use std::time::Duration; 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 // 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 // the same APID. If they had distinct APIDs, the more correct approach would be to have
// each reporter have an own sequence count provider. // each reporter have an own sequence count provider.
let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8); let cfg = VerificationReporterCfg::new(TEST_APID, 1, 2, 8).unwrap();
// Shared pool object to store the verification PUS telemetry // Shared pool object to store the verification PUS telemetry
let pool_cfg = StaticPoolConfig::new_from_subpool_cfg_tuples( let pool_cfg = StaticPoolConfig::new_from_subpool_cfg_tuples(
vec![(10, 32), (10, 64), (10, 128), (10, 1024)], vec![(10, 32), (10, 64), (10, 128), (10, 1024)],
@@ -48,8 +46,8 @@ pub mod crossbeam_test {
let sender = let sender =
PacketSenderWithSharedPool::new_with_shared_packet_pool(tx.clone(), &shared_tm_pool); PacketSenderWithSharedPool::new_with_shared_packet_pool(tx.clone(), &shared_tm_pool);
let sender_1 = sender.clone(); let sender_1 = sender.clone();
let reporter_with_sender_0 = VerificationReporter::new(TEST_COMPONENT_ID_0.id(), &cfg); let mut 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_1 = reporter_with_sender_0.clone();
// For test purposes, we retrieve the request ID from the TCs and pass them to the receiver // For test purposes, we retrieve the request ID from the TCs and pass them to the receiver
// tread. // tread.
let req_id_0; let req_id_0;
@@ -59,9 +57,9 @@ pub mod crossbeam_test {
let (tx_tc_1, rx_tc_1) = crossbeam_channel::bounded(3); let (tx_tc_1, rx_tc_1) = crossbeam_channel::bounded(3);
{ {
let mut tc_guard = shared_tc_pool.write().unwrap(); 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 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); req_id_0 = RequestId::new(&pus_tc_0);
let addr = tc_guard let addr = tc_guard
.free_element(pus_tc_0.len_written(), |buf| { .free_element(pus_tc_0.len_written(), |buf| {
@@ -69,9 +67,9 @@ pub mod crossbeam_test {
}) })
.unwrap(); .unwrap();
tx_tc_0.send(addr).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 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); req_id_1 = RequestId::new(&pus_tc_1);
let addr = tc_guard let addr = tc_guard
.free_element(pus_tc_0.len_written(), |buf| { .free_element(pus_tc_0.len_written(), |buf| {

View File

@@ -17,14 +17,12 @@ use core::{
use std::{ use std::{
io::{Read, Write}, io::{Read, Write},
net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream}, net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream},
sync::{Mutex, mpsc}, sync::{mpsc, Mutex},
thread, thread,
}; };
use arbitrary_int::{u11, u14};
use hashbrown::HashSet; use hashbrown::HashSet;
use satrs::{ use satrs::{
ComponentId,
encoding::{ encoding::{
ccsds::{SpValidity, SpacePacketValidator}, ccsds::{SpValidity, SpacePacketValidator},
cobs::encode_packet_with_cobs, cobs::encode_packet_with_cobs,
@@ -34,10 +32,11 @@ use satrs::{
TcpSpacepacketsServer, TcpTmtcInCobsServer, TcpSpacepacketsServer, TcpTmtcInCobsServer,
}, },
tmtc::PacketSource, tmtc::PacketSource,
ComponentId,
}; };
use spacepackets::{ use spacepackets::{
ecss::{tc::PusTcCreator, WritablePusPacket},
CcsdsPacket, PacketId, SpHeader, CcsdsPacket, PacketId, SpHeader,
ecss::{CreatorConfig, WritablePusPacket, tc::PusTcCreator},
}; };
use std::{collections::VecDeque, sync::Arc, vec::Vec}; 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)); 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); const TEST_PACKET_ID_0: PacketId = PacketId::new_for_tc(true, TEST_APID_0);
#[derive(Default)] #[derive(Default)]
@@ -218,8 +217,8 @@ impl SpacePacketValidator for SimpleVerificator {
fn test_ccsds_server() { fn test_ccsds_server() {
let (tc_sender, tc_receiver) = mpsc::channel(); let (tc_sender, tc_receiver) = mpsc::channel();
let mut tm_source = SyncTmSource::default(); let mut tm_source = SyncTmSource::default();
let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, u14::new(0), 0); let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, 0, 0);
let verif_tm = PusTcCreator::new_simple(sph, 1, 1, &[], CreatorConfig::default()); let verif_tm = PusTcCreator::new_simple(sph, 1, 1, &[], true);
let tm_0 = verif_tm.to_vec().expect("tm generation failed"); let tm_0 = verif_tm.to_vec().expect("tm generation failed");
tm_source.add_tm(&tm_0); tm_source.add_tm(&tm_0);
let mut packet_id_lookup = SimpleVerificator::default(); let mut packet_id_lookup = SimpleVerificator::default();
@@ -268,8 +267,8 @@ fn test_ccsds_server() {
.expect("setting reas timeout failed"); .expect("setting reas timeout failed");
// Send ping telecommand. // Send ping telecommand.
let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, u14::new(0), 0); let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, 0, 0);
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default()); let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], true);
let tc_0 = ping_tc.to_vec().expect("packet creation failed"); let tc_0 = ping_tc.to_vec().expect("packet creation failed");
stream stream
.write_all(&tc_0) .write_all(&tc_0)