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(())
}
}