Merge remote-tracking branch 'origin/main' into ccsds-scheduler
This commit is contained in:
@@ -8,10 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v0.3.0-alpha.3] 2025-09-??
|
||||
# [v0.3.0-alpha.3] 2025-11-06
|
||||
|
||||
- Bump `sat-rs` edition to 2024.
|
||||
- Bumped `spacepackets` to v0.16
|
||||
- Bumped `spacepackets` to v0.17
|
||||
- `ComponentId` is u32 now
|
||||
- Simplified TCP servers
|
||||
|
||||
## Changed
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "satrs"
|
||||
version = "0.3.0-alpha.2"
|
||||
version = "0.3.0-alpha.3"
|
||||
edition = "2024"
|
||||
rust-version = "1.85.0"
|
||||
authors = ["Robin Mueller <muellerr@irs.uni-stuttgart.de>"]
|
||||
@@ -14,16 +14,16 @@ categories = ["aerospace", "aerospace::space-protocols", "no-std", "hardware-sup
|
||||
|
||||
[dependencies]
|
||||
satrs-shared = { version = "0.2", path = "../satrs-shared" }
|
||||
spacepackets = { version = "0.16", default-features = false }
|
||||
spacepackets = { version = "0.17", default-features = false }
|
||||
|
||||
delegate = ">0.7, <=0.13"
|
||||
delegate = "0.13"
|
||||
paste = "1"
|
||||
derive-new = ">=0.6, <=0.7"
|
||||
num_enum = { version = ">0.5, <=0.7", default-features = false }
|
||||
cobs = { version = "0.4", default-features = false }
|
||||
derive-new = "0.7"
|
||||
num_enum = { version = "0.7", default-features = false }
|
||||
cobs = { version = "0.5", default-features = false }
|
||||
thiserror = { version = "2", default-features = false }
|
||||
|
||||
hashbrown = { version = ">=0.14, <=0.15", optional = true }
|
||||
hashbrown = { version = "0.16", optional = true }
|
||||
static_cell = { version = "2" }
|
||||
heapless = { version = "0.9", optional = true }
|
||||
dyn-clone = { version = "1", optional = true }
|
||||
@@ -64,6 +64,7 @@ std = [
|
||||
]
|
||||
alloc = [
|
||||
"serde/alloc",
|
||||
"cobs/alloc",
|
||||
"spacepackets/alloc",
|
||||
"hashbrown",
|
||||
"dyn-clone",
|
||||
@@ -71,7 +72,6 @@ alloc = [
|
||||
]
|
||||
serde = ["dep:serde", "spacepackets/serde", "satrs-shared/serde"]
|
||||
crossbeam = ["crossbeam-channel"]
|
||||
# heapless = ["dep:heapless", "static_cell"]
|
||||
defmt = ["dep:defmt", "spacepackets/defmt"]
|
||||
test_util = []
|
||||
|
||||
|
||||
@@ -296,18 +296,18 @@ mod tests {
|
||||
fn test_mode_announce() {
|
||||
let mut assy_helper = DevManagerCommandingHelper::new(TransparentDevManagerHook::default());
|
||||
let mode_req_sender = ModeReqSenderMock::default();
|
||||
assy_helper.add_mode_child(ExampleId::Id1 as u64, UNKNOWN_MODE);
|
||||
assy_helper.add_mode_child(ExampleId::Id2 as u64, UNKNOWN_MODE);
|
||||
assy_helper.add_mode_child(ExampleId::Id1 as ComponentId, UNKNOWN_MODE);
|
||||
assy_helper.add_mode_child(ExampleId::Id2 as ComponentId, UNKNOWN_MODE);
|
||||
assy_helper
|
||||
.send_announce_mode_cmd_to_children(1, &mode_req_sender, false)
|
||||
.unwrap();
|
||||
assert_eq!(mode_req_sender.requests.borrow().len(), 2);
|
||||
let mut req = mode_req_sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req.target_id, ExampleId::Id1 as u64);
|
||||
assert_eq!(req.target_id, ExampleId::Id1 as ComponentId);
|
||||
assert_eq!(req.request_id, 1);
|
||||
assert_eq!(req.request, ModeRequest::AnnounceMode);
|
||||
req = mode_req_sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req.target_id, ExampleId::Id2 as u64);
|
||||
assert_eq!(req.target_id, ExampleId::Id2 as ComponentId);
|
||||
assert_eq!(req.request_id, 1);
|
||||
assert_eq!(req.request, ModeRequest::AnnounceMode);
|
||||
}
|
||||
@@ -316,18 +316,18 @@ mod tests {
|
||||
fn test_mode_announce_recursive() {
|
||||
let mut assy_helper = DevManagerCommandingHelper::new(TransparentDevManagerHook::default());
|
||||
let mode_req_sender = ModeReqSenderMock::default();
|
||||
assy_helper.add_mode_child(ExampleId::Id1 as u64, UNKNOWN_MODE);
|
||||
assy_helper.add_mode_child(ExampleId::Id2 as u64, UNKNOWN_MODE);
|
||||
assy_helper.add_mode_child(ExampleId::Id1 as ComponentId, UNKNOWN_MODE);
|
||||
assy_helper.add_mode_child(ExampleId::Id2 as ComponentId, UNKNOWN_MODE);
|
||||
assy_helper
|
||||
.send_announce_mode_cmd_to_children(1, &mode_req_sender, true)
|
||||
.unwrap();
|
||||
assert_eq!(mode_req_sender.requests.borrow().len(), 2);
|
||||
let mut req = mode_req_sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req.target_id, ExampleId::Id1 as u64);
|
||||
assert_eq!(req.target_id, ExampleId::Id1 as ComponentId);
|
||||
assert_eq!(req.request_id, 1);
|
||||
assert_eq!(req.request, ModeRequest::AnnounceModeRecursive);
|
||||
req = mode_req_sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req.target_id, ExampleId::Id2 as u64);
|
||||
assert_eq!(req.target_id, ExampleId::Id2 as ComponentId);
|
||||
assert_eq!(req.request_id, 1);
|
||||
assert_eq!(req.request, ModeRequest::AnnounceModeRecursive);
|
||||
}
|
||||
@@ -337,12 +337,12 @@ mod tests {
|
||||
let mut dev_mgmt_helper =
|
||||
DevManagerCommandingHelper::new(TransparentDevManagerHook::default());
|
||||
let mode_req_sender = ModeReqSenderMock::default();
|
||||
dev_mgmt_helper.add_mode_child(ExampleId::Id1 as u64, UNKNOWN_MODE);
|
||||
dev_mgmt_helper.add_mode_child(ExampleId::Id1 as ComponentId, UNKNOWN_MODE);
|
||||
let expected_mode = ModeAndSubmode::new(ExampleMode::Mode1 as u32, 0);
|
||||
dev_mgmt_helper
|
||||
.send_mode_cmd_to_one_child(
|
||||
1,
|
||||
ExampleId::Id1 as u64,
|
||||
ExampleId::Id1 as ComponentId,
|
||||
expected_mode,
|
||||
false,
|
||||
&mode_req_sender,
|
||||
@@ -350,7 +350,7 @@ mod tests {
|
||||
.unwrap();
|
||||
assert_eq!(mode_req_sender.requests.borrow().len(), 1);
|
||||
let req = mode_req_sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req.target_id, ExampleId::Id1 as u64);
|
||||
assert_eq!(req.target_id, ExampleId::Id1 as ComponentId);
|
||||
assert_eq!(req.request_id, 1);
|
||||
assert_eq!(
|
||||
req.request,
|
||||
@@ -368,7 +368,7 @@ mod tests {
|
||||
assert_eq!(ctx.active_request_id, 1);
|
||||
}
|
||||
let reply = GenericMessage::new(
|
||||
MessageMetadata::new(1, ExampleId::Id1 as u64),
|
||||
MessageMetadata::new(1, ExampleId::Id1 as ComponentId),
|
||||
ModeReply::ModeReply(expected_mode),
|
||||
);
|
||||
if let DevManagerHelperResult::ModeCommandingDone(ActiveModeCommandContext {
|
||||
@@ -387,15 +387,15 @@ mod tests {
|
||||
let mut dev_mgmt_helper =
|
||||
DevManagerCommandingHelper::new(TransparentDevManagerHook::default());
|
||||
let mode_req_sender = ModeReqSenderMock::default();
|
||||
dev_mgmt_helper.add_mode_child(ExampleId::Id1 as u64, UNKNOWN_MODE);
|
||||
dev_mgmt_helper.add_mode_child(ExampleId::Id2 as u64, UNKNOWN_MODE);
|
||||
dev_mgmt_helper.add_mode_child(ExampleId::Id1 as ComponentId, UNKNOWN_MODE);
|
||||
dev_mgmt_helper.add_mode_child(ExampleId::Id2 as ComponentId, UNKNOWN_MODE);
|
||||
let expected_mode = ModeAndSubmode::new(ExampleMode::Mode2 as u32, 0);
|
||||
dev_mgmt_helper
|
||||
.send_mode_cmd_to_all_children(1, expected_mode, false, &mode_req_sender)
|
||||
.unwrap();
|
||||
assert_eq!(mode_req_sender.requests.borrow().len(), 2);
|
||||
let req = mode_req_sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req.target_id, ExampleId::Id1 as u64);
|
||||
assert_eq!(req.target_id, ExampleId::Id1 as ComponentId);
|
||||
assert_eq!(req.request_id, 1);
|
||||
assert_eq!(
|
||||
req.request,
|
||||
@@ -405,7 +405,7 @@ mod tests {
|
||||
}
|
||||
);
|
||||
let req = mode_req_sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req.target_id, ExampleId::Id2 as u64);
|
||||
assert_eq!(req.target_id, ExampleId::Id2 as ComponentId);
|
||||
assert_eq!(req.request_id, 1);
|
||||
assert_eq!(
|
||||
req.request,
|
||||
@@ -424,7 +424,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let reply = GenericMessage::new(
|
||||
MessageMetadata::new(1, ExampleId::Id1 as u64),
|
||||
MessageMetadata::new(1, ExampleId::Id1 as ComponentId),
|
||||
ModeReply::ModeReply(expected_mode),
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -432,7 +432,7 @@ mod tests {
|
||||
DevManagerHelperResult::Busy
|
||||
);
|
||||
let reply = GenericMessage::new(
|
||||
MessageMetadata::new(1, ExampleId::Id2 as u64),
|
||||
MessageMetadata::new(1, ExampleId::Id2 as ComponentId),
|
||||
ModeReply::ModeReply(expected_mode),
|
||||
);
|
||||
if let DevManagerHelperResult::ModeCommandingDone(ActiveModeCommandContext {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use spacepackets::SpHeader;
|
||||
|
||||
use crate::{ComponentId, tmtc::PacketSenderRaw};
|
||||
use crate::{ComponentId, tmtc::PacketHandler};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum SpValidity {
|
||||
@@ -24,13 +24,17 @@ pub trait SpacePacketValidator {
|
||||
#[derive(Default, Debug, PartialEq, Eq)]
|
||||
pub struct ParseResult {
|
||||
pub packets_found: u32,
|
||||
/// If an incomplete space packet was found, its start index is indicated by this value.
|
||||
pub incomplete_tail_start: Option<usize>,
|
||||
pub parsed_bytes: usize,
|
||||
// If an incomplete space packet was found, its start index is indicated by this value.
|
||||
//pub incomplete_packet_start: Option<usize>,
|
||||
}
|
||||
|
||||
/// This function parses a given buffer for tightly packed CCSDS space packets. It uses the
|
||||
/// [spacepackets::SpHeader] of the CCSDS packets and a user provided [SpacePacketValidator]
|
||||
/// to check whether a received space packet is relevant for processing.
|
||||
/// This function parses a given buffer for tightly packed CCSDS space packets.
|
||||
///
|
||||
/// Please note that it is recommended to use a proper data link layer instead to have proper
|
||||
/// packet framing and to allow more reliable recovery from packet loss.
|
||||
/// It uses the [spacepackets::SpHeader] of the CCSDS packets and a user provided
|
||||
/// [SpacePacketValidator] to check whether a received space packet is relevant for processing.
|
||||
///
|
||||
/// This function is also able to deal with broken tail packets at the end as long a the parser
|
||||
/// can read the full 7 bytes which constitue a space packet header plus one byte minimal size.
|
||||
@@ -41,17 +45,18 @@ pub struct ParseResult {
|
||||
/// [SpacePacketValidator]:
|
||||
///
|
||||
/// 1. [SpValidity::Valid]: The parser will forward all packets to the given `packet_sender` and
|
||||
/// return the number of packets found.If the [PacketSenderRaw::send_packet] calls fails, the
|
||||
/// return the number of packets found.If the [PacketHandler::handle_packet] calls fails, the
|
||||
/// error will be returned.
|
||||
/// 2. [SpValidity::Invalid]: The parser assumes that the synchronization is lost and tries to
|
||||
/// find the start of a new space packet header by scanning all the following bytes.
|
||||
/// 3. [SpValidity::Skip]: The parser skips the packet using the packet length determined from the
|
||||
/// space packet header.
|
||||
///
|
||||
pub fn parse_buffer_for_ccsds_space_packets<SendError>(
|
||||
buf: &[u8],
|
||||
packet_validator: &(impl SpacePacketValidator + ?Sized),
|
||||
sender_id: ComponentId,
|
||||
packet_sender: &(impl PacketSenderRaw<Error = SendError> + ?Sized),
|
||||
packet_sender: &(impl PacketHandler<Error = SendError> + ?Sized),
|
||||
) -> Result<ParseResult, SendError> {
|
||||
let mut parse_result = ParseResult::default();
|
||||
let mut current_idx = 0;
|
||||
@@ -66,11 +71,12 @@ pub fn parse_buffer_for_ccsds_space_packets<SendError>(
|
||||
let packet_size = sp_header.packet_len();
|
||||
if (current_idx + packet_size) <= buf_len {
|
||||
packet_sender
|
||||
.send_packet(sender_id, &buf[current_idx..current_idx + packet_size])?;
|
||||
.handle_packet(sender_id, &buf[current_idx..current_idx + packet_size])?;
|
||||
parse_result.packets_found += 1;
|
||||
} else {
|
||||
// Move packet to start of buffer if applicable.
|
||||
parse_result.incomplete_tail_start = Some(current_idx);
|
||||
//parse_result.incomplete_packet_start = Some(current_idx);
|
||||
break;
|
||||
}
|
||||
current_idx += packet_size;
|
||||
continue;
|
||||
@@ -84,6 +90,7 @@ pub fn parse_buffer_for_ccsds_space_packets<SendError>(
|
||||
}
|
||||
}
|
||||
}
|
||||
parse_result.parsed_bytes = current_idx;
|
||||
Ok(parse_result)
|
||||
}
|
||||
|
||||
@@ -92,7 +99,7 @@ mod tests {
|
||||
use arbitrary_int::{u11, u14};
|
||||
use spacepackets::{
|
||||
CcsdsPacket, PacketId, PacketSequenceControl, PacketType, SequenceFlags, SpHeader,
|
||||
ecss::{CreatorConfig, tc::PusTcCreator},
|
||||
ecss::{CreatorConfig, MessageTypeId, tc::PusTcCreator},
|
||||
};
|
||||
|
||||
use crate::{ComponentId, encoding::tests::TcCacher};
|
||||
@@ -132,7 +139,12 @@ mod tests {
|
||||
#[test]
|
||||
fn test_basic() {
|
||||
let sph = SpHeader::new_from_apid(TEST_APID_0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let mut buffer: [u8; 32] = [0; 32];
|
||||
let packet_len = ping_tc
|
||||
.write_to_bytes(&mut buffer)
|
||||
@@ -157,8 +169,14 @@ mod tests {
|
||||
#[test]
|
||||
fn test_multi_packet() {
|
||||
let sph = SpHeader::new_from_apid(TEST_APID_0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let action_tc = PusTcCreator::new_simple(sph, 8, 0, &[], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let action_tc =
|
||||
PusTcCreator::new_simple(sph, MessageTypeId::new(8, 0), &[], CreatorConfig::default());
|
||||
let mut buffer: [u8; 32] = [0; 32];
|
||||
let packet_len_ping = ping_tc
|
||||
.write_to_bytes(&mut buffer)
|
||||
@@ -192,9 +210,15 @@ mod tests {
|
||||
#[test]
|
||||
fn test_multi_apid() {
|
||||
let sph = SpHeader::new_from_apid(TEST_APID_0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
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, MessageTypeId::new(8, 0), &[], CreatorConfig::default());
|
||||
let mut buffer: [u8; 32] = [0; 32];
|
||||
let packet_len_ping = ping_tc
|
||||
.write_to_bytes(&mut buffer)
|
||||
@@ -224,15 +248,13 @@ mod tests {
|
||||
fn test_split_packet_multi() {
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
17,
|
||||
1,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let action_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_1),
|
||||
8,
|
||||
0,
|
||||
MessageTypeId::new(8, 0),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
@@ -254,8 +276,7 @@ mod tests {
|
||||
assert!(parse_result.is_ok());
|
||||
let parse_result = parse_result.unwrap();
|
||||
assert_eq!(parse_result.packets_found, 1);
|
||||
assert!(parse_result.incomplete_tail_start.is_some());
|
||||
let incomplete_tail_idx = parse_result.incomplete_tail_start.unwrap();
|
||||
let incomplete_tail_idx = parse_result.parsed_bytes;
|
||||
assert_eq!(incomplete_tail_idx, packet_len_ping);
|
||||
|
||||
let queue = tc_cacher.tc_queue.borrow();
|
||||
@@ -268,8 +289,7 @@ mod tests {
|
||||
fn test_one_split_packet() {
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
17,
|
||||
1,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{ComponentId, tmtc::PacketSenderRaw};
|
||||
use cobs::{decode_in_place, encode, max_encoding_length};
|
||||
use crate::{ComponentId, tmtc::PacketHandler};
|
||||
use cobs::{decode_in_place, encode_including_sentinels, max_encoding_length};
|
||||
|
||||
/// This function encodes the given packet with COBS and also wraps the encoded packet with
|
||||
/// the sentinel value 0. It can be used repeatedly on the same encoded buffer by expecting
|
||||
@@ -37,15 +37,16 @@ pub fn encode_packet_with_cobs(
|
||||
if *current_idx + max_encoding_len + 2 > encoded_buf.len() {
|
||||
return false;
|
||||
}
|
||||
encoded_buf[*current_idx] = 0;
|
||||
*current_idx += 1;
|
||||
*current_idx += encode(packet, &mut encoded_buf[*current_idx..]);
|
||||
encoded_buf[*current_idx] = 0;
|
||||
*current_idx += 1;
|
||||
*current_idx += encode_including_sentinels(packet, &mut encoded_buf[*current_idx..]);
|
||||
true
|
||||
}
|
||||
|
||||
/// This function parses a given buffer for COBS encoded packets. The packet structure is
|
||||
/// This function parses a given buffer for COBS encoded packets.
|
||||
///
|
||||
/// Please note that, it is recommended to use [cobs::CobsDecoderOwned] or [cobs::CobsDecoder]
|
||||
/// instead.
|
||||
///
|
||||
/// The packet structure is
|
||||
/// expected to be like this, assuming a sentinel value of 0 as the packet delimiter:
|
||||
///
|
||||
/// 0 | ... Encoded Packet Data ... | 0 | 0 | ... Encoded Packet Data ... | 0
|
||||
@@ -58,7 +59,7 @@ pub fn encode_packet_with_cobs(
|
||||
pub fn parse_buffer_for_cobs_encoded_packets<SendError>(
|
||||
buf: &mut [u8],
|
||||
sender_id: ComponentId,
|
||||
packet_sender: &(impl PacketSenderRaw<Error = SendError> + ?Sized),
|
||||
packet_sender: &(impl PacketHandler<Error = SendError> + ?Sized),
|
||||
next_write_idx: &mut usize,
|
||||
) -> Result<u32, SendError> {
|
||||
let mut start_index_packet = 0;
|
||||
@@ -79,7 +80,7 @@ pub fn parse_buffer_for_cobs_encoded_packets<SendError>(
|
||||
let decode_result = decode_in_place(&mut buf[start_index_packet..i]);
|
||||
if let Ok(packet_len) = decode_result {
|
||||
packets_found += 1;
|
||||
packet_sender.send_packet(
|
||||
packet_sender.handle_packet(
|
||||
sender_id,
|
||||
&buf[start_index_packet..start_index_packet + packet_len],
|
||||
)?;
|
||||
|
||||
@@ -12,7 +12,7 @@ pub(crate) mod tests {
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
tmtc::{PacketAsVec, PacketSenderRaw},
|
||||
tmtc::{PacketAsVec, PacketHandler},
|
||||
};
|
||||
|
||||
use super::cobs::encode_packet_with_cobs;
|
||||
@@ -25,10 +25,10 @@ pub(crate) mod tests {
|
||||
pub(crate) tc_queue: RefCell<VecDeque<PacketAsVec>>,
|
||||
}
|
||||
|
||||
impl PacketSenderRaw for TcCacher {
|
||||
impl PacketHandler for TcCacher {
|
||||
type Error = ();
|
||||
|
||||
fn send_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> {
|
||||
fn handle_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> {
|
||||
let mut mut_queue = self.tc_queue.borrow_mut();
|
||||
mut_queue.push_back(PacketAsVec::new(sender_id, tc_raw.to_vec()));
|
||||
Ok(())
|
||||
|
||||
@@ -386,7 +386,7 @@ impl UnsignedEnum for EventU32 {
|
||||
self.base.write_to_bytes(self.raw(), buf, self.size())
|
||||
}
|
||||
|
||||
fn value(&self) -> u64 {
|
||||
fn value_raw(&self) -> u64 {
|
||||
self.raw().into()
|
||||
}
|
||||
}
|
||||
@@ -445,7 +445,7 @@ impl<SEVERITY: HasSeverity> UnsignedEnum for EventU32TypedSev<SEVERITY> {
|
||||
delegate!(to self.event {
|
||||
fn size(&self) -> usize;
|
||||
fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError>;
|
||||
fn value(&self) -> u64;
|
||||
fn value_raw(&self) -> u64;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -558,7 +558,7 @@ impl UnsignedEnum for EventU16 {
|
||||
self.base.write_to_bytes(self.raw(), buf, self.size())
|
||||
}
|
||||
|
||||
fn value(&self) -> u64 {
|
||||
fn value_raw(&self) -> u64 {
|
||||
self.raw().into()
|
||||
}
|
||||
}
|
||||
@@ -611,7 +611,7 @@ impl<SEVERITY: HasSeverity> UnsignedEnum for EventU16TypedSev<SEVERITY> {
|
||||
delegate!(to self.event {
|
||||
fn size(&self) -> usize;
|
||||
fn write_to_be_bytes(&self, buf: &mut [u8]) -> Result<usize, ByteConversionError>;
|
||||
fn value(&self) -> u64;
|
||||
fn value_raw(&self) -> u64;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
pub mod tcp_server;
|
||||
pub mod udp_server;
|
||||
|
||||
mod tcp_cobs_server;
|
||||
mod tcp_spacepackets_server;
|
||||
pub mod tcp_cobs_server;
|
||||
pub mod tcp_spacepackets_server;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec;
|
||||
use cobs::CobsDecoderOwned;
|
||||
use cobs::DecodeError;
|
||||
use cobs::encode;
|
||||
use core::sync::atomic::AtomicBool;
|
||||
use core::time::Duration;
|
||||
@@ -9,40 +11,58 @@ use std::io::Write;
|
||||
use std::net::SocketAddr;
|
||||
use std::vec::Vec;
|
||||
|
||||
use crate::encoding::parse_buffer_for_cobs_encoded_packets;
|
||||
use crate::tmtc::PacketSenderRaw;
|
||||
use crate::queue::GenericSendError;
|
||||
use crate::tmtc::PacketHandler;
|
||||
use crate::tmtc::PacketSource;
|
||||
|
||||
use crate::ComponentId;
|
||||
use crate::hal::std::tcp_server::{
|
||||
ConnectionResult, ServerConfig, TcpTcParser, TcpTmSender, TcpTmtcError, TcpTmtcGenericServer,
|
||||
ConnectionResult, ServerConfig, TcpTcParser, TcpTmSender, TcpTmtcGenericServer,
|
||||
};
|
||||
|
||||
use super::tcp_server::HandledConnectionHandler;
|
||||
use super::tcp_server::HandledConnectionInfo;
|
||||
|
||||
/// Concrete [TcpTcParser] implementation for the [TcpTmtcInCobsServer].
|
||||
#[derive(Default)]
|
||||
pub struct CobsTcParser {}
|
||||
pub struct CobsTcParser<PacketHandlerInstance: PacketHandler> {
|
||||
sender_id: ComponentId,
|
||||
owned_decoder: CobsDecoderOwned,
|
||||
packet_handler: PacketHandlerInstance,
|
||||
last_decode_error: Option<DecodeError>,
|
||||
}
|
||||
|
||||
impl<TmError, TcError: 'static> TcpTcParser<TmError, TcError> for CobsTcParser {
|
||||
fn handle_tc_parsing(
|
||||
&mut self,
|
||||
tc_buffer: &mut [u8],
|
||||
impl<PacketHandlerInstance: PacketHandler> CobsTcParser<PacketHandlerInstance> {
|
||||
pub fn new(
|
||||
sender_id: ComponentId,
|
||||
tc_sender: &(impl PacketSenderRaw<Error = TcError> + ?Sized),
|
||||
conn_result: &mut HandledConnectionInfo,
|
||||
current_write_idx: usize,
|
||||
next_write_idx: &mut usize,
|
||||
) -> Result<(), TcpTmtcError<TmError, TcError>> {
|
||||
conn_result.num_received_tcs += parse_buffer_for_cobs_encoded_packets(
|
||||
&mut tc_buffer[..current_write_idx],
|
||||
decoder_buf_size: usize,
|
||||
packet_handler: PacketHandlerInstance,
|
||||
) -> Self {
|
||||
Self {
|
||||
sender_id,
|
||||
tc_sender,
|
||||
next_write_idx,
|
||||
)
|
||||
.map_err(|e| TcpTmtcError::TcError(e))?;
|
||||
Ok(())
|
||||
owned_decoder: CobsDecoderOwned::new(decoder_buf_size),
|
||||
packet_handler,
|
||||
last_decode_error: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<PacketHandlerInstance: PacketHandler> TcpTcParser for CobsTcParser<PacketHandlerInstance> {
|
||||
fn reset(&mut self) {
|
||||
self.owned_decoder.reset();
|
||||
}
|
||||
|
||||
fn push(&mut self, data: &[u8], conn_result: &mut HandledConnectionInfo) {
|
||||
for byte in data {
|
||||
match self.owned_decoder.feed(*byte) {
|
||||
Ok(Some(packet_len)) => {
|
||||
self.packet_handler
|
||||
.handle_packet(self.sender_id, &self.owned_decoder.dest()[..packet_len])
|
||||
.ok();
|
||||
conn_result.num_received_tcs += 1;
|
||||
}
|
||||
Ok(None) => (),
|
||||
Err(e) => self.last_decode_error = Some(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,22 +81,18 @@ impl CobsTmSender {
|
||||
}
|
||||
}
|
||||
|
||||
impl<TmError, TcError> TcpTmSender<TmError, TcError> for CobsTmSender {
|
||||
impl TcpTmSender for CobsTmSender {
|
||||
fn handle_tm_sending(
|
||||
&mut self,
|
||||
tm_buffer: &mut [u8],
|
||||
tm_source: &mut (impl PacketSource<Error = TmError> + ?Sized),
|
||||
tm_source: &mut (impl PacketSource<Error = ()> + ?Sized),
|
||||
conn_result: &mut HandledConnectionInfo,
|
||||
stream: &mut TcpStream,
|
||||
) -> Result<bool, TcpTmtcError<TmError, TcError>> {
|
||||
) -> Result<bool, std::io::Error> {
|
||||
let mut tm_was_sent = false;
|
||||
loop {
|
||||
// Write TM until TM source is exhausted. For now, there is no limit for the amount
|
||||
// of TM written this way.
|
||||
let read_tm_len = tm_source
|
||||
.retrieve_packet(tm_buffer)
|
||||
.map_err(|e| TcpTmtcError::TmError(e))?;
|
||||
|
||||
// Write TM until TM source is exhausted or there is an unexpected error. For now, there
|
||||
// is no limit for the amount of TM written this way.
|
||||
while let Ok(read_tm_len) = tm_source.retrieve_packet(tm_buffer) {
|
||||
if read_tm_len == 0 {
|
||||
return Ok(tm_was_sent);
|
||||
}
|
||||
@@ -95,6 +111,7 @@ impl<TmError, TcError> TcpTmSender<TmError, TcError> for CobsTmSender {
|
||||
current_idx += 1;
|
||||
stream.write_all(&self.tm_encoding_buffer[..current_idx])?;
|
||||
}
|
||||
Ok(tm_was_sent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,8 +125,8 @@ impl<TmError, TcError> TcpTmSender<TmError, TcError> for CobsTmSender {
|
||||
///
|
||||
/// Using a framing protocol like COBS imposes minimal restrictions on the type of TMTC data
|
||||
/// exchanged while also allowing packets with flexible size and a reliable way to reconstruct full
|
||||
/// packets even from a data stream which is split up. The server wil use the
|
||||
/// [parse_buffer_for_cobs_encoded_packets] function to parse for packets and pass them to a
|
||||
/// packets even from a data stream which is split up. The server wil use the streaming
|
||||
/// [CobsDecoderOwned] decoder to parse for packets and pass them to a
|
||||
/// generic TC receiver. The user can use [crate::encoding::encode_packet_with_cobs] to encode
|
||||
/// telecommands sent to the server.
|
||||
///
|
||||
@@ -118,30 +135,19 @@ impl<TmError, TcError> TcpTmSender<TmError, TcError> for CobsTmSender {
|
||||
/// The [TCP integration tests](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs/tests/tcp_servers.rs)
|
||||
/// test also serves as the example application for this module.
|
||||
pub struct TcpTmtcInCobsServer<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = SendError>,
|
||||
TmSource: PacketSource<Error = ()>,
|
||||
TcHandler: PacketHandler<Error = GenericSendError>,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError,
|
||||
SendError: 'static,
|
||||
> {
|
||||
pub generic_server: TcpTmtcGenericServer<
|
||||
TmSource,
|
||||
TcSender,
|
||||
CobsTmSender,
|
||||
CobsTcParser,
|
||||
HandledConnection,
|
||||
TmError,
|
||||
SendError,
|
||||
>,
|
||||
pub generic_server:
|
||||
TcpTmtcGenericServer<TmSource, CobsTmSender, CobsTcParser<TcHandler>, HandledConnection>,
|
||||
}
|
||||
|
||||
impl<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcReceiver: PacketSenderRaw<Error = TcError>,
|
||||
TmSource: PacketSource<Error = ()>,
|
||||
TcHandler: PacketHandler<Error = GenericSendError>,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcError: 'static,
|
||||
> TcpTmtcInCobsServer<TmSource, TcReceiver, HandledConnection, TmError, TcError>
|
||||
> TcpTmtcInCobsServer<TmSource, TcHandler, HandledConnection>
|
||||
{
|
||||
/// Create a new TCP TMTC server which exchanges TMTC packets encoded with
|
||||
/// [COBS protocol](https://en.wikipedia.org/wiki/Consistent_Overhead_Byte_Stuffing).
|
||||
@@ -156,17 +162,16 @@ impl<
|
||||
pub fn new(
|
||||
cfg: ServerConfig,
|
||||
tm_source: TmSource,
|
||||
tc_receiver: TcReceiver,
|
||||
cobs_tc_parser: CobsTcParser<TcHandler>,
|
||||
handled_connection: HandledConnection,
|
||||
stop_signal: Option<Arc<AtomicBool>>,
|
||||
) -> Result<Self, std::io::Error> {
|
||||
Ok(Self {
|
||||
generic_server: TcpTmtcGenericServer::new(
|
||||
cfg,
|
||||
CobsTcParser::default(),
|
||||
cobs_tc_parser,
|
||||
CobsTmSender::new(cfg.tm_buffer_size),
|
||||
tm_source,
|
||||
tc_receiver,
|
||||
handled_connection,
|
||||
stop_signal,
|
||||
)?,
|
||||
@@ -185,7 +190,7 @@ impl<
|
||||
pub fn handle_all_connections(
|
||||
&mut self,
|
||||
poll_duration: Option<Duration>,
|
||||
) -> Result<ConnectionResult, TcpTmtcError<TmError, TcError>>;
|
||||
) -> Result<ConnectionResult, std::io::Error>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,7 +217,6 @@ mod tests {
|
||||
ConnectionResult, ServerConfig,
|
||||
tests::{ConnectionFinishedHandler, SyncTmSource},
|
||||
},
|
||||
queue::GenericSendError,
|
||||
tmtc::PacketAsVec,
|
||||
};
|
||||
use alloc::sync::Arc;
|
||||
@@ -243,17 +247,12 @@ mod tests {
|
||||
tc_sender: mpsc::Sender<PacketAsVec>,
|
||||
tm_source: SyncTmSource,
|
||||
stop_signal: Option<Arc<AtomicBool>>,
|
||||
) -> TcpTmtcInCobsServer<
|
||||
SyncTmSource,
|
||||
mpsc::Sender<PacketAsVec>,
|
||||
ConnectionFinishedHandler,
|
||||
(),
|
||||
GenericSendError,
|
||||
> {
|
||||
) -> TcpTmtcInCobsServer<SyncTmSource, mpsc::Sender<PacketAsVec>, ConnectionFinishedHandler>
|
||||
{
|
||||
TcpTmtcInCobsServer::new(
|
||||
ServerConfig::new(TCP_SERVER_ID, *addr, Duration::from_millis(2), 1024, 1024),
|
||||
tm_source,
|
||||
tc_sender,
|
||||
super::CobsTcParser::new(TCP_SERVER_ID, 1024, tc_sender),
|
||||
ConnectionFinishedHandler::default(),
|
||||
stop_signal,
|
||||
)
|
||||
|
||||
@@ -12,7 +12,7 @@ use std::net::SocketAddr;
|
||||
use std::thread;
|
||||
|
||||
use crate::ComponentId;
|
||||
use crate::tmtc::{PacketSenderRaw, PacketSource};
|
||||
use crate::tmtc::PacketSource;
|
||||
use thiserror::Error;
|
||||
|
||||
// Re-export the TMTC in COBS server.
|
||||
@@ -73,11 +73,9 @@ impl ServerConfig {
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum TcpTmtcError<TmError, TcError> {
|
||||
pub enum TcpTmError<TmError> {
|
||||
#[error("TM retrieval error: {0}")]
|
||||
TmError(TmError),
|
||||
#[error("TC retrieval error: {0}")]
|
||||
TcError(TcError),
|
||||
#[error("io error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
@@ -116,32 +114,29 @@ pub trait HandledConnectionHandler {
|
||||
}
|
||||
|
||||
/// Generic parser abstraction for an object which can parse for telecommands given a raw
|
||||
/// bytestream received from a TCP socket and send them using a generic [PacketSenderRaw]
|
||||
/// implementation. This allows different encoding schemes for telecommands.
|
||||
pub trait TcpTcParser<TmError, SendError> {
|
||||
fn handle_tc_parsing(
|
||||
&mut self,
|
||||
tc_buffer: &mut [u8],
|
||||
sender_id: ComponentId,
|
||||
tc_sender: &(impl PacketSenderRaw<Error = SendError> + ?Sized),
|
||||
conn_result: &mut HandledConnectionInfo,
|
||||
current_write_idx: usize,
|
||||
next_write_idx: &mut usize,
|
||||
) -> Result<(), TcpTmtcError<TmError, SendError>>;
|
||||
/// bytestream received from a TCP socket and extract packets from them. This allows different
|
||||
/// encoding schemes for telecommands.
|
||||
pub trait TcpTcParser {
|
||||
/// Reset the state of the parser.
|
||||
fn reset(&mut self);
|
||||
|
||||
/// Pushes received data into the parser.
|
||||
fn push(&mut self, tc_data: &[u8], conn_result: &mut HandledConnectionInfo);
|
||||
}
|
||||
|
||||
/// Generic sender abstraction for an object which can pull telemetry from a given TM source
|
||||
/// using a [PacketSource] and then send them back to a client using a given [TcpStream].
|
||||
/// The concrete implementation can also perform any encoding steps which are necessary before
|
||||
/// sending back the data to a client.
|
||||
pub trait TcpTmSender<TmError, TcError> {
|
||||
pub trait TcpTmSender {
|
||||
/// Returns whether any packets were sent back to the client.
|
||||
fn handle_tm_sending(
|
||||
&mut self,
|
||||
tm_buffer: &mut [u8],
|
||||
tm_source: &mut (impl PacketSource<Error = TmError> + ?Sized),
|
||||
tm_source: &mut (impl PacketSource<Error = ()> + ?Sized),
|
||||
conn_result: &mut HandledConnectionInfo,
|
||||
stream: &mut TcpStream,
|
||||
) -> Result<bool, TcpTmtcError<TmError, TcError>>;
|
||||
) -> Result<bool, std::io::Error>;
|
||||
}
|
||||
|
||||
/// TCP TMTC server implementation for exchange of generic TMTC packets in a generic way which
|
||||
@@ -151,7 +146,8 @@ pub trait TcpTmSender<TmError, TcError> {
|
||||
/// through the following 4 core abstractions:
|
||||
///
|
||||
/// 1. [TcpTcParser] to parse for telecommands from the raw bytestream received from a client.
|
||||
/// 2. Parsed telecommands will be sent using the [PacketSenderRaw] object.
|
||||
/// 2. Parsed telecommands will be handled by the [TcpTcParser] object as well. For example, this
|
||||
/// parser can contain a message queue handle to send the packets somewhere.
|
||||
/// 3. [TcpTmSender] to send telemetry pulled from a TM source back to the client.
|
||||
/// 4. [PacketSource] as a generic TM source used by the [TcpTmSender].
|
||||
///
|
||||
@@ -163,13 +159,10 @@ pub trait TcpTmSender<TmError, TcError> {
|
||||
/// 1. [TcpTmtcInCobsServer] to exchange TMTC wrapped inside the COBS framing protocol.
|
||||
/// 2. [TcpSpacepacketsServer] to exchange space packets via TCP.
|
||||
pub struct TcpTmtcGenericServer<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = TcSendError>,
|
||||
TmSender: TcpTmSender<TmError, TcSendError>,
|
||||
TcParser: TcpTcParser<TmError, TcSendError>,
|
||||
TmSource: PacketSource<Error = ()>,
|
||||
TmSender: TcpTmSender,
|
||||
TcParser: TcpTcParser,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError,
|
||||
TcSendError,
|
||||
> {
|
||||
pub id: ComponentId,
|
||||
pub finished_handler: HandledConnection,
|
||||
@@ -177,7 +170,6 @@ pub struct TcpTmtcGenericServer<
|
||||
pub(crate) inner_loop_delay: Duration,
|
||||
pub(crate) tm_source: TmSource,
|
||||
pub(crate) tm_buffer: Vec<u8>,
|
||||
pub(crate) tc_sender: TcSender,
|
||||
pub(crate) tc_buffer: Vec<u8>,
|
||||
poll: Poll,
|
||||
events: Events,
|
||||
@@ -187,23 +179,11 @@ pub struct TcpTmtcGenericServer<
|
||||
}
|
||||
|
||||
impl<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = TcSendError>,
|
||||
TmSender: TcpTmSender<TmError, TcSendError>,
|
||||
TcParser: TcpTcParser<TmError, TcSendError>,
|
||||
TmSource: PacketSource<Error = ()>,
|
||||
TmSender: TcpTmSender,
|
||||
TcParser: TcpTcParser,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcSendError: 'static,
|
||||
>
|
||||
TcpTmtcGenericServer<
|
||||
TmSource,
|
||||
TcSender,
|
||||
TmSender,
|
||||
TcParser,
|
||||
HandledConnection,
|
||||
TmError,
|
||||
TcSendError,
|
||||
>
|
||||
> TcpTmtcGenericServer<TmSource, TmSender, TcParser, HandledConnection>
|
||||
{
|
||||
/// Create a new generic TMTC server instance.
|
||||
///
|
||||
@@ -223,7 +203,6 @@ impl<
|
||||
tc_parser: TcParser,
|
||||
tm_sender: TmSender,
|
||||
tm_source: TmSource,
|
||||
tc_receiver: TcSender,
|
||||
finished_handler: HandledConnection,
|
||||
stop_signal: Option<Arc<AtomicBool>>,
|
||||
) -> Result<Self, std::io::Error> {
|
||||
@@ -263,7 +242,6 @@ impl<
|
||||
inner_loop_delay: cfg.inner_loop_delay,
|
||||
tm_source,
|
||||
tm_buffer: vec![0; cfg.tm_buffer_size],
|
||||
tc_sender: tc_receiver,
|
||||
tc_buffer: vec![0; cfg.tc_buffer_size],
|
||||
stop_signal,
|
||||
finished_handler,
|
||||
@@ -297,7 +275,7 @@ impl<
|
||||
pub fn handle_all_connections(
|
||||
&mut self,
|
||||
poll_timeout: Option<Duration>,
|
||||
) -> Result<ConnectionResult, TcpTmtcError<TmError, TcSendError>> {
|
||||
) -> Result<ConnectionResult, std::io::Error> {
|
||||
let mut handled_connections = 0;
|
||||
// Poll Mio for events.
|
||||
self.poll.poll(&mut self.events, poll_timeout)?;
|
||||
@@ -327,7 +305,7 @@ impl<
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => break,
|
||||
Err(err) => {
|
||||
self.reregister_poll_interest()?;
|
||||
return Err(TcpTmtcError::Io(err));
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,58 +328,24 @@ impl<
|
||||
&mut self,
|
||||
mut stream: TcpStream,
|
||||
addr: SocketAddr,
|
||||
) -> Result<(), TcpTmtcError<TmError, TcSendError>> {
|
||||
let mut current_write_idx;
|
||||
let mut next_write_idx = 0;
|
||||
) -> Result<(), std::io::Error> {
|
||||
self.tc_handler.reset();
|
||||
let mut connection_result = HandledConnectionInfo::new(addr);
|
||||
current_write_idx = next_write_idx;
|
||||
loop {
|
||||
let read_result = stream.read(&mut self.tc_buffer[current_write_idx..]);
|
||||
let read_result = stream.read(&mut self.tc_buffer);
|
||||
match read_result {
|
||||
Ok(0) => {
|
||||
// Connection closed by client. If any TC was read, parse for complete packets.
|
||||
// After that, break the outer loop.
|
||||
if current_write_idx > 0 {
|
||||
self.tc_handler.handle_tc_parsing(
|
||||
&mut self.tc_buffer,
|
||||
self.id,
|
||||
&self.tc_sender,
|
||||
&mut connection_result,
|
||||
current_write_idx,
|
||||
&mut next_write_idx,
|
||||
)?;
|
||||
}
|
||||
// Connection closed by client.
|
||||
break;
|
||||
}
|
||||
Ok(read_len) => {
|
||||
current_write_idx += read_len;
|
||||
// TC buffer is full, we must parse for complete packets now.
|
||||
if current_write_idx == self.tc_buffer.capacity() {
|
||||
self.tc_handler.handle_tc_parsing(
|
||||
&mut self.tc_buffer,
|
||||
self.id,
|
||||
&self.tc_sender,
|
||||
&mut connection_result,
|
||||
current_write_idx,
|
||||
&mut next_write_idx,
|
||||
)?;
|
||||
current_write_idx = next_write_idx;
|
||||
}
|
||||
self.tc_handler
|
||||
.push(&self.tc_buffer[0..read_len], &mut connection_result);
|
||||
}
|
||||
Err(e) => match e.kind() {
|
||||
// As per [TcpStream::set_read_timeout] documentation, this should work for
|
||||
// both UNIX and Windows.
|
||||
std::io::ErrorKind::WouldBlock | std::io::ErrorKind::TimedOut => {
|
||||
self.tc_handler.handle_tc_parsing(
|
||||
&mut self.tc_buffer,
|
||||
self.id,
|
||||
&self.tc_sender,
|
||||
&mut connection_result,
|
||||
current_write_idx,
|
||||
&mut next_write_idx,
|
||||
)?;
|
||||
current_write_idx = next_write_idx;
|
||||
|
||||
if !self.tm_handler.handle_tm_sending(
|
||||
&mut self.tm_buffer,
|
||||
&mut self.tm_source,
|
||||
@@ -426,7 +370,7 @@ impl<
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(TcpTmtcError::Io(e));
|
||||
return Err(e);
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -502,8 +446,11 @@ pub(crate) mod tests {
|
||||
.connection_info
|
||||
.pop_back()
|
||||
.expect("no connection info available");
|
||||
assert_eq!(last_conn_result.num_received_tcs, num_tcs);
|
||||
assert_eq!(last_conn_result.num_sent_tms, num_tms);
|
||||
assert_eq!(
|
||||
last_conn_result.num_received_tcs, num_tcs,
|
||||
"received tcs mismatch"
|
||||
);
|
||||
assert_eq!(last_conn_result.num_sent_tms, num_tms, "sent tms missmatch");
|
||||
}
|
||||
|
||||
pub fn check_no_connections_left(&self) {
|
||||
|
||||
@@ -7,39 +7,104 @@ use std::{io::Write, net::SocketAddr};
|
||||
use crate::{
|
||||
ComponentId,
|
||||
encoding::{ccsds::SpacePacketValidator, parse_buffer_for_ccsds_space_packets},
|
||||
tmtc::{PacketSenderRaw, PacketSource},
|
||||
queue::GenericSendError,
|
||||
tmtc::{PacketHandler, PacketSource},
|
||||
};
|
||||
|
||||
use super::tcp_server::{
|
||||
ConnectionResult, HandledConnectionHandler, HandledConnectionInfo, ServerConfig, TcpTcParser,
|
||||
TcpTmSender, TcpTmtcError, TcpTmtcGenericServer,
|
||||
TcpTmSender, TcpTmtcGenericServer,
|
||||
};
|
||||
|
||||
impl<T: SpacePacketValidator, TmError, TcError: 'static> TcpTcParser<TmError, TcError> for T {
|
||||
fn handle_tc_parsing(
|
||||
&mut self,
|
||||
tc_buffer: &mut [u8],
|
||||
pub struct CcsdsPacketParser<
|
||||
PacketValidator: SpacePacketValidator,
|
||||
PacketHandlerInstance: PacketHandler,
|
||||
> {
|
||||
sender_id: ComponentId,
|
||||
parsing_buffer: alloc::vec::Vec<u8>,
|
||||
validator: PacketValidator,
|
||||
packet_handler: PacketHandlerInstance,
|
||||
current_write_index: usize,
|
||||
}
|
||||
|
||||
impl<PacketValidator: SpacePacketValidator, PacketHandlerInstance: PacketHandler>
|
||||
CcsdsPacketParser<PacketValidator, PacketHandlerInstance>
|
||||
{
|
||||
pub fn new(
|
||||
sender_id: ComponentId,
|
||||
tc_sender: &(impl PacketSenderRaw<Error = TcError> + ?Sized),
|
||||
conn_result: &mut HandledConnectionInfo,
|
||||
current_write_idx: usize,
|
||||
next_write_idx: &mut usize,
|
||||
) -> Result<(), TcpTmtcError<TmError, TcError>> {
|
||||
// Reader vec full, need to parse for packets.
|
||||
let parse_result = parse_buffer_for_ccsds_space_packets(
|
||||
&tc_buffer[..current_write_idx],
|
||||
self,
|
||||
parsing_buf_size: usize,
|
||||
packet_handler: PacketHandlerInstance,
|
||||
validator: PacketValidator,
|
||||
) -> Self {
|
||||
Self {
|
||||
sender_id,
|
||||
tc_sender,
|
||||
)
|
||||
.map_err(|e| TcpTmtcError::TcError(e))?;
|
||||
if let Some(broken_tail_start) = parse_result.incomplete_tail_start {
|
||||
// Copy broken tail to front of buffer.
|
||||
tc_buffer.copy_within(broken_tail_start..current_write_idx, 0);
|
||||
*next_write_idx = current_write_idx - broken_tail_start;
|
||||
parsing_buffer: alloc::vec![0; parsing_buf_size],
|
||||
validator,
|
||||
packet_handler,
|
||||
current_write_index: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn write_to_buffer(&mut self, data: &[u8]) -> usize {
|
||||
let available = self.parsing_buffer.len() - self.current_write_index;
|
||||
let to_write = core::cmp::min(data.len(), available);
|
||||
|
||||
self.parsing_buffer[self.current_write_index..self.current_write_index + to_write]
|
||||
.copy_from_slice(&data[..to_write]);
|
||||
self.current_write_index += to_write;
|
||||
|
||||
to_write
|
||||
}
|
||||
|
||||
fn parse_and_handle_packets(&mut self) -> u32 {
|
||||
match parse_buffer_for_ccsds_space_packets(
|
||||
&self.parsing_buffer[..self.current_write_index],
|
||||
&self.validator,
|
||||
self.sender_id,
|
||||
&self.packet_handler,
|
||||
) {
|
||||
Ok(parse_result) => {
|
||||
self.parsing_buffer
|
||||
.copy_within(parse_result.parsed_bytes..self.current_write_index, 0);
|
||||
self.current_write_index -= parse_result.parsed_bytes;
|
||||
parse_result.packets_found
|
||||
}
|
||||
Err(_) => 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn drop_first_half_of_buffer(&mut self) {
|
||||
let mid = self.parsing_buffer.len() / 2;
|
||||
self.parsing_buffer.copy_within(mid.., 0);
|
||||
self.current_write_index -= mid;
|
||||
}
|
||||
}
|
||||
impl<PacketValidator: SpacePacketValidator, PacketHandlerInstance: PacketHandler> TcpTcParser
|
||||
for CcsdsPacketParser<PacketValidator, PacketHandlerInstance>
|
||||
{
|
||||
fn reset(&mut self) {
|
||||
self.current_write_index = 0;
|
||||
}
|
||||
|
||||
fn push(&mut self, mut tc_buffer: &[u8], conn_result: &mut HandledConnectionInfo) {
|
||||
while !tc_buffer.is_empty() {
|
||||
// Write as much as possible to buffer
|
||||
let written = self.write_to_buffer(tc_buffer);
|
||||
tc_buffer = &tc_buffer[written..];
|
||||
|
||||
// Parse for complete packets
|
||||
let packets_found = self.parse_and_handle_packets();
|
||||
conn_result.num_received_tcs += packets_found;
|
||||
|
||||
if tc_buffer.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle buffer overflow
|
||||
if self.current_write_index == self.parsing_buffer.len() {
|
||||
self.drop_first_half_of_buffer();
|
||||
}
|
||||
}
|
||||
conn_result.num_received_tcs += parse_result.packets_found;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,21 +112,18 @@ impl<T: SpacePacketValidator, TmError, TcError: 'static> TcpTcParser<TmError, Tc
|
||||
#[derive(Default)]
|
||||
pub struct SpacepacketsTmSender {}
|
||||
|
||||
impl<TmError, TcError> TcpTmSender<TmError, TcError> for SpacepacketsTmSender {
|
||||
impl TcpTmSender for SpacepacketsTmSender {
|
||||
fn handle_tm_sending(
|
||||
&mut self,
|
||||
tm_buffer: &mut [u8],
|
||||
tm_source: &mut (impl PacketSource<Error = TmError> + ?Sized),
|
||||
tm_source: &mut (impl PacketSource<Error = ()> + ?Sized),
|
||||
conn_result: &mut HandledConnectionInfo,
|
||||
stream: &mut TcpStream,
|
||||
) -> Result<bool, TcpTmtcError<TmError, TcError>> {
|
||||
) -> Result<bool, std::io::Error> {
|
||||
let mut tm_was_sent = false;
|
||||
loop {
|
||||
while let Ok(read_tm_len) = tm_source.retrieve_packet(tm_buffer) {
|
||||
// Write TM until TM source is exhausted. For now, there is no limit for the amount
|
||||
// of TM written this way.
|
||||
let read_tm_len = tm_source
|
||||
.retrieve_packet(tm_buffer)
|
||||
.map_err(|e| TcpTmtcError::TmError(e))?;
|
||||
|
||||
if read_tm_len == 0 {
|
||||
return Ok(tm_was_sent);
|
||||
@@ -71,6 +133,7 @@ impl<TmError, TcError> TcpTmSender<TmError, TcError> for SpacepacketsTmSender {
|
||||
|
||||
stream.write_all(&tm_buffer[..read_tm_len])?;
|
||||
}
|
||||
Ok(tm_was_sent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,32 +151,25 @@ impl<TmError, TcError> TcpTmSender<TmError, TcError> for SpacepacketsTmSender {
|
||||
/// The [TCP server integration tests](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs/tests/tcp_servers.rs)
|
||||
/// also serves as the example application for this module.
|
||||
pub struct TcpSpacepacketsServer<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = SendError>,
|
||||
TmSource: PacketSource<Error = ()>,
|
||||
TcSender: PacketHandler<Error = GenericSendError>,
|
||||
Validator: SpacePacketValidator,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError,
|
||||
SendError: 'static,
|
||||
> {
|
||||
pub generic_server: TcpTmtcGenericServer<
|
||||
TmSource,
|
||||
TcSender,
|
||||
SpacepacketsTmSender,
|
||||
Validator,
|
||||
CcsdsPacketParser<Validator, TcSender>,
|
||||
HandledConnection,
|
||||
TmError,
|
||||
SendError,
|
||||
>,
|
||||
}
|
||||
|
||||
impl<
|
||||
TmSource: PacketSource<Error = TmError>,
|
||||
TcSender: PacketSenderRaw<Error = TcError>,
|
||||
TmSource: PacketSource<Error = ()>,
|
||||
TcSender: PacketHandler<Error = GenericSendError>,
|
||||
Validator: SpacePacketValidator,
|
||||
HandledConnection: HandledConnectionHandler,
|
||||
TmError: 'static,
|
||||
TcError: 'static,
|
||||
> TcpSpacepacketsServer<TmSource, TcSender, Validator, HandledConnection, TmError, TcError>
|
||||
> TcpSpacepacketsServer<TmSource, TcSender, Validator, HandledConnection>
|
||||
{
|
||||
///
|
||||
/// ## Parameter
|
||||
@@ -122,7 +178,7 @@ impl<
|
||||
/// * `tm_source` - Generic TM source used by the server to pull telemetry packets which are
|
||||
/// then sent back to the client.
|
||||
/// * `tc_sender` - Any received telecommands which were decoded successfully will be
|
||||
/// forwarded using this [PacketSenderRaw].
|
||||
/// forwarded using this [PacketHandler].
|
||||
/// * `validator` - Used to determine the space packets relevant for further processing and
|
||||
/// to detect broken space packets.
|
||||
/// * `handled_connection_hook` - Called to notify the user about a succesfully handled
|
||||
@@ -132,18 +188,16 @@ impl<
|
||||
pub fn new(
|
||||
cfg: ServerConfig,
|
||||
tm_source: TmSource,
|
||||
tc_sender: TcSender,
|
||||
validator: Validator,
|
||||
tc_parser: CcsdsPacketParser<Validator, TcSender>,
|
||||
handled_connection_hook: HandledConnection,
|
||||
stop_signal: Option<Arc<AtomicBool>>,
|
||||
) -> Result<Self, std::io::Error> {
|
||||
Ok(Self {
|
||||
generic_server: TcpTmtcGenericServer::new(
|
||||
cfg,
|
||||
validator,
|
||||
tc_parser,
|
||||
SpacepacketsTmSender::default(),
|
||||
tm_source,
|
||||
tc_sender,
|
||||
handled_connection_hook,
|
||||
stop_signal,
|
||||
)?,
|
||||
@@ -162,7 +216,7 @@ impl<
|
||||
pub fn handle_all_connections(
|
||||
&mut self,
|
||||
poll_timeout: Option<Duration>
|
||||
) -> Result<ConnectionResult, TcpTmtcError<TmError, TcError>>;
|
||||
) -> Result<ConnectionResult, std::io::Error>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -187,7 +241,7 @@ mod tests {
|
||||
use hashbrown::HashSet;
|
||||
use spacepackets::{
|
||||
CcsdsPacket, PacketId, SpHeader,
|
||||
ecss::{CreatorConfig, WritablePusPacket, tc::PusTcCreator},
|
||||
ecss::{CreatorConfig, MessageTypeId, WritablePusPacket, tc::PusTcCreator},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
@@ -197,7 +251,6 @@ mod tests {
|
||||
ConnectionResult, ServerConfig,
|
||||
tests::{ConnectionFinishedHandler, SyncTmSource},
|
||||
},
|
||||
queue::GenericSendError,
|
||||
tmtc::PacketAsVec,
|
||||
};
|
||||
|
||||
@@ -224,23 +277,19 @@ mod tests {
|
||||
|
||||
fn generic_tmtc_server(
|
||||
addr: &SocketAddr,
|
||||
tc_sender: mpsc::Sender<PacketAsVec>,
|
||||
tc_parser: super::CcsdsPacketParser<SimpleValidator, mpsc::Sender<PacketAsVec>>,
|
||||
tm_source: SyncTmSource,
|
||||
validator: SimpleValidator,
|
||||
stop_signal: Option<Arc<AtomicBool>>,
|
||||
) -> TcpSpacepacketsServer<
|
||||
SyncTmSource,
|
||||
mpsc::Sender<PacketAsVec>,
|
||||
SimpleValidator,
|
||||
ConnectionFinishedHandler,
|
||||
(),
|
||||
GenericSendError,
|
||||
> {
|
||||
TcpSpacepacketsServer::new(
|
||||
ServerConfig::new(TCP_SERVER_ID, *addr, Duration::from_millis(2), 1024, 1024),
|
||||
tm_source,
|
||||
tc_sender,
|
||||
validator,
|
||||
tc_parser,
|
||||
ConnectionFinishedHandler::default(),
|
||||
stop_signal,
|
||||
)
|
||||
@@ -256,9 +305,8 @@ mod tests {
|
||||
validator.0.insert(TEST_PACKET_ID_0);
|
||||
let mut tcp_server = generic_tmtc_server(
|
||||
&auto_port_addr,
|
||||
tc_sender.clone(),
|
||||
super::CcsdsPacketParser::new(TCP_SERVER_ID, 1024, tc_sender.clone(), validator),
|
||||
tm_source,
|
||||
validator,
|
||||
None,
|
||||
);
|
||||
let dest_addr = tcp_server
|
||||
@@ -286,8 +334,7 @@ mod tests {
|
||||
});
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
17,
|
||||
1,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
@@ -322,8 +369,7 @@ mod tests {
|
||||
let mut total_tm_len = 0;
|
||||
let verif_tm = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
1,
|
||||
1,
|
||||
MessageTypeId::new(1, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
@@ -332,8 +378,7 @@ mod tests {
|
||||
tm_source.add_tm(&tm_0);
|
||||
let verif_tm = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_1),
|
||||
1,
|
||||
3,
|
||||
MessageTypeId::new(1, 3),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
@@ -347,9 +392,8 @@ mod tests {
|
||||
validator.0.insert(TEST_PACKET_ID_1);
|
||||
let mut tcp_server = generic_tmtc_server(
|
||||
&auto_port_addr,
|
||||
tc_sender.clone(),
|
||||
super::CcsdsPacketParser::new(TCP_SERVER_ID, 1024, tc_sender.clone(), validator),
|
||||
tm_source,
|
||||
validator,
|
||||
None,
|
||||
);
|
||||
let dest_addr = tcp_server
|
||||
@@ -384,8 +428,7 @@ mod tests {
|
||||
// Send telecommands
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_0),
|
||||
17,
|
||||
1,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
@@ -395,8 +438,7 @@ mod tests {
|
||||
.expect("writing to TCP server failed");
|
||||
let action_tc = PusTcCreator::new_simple(
|
||||
SpHeader::new_from_apid(TEST_APID_1),
|
||||
8,
|
||||
0,
|
||||
MessageTypeId::new(8, 0),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Generic UDP TC server.
|
||||
use crate::ComponentId;
|
||||
use crate::tmtc::PacketSenderRaw;
|
||||
use crate::tmtc::PacketHandler;
|
||||
use core::fmt::Debug;
|
||||
use std::io::{self, ErrorKind};
|
||||
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
|
||||
@@ -12,7 +12,7 @@ use std::vec::Vec;
|
||||
///
|
||||
/// It caches all received telecomands into a vector. The maximum expected telecommand size should
|
||||
/// be declared upfront. This avoids dynamic allocation during run-time. The user can specify a TC
|
||||
/// sender in form of a special trait object which implements [PacketSenderRaw]. For example, this
|
||||
/// sender in form of a special trait object which implements [PacketHandler]. For example, this
|
||||
/// can be used to send the telecommands to a centralized TC source component for further
|
||||
/// processing and routing.
|
||||
///
|
||||
@@ -24,9 +24,9 @@ use std::vec::Vec;
|
||||
/// use spacepackets::ecss::WritablePusPacket;
|
||||
/// use satrs::hal::std::udp_server::UdpTcServer;
|
||||
/// use satrs::ComponentId;
|
||||
/// use satrs::tmtc::PacketSenderRaw;
|
||||
/// use satrs::tmtc::PacketHandler;
|
||||
/// use spacepackets::SpHeader;
|
||||
/// use spacepackets::ecss::tc::{PusTcCreator, CreatorConfig};
|
||||
/// use spacepackets::ecss::tc::{MessageTypeId, PusTcCreator, CreatorConfig};
|
||||
/// use arbitrary_int::u11;
|
||||
///
|
||||
/// const UDP_SERVER_ID: ComponentId = 0x05;
|
||||
@@ -36,7 +36,7 @@ use std::vec::Vec;
|
||||
/// let mut udp_tc_server = UdpTcServer::new(UDP_SERVER_ID, dest_addr, 2048, packet_sender)
|
||||
/// .expect("Creating UDP TMTC server failed");
|
||||
/// let sph = SpHeader::new_from_apid(u11::new(0x02));
|
||||
/// let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
/// let pus_tc = PusTcCreator::new_simple(sph, MessageTypeId::new(17, 1), &[], CreatorConfig::default());
|
||||
/// // Can not fail.
|
||||
/// let ping_tc_raw = pus_tc.to_vec().unwrap();
|
||||
///
|
||||
@@ -60,7 +60,7 @@ use std::vec::Vec;
|
||||
/// [example code](https://egit.irs.uni-stuttgart.de/rust/sat-rs/src/branch/main/satrs-example/src/tmtc.rs#L67)
|
||||
/// on how to use this TC server. It uses the server to receive PUS telecommands on a specific port
|
||||
/// and then forwards them to a generic CCSDS packet receiver.
|
||||
pub struct UdpTcServer<TcSender: PacketSenderRaw<Error = SendError>, SendError> {
|
||||
pub struct UdpTcServer<TcSender: PacketHandler<Error = SendError>, SendError> {
|
||||
pub id: ComponentId,
|
||||
pub socket: UdpSocket,
|
||||
recv_buf: Vec<u8>,
|
||||
@@ -78,7 +78,7 @@ pub enum ReceiveResult<SendError: Debug + 'static> {
|
||||
Send(SendError),
|
||||
}
|
||||
|
||||
impl<TcSender: PacketSenderRaw<Error = SendError>, SendError: Debug + 'static>
|
||||
impl<TcSender: PacketHandler<Error = SendError>, SendError: Debug + 'static>
|
||||
UdpTcServer<TcSender, SendError>
|
||||
{
|
||||
pub fn new<A: ToSocketAddrs>(
|
||||
@@ -112,7 +112,7 @@ impl<TcSender: PacketSenderRaw<Error = SendError>, SendError: Debug + 'static>
|
||||
let (num_bytes, from) = res;
|
||||
self.sender_addr = Some(from);
|
||||
self.tc_sender
|
||||
.send_packet(self.id, &self.recv_buf[0..num_bytes])
|
||||
.handle_packet(self.id, &self.recv_buf[0..num_bytes])
|
||||
.map_err(ReceiveResult::Send)?;
|
||||
Ok(res)
|
||||
}
|
||||
@@ -127,12 +127,12 @@ mod tests {
|
||||
use crate::ComponentId;
|
||||
use crate::hal::std::udp_server::{ReceiveResult, UdpTcServer};
|
||||
use crate::queue::GenericSendError;
|
||||
use crate::tmtc::PacketSenderRaw;
|
||||
use crate::tmtc::PacketHandler;
|
||||
use arbitrary_int::u11;
|
||||
use core::cell::RefCell;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::CreatorConfig;
|
||||
use spacepackets::ecss::tc::PusTcCreator;
|
||||
use spacepackets::ecss::{CreatorConfig, MessageTypeId};
|
||||
use std::collections::VecDeque;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
|
||||
use std::vec::Vec;
|
||||
@@ -146,10 +146,10 @@ mod tests {
|
||||
pub sent_cmds: RefCell<VecDeque<Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl PacketSenderRaw for PingReceiver {
|
||||
impl PacketHandler for PingReceiver {
|
||||
type Error = GenericSendError;
|
||||
|
||||
fn send_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> {
|
||||
fn handle_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> {
|
||||
assert_eq!(sender_id, UDP_SERVER_ID);
|
||||
let mut sent_data = Vec::new();
|
||||
sent_data.extend_from_slice(tc_raw);
|
||||
@@ -169,7 +169,12 @@ mod tests {
|
||||
.expect("Creating UDP TMTC server failed");
|
||||
is_send(&udp_tc_server);
|
||||
let sph = SpHeader::new_from_apid(u11::new(0x02));
|
||||
let pus_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let pus_tc = PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let len = pus_tc
|
||||
.write_to_bytes(&mut buf)
|
||||
.expect("Error writing PUS TC packet");
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
//! - The [pus] module which provides special support for projects using
|
||||
//! the [ECSS PUS C standard](https://ecss.nl/standard/ecss-e-st-70-41c-space-engineering-telemetry-and-telecommand-packet-utilization-15-april-2016/).
|
||||
#![no_std]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
#[cfg(any(feature = "alloc", test))]
|
||||
extern crate alloc;
|
||||
#[cfg(feature = "alloc")]
|
||||
@@ -58,7 +58,7 @@ pub use spacepackets;
|
||||
use spacepackets::PacketId;
|
||||
|
||||
/// Generic component ID type.
|
||||
pub type ComponentId = u64;
|
||||
pub type ComponentId = u32;
|
||||
|
||||
pub trait ValidatorU16Id {
|
||||
fn validate(&self, id: u16) -> bool;
|
||||
|
||||
@@ -4,6 +4,7 @@ use spacepackets::ByteConversionError;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::CreatorConfig;
|
||||
use spacepackets::ecss::EcssEnumeration;
|
||||
use spacepackets::ecss::MessageTypeId;
|
||||
use spacepackets::ecss::tm::PusTmCreator;
|
||||
use spacepackets::ecss::tm::PusTmSecondaryHeader;
|
||||
|
||||
@@ -30,7 +31,7 @@ impl EventReportCreator {
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.generate_and_send_generic_tm(
|
||||
Subservice::TmInfoReport,
|
||||
MessageSubtypeId::TmInfoReport,
|
||||
time_stamp,
|
||||
event_id,
|
||||
params,
|
||||
@@ -46,7 +47,7 @@ impl EventReportCreator {
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.generate_and_send_generic_tm(
|
||||
Subservice::TmLowSeverityReport,
|
||||
MessageSubtypeId::TmLowSeverityReport,
|
||||
time_stamp,
|
||||
event_id,
|
||||
params,
|
||||
@@ -62,7 +63,7 @@ impl EventReportCreator {
|
||||
buf: &'src_data mut [u8],
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.generate_and_send_generic_tm(
|
||||
Subservice::TmMediumSeverityReport,
|
||||
MessageSubtypeId::TmMediumSeverityReport,
|
||||
time_stamp,
|
||||
event_id,
|
||||
params,
|
||||
@@ -78,7 +79,7 @@ impl EventReportCreator {
|
||||
src_data_buf: &'src_data mut [u8],
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.generate_and_send_generic_tm(
|
||||
Subservice::TmHighSeverityReport,
|
||||
MessageSubtypeId::TmHighSeverityReport,
|
||||
time_stamp,
|
||||
event_id,
|
||||
params,
|
||||
@@ -88,7 +89,7 @@ impl EventReportCreator {
|
||||
|
||||
fn generate_and_send_generic_tm<'time, 'src_data>(
|
||||
&self,
|
||||
subservice: Subservice,
|
||||
subservice: MessageSubtypeId,
|
||||
time_stamp: &'time [u8],
|
||||
event_id: impl EcssEnumeration,
|
||||
params: Option<&'src_data [u8]>,
|
||||
@@ -99,7 +100,7 @@ impl EventReportCreator {
|
||||
|
||||
fn generate_generic_event_tm<'time, 'src_data>(
|
||||
&self,
|
||||
subservice: Subservice,
|
||||
subservice: MessageSubtypeId,
|
||||
time_stamp: &'time [u8],
|
||||
event_id: impl EcssEnumeration,
|
||||
params: Option<&'src_data [u8]>,
|
||||
@@ -110,8 +111,12 @@ impl EventReportCreator {
|
||||
src_data_len += aux_data.len();
|
||||
}
|
||||
source_buffer_large_enough(src_data_buf.len(), src_data_len)?;
|
||||
let sec_header =
|
||||
PusTmSecondaryHeader::new(5, subservice.into(), 0, self.dest_id, time_stamp);
|
||||
let sec_header = PusTmSecondaryHeader::new(
|
||||
MessageTypeId::new(5, subservice.into()),
|
||||
0,
|
||||
self.dest_id,
|
||||
time_stamp,
|
||||
);
|
||||
let mut current_idx = 0;
|
||||
event_id.write_to_be_bytes(&mut src_data_buf[0..event_id.size()])?;
|
||||
current_idx += event_id.size();
|
||||
@@ -328,12 +333,12 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn severity_to_subservice(severity: Severity) -> Subservice {
|
||||
fn severity_to_subservice(severity: Severity) -> MessageSubtypeId {
|
||||
match severity {
|
||||
Severity::Info => Subservice::TmInfoReport,
|
||||
Severity::Low => Subservice::TmLowSeverityReport,
|
||||
Severity::Medium => Subservice::TmMediumSeverityReport,
|
||||
Severity::High => Subservice::TmHighSeverityReport,
|
||||
Severity::Info => MessageSubtypeId::TmInfoReport,
|
||||
Severity::Low => MessageSubtypeId::TmLowSeverityReport,
|
||||
Severity::Medium => MessageSubtypeId::TmMediumSeverityReport,
|
||||
Severity::High => MessageSubtypeId::TmHighSeverityReport,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -311,9 +311,9 @@ pub mod alloc_mod {
|
||||
mod tests {
|
||||
use alloc::string::{String, ToString};
|
||||
use alloc::vec;
|
||||
use arbitrary_int::u11;
|
||||
use arbitrary_int::{u11, u21};
|
||||
use spacepackets::ecss::PusPacket;
|
||||
use spacepackets::ecss::event::Subservice;
|
||||
use spacepackets::ecss::event::MessageSubtypeId;
|
||||
use spacepackets::ecss::tm::PusTmReader;
|
||||
|
||||
use super::*;
|
||||
@@ -325,7 +325,7 @@ mod tests {
|
||||
const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5);
|
||||
const EMPTY_STAMP: [u8; 7] = [0; 7];
|
||||
const TEST_APID: u11 = u11::new(0x02);
|
||||
const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
|
||||
const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, u21::new(0x05));
|
||||
|
||||
fn create_basic_man_1() -> DefaultPusEventU32TmCreator {
|
||||
let reporter = EventReporter::new(TEST_ID.raw(), TEST_APID, 0, 128);
|
||||
@@ -409,8 +409,11 @@ mod tests {
|
||||
assert!(res.params_were_propagated);
|
||||
let event_tm = event_rx.try_recv().expect("no event received");
|
||||
let tm = PusTmReader::new(&event_tm.packet, 7).expect("reading TM failed");
|
||||
assert_eq!(tm.service(), 5);
|
||||
assert_eq!(tm.subservice(), Subservice::TmInfoReport as u8);
|
||||
assert_eq!(tm.service_type_id(), 5);
|
||||
assert_eq!(
|
||||
tm.message_subtype_id(),
|
||||
MessageSubtypeId::TmInfoReport as u8
|
||||
);
|
||||
assert_eq!(tm.user_data().len(), 4 + param_data.len());
|
||||
let u32_event = u32::from_be_bytes(tm.user_data()[0..4].try_into().unwrap());
|
||||
assert_eq!(u32_event, INFO_EVENT.raw());
|
||||
@@ -437,8 +440,11 @@ mod tests {
|
||||
assert!(res.params_were_propagated);
|
||||
let event_tm = event_rx.try_recv().expect("no event received");
|
||||
let tm = PusTmReader::new(&event_tm.packet, 7).expect("reading TM failed");
|
||||
assert_eq!(tm.service(), 5);
|
||||
assert_eq!(tm.subservice(), Subservice::TmInfoReport as u8);
|
||||
assert_eq!(tm.service_type_id(), 5);
|
||||
assert_eq!(
|
||||
tm.message_subtype_id(),
|
||||
MessageSubtypeId::TmInfoReport as u8
|
||||
);
|
||||
assert_eq!(tm.user_data().len(), 4 + param_data.len());
|
||||
let u32_event = u32::from_be_bytes(tm.user_data()[0..4].try_into().unwrap());
|
||||
assert_eq!(u32_event, INFO_EVENT.raw());
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::pus::verification::TcStateToken;
|
||||
use crate::pus::{DirectPusPacketHandlerResult, PartialPusHandlingError, PusPacketHandlingError};
|
||||
use crate::queue::GenericSendError;
|
||||
use spacepackets::ecss::PusPacket;
|
||||
use spacepackets::ecss::event::Subservice;
|
||||
use spacepackets::ecss::event::MessageSubtypeId;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use super::verification::VerificationReportingProvider;
|
||||
@@ -60,11 +60,11 @@ impl<
|
||||
.tc_in_mem_converter_mut()
|
||||
.cache(&ecss_tc_and_token.tc_in_memory)?;
|
||||
let tc = self.service_helper.tc_in_mem_converter().convert()?;
|
||||
let subservice = tc.subservice();
|
||||
let srv = Subservice::try_from(subservice);
|
||||
let subservice = tc.message_subtype_id();
|
||||
let srv = MessageSubtypeId::try_from(subservice);
|
||||
if srv.is_err() {
|
||||
return Ok(DirectPusPacketHandlerResult::CustomSubservice(
|
||||
tc.subservice(),
|
||||
tc.message_subtype_id(),
|
||||
ecss_tc_and_token.token,
|
||||
));
|
||||
}
|
||||
@@ -116,21 +116,21 @@ impl<
|
||||
};
|
||||
|
||||
match srv.unwrap() {
|
||||
Subservice::TmInfoReport
|
||||
| Subservice::TmLowSeverityReport
|
||||
| Subservice::TmMediumSeverityReport
|
||||
| Subservice::TmHighSeverityReport => {
|
||||
MessageSubtypeId::TmInfoReport
|
||||
| MessageSubtypeId::TmLowSeverityReport
|
||||
| MessageSubtypeId::TmMediumSeverityReport
|
||||
| MessageSubtypeId::TmHighSeverityReport => {
|
||||
return Err(PusPacketHandlingError::RequestConversion(
|
||||
GenericConversionError::WrongService(tc.subservice()),
|
||||
GenericConversionError::WrongService(tc.message_subtype_id()),
|
||||
));
|
||||
}
|
||||
Subservice::TcEnableEventGeneration => {
|
||||
MessageSubtypeId::TcEnableEventGeneration => {
|
||||
handle_enable_disable_request(true)?;
|
||||
}
|
||||
Subservice::TcDisableEventGeneration => {
|
||||
MessageSubtypeId::TcDisableEventGeneration => {
|
||||
handle_enable_disable_request(false)?;
|
||||
}
|
||||
Subservice::TcReportDisabledList | Subservice::TmDisabledEventsReport => {
|
||||
MessageSubtypeId::TcReportDisabledList | MessageSubtypeId::TmDisabledEventsReport => {
|
||||
return Ok(DirectPusPacketHandlerResult::SubserviceNotImplemented(
|
||||
subservice,
|
||||
ecss_tc_and_token.token,
|
||||
@@ -147,8 +147,8 @@ mod tests {
|
||||
use arbitrary_int::traits::Integer as _;
|
||||
use arbitrary_int::u14;
|
||||
use delegate::delegate;
|
||||
use spacepackets::ecss::CreatorConfig;
|
||||
use spacepackets::ecss::event::Subservice;
|
||||
use spacepackets::ecss::event::MessageSubtypeId;
|
||||
use spacepackets::ecss::{CreatorConfig, MessageTypeId};
|
||||
use spacepackets::time::{TimeWriter, cds};
|
||||
use spacepackets::util::UnsignedEnum;
|
||||
use spacepackets::{
|
||||
@@ -241,12 +241,12 @@ mod tests {
|
||||
|
||||
fn event_test(
|
||||
test_harness: &mut (impl PusTestHarness + SimplePusPacketHandler),
|
||||
subservice: Subservice,
|
||||
subservice: MessageSubtypeId,
|
||||
expected_event_req: EventRequest,
|
||||
event_req_receiver: mpsc::Receiver<EventRequestWithToken>,
|
||||
) {
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(5, subservice as u8);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(5, subservice as u8));
|
||||
let mut app_data = [0; 4];
|
||||
TEST_EVENT_0
|
||||
.write_to_be_bytes(&mut app_data)
|
||||
@@ -272,7 +272,7 @@ mod tests {
|
||||
let mut test_harness = Pus5HandlerWithStoreTester::new(event_request_tx);
|
||||
event_test(
|
||||
&mut test_harness,
|
||||
Subservice::TcEnableEventGeneration,
|
||||
MessageSubtypeId::TcEnableEventGeneration,
|
||||
EventRequest::Enable(TEST_EVENT_0),
|
||||
event_request_rx,
|
||||
);
|
||||
@@ -284,7 +284,7 @@ mod tests {
|
||||
let mut test_harness = Pus5HandlerWithStoreTester::new(event_request_tx);
|
||||
event_test(
|
||||
&mut test_harness,
|
||||
Subservice::TcDisableEventGeneration,
|
||||
MessageSubtypeId::TcDisableEventGeneration,
|
||||
EventRequest::Disable(TEST_EVENT_0),
|
||||
event_request_rx,
|
||||
);
|
||||
@@ -311,7 +311,7 @@ mod tests {
|
||||
let (event_request_tx, _) = mpsc::channel();
|
||||
let mut test_harness = Pus5HandlerWithStoreTester::new(event_request_tx);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(5, 200);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(5, 200));
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
@@ -331,8 +331,10 @@ mod tests {
|
||||
let (event_request_tx, _) = mpsc::channel();
|
||||
let mut test_harness = Pus5HandlerWithStoreTester::new(event_request_tx);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sec_header =
|
||||
PusTcSecondaryHeader::new_simple(5, Subservice::TcEnableEventGeneration as u8);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(
|
||||
5,
|
||||
MessageSubtypeId::TcEnableEventGeneration as u8,
|
||||
));
|
||||
let ping_tc =
|
||||
PusTcCreator::new(sp_header, sec_header, &[0, 1, 2], CreatorConfig::default());
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
|
||||
@@ -1258,7 +1258,7 @@ pub(crate) fn source_buffer_large_enough(
|
||||
|
||||
#[cfg(any(feature = "test_util", test))]
|
||||
pub mod test_util {
|
||||
use arbitrary_int::u11;
|
||||
use arbitrary_int::{u11, u21};
|
||||
use spacepackets::ecss::{tc::PusTcCreator, tm::PusTmReader};
|
||||
|
||||
use crate::request::UniqueApidTargetId;
|
||||
@@ -1269,8 +1269,8 @@ pub mod test_util {
|
||||
};
|
||||
|
||||
pub const TEST_APID: u11 = u11::new(0x101);
|
||||
pub const TEST_UNIQUE_ID_0: u32 = 0x05;
|
||||
pub const TEST_UNIQUE_ID_1: u32 = 0x06;
|
||||
pub const TEST_UNIQUE_ID_0: u21 = u21::new(0x05);
|
||||
pub const TEST_UNIQUE_ID_1: u21 = u21::new(0x06);
|
||||
|
||||
pub const TEST_COMPONENT_ID_0: UniqueApidTargetId =
|
||||
UniqueApidTargetId::new(TEST_APID, TEST_UNIQUE_ID_0);
|
||||
@@ -1364,10 +1364,10 @@ pub mod tests {
|
||||
let mut timestamp = [0; 7];
|
||||
timestamp.clone_from_slice(&tm.timestamp()[0..7]);
|
||||
Self {
|
||||
subservice: PusPacket::subservice(tm),
|
||||
subservice: PusPacket::message_subtype_id(tm),
|
||||
apid: tm.apid(),
|
||||
seq_count: tm.seq_count(),
|
||||
msg_counter: tm.msg_counter(),
|
||||
msg_counter: tm.msg_type_counter(),
|
||||
dest_id: tm.dest_id(),
|
||||
timestamp: timestamp.to_vec(),
|
||||
}
|
||||
@@ -1478,8 +1478,8 @@ pub mod tests {
|
||||
let tm_pool = self.tm_pool.0.read().unwrap();
|
||||
let tm_raw = tm_pool.read_as_vec(&tm_in_pool.store_addr).unwrap();
|
||||
let tm = PusTmReader::new(&tm_raw, 7).unwrap();
|
||||
assert_eq!(PusPacket::service(&tm), 1);
|
||||
assert_eq!(PusPacket::subservice(&tm), subservice);
|
||||
assert_eq!(PusPacket::service_type_id(&tm), 1);
|
||||
assert_eq!(PusPacket::message_subtype_id(&tm), subservice);
|
||||
assert_eq!(tm.apid(), TEST_APID);
|
||||
let req_id =
|
||||
RequestId::from_bytes(tm.user_data()).expect("generating request ID failed");
|
||||
@@ -1597,8 +1597,8 @@ pub mod tests {
|
||||
assert!(next_msg.is_ok());
|
||||
let next_msg = next_msg.unwrap();
|
||||
let tm = PusTmReader::new(next_msg.packet.as_slice(), 7).unwrap();
|
||||
assert_eq!(PusPacket::service(&tm), 1);
|
||||
assert_eq!(PusPacket::subservice(&tm), subservice);
|
||||
assert_eq!(PusPacket::service_type_id(&tm), 1);
|
||||
assert_eq!(PusPacket::message_subtype_id(&tm), subservice);
|
||||
assert_eq!(tm.apid(), TEST_APID);
|
||||
let req_id =
|
||||
RequestId::from_bytes(tm.user_data()).expect("generating request ID failed");
|
||||
@@ -1615,9 +1615,9 @@ pub mod tests {
|
||||
|
||||
impl<const SERVICE: u8> TestConverter<SERVICE> {
|
||||
pub fn check_service(&self, tc: &PusTcReader) -> Result<(), PusPacketHandlingError> {
|
||||
if tc.service() != SERVICE {
|
||||
if tc.service_type_id() != SERVICE {
|
||||
return Err(PusPacketHandlingError::RequestConversion(
|
||||
GenericConversionError::WrongService(tc.service()),
|
||||
GenericConversionError::WrongService(tc.service_type_id()),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -37,6 +37,7 @@ mod tests {
|
||||
use std::sync::mpsc;
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
mode::{
|
||||
ModeAndSubmode, ModeReply, ModeReplySender, ModeRequest, ModeRequestSender,
|
||||
ModeRequestorAndHandlerMpsc, ModeRequestorOneChildMpsc,
|
||||
@@ -44,9 +45,9 @@ mod tests {
|
||||
request::{GenericMessage, MessageMetadata},
|
||||
};
|
||||
|
||||
const TEST_COMPONENT_ID_0: u64 = 5;
|
||||
const TEST_COMPONENT_ID_1: u64 = 6;
|
||||
const TEST_COMPONENT_ID_2: u64 = 7;
|
||||
const TEST_COMPONENT_ID_0: ComponentId = 5;
|
||||
const TEST_COMPONENT_ID_1: ComponentId = 6;
|
||||
const TEST_COMPONENT_ID_2: ComponentId = 7;
|
||||
|
||||
#[test]
|
||||
fn test_simple_mode_requestor() {
|
||||
|
||||
@@ -202,14 +202,16 @@ pub trait PusScheduler {
|
||||
pus_tc: &(impl IsPusTelecommand + PusPacket + GenericPusTcSecondaryHeader),
|
||||
pool: &mut (impl PoolProvider + ?Sized),
|
||||
) -> Result<TcInfo, ScheduleError> {
|
||||
if PusPacket::service(pus_tc) != 11 {
|
||||
return Err(ScheduleError::WrongService(PusPacket::service(pus_tc)));
|
||||
}
|
||||
if PusPacket::subservice(pus_tc) != 4 {
|
||||
return Err(ScheduleError::WrongSubservice(PusPacket::subservice(
|
||||
if PusPacket::service_type_id(pus_tc) != 11 {
|
||||
return Err(ScheduleError::WrongService(PusPacket::service_type_id(
|
||||
pus_tc,
|
||||
)));
|
||||
}
|
||||
if PusPacket::message_subtype_id(pus_tc) != 4 {
|
||||
return Err(ScheduleError::WrongSubservice(
|
||||
PusPacket::message_subtype_id(pus_tc),
|
||||
));
|
||||
}
|
||||
if pus_tc.user_data().is_empty() {
|
||||
return Err(ScheduleError::TcDataEmpty);
|
||||
}
|
||||
@@ -229,7 +231,9 @@ pub trait PusScheduler {
|
||||
pool: &mut (impl PoolProvider + ?Sized),
|
||||
) -> Result<TcInfo, ScheduleError> {
|
||||
let check_tc = PusTcReader::new(tc)?;
|
||||
if PusPacket::service(&check_tc) == 11 && PusPacket::subservice(&check_tc) == 4 {
|
||||
if PusPacket::service_type_id(&check_tc) == 11
|
||||
&& PusPacket::message_subtype_id(&check_tc) == 4
|
||||
{
|
||||
return Err(ScheduleError::NestedScheduledTc);
|
||||
}
|
||||
let req_id = RequestId::from_tc(&check_tc);
|
||||
@@ -420,7 +424,9 @@ pub mod alloc_mod {
|
||||
pool: &mut (impl PoolProvider + ?Sized),
|
||||
) -> Result<TcInfo, ScheduleError> {
|
||||
let check_tc = PusTcReader::new(tc)?;
|
||||
if PusPacket::service(&check_tc) == 11 && PusPacket::subservice(&check_tc) == 4 {
|
||||
if PusPacket::service_type_id(&check_tc) == 11
|
||||
&& PusPacket::message_subtype_id(&check_tc) == 4
|
||||
{
|
||||
return Err(ScheduleError::NestedScheduledTc);
|
||||
}
|
||||
let req_id = RequestId::from_tc(&check_tc);
|
||||
@@ -798,7 +804,7 @@ mod tests {
|
||||
use arbitrary_int::traits::Integer;
|
||||
use arbitrary_int::{u11, u14};
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
|
||||
use spacepackets::ecss::{CreatorConfig, WritablePusPacket};
|
||||
use spacepackets::ecss::{CreatorConfig, MessageTypeId, WritablePusPacket};
|
||||
use spacepackets::time::{TimeWriter, UnixTime, cds};
|
||||
use spacepackets::{PacketId, PacketSequenceControl, PacketType, SequenceFlags, SpHeader};
|
||||
use std::time::Duration;
|
||||
@@ -822,17 +828,32 @@ mod tests {
|
||||
|
||||
fn scheduled_tc(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator<'_> {
|
||||
let (sph, len_app_data) = pus_tc_base(timestamp, buf);
|
||||
PusTcCreator::new_simple(sph, 11, 4, &buf[..len_app_data], CreatorConfig::default())
|
||||
PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(11, 4),
|
||||
&buf[..len_app_data],
|
||||
CreatorConfig::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn wrong_tc_service(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator<'_> {
|
||||
let (sph, len_app_data) = pus_tc_base(timestamp, buf);
|
||||
PusTcCreator::new_simple(sph, 12, 4, &buf[..len_app_data], CreatorConfig::default())
|
||||
PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(12, 4),
|
||||
&buf[..len_app_data],
|
||||
CreatorConfig::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn wrong_tc_subservice(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator<'_> {
|
||||
let (sph, len_app_data) = pus_tc_base(timestamp, buf);
|
||||
PusTcCreator::new_simple(sph, 11, 5, &buf[..len_app_data], CreatorConfig::default())
|
||||
PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(11, 5),
|
||||
&buf[..len_app_data],
|
||||
CreatorConfig::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn double_wrapped_time_tagged_tc(timestamp: UnixTime, buf: &mut [u8]) -> PusTcCreator<'_> {
|
||||
@@ -843,15 +864,18 @@ mod tests {
|
||||
let sph = SpHeader::new_for_unseg_tc(u11::new(0x02), u14::new(0x34), 0);
|
||||
// app data should not matter, double wrapped time-tagged commands should be rejected right
|
||||
// away
|
||||
let inner_time_tagged_tc =
|
||||
PusTcCreator::new_simple(sph, 11, 4, &[], CreatorConfig::default());
|
||||
let inner_time_tagged_tc = PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(11, 4),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let packet_len = inner_time_tagged_tc
|
||||
.write_to_bytes(&mut buf[len_time_stamp..])
|
||||
.expect("writing inner time tagged tc failed");
|
||||
PusTcCreator::new_simple(
|
||||
sph,
|
||||
11,
|
||||
4,
|
||||
MessageTypeId::new(11, 4),
|
||||
&buf[..len_time_stamp + packet_len],
|
||||
CreatorConfig::default(),
|
||||
)
|
||||
@@ -859,12 +883,22 @@ mod tests {
|
||||
|
||||
fn invalid_time_tagged_cmd() -> PusTcCreator<'static> {
|
||||
let sph = SpHeader::new_for_unseg_tc(u11::new(0x02), u14::new(0x34), 1);
|
||||
PusTcCreator::new_simple(sph, 11, 4, &[], CreatorConfig::default())
|
||||
PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(11, 4),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn base_ping_tc_simple_ctor(seq_count: u14, app_data: &'static [u8]) -> PusTcCreator<'static> {
|
||||
let sph = SpHeader::new_for_unseg_tc(u11::new(0x02), seq_count, 0);
|
||||
PusTcCreator::new_simple(sph, 17, 1, app_data, CreatorConfig::default())
|
||||
PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(17, 1),
|
||||
app_data,
|
||||
CreatorConfig::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn ping_tc_to_store(
|
||||
@@ -1033,7 +1067,7 @@ mod tests {
|
||||
let apid_to_set = u11::new(0x22);
|
||||
let seq_count = u14::new(105);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(apid_to_set, u14::new(105), 0);
|
||||
let mut sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let mut sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
sec_header.source_id = src_id_to_set;
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
@@ -2010,7 +2044,7 @@ mod tests {
|
||||
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)),
|
||||
0,
|
||||
);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, CreatorConfig::default());
|
||||
let mut buf: [u8; 64] = [0; 64];
|
||||
let result = generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc);
|
||||
@@ -2032,7 +2066,7 @@ mod tests {
|
||||
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)),
|
||||
0,
|
||||
);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, CreatorConfig::default());
|
||||
let mut buf: [u8; 16] = [0; 16];
|
||||
let result = generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc);
|
||||
@@ -2061,7 +2095,7 @@ mod tests {
|
||||
PacketSequenceControl::new(SequenceFlags::Unsegmented, u14::new(5)),
|
||||
0,
|
||||
);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
let ping_tc = PusTcCreator::new_no_app_data(sph, sec_header, CreatorConfig::default());
|
||||
let mut buf: [u8; 64] = [0; 64];
|
||||
generate_insert_telecommand_app_data(&mut buf, &time_writer, &ping_tc).unwrap();
|
||||
|
||||
@@ -79,8 +79,8 @@ impl<
|
||||
.tc_in_mem_converter_mut()
|
||||
.cache(&ecss_tc_and_token.tc_in_memory)?;
|
||||
let tc = self.service_helper.tc_in_mem_converter().convert()?;
|
||||
let subservice = PusPacket::subservice(&tc);
|
||||
let standard_subservice = scheduling::Subservice::try_from(subservice);
|
||||
let subservice = PusPacket::message_subtype_id(&tc);
|
||||
let standard_subservice = scheduling::MessageSubtypeId::try_from(subservice);
|
||||
if standard_subservice.is_err() {
|
||||
return Ok(DirectPusPacketHandlerResult::CustomSubservice(
|
||||
subservice,
|
||||
@@ -88,7 +88,7 @@ impl<
|
||||
));
|
||||
}
|
||||
match standard_subservice.unwrap() {
|
||||
scheduling::Subservice::TcEnableScheduling => {
|
||||
scheduling::MessageSubtypeId::TcEnableScheduling => {
|
||||
let opt_started_token = match self.service_helper.verif_reporter().start_success(
|
||||
&self.service_helper.common.tm_sender,
|
||||
ecss_tc_and_token.token,
|
||||
@@ -117,7 +117,7 @@ impl<
|
||||
));
|
||||
}
|
||||
}
|
||||
scheduling::Subservice::TcDisableScheduling => {
|
||||
scheduling::MessageSubtypeId::TcDisableScheduling => {
|
||||
let opt_started_token = match self.service_helper.verif_reporter().start_success(
|
||||
&self.service_helper.common.tm_sender,
|
||||
ecss_tc_and_token.token,
|
||||
@@ -147,7 +147,7 @@ impl<
|
||||
));
|
||||
}
|
||||
}
|
||||
scheduling::Subservice::TcResetScheduling => {
|
||||
scheduling::MessageSubtypeId::TcResetScheduling => {
|
||||
let start_token = self
|
||||
.service_helper
|
||||
.verif_reporter()
|
||||
@@ -171,7 +171,7 @@ impl<
|
||||
)
|
||||
.expect("Error sending completion success");
|
||||
}
|
||||
scheduling::Subservice::TcInsertActivity => {
|
||||
scheduling::MessageSubtypeId::TcInsertActivity => {
|
||||
let start_token = self
|
||||
.service_helper
|
||||
.common
|
||||
@@ -264,9 +264,9 @@ mod tests {
|
||||
use arbitrary_int::u14;
|
||||
use delegate::delegate;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::scheduling::Subservice;
|
||||
use spacepackets::ecss::scheduling::MessageSubtypeId;
|
||||
use spacepackets::ecss::tc::PusTcSecondaryHeader;
|
||||
use spacepackets::ecss::{CreatorConfig, WritablePusPacket};
|
||||
use spacepackets::ecss::{CreatorConfig, MessageTypeId, WritablePusPacket};
|
||||
use spacepackets::time::TimeWriter;
|
||||
use spacepackets::{
|
||||
ecss::{tc::PusTcCreator, tm::PusTmReader},
|
||||
@@ -386,10 +386,10 @@ mod tests {
|
||||
|
||||
fn generic_subservice_send(
|
||||
test_harness: &mut Pus11HandlerWithStoreTester,
|
||||
subservice: Subservice,
|
||||
subservice: MessageSubtypeId,
|
||||
) {
|
||||
let reply_header = SpHeader::new_for_unseg_tm(TEST_APID, u14::ZERO, 0);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(11, subservice as u8);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(11, subservice as u8));
|
||||
let enable_scheduling =
|
||||
PusTcCreator::new(reply_header, tc_header, &[0; 7], CreatorConfig::default());
|
||||
let token = test_harness.start_verification(&enable_scheduling);
|
||||
@@ -411,7 +411,7 @@ mod tests {
|
||||
let mut test_harness = Pus11HandlerWithStoreTester::new();
|
||||
test_harness.handler.scheduler_mut().disable();
|
||||
assert!(!test_harness.handler.scheduler().is_enabled());
|
||||
generic_subservice_send(&mut test_harness, Subservice::TcEnableScheduling);
|
||||
generic_subservice_send(&mut test_harness, MessageSubtypeId::TcEnableScheduling);
|
||||
assert!(test_harness.handler.scheduler().is_enabled());
|
||||
assert_eq!(test_harness.handler.scheduler().enabled_count, 1);
|
||||
}
|
||||
@@ -421,7 +421,7 @@ mod tests {
|
||||
let mut test_harness = Pus11HandlerWithStoreTester::new();
|
||||
test_harness.handler.scheduler_mut().enable();
|
||||
assert!(test_harness.handler.scheduler().is_enabled());
|
||||
generic_subservice_send(&mut test_harness, Subservice::TcDisableScheduling);
|
||||
generic_subservice_send(&mut test_harness, MessageSubtypeId::TcDisableScheduling);
|
||||
assert!(!test_harness.handler.scheduler().is_enabled());
|
||||
assert_eq!(test_harness.handler.scheduler().disabled_count, 1);
|
||||
}
|
||||
@@ -429,7 +429,7 @@ mod tests {
|
||||
#[test]
|
||||
fn test_reset_scheduler_tc() {
|
||||
let mut test_harness = Pus11HandlerWithStoreTester::new();
|
||||
generic_subservice_send(&mut test_harness, Subservice::TcResetScheduling);
|
||||
generic_subservice_send(&mut test_harness, MessageSubtypeId::TcResetScheduling);
|
||||
assert_eq!(test_harness.handler.scheduler().reset_count, 1);
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ mod tests {
|
||||
fn test_insert_activity_tc() {
|
||||
let mut test_harness = Pus11HandlerWithStoreTester::new();
|
||||
let mut reply_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let mut sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let mut sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
let ping_tc = PusTcCreator::new(reply_header, sec_header, &[], CreatorConfig::default());
|
||||
let req_id_ping_tc = scheduler::RequestId::from_tc(&ping_tc);
|
||||
let stamper = cds::CdsTime::now_with_u16_days().expect("time provider failed");
|
||||
@@ -447,7 +447,10 @@ mod tests {
|
||||
sched_app_data[written_len..written_len + ping_raw.len()].copy_from_slice(&ping_raw);
|
||||
written_len += ping_raw.len();
|
||||
reply_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
sec_header = PusTcSecondaryHeader::new_simple(11, Subservice::TcInsertActivity as u8);
|
||||
sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(
|
||||
11,
|
||||
MessageSubtypeId::TcInsertActivity as u8,
|
||||
));
|
||||
let enable_scheduling = PusTcCreator::new(
|
||||
reply_header,
|
||||
sec_header,
|
||||
|
||||
@@ -6,7 +6,7 @@ use arbitrary_int::traits::Integer as _;
|
||||
use arbitrary_int::u14;
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use spacepackets::ecss::{CreatorConfig, PusPacket};
|
||||
use spacepackets::ecss::{CreatorConfig, MessageTypeId, PusPacket};
|
||||
use std::sync::mpsc;
|
||||
|
||||
use super::verification::{VerificationReporter, VerificationReportingProvider};
|
||||
@@ -59,10 +59,10 @@ impl<
|
||||
.tc_in_mem_converter_mut()
|
||||
.cache(&ecss_tc_and_token.tc_in_memory)?;
|
||||
let tc = self.service_helper.tc_in_mem_converter().convert()?;
|
||||
if tc.service() != 17 {
|
||||
return Err(GenericConversionError::WrongService(tc.service()).into());
|
||||
if tc.service_type_id() != 17 {
|
||||
return Err(GenericConversionError::WrongService(tc.service_type_id()).into());
|
||||
}
|
||||
if tc.subservice() == 1 {
|
||||
if tc.message_subtype_id() == 1 {
|
||||
let opt_started_token = match self.service_helper.verif_reporter().start_success(
|
||||
&self.service_helper.common.tm_sender,
|
||||
ecss_tc_and_token.token,
|
||||
@@ -82,7 +82,7 @@ impl<
|
||||
u14::ZERO,
|
||||
0,
|
||||
);
|
||||
let tc_header = PusTmSecondaryHeader::new_simple(17, 2, time_stamp);
|
||||
let tc_header = PusTmSecondaryHeader::new_simple(MessageTypeId::new(17, 2), time_stamp);
|
||||
let ping_reply =
|
||||
PusTmCreator::new(reply_header, tc_header, &[], CreatorConfig::default());
|
||||
if let Err(e) = self
|
||||
@@ -104,7 +104,7 @@ impl<
|
||||
}
|
||||
} else {
|
||||
return Ok(DirectPusPacketHandlerResult::CustomSubservice(
|
||||
tc.subservice(),
|
||||
tc.message_subtype_id(),
|
||||
ecss_tc_and_token.token,
|
||||
));
|
||||
}
|
||||
@@ -160,7 +160,7 @@ mod tests {
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader};
|
||||
use spacepackets::ecss::tm::PusTmReader;
|
||||
use spacepackets::ecss::{CreatorConfig, PusPacket};
|
||||
use spacepackets::ecss::{CreatorConfig, MessageTypeId, PusPacket};
|
||||
use spacepackets::time::{TimeWriter, cds};
|
||||
|
||||
use super::PusService17TestHandler;
|
||||
@@ -292,7 +292,7 @@ mod tests {
|
||||
fn ping_test(test_harness: &mut (impl PusTestHarness + SimplePusPacketHandler)) {
|
||||
// Create a ping TC, verify acceptance.
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
@@ -311,8 +311,8 @@ mod tests {
|
||||
|
||||
// Ping reply
|
||||
let tm = test_harness.read_next_tm();
|
||||
assert_eq!(tm.service(), 17);
|
||||
assert_eq!(tm.subservice(), 2);
|
||||
assert_eq!(tm.service_type_id(), 17);
|
||||
assert_eq!(tm.message_subtype_id(), 2);
|
||||
assert!(tm.user_data().is_empty());
|
||||
|
||||
// TM completion
|
||||
@@ -348,7 +348,7 @@ mod tests {
|
||||
fn test_sending_unsupported_service() {
|
||||
let mut test_harness = Pus17HandlerWithStoreTester::new(0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(3, 1);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(3, 1));
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
@@ -370,7 +370,7 @@ mod tests {
|
||||
fn test_sending_custom_subservice() {
|
||||
let mut test_harness = Pus17HandlerWithStoreTester::new(0);
|
||||
let sp_header = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 200);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 200));
|
||||
let ping_tc =
|
||||
PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let token = test_harness.start_verification(&ping_tc);
|
||||
|
||||
@@ -23,13 +23,13 @@
|
||||
//! use satrs::request::UniqueApidTargetId;
|
||||
//! use spacepackets::ecss::PusPacket;
|
||||
//! use spacepackets::SpHeader;
|
||||
//! use spacepackets::ecss::tc::{PusTcCreator, PusTcSecondaryHeader, CreatorConfig};
|
||||
//! use spacepackets::ecss::tc::{MessageTypeId, PusTcCreator, PusTcSecondaryHeader, CreatorConfig};
|
||||
//! use spacepackets::ecss::tm::PusTmReader;
|
||||
//! use arbitrary_int::u11;
|
||||
//! use arbitrary_int::{u11, u21};
|
||||
//!
|
||||
//! const EMPTY_STAMP: [u8; 7] = [0; 7];
|
||||
//! const TEST_APID: u11 = u11::new(0x02);
|
||||
//! const TEST_COMPONENT_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
|
||||
//! const TEST_COMPONENT_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, u21::new(0x05));
|
||||
//!
|
||||
//! let pool_cfg = StaticPoolConfig::new_from_subpool_cfg_tuples(
|
||||
//! vec![(10, 32), (10, 64), (10, 128), (10, 1024)], false
|
||||
@@ -41,7 +41,7 @@
|
||||
//! let cfg = VerificationReporterConfig::new(TEST_APID, 1, 2, 8);
|
||||
//! let mut reporter = VerificationReporter::new(TEST_COMPONENT_ID.id(), &cfg);
|
||||
//!
|
||||
//! let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
//! let tc_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
//! let pus_tc_0 = PusTcCreator::new_no_app_data(
|
||||
//! SpHeader::new_from_apid(TEST_APID),
|
||||
//! tc_header,
|
||||
@@ -67,11 +67,11 @@
|
||||
//! }
|
||||
//! let pus_tm = PusTmReader::new(&tm_buf[0..tm_len], 7).expect("Error reading verification TM");
|
||||
//! if packet_idx == 0 {
|
||||
//! assert_eq!(pus_tm.subservice(), 1);
|
||||
//! assert_eq!(pus_tm.message_subtype_id(), 1);
|
||||
//! } else if packet_idx == 1 {
|
||||
//! assert_eq!(pus_tm.subservice(), 3);
|
||||
//! assert_eq!(pus_tm.message_subtype_id(), 3);
|
||||
//! } else if packet_idx == 2 {
|
||||
//! assert_eq!(pus_tm.subservice(), 7);
|
||||
//! assert_eq!(pus_tm.message_subtype_id(), 7);
|
||||
//! }
|
||||
//! packet_idx += 1;
|
||||
//! }
|
||||
@@ -94,7 +94,7 @@ use serde::{Deserialize, Serialize};
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::tc::IsPusTelecommand;
|
||||
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use spacepackets::ecss::{CreatorConfig, EcssEnumeration};
|
||||
use spacepackets::ecss::{CreatorConfig, EcssEnumeration, MessageTypeId};
|
||||
use spacepackets::{ByteConversionError, CcsdsPacket, PacketId, PacketSequenceControl};
|
||||
|
||||
pub use spacepackets::ecss::verification::*;
|
||||
@@ -507,9 +507,7 @@ impl VerificationReportCreator {
|
||||
self.dest_id = dest_id;
|
||||
}
|
||||
|
||||
/// Initialize verification handling by passing a TC reference. This returns a token required
|
||||
/// to call the acceptance functions
|
||||
pub fn read_request_id_from_tc(pus_tc: &(impl CcsdsPacket + IsPusTelecommand)) -> RequestId {
|
||||
pub fn read_request_id(&self, pus_tc: &(impl CcsdsPacket + IsPusTelecommand)) -> RequestId {
|
||||
RequestId::new(pus_tc)
|
||||
}
|
||||
|
||||
@@ -569,7 +567,7 @@ impl VerificationReportCreator {
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
let tm_creator = self.success_verification_no_step(
|
||||
src_data_buf,
|
||||
Subservice::TmAcceptanceSuccess.into(),
|
||||
MessageSubtypeId::TmAcceptanceSuccess.into(),
|
||||
request_id,
|
||||
seq_count,
|
||||
msg_count,
|
||||
@@ -589,7 +587,7 @@ impl VerificationReportCreator {
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.failure_verification_no_step(
|
||||
src_data_buf,
|
||||
Subservice::TmAcceptanceFailure.into(),
|
||||
MessageSubtypeId::TmAcceptanceFailure.into(),
|
||||
request_id,
|
||||
seq_count,
|
||||
msg_count,
|
||||
@@ -611,7 +609,7 @@ impl VerificationReportCreator {
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
let tm_creator = self.success_verification_no_step(
|
||||
src_data_buf,
|
||||
Subservice::TmStartSuccess.into(),
|
||||
MessageSubtypeId::TmStartSuccess.into(),
|
||||
request_id,
|
||||
seq_count,
|
||||
msg_count,
|
||||
@@ -634,7 +632,7 @@ impl VerificationReportCreator {
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.failure_verification_no_step(
|
||||
src_data_buf,
|
||||
Subservice::TmStartFailure.into(),
|
||||
MessageSubtypeId::TmStartFailure.into(),
|
||||
request_id,
|
||||
seq_count,
|
||||
msg_count,
|
||||
@@ -657,7 +655,7 @@ impl VerificationReportCreator {
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.create_pus_verif_success_tm(
|
||||
src_data_buf,
|
||||
Subservice::TmStepSuccess.into(),
|
||||
MessageSubtypeId::TmStepSuccess.into(),
|
||||
seq_count,
|
||||
msg_count,
|
||||
request_id,
|
||||
@@ -680,7 +678,7 @@ impl VerificationReportCreator {
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.create_pus_verif_fail_tm(
|
||||
src_data_buf,
|
||||
Subservice::TmStepFailure.into(),
|
||||
MessageSubtypeId::TmStepFailure.into(),
|
||||
seq_count,
|
||||
msg_count,
|
||||
&token.request_id(),
|
||||
@@ -703,7 +701,7 @@ impl VerificationReportCreator {
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.success_verification_no_step(
|
||||
src_data_buf,
|
||||
Subservice::TmCompletionSuccess.into(),
|
||||
MessageSubtypeId::TmCompletionSuccess.into(),
|
||||
request_id,
|
||||
seq_counter,
|
||||
msg_counter,
|
||||
@@ -725,7 +723,7 @@ impl VerificationReportCreator {
|
||||
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
|
||||
self.failure_verification_no_step(
|
||||
src_data_buf,
|
||||
Subservice::TmCompletionFailure.into(),
|
||||
MessageSubtypeId::TmCompletionFailure.into(),
|
||||
request_id,
|
||||
seq_count,
|
||||
msg_count,
|
||||
@@ -822,8 +820,12 @@ impl VerificationReportCreator {
|
||||
time_stamp: &'time [u8],
|
||||
source_data_len: usize,
|
||||
) -> PusTmCreator<'time, 'src_data> {
|
||||
let tm_sec_header =
|
||||
PusTmSecondaryHeader::new(1, subservice, msg_counter, self.dest_id, time_stamp);
|
||||
let tm_sec_header = PusTmSecondaryHeader::new(
|
||||
MessageTypeId::new(1, subservice),
|
||||
msg_counter,
|
||||
self.dest_id,
|
||||
time_stamp,
|
||||
);
|
||||
PusTmCreator::new(
|
||||
sp_header,
|
||||
tm_sec_header,
|
||||
@@ -897,7 +899,7 @@ pub mod alloc_mod {
|
||||
> {
|
||||
owner_id: ComponentId,
|
||||
source_data_buf: RefCell<alloc::vec::Vec<u8>>,
|
||||
pub reporter_creator: VerificationReportCreator,
|
||||
pub report_creator: VerificationReportCreator,
|
||||
pub tm_hook: VerificationHookInstance,
|
||||
}
|
||||
|
||||
@@ -913,7 +915,7 @@ pub mod alloc_mod {
|
||||
+ cfg.fail_code_field_width
|
||||
+ cfg.max_fail_data_len
|
||||
]),
|
||||
reporter_creator: reporter,
|
||||
report_creator: reporter,
|
||||
tm_hook: DummyVerificationHook::default(),
|
||||
}
|
||||
}
|
||||
@@ -937,7 +939,7 @@ pub mod alloc_mod {
|
||||
+ cfg.fail_code_field_width
|
||||
+ cfg.max_fail_data_len
|
||||
]),
|
||||
reporter_creator: reporter,
|
||||
report_creator: reporter,
|
||||
tm_hook,
|
||||
}
|
||||
}
|
||||
@@ -946,9 +948,7 @@ pub mod alloc_mod {
|
||||
&self,
|
||||
pus_tc: &(impl CcsdsPacket + IsPusTelecommand),
|
||||
) -> VerificationToken<TcStateNone> {
|
||||
VerificationToken::<TcStateNone>::new(
|
||||
VerificationReportCreator::read_request_id_from_tc(pus_tc),
|
||||
)
|
||||
VerificationToken::<TcStateNone>::new(self.report_creator.read_request_id(pus_tc))
|
||||
}
|
||||
|
||||
pub fn start_verification_with_req_id(
|
||||
@@ -959,7 +959,7 @@ pub mod alloc_mod {
|
||||
}
|
||||
|
||||
delegate!(
|
||||
to self.reporter_creator {
|
||||
to self.report_creator {
|
||||
pub fn set_apid(&mut self, apid: u11);
|
||||
pub fn apid(&self) -> u11;
|
||||
pub fn dest_id(&self) -> u16;
|
||||
@@ -976,7 +976,7 @@ pub mod alloc_mod {
|
||||
for VerificationReporter<VerificationHookInstance>
|
||||
{
|
||||
delegate!(
|
||||
to self.reporter_creator {
|
||||
to self.report_creator {
|
||||
fn set_apid(&mut self, apid: Apid);
|
||||
fn apid(&self) -> Apid;
|
||||
}
|
||||
@@ -1002,7 +1002,7 @@ pub mod alloc_mod {
|
||||
) -> Result<VerificationToken<TcStateAccepted>, EcssTmtcError> {
|
||||
let mut source_data_buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.report_creator
|
||||
.acceptance_success(
|
||||
source_data_buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
@@ -1025,7 +1025,7 @@ pub mod alloc_mod {
|
||||
) -> Result<(), EcssTmtcError> {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.report_creator
|
||||
.acceptance_failure(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
@@ -1050,7 +1050,7 @@ pub mod alloc_mod {
|
||||
) -> Result<VerificationToken<TcStateStarted>, EcssTmtcError> {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.report_creator
|
||||
.start_success(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
@@ -1076,7 +1076,7 @@ pub mod alloc_mod {
|
||||
) -> Result<(), EcssTmtcError> {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.report_creator
|
||||
.start_failure(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
@@ -1102,7 +1102,7 @@ pub mod alloc_mod {
|
||||
) -> Result<(), EcssTmtcError> {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.report_creator
|
||||
.step_success(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
@@ -1129,7 +1129,7 @@ pub mod alloc_mod {
|
||||
) -> Result<(), EcssTmtcError> {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.report_creator
|
||||
.step_failure(buf.as_mut_slice(), token, u14::ZERO, 0, params)
|
||||
.map_err(PusError::ByteConversion)?;
|
||||
self.tm_hook.modify_tm(&mut tm_creator);
|
||||
@@ -1150,7 +1150,7 @@ pub mod alloc_mod {
|
||||
) -> Result<(), EcssTmtcError> {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.report_creator
|
||||
.completion_success(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
@@ -1176,7 +1176,7 @@ pub mod alloc_mod {
|
||||
) -> Result<(), EcssTmtcError> {
|
||||
let mut buf = self.source_data_buf.borrow_mut();
|
||||
let mut tm_creator = self
|
||||
.reporter_creator
|
||||
.report_creator
|
||||
.completion_failure(
|
||||
buf.as_mut_slice(),
|
||||
&token.request_id(),
|
||||
@@ -1427,7 +1427,7 @@ pub mod test_util {
|
||||
token.request_id(),
|
||||
VerificationReportInfo::AcceptanceFailure(FailureData {
|
||||
sender: self.owner_id(),
|
||||
error_enum: params.failure_code.value(),
|
||||
error_enum: params.failure_code.value_raw(),
|
||||
fail_data: params.failure_data.to_vec(),
|
||||
time_stamp: params.time_stamp.to_vec(),
|
||||
}),
|
||||
@@ -1464,7 +1464,7 @@ pub mod test_util {
|
||||
token.request_id(),
|
||||
VerificationReportInfo::StartedFailure(FailureData {
|
||||
sender: self.owner_id(),
|
||||
error_enum: params.failure_code.value(),
|
||||
error_enum: params.failure_code.value_raw(),
|
||||
fail_data: params.failure_data.to_vec(),
|
||||
time_stamp: params.time_stamp.to_vec(),
|
||||
}),
|
||||
@@ -1486,7 +1486,7 @@ pub mod test_util {
|
||||
sender: self.owner_id(),
|
||||
time_stamp: time_stamp.to_vec(),
|
||||
},
|
||||
step: step.value() as u16,
|
||||
step: step.value_raw() as u16,
|
||||
},
|
||||
));
|
||||
Ok(())
|
||||
@@ -1502,7 +1502,7 @@ pub mod test_util {
|
||||
token.request_id(),
|
||||
VerificationReportInfo::StepFailure(FailureData {
|
||||
sender: self.owner_id(),
|
||||
error_enum: params.common.failure_code.value(),
|
||||
error_enum: params.common.failure_code.value_raw(),
|
||||
fail_data: params.common.failure_data.to_vec(),
|
||||
time_stamp: params.common.time_stamp.to_vec(),
|
||||
}),
|
||||
@@ -1536,7 +1536,7 @@ pub mod test_util {
|
||||
token.request_id(),
|
||||
VerificationReportInfo::CompletionFailure(FailureData {
|
||||
sender: self.owner_id(),
|
||||
error_enum: params.failure_code.value(),
|
||||
error_enum: params.failure_code.value_raw(),
|
||||
fail_data: params.failure_data.to_vec(),
|
||||
time_stamp: params.time_stamp.to_vec(),
|
||||
}),
|
||||
@@ -1731,8 +1731,8 @@ pub mod tests {
|
||||
use arbitrary_int::{u11, u14};
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
|
||||
use spacepackets::ecss::{
|
||||
CreatorConfig, EcssEnumU8, EcssEnumU16, EcssEnumU32, EcssEnumeration, PusError, PusPacket,
|
||||
WritablePusPacket,
|
||||
CreatorConfig, EcssEnumU8, EcssEnumU16, EcssEnumU32, EcssEnumeration, MessageTypeId,
|
||||
PusError, PusPacket, WritablePusPacket,
|
||||
};
|
||||
use spacepackets::util::UnsignedEnum;
|
||||
use spacepackets::{ByteConversionError, SpHeader};
|
||||
@@ -1783,7 +1783,7 @@ pub mod tests {
|
||||
panic!("TestSender: Can not deal with addresses");
|
||||
}
|
||||
PusTmVariant::Direct(tm) => {
|
||||
assert_eq!(PusPacket::service(&tm), 1);
|
||||
assert_eq!(PusPacket::service_type_id(&tm), 1);
|
||||
assert!(!tm.source_data().is_empty());
|
||||
let mut time_stamp = [0; 7];
|
||||
time_stamp.clone_from_slice(&tm.timestamp()[0..7]);
|
||||
@@ -2102,7 +2102,7 @@ pub mod tests {
|
||||
|
||||
fn create_generic_ping() -> PusTcCreator<'static> {
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(0x34), 0);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
PusTcCreator::new(sph, tc_header, &[], CreatorConfig::default())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use arbitrary_int::u11;
|
||||
use arbitrary_int::{prelude::*, u11, u21};
|
||||
use core::{fmt, marker::PhantomData};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -29,11 +29,11 @@ pub type Apid = u11;
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct UniqueApidTargetId {
|
||||
pub apid: Apid,
|
||||
pub unique_id: u32,
|
||||
pub unique_id: u21,
|
||||
}
|
||||
|
||||
impl UniqueApidTargetId {
|
||||
pub const fn new(apid: Apid, target: u32) -> Self {
|
||||
pub const fn new(apid: Apid, target: u21) -> Self {
|
||||
Self {
|
||||
apid,
|
||||
unique_id: target,
|
||||
@@ -41,7 +41,7 @@ impl UniqueApidTargetId {
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> ComponentId {
|
||||
((self.apid.value() as u64) << 32) | (self.unique_id as u64)
|
||||
((self.apid.value() as u32) << 21) | (self.unique_id.value())
|
||||
}
|
||||
|
||||
pub fn id(&self) -> ComponentId {
|
||||
@@ -61,21 +61,21 @@ impl UniqueApidTargetId {
|
||||
}
|
||||
Ok(Self::new(
|
||||
tc.apid(),
|
||||
u32::from_be_bytes(tc.user_data()[0..4].try_into().unwrap()),
|
||||
u21::new(u32::from_be_bytes(tc.user_data()[0..4].try_into().unwrap())),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for UniqueApidTargetId {
|
||||
fn from(raw: u64) -> Self {
|
||||
impl From<ComponentId> for UniqueApidTargetId {
|
||||
fn from(raw: ComponentId) -> Self {
|
||||
Self {
|
||||
apid: u11::new((raw >> 32) as u16),
|
||||
unique_id: raw as u32,
|
||||
apid: u11::new((raw >> 21) as u16),
|
||||
unique_id: u21::new(raw & u21::MAX.value()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UniqueApidTargetId> for u64 {
|
||||
impl From<UniqueApidTargetId> for ComponentId {
|
||||
fn from(target_and_apid_id: UniqueApidTargetId) -> Self {
|
||||
target_and_apid_id.raw()
|
||||
}
|
||||
@@ -497,37 +497,38 @@ mod tests {
|
||||
use std::sync::mpsc;
|
||||
|
||||
use alloc::string::ToString;
|
||||
use arbitrary_int::{u11, u14};
|
||||
use arbitrary_int::{u11, u14, u21};
|
||||
use spacepackets::{
|
||||
ByteConversionError, SpHeader,
|
||||
ecss::{
|
||||
CreatorConfig,
|
||||
CreatorConfig, MessageTypeId,
|
||||
tc::{PusTcCreator, PusTcSecondaryHeader},
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ComponentId,
|
||||
queue::{GenericReceiveError, GenericSendError},
|
||||
request::{Apid, MessageMetadata, MessageSenderMap, MessageSenderStoreProvider},
|
||||
};
|
||||
|
||||
use super::{GenericMessage, MessageReceiverWithId, UniqueApidTargetId};
|
||||
|
||||
const TEST_CHANNEL_ID_0: u64 = 1;
|
||||
const TEST_CHANNEL_ID_1: u64 = 2;
|
||||
const TEST_CHANNEL_ID_2: u64 = 3;
|
||||
const TEST_CHANNEL_ID_0: ComponentId = 1;
|
||||
const TEST_CHANNEL_ID_1: ComponentId = 2;
|
||||
const TEST_CHANNEL_ID_2: ComponentId = 3;
|
||||
|
||||
#[test]
|
||||
fn test_basic_target_id_with_apid() {
|
||||
let id = UniqueApidTargetId::new(Apid::new(0x111), 0x01);
|
||||
let id = UniqueApidTargetId::new(Apid::new(0x111), u21::new(0x01));
|
||||
assert_eq!(id.apid.value(), 0x111);
|
||||
assert_eq!(id.unique_id, 0x01);
|
||||
assert_eq!(id.unique_id.value(), 0x01);
|
||||
assert_eq!(id.id(), id.raw());
|
||||
assert_eq!(u64::from(id), id.raw());
|
||||
assert_eq!(ComponentId::from(id), id.raw());
|
||||
let id_raw = id.raw();
|
||||
let id_from_raw = UniqueApidTargetId::from(id_raw);
|
||||
assert_eq!(id_from_raw, id);
|
||||
assert_eq!(id.id(), (0x111 << 32) | 0x01);
|
||||
assert_eq!(id.id(), (0x111 << 21) | 0x01);
|
||||
let string = id.to_string();
|
||||
assert_eq!(
|
||||
string,
|
||||
@@ -539,17 +540,21 @@ mod tests {
|
||||
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 app_data = 1_u32.to_be_bytes();
|
||||
let pus_tc =
|
||||
PusTcCreator::new_simple(sp_header, 17, 1, &app_data, CreatorConfig::default());
|
||||
let pus_tc = PusTcCreator::new_simple(
|
||||
sp_header,
|
||||
MessageTypeId::new(17, 1),
|
||||
&app_data,
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let id = UniqueApidTargetId::from_pus_tc(&pus_tc).unwrap();
|
||||
assert_eq!(id.apid.value(), 0x111);
|
||||
assert_eq!(id.unique_id, 1);
|
||||
assert_eq!(id.unique_id.value(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_target_id_with_apid_from_pus_tc_invalid_app_data() {
|
||||
let sp_header = SpHeader::new_for_unseg_tc(u11::new(0x111), u14::new(5), 0);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let sec_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
let pus_tc = PusTcCreator::new_no_app_data(sp_header, sec_header, CreatorConfig::default());
|
||||
let error = UniqueApidTargetId::from_pus_tc(&pus_tc);
|
||||
assert!(error.is_err());
|
||||
|
||||
@@ -782,7 +782,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(self.sender.requests.borrow().len(), 2);
|
||||
let req_0 = self.sender.requests.get_mut().pop_front().unwrap();
|
||||
assert_eq!(req_0.target_id, ExampleTargetId::Target0 as u64);
|
||||
assert_eq!(req_0.target_id, ExampleTargetId::Target0 as ComponentId);
|
||||
assert_eq!(req_0.request_id, expected_req_id);
|
||||
assert_eq!(
|
||||
req_0.request,
|
||||
@@ -792,7 +792,7 @@ mod tests {
|
||||
}
|
||||
);
|
||||
let req_1 = self.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req_1.target_id, ExampleTargetId::Target1 as u64);
|
||||
assert_eq!(req_1.target_id, ExampleTargetId::Target1 as ComponentId);
|
||||
assert_eq!(
|
||||
req_1.request,
|
||||
ModeRequest::SetMode {
|
||||
@@ -808,7 +808,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(self.sender.requests.borrow().len(), 1);
|
||||
let req_0 = self.sender.requests.get_mut().pop_front().unwrap();
|
||||
assert_eq!(req_0.target_id, ExampleTargetId::Target2 as u64);
|
||||
assert_eq!(req_0.target_id, ExampleTargetId::Target2 as ComponentId);
|
||||
assert_eq!(req_0.request_id, expected_req_id);
|
||||
assert_eq!(
|
||||
req_0.request,
|
||||
@@ -827,7 +827,7 @@ mod tests {
|
||||
assert_eq!(self.execution_helper.current_sequence_index().unwrap(), 0);
|
||||
assert_eq!(self.sender.requests.borrow().len(), 2);
|
||||
let req_0 = self.sender.requests.get_mut().pop_front().unwrap();
|
||||
assert_eq!(req_0.target_id, ExampleTargetId::Target0 as u64);
|
||||
assert_eq!(req_0.target_id, ExampleTargetId::Target0 as ComponentId);
|
||||
assert_eq!(req_0.request_id, expected_req_id);
|
||||
assert_eq!(
|
||||
req_0.request,
|
||||
@@ -837,7 +837,7 @@ mod tests {
|
||||
}
|
||||
);
|
||||
let req_1 = self.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
assert_eq!(req_1.target_id, ExampleTargetId::Target1 as u64);
|
||||
assert_eq!(req_1.target_id, ExampleTargetId::Target1 as ComponentId);
|
||||
assert_eq!(
|
||||
req_1.request,
|
||||
ModeRequest::SetMode {
|
||||
@@ -850,9 +850,9 @@ mod tests {
|
||||
|
||||
fn create_default_mode_store() -> ModeStoreVec {
|
||||
let mut mode_store = ModeStoreVec::default();
|
||||
mode_store.add_component(ExampleTargetId::Target0 as u64, UNKNOWN_MODE);
|
||||
mode_store.add_component(ExampleTargetId::Target1 as u64, UNKNOWN_MODE);
|
||||
mode_store.add_component(ExampleTargetId::Target2 as u64, UNKNOWN_MODE);
|
||||
mode_store.add_component(ExampleTargetId::Target0 as ComponentId, UNKNOWN_MODE);
|
||||
mode_store.add_component(ExampleTargetId::Target1 as ComponentId, UNKNOWN_MODE);
|
||||
mode_store.add_component(ExampleTargetId::Target2 as ComponentId, UNKNOWN_MODE);
|
||||
mode_store
|
||||
}
|
||||
|
||||
@@ -863,13 +863,13 @@ mod tests {
|
||||
let mut table_seq_0 = SequenceTableMapTable::new("MODE_0_SEQ_0");
|
||||
table_seq_0.add_entry(SequenceTableEntry::new(
|
||||
"TARGET_0",
|
||||
ExampleTargetId::Target0 as u64,
|
||||
ExampleTargetId::Target0 as ComponentId,
|
||||
SUBSYSTEM_MD0_TGT0_MODE,
|
||||
false,
|
||||
));
|
||||
table_seq_0.add_entry(SequenceTableEntry::new(
|
||||
"TARGET_1",
|
||||
ExampleTargetId::Target1 as u64,
|
||||
ExampleTargetId::Target1 as ComponentId,
|
||||
SUBSYSTEM_MD0_TGT1_MODE,
|
||||
false,
|
||||
));
|
||||
@@ -881,13 +881,13 @@ mod tests {
|
||||
let mut table_seq_0 = SequenceTableMapTable::new("MODE_1_SEQ_0");
|
||||
table_seq_0.add_entry(SequenceTableEntry::new(
|
||||
"MD1_SEQ0_TGT0",
|
||||
ExampleTargetId::Target0 as u64,
|
||||
ExampleTargetId::Target0 as ComponentId,
|
||||
SUBSYSTEM_MD1_ST0_TGT0_MODE,
|
||||
false,
|
||||
));
|
||||
table_seq_0.add_entry(SequenceTableEntry::new(
|
||||
"MD1_SEQ0_TGT1",
|
||||
ExampleTargetId::Target1 as u64,
|
||||
ExampleTargetId::Target1 as ComponentId,
|
||||
SUBSYSTEM_MD1_ST0_TGT1_MODE,
|
||||
false,
|
||||
));
|
||||
@@ -895,7 +895,7 @@ mod tests {
|
||||
let mut table_seq_1 = SequenceTableMapTable::new("MODE_1_SEQ_1");
|
||||
table_seq_1.add_entry(SequenceTableEntry::new(
|
||||
"MD1_SEQ1_TGT2",
|
||||
ExampleTargetId::Target2 as u64,
|
||||
ExampleTargetId::Target2 as ComponentId,
|
||||
SUBSYSTEM_MD1_ST1_TGT2_MODE,
|
||||
false,
|
||||
));
|
||||
@@ -1263,11 +1263,11 @@ mod tests {
|
||||
assert_eq!(req.request, ModeRequest::AnnounceModeRecursive);
|
||||
};
|
||||
let req0 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req0, ExampleTargetId::Target0 as u64);
|
||||
check_req(req0, ExampleTargetId::Target0 as ComponentId);
|
||||
let req1 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req1, ExampleTargetId::Target1 as u64);
|
||||
check_req(req1, ExampleTargetId::Target1 as ComponentId);
|
||||
let req2 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req2, ExampleTargetId::Target2 as u64);
|
||||
check_req(req2, ExampleTargetId::Target2 as ComponentId);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1283,11 +1283,11 @@ mod tests {
|
||||
assert_eq!(req.request, ModeRequest::AnnounceMode);
|
||||
};
|
||||
let req0 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req0, ExampleTargetId::Target0 as u64);
|
||||
check_req(req0, ExampleTargetId::Target0 as ComponentId);
|
||||
let req1 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req1, ExampleTargetId::Target1 as u64);
|
||||
check_req(req1, ExampleTargetId::Target1 as ComponentId);
|
||||
let req2 = tb.sender.requests.borrow_mut().pop_front().unwrap();
|
||||
check_req(req2, ExampleTargetId::Target2 as u64);
|
||||
check_req(req2, ExampleTargetId::Target2 as ComponentId);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -50,20 +50,20 @@ impl PacketInPool {
|
||||
|
||||
/// Generic trait for object which can send any packets in form of a raw bytestream, with
|
||||
/// no assumptions about the received protocol.
|
||||
pub trait PacketSenderRaw: Send {
|
||||
pub trait PacketHandler: Send {
|
||||
type Error;
|
||||
fn send_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error>;
|
||||
fn handle_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error>;
|
||||
}
|
||||
|
||||
/// Extension trait of [PacketSenderRaw] which allows downcasting by implementing [Downcast].
|
||||
/// Extension trait of [PacketHandler] which allows downcasting by implementing [Downcast].
|
||||
#[cfg(feature = "alloc")]
|
||||
pub trait PacketSenderRawExt: PacketSenderRaw + Downcast {
|
||||
pub trait PacketSenderRawExt: PacketHandler + Downcast {
|
||||
// Remove this once trait upcasting coercion has been implemented.
|
||||
// Tracking issue: https://github.com/rust-lang/rust/issues/65991
|
||||
fn upcast(&self) -> &dyn PacketSenderRaw<Error = Self::Error>;
|
||||
fn upcast(&self) -> &dyn PacketHandler<Error = Self::Error>;
|
||||
// Remove this once trait upcasting coercion has been implemented.
|
||||
// Tracking issue: https://github.com/rust-lang/rust/issues/65991
|
||||
fn upcast_mut(&mut self) -> &mut dyn PacketSenderRaw<Error = Self::Error>;
|
||||
fn upcast_mut(&mut self) -> &mut dyn PacketHandler<Error = Self::Error>;
|
||||
}
|
||||
|
||||
/// Blanket implementation to automatically implement [PacketSenderRawExt] when the [alloc]
|
||||
@@ -71,16 +71,16 @@ pub trait PacketSenderRawExt: PacketSenderRaw + Downcast {
|
||||
#[cfg(feature = "alloc")]
|
||||
impl<T> PacketSenderRawExt for T
|
||||
where
|
||||
T: PacketSenderRaw + Send + 'static,
|
||||
T: PacketHandler + Send + 'static,
|
||||
{
|
||||
// Remove this once trait upcasting coercion has been implemented.
|
||||
// Tracking issue: https://github.com/rust-lang/rust/issues/65991
|
||||
fn upcast(&self) -> &dyn PacketSenderRaw<Error = Self::Error> {
|
||||
fn upcast(&self) -> &dyn PacketHandler<Error = Self::Error> {
|
||||
self
|
||||
}
|
||||
// Remove this once trait upcasting coercion has been implemented.
|
||||
// Tracking issue: https://github.com/rust-lang/rust/issues/65991
|
||||
fn upcast_mut(&mut self) -> &mut dyn PacketSenderRaw<Error = Self::Error> {
|
||||
fn upcast_mut(&mut self) -> &mut dyn PacketHandler<Error = Self::Error> {
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -288,19 +288,19 @@ pub mod std_mod {
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketSenderRaw for mpsc::Sender<PacketAsVec> {
|
||||
impl PacketHandler for mpsc::Sender<PacketAsVec> {
|
||||
type Error = GenericSendError;
|
||||
|
||||
fn send_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> {
|
||||
fn handle_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> {
|
||||
self.send(PacketAsVec::new(sender_id, packet.to_vec()))
|
||||
.map_err(|_| GenericSendError::RxDisconnected)
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketSenderRaw for mpsc::SyncSender<PacketAsVec> {
|
||||
impl PacketHandler for mpsc::SyncSender<PacketAsVec> {
|
||||
type Error = GenericSendError;
|
||||
|
||||
fn send_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> {
|
||||
fn handle_packet(&self, sender_id: ComponentId, tc_raw: &[u8]) -> Result<(), Self::Error> {
|
||||
self.try_send(PacketAsVec::new(sender_id, tc_raw.to_vec()))
|
||||
.map_err(|e| match e {
|
||||
mpsc::TrySendError::Full(_) => GenericSendError::QueueFull(None),
|
||||
@@ -402,12 +402,12 @@ pub mod std_mod {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Sender: PacketInPoolSender, PacketStore: CcsdsPacketPool + Send> PacketSenderRaw
|
||||
impl<Sender: PacketInPoolSender, PacketStore: CcsdsPacketPool + Send> PacketHandler
|
||||
for PacketSenderWithSharedPool<Sender, PacketStore>
|
||||
{
|
||||
type Error = StoreAndSendError;
|
||||
|
||||
fn send_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> {
|
||||
fn handle_packet(&self, sender_id: ComponentId, packet: &[u8]) -> Result<(), Self::Error> {
|
||||
let mut shared_pool = self.shared_pool.borrow_mut();
|
||||
let store_addr = shared_pool.add_raw_tc(packet)?;
|
||||
drop(shared_pool);
|
||||
@@ -450,7 +450,7 @@ pub mod std_mod {
|
||||
_sp_header: &SpHeader,
|
||||
tc_raw: &[u8],
|
||||
) -> Result<(), Self::Error> {
|
||||
self.send_packet(sender_id, tc_raw)
|
||||
self.handle_packet(sender_id, tc_raw)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,10 +494,10 @@ pub(crate) mod tests {
|
||||
|
||||
pub(crate) fn send_with_sender<SendError>(
|
||||
sender_id: ComponentId,
|
||||
packet_sender: &(impl PacketSenderRaw<Error = SendError> + ?Sized),
|
||||
packet_sender: &(impl PacketHandler<Error = SendError> + ?Sized),
|
||||
packet: &[u8],
|
||||
) -> Result<(), SendError> {
|
||||
packet_sender.send_packet(sender_id, packet)
|
||||
packet_sender.handle_packet(sender_id, packet)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use arbitrary_int::{u11, u14};
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::CreatorConfig;
|
||||
use spacepackets::ecss::tm::{PusTmCreator, PusTmSecondaryHeader};
|
||||
use spacepackets::ecss::{CreatorConfig, MessageTypeId};
|
||||
use spacepackets::time::cds::CdsTime;
|
||||
|
||||
pub struct PusTmWithCdsShortHelper {
|
||||
@@ -50,7 +50,10 @@ impl PusTmWithCdsShortHelper {
|
||||
seq_count: u14,
|
||||
) -> PusTmCreator<'_, 'data> {
|
||||
let reply_header = SpHeader::new_for_unseg_tm(self.apid, seq_count, 0);
|
||||
let tc_header = PusTmSecondaryHeader::new_simple(service, subservice, &self.cds_short_buf);
|
||||
let tc_header = PusTmSecondaryHeader::new_simple(
|
||||
MessageTypeId::new(service, subservice),
|
||||
&self.cds_short_buf,
|
||||
);
|
||||
PusTmCreator::new(
|
||||
reply_header,
|
||||
tc_header,
|
||||
@@ -73,8 +76,8 @@ mod tests {
|
||||
let stamper = CdsTime::new_with_u16_days(0, 0);
|
||||
let tm =
|
||||
pus_tm_helper.create_pus_tm_with_stamper(17, 1, &[1, 2, 3, 4], &stamper, u14::new(25));
|
||||
assert_eq!(tm.service(), 17);
|
||||
assert_eq!(tm.subservice(), 1);
|
||||
assert_eq!(tm.service_type_id(), 17);
|
||||
assert_eq!(tm.message_subtype_id(), 1);
|
||||
assert_eq!(tm.user_data(), &[1, 2, 3, 4]);
|
||||
assert_eq!(tm.seq_count().value(), 25);
|
||||
assert_eq!(tm.timestamp(), [64, 0, 0, 0, 0, 0, 0])
|
||||
@@ -84,8 +87,8 @@ mod tests {
|
||||
fn test_helper_from_now() {
|
||||
let mut pus_tm_helper = PusTmWithCdsShortHelper::new(u11::new(0x123));
|
||||
let tm = pus_tm_helper.create_pus_tm_timestamp_now(17, 1, &[1, 2, 3, 4], u14::new(25));
|
||||
assert_eq!(tm.service(), 17);
|
||||
assert_eq!(tm.subservice(), 1);
|
||||
assert_eq!(tm.service_type_id(), 17);
|
||||
assert_eq!(tm.message_subtype_id(), 1);
|
||||
assert_eq!(tm.user_data(), &[1, 2, 3, 4]);
|
||||
assert_eq!(tm.seq_count().value(), 25);
|
||||
assert_eq!(tm.timestamp().len(), 7);
|
||||
|
||||
@@ -45,7 +45,7 @@ pub enum AcsMode {
|
||||
}
|
||||
|
||||
#[derive(Debug, TryFromPrimitive)]
|
||||
#[repr(u64)]
|
||||
#[repr(u32)]
|
||||
pub enum TestComponentId {
|
||||
MagnetometerDevice0 = 1,
|
||||
MagnetometerDevice1 = 2,
|
||||
@@ -299,7 +299,7 @@ struct AcsSubsystem {
|
||||
|
||||
impl AcsSubsystem {
|
||||
pub fn id() -> ComponentId {
|
||||
TestComponentId::AcsSubsystem as u64
|
||||
TestComponentId::AcsSubsystem as ComponentId
|
||||
}
|
||||
|
||||
pub fn new(mode_node: ModeRequestorAndHandlerMpscBounded) -> Self {
|
||||
@@ -518,7 +518,7 @@ struct MgmAssembly {
|
||||
|
||||
impl MgmAssembly {
|
||||
pub fn id() -> ComponentId {
|
||||
TestComponentId::MagnetometerAssembly as u64
|
||||
TestComponentId::MagnetometerAssembly as ComponentId
|
||||
}
|
||||
pub fn new(mode_node: ModeRequestorAndHandlerMpscBounded) -> Self {
|
||||
Self {
|
||||
@@ -923,7 +923,7 @@ impl ModeRequestHandler for CommonDevice {
|
||||
mode_and_submode: ModeAndSubmode,
|
||||
forced: bool,
|
||||
) -> Result<(), ModeError> {
|
||||
if self.id() == TestComponentId::MagnetorquerDevice as u64 {
|
||||
if self.id() == TestComponentId::MagnetorquerDevice as ComponentId {
|
||||
println!("test");
|
||||
}
|
||||
self.mode_and_submode = mode_and_submode;
|
||||
@@ -996,7 +996,7 @@ pub struct AcsController {
|
||||
|
||||
impl AcsController {
|
||||
pub fn id() -> ComponentId {
|
||||
TestComponentId::AcsController as u64
|
||||
TestComponentId::AcsController as ComponentId
|
||||
}
|
||||
pub fn new(mode_node: ModeRequestHandlerMpscBounded) -> Self {
|
||||
Self {
|
||||
@@ -1020,7 +1020,7 @@ impl AcsController {
|
||||
|
||||
impl ModeNode for AcsController {
|
||||
fn id(&self) -> ComponentId {
|
||||
TestComponentId::AcsController as u64
|
||||
TestComponentId::AcsController as ComponentId
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1185,22 +1185,22 @@ impl TreeTestbench {
|
||||
|
||||
let mut mgm_dev_0 = CommonDevice::new(
|
||||
"MGM_0",
|
||||
TestComponentId::MagnetometerDevice0 as u64,
|
||||
TestComponentId::MagnetometerDevice0 as ComponentId,
|
||||
mgm_dev_node_0,
|
||||
);
|
||||
let mut mgm_dev_1 = CommonDevice::new(
|
||||
"MGM_1",
|
||||
TestComponentId::MagnetometerDevice1 as u64,
|
||||
TestComponentId::MagnetometerDevice1 as ComponentId,
|
||||
mgm_dev_node_1,
|
||||
);
|
||||
let mut mgt_dev = CommonDevice::new(
|
||||
"MGT",
|
||||
TestComponentId::MagnetorquerDevice as u64,
|
||||
TestComponentId::MagnetorquerDevice as ComponentId,
|
||||
mgt_dev_node,
|
||||
);
|
||||
let mut mgt_manager = DeviceManager::new(
|
||||
"MGT_MANAGER",
|
||||
TestComponentId::MgtDevManager as u64,
|
||||
TestComponentId::MgtDevManager as ComponentId,
|
||||
mgt_dev_mgmt_node,
|
||||
);
|
||||
let mut mgm_assy = MgmAssembly::new(mgm_assy_node);
|
||||
@@ -1212,38 +1212,38 @@ impl TreeTestbench {
|
||||
let mut target_table_safe = TargetTablesMapValue::new("SAFE_TARGET_TBL", None);
|
||||
target_table_safe.add_entry(TargetTableEntry::new(
|
||||
"CTRL_SAFE",
|
||||
TestComponentId::AcsController as u64,
|
||||
TestComponentId::AcsController as ComponentId,
|
||||
ModeAndSubmode::new(AcsMode::SAFE as u32, 0),
|
||||
// All submodes allowed.
|
||||
Some(0xffff),
|
||||
));
|
||||
target_table_safe.add_entry(TargetTableEntry::new_with_precise_submode(
|
||||
"MGM_A_NML",
|
||||
TestComponentId::MagnetometerAssembly as u64,
|
||||
TestComponentId::MagnetometerAssembly as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||
));
|
||||
target_table_safe.add_entry(TargetTableEntry::new_with_precise_submode(
|
||||
"MGT_MAN_NML",
|
||||
TestComponentId::MgtDevManager as u64,
|
||||
TestComponentId::MgtDevManager as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||
));
|
||||
let mut sequence_tbl_safe_0 = SequenceTableMapTable::new("SAFE_SEQ_0_TBL");
|
||||
sequence_tbl_safe_0.add_entry(SequenceTableEntry::new(
|
||||
"SAFE_SEQ_0_MGM_A",
|
||||
TestComponentId::MagnetometerAssembly as u64,
|
||||
TestComponentId::MagnetometerAssembly as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as Mode, 0),
|
||||
false,
|
||||
));
|
||||
sequence_tbl_safe_0.add_entry(SequenceTableEntry::new(
|
||||
"SAFE_SEQ_0_MGT_MAN",
|
||||
TestComponentId::MgtDevManager as u64,
|
||||
TestComponentId::MgtDevManager as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as Mode, 0),
|
||||
false,
|
||||
));
|
||||
let mut sequence_tbl_safe_1 = SequenceTableMapTable::new("SAFE_SEQ_1_TBL");
|
||||
sequence_tbl_safe_1.add_entry(SequenceTableEntry::new(
|
||||
"SAFE_SEQ_1_ACS_CTRL",
|
||||
TestComponentId::AcsController as u64,
|
||||
TestComponentId::AcsController as ComponentId,
|
||||
ModeAndSubmode::new(AcsMode::SAFE as Mode, 0),
|
||||
false,
|
||||
));
|
||||
@@ -1408,7 +1408,7 @@ fn announce_recursively() {
|
||||
fn generic_mode_reply_checker(
|
||||
reply_meta: MessageMetadata,
|
||||
mode_and_submode: ModeAndSubmode,
|
||||
expected_modes: &mut HashMap<u64, ModeAndSubmode>,
|
||||
expected_modes: &mut HashMap<ComponentId, ModeAndSubmode>,
|
||||
) {
|
||||
let id = TestComponentId::try_from(reply_meta.sender_id()).expect("invalid sender id");
|
||||
if !expected_modes.contains_key(&reply_meta.sender_id()) {
|
||||
@@ -1528,15 +1528,15 @@ fn command_safe_mode() {
|
||||
);
|
||||
let mut expected_modes = HashMap::new();
|
||||
expected_modes.insert(
|
||||
TestComponentId::AcsController as u64,
|
||||
TestComponentId::AcsController as ComponentId,
|
||||
ModeAndSubmode::new(AcsMode::SAFE as u32, 0),
|
||||
);
|
||||
expected_modes.insert(
|
||||
TestComponentId::MagnetometerAssembly as u64,
|
||||
TestComponentId::MagnetometerAssembly as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||
);
|
||||
expected_modes.insert(
|
||||
TestComponentId::MgtDevManager as u64,
|
||||
TestComponentId::MgtDevManager as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||
);
|
||||
while let Some(reply) = tb.subsystem.mode_reply_mock.mode_reply_messages.pop_front() {
|
||||
@@ -1558,11 +1558,11 @@ fn command_safe_mode() {
|
||||
);
|
||||
let mut expected_modes = HashMap::new();
|
||||
expected_modes.insert(
|
||||
TestComponentId::MagnetometerDevice0 as u64,
|
||||
TestComponentId::MagnetometerDevice0 as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||
);
|
||||
expected_modes.insert(
|
||||
TestComponentId::MagnetometerDevice1 as u64,
|
||||
TestComponentId::MagnetometerDevice1 as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||
);
|
||||
while let Some(reply) = tb.mgm_assy.mode_reply_mock.mode_reply_messages.pop_front() {
|
||||
@@ -1578,7 +1578,7 @@ fn command_safe_mode() {
|
||||
);
|
||||
let mut expected_modes = HashMap::new();
|
||||
expected_modes.insert(
|
||||
TestComponentId::MagnetorquerDevice as u64,
|
||||
TestComponentId::MagnetorquerDevice as ComponentId,
|
||||
ModeAndSubmode::new(DefaultMode::NORMAL as u32, 0),
|
||||
);
|
||||
let reply = tb
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use arbitrary_int::u11;
|
||||
use arbitrary_int::{u11, u21};
|
||||
use satrs::event_man_legacy::{
|
||||
EventManagerWithMpsc, EventMessage, EventMessageU32, EventRoutingError, EventSendProvider,
|
||||
EventU32SenderMpsc,
|
||||
@@ -18,7 +18,7 @@ const INFO_EVENT: EventU32TypedSev<SeverityInfo> = EventU32TypedSev::<SeverityIn
|
||||
const LOW_SEV_EVENT: EventU32 = EventU32::new(Severity::Low, 1, 5);
|
||||
const EMPTY_STAMP: [u8; 7] = [0; 7];
|
||||
const TEST_APID: u11 = u11::new(0x02);
|
||||
const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, 0x05);
|
||||
const TEST_ID: UniqueApidTargetId = UniqueApidTargetId::new(TEST_APID, u21::new(0x05));
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum CustomTmSenderError {
|
||||
@@ -107,8 +107,8 @@ fn test_threaded_usage() {
|
||||
Ok(event_tm) => {
|
||||
let tm = PusTmReader::new(event_tm.packet.as_slice(), 7)
|
||||
.expect("Deserializing TM failed");
|
||||
assert_eq!(tm.service(), 5);
|
||||
assert_eq!(tm.subservice(), 1);
|
||||
assert_eq!(tm.service_type_id(), 5);
|
||||
assert_eq!(tm.message_subtype_id(), 1);
|
||||
let src_data = tm.source_data();
|
||||
assert!(!src_data.is_empty());
|
||||
assert_eq!(src_data.len(), 4);
|
||||
@@ -137,8 +137,8 @@ fn test_threaded_usage() {
|
||||
Ok(event_tm) => {
|
||||
let tm = PusTmReader::new(event_tm.packet.as_slice(), 7)
|
||||
.expect("Deserializing TM failed");
|
||||
assert_eq!(tm.service(), 5);
|
||||
assert_eq!(tm.subservice(), 2);
|
||||
assert_eq!(tm.service_type_id(), 5);
|
||||
assert_eq!(tm.message_subtype_id(), 2);
|
||||
let src_data = tm.source_data();
|
||||
assert!(!src_data.is_empty());
|
||||
assert_eq!(src_data.len(), 12);
|
||||
|
||||
@@ -13,7 +13,9 @@ pub mod crossbeam_test {
|
||||
use spacepackets::SpHeader;
|
||||
use spacepackets::ecss::tc::{PusTcCreator, PusTcReader, PusTcSecondaryHeader};
|
||||
use spacepackets::ecss::tm::PusTmReader;
|
||||
use spacepackets::ecss::{CreatorConfig, EcssEnumU8, EcssEnumU16, WritablePusPacket};
|
||||
use spacepackets::ecss::{
|
||||
CreatorConfig, EcssEnumU8, EcssEnumU16, MessageTypeId, WritablePusPacket,
|
||||
};
|
||||
use std::sync::RwLock;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
@@ -60,7 +62,7 @@ pub mod crossbeam_test {
|
||||
{
|
||||
let mut tc_guard = shared_tc_pool.write().unwrap();
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, u14::ZERO, 0);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(17, 1);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(17, 1));
|
||||
let pus_tc_0 = PusTcCreator::new_no_app_data(sph, tc_header, CreatorConfig::default());
|
||||
req_id_0 = RequestId::new(&pus_tc_0);
|
||||
let addr = tc_guard
|
||||
@@ -70,7 +72,7 @@ pub mod crossbeam_test {
|
||||
.unwrap();
|
||||
tx_tc_0.send(addr).unwrap();
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID, u14::new(1), 0);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(5, 1);
|
||||
let tc_header = PusTcSecondaryHeader::new_simple(MessageTypeId::new(5, 1));
|
||||
let pus_tc_1 = PusTcCreator::new_no_app_data(sph, tc_header, CreatorConfig::default());
|
||||
req_id_1 = RequestId::new(&pus_tc_1);
|
||||
let addr = tc_guard
|
||||
@@ -164,11 +166,11 @@ pub mod crossbeam_test {
|
||||
RequestId::from_bytes(&pus_tm.source_data()[0..RequestId::SIZE_AS_BYTES])
|
||||
.expect("reading request ID from PUS TM source data failed");
|
||||
if !verif_map.contains_key(&req_id) {
|
||||
let content = vec![pus_tm.subservice()];
|
||||
let content = vec![pus_tm.service_type_id()];
|
||||
verif_map.insert(req_id, content);
|
||||
} else {
|
||||
let content = verif_map.get_mut(&req_id).unwrap();
|
||||
content.push(pus_tm.subservice())
|
||||
content.push(pus_tm.message_subtype_id())
|
||||
}
|
||||
packet_counter += 1;
|
||||
}
|
||||
|
||||
@@ -29,15 +29,18 @@ use satrs::{
|
||||
ccsds::{SpValidity, SpacePacketValidator},
|
||||
cobs::encode_packet_with_cobs,
|
||||
},
|
||||
hal::std::tcp_server::{
|
||||
ConnectionResult, HandledConnectionHandler, HandledConnectionInfo, ServerConfig,
|
||||
TcpSpacepacketsServer, TcpTmtcInCobsServer,
|
||||
hal::std::{
|
||||
tcp_server::{
|
||||
CobsTcParser, ConnectionResult, HandledConnectionHandler, HandledConnectionInfo,
|
||||
ServerConfig, TcpSpacepacketsServer, TcpTmtcInCobsServer,
|
||||
},
|
||||
tcp_spacepackets_server::CcsdsPacketParser,
|
||||
},
|
||||
tmtc::PacketSource,
|
||||
};
|
||||
use spacepackets::{
|
||||
CcsdsPacket, PacketId, SpHeader,
|
||||
ecss::{CreatorConfig, WritablePusPacket, tc::PusTcCreator},
|
||||
ecss::{CreatorConfig, MessageTypeId, WritablePusPacket, tc::PusTcCreator},
|
||||
};
|
||||
use std::{collections::VecDeque, sync::Arc, vec::Vec};
|
||||
|
||||
@@ -121,7 +124,7 @@ fn test_cobs_server() {
|
||||
1024,
|
||||
),
|
||||
tm_source,
|
||||
tc_sender.clone(),
|
||||
CobsTcParser::new(TCP_SERVER_ID, 1024, tc_sender.clone()),
|
||||
ConnectionFinishedHandler::default(),
|
||||
None,
|
||||
)
|
||||
@@ -219,7 +222,8 @@ fn test_ccsds_server() {
|
||||
let (tc_sender, tc_receiver) = mpsc::channel();
|
||||
let mut tm_source = SyncTmSource::default();
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, u14::new(0), 0);
|
||||
let verif_tm = PusTcCreator::new_simple(sph, 1, 1, &[], CreatorConfig::default());
|
||||
let verif_tm =
|
||||
PusTcCreator::new_simple(sph, MessageTypeId::new(1, 1), &[], CreatorConfig::default());
|
||||
let tm_0 = verif_tm.to_vec().expect("tm generation failed");
|
||||
tm_source.add_tm(&tm_0);
|
||||
let mut packet_id_lookup = SimpleVerificator::default();
|
||||
@@ -233,8 +237,7 @@ fn test_ccsds_server() {
|
||||
1024,
|
||||
),
|
||||
tm_source,
|
||||
tc_sender,
|
||||
packet_id_lookup,
|
||||
CcsdsPacketParser::new(TCP_SERVER_ID, 1024, tc_sender, packet_id_lookup),
|
||||
ConnectionFinishedHandler::default(),
|
||||
None,
|
||||
)
|
||||
@@ -269,7 +272,12 @@ fn test_ccsds_server() {
|
||||
|
||||
// Send ping telecommand.
|
||||
let sph = SpHeader::new_for_unseg_tc(TEST_APID_0, u14::new(0), 0);
|
||||
let ping_tc = PusTcCreator::new_simple(sph, 17, 1, &[], CreatorConfig::default());
|
||||
let ping_tc = PusTcCreator::new_simple(
|
||||
sph,
|
||||
MessageTypeId::new(17, 1),
|
||||
&[],
|
||||
CreatorConfig::default(),
|
||||
);
|
||||
let tc_0 = ping_tc.to_vec().expect("packet creation failed");
|
||||
stream
|
||||
.write_all(&tc_0)
|
||||
|
||||
Reference in New Issue
Block a user