129 lines
3.9 KiB
Rust
129 lines
3.9 KiB
Rust
|
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<StoreAddr>,
|
||
|
tc_buf: [u8; 4096],
|
||
|
pus_receiver: PusTcDistributor<MpscTmInSharedPoolSenderBounded>,
|
||
|
}
|
||
|
|
||
|
impl TcSourceTaskStatic {
|
||
|
pub fn new(
|
||
|
shared_tc_pool: SharedTcPool,
|
||
|
tc_receiver: mpsc::Receiver<StoreAddr>,
|
||
|
pus_receiver: PusTcDistributor<MpscTmInSharedPoolSenderBounded>,
|
||
|
) -> 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<Vec<u8>>,
|
||
|
pus_receiver: PusTcDistributor<MpscTmAsVecSender>,
|
||
|
}
|
||
|
|
||
|
impl TcSourceTaskDynamic {
|
||
|
pub fn new(
|
||
|
tc_receiver: mpsc::Receiver<Vec<u8>>,
|
||
|
pus_receiver: PusTcDistributor<MpscTmAsVecSender>,
|
||
|
) -> 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
|
||
|
}
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
}
|