that gets the job done
Some checks failed
Rust/sat-rs/pipeline/pr-main There was a failure building this commit

This commit is contained in:
Robin Müller 2024-04-03 18:04:32 +02:00
parent 68908f53d4
commit cba4a29396
Signed by: muellerr
GPG Key ID: A649FB78196E3849
12 changed files with 290 additions and 174 deletions

View File

@ -17,6 +17,8 @@ zerocopy = "0.6"
csv = "1" csv = "1"
num_enum = "0.7" num_enum = "0.7"
thiserror = "1" thiserror = "1"
lazy_static = "1"
strum = { version = "0.26", features = ["derive"] }
derive-new = "0.5" derive-new = "0.5"
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"

View File

@ -36,8 +36,15 @@ class EventU32:
) )
class RequestTargetId(enum.IntEnum): class Apid(enum.IntEnum):
ACS = 1 SCHED = 1
GENERIC_PUS = 2
ACS = 3
CFDP = 4
class AcsId(enum.IntEnum):
MGM_0 = 0
class AcsHkIds(enum.IntEnum): class AcsHkIds(enum.IntEnum):

View File

@ -1,23 +1,35 @@
import datetime import datetime
import struct
import logging import logging
from spacepackets.ccsds import CdsShortTimestamp from spacepackets.ccsds import CdsShortTimestamp
from spacepackets.ecss import PusTelecommand from spacepackets.ecss import PusTelecommand
from tmtccmd.config import CmdTreeNode from tmtccmd.config import CmdTreeNode
from tmtccmd.pus.tc.s200_fsfw_mode import Mode
from tmtccmd.tmtc import DefaultPusQueueHelper from tmtccmd.tmtc import DefaultPusQueueHelper
from tmtccmd.pus.s11_tc_sched import create_time_tagged_cmd from tmtccmd.pus.s11_tc_sched import create_time_tagged_cmd
from tmtccmd.pus.tc.s3_fsfw_hk import create_request_one_hk_command from tmtccmd.pus.s200_fsfw_mode import Subservice as ModeSubservice
from common import ( from common import EXAMPLE_PUS_APID, AcsId, Apid
EXAMPLE_PUS_APID,
make_addressable_id,
RequestTargetId,
AcsHkIds,
)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
def create_set_mode_cmd(
apid: int, unique_id: int, mode: int, submode: int
) -> PusTelecommand:
app_data = bytearray()
app_data.extend(struct.pack("!I", unique_id))
app_data.extend(struct.pack("!I", mode))
app_data.extend(struct.pack("!H", submode))
return PusTelecommand(
service=200,
subservice=ModeSubservice.TC_MODE_COMMAND,
apid=apid,
app_data=app_data,
)
def create_cmd_definition_tree() -> CmdTreeNode: def create_cmd_definition_tree() -> CmdTreeNode:
root_node = CmdTreeNode.root_node() root_node = CmdTreeNode.root_node()
@ -95,12 +107,33 @@ def pack_pus_telecommands(q: DefaultPusQueueHelper, cmd_path: str):
) )
if cmd_path_list[0] == "acs": if cmd_path_list[0] == "acs":
assert len(cmd_path_list) >= 2 assert len(cmd_path_list) >= 2
if cmd_path_list[1] == "mgm": if cmd_path_list[1] == "mgms":
assert len(cmd_path_list) >= 3 assert len(cmd_path_list) >= 3
if cmd_path_list[2] == "one_shot_hk": if cmd_path_list[2] == "hk":
if cmd_path_list[3] == "one_shot_hk":
q.add_log_cmd("Sending HK one shot request") q.add_log_cmd("Sending HK one shot request")
q.add_pus_tc( # TODO: Fix
create_request_one_hk_command( # q.add_pus_tc(
make_addressable_id(RequestTargetId.ACS, AcsHkIds.MGM_SET) # create_request_one_hk_command(
) # make_addressable_id(Apid.ACS, AcsId.MGM_SET)
# )
# )
if cmd_path_list[2] == "mode":
if cmd_path_list[3] == "set_mode":
handle_set_mode_cmd(
q, "MGM 0", cmd_path_list[4], Apid.ACS, AcsId.MGM_0
) )
def handle_set_mode_cmd(
q: DefaultPusQueueHelper, target_str: str, mode_str: str, apid: int, unique_id: int
):
if mode_str == "off":
q.add_log_cmd(f"Sending Mode OFF to {target_str}")
q.add_pus_tc(create_set_mode_cmd(apid, unique_id, Mode.OFF, 0))
elif mode_str == "on":
q.add_log_cmd(f"Sending Mode ON to {target_str}")
q.add_pus_tc(create_set_mode_cmd(apid, unique_id, Mode.ON, 0))
elif mode_str == "normal":
q.add_log_cmd(f"Sending Mode NORMAL to {target_str}")
q.add_pus_tc(create_set_mode_cmd(apid, unique_id, Mode.NORMAL, 0))

View File

@ -1,7 +1,9 @@
use satrs::encoding::ccsds::PacketIdValidator;
use satrs::pus::ReceivesEcssPusTc; use satrs::pus::ReceivesEcssPusTc;
use satrs::spacepackets::{CcsdsPacket, SpHeader}; use satrs::spacepackets::{CcsdsPacket, PacketId, SpHeader};
use satrs::tmtc::{CcsdsPacketHandler, ReceivesCcsdsTc}; use satrs::tmtc::{CcsdsPacketHandler, ReceivesCcsdsTc};
use satrs_example::config::components::Apid; use satrs_example::config::components::Apid;
use satrs_example::config::PACKET_ID_VALIDATOR;
#[derive(Clone)] #[derive(Clone)]
pub struct CcsdsReceiver< pub struct CcsdsReceiver<
@ -11,6 +13,16 @@ pub struct CcsdsReceiver<
pub tc_source: TcSource, pub tc_source: TcSource,
} }
impl<
TcSource: ReceivesCcsdsTc<Error = E> + ReceivesEcssPusTc<Error = E> + Clone + 'static,
E: 'static,
> PacketIdValidator for CcsdsReceiver<TcSource, E>
{
fn validate(&self, packet_id: u16) -> bool {
PACKET_ID_VALIDATOR.contains(&PacketId::from(packet_id))
}
}
impl< impl<
TcSource: ReceivesCcsdsTc<Error = E> + ReceivesEcssPusTc<Error = E> + Clone + 'static, TcSource: ReceivesCcsdsTc<Error = E> + ReceivesEcssPusTc<Error = E> + Clone + 'static,
E: 'static, E: 'static,
@ -18,16 +30,7 @@ impl<
{ {
type Error = E; type Error = E;
fn valid_apids(&self) -> &'static [u16] { fn handle_packet_with_valid_apid(
&[
Apid::GenericPus as u16,
Apid::Acs as u16,
Apid::Sched as u16,
Apid::EventTm as u16,
]
}
fn handle_known_apid(
&mut self, &mut self,
sp_header: &SpHeader, sp_header: &SpHeader,
tc_raw: &[u8], tc_raw: &[u8],
@ -39,7 +42,7 @@ impl<
Ok(()) Ok(())
} }
fn handle_unknown_apid( fn handle_packet_with_unknown_apid(
&mut self, &mut self,
sp_header: &SpHeader, sp_header: &SpHeader,
_tc_raw: &[u8], _tc_raw: &[u8],

View File

@ -1,7 +1,12 @@
use satrs::res_code::ResultU16; use lazy_static::lazy_static;
use satrs::{
res_code::ResultU16,
spacepackets::{PacketId, PacketType},
};
use satrs_mib::res_code::ResultU16Info; use satrs_mib::res_code::ResultU16Info;
use satrs_mib::resultcode; use satrs_mib::resultcode;
use std::net::Ipv4Addr; use std::{collections::HashSet, net::Ipv4Addr};
use strum::IntoEnumIterator;
use num_enum::{IntoPrimitive, TryFromPrimitive}; use num_enum::{IntoPrimitive, TryFromPrimitive};
use satrs::{ use satrs::{
@ -36,6 +41,16 @@ pub const SERVER_PORT: u16 = 7301;
pub const TEST_EVENT: EventU32TypedSev<SeverityInfo> = pub const TEST_EVENT: EventU32TypedSev<SeverityInfo> =
EventU32TypedSev::<SeverityInfo>::const_new(0, 0); EventU32TypedSev::<SeverityInfo>::const_new(0, 0);
lazy_static! {
pub static ref PACKET_ID_VALIDATOR: HashSet<PacketId> = {
let mut set = HashSet::new();
for id in components::Apid::iter() {
set.insert(PacketId::const_new(PacketType::Tc, true, id as u16));
}
set
};
}
pub mod tmtc_err { pub mod tmtc_err {
use super::*; use super::*;
@ -102,26 +117,25 @@ pub mod mode_err {
pub mod components { pub mod components {
use satrs::request::UniqueApidTargetId; use satrs::request::UniqueApidTargetId;
use strum::EnumIter;
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq, EnumIter)]
pub enum Apid { pub enum Apid {
VerificationTm = 1, Sched = 1,
Sched = 2, GenericPus = 2,
EventTm = 3, Acs = 3,
HkTm = 4, Cfdp = 4,
GenericPus = 5,
Acs = 6,
Cfdp = 7,
} }
// Component IDs for components with the PUS APID. // Component IDs for components with the PUS APID.
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub enum PusId { pub enum PusId {
PusRouting = 0, PusEventManagement = 0,
PusTest = 1, PusRouting = 1,
PusAction = 2, PusTest = 2,
PusMode = 3, PusAction = 3,
PusHk = 4, PusMode = 4,
PusHk = 5,
} }
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
@ -132,7 +146,7 @@ pub mod components {
pub const PUS_ACTION_SERVICE: UniqueApidTargetId = pub const PUS_ACTION_SERVICE: UniqueApidTargetId =
UniqueApidTargetId::new(Apid::GenericPus as u16, PusId::PusAction as u32); UniqueApidTargetId::new(Apid::GenericPus as u16, PusId::PusAction as u32);
pub const PUS_EVENT_MANAGEMENT: UniqueApidTargetId = pub const PUS_EVENT_MANAGEMENT: UniqueApidTargetId =
UniqueApidTargetId::new(Apid::EventTm as u16, 0); UniqueApidTargetId::new(Apid::GenericPus as u16, 0);
pub const PUS_ROUTING_SERVICE: UniqueApidTargetId = pub const PUS_ROUTING_SERVICE: UniqueApidTargetId =
UniqueApidTargetId::new(Apid::GenericPus as u16, PusId::PusRouting as u32); UniqueApidTargetId::new(Apid::GenericPus as u16, PusId::PusRouting as u32);
pub const PUS_TEST_SERVICE: UniqueApidTargetId = pub const PUS_TEST_SERVICE: UniqueApidTargetId =

View File

@ -3,8 +3,10 @@ use std::sync::mpsc::{self};
use crate::pus::create_verification_reporter; use crate::pus::create_verification_reporter;
use satrs::event_man::{EventMessageU32, EventRoutingError}; use satrs::event_man::{EventMessageU32, EventRoutingError};
use satrs::params::WritableToBeBytes; use satrs::params::WritableToBeBytes;
use satrs::pus::event::EventTmHookProvider;
use satrs::pus::verification::VerificationReporter; use satrs::pus::verification::VerificationReporter;
use satrs::pus::EcssTmSenderCore; use satrs::pus::EcssTmSenderCore;
use satrs::request::UniqueApidTargetId;
use satrs::{ use satrs::{
event_man::{ event_man::{
EventManagerWithBoundedMpsc, EventSendProvider, EventU32SenderMpscBounded, EventManagerWithBoundedMpsc, EventSendProvider, EventU32SenderMpscBounded,
@ -18,11 +20,22 @@ use satrs::{
}, },
spacepackets::time::cds::CdsTime, spacepackets::time::cds::CdsTime,
}; };
use satrs_example::config::components;
use satrs_example::config::components::PUS_EVENT_MANAGEMENT; use satrs_example::config::components::PUS_EVENT_MANAGEMENT;
use crate::update_time; use crate::update_time;
// This helper sets the APID of the event sender for the PUS telemetry.
#[derive(Default)]
pub struct EventApidSetter {
pub next_apid: u16,
}
impl EventTmHookProvider for EventApidSetter {
fn modify_tm(&self, tm: &mut satrs::spacepackets::ecss::tm::PusTmCreator) {
tm.set_apid(self.next_apid);
}
}
/// The PUS event handler subscribes for all events and converts them into ECSS PUS 5 event /// The PUS event handler subscribes for all events and converts them into ECSS PUS 5 event
/// packets. It also handles the verification completion of PUS event service requests. /// packets. It also handles the verification completion of PUS event service requests.
pub struct PusEventHandler<TmSender: EcssTmSenderCore> { pub struct PusEventHandler<TmSender: EcssTmSenderCore> {
@ -33,6 +46,7 @@ pub struct PusEventHandler<TmSender: EcssTmSenderCore> {
time_provider: CdsTime, time_provider: CdsTime,
timestamp: [u8; 7], timestamp: [u8; 7],
verif_handler: VerificationReporter, verif_handler: VerificationReporter,
event_apid_setter: EventApidSetter,
} }
impl<TmSender: EcssTmSenderCore> PusEventHandler<TmSender> { impl<TmSender: EcssTmSenderCore> PusEventHandler<TmSender> {
@ -47,12 +61,7 @@ impl<TmSender: EcssTmSenderCore> PusEventHandler<TmSender> {
// All events sent to the manager are routed to the PUS event manager, which generates PUS event // All events sent to the manager are routed to the PUS event manager, which generates PUS event
// telemetry for each event. // telemetry for each event.
let event_reporter = EventReporter::new( let event_reporter = EventReporter::new(PUS_EVENT_MANAGEMENT.raw(), 0, 0, 128).unwrap();
PUS_EVENT_MANAGEMENT.raw(),
components::Apid::EventTm as u16,
128,
)
.unwrap();
let pus_event_dispatcher = let pus_event_dispatcher =
DefaultPusEventU32Dispatcher::new_with_default_backend(event_reporter); DefaultPusEventU32Dispatcher::new_with_default_backend(event_reporter);
let pus_event_man_send_provider = EventU32SenderMpscBounded::new( let pus_event_man_send_provider = EventU32SenderMpscBounded::new(
@ -72,6 +81,7 @@ impl<TmSender: EcssTmSenderCore> PusEventHandler<TmSender> {
timestamp: [0; 7], timestamp: [0; 7],
verif_handler, verif_handler,
tm_sender, tm_sender,
event_apid_setter: EventApidSetter::default(),
} }
} }
@ -113,6 +123,7 @@ impl<TmSender: EcssTmSenderCore> PusEventHandler<TmSender> {
let param_vec = event_msg.params().map_or(Vec::new(), |param| { let param_vec = event_msg.params().map_or(Vec::new(), |param| {
param.to_vec().expect("failed to convert params to vec") param.to_vec().expect("failed to convert params to vec")
}); });
self.event_apid_setter.next_apid = UniqueApidTargetId::from(event_msg.sender_id()).apid;
self.pus_event_dispatcher self.pus_event_dispatcher
.generate_pus_event_tm_generic( .generate_pus_event_tm_generic(
&self.tm_sender, &self.tm_sender,

View File

@ -23,7 +23,7 @@ use satrs_example::config::pool::{create_sched_tc_pool, create_static_pools};
use satrs_example::config::tasks::{ use satrs_example::config::tasks::{
FREQ_MS_AOCS, FREQ_MS_EVENT_HANDLING, FREQ_MS_PUS_STACK, FREQ_MS_UDP_TMTC, FREQ_MS_AOCS, FREQ_MS_EVENT_HANDLING, FREQ_MS_PUS_STACK, FREQ_MS_UDP_TMTC,
}; };
use satrs_example::config::{OBSW_SERVER_ADDR, SERVER_PORT}; use satrs_example::config::{OBSW_SERVER_ADDR, PACKET_ID_VALIDATOR, SERVER_PORT};
use tmtc::PusTcSourceProviderDynamic; use tmtc::PusTcSourceProviderDynamic;
use udp::DynamicUdpTmHandler; use udp::DynamicUdpTmHandler;
@ -191,6 +191,7 @@ fn static_tmtc_pool_main() {
tcp_server_cfg, tcp_server_cfg,
sync_tm_tcp_source.clone(), sync_tm_tcp_source.clone(),
tcp_ccsds_distributor, tcp_ccsds_distributor,
PACKET_ID_VALIDATOR.clone(),
) )
.expect("tcp server creation failed"); .expect("tcp server creation failed");
@ -415,6 +416,7 @@ fn dyn_tmtc_pool_main() {
tcp_server_cfg, tcp_server_cfg,
sync_tm_tcp_source.clone(), sync_tm_tcp_source.clone(),
tcp_ccsds_distributor, tcp_ccsds_distributor,
PACKET_ID_VALIDATOR.clone(),
) )
.expect("tcp server creation failed"); .expect("tcp server creation failed");

View File

@ -1,5 +1,5 @@
use std::{ use std::{
collections::VecDeque, collections::{HashSet, VecDeque},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
@ -10,17 +10,9 @@ use satrs::{
spacepackets::PacketId, spacepackets::PacketId,
tmtc::{CcsdsDistributor, CcsdsError, ReceivesCcsdsTc, TmPacketSourceCore}, tmtc::{CcsdsDistributor, CcsdsError, ReceivesCcsdsTc, TmPacketSourceCore},
}; };
use satrs_example::config::components;
use crate::ccsds::CcsdsReceiver; use crate::ccsds::CcsdsReceiver;
pub const PACKET_ID_LOOKUP: &[PacketId] = &[
PacketId::const_tc(true, components::Apid::GenericPus as u16),
PacketId::const_tc(true, components::Apid::EventTm as u16),
PacketId::const_tc(true, components::Apid::Acs as u16),
PacketId::const_tc(true, components::Apid::Sched as u16),
];
#[derive(Default, Clone)] #[derive(Default, Clone)]
pub struct SyncTcpTmSource { pub struct SyncTcpTmSource {
tm_queue: Arc<Mutex<VecDeque<Vec<u8>>>>, tm_queue: Arc<Mutex<VecDeque<Vec<u8>>>>,
@ -82,6 +74,7 @@ pub type TcpServerType<TcSource, MpscErrorType> = TcpSpacepacketsServer<
CcsdsError<MpscErrorType>, CcsdsError<MpscErrorType>,
SyncTcpTmSource, SyncTcpTmSource,
CcsdsDistributor<CcsdsReceiver<TcSource, MpscErrorType>, MpscErrorType>, CcsdsDistributor<CcsdsReceiver<TcSource, MpscErrorType>, MpscErrorType>,
HashSet<PacketId>,
>; >;
pub struct TcpTask< pub struct TcpTask<
@ -108,14 +101,10 @@ impl<
cfg: ServerConfig, cfg: ServerConfig,
tm_source: SyncTcpTmSource, tm_source: SyncTcpTmSource,
tc_receiver: CcsdsDistributor<CcsdsReceiver<TcSource, MpscErrorType>, MpscErrorType>, tc_receiver: CcsdsDistributor<CcsdsReceiver<TcSource, MpscErrorType>, MpscErrorType>,
packet_id_lookup: HashSet<PacketId>,
) -> Result<Self, std::io::Error> { ) -> Result<Self, std::io::Error> {
Ok(Self { Ok(Self {
server: TcpSpacepacketsServer::new( server: TcpSpacepacketsServer::new(cfg, tm_source, tc_receiver, packet_id_lookup)?,
cfg,
tm_source,
tc_receiver,
Box::new(PACKET_ID_LOOKUP),
)?,
}) })
} }

View File

@ -2,60 +2,71 @@
use alloc::vec::Vec; use alloc::vec::Vec;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
use hashbrown::HashSet; use hashbrown::HashSet;
#[cfg(feature = "std")]
use std::collections::HashSet as StdHashSet;
use spacepackets::PacketId; use spacepackets::PacketId;
use crate::tmtc::ReceivesTcCore; use crate::tmtc::ReceivesTcCore;
pub trait PacketIdLookup { pub trait PacketIdValidator {
fn validate(&self, packet_id: u16) -> bool; fn validate(&self, packet_id: u16) -> bool;
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl PacketIdLookup for Vec<u16> { impl PacketIdValidator for Vec<u16> {
fn validate(&self, packet_id: u16) -> bool { fn validate(&self, packet_id: u16) -> bool {
self.contains(&packet_id) self.contains(&packet_id)
} }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl PacketIdLookup for HashSet<u16> { impl PacketIdValidator for HashSet<u16> {
fn validate(&self, packet_id: u16) -> bool { fn validate(&self, packet_id: u16) -> bool {
self.contains(&packet_id) self.contains(&packet_id)
} }
} }
impl PacketIdLookup for [u16] { impl PacketIdValidator for [u16] {
fn validate(&self, packet_id: u16) -> bool { fn validate(&self, packet_id: u16) -> bool {
self.binary_search(&packet_id).is_ok() self.binary_search(&packet_id).is_ok()
} }
} }
impl PacketIdLookup for &[u16] { impl PacketIdValidator for &[u16] {
fn validate(&self, packet_id: u16) -> bool { fn validate(&self, packet_id: u16) -> bool {
self.binary_search(&packet_id).is_ok() self.binary_search(&packet_id).is_ok()
} }
} }
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
impl PacketIdLookup for Vec<PacketId> { impl PacketIdValidator for Vec<PacketId> {
fn validate(&self, packet_id: u16) -> bool {
self.contains(&PacketId::from(packet_id))
}
}
#[cfg(feature = "alloc")]
impl PacketIdLookup for HashSet<PacketId> {
fn validate(&self, packet_id: u16) -> bool { fn validate(&self, packet_id: u16) -> bool {
self.contains(&PacketId::from(packet_id)) self.contains(&PacketId::from(packet_id))
} }
} }
impl PacketIdLookup for [PacketId] { #[cfg(feature = "alloc")]
impl PacketIdValidator for HashSet<PacketId> {
fn validate(&self, packet_id: u16) -> bool {
self.contains(&PacketId::from(packet_id))
}
}
#[cfg(feature = "std")]
impl PacketIdValidator for StdHashSet<PacketId> {
fn validate(&self, packet_id: u16) -> bool {
self.contains(&PacketId::from(packet_id))
}
}
impl PacketIdValidator for [PacketId] {
fn validate(&self, packet_id: u16) -> bool { fn validate(&self, packet_id: u16) -> bool {
self.binary_search(&PacketId::from(packet_id)).is_ok() self.binary_search(&PacketId::from(packet_id)).is_ok()
} }
} }
impl PacketIdLookup for &[PacketId] { impl PacketIdValidator for &[PacketId] {
fn validate(&self, packet_id: u16) -> bool { fn validate(&self, packet_id: u16) -> bool {
self.binary_search(&PacketId::from(packet_id)).is_ok() self.binary_search(&PacketId::from(packet_id)).is_ok()
} }
@ -75,7 +86,7 @@ impl PacketIdLookup for &[PacketId] {
/// error will be returned. /// error will be returned.
pub fn parse_buffer_for_ccsds_space_packets<E>( pub fn parse_buffer_for_ccsds_space_packets<E>(
buf: &mut [u8], buf: &mut [u8],
packet_id_lookup: &(impl PacketIdLookup + ?Sized), packet_id_validator: &(impl PacketIdValidator + ?Sized),
tc_receiver: &mut (impl ReceivesTcCore<Error = E> + ?Sized), tc_receiver: &mut (impl ReceivesTcCore<Error = E> + ?Sized),
next_write_idx: &mut usize, next_write_idx: &mut usize,
) -> Result<u32, E> { ) -> Result<u32, E> {
@ -88,7 +99,7 @@ pub fn parse_buffer_for_ccsds_space_packets<E>(
break; break;
} }
let packet_id = u16::from_be_bytes(buf[current_idx..current_idx + 2].try_into().unwrap()); let packet_id = u16::from_be_bytes(buf[current_idx..current_idx + 2].try_into().unwrap());
if packet_id_lookup.validate(packet_id) { if packet_id_validator.validate(packet_id) {
let length_field = let length_field =
u16::from_be_bytes(buf[current_idx + 4..current_idx + 6].try_into().unwrap()); u16::from_be_bytes(buf[current_idx + 4..current_idx + 6].try_into().unwrap());
let packet_size = length_field + 7; let packet_size = length_field + 7;

View File

@ -4,10 +4,8 @@ use std::{
net::{SocketAddr, TcpListener, TcpStream}, net::{SocketAddr, TcpListener, TcpStream},
}; };
use alloc::boxed::Box;
use crate::{ use crate::{
encoding::{ccsds::PacketIdLookup, parse_buffer_for_ccsds_space_packets}, encoding::{ccsds::PacketIdValidator, parse_buffer_for_ccsds_space_packets},
tmtc::{ReceivesTc, TmPacketSource}, tmtc::{ReceivesTc, TmPacketSource},
}; };
@ -16,17 +14,19 @@ use super::tcp_server::{
}; };
/// Concrete [TcpTcParser] implementation for the [TcpSpacepacketsServer]. /// Concrete [TcpTcParser] implementation for the [TcpSpacepacketsServer].
pub struct SpacepacketsTcParser { pub struct SpacepacketsTcParser<PacketIdChecker: PacketIdValidator> {
packet_id_lookup: Box<dyn PacketIdLookup + Send>, packet_id_lookup: PacketIdChecker,
} }
impl SpacepacketsTcParser { impl<PacketIdChecker: PacketIdValidator> SpacepacketsTcParser<PacketIdChecker> {
pub fn new(packet_id_lookup: Box<dyn PacketIdLookup + Send>) -> Self { pub fn new(packet_id_lookup: PacketIdChecker) -> Self {
Self { packet_id_lookup } Self { packet_id_lookup }
} }
} }
impl<TmError, TcError: 'static> TcpTcParser<TmError, TcError> for SpacepacketsTcParser { impl<TmError, TcError: 'static, PacketIdChecker: PacketIdValidator> TcpTcParser<TmError, TcError>
for SpacepacketsTcParser<PacketIdChecker>
{
fn handle_tc_parsing( fn handle_tc_parsing(
&mut self, &mut self,
tc_buffer: &mut [u8], tc_buffer: &mut [u8],
@ -38,7 +38,7 @@ impl<TmError, TcError: 'static> TcpTcParser<TmError, TcError> for SpacepacketsTc
// Reader vec full, need to parse for packets. // Reader vec full, need to parse for packets.
conn_result.num_received_tcs += parse_buffer_for_ccsds_space_packets( conn_result.num_received_tcs += parse_buffer_for_ccsds_space_packets(
&mut tc_buffer[..current_write_idx], &mut tc_buffer[..current_write_idx],
self.packet_id_lookup.as_ref(), &self.packet_id_lookup,
tc_receiver.upcast_mut(), tc_receiver.upcast_mut(),
next_write_idx, next_write_idx,
) )
@ -95,6 +95,7 @@ pub struct TcpSpacepacketsServer<
TcError: 'static, TcError: 'static,
TmSource: TmPacketSource<Error = TmError>, TmSource: TmPacketSource<Error = TmError>,
TcReceiver: ReceivesTc<Error = TcError>, TcReceiver: ReceivesTc<Error = TcError>,
PacketIdChecker: PacketIdValidator,
> { > {
generic_server: TcpTmtcGenericServer< generic_server: TcpTmtcGenericServer<
TmError, TmError,
@ -102,7 +103,7 @@ pub struct TcpSpacepacketsServer<
TmSource, TmSource,
TcReceiver, TcReceiver,
SpacepacketsTmSender, SpacepacketsTmSender,
SpacepacketsTcParser, SpacepacketsTcParser<PacketIdChecker>,
>, >,
} }
@ -111,7 +112,8 @@ impl<
TcError: 'static, TcError: 'static,
TmSource: TmPacketSource<Error = TmError>, TmSource: TmPacketSource<Error = TmError>,
TcReceiver: ReceivesTc<Error = TcError>, TcReceiver: ReceivesTc<Error = TcError>,
> TcpSpacepacketsServer<TmError, TcError, TmSource, TcReceiver> PacketIdChecker: PacketIdValidator,
> TcpSpacepacketsServer<TmError, TcError, TmSource, TcReceiver, PacketIdChecker>
{ {
/// ///
/// ## Parameter /// ## Parameter
@ -127,12 +129,12 @@ impl<
cfg: ServerConfig, cfg: ServerConfig,
tm_source: TmSource, tm_source: TmSource,
tc_receiver: TcReceiver, tc_receiver: TcReceiver,
packet_id_lookup: Box<dyn PacketIdLookup + Send>, packet_id_checker: PacketIdChecker,
) -> Result<Self, std::io::Error> { ) -> Result<Self, std::io::Error> {
Ok(Self { Ok(Self {
generic_server: TcpTmtcGenericServer::new( generic_server: TcpTmtcGenericServer::new(
cfg, cfg,
SpacepacketsTcParser::new(packet_id_lookup), SpacepacketsTcParser::new(packet_id_checker),
SpacepacketsTmSender::default(), SpacepacketsTmSender::default(),
tm_source, tm_source,
tc_receiver, tc_receiver,
@ -170,7 +172,7 @@ mod tests {
thread, thread,
}; };
use alloc::{boxed::Box, sync::Arc}; use alloc::sync::Arc;
use hashbrown::HashSet; use hashbrown::HashSet;
use spacepackets::{ use spacepackets::{
ecss::{tc::PusTcCreator, WritablePusPacket}, ecss::{tc::PusTcCreator, WritablePusPacket},
@ -194,12 +196,12 @@ mod tests {
tc_receiver: SyncTcCacher, tc_receiver: SyncTcCacher,
tm_source: SyncTmSource, tm_source: SyncTmSource,
packet_id_lookup: HashSet<PacketId>, packet_id_lookup: HashSet<PacketId>,
) -> TcpSpacepacketsServer<(), (), SyncTmSource, SyncTcCacher> { ) -> TcpSpacepacketsServer<(), (), SyncTmSource, SyncTcCacher, HashSet<PacketId>> {
TcpSpacepacketsServer::new( TcpSpacepacketsServer::new(
ServerConfig::new(*addr, Duration::from_millis(2), 1024, 1024), ServerConfig::new(*addr, Duration::from_millis(2), 1024, 1024),
tm_source, tm_source,
tc_receiver, tc_receiver,
Box::new(packet_id_lookup), packet_id_lookup,
) )
.expect("TCP server generation failed") .expect("TCP server generation failed")
} }

View File

@ -6,8 +6,10 @@ use spacepackets::ByteConversionError;
use spacepackets::{SpHeader, MAX_APID}; use spacepackets::{SpHeader, MAX_APID};
use crate::pus::EcssTmSenderCore; use crate::pus::EcssTmSenderCore;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub use alloc_mod::EventReporter; pub use alloc_mod::*;
pub use spacepackets::ecss::event::*; pub use spacepackets::ecss::event::*;
pub struct EventReportCreator { pub struct EventReportCreator {
@ -16,102 +18,98 @@ pub struct EventReportCreator {
} }
impl EventReportCreator { impl EventReportCreator {
pub fn new(apid: u16) -> Option<Self> { pub fn new(apid: u16, dest_id: u16) -> Option<Self> {
if apid > MAX_APID { if apid > MAX_APID {
return None; return None;
} }
Some(Self { Some(Self { dest_id, apid })
// msg_count: 0,
dest_id: 0,
apid,
})
} }
pub fn event_info<'time, 'src_data>( pub fn event_info<'time, 'src_data>(
&self, &self,
src_data_buf: &'src_data mut [u8],
time_stamp: &'time [u8], time_stamp: &'time [u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&'src_data [u8]>, params: Option<&'src_data [u8]>,
src_data_buf: &'src_data mut [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
self.generate_and_send_generic_tm( self.generate_and_send_generic_tm(
src_data_buf,
Subservice::TmInfoReport, Subservice::TmInfoReport,
time_stamp, time_stamp,
event_id, event_id,
aux_data, params,
src_data_buf,
) )
} }
pub fn event_low_severity<'time, 'src_data>( pub fn event_low_severity<'time, 'src_data>(
&self, &self,
src_data_buf: &'src_data mut [u8],
time_stamp: &'time [u8], time_stamp: &'time [u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&'src_data [u8]>, params: Option<&'src_data [u8]>,
src_data_buf: &'src_data mut [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
self.generate_and_send_generic_tm( self.generate_and_send_generic_tm(
src_data_buf,
Subservice::TmLowSeverityReport, Subservice::TmLowSeverityReport,
time_stamp, time_stamp,
event_id, event_id,
aux_data, params,
src_data_buf,
) )
} }
pub fn event_medium_severity<'time, 'src_data>( pub fn event_medium_severity<'time, 'src_data>(
&self, &self,
buf: &'src_data mut [u8],
time_stamp: &'time [u8], time_stamp: &'time [u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&'src_data [u8]>, params: Option<&'src_data [u8]>,
buf: &'src_data mut [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
self.generate_and_send_generic_tm( self.generate_and_send_generic_tm(
buf,
Subservice::TmMediumSeverityReport, Subservice::TmMediumSeverityReport,
time_stamp, time_stamp,
event_id, event_id,
aux_data, params,
buf,
) )
} }
pub fn event_high_severity<'time, 'src_data>( pub fn event_high_severity<'time, 'src_data>(
&self, &self,
src_data_buf: &'src_data mut [u8],
time_stamp: &'time [u8], time_stamp: &'time [u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&'src_data [u8]>, params: Option<&'src_data [u8]>,
src_data_buf: &'src_data mut [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
self.generate_and_send_generic_tm( self.generate_and_send_generic_tm(
src_data_buf,
Subservice::TmHighSeverityReport, Subservice::TmHighSeverityReport,
time_stamp, time_stamp,
event_id, event_id,
aux_data, params,
src_data_buf,
) )
} }
fn generate_and_send_generic_tm<'time, 'src_data>( fn generate_and_send_generic_tm<'time, 'src_data>(
&self, &self,
src_data_buf: &'src_data mut [u8],
subservice: Subservice, subservice: Subservice,
time_stamp: &'time [u8], time_stamp: &'time [u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&'src_data [u8]>, params: Option<&'src_data [u8]>,
src_data_buf: &'src_data mut [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
self.generate_generic_event_tm(src_data_buf, subservice, time_stamp, event_id, aux_data) self.generate_generic_event_tm(subservice, time_stamp, event_id, params, src_data_buf)
} }
fn generate_generic_event_tm<'time, 'src_data>( fn generate_generic_event_tm<'time, 'src_data>(
&self, &self,
src_data_buf: &'src_data mut [u8],
subservice: Subservice, subservice: Subservice,
time_stamp: &'time [u8], time_stamp: &'time [u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&'src_data [u8]>, params: Option<&'src_data [u8]>,
src_data_buf: &'src_data mut [u8],
) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> { ) -> Result<PusTmCreator<'time, 'src_data>, ByteConversionError> {
let mut src_data_len = event_id.size(); let mut src_data_len = event_id.size();
if let Some(aux_data) = aux_data { if let Some(aux_data) = params {
src_data_len += aux_data.len(); src_data_len += aux_data.len();
} }
source_buffer_large_enough(src_data_buf.len(), src_data_len)?; source_buffer_large_enough(src_data_buf.len(), src_data_len)?;
@ -121,7 +119,7 @@ impl EventReportCreator {
let mut current_idx = 0; let mut current_idx = 0;
event_id.write_to_be_bytes(&mut src_data_buf[0..event_id.size()])?; event_id.write_to_be_bytes(&mut src_data_buf[0..event_id.size()])?;
current_idx += event_id.size(); current_idx += event_id.size();
if let Some(aux_data) = aux_data { if let Some(aux_data) = params {
src_data_buf[current_idx..current_idx + aux_data.len()].copy_from_slice(aux_data); src_data_buf[current_idx..current_idx + aux_data.len()].copy_from_slice(aux_data);
current_idx += aux_data.len(); current_idx += aux_data.len();
} }
@ -142,25 +140,56 @@ mod alloc_mod {
use alloc::vec::Vec; use alloc::vec::Vec;
use core::cell::RefCell; use core::cell::RefCell;
pub struct EventReporter { pub trait EventTmHookProvider {
fn modify_tm(&self, tm: &mut PusTmCreator);
}
#[derive(Default)]
pub struct DummyEventHook {}
impl EventTmHookProvider for DummyEventHook {
fn modify_tm(&self, _tm: &mut PusTmCreator) {}
}
pub struct EventReporter<EventTmHook: EventTmHookProvider = DummyEventHook> {
id: ComponentId, id: ComponentId,
// Use interior mutability pattern here. This is just an intermediate buffer to the PUS event packet // Use interior mutability pattern here. This is just an intermediate buffer to the PUS event packet
// generation. // generation.
source_data_buf: RefCell<Vec<u8>>, source_data_buf: RefCell<Vec<u8>>,
pub report_creator: EventReportCreator, pub report_creator: EventReportCreator,
pub tm_hook: EventTmHook,
} }
impl EventReporter { impl EventReporter<DummyEventHook> {
pub fn new( pub fn new(
id: ComponentId, id: ComponentId,
apid: u16, default_apid: u16,
default_dest_id: u16,
max_event_id_and_aux_data_size: usize, max_event_id_and_aux_data_size: usize,
) -> Option<Self> { ) -> Option<Self> {
let reporter = EventReportCreator::new(apid)?; let reporter = EventReportCreator::new(default_apid, default_dest_id)?;
Some(Self { Some(Self {
id, id,
source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]), source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]),
report_creator: reporter, report_creator: reporter,
tm_hook: DummyEventHook::default(),
})
}
}
impl<EventTmHook: EventTmHookProvider> EventReporter<EventTmHook> {
pub fn new_with_hook(
id: ComponentId,
default_apid: u16,
default_dest_id: u16,
max_event_id_and_aux_data_size: usize,
tm_hook: EventTmHook,
) -> Option<Self> {
let reporter = EventReportCreator::new(default_apid, default_dest_id)?;
Some(Self {
id,
source_data_buf: RefCell::new(vec![0; max_event_id_and_aux_data_size]),
report_creator: reporter,
tm_hook,
}) })
} }
@ -169,13 +198,14 @@ mod alloc_mod {
sender: &(impl EcssTmSenderCore + ?Sized), sender: &(impl EcssTmSenderCore + ?Sized),
time_stamp: &[u8], time_stamp: &[u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&[u8]>, params: Option<&[u8]>,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut mut_buf = self.source_data_buf.borrow_mut(); let mut mut_buf = self.source_data_buf.borrow_mut();
let tm_creator = self let mut tm_creator = self
.report_creator .report_creator
.event_info(mut_buf.as_mut_slice(), time_stamp, event_id, aux_data) .event_info(time_stamp, event_id, params, mut_buf.as_mut_slice())
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.id, tm_creator.into())?; sender.send_tm(self.id, tm_creator.into())?;
Ok(()) Ok(())
} }
@ -185,13 +215,14 @@ mod alloc_mod {
sender: &(impl EcssTmSenderCore + ?Sized), sender: &(impl EcssTmSenderCore + ?Sized),
time_stamp: &[u8], time_stamp: &[u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&[u8]>, params: Option<&[u8]>,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut mut_buf = self.source_data_buf.borrow_mut(); let mut mut_buf = self.source_data_buf.borrow_mut();
let tm_creator = self let mut tm_creator = self
.report_creator .report_creator
.event_low_severity(mut_buf.as_mut_slice(), time_stamp, event_id, aux_data) .event_low_severity(time_stamp, event_id, params, mut_buf.as_mut_slice())
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.id, tm_creator.into())?; sender.send_tm(self.id, tm_creator.into())?;
Ok(()) Ok(())
} }
@ -201,13 +232,14 @@ mod alloc_mod {
sender: &(impl EcssTmSenderCore + ?Sized), sender: &(impl EcssTmSenderCore + ?Sized),
time_stamp: &[u8], time_stamp: &[u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&[u8]>, params: Option<&[u8]>,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut mut_buf = self.source_data_buf.borrow_mut(); let mut mut_buf = self.source_data_buf.borrow_mut();
let tm_creator = self let mut tm_creator = self
.report_creator .report_creator
.event_medium_severity(mut_buf.as_mut_slice(), time_stamp, event_id, aux_data) .event_medium_severity(time_stamp, event_id, params, mut_buf.as_mut_slice())
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.id, tm_creator.into())?; sender.send_tm(self.id, tm_creator.into())?;
Ok(()) Ok(())
} }
@ -217,13 +249,14 @@ mod alloc_mod {
sender: &(impl EcssTmSenderCore + ?Sized), sender: &(impl EcssTmSenderCore + ?Sized),
time_stamp: &[u8], time_stamp: &[u8],
event_id: impl EcssEnumeration, event_id: impl EcssEnumeration,
aux_data: Option<&[u8]>, params: Option<&[u8]>,
) -> Result<(), EcssTmtcError> { ) -> Result<(), EcssTmtcError> {
let mut mut_buf = self.source_data_buf.borrow_mut(); let mut mut_buf = self.source_data_buf.borrow_mut();
let tm_creator = self let mut tm_creator = self
.report_creator .report_creator
.event_high_severity(mut_buf.as_mut_slice(), time_stamp, event_id, aux_data) .event_high_severity(time_stamp, event_id, params, mut_buf.as_mut_slice())
.map_err(PusError::ByteConversion)?; .map_err(PusError::ByteConversion)?;
self.tm_hook.modify_tm(&mut tm_creator);
sender.send_tm(self.id, tm_creator.into())?; sender.send_tm(self.id, tm_creator.into())?;
Ok(()) Ok(())
} }
@ -346,6 +379,7 @@ mod tests {
let reporter = EventReporter::new( let reporter = EventReporter::new(
TEST_COMPONENT_ID_0.id(), TEST_COMPONENT_ID_0.id(),
EXAMPLE_APID, EXAMPLE_APID,
0,
max_event_aux_data_buf, max_event_aux_data_buf,
); );
assert!(reporter.is_some()); assert!(reporter.is_some());
@ -440,7 +474,7 @@ mod tests {
fn insufficient_buffer() { fn insufficient_buffer() {
let mut sender = TestSender::default(); let mut sender = TestSender::default();
for i in 0..3 { for i in 0..3 {
let reporter = EventReporter::new(0, EXAMPLE_APID, i); let reporter = EventReporter::new(0, EXAMPLE_APID, 0, i);
assert!(reporter.is_some()); assert!(reporter.is_some());
let mut reporter = reporter.unwrap(); let mut reporter = reporter.unwrap();
check_buf_too_small(&mut reporter, &mut sender, i); check_buf_too_small(&mut reporter, &mut sender, i);

View File

@ -81,7 +81,10 @@
//! let mutable_handler_ref = ccsds_distributor.packet_handler_mut(); //! let mutable_handler_ref = ccsds_distributor.packet_handler_mut();
//! mutable_handler_ref.mutable_foo(); //! mutable_handler_ref.mutable_foo();
//! ``` //! ```
use crate::tmtc::{ReceivesCcsdsTc, ReceivesTcCore}; use crate::{
encoding::ccsds::PacketIdValidator,
tmtc::{ReceivesCcsdsTc, ReceivesTcCore},
};
use core::fmt::{Display, Formatter}; use core::fmt::{Display, Formatter};
use spacepackets::{ByteConversionError, CcsdsPacket, SpHeader}; use spacepackets::{ByteConversionError, CcsdsPacket, SpHeader};
#[cfg(feature = "std")] #[cfg(feature = "std")]
@ -93,14 +96,16 @@ use std::error::Error;
/// instance of this handler to the [CcsdsDistributor]. The distributor will use the trait /// instance of this handler to the [CcsdsDistributor]. The distributor will use the trait
/// interface to dispatch received packets to the user based on the Application Process Identifier /// interface to dispatch received packets to the user based on the Application Process Identifier
/// (APID) field of the CCSDS packet. /// (APID) field of the CCSDS packet.
pub trait CcsdsPacketHandler { pub trait CcsdsPacketHandler: PacketIdValidator {
type Error; type Error;
// TODO: Rework this to return a boolean based on u16 input.. fn handle_packet_with_valid_apid(
fn valid_apids(&self) -> &'static [u16]; &mut self,
fn handle_known_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) sp_header: &SpHeader,
-> Result<(), Self::Error>; tc_raw: &[u8],
fn handle_unknown_apid( ) -> Result<(), Self::Error>;
fn handle_packet_with_unknown_apid(
&mut self, &mut self,
sp_header: &SpHeader, sp_header: &SpHeader,
tc_raw: &[u8], tc_raw: &[u8],
@ -184,18 +189,16 @@ impl<PacketHandler: CcsdsPacketHandler<Error = E>, E: 'static> CcsdsDistributor<
} }
fn dispatch_ccsds(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) -> Result<(), CcsdsError<E>> { fn dispatch_ccsds(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) -> Result<(), CcsdsError<E>> {
let apid = sp_header.apid(); //let valid_apids = self.packet_handler.valid_apids();
let valid_apids = self.packet_handler.valid_apids(); let valid_apid = self.packet_handler().validate(sp_header.packet_id().raw());
for &valid_apid in valid_apids { if valid_apid {
if valid_apid == apid {
return self return self
.packet_handler .packet_handler
.handle_known_apid(sp_header, tc_raw) .handle_packet_with_valid_apid(sp_header, tc_raw)
.map_err(|e| CcsdsError::CustomError(e)); .map_err(|e| CcsdsError::CustomError(e));
} }
}
self.packet_handler self.packet_handler
.handle_unknown_apid(sp_header, tc_raw) .handle_packet_with_unknown_apid(sp_header, tc_raw)
.map_err(|e| CcsdsError::CustomError(e)) .map_err(|e| CcsdsError::CustomError(e))
} }
} }
@ -242,13 +245,16 @@ pub(crate) mod tests {
pub unknown_packet_queue: VecDeque<(u16, Vec<u8>)>, pub unknown_packet_queue: VecDeque<(u16, Vec<u8>)>,
} }
impl CcsdsPacketHandler for BasicApidHandlerSharedQueue { impl PacketIdValidator for BasicApidHandlerSharedQueue {
type Error = (); fn validate(&self, packet_id: u16) -> bool {
fn valid_apids(&self) -> &'static [u16] { &[0x000, 0x002].contains(&packet_id)
&[0x000, 0x002] }
} }
fn handle_known_apid( impl CcsdsPacketHandler for BasicApidHandlerSharedQueue {
type Error = ();
fn handle_packet_with_valid_apid(
&mut self, &mut self,
sp_header: &SpHeader, sp_header: &SpHeader,
tc_raw: &[u8], tc_raw: &[u8],
@ -262,7 +268,7 @@ pub(crate) mod tests {
Ok(()) Ok(())
} }
fn handle_unknown_apid( fn handle_packet_with_unknown_apid(
&mut self, &mut self,
sp_header: &SpHeader, sp_header: &SpHeader,
tc_raw: &[u8], tc_raw: &[u8],
@ -277,14 +283,16 @@ pub(crate) mod tests {
} }
} }
impl PacketIdValidator for BasicApidHandlerOwnedQueue {
fn validate(&self, packet_id: u16) -> bool {
&[0x000, 0x002].contains(&packet_id)
}
}
impl CcsdsPacketHandler for BasicApidHandlerOwnedQueue { impl CcsdsPacketHandler for BasicApidHandlerOwnedQueue {
type Error = (); type Error = ();
fn valid_apids(&self) -> &'static [u16] { fn handle_packet_with_valid_apid(
&[0x000, 0x002]
}
fn handle_known_apid(
&mut self, &mut self,
sp_header: &SpHeader, sp_header: &SpHeader,
tc_raw: &[u8], tc_raw: &[u8],
@ -295,7 +303,7 @@ pub(crate) mod tests {
Ok(()) Ok(())
} }
fn handle_unknown_apid( fn handle_packet_with_unknown_apid(
&mut self, &mut self,
sp_header: &SpHeader, sp_header: &SpHeader,
tc_raw: &[u8], tc_raw: &[u8],