diff --git a/satrs-example/client/Cargo.toml b/satrs-example/client/Cargo.toml index a6d4004..e946cdc 100644 --- a/satrs-example/client/Cargo.toml +++ b/satrs-example/client/Cargo.toml @@ -9,3 +9,10 @@ log = "0.4" fern = "0.7" humantime = "2" satrs-example = { path = ".." } +models = { path = "../models" } +spacepackets = { version = "0.17", git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", default-features = false } +bitbybit = "1.4" +arbitrary-int = "2" +ctrlc = { version = "3.5" } +postcard = { version = "1" } +anyhow = "1" diff --git a/satrs-example/client/src/main.rs b/satrs-example/client/src/main.rs index 5e1b1e5..04190ad 100644 --- a/satrs-example/client/src/main.rs +++ b/satrs-example/client/src/main.rs @@ -1,9 +1,16 @@ +use anyhow::bail; +use arbitrary_int::u11; use clap::Parser as _; +use models::{Apid, TcHeader}; use satrs_example::config::{OBSW_SERVER_ADDR, SERVER_PORT}; +use spacepackets::{CcsdsPacketReader, SpacePacketHeader}; use std::{ net::{IpAddr, SocketAddr, UdpSocket}, - sync::{Arc, atomic::AtomicBool}, - time::SystemTime, + sync::{ + Arc, + atomic::{AtomicBool, Ordering}, + }, + time::{Duration, SystemTime}, }; #[derive(clap::Parser)] @@ -30,13 +37,80 @@ fn setup_logger(level: log::LevelFilter) -> Result<(), fern::InitError> { Ok(()) } -fn main() { +fn main() -> anyhow::Result<()> { setup_logger(log::LevelFilter::Debug).unwrap(); let kill_signal = Arc::new(AtomicBool::new(false)); + let ctrl_kill_signal = kill_signal.clone(); + ctrlc::set_handler(move || ctrl_kill_signal.store(true, Ordering::Relaxed)).unwrap(); let cli = Cli::parse(); let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT); let client = UdpSocket::bind("127.0.0.1:7302").expect("Connecting to UDP server failed"); + client.set_nonblocking(true)?; + client.set_read_timeout(Some(Duration::from_millis(200)))?; - if cli.ping {} + if cli.ping { + log::info!("sending ping request"); + let request = models::ccsds::CcsdsTcPacketOwned::new_with_request( + SpacePacketHeader::new_from_apid(u11::new(Apid::Tmtc as u16)), + TcHeader::new(models::ComponentId::Controller, models::MessageType::Ping), + models::request::Request::Ping, + ); + let request_packet = request.to_vec(); + client.send_to(&request_packet, addr).unwrap(); + } + + let mut recv_buf: Box<[u8; 2048]> = Box::new([0; 2048]); + loop { + if kill_signal.load(std::sync::atomic::Ordering::Relaxed) { + log::info!("received kill signal, exiting"); + break; + } + match client.recv(recv_buf.as_mut_slice()) { + Ok(received_bytes) => handle_raw_tm_packet(&recv_buf.as_slice()[0..received_bytes])?, + Err(e) => { + if e.kind() == std::io::ErrorKind::WouldBlock + || e.kind() == std::io::ErrorKind::TimedOut + { + continue; + } + log::warn!("UDP reception error: {}", e) + } + } + } + Ok(()) +} + +fn handle_raw_tm_packet(data: &[u8]) -> anyhow::Result<()> { + match spacepackets::CcsdsPacketReader::new_with_checksum(data) { + Ok(packet) => { + let (tm_header, response, remainder) = unpack_tm_header_and_response(&packet)?; + log::info!( + "Received TM with APID {} and TM header {:?}", + packet.apid(), + tm_header + ); + log::info!("Response: {:?} with remainder: {:?} ", response, remainder); + } + Err(_) => todo!(), + } + Ok(()) +} + +fn unpack_tm_header_and_response<'a>( + packet: &'a CcsdsPacketReader, +) -> anyhow::Result<(models::TmHeader, models::response::Response, &'a [u8])> { + let tm_header_result = postcard::take_from_bytes::(packet.user_data()); + if let Err(e) = tm_header_result { + bail!("Failed to deserialize TM header: {}", e); + } + let (tm_header, remainder) = tm_header_result.unwrap(); + log::info!("TM header: {:?}", tm_header); + let response_result = postcard::take_from_bytes::(remainder); + if let Err(e) = response_result { + bail!("Failed to deserialize TM header: {}", e); + } + let response = response_result.unwrap(); + log::info!("Response: {:?}", response); + Ok((tm_header, response.0, response.1)) } diff --git a/satrs-example/models/Cargo.toml b/satrs-example/models/Cargo.toml index 70e6c71..4cbb066 100644 --- a/satrs-example/models/Cargo.toml +++ b/satrs-example/models/Cargo.toml @@ -7,5 +7,8 @@ edition = "2024" serde = { version = "1", features = ["derive"] } spacepackets = { version = "0.17", git = "https://egit.irs.uni-stuttgart.de/rust/spacepackets.git", default-features = false } num_enum = { version = "0.7" } +strum = { version = "0.27", features = ["derive"] } postcard = { version = "1" } thiserror = { version = "2" } +bitbybit = "1.4" +arbitrary-int = "2" diff --git a/satrs-example/models/src/ccsds.rs b/satrs-example/models/src/ccsds.rs index 0ad2070..eec2a59 100644 --- a/satrs-example/models/src/ccsds.rs +++ b/satrs-example/models/src/ccsds.rs @@ -12,6 +12,59 @@ pub struct CcsdsTcPacketOwned { pub payload: alloc::vec::Vec, } +impl CcsdsTcPacketOwned { + pub fn new_with_request( + sp_header: SpacePacketHeader, + tc_header: TcHeader, + request: R, + ) -> Self { + let request_serialized = postcard::to_allocvec(&request).unwrap(); + Self::new(sp_header, tc_header, request_serialized) + } + + pub fn new( + sp_header: SpacePacketHeader, + tc_header: TcHeader, + payload: alloc::vec::Vec, + ) -> Self { + Self { + sp_header, + tc_header, + payload, + } + } + + pub fn write_to_bytes(&self, buf: &mut [u8]) -> Result { + let response_len = + postcard::experimental::serialized_size(&self.tc_header)? + self.payload.len(); + let mut ccsds_tc = CcsdsPacketCreatorWithReservedData::new_tc_with_checksum( + self.sp_header, + response_len, + buf, + )?; + let user_data = ccsds_tc.packet_data_mut(); + let ser_len = postcard::to_slice(&self.tc_header, user_data)?.len(); + user_data[ser_len..ser_len + self.payload.len()].copy_from_slice(&self.payload); + let ccsds_packet_len = ccsds_tc.finish(); + Ok(ccsds_packet_len) + } + + pub fn len_written(&self) -> usize { + ccsds_packet_len_for_user_data_len_with_checksum( + postcard::experimental::serialized_size(&self.tc_header).unwrap() as usize + + postcard::experimental::serialized_size(&self.payload).unwrap() as usize, + ) + .unwrap() + } + + pub fn to_vec(&self) -> alloc::vec::Vec { + let mut buf = alloc::vec![0u8; self.len_written()]; + let len = self.write_to_bytes(&mut buf).unwrap(); + buf.truncate(len); + buf + } +} + #[derive(Debug, thiserror::Error)] pub enum CcsdsCreationError { #[error("CCSDS packet creation error: {0}")] diff --git a/satrs-example/models/src/lib.rs b/satrs-example/models/src/lib.rs index e95aadb..15f7497 100644 --- a/satrs-example/models/src/lib.rs +++ b/satrs-example/models/src/lib.rs @@ -18,6 +18,30 @@ pub mod ccsds; #[repr(u64)] pub enum ComponentId { Pcdu, + Controller, + + AcsSubsystem, + AcsAssembly, + AcsMgm0, + AcsMgm1, + + EpsSubsystem, + EpsPcdu, + + UdpServer, + TcpServer, + + Ground +} + +#[derive(Debug, PartialEq, Eq, strum::EnumIter)] +#[bitbybit::bitenum(u11)] +pub enum Apid { + Tmtc = 1, + Cfdp = 2, + + Acs = 3, + Eps = 6, } #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] @@ -39,6 +63,15 @@ pub struct TcHeader { pub request_type: MessageType, } +impl TcHeader { + pub fn new(target_id: ComponentId, request_type: MessageType) -> Self { + Self { + target_id, + request_type, + } + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub enum MessageType { Ping, diff --git a/satrs-example/src/config.rs b/satrs-example/src/config.rs index 908bce1..5603fbf 100644 --- a/satrs-example/src/config.rs +++ b/satrs-example/src/config.rs @@ -7,7 +7,7 @@ use satrs::{ use satrs_mib::res_code::ResultU16Info; use satrs_mib::resultcode; use std::{collections::HashSet, net::Ipv4Addr}; -use strum::IntoEnumIterator; +use strum::IntoEnumIterator as _; use num_enum::{IntoPrimitive, TryFromPrimitive}; use satrs::{ @@ -44,14 +44,14 @@ pub const TEST_EVENT: EventU32TypedSev = EventU32TypedSev:: = { let mut set = HashSet::new(); - for id in crate::ids::Apid::iter() { + for id in models::Apid::iter() { set.insert(PacketId::new(PacketType::Tc, true, u11::new(id as u16))); } set }; pub static ref APID_VALIDATOR: HashSet = { let mut set = HashSet::new(); - for id in crate::ids::Apid::iter() { + for id in models::Apid::iter() { set.insert(id as u16); } set diff --git a/satrs-example/src/eps/pcdu.rs b/satrs-example/src/eps/pcdu.rs index 50285d0..2591f54 100644 --- a/satrs-example/src/eps/pcdu.rs +++ b/satrs-example/src/eps/pcdu.rs @@ -5,7 +5,10 @@ use std::{ }; use derive_new::new; -use models::ccsds::CcsdsTmPacketOwned; +use models::{ + ccsds::{CcsdsTcPacketOwned, CcsdsTmPacketOwned}, + ComponentId, +}; use num_enum::{IntoPrimitive, TryFromPrimitive}; use satrs::{ hk::{HkRequest, HkRequestVariant}, @@ -16,14 +19,9 @@ use satrs::{ mode_tree::{ModeChild, ModeNode}, power::SwitchRequest, queue::GenericSendError, - request::{GenericMessage, MessageMetadata, UniqueApidTargetId}, - spacepackets::ByteConversionError, -}; -use satrs_example::{ - config::components::NO_SENDER, - ids::{eps::PCDU, generic_pus::PUS_MODE}, - DeviceMode, TimestampHelper, + request::{GenericMessage, MessageMetadata}, }; +use satrs_example::{config::components::NO_SENDER, DeviceMode, TimestampHelper}; use satrs_minisim::{ eps::{ PcduReply, PcduRequest, PcduSwitch, SwitchMap, SwitchMapBinaryWrapper, SwitchMapWrapper, @@ -32,8 +30,6 @@ use satrs_minisim::{ }; use serde::{Deserialize, Serialize}; -use crate::{hk::PusHkHelper, requests::CompositeRequest}; - pub trait SerialInterface { type Error: core::fmt::Debug; @@ -198,30 +194,44 @@ pub struct SwitchSet { pub type SharedSwitchSet = Arc>; /// Example PCDU device handler. -#[derive(new)] #[allow(clippy::too_many_arguments)] pub struct PcduHandler { - id: UniqueApidTargetId, dev_str: &'static str, mode_node: ModeRequestHandlerMpscBounded, - composite_request_rx: mpsc::Receiver>, - //hk_reply_tx: mpsc::SyncSender>, - hk_tx: std::sync::mpsc::SyncSender, switch_request_rx: mpsc::Receiver>, + tc_rx: std::sync::mpsc::Receiver, tm_tx: mpsc::SyncSender, pub com_interface: ComInterface, shared_switch_map: Arc>, - #[new(value = "PusHkHelper::new(id)")] - hk_helper: PusHkHelper, - #[new(value = "ModeAndSubmode::new(satrs_example::DeviceMode::Off as u32, 0)")] + //hk_helper: PusHkHelper, mode_and_submode: ModeAndSubmode, - #[new(default)] stamp_helper: TimestampHelper, - #[new(value = "[0; 256]")] tm_buf: [u8; 256], } impl PcduHandler { + pub fn new( + mode_node: ModeRequestHandlerMpscBounded, + tc_rx: std::sync::mpsc::Receiver, + tm_tx: std::sync::mpsc::SyncSender, + switch_request_rx: mpsc::Receiver>, + com_interface: ComInterface, + shared_switch_map: Arc>, + ) -> Self { + Self { + dev_str: "PCDU", + mode_node, + tc_rx, + switch_request_rx, + tm_tx, + com_interface, + shared_switch_map, + //hk_helper: PusHkHelper, + mode_and_submode: ModeAndSubmode::new(0, 0), + stamp_helper: TimestampHelper::default(), + tm_buf: [0; 256], + } + } pub fn periodic_operation(&mut self, op_code: OpCode) { match op_code { OpCode::RegularOp => { @@ -243,6 +253,7 @@ impl PcduHandler { } pub fn handle_composite_requests(&mut self) { + /* loop { match self.composite_request_rx.try_recv() { Ok(ref msg) => match &msg.message { @@ -267,10 +278,13 @@ impl PcduHandler { } } } + */ } pub fn handle_hk_request(&mut self, _requestor_info: &MessageMetadata, hk_request: &HkRequest) { match hk_request.variant { + HkRequestVariant::OneShot => todo!(), + /* HkRequestVariant::OneShot => { if hk_request.unique_id == SetId::SwitcherSet as u32 { if let Ok(_hk_tm) = self.hk_helper.generate_hk_report_packet( @@ -311,6 +325,7 @@ impl PcduHandler { } } } + */ HkRequestVariant::EnablePeriodic => todo!(), HkRequestVariant::DisablePeriodic => todo!(), HkRequestVariant::ModifyCollectionInterval(_) => todo!(), @@ -449,7 +464,7 @@ impl ModeRequestHandler for PcduHandler ModeRequestHandler for PcduHandler Result<(), Self::Error> { - if requestor.sender_id() != PUS_MODE.id() { + if requestor.sender_id() != ComponentId::Ground as u32 { log::warn!( "can not send back mode reply to sender {}", requestor.sender_id() @@ -489,7 +504,7 @@ impl ModeRequestHandler for PcduHandler ModeNode for PcduHandler { fn id(&self) -> satrs::ComponentId { - PCDU.into() + ComponentId::EpsPcdu as u32 } } @@ -505,9 +520,7 @@ impl ModeChild for PcduHandler { mod tests { use std::sync::mpsc; - use arbitrary_int::u21; use satrs::{mode::ModeRequest, power::SwitchStateBinary, request::GenericMessage}; - use satrs_example::ids::{self, Apid}; use satrs_minisim::eps::SwitchMapBinary; use super::*; @@ -551,9 +564,7 @@ mod tests { pub mode_request_tx: mpsc::SyncSender>, pub mode_reply_rx_to_pus: mpsc::Receiver>, pub mode_reply_rx_to_parent: mpsc::Receiver>, - pub composite_request_tx: mpsc::Sender>, - //pub hk_reply_rx: mpsc::Receiver>, - pub hk_rx: std::sync::mpsc::Receiver, + pub tc_tx: mpsc::SyncSender, pub tm_rx: mpsc::Receiver, pub switch_request_tx: mpsc::Sender>, pub handler: PcduHandler, @@ -564,32 +575,28 @@ mod tests { let (mode_request_tx, mode_request_rx) = mpsc::sync_channel(5); let (mode_reply_tx_to_pus, mode_reply_rx_to_pus) = mpsc::sync_channel(5); let (mode_reply_tx_to_parent, mode_reply_rx_to_parent) = mpsc::sync_channel(5); - let mode_node = ModeRequestHandlerMpscBounded::new(PCDU.into(), mode_request_rx); - let (composite_request_tx, composite_request_rx) = mpsc::channel(); - let (hk_tx, hk_rx) = mpsc::sync_channel(10); + let mode_node = + ModeRequestHandlerMpscBounded::new(ComponentId::EpsPcdu as u32, mode_request_rx); + let (tc_tx, tc_rx) = mpsc::sync_channel(5); + //let (hk_tx, hk_rx) = mpsc::sync_channel(10); let (tm_tx, tm_rx) = mpsc::sync_channel(5); let (switch_request_tx, switch_reqest_rx) = mpsc::channel(); let shared_switch_map = Arc::new(Mutex::new(SwitchSet::default())); let mut handler = PcduHandler::new( - UniqueApidTargetId::new(Apid::Eps.raw_value(), u21::new(0)), - "TEST_PCDU", mode_node, - composite_request_rx, - hk_tx, - switch_reqest_rx, + tc_rx, tm_tx.clone(), - //TmTcSender::Normal(tm_tx.clone()), + switch_reqest_rx, SerialInterfaceTest::default(), shared_switch_map, ); - handler.add_mode_parent(ids::eps::SUBSYSTEM.into(), mode_reply_tx_to_parent); - handler.add_mode_parent(PUS_MODE.into(), mode_reply_tx_to_pus); + handler.add_mode_parent(ComponentId::EpsSubsystem as u32, mode_reply_tx_to_parent); + //handler.add_mode_parent(PUS_MODE.into(), mode_reply_tx_to_pus); Self { mode_request_tx, mode_reply_rx_to_pus, mode_reply_rx_to_parent, - composite_request_tx, - hk_rx, + tc_tx, tm_rx, switch_request_tx, handler, @@ -678,7 +685,7 @@ mod tests { testbench .mode_request_tx .send(GenericMessage::new( - MessageMetadata::new(0, PUS_MODE.id()), + MessageMetadata::new(0, ComponentId::Ground as u32), ModeRequest::SetMode { mode_and_submode: ModeAndSubmode::new(DeviceMode::Normal as u32, 0), forced: false, @@ -713,7 +720,7 @@ mod tests { testbench .mode_request_tx .send(GenericMessage::new( - MessageMetadata::new(0, PUS_MODE.id()), + MessageMetadata::new(0, ComponentId::Ground as u32), ModeRequest::SetMode { mode_and_submode: ModeAndSubmode::new(DeviceMode::Normal as u32, 0), forced: false, @@ -723,7 +730,7 @@ mod tests { testbench .switch_request_tx .send(GenericMessage::new( - MessageMetadata::new(0, ids::acs::MGM0.id()), + MessageMetadata::new(0, ComponentId::AcsMgm0 as u32), SwitchRequest::new(0, SwitchStateBinary::On), )) .expect("failed to send switch request"); diff --git a/satrs-example/src/ids.rs b/satrs-example/src/ids.rs deleted file mode 100644 index 11ae2f7..0000000 --- a/satrs-example/src/ids.rs +++ /dev/null @@ -1,109 +0,0 @@ -//! This is an auto-generated configuration module. -use satrs::request::UniqueApidTargetId; - -#[derive(Debug, PartialEq, Eq, strum::EnumIter)] -#[bitbybit::bitenum(u11)] -pub enum Apid { - Sched = 1, - GenericPus = 2, - Acs = 3, - Cfdp = 4, - Tmtc = 5, - Eps = 6, -} - -pub mod acs { - - #[derive(Debug, PartialEq, Eq)] - #[bitbybit::bitenum(u21, exhaustive = false)] - pub enum Id { - Subsystem = 1, - Assembly = 2, - Mgm0 = 3, - Mgm1 = 4, - } - - pub const SUBSYSTEM: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Subsystem.raw_value()); - pub const ASSEMBLY: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Assembly.raw_value()); - pub const MGM0: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Mgm0.raw_value()); - pub const MGM1: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Acs.raw_value(), Id::Mgm1.raw_value()); -} - -pub mod eps { - #[derive(Debug, PartialEq, Eq)] - #[bitbybit::bitenum(u21, exhaustive = false)] - pub enum Id { - Pcdu = 0, - Subsystem = 1, - } - - pub const PCDU: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Eps.raw_value(), Id::Pcdu.raw_value()); - pub const SUBSYSTEM: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Eps.raw_value(), Id::Subsystem.raw_value()); -} - -pub mod generic_pus { - #[derive(Debug, PartialEq, Eq)] - #[bitbybit::bitenum(u21, exhaustive = false)] - pub enum Id { - PusEventManagement = 0, - PusRouting = 1, - PusTest = 2, - PusAction = 3, - PusMode = 4, - PusHk = 5, - } - - pub const PUS_EVENT_MANAGEMENT: super::UniqueApidTargetId = super::UniqueApidTargetId::new( - super::Apid::GenericPus.raw_value(), - Id::PusEventManagement.raw_value(), - ); - pub const PUS_ROUTING: super::UniqueApidTargetId = super::UniqueApidTargetId::new( - super::Apid::GenericPus.raw_value(), - Id::PusRouting.raw_value(), - ); - pub const PUS_TEST: super::UniqueApidTargetId = super::UniqueApidTargetId::new( - super::Apid::GenericPus.raw_value(), - Id::PusTest.raw_value(), - ); - pub const PUS_ACTION: super::UniqueApidTargetId = super::UniqueApidTargetId::new( - super::Apid::GenericPus.raw_value(), - Id::PusAction.raw_value(), - ); - pub const PUS_MODE: super::UniqueApidTargetId = super::UniqueApidTargetId::new( - super::Apid::GenericPus.raw_value(), - Id::PusMode.raw_value(), - ); - pub const PUS_HK: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::GenericPus.raw_value(), Id::PusHk.raw_value()); -} - -pub mod sched { - #[derive(Debug, PartialEq, Eq)] - #[bitbybit::bitenum(u21, exhaustive = false)] - pub enum Id { - PusSched = 0, - } - - pub const PUS_SCHED: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Sched.raw_value(), Id::PusSched.raw_value()); -} - -pub mod tmtc { - #[derive(Debug, PartialEq, Eq)] - #[bitbybit::bitenum(u21, exhaustive = false)] - pub enum Id { - UdpServer = 0, - TcpServer = 1, - } - - pub const UDP_SERVER: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Tmtc.raw_value(), Id::UdpServer.raw_value()); - pub const TCP_SERVER: super::UniqueApidTargetId = - super::UniqueApidTargetId::new(super::Apid::Tmtc.raw_value(), Id::TcpServer.raw_value()); -} diff --git a/satrs-example/src/lib.rs b/satrs-example/src/lib.rs index bdb8261..0432644 100644 --- a/satrs-example/src/lib.rs +++ b/satrs-example/src/lib.rs @@ -4,7 +4,6 @@ pub use models::ComponentId; use satrs::spacepackets::time::cds::CdsTime; pub mod config; -pub mod ids; /// Simple type modelling packet stored in the heap. This structure is intended to /// be used when sending a packet via a message queue, so it also contains the sender ID. diff --git a/satrs-example/src/main.rs b/satrs-example/src/main.rs index 5c94b6d..630b284 100644 --- a/satrs-example/src/main.rs +++ b/satrs-example/src/main.rs @@ -16,7 +16,8 @@ use interface::{ }; use log::info; use logger::setup_logger; -use requests::GenericRequestRouter; +use models::ComponentId; +//use requests::GenericRequestRouter; use satrs::{ hal::std::{tcp_server::ServerConfig, udp_server::UdpTcServer}, mode::{Mode, ModeAndSubmode, ModeRequest, ModeRequestHandlerMpscBounded}, @@ -30,11 +31,6 @@ use satrs_example::{ tasks::{FREQ_MS_AOCS, FREQ_MS_PUS_STACK, FREQ_MS_UDP_TMTC, SIM_CLIENT_IDLE_DELAY_MS}, OBSW_SERVER_ADDR, PACKET_ID_VALIDATOR, SERVER_PORT, }, - ids::{ - acs::*, - eps::*, - tmtc::{TCP_SERVER, UDP_SERVER}, - }, DeviceMode, }; use tmtc::sender::TmTcSender; @@ -67,14 +63,15 @@ fn main() { let (pcdu_sim_reply_tx, pcdu_sim_reply_rx) = mpsc::channel(); let mut opt_sim_client = create_sim_client(sim_request_rx); - let (mgm_0_handler_composite_tx, mgm_0_handler_composite_rx) = mpsc::sync_channel(10); - let (mgm_1_handler_composite_tx, mgm_1_handler_composite_rx) = mpsc::sync_channel(10); - let (pcdu_handler_composite_tx, pcdu_handler_composite_rx) = mpsc::sync_channel(30); + //let (mgm_0_handler_composite_tx, mgm_0_handler_composite_rx) = mpsc::sync_channel(10); + //let (mgm_1_handler_composite_tx, mgm_1_handler_composite_rx) = mpsc::sync_channel(10); + let (pcdu_handler_tc_tx, pcdu_handler_tc_rx) = mpsc::sync_channel(30); let (mgm_0_handler_mode_tx, mgm_0_handler_mode_rx) = mpsc::sync_channel(5); let (mgm_1_handler_mode_tx, mgm_1_handler_mode_rx) = mpsc::sync_channel(5); let (pcdu_handler_mode_tx, pcdu_handler_mode_rx) = mpsc::sync_channel(5); // Some request are targetable. This map is used to retrieve sender handles based on a target ID. + /* let mut request_map = GenericRequestRouter::default(); request_map .composite_router_map @@ -85,6 +82,7 @@ fn main() { request_map .composite_router_map .insert(PCDU.id(), pcdu_handler_composite_tx); + */ // Create event handling components // These sender handles are used to send event requests, for example to enable or disable @@ -104,30 +102,36 @@ fn main() { //let (pus_mode_tx, pus_mode_rx) = mpsc::sync_channel(50); //let (_pus_action_reply_tx, pus_action_reply_rx) = mpsc::channel(); - let (pus_hk_reply_tx, pus_hk_reply_rx) = mpsc::sync_channel(50); + //let (pus_hk_reply_tx, pus_hk_reply_rx) = mpsc::sync_channel(50); //let (pus_mode_reply_tx, pus_mode_reply_rx) = mpsc::sync_channel(30); - let mut ccsds_distributor = CcsdsDistributor::default(); + let ccsds_distributor = CcsdsDistributor::default(); let mut tmtc_task = TcSourceTask::new( tc_source_rx, ccsds_distributor, //PusTcDistributor::new(tm_sender.clone(), pus_router), ); + tmtc_task.add_target(ComponentId::EpsPcdu, pcdu_handler_tc_tx); let tc_sender = TmTcSender::Normal(tc_source_tx.clone()); let udp_tm_handler = UdpTmHandlerWithChannel { tm_rx: tm_server_rx, }; let sock_addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT); - let udp_tc_server = UdpTcServer::new(UDP_SERVER.id(), sock_addr, 2048, tc_sender.clone()) - .expect("creating UDP TMTC server failed"); + let udp_tc_server = UdpTcServer::new( + ComponentId::UdpServer as u32, + sock_addr, + 2048, + tc_sender.clone(), + ) + .expect("creating UDP TMTC server failed"); let mut udp_tmtc_server = UdpTmtcServer { udp_tc_server, tm_handler: udp_tm_handler.into(), }; let tcp_server_cfg = ServerConfig::new( - TCP_SERVER.id(), + ComponentId::TcpServer as u32, sock_addr, Duration::from_millis(400), 4096, @@ -150,8 +154,10 @@ fn main() { //let shared_mgm_0_set = Arc::default(); //let shared_mgm_1_set = Arc::default(); - let mgm_0_mode_node = ModeRequestHandlerMpscBounded::new(MGM0.into(), mgm_0_handler_mode_rx); - let mgm_1_mode_node = ModeRequestHandlerMpscBounded::new(MGM1.into(), mgm_1_handler_mode_rx); + let mgm_0_mode_node = + ModeRequestHandlerMpscBounded::new(ComponentId::AcsMgm0 as u32, mgm_0_handler_mode_rx); + let mgm_1_mode_node = + ModeRequestHandlerMpscBounded::new(ComponentId::AcsMgm1 as u32, mgm_1_handler_mode_rx); /* let (mgm_0_spi_interface, mgm_1_spi_interface) = if let Some(sim_client) = opt_sim_client.as_mut() { @@ -221,15 +227,13 @@ fn main() { } else { SerialSimInterfaceWrapper::Dummy(SerialInterfaceDummy::default()) }; - let pcdu_mode_node = ModeRequestHandlerMpscBounded::new(PCDU.into(), pcdu_handler_mode_rx); + let pcdu_mode_node = + ModeRequestHandlerMpscBounded::new(ComponentId::Pcdu as u32, pcdu_handler_mode_rx); let mut pcdu_handler = PcduHandler::new( - PCDU, - "PCDU", pcdu_mode_node, - pcdu_handler_composite_rx, - pus_hk_reply_tx, - switch_request_rx, + pcdu_handler_tc_rx, tm_sink_tx.clone(), + switch_request_rx, pcdu_serial_interface, shared_switch_set, ); @@ -255,7 +259,7 @@ fn main() { info!("Starting TMTC and UDP task"); let jh_udp_tmtc = thread::Builder::new() - .name("SATRS tmtc-udp".to_string()) + .name("TMTC & UDP".to_string()) .spawn(move || { info!("Running UDP server on port {SERVER_PORT}"); loop { diff --git a/satrs-example/src/requests.rs b/satrs-example/src/requests.rs index c6d80aa..c798f5f 100644 --- a/satrs-example/src/requests.rs +++ b/satrs-example/src/requests.rs @@ -15,8 +15,8 @@ use satrs::spacepackets::ecss::tc::PusTcReader; use satrs::spacepackets::ecss::PusPacket; use satrs::ComponentId; use satrs_example::config::tmtc_err; -use satrs_example::ids; +/* #[derive(Clone, Debug)] #[non_exhaustive] pub enum CompositeRequest { @@ -153,3 +153,4 @@ impl PusRequestRouter for GenericRequestRouter { Err(GenericRoutingError::UnknownTargetId(target_id)) } } +*/ diff --git a/satrs-example/src/tmtc/tc_source.rs b/satrs-example/src/tmtc/tc_source.rs index 4203f33..a1f670a 100644 --- a/satrs-example/src/tmtc/tc_source.rs +++ b/satrs-example/src/tmtc/tc_source.rs @@ -89,15 +89,26 @@ impl TcSourceTask { } } + pub fn add_target( + &mut self, + target_id: ComponentId, + sender: mpsc::SyncSender, + ) { + self.ccsds_distributor.insert(target_id, sender); + } + pub fn periodic_operation(&mut self) { - self.poll_tc(); + loop { + if self.poll_tc() == HandlingStatus::Empty { + break; + } + } } pub fn poll_tc(&mut self) -> HandlingStatus { - // Right now, we only expect ECSS PUS packets. - // If packets like CFDP are expected, we might have to check the APID first. match self.tc_receiver.try_recv() { Ok(packet) => { + log::debug!("received raw packet: {:?}", packet); let ccsds_tc_reader_result = CcsdsPacketReader::new(&packet.packet, Some(ChecksumType::WithCrc16)); if ccsds_tc_reader_result.is_err() { @@ -121,6 +132,7 @@ impl TcSourceTask { } let (tc_header, payload) = tc_header_result.unwrap(); if let Some(sender) = self.ccsds_distributor.get(&tc_header.target_id) { + log::debug!("sending TC packet to target ID: {:?}", tc_header.target_id); sender .send(CcsdsTcPacketOwned { sp_header: *ccsds_tc_reader.sp_header(),