97 lines
3.1 KiB
Rust
97 lines
3.1 KiB
Rust
use satrs::pus::ReceivesEcssPusTc;
|
|
use satrs::queue::GenericSendError;
|
|
use satrs::spacepackets::SpHeader;
|
|
use std::sync::mpsc::{self};
|
|
use thiserror::Error;
|
|
|
|
use satrs::pool::{PoolProvider, SharedStaticMemoryPool, StoreAddr, StoreError};
|
|
use satrs::spacepackets::ecss::tc::PusTcReader;
|
|
use satrs::tmtc::{ReceivesCcsdsTc, ReceivesTc};
|
|
|
|
pub mod tc_source;
|
|
pub mod tm_sink;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Error)]
|
|
pub enum StoreAndSendError {
|
|
#[error("Store error: {0}")]
|
|
Store(#[from] StoreError),
|
|
#[error("Genreric send error: {0}")]
|
|
Send(#[from] GenericSendError),
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct SharedTcPool(pub SharedStaticMemoryPool);
|
|
|
|
impl SharedTcPool {
|
|
pub fn add_pus_tc(&mut self, pus_tc: &PusTcReader) -> Result<StoreAddr, StoreError> {
|
|
let mut pg = self.0.write().expect("error locking TC store");
|
|
let addr = pg.free_element(pus_tc.len_packed(), |buf| {
|
|
buf[0..pus_tc.len_packed()].copy_from_slice(pus_tc.raw_data());
|
|
})?;
|
|
Ok(addr)
|
|
}
|
|
|
|
pub fn add_ccsds_tc(&mut self, _: &SpHeader, tc_raw: &[u8]) -> Result<StoreAddr, StoreError> {
|
|
self.add_raw_tc(tc_raw)
|
|
}
|
|
|
|
pub fn add_raw_tc(&mut self, tc_raw: &[u8]) -> Result<StoreAddr, StoreError> {
|
|
let mut pg = self.0.write().expect("error locking TC store");
|
|
let addr = pg.free_element(tc_raw.len(), |buf| {
|
|
buf[0..tc_raw.len()].copy_from_slice(tc_raw);
|
|
})?;
|
|
Ok(addr)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct TcSenderSharedPool {
|
|
pub tc_source: mpsc::SyncSender<StoreAddr>,
|
|
pub shared_pool: SharedTcPool,
|
|
}
|
|
|
|
impl TcSenderSharedPool {
|
|
#[allow(dead_code)]
|
|
pub fn shared_pool(&self) -> SharedStaticMemoryPool {
|
|
self.shared_pool.0.clone()
|
|
}
|
|
}
|
|
|
|
impl ReceivesTc for TcSenderSharedPool {
|
|
type Error = StoreAndSendError;
|
|
|
|
fn pass_tc(&mut self, tc_raw: &[u8]) -> Result<(), Self::Error> {
|
|
let addr = self.shared_pool.add_raw_tc(tc_raw)?;
|
|
self.tc_source.try_send(addr).map_err(|e| match e {
|
|
mpsc::TrySendError::Full(_) => GenericSendError::QueueFull(None),
|
|
mpsc::TrySendError::Disconnected(_) => GenericSendError::RxDisconnected,
|
|
})?;
|
|
Ok(())
|
|
}
|
|
}
|
|
impl ReceivesEcssPusTc for TcSenderSharedPool {
|
|
type Error = StoreAndSendError;
|
|
|
|
fn pass_pus_tc(&mut self, _: &SpHeader, pus_tc: &PusTcReader) -> Result<(), Self::Error> {
|
|
let addr = self.shared_pool.add_pus_tc(pus_tc)?;
|
|
self.tc_source.try_send(addr).map_err(|e| match e {
|
|
mpsc::TrySendError::Full(_) => GenericSendError::QueueFull(None),
|
|
mpsc::TrySendError::Disconnected(_) => GenericSendError::RxDisconnected,
|
|
})?;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl ReceivesCcsdsTc for TcSenderSharedPool {
|
|
type Error = StoreAndSendError;
|
|
|
|
fn pass_ccsds(&mut self, sp_header: &SpHeader, tc_raw: &[u8]) -> Result<(), Self::Error> {
|
|
let addr = self.shared_pool.add_ccsds_tc(sp_header, tc_raw)?;
|
|
self.tc_source.try_send(addr).map_err(|e| match e {
|
|
mpsc::TrySendError::Full(_) => GenericSendError::QueueFull(None),
|
|
mpsc::TrySendError::Disconnected(_) => GenericSendError::RxDisconnected,
|
|
})?;
|
|
Ok(())
|
|
}
|
|
}
|