diff --git a/.idea/runConfigurations/Run_obsw_client_example.xml b/.idea/runConfigurations/Run_obsw_client_example.xml
new file mode 100644
index 0000000..dc85ad6
--- /dev/null
+++ b/.idea/runConfigurations/Run_obsw_client_example.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/Run_obsw_example.xml b/.idea/runConfigurations/Run_obsw_example.xml
new file mode 100644
index 0000000..ed323c9
--- /dev/null
+++ b/.idea/runConfigurations/Run_obsw_example.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 455bb58..af38bfb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -235,6 +235,7 @@ dependencies = [
name = "fsrc-example"
version = "0.1.0"
dependencies = [
+ "fsrc-core",
"spacepackets",
]
diff --git a/fsrc-core/src/hal/host/udp_server.rs b/fsrc-core/src/hal/host/udp_server.rs
index 53a67c5..b2c4b40 100644
--- a/fsrc-core/src/hal/host/udp_server.rs
+++ b/fsrc-core/src/hal/host/udp_server.rs
@@ -1,20 +1,24 @@
use crate::hal::host::udp_server::ReceiveResult::{IoError, ReceiverError};
use crate::tmtc::ReceivesTc;
+use std::boxed::Box;
use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
+use std::vec;
use std::vec::Vec;
-pub struct UdpTmtcServer {
- socket: UdpSocket,
+pub struct UdpTcServer {
+ pub socket: UdpSocket,
recv_buf: Vec,
+ sender_addr: Option,
tc_receiver: Box>,
}
+#[derive(Debug)]
pub enum ReceiveResult {
IoError(std::io::Error),
ReceiverError(E),
}
-impl UdpTmtcServer {
+impl UdpTcServer {
pub fn new(
addr: A,
max_recv_size: usize,
@@ -22,7 +26,8 @@ impl UdpTmtcServer {
) -> Result {
Ok(Self {
socket: UdpSocket::bind(addr)?,
- recv_buf: Vec::with_capacity(max_recv_size),
+ recv_buf: vec![0; max_recv_size],
+ sender_addr: None,
tc_receiver,
})
}
@@ -32,6 +37,7 @@ impl UdpTmtcServer {
.socket
.recv_from(&mut self.recv_buf)
.map_err(|e| IoError(e))?;
+ self.sender_addr = Some(res.1);
self.tc_receiver
.pass_tc(&self.recv_buf[0..res.0])
.map_err(|e| ReceiverError(e))?;
diff --git a/fsrc-core/src/hal/mod.rs b/fsrc-core/src/hal/mod.rs
index 43769ba..0c9616d 100644
--- a/fsrc-core/src/hal/mod.rs
+++ b/fsrc-core/src/hal/mod.rs
@@ -1,2 +1,2 @@
-#[cfg(feature = "use_std")]
+#[cfg(feature = "std")]
pub mod host;
diff --git a/fsrc-core/src/tmtc/ccsds_distrib.rs b/fsrc-core/src/tmtc/ccsds_distrib.rs
index dfe1238..15bd1bb 100644
--- a/fsrc-core/src/tmtc/ccsds_distrib.rs
+++ b/fsrc-core/src/tmtc/ccsds_distrib.rs
@@ -2,7 +2,7 @@
//!
//! The routing components consist of two core components:
//! 1. [CcsdsDistributor] component which dispatches received packets to a user-provided handler
-//! 2. [ApidPacketHandler] trait which should be implemented by the user-provided packet handler.
+//! 2. [CcsdsPacketHandler] trait which should be implemented by the user-provided packet handler.
//!
//! The [CcsdsDistributor] implements the [ReceivesCcsdsTc] and [ReceivesTc] trait which allows to
//! pass raw or CCSDS packets to it. Upon receiving a packet, it performs the following steps:
@@ -11,14 +11,14 @@
//! respective CCSDS space packet header field. If that process fails, a [PacketError] is
//! returned to the user
//! 2. If a valid APID is found and matches one of the APIDs provided by
-//! [ApidPacketHandler::valid_apids], it will pass the packet to the user provided
-//! [ApidPacketHandler::handle_known_apid] function. If no valid APID is found, the packet
-//! will be passed to the [ApidPacketHandler::handle_unknown_apid] function.
+//! [CcsdsPacketHandler::valid_apids], it will pass the packet to the user provided
+//! [CcsdsPacketHandler::handle_known_apid] function. If no valid APID is found, the packet
+//! will be passed to the [CcsdsPacketHandler::handle_unknown_apid] function.
//!
//! # Example
//!
//! ```rust
-//! use fsrc_core::tmtc::ccsds_distrib::{ApidPacketHandler, CcsdsDistributor};
+//! use fsrc_core::tmtc::ccsds_distrib::{CcsdsPacketHandler, CcsdsDistributor};
//! use fsrc_core::tmtc::ReceivesTc;
//! use spacepackets::{CcsdsPacket, SpHeader};
//! use spacepackets::tc::PusTc;
@@ -33,7 +33,7 @@
//! fn mutable_foo(&mut self) {}
//! }
//!
-//! impl ApidPacketHandler for ConcreteApidHandler {
+//! impl CcsdsPacketHandler for ConcreteApidHandler {
//! type Error = ();
//! fn valid_apids(&self) -> &'static [u16] { &[0x002] }
//! fn handle_known_apid(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) -> Result<(), Self::Error> {
@@ -86,7 +86,7 @@
//! ```
use crate::tmtc::{ReceivesCcsdsTc, ReceivesTc};
use downcast_rs::Downcast;
-use spacepackets::{CcsdsPacket, PacketError, SpHeader};
+use spacepackets::{CcsdsPacket, PacketError, SizeMissmatch, SpHeader};
/// Generic trait for a handler or dispatcher object handling CCSDS packets.
///
@@ -98,7 +98,7 @@ use spacepackets::{CcsdsPacket, PacketError, SpHeader};
/// This trait automatically implements the [downcast_rs::Downcast] to allow a more convenient API
/// to cast trait objects back to their concrete type after the handler was passed to the
/// distributor.
-pub trait ApidPacketHandler: Downcast {
+pub trait CcsdsPacketHandler: Downcast {
type Error;
fn valid_apids(&self) -> &'static [u16];
@@ -111,14 +111,14 @@ pub trait ApidPacketHandler: Downcast {
) -> Result<(), Self::Error>;
}
-downcast_rs::impl_downcast!(ApidPacketHandler assoc Error);
+downcast_rs::impl_downcast!(CcsdsPacketHandler assoc Error);
/// The CCSDS distributor dispatches received CCSDS packets to a user provided packet handler.
pub struct CcsdsDistributor {
/// User provided APID handler stored as a generic trait object.
/// It can be cast back to the original concrete type using the [Self::apid_handler_ref] or
/// the [Self::apid_handler_mut] method.
- pub apid_handler: Box>,
+ pub apid_handler: Box>,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -139,26 +139,34 @@ impl ReceivesTc for CcsdsDistributor {
type Error = CcsdsError;
fn pass_tc(&mut self, tc_raw: &[u8]) -> Result<(), Self::Error> {
+ if tc_raw.len() < 7 {
+ return Err(CcsdsError::PacketError(
+ PacketError::FromBytesSliceTooSmall(SizeMissmatch {
+ found: tc_raw.len(),
+ expected: 7,
+ }),
+ ));
+ }
let sp_header = SpHeader::from_raw_slice(tc_raw).map_err(|e| CcsdsError::PacketError(e))?;
self.dispatch_ccsds(&sp_header, tc_raw)
}
}
impl CcsdsDistributor {
- pub fn new(apid_handler: Box>) -> Self {
+ pub fn new(apid_handler: Box>) -> Self {
CcsdsDistributor { apid_handler }
}
/// This function can be used to retrieve a reference to the concrete instance of the APID
/// handler after it was passed to the distributor. See the
/// [module documentation][crate::tmtc::ccsds_distrib] for an fsrc-example.
- pub fn apid_handler_ref>(&self) -> Option<&T> {
+ pub fn apid_handler_ref>(&self) -> Option<&T> {
self.apid_handler.downcast_ref::()
}
/// This function can be used to retrieve a mutable reference to the concrete instance of the
/// APID handler after it was passed to the distributor.
- pub fn apid_handler_mut>(&mut self) -> Option<&mut T> {
+ pub fn apid_handler_mut>(&mut self) -> Option<&mut T> {
self.apid_handler.downcast_mut::()
}
@@ -182,7 +190,7 @@ impl CcsdsDistributor {
#[cfg(test)]
pub(crate) mod tests {
use super::*;
- use crate::tmtc::ccsds_distrib::{ApidPacketHandler, CcsdsDistributor};
+ use crate::tmtc::ccsds_distrib::{CcsdsDistributor, CcsdsPacketHandler};
use spacepackets::tc::PusTc;
use spacepackets::CcsdsPacket;
use std::collections::VecDeque;
@@ -207,7 +215,7 @@ pub(crate) mod tests {
pub unknown_packet_queue: VecDeque<(u16, Vec)>,
}
- impl ApidPacketHandler for BasicApidHandlerSharedQueue {
+ impl CcsdsPacketHandler for BasicApidHandlerSharedQueue {
type Error = ();
fn valid_apids(&self) -> &'static [u16] {
&[0x000, 0x002]
@@ -242,7 +250,7 @@ pub(crate) mod tests {
}
}
- impl ApidPacketHandler for BasicApidHandlerOwnedQueue {
+ impl CcsdsPacketHandler for BasicApidHandlerOwnedQueue {
type Error = ();
fn valid_apids(&self) -> &'static [u16] {
diff --git a/fsrc-core/src/tmtc/mod.rs b/fsrc-core/src/tmtc/mod.rs
index 0c9c02c..7d52337 100644
--- a/fsrc-core/src/tmtc/mod.rs
+++ b/fsrc-core/src/tmtc/mod.rs
@@ -12,6 +12,9 @@ use spacepackets::SpHeader;
pub mod ccsds_distrib;
pub mod pus_distrib;
+pub use ccsds_distrib::{CcsdsDistributor, CcsdsError, CcsdsPacketHandler};
+pub use pus_distrib::{PusDistributor, PusServiceProvider};
+
const _RAW_PACKET_ERROR: &str = "raw-tmtc";
const _CCSDS_ERROR: &str = "ccsds-tmtc";
const _PUS_ERROR: &str = "pus-tmtc";
diff --git a/fsrc-core/src/tmtc/pus_distrib.rs b/fsrc-core/src/tmtc/pus_distrib.rs
index 2928110..8a3dfa6 100644
--- a/fsrc-core/src/tmtc/pus_distrib.rs
+++ b/fsrc-core/src/tmtc/pus_distrib.rs
@@ -137,7 +137,8 @@ mod tests {
use crate::tmtc::ccsds_distrib::tests::{
generate_ping_tc, BasicApidHandlerOwnedQueue, BasicApidHandlerSharedQueue,
};
- use crate::tmtc::ccsds_distrib::{ApidPacketHandler, CcsdsDistributor};
+ use crate::tmtc::ccsds_distrib::{CcsdsDistributor, CcsdsPacketHandler};
+ use alloc::vec::Vec;
use spacepackets::ecss::PusError;
use spacepackets::tc::PusTc;
use spacepackets::CcsdsPacket;
@@ -235,11 +236,11 @@ mod tests {
};
}
- impl ApidPacketHandler for ApidHandlerOwned {
+ impl CcsdsPacketHandler for ApidHandlerOwned {
apid_handler_impl!();
}
- impl ApidPacketHandler for ApidHandlerShared {
+ impl CcsdsPacketHandler for ApidHandlerShared {
apid_handler_impl!();
}
diff --git a/fsrc-core/tests/pool_test.rs b/fsrc-core/tests/pool_test.rs
index 54e10e9..aaa7910 100644
--- a/fsrc-core/tests/pool_test.rs
+++ b/fsrc-core/tests/pool_test.rs
@@ -1,7 +1,6 @@
+use fsrc_core::pool::{LocalPool, PoolCfg, StoreAddr, StoreError};
use std::sync::{Arc, RwLock};
use std::thread;
-use fsrc_core::pool::{LocalPool, PoolCfg, StoreAddr, StoreError};
-
struct PoolAccessDummy<'a> {
pool: &'a mut LocalPool,
diff --git a/fsrc-example/Cargo.toml b/fsrc-example/Cargo.toml
index 1ddb71a..8f29e3b 100644
--- a/fsrc-example/Cargo.toml
+++ b/fsrc-example/Cargo.toml
@@ -6,3 +6,6 @@ authors = ["Robin Mueller "]
[dependencies.spacepackets]
path = "../spacepackets"
+
+[dependencies.fsrc-core]
+path = "../fsrc-core"
diff --git a/fsrc-example/src/bin/client.rs b/fsrc-example/src/bin/client.rs
index 5956570..1a71a73 100644
--- a/fsrc-example/src/bin/client.rs
+++ b/fsrc-example/src/bin/client.rs
@@ -8,7 +8,7 @@ fn main() {
let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT);
let mut sph = SpHeader::tc(0x02, 0, 0).unwrap();
let pus_tc = PusTc::new_simple(&mut sph, 17, 1, None, true);
- let client = UdpSocket::bind("127.0.0.1:7300").expect("Connecting to UDP server failed");
+ let client = UdpSocket::bind("127.0.0.1:7302").expect("Connecting to UDP server failed");
let size = pus_tc.write_to(&mut buf).expect("Creating PUS TC failed");
client
.send_to(&buf[0..size], &addr)
diff --git a/fsrc-example/src/bin/obsw.rs b/fsrc-example/src/bin/obsw.rs
index 690cd3e..f4ae995 100644
--- a/fsrc-example/src/bin/obsw.rs
+++ b/fsrc-example/src/bin/obsw.rs
@@ -1,15 +1,96 @@
+use fsrc_core::hal::host::udp_server::{ReceiveResult, UdpTcServer};
+use fsrc_core::tmtc::{
+ CcsdsDistributor, CcsdsError, CcsdsPacketHandler, PusDistributor, PusServiceProvider,
+ ReceivesCcsdsTc,
+};
use fsrc_example::{OBSW_SERVER_ADDR, SERVER_PORT};
-use std::net::{IpAddr, SocketAddr, UdpSocket};
+use spacepackets::tc::PusTc;
+use spacepackets::{CcsdsPacket, SpHeader};
+use std::net::{IpAddr, SocketAddr};
-fn main() {
- let mut recv_buf = [0; 1024];
- let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT);
- let socket = UdpSocket::bind(&addr).expect("Error opening UDP socket");
- loop {
- let (num_bytes, src) = socket.recv_from(&mut recv_buf).expect("UDP Receive error");
- println!(
- "Received TM with len {num_bytes} from {src}: {:x?}",
- &recv_buf[0..num_bytes]
- );
+const PUS_APID: u16 = 0x02;
+
+struct PusReceiver {}
+
+struct CcsdsReceiver {
+ pus_handler: PusDistributor<()>,
+}
+
+impl CcsdsPacketHandler for CcsdsReceiver {
+ type Error = ();
+
+ fn valid_apids(&self) -> &'static [u16] {
+ &[PUS_APID]
+ }
+
+ fn handle_known_apid(
+ &mut self,
+ sp_header: &SpHeader,
+ tc_raw: &[u8],
+ ) -> Result<(), Self::Error> {
+ if sp_header.apid() == PUS_APID {
+ self.pus_handler
+ .pass_ccsds(sp_header, tc_raw)
+ .expect("Handling PUS packet failed");
+ }
+ Ok(())
+ }
+
+ fn handle_unknown_apid(
+ &mut self,
+ _sp_header: &SpHeader,
+ _tc_raw: &[u8],
+ ) -> Result<(), Self::Error> {
+ println!("Unknown APID detected");
+ Ok(())
+ }
+}
+
+impl PusServiceProvider for PusReceiver {
+ type Error = ();
+
+ fn handle_pus_tc_packet(
+ &mut self,
+ service: u8,
+ _header: &SpHeader,
+ pus_tc: &PusTc,
+ ) -> Result<(), Self::Error> {
+ if service == 17 {
+ println!("Received PUS ping command");
+ let raw_data = pus_tc.raw().expect("Could not retrieve raw data");
+ println!("Raw data: 0x{raw_data:x?}");
+ }
+ Ok(())
+ }
+}
+
+fn main() {
+ let addr = SocketAddr::new(IpAddr::V4(OBSW_SERVER_ADDR), SERVER_PORT);
+ let pus_receiver = PusReceiver {};
+ let pus_distributor = PusDistributor::new(Box::new(pus_receiver));
+ let ccsds_receiver = CcsdsReceiver {
+ pus_handler: pus_distributor,
+ };
+ let ccsds_distributor = CcsdsDistributor::new(Box::new(ccsds_receiver));
+ let mut udp_tmtc_server = UdpTcServer::new(addr, 2048, Box::new(ccsds_distributor))
+ .expect("Creating UDP TMTC server failed");
+ loop {
+ let res = udp_tmtc_server.recv_tc();
+ match res {
+ Ok(_) => (),
+ Err(e) => match e {
+ ReceiveResult::ReceiverError(e) => match e {
+ CcsdsError::PacketError(e) => {
+ println!("Got packet error: {e:?}");
+ }
+ CcsdsError::CustomError(_) => {
+ println!("Unknown receiver error")
+ }
+ },
+ ReceiveResult::IoError(e) => {
+ println!("IO error {e}");
+ }
+ },
+ }
}
}
diff --git a/spacepackets b/spacepackets
index 35073a4..42d3487 160000
--- a/spacepackets
+++ b/spacepackets
@@ -1 +1 @@
-Subproject commit 35073a45a536051e3852696c501d7afa1b36a808
+Subproject commit 42d3487c1934cfecf9b2d599c2f81fde52a61cc3