diff --git a/.idea/runConfigurations/Check.xml b/.idea/runConfigurations/Check.xml
new file mode 100644
index 0000000..7742dee
--- /dev/null
+++ b/.idea/runConfigurations/Check.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 1793871..303e398 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -211,6 +211,7 @@ version = "0.1.0"
dependencies = [
"bus",
"num",
+ "spacepackets",
"thiserror",
]
diff --git a/fsrc-core/Cargo.toml b/fsrc-core/Cargo.toml
index c64545d..f12146b 100644
--- a/fsrc-core/Cargo.toml
+++ b/fsrc-core/Cargo.toml
@@ -9,3 +9,8 @@ edition = "2021"
thiserror = "1.0"
bus = "2.2.3"
num = "0.4"
+spacepackets = { path = "../spacepackets"}
+
+[features]
+default = ["use_std"]
+use_std = []
diff --git a/fsrc-core/examples/tc_server.rs b/fsrc-core/examples/tc_server.rs
new file mode 100644
index 0000000..dfdced9
--- /dev/null
+++ b/fsrc-core/examples/tc_server.rs
@@ -0,0 +1,23 @@
+extern crate core;
+
+use std::net::{IpAddr, Ipv4Addr, SocketAddr, UdpSocket};
+use std::thread;
+
+fn main() {
+ let server_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7301);
+ let socket = UdpSocket::bind(&server_addr.clone()).expect("Error opening UDP socket");
+ let mut recv_buf = [0; 1024];
+ let jh = thread::spawn(move || {
+ let dummy_data = [1, 2, 3, 4];
+ let client = UdpSocket::bind("127.0.0.1:7300").expect("Connecting to UDP server failed");
+ client
+ .send_to(&dummy_data, &server_addr)
+ .expect(&*format!("Sending to {:?} failed", server_addr));
+ });
+ let (num_bytes, src) = socket.recv_from(&mut recv_buf).expect("UDP Receive error");
+ println!(
+ "Received {num_bytes} bytes from {src}: {:x?}",
+ &recv_buf[0..num_bytes]
+ );
+ jh.join().expect("Joining thread failed");
+}
diff --git a/fsrc-core/examples/test.rs b/fsrc-core/examples/test.rs
new file mode 100644
index 0000000..49a7405
--- /dev/null
+++ b/fsrc-core/examples/test.rs
@@ -0,0 +1,67 @@
+use postcard::{from_bytes, to_stdvec};
+use serde::{Deserialize, Serialize};
+use zerocopy::byteorder::{I32, U16};
+use zerocopy::{AsBytes, FromBytes, NetworkEndian, Unaligned};
+
+#[derive(AsBytes, FromBytes, Unaligned, Debug, Eq, PartialEq)]
+#[repr(C, packed)]
+struct ZeroCopyTest {
+ some_bool: u8,
+ some_u16: U16,
+ some_i32: I32,
+ some_float: [u8; 4],
+}
+
+#[derive(Serialize, Deserialize, Debug, PartialEq)]
+struct PostcardTest {
+ some_bool: u8,
+ some_u16: u16,
+ some_i32: i32,
+ some_float: f32,
+}
+
+#[derive(Serialize, Deserialize, Debug, PartialEq)]
+struct SliceSerTest<'slice> {
+ some_u8: u8,
+ some_u32: u32,
+ some_slice: &'slice [u8],
+}
+
+fn main() {
+ let pc_test = PostcardTest {
+ some_bool: true as u8,
+ some_u16: 0x42,
+ some_i32: -200,
+ some_float: 7.7_f32,
+ };
+
+ let out = to_stdvec(&pc_test).unwrap();
+ println!("{:#04x?}", out);
+
+ let sample_hk = ZeroCopyTest {
+ some_bool: true as u8,
+ some_u16: U16::from(0x42),
+ some_i32: I32::from(-200),
+ some_float: 7.7_f32.to_be_bytes(),
+ };
+ let mut slice = [0; 11];
+ sample_hk.write_to(slice.as_mut_slice());
+ println!("{:#04x?}", slice);
+
+ let ser_vec;
+ {
+ let test_buf = [0, 1, 2, 3];
+ let test_with_slice = SliceSerTest {
+ some_u8: 12,
+ some_u32: 1,
+ some_slice: test_buf.as_slice(),
+ };
+ ser_vec = to_stdvec(&test_with_slice).unwrap();
+ println!("{:#04x?}", out);
+ }
+
+ {
+ let test_deser: SliceSerTest = from_bytes(ser_vec.as_slice()).unwrap();
+ println!("{:?}", test_deser);
+ }
+}
diff --git a/fsrc-core/src/hal/host/mod.rs b/fsrc-core/src/hal/host/mod.rs
new file mode 100644
index 0000000..d9e7799
--- /dev/null
+++ b/fsrc-core/src/hal/host/mod.rs
@@ -0,0 +1 @@
+pub mod udp_server;
diff --git a/fsrc-core/src/hal/host/udp_server.rs b/fsrc-core/src/hal/host/udp_server.rs
new file mode 100644
index 0000000..d4cb29f
--- /dev/null
+++ b/fsrc-core/src/hal/host/udp_server.rs
@@ -0,0 +1,29 @@
+use crate::tmtc::ReceivesTc;
+use std::net::{SocketAddr, ToSocketAddrs, UdpSocket};
+use std::vec::Vec;
+
+pub struct UdpTmtcServer {
+ socket: UdpSocket,
+ recv_buf: Vec,
+ tc_receiver: Box,
+}
+
+impl UdpTmtcServer {
+ pub fn new(
+ addr: A,
+ max_recv_size: usize,
+ tc_receiver: Box,
+ ) -> Result {
+ Ok(Self {
+ socket: UdpSocket::bind(addr)?,
+ recv_buf: Vec::with_capacity(max_recv_size),
+ tc_receiver,
+ })
+ }
+
+ pub fn recv_tc(&mut self) -> Result<(usize, SocketAddr), std::io::Error> {
+ let res = self.socket.recv_from(&mut self.recv_buf)?;
+ self.tc_receiver.pass_tc(&self.recv_buf[0..res.0]);
+ Ok(res)
+ }
+}
diff --git a/fsrc-core/src/hal/mod.rs b/fsrc-core/src/hal/mod.rs
new file mode 100644
index 0000000..43769ba
--- /dev/null
+++ b/fsrc-core/src/hal/mod.rs
@@ -0,0 +1,2 @@
+#[cfg(feature = "use_std")]
+pub mod host;
diff --git a/fsrc-core/src/lib.rs b/fsrc-core/src/lib.rs
index 148ac45..5b4c86b 100644
--- a/fsrc-core/src/lib.rs
+++ b/fsrc-core/src/lib.rs
@@ -2,5 +2,7 @@
pub mod event_man;
pub mod events;
pub mod executable;
+pub mod hal;
pub mod objects;
pub mod pool;
+pub mod tmtc;
diff --git a/fsrc-core/src/pool.rs b/fsrc-core/src/pool.rs
index 99f8853..da53bd0 100644
--- a/fsrc-core/src/pool.rs
+++ b/fsrc-core/src/pool.rs
@@ -171,7 +171,7 @@ impl LocalPool {
/// Add new data to the pool. It will attempt to reserve a memory block with the appropriate
/// size and then copy the given data to the block. Yields a [StoreAddr] which can be used
/// to access the data stored in the pool
- pub fn add(&mut self, data: impl AsRef<[u8]>) -> Result {
+ pub fn add(&mut self, data: &[u8]) -> Result {
let data_len = data.as_ref().len();
if data_len > Self::MAX_SIZE {
return Err(StoreError::DataTooLarge(data_len));
diff --git a/fsrc-core/src/tmtc/ccsds_distrib.rs b/fsrc-core/src/tmtc/ccsds_distrib.rs
new file mode 100644
index 0000000..dafadac
--- /dev/null
+++ b/fsrc-core/src/tmtc/ccsds_distrib.rs
@@ -0,0 +1,19 @@
+use crate::tmtc::{ReceivesCcsds, ReceivesTc};
+use spacepackets::{CcsdsPacket, SpHeader};
+
+pub trait ApidHandler {
+ fn get_apid_handler(&self, apid: u16) -> Box;
+}
+
+struct CcsdsDistributor {
+ apid_handlers: Box,
+}
+
+impl ReceivesTc for CcsdsDistributor {
+ fn pass_tc(&mut self, tm_raw: &[u8]) {
+ // TODO: Better error handling
+ let sp_header = SpHeader::from_raw_slice(tm_raw).unwrap();
+ let mut handler = self.apid_handlers.get_apid_handler(sp_header.apid());
+ handler.pass_ccsds(&sp_header, tm_raw).unwrap();
+ }
+}
diff --git a/fsrc-core/src/tmtc/mod.rs b/fsrc-core/src/tmtc/mod.rs
new file mode 100644
index 0000000..2bf8cce
--- /dev/null
+++ b/fsrc-core/src/tmtc/mod.rs
@@ -0,0 +1,18 @@
+use spacepackets::ecss::PusError;
+use spacepackets::tc::PusTc;
+use spacepackets::{PacketError, SpHeader};
+
+pub mod ccsds_distrib;
+pub mod pus_distrib;
+
+pub trait ReceivesTc {
+ fn pass_tc(&mut self, tc_raw: &[u8]);
+}
+
+pub trait ReceivesCcsds {
+ fn pass_ccsds(&mut self, header: &SpHeader, tm_raw: &[u8]) -> Result<(), PacketError>;
+}
+
+pub trait ReceivesPus {
+ fn pass_pus(&mut self, pus_tc: &PusTc) -> Result<(), PusError>;
+}
diff --git a/fsrc-core/src/tmtc/pus_distrib.rs b/fsrc-core/src/tmtc/pus_distrib.rs
new file mode 100644
index 0000000..f9dccd4
--- /dev/null
+++ b/fsrc-core/src/tmtc/pus_distrib.rs
@@ -0,0 +1,39 @@
+use crate::tmtc::{ReceivesCcsds, ReceivesPus, ReceivesTc};
+use spacepackets::ecss::PusPacket;
+use spacepackets::tc::PusTc;
+use spacepackets::{CcsdsPacket, PacketError, SpHeader};
+
+pub trait PusServiceProvider {
+ fn get_apid(&self, service: u8) -> u16;
+ fn get_service_handler(&self, service: u8, subservice: u8) -> Box;
+}
+
+pub struct PusDistributor {
+ service_provider: Box,
+}
+
+impl ReceivesTc for PusDistributor {
+ fn pass_tc(&mut self, tm_raw: &[u8]) {
+ // Convert to ccsds and call pass_ccsds
+ let sp_header = SpHeader::from_raw_slice(tm_raw).unwrap();
+ self.pass_ccsds(&sp_header, tm_raw).unwrap();
+ }
+}
+
+impl ReceivesCcsds for PusDistributor {
+ fn pass_ccsds(&mut self, _header: &SpHeader, tm_raw: &[u8]) -> Result<(), PacketError> {
+ // TODO: Better error handling
+ let (tc, _) = PusTc::new_from_raw_slice(tm_raw).unwrap();
+
+ let mut srv_provider = self
+ .service_provider
+ .get_service_handler(tc.service(), tc.subservice());
+ let apid = self.service_provider.get_apid(tc.service());
+ if apid != tc.apid() {
+ // TODO: Dedicated error
+ return Ok(());
+ }
+ srv_provider.pass_pus(&tc).unwrap();
+ Ok(())
+ }
+}
diff --git a/spacepackets b/spacepackets
index 063b849..a7b97e2 160000
--- a/spacepackets
+++ b/spacepackets
@@ -1 +1 @@
-Subproject commit 063b8491545a71dee0ada2a15dc565f9cced75d2
+Subproject commit a7b97e22f5c7a183372bd30933e66b8bf3fc6a7b