ping request is arriving

This commit is contained in:
Robin Mueller
2026-01-14 12:17:32 +01:00
parent 3d267046bf
commit 0263fad0e1
12 changed files with 272 additions and 188 deletions
+7
View File
@@ -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"
+78 -4
View File
@@ -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::<models::TmHeader>(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::<models::response::Response>(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))
}
+3
View File
@@ -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"
+53
View File
@@ -12,6 +12,59 @@ pub struct CcsdsTcPacketOwned {
pub payload: alloc::vec::Vec<u8>,
}
impl CcsdsTcPacketOwned {
pub fn new_with_request<R: serde::Serialize>(
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<u8>,
) -> Self {
Self {
sp_header,
tc_header,
payload,
}
}
pub fn write_to_bytes(&self, buf: &mut [u8]) -> Result<usize, CcsdsCreationError> {
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<u8> {
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}")]
+33
View File
@@ -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,
+3 -3
View File
@@ -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<SeverityInfo> = EventU32TypedSev::<Severi
lazy_static! {
pub static ref PACKET_ID_VALIDATOR: HashSet<PacketId> = {
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<u16> = {
let mut set = HashSet::new();
for id in crate::ids::Apid::iter() {
for id in models::Apid::iter() {
set.insert(id as u16);
}
set
+51 -44
View File
@@ -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<Mutex<SwitchSet>>;
/// Example PCDU device handler.
#[derive(new)]
#[allow(clippy::too_many_arguments)]
pub struct PcduHandler<ComInterface: SerialInterface> {
id: UniqueApidTargetId,
dev_str: &'static str,
mode_node: ModeRequestHandlerMpscBounded,
composite_request_rx: mpsc::Receiver<GenericMessage<CompositeRequest>>,
//hk_reply_tx: mpsc::SyncSender<GenericMessage<HkReply>>,
hk_tx: std::sync::mpsc::SyncSender<CcsdsTmPacketOwned>,
switch_request_rx: mpsc::Receiver<GenericMessage<SwitchRequest>>,
tc_rx: std::sync::mpsc::Receiver<CcsdsTcPacketOwned>,
tm_tx: mpsc::SyncSender<CcsdsTmPacketOwned>,
pub com_interface: ComInterface,
shared_switch_map: Arc<Mutex<SwitchSet>>,
#[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<ComInterface: SerialInterface> PcduHandler<ComInterface> {
pub fn new(
mode_node: ModeRequestHandlerMpscBounded,
tc_rx: std::sync::mpsc::Receiver<CcsdsTcPacketOwned>,
tm_tx: std::sync::mpsc::SyncSender<CcsdsTmPacketOwned>,
switch_request_rx: mpsc::Receiver<GenericMessage<SwitchRequest>>,
com_interface: ComInterface,
shared_switch_map: Arc<Mutex<SwitchSet>>,
) -> 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<ComInterface: SerialInterface> PcduHandler<ComInterface> {
}
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<ComInterface: SerialInterface> PcduHandler<ComInterface> {
}
}
}
*/
}
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<ComInterface: SerialInterface> PcduHandler<ComInterface> {
}
}
}
*/
HkRequestVariant::EnablePeriodic => todo!(),
HkRequestVariant::DisablePeriodic => todo!(),
HkRequestVariant::ModifyCollectionInterval(_) => todo!(),
@@ -449,7 +464,7 @@ impl<ComInterface: SerialInterface> ModeRequestHandler for PcduHandler<ComInterf
if requestor.sender_id() == NO_SENDER {
return Ok(());
}
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()
@@ -466,7 +481,7 @@ impl<ComInterface: SerialInterface> ModeRequestHandler for PcduHandler<ComInterf
requestor: MessageMetadata,
reply: ModeReply,
) -> 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<ComInterface: SerialInterface> ModeRequestHandler for PcduHandler<ComInterf
impl<ComInterface: SerialInterface> ModeNode for PcduHandler<ComInterface> {
fn id(&self) -> satrs::ComponentId {
PCDU.into()
ComponentId::EpsPcdu as u32
}
}
@@ -505,9 +520,7 @@ impl<ComInterface: SerialInterface> ModeChild for PcduHandler<ComInterface> {
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<GenericMessage<ModeRequest>>,
pub mode_reply_rx_to_pus: mpsc::Receiver<GenericMessage<ModeReply>>,
pub mode_reply_rx_to_parent: mpsc::Receiver<GenericMessage<ModeReply>>,
pub composite_request_tx: mpsc::Sender<GenericMessage<CompositeRequest>>,
//pub hk_reply_rx: mpsc::Receiver<GenericMessage<HkReply>>,
pub hk_rx: std::sync::mpsc::Receiver<CcsdsTmPacketOwned>,
pub tc_tx: mpsc::SyncSender<CcsdsTcPacketOwned>,
pub tm_rx: mpsc::Receiver<CcsdsTmPacketOwned>,
pub switch_request_tx: mpsc::Sender<GenericMessage<SwitchRequest>>,
pub handler: PcduHandler<SerialInterfaceTest>,
@@ -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");
-109
View File
@@ -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());
}
-1
View File
@@ -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.
+27 -23
View File
@@ -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 {
+2 -1
View File
@@ -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<ModeRequest> for GenericRequestRouter {
Err(GenericRoutingError::UnknownTargetId(target_id))
}
}
*/
+15 -3
View File
@@ -89,15 +89,26 @@ impl TcSourceTask {
}
}
pub fn add_target(
&mut self,
target_id: ComponentId,
sender: mpsc::SyncSender<CcsdsTcPacketOwned>,
) {
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(),