ping request is arriving
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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}")]
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user