use satrs::{pool::PoolProvider, tmtc::tc_helper::SharedTcPool}; use std::sync::mpsc::{self, TryRecvError}; use satrs::{ pool::StoreAddr, pus::{MpscTmAsVecSender, MpscTmInSharedPoolSenderBounded}, spacepackets::ecss::{tc::PusTcReader, PusPacket}, }; use crate::pus::PusTcDistributor; // TC source components where static pools are the backing memory of the received telecommands. pub struct TcSourceTaskStatic { shared_tc_pool: SharedTcPool, tc_receiver: mpsc::Receiver, tc_buf: [u8; 4096], pus_receiver: PusTcDistributor, } impl TcSourceTaskStatic { pub fn new( shared_tc_pool: SharedTcPool, tc_receiver: mpsc::Receiver, pus_receiver: PusTcDistributor, ) -> Self { Self { shared_tc_pool, tc_receiver, tc_buf: [0; 4096], pus_receiver, } } pub fn periodic_operation(&mut self) { self.poll_tc(); } pub fn poll_tc(&mut self) -> bool { match self.tc_receiver.try_recv() { Ok(addr) => { let pool = self .shared_tc_pool .0 .read() .expect("locking tc pool failed"); pool.read(&addr, &mut self.tc_buf) .expect("reading pool failed"); drop(pool); match PusTcReader::new(&self.tc_buf) { Ok((pus_tc, _)) => { self.pus_receiver .handle_tc_packet( satrs::pus::TcInMemory::StoreAddr(addr), pus_tc.service(), &pus_tc, ) .ok(); true } Err(e) => { log::warn!("error creating PUS TC from raw data: {e}"); log::warn!("raw data: {:x?}", self.tc_buf); true } } } Err(e) => match e { TryRecvError::Empty => false, TryRecvError::Disconnected => { log::warn!("tmtc thread: sender disconnected"); false } }, } } } // TC source components where the heap is the backing memory of the received telecommands. pub struct TcSourceTaskDynamic { pub tc_receiver: mpsc::Receiver>, pus_receiver: PusTcDistributor, } impl TcSourceTaskDynamic { pub fn new( tc_receiver: mpsc::Receiver>, pus_receiver: PusTcDistributor, ) -> Self { Self { tc_receiver, pus_receiver, } } pub fn periodic_operation(&mut self) { self.poll_tc(); } pub fn poll_tc(&mut self) -> bool { // Right now, we only expect PUS packets. match self.tc_receiver.try_recv() { Ok(tc) => match PusTcReader::new(&tc) { Ok((pus_tc, _)) => { self.pus_receiver .handle_tc_packet( satrs::pus::TcInMemory::Vec(tc.clone()), pus_tc.service(), &pus_tc, ) .ok(); true } Err(e) => { log::warn!("error creating PUS TC from raw data: {e}"); log::warn!("raw data: {:x?}", tc); true } }, Err(e) => match e { TryRecvError::Empty => false, TryRecvError::Disconnected => { log::warn!("tmtc thread: sender disconnected"); false } }, } } }