first packet routing components
This commit is contained in:
parent
2843a18867
commit
db78b02348
18
.idea/runConfigurations/Check.xml
generated
Normal file
18
.idea/runConfigurations/Check.xml
generated
Normal file
@ -0,0 +1,18 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Check" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
|
||||
<option name="command" value="run" />
|
||||
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
|
||||
<option name="channel" value="DEFAULT" />
|
||||
<option name="requiredFeatures" value="true" />
|
||||
<option name="allFeatures" value="true" />
|
||||
<option name="emulateTerminal" value="false" />
|
||||
<option name="withSudo" value="false" />
|
||||
<option name="backtrace" value="SHORT" />
|
||||
<envs />
|
||||
<option name="isRedirectInput" value="false" />
|
||||
<option name="redirectInputPath" value="" />
|
||||
<method v="2">
|
||||
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -211,6 +211,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bus",
|
||||
"num",
|
||||
"spacepackets",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -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 = []
|
||||
|
23
fsrc-core/examples/tc_server.rs
Normal file
23
fsrc-core/examples/tc_server.rs
Normal file
@ -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");
|
||||
}
|
67
fsrc-core/examples/test.rs
Normal file
67
fsrc-core/examples/test.rs
Normal file
@ -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<NetworkEndian>,
|
||||
some_i32: I32<NetworkEndian>,
|
||||
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);
|
||||
}
|
||||
}
|
1
fsrc-core/src/hal/host/mod.rs
Normal file
1
fsrc-core/src/hal/host/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod udp_server;
|
29
fsrc-core/src/hal/host/udp_server.rs
Normal file
29
fsrc-core/src/hal/host/udp_server.rs
Normal file
@ -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<u8>,
|
||||
tc_receiver: Box<dyn ReceivesTc>,
|
||||
}
|
||||
|
||||
impl UdpTmtcServer {
|
||||
pub fn new<A: ToSocketAddrs, E>(
|
||||
addr: A,
|
||||
max_recv_size: usize,
|
||||
tc_receiver: Box<dyn ReceivesTc>,
|
||||
) -> Result<Self, std::io::Error> {
|
||||
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)
|
||||
}
|
||||
}
|
2
fsrc-core/src/hal/mod.rs
Normal file
2
fsrc-core/src/hal/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
#[cfg(feature = "use_std")]
|
||||
pub mod host;
|
@ -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;
|
||||
|
@ -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<StoreAddr, StoreError> {
|
||||
pub fn add(&mut self, data: &[u8]) -> Result<StoreAddr, StoreError> {
|
||||
let data_len = data.as_ref().len();
|
||||
if data_len > Self::MAX_SIZE {
|
||||
return Err(StoreError::DataTooLarge(data_len));
|
||||
|
19
fsrc-core/src/tmtc/ccsds_distrib.rs
Normal file
19
fsrc-core/src/tmtc/ccsds_distrib.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use crate::tmtc::{ReceivesCcsds, ReceivesTc};
|
||||
use spacepackets::{CcsdsPacket, SpHeader};
|
||||
|
||||
pub trait ApidHandler {
|
||||
fn get_apid_handler(&self, apid: u16) -> Box<dyn ReceivesCcsds>;
|
||||
}
|
||||
|
||||
struct CcsdsDistributor {
|
||||
apid_handlers: Box<dyn ApidHandler>,
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
18
fsrc-core/src/tmtc/mod.rs
Normal file
18
fsrc-core/src/tmtc/mod.rs
Normal file
@ -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>;
|
||||
}
|
39
fsrc-core/src/tmtc/pus_distrib.rs
Normal file
39
fsrc-core/src/tmtc/pus_distrib.rs
Normal file
@ -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<dyn ReceivesPus>;
|
||||
}
|
||||
|
||||
pub struct PusDistributor {
|
||||
service_provider: Box<dyn PusServiceProvider>,
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
}
|
@ -1 +1 @@
|
||||
Subproject commit 063b8491545a71dee0ada2a15dc565f9cced75d2
|
||||
Subproject commit a7b97e22f5c7a183372bd30933e66b8bf3fc6a7b
|
Loading…
x
Reference in New Issue
Block a user