use models::{ ComponentId, ccsds::{CcsdsTcPacketOwned, CcsdsTmPacketOwned}, control, }; use satrs::spacepackets::CcsdsPacketIdAndPsc; use crate::ccsds::pack_ccsds_tm_packet_for_now; pub struct Controller { pub tc_rx: std::sync::mpsc::Receiver, pub tm_tx: std::sync::mpsc::SyncSender, pub event_ctrl_tx: std::sync::mpsc::SyncSender, } impl Controller { pub fn new( tc_rx: std::sync::mpsc::Receiver, tm_tx: std::sync::mpsc::SyncSender, event_ctrl_tx: std::sync::mpsc::SyncSender, ) -> Self { Self { tc_rx, tm_tx, event_ctrl_tx, } } pub fn periodic_operation(&mut self) { self.handle_telecommands(); } pub fn handle_telecommands(&mut self) { loop { match self.tc_rx.try_recv() { Ok(packet) => { let tc_id = CcsdsPacketIdAndPsc::new_from_ccsds_packet(&packet.sp_header); match postcard::from_bytes::(&packet.payload) { Ok(request) => { log::info!( "received request {:?} with TC ID {:#010x}", request, tc_id.raw() ); match request { control::request::Request::Ping => self .send_telemetry(Some(tc_id), control::response::Response::Ok), control::request::Request::TestEvent => { self.event_ctrl_tx.send(control::Event::TestEvent).unwrap() } } } Err(e) => { log::warn!("failed to deserialize request: {}", e); } } } Err(e) => match e { std::sync::mpsc::TryRecvError::Empty => break, std::sync::mpsc::TryRecvError::Disconnected => { log::warn!("packet sender disconnected") } }, } } } pub fn send_telemetry( &self, tc_id: Option, response: control::response::Response, ) { match pack_ccsds_tm_packet_for_now(ComponentId::Controller, tc_id, &response) { Ok(packet) => { if let Err(e) = self.tm_tx.send(packet) { log::warn!("failed to send TM packet: {}", e); } } Err(e) => { log::warn!("failed to pack TM packet: {}", e); } } } }